OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/renderer/pepper/pepper_truetype_font.h" | 5 #include "content/renderer/pepper/pepper_truetype_font.h" |
6 | 6 |
7 #import <ApplicationServices/ApplicationServices.h> | 7 #import <ApplicationServices/ApplicationServices.h> |
8 | 8 |
9 #include <stdio.h> | 9 #include <stdio.h> |
10 | 10 |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 virtual int32_t GetTableTags(std::vector<uint32_t>* tags) OVERRIDE; | 107 virtual int32_t GetTableTags(std::vector<uint32_t>* tags) OVERRIDE; |
108 virtual int32_t GetTable(uint32_t table_tag, | 108 virtual int32_t GetTable(uint32_t table_tag, |
109 int32_t offset, | 109 int32_t offset, |
110 int32_t max_data_length, | 110 int32_t max_data_length, |
111 std::string* data) OVERRIDE; | 111 std::string* data) OVERRIDE; |
112 private: | 112 private: |
113 virtual int32_t GetEntireFont(int32_t offset, | 113 virtual int32_t GetEntireFont(int32_t offset, |
114 int32_t max_data_length, | 114 int32_t max_data_length, |
115 std::string* data); | 115 std::string* data); |
116 | 116 |
117 base::mac::ScopedCFTypeRef<CTFontRef> font_ref_; | 117 base::ScopedCFTypeRef<CTFontRef> font_ref_; |
118 | 118 |
119 DISALLOW_COPY_AND_ASSIGN(PepperTrueTypeFontMac); | 119 DISALLOW_COPY_AND_ASSIGN(PepperTrueTypeFontMac); |
120 }; | 120 }; |
121 | 121 |
122 PepperTrueTypeFontMac::PepperTrueTypeFontMac( | 122 PepperTrueTypeFontMac::PepperTrueTypeFontMac( |
123 const ppapi::proxy::SerializedTrueTypeFontDesc& desc) { | 123 const ppapi::proxy::SerializedTrueTypeFontDesc& desc) { |
124 // Create attributes and traits dictionaries. | 124 // Create attributes and traits dictionaries. |
125 base::mac::ScopedCFTypeRef<CFMutableDictionaryRef> attributes_ref( | 125 base::ScopedCFTypeRef<CFMutableDictionaryRef> attributes_ref( |
126 CFDictionaryCreateMutable(kCFAllocatorDefault, 0, | 126 CFDictionaryCreateMutable(kCFAllocatorDefault, |
| 127 0, |
127 &kCFTypeDictionaryKeyCallBacks, | 128 &kCFTypeDictionaryKeyCallBacks, |
128 &kCFTypeDictionaryValueCallBacks)); | 129 &kCFTypeDictionaryValueCallBacks)); |
129 | 130 |
130 base::mac::ScopedCFTypeRef<CFMutableDictionaryRef> traits_ref( | 131 base::ScopedCFTypeRef<CFMutableDictionaryRef> traits_ref( |
131 CFDictionaryCreateMutable(kCFAllocatorDefault, 0, | 132 CFDictionaryCreateMutable(kCFAllocatorDefault, |
| 133 0, |
132 &kCFTypeDictionaryKeyCallBacks, | 134 &kCFTypeDictionaryKeyCallBacks, |
133 &kCFTypeDictionaryValueCallBacks)); | 135 &kCFTypeDictionaryValueCallBacks)); |
134 if (!attributes_ref || !traits_ref) | 136 if (!attributes_ref || !traits_ref) |
135 return; | 137 return; |
136 | 138 |
137 CFDictionaryAddValue(attributes_ref, kCTFontTraitsAttribute, traits_ref); | 139 CFDictionaryAddValue(attributes_ref, kCTFontTraitsAttribute, traits_ref); |
138 | 140 |
139 // Use symbolic traits to specify traits when possible. | 141 // Use symbolic traits to specify traits when possible. |
140 CTFontSymbolicTraits symbolic_traits = 0; | 142 CTFontSymbolicTraits symbolic_traits = 0; |
141 if (desc.style & PP_TRUETYPEFONTSTYLE_ITALIC) | 143 if (desc.style & PP_TRUETYPEFONTSTYLE_ITALIC) |
142 symbolic_traits |= kCTFontItalicTrait; | 144 symbolic_traits |= kCTFontItalicTrait; |
143 if (desc.weight == PP_TRUETYPEFONTWEIGHT_BOLD) | 145 if (desc.weight == PP_TRUETYPEFONTWEIGHT_BOLD) |
144 symbolic_traits |= kCTFontBoldTrait; | 146 symbolic_traits |= kCTFontBoldTrait; |
145 if (desc.width == PP_TRUETYPEFONTWIDTH_CONDENSED) | 147 if (desc.width == PP_TRUETYPEFONTWIDTH_CONDENSED) |
146 symbolic_traits |= kCTFontCondensedTrait; | 148 symbolic_traits |= kCTFontCondensedTrait; |
147 else if (desc.width == PP_TRUETYPEFONTWIDTH_EXPANDED) | 149 else if (desc.width == PP_TRUETYPEFONTWIDTH_EXPANDED) |
148 symbolic_traits |= kCTFontExpandedTrait; | 150 symbolic_traits |= kCTFontExpandedTrait; |
149 | 151 |
150 base::mac::ScopedCFTypeRef<CFNumberRef> symbolic_traits_ref( | 152 base::ScopedCFTypeRef<CFNumberRef> symbolic_traits_ref(CFNumberCreate( |
151 CFNumberCreate(kCFAllocatorDefault, | 153 kCFAllocatorDefault, kCFNumberSInt32Type, &symbolic_traits)); |
152 kCFNumberSInt32Type, | |
153 &symbolic_traits)); | |
154 if (!symbolic_traits_ref) | 154 if (!symbolic_traits_ref) |
155 return; | 155 return; |
156 CFDictionaryAddValue(traits_ref, kCTFontSymbolicTrait, symbolic_traits_ref); | 156 CFDictionaryAddValue(traits_ref, kCTFontSymbolicTrait, symbolic_traits_ref); |
157 | 157 |
158 // Font family matching doesn't work using family classes in symbolic traits. | 158 // Font family matching doesn't work using family classes in symbolic traits. |
159 // Instead, map generic_family to font families that are always available. | 159 // Instead, map generic_family to font families that are always available. |
160 std::string family(desc.family); | 160 std::string family(desc.family); |
161 if (family.empty()) { | 161 if (family.empty()) { |
162 switch (desc.generic_family) { | 162 switch (desc.generic_family) { |
163 case PP_TRUETYPEFONTFAMILY_SERIF: | 163 case PP_TRUETYPEFONTFAMILY_SERIF: |
164 family = "Times"; | 164 family = "Times"; |
165 break; | 165 break; |
166 case PP_TRUETYPEFONTFAMILY_SANSSERIF: | 166 case PP_TRUETYPEFONTFAMILY_SANSSERIF: |
167 family = "Helvetica"; | 167 family = "Helvetica"; |
168 break; | 168 break; |
169 case PP_TRUETYPEFONTFAMILY_CURSIVE: | 169 case PP_TRUETYPEFONTFAMILY_CURSIVE: |
170 family = "Apple Chancery"; | 170 family = "Apple Chancery"; |
171 break; | 171 break; |
172 case PP_TRUETYPEFONTFAMILY_FANTASY: | 172 case PP_TRUETYPEFONTFAMILY_FANTASY: |
173 family = "Papyrus"; | 173 family = "Papyrus"; |
174 break; | 174 break; |
175 case PP_TRUETYPEFONTFAMILY_MONOSPACE: | 175 case PP_TRUETYPEFONTFAMILY_MONOSPACE: |
176 family = "Courier"; | 176 family = "Courier"; |
177 break; | 177 break; |
178 } | 178 } |
179 } | 179 } |
180 | 180 |
181 base::mac::ScopedCFTypeRef<CFStringRef> name_ref( | 181 base::ScopedCFTypeRef<CFStringRef> name_ref( |
182 base::SysUTF8ToCFStringRef(family)); | 182 base::SysUTF8ToCFStringRef(family)); |
183 if (name_ref) | 183 if (name_ref) |
184 CFDictionaryAddValue(attributes_ref, kCTFontFamilyNameAttribute, name_ref); | 184 CFDictionaryAddValue(attributes_ref, kCTFontFamilyNameAttribute, name_ref); |
185 | 185 |
186 if (desc.weight != PP_TRUETYPEFONTWEIGHT_NORMAL && | 186 if (desc.weight != PP_TRUETYPEFONTWEIGHT_NORMAL && |
187 desc.weight != PP_TRUETYPEFONTWEIGHT_BOLD) { | 187 desc.weight != PP_TRUETYPEFONTWEIGHT_BOLD) { |
188 float weight = GetMacWeight(desc.weight); | 188 float weight = GetMacWeight(desc.weight); |
189 base::mac::ScopedCFTypeRef<CFNumberRef> weight_trait_ref( | 189 base::ScopedCFTypeRef<CFNumberRef> weight_trait_ref( |
190 CFNumberCreate(kCFAllocatorDefault, | 190 CFNumberCreate(kCFAllocatorDefault, kCFNumberFloat32Type, &weight)); |
191 kCFNumberFloat32Type, | |
192 &weight)); | |
193 if (weight_trait_ref) | 191 if (weight_trait_ref) |
194 CFDictionaryAddValue(traits_ref, kCTFontWeightTrait, weight_trait_ref); | 192 CFDictionaryAddValue(traits_ref, kCTFontWeightTrait, weight_trait_ref); |
195 } | 193 } |
196 | 194 |
197 if (desc.width != PP_TRUETYPEFONTWIDTH_NORMAL && | 195 if (desc.width != PP_TRUETYPEFONTWIDTH_NORMAL && |
198 desc.width != PP_TRUETYPEFONTWIDTH_CONDENSED && | 196 desc.width != PP_TRUETYPEFONTWIDTH_CONDENSED && |
199 desc.width != PP_TRUETYPEFONTWIDTH_EXPANDED) { | 197 desc.width != PP_TRUETYPEFONTWIDTH_EXPANDED) { |
200 float width = GetMacWidth(desc.width); | 198 float width = GetMacWidth(desc.width); |
201 base::mac::ScopedCFTypeRef<CFNumberRef> width_trait_ref( | 199 base::ScopedCFTypeRef<CFNumberRef> width_trait_ref( |
202 CFNumberCreate(kCFAllocatorDefault, | 200 CFNumberCreate(kCFAllocatorDefault, kCFNumberFloat32Type, &width)); |
203 kCFNumberFloat32Type, | |
204 &width)); | |
205 if (width_trait_ref) | 201 if (width_trait_ref) |
206 CFDictionaryAddValue(traits_ref, kCTFontWidthTrait, width_trait_ref); | 202 CFDictionaryAddValue(traits_ref, kCTFontWidthTrait, width_trait_ref); |
207 } | 203 } |
208 | 204 |
209 base::mac::ScopedCFTypeRef<CTFontDescriptorRef> desc_ref( | 205 base::ScopedCFTypeRef<CTFontDescriptorRef> desc_ref( |
210 CTFontDescriptorCreateWithAttributes(attributes_ref)); | 206 CTFontDescriptorCreateWithAttributes(attributes_ref)); |
211 | 207 |
212 if (desc_ref) | 208 if (desc_ref) |
213 font_ref_.reset(CTFontCreateWithFontDescriptor(desc_ref, 0, NULL)); | 209 font_ref_.reset(CTFontCreateWithFontDescriptor(desc_ref, 0, NULL)); |
214 } | 210 } |
215 | 211 |
216 PepperTrueTypeFontMac::~PepperTrueTypeFontMac() { | 212 PepperTrueTypeFontMac::~PepperTrueTypeFontMac() { |
217 } | 213 } |
218 | 214 |
219 bool PepperTrueTypeFontMac::IsValid() { | 215 bool PepperTrueTypeFontMac::IsValid() { |
220 return font_ref_.get() != NULL; | 216 return font_ref_.get() != NULL; |
221 } | 217 } |
222 | 218 |
223 int32_t PepperTrueTypeFontMac::Describe( | 219 int32_t PepperTrueTypeFontMac::Describe( |
224 ppapi::proxy::SerializedTrueTypeFontDesc* desc) { | 220 ppapi::proxy::SerializedTrueTypeFontDesc* desc) { |
225 if (!IsValid()) | 221 if (!IsValid()) |
226 return PP_ERROR_FAILED; | 222 return PP_ERROR_FAILED; |
227 | 223 |
228 base::mac::ScopedCFTypeRef<CTFontDescriptorRef> desc_ref( | 224 base::ScopedCFTypeRef<CTFontDescriptorRef> desc_ref( |
229 CTFontCopyFontDescriptor(font_ref_)); | 225 CTFontCopyFontDescriptor(font_ref_)); |
230 | 226 |
231 base::mac::ScopedCFTypeRef<CFStringRef> family_name_ref( | 227 base::ScopedCFTypeRef<CFStringRef> family_name_ref( |
232 base::mac::CFCast<CFStringRef>(CTFontDescriptorCopyAttribute( | 228 base::mac::CFCast<CFStringRef>( |
233 desc_ref, kCTFontFamilyNameAttribute))); | 229 CTFontDescriptorCopyAttribute(desc_ref, kCTFontFamilyNameAttribute))); |
234 desc->family = base::SysCFStringRefToUTF8(family_name_ref); | 230 desc->family = base::SysCFStringRefToUTF8(family_name_ref); |
235 | 231 |
236 base::mac::ScopedCFTypeRef<CFDictionaryRef> traits_ref( | 232 base::ScopedCFTypeRef<CFDictionaryRef> traits_ref( |
237 base::mac::CFCast<CFDictionaryRef>( | 233 base::mac::CFCast<CFDictionaryRef>( |
238 CTFontDescriptorCopyAttribute(desc_ref, kCTFontTraitsAttribute))); | 234 CTFontDescriptorCopyAttribute(desc_ref, kCTFontTraitsAttribute))); |
239 | 235 |
240 desc->style = PP_TRUETYPEFONTSTYLE_NORMAL; | 236 desc->style = PP_TRUETYPEFONTSTYLE_NORMAL; |
241 CTFontSymbolicTraits symbolic_traits(CTFontGetSymbolicTraits(font_ref_)); | 237 CTFontSymbolicTraits symbolic_traits(CTFontGetSymbolicTraits(font_ref_)); |
242 if (symbolic_traits & kCTFontItalicTrait) | 238 if (symbolic_traits & kCTFontItalicTrait) |
243 desc->style = static_cast<PP_TrueTypeFontStyle_Dev>( | 239 desc->style = static_cast<PP_TrueTypeFontStyle_Dev>( |
244 desc->style | PP_TRUETYPEFONTSTYLE_ITALIC); | 240 desc->style | PP_TRUETYPEFONTSTYLE_ITALIC); |
245 if (symbolic_traits & kCTFontBoldTrait) { | 241 if (symbolic_traits & kCTFontBoldTrait) { |
246 desc->weight = PP_TRUETYPEFONTWEIGHT_BOLD; | 242 desc->weight = PP_TRUETYPEFONTWEIGHT_BOLD; |
(...skipping 11 matching lines...) Expand all Loading... |
258 if (FindFloat(traits_ref, kCTFontWidthTrait, &width)) | 254 if (FindFloat(traits_ref, kCTFontWidthTrait, &width)) |
259 desc->width = GetPepperWidth(width); | 255 desc->width = GetPepperWidth(width); |
260 } | 256 } |
261 | 257 |
262 // Character set isn't supported on Mac. | 258 // Character set isn't supported on Mac. |
263 desc->charset = PP_TRUETYPEFONTCHARSET_DEFAULT; | 259 desc->charset = PP_TRUETYPEFONTCHARSET_DEFAULT; |
264 return PP_OK; | 260 return PP_OK; |
265 } | 261 } |
266 | 262 |
267 int32_t PepperTrueTypeFontMac::GetTableTags(std::vector<uint32_t>* tags) { | 263 int32_t PepperTrueTypeFontMac::GetTableTags(std::vector<uint32_t>* tags) { |
268 base::mac::ScopedCFTypeRef<CFArrayRef> tag_array( | 264 base::ScopedCFTypeRef<CFArrayRef> tag_array( |
269 CTFontCopyAvailableTables(font_ref_, kCTFontTableOptionNoOptions)); | 265 CTFontCopyAvailableTables(font_ref_, kCTFontTableOptionNoOptions)); |
270 if (!tag_array) | 266 if (!tag_array) |
271 return PP_ERROR_FAILED; | 267 return PP_ERROR_FAILED; |
272 | 268 |
273 // Items returned by CTFontCopyAvailableTables are not boxed. Whose bright | 269 // Items returned by CTFontCopyAvailableTables are not boxed. Whose bright |
274 // idea was this? | 270 // idea was this? |
275 CFIndex length = CFArrayGetCount(tag_array); | 271 CFIndex length = CFArrayGetCount(tag_array); |
276 tags->resize(length); | 272 tags->resize(length); |
277 for (CFIndex i = 0; i < length; ++i) { | 273 for (CFIndex i = 0; i < length; ++i) { |
278 (*tags)[i] = | 274 (*tags)[i] = |
279 reinterpret_cast<uintptr_t>(CFArrayGetValueAtIndex(tag_array, i)); | 275 reinterpret_cast<uintptr_t>(CFArrayGetValueAtIndex(tag_array, i)); |
280 } | 276 } |
281 return length; | 277 return length; |
282 } | 278 } |
283 | 279 |
284 int32_t PepperTrueTypeFontMac::GetTable(uint32_t table_tag, | 280 int32_t PepperTrueTypeFontMac::GetTable(uint32_t table_tag, |
285 int32_t offset, | 281 int32_t offset, |
286 int32_t max_data_length, | 282 int32_t max_data_length, |
287 std::string* data) { | 283 std::string* data) { |
288 if (!table_tag) | 284 if (!table_tag) |
289 return GetEntireFont(offset, max_data_length, data); | 285 return GetEntireFont(offset, max_data_length, data); |
290 | 286 |
291 base::mac::ScopedCFTypeRef<CFDataRef> table_ref( | 287 base::ScopedCFTypeRef<CFDataRef> table_ref( |
292 CTFontCopyTable(font_ref_, static_cast<CTFontTableTag>(table_tag), | 288 CTFontCopyTable(font_ref_, |
| 289 static_cast<CTFontTableTag>(table_tag), |
293 kCTFontTableOptionNoOptions)); | 290 kCTFontTableOptionNoOptions)); |
294 if (!table_ref) | 291 if (!table_ref) |
295 return PP_ERROR_FAILED; | 292 return PP_ERROR_FAILED; |
296 | 293 |
297 CFIndex table_size = CFDataGetLength(table_ref); | 294 CFIndex table_size = CFDataGetLength(table_ref); |
298 CFIndex safe_offset = | 295 CFIndex safe_offset = |
299 std::min(base::checked_numeric_cast<CFIndex>(offset), table_size); | 296 std::min(base::checked_numeric_cast<CFIndex>(offset), table_size); |
300 CFIndex safe_length = | 297 CFIndex safe_length = |
301 std::min(table_size - safe_offset, | 298 std::min(table_size - safe_offset, |
302 base::checked_numeric_cast<CFIndex>(max_data_length)); | 299 base::checked_numeric_cast<CFIndex>(max_data_length)); |
(...skipping 10 matching lines...) Expand all Loading... |
313 // Reconstruct the font header, table directory, and tables. | 310 // Reconstruct the font header, table directory, and tables. |
314 std::vector<uint32_t> table_tags; | 311 std::vector<uint32_t> table_tags; |
315 int32_t table_count = GetTableTags(&table_tags); | 312 int32_t table_count = GetTableTags(&table_tags); |
316 if (table_count < 0) | 313 if (table_count < 0) |
317 return table_count; // PPAPI error code. | 314 return table_count; // PPAPI error code. |
318 | 315 |
319 // Allocate enough room for the header and the table directory entries. | 316 // Allocate enough room for the header and the table directory entries. |
320 std::string font(sizeof(FontHeader) + | 317 std::string font(sizeof(FontHeader) + |
321 sizeof(FontDirectoryEntry) * table_count, 0); | 318 sizeof(FontDirectoryEntry) * table_count, 0); |
322 // Map the OS X font type value to a TrueType scalar type. | 319 // Map the OS X font type value to a TrueType scalar type. |
323 base::mac::ScopedCFTypeRef<CFNumberRef> font_type_ref( | 320 base::ScopedCFTypeRef<CFNumberRef> font_type_ref( |
324 base::mac::CFCast<CFNumberRef>( | 321 base::mac::CFCast<CFNumberRef>( |
325 CTFontCopyAttribute(font_ref_, kCTFontFormatAttribute))); | 322 CTFontCopyAttribute(font_ref_, kCTFontFormatAttribute))); |
326 int32_t font_type; | 323 int32_t font_type; |
327 CFNumberGetValue(font_type_ref, kCFNumberSInt32Type, &font_type); | 324 CFNumberGetValue(font_type_ref, kCFNumberSInt32Type, &font_type); |
328 switch (font_type) { | 325 switch (font_type) { |
329 case kCTFontFormatOpenTypePostScript: | 326 case kCTFontFormatOpenTypePostScript: |
330 font_type = MAKE_TABLE_TAG('O', 'T', 'T', 'O'); | 327 font_type = MAKE_TABLE_TAG('O', 'T', 'T', 'O'); |
331 break; | 328 break; |
332 case kCTFontFormatTrueType: | 329 case kCTFontFormatTrueType: |
333 case kCTFontFormatBitmap: | 330 case kCTFontFormatBitmap: |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 | 399 |
403 } // namespace | 400 } // namespace |
404 | 401 |
405 // static | 402 // static |
406 PepperTrueTypeFont* PepperTrueTypeFont::Create( | 403 PepperTrueTypeFont* PepperTrueTypeFont::Create( |
407 const ppapi::proxy::SerializedTrueTypeFontDesc& desc) { | 404 const ppapi::proxy::SerializedTrueTypeFontDesc& desc) { |
408 return new PepperTrueTypeFontMac(desc); | 405 return new PepperTrueTypeFontMac(desc); |
409 } | 406 } |
410 | 407 |
411 } // namespace content | 408 } // namespace content |
OLD | NEW |