OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkAdvancedTypefaceMetrics.h" | 8 #include "SkAdvancedTypefaceMetrics.h" |
9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
10 #include "SkCanvas.h" | 10 #include "SkCanvas.h" |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 static void* sk_ft_alloc(FT_Memory, long size) { | 69 static void* sk_ft_alloc(FT_Memory, long size) { |
70 return sk_malloc_throw(size); | 70 return sk_malloc_throw(size); |
71 } | 71 } |
72 static void sk_ft_free(FT_Memory, void* block) { | 72 static void sk_ft_free(FT_Memory, void* block) { |
73 sk_free(block); | 73 sk_free(block); |
74 } | 74 } |
75 static void* sk_ft_realloc(FT_Memory, long cur_size, long new_size, void* bl
ock) { | 75 static void* sk_ft_realloc(FT_Memory, long cur_size, long new_size, void* bl
ock) { |
76 return sk_realloc_throw(block, new_size); | 76 return sk_realloc_throw(block, new_size); |
77 } | 77 } |
78 }; | 78 }; |
79 FT_MemoryRec_ gFTMemory = { NULL, sk_ft_alloc, sk_ft_free, sk_ft_realloc }; | 79 FT_MemoryRec_ gFTMemory = { nullptr, sk_ft_alloc, sk_ft_free, sk_ft_realloc }; |
80 | 80 |
81 class FreeTypeLibrary : SkNoncopyable { | 81 class FreeTypeLibrary : SkNoncopyable { |
82 public: | 82 public: |
83 FreeTypeLibrary() : fLibrary(NULL), fIsLCDSupported(false), fLCDExtra(0) { | 83 FreeTypeLibrary() : fLibrary(nullptr), fIsLCDSupported(false), fLCDExtra(0)
{ |
84 if (FT_New_Library(&gFTMemory, &fLibrary)) { | 84 if (FT_New_Library(&gFTMemory, &fLibrary)) { |
85 return; | 85 return; |
86 } | 86 } |
87 FT_Add_Default_Modules(fLibrary); | 87 FT_Add_Default_Modules(fLibrary); |
88 | 88 |
89 // Setup LCD filtering. This reduces color fringes for LCD smoothed glyp
hs. | 89 // Setup LCD filtering. This reduces color fringes for LCD smoothed glyp
hs. |
90 // Default { 0x10, 0x40, 0x70, 0x40, 0x10 } adds up to 0x110, simulating
ink spread. | 90 // Default { 0x10, 0x40, 0x70, 0x40, 0x10 } adds up to 0x110, simulating
ink spread. |
91 // SetLcdFilter must be called before SetLcdFilterWeights. | 91 // SetLcdFilter must be called before SetLcdFilterWeights. |
92 if (FT_Library_SetLcdFilter(fLibrary, FT_LCD_FILTER_DEFAULT) == 0) { | 92 if (FT_Library_SetLcdFilter(fLibrary, FT_LCD_FILTER_DEFAULT) == 0) { |
93 fIsLCDSupported = true; | 93 fIsLCDSupported = true; |
94 fLCDExtra = 2; //Using a filter adds one full pixel to each side. | 94 fLCDExtra = 2; //Using a filter adds one full pixel to each side. |
95 | 95 |
96 #ifdef SK_FONTHOST_FREETYPE_USE_NORMAL_LCD_FILTER | 96 #ifdef SK_FONTHOST_FREETYPE_USE_NORMAL_LCD_FILTER |
97 // Adds to 0x110 simulating ink spread, but provides better results
than default. | 97 // Adds to 0x110 simulating ink spread, but provides better results
than default. |
98 static unsigned char gGaussianLikeHeavyWeights[] = { 0x1A, 0x43, 0x5
6, 0x43, 0x1A, }; | 98 static unsigned char gGaussianLikeHeavyWeights[] = { 0x1A, 0x43, 0x5
6, 0x43, 0x1A, }; |
99 | 99 |
100 # if SK_FONTHOST_FREETYPE_RUNTIME_VERSION > 0x020400 | 100 # if SK_FONTHOST_FREETYPE_RUNTIME_VERSION > 0x020400 |
101 FT_Library_SetLcdFilterWeights(fLibrary, gGaussianLikeHeavyWeights); | 101 FT_Library_SetLcdFilterWeights(fLibrary, gGaussianLikeHeavyWeights); |
102 # elif SK_CAN_USE_DLOPEN == 1 | 102 # elif SK_CAN_USE_DLOPEN == 1 |
103 //The FreeType library is already loaded, so symbols are available i
n process. | 103 //The FreeType library is already loaded, so symbols are available i
n process. |
104 void* self = dlopen(NULL, RTLD_LAZY); | 104 void* self = dlopen(nullptr, RTLD_LAZY); |
105 if (self) { | 105 if (self) { |
106 FT_Library_SetLcdFilterWeightsProc setLcdFilterWeights; | 106 FT_Library_SetLcdFilterWeightsProc setLcdFilterWeights; |
107 //The following cast is non-standard, but safe for POSIX. | 107 //The following cast is non-standard, but safe for POSIX. |
108 *reinterpret_cast<void**>(&setLcdFilterWeights) = | 108 *reinterpret_cast<void**>(&setLcdFilterWeights) = |
109 dlsym(self, "FT_Library_SetLcdFilterWeights"); | 109 dlsym(self, "FT_Library_SetLcdFilterWeights"); |
110 dlclose(self); | 110 dlclose(self); |
111 | 111 |
112 if (setLcdFilterWeights) { | 112 if (setLcdFilterWeights) { |
113 setLcdFilterWeights(fLibrary, gGaussianLikeHeavyWeights); | 113 setLcdFilterWeights(fLibrary, gGaussianLikeHeavyWeights); |
114 } | 114 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 | 150 |
151 // Private to RefFreeType and UnrefFreeType | 151 // Private to RefFreeType and UnrefFreeType |
152 static int gFTCount; | 152 static int gFTCount; |
153 | 153 |
154 // Caller must lock gFTMutex before calling this function. | 154 // Caller must lock gFTMutex before calling this function. |
155 static bool ref_ft_library() { | 155 static bool ref_ft_library() { |
156 gFTMutex.assertHeld(); | 156 gFTMutex.assertHeld(); |
157 SkASSERT(gFTCount >= 0); | 157 SkASSERT(gFTCount >= 0); |
158 | 158 |
159 if (0 == gFTCount) { | 159 if (0 == gFTCount) { |
160 SkASSERT(NULL == gFTLibrary); | 160 SkASSERT(nullptr == gFTLibrary); |
161 gFTLibrary = new FreeTypeLibrary; | 161 gFTLibrary = new FreeTypeLibrary; |
162 } | 162 } |
163 ++gFTCount; | 163 ++gFTCount; |
164 return gFTLibrary->library(); | 164 return gFTLibrary->library(); |
165 } | 165 } |
166 | 166 |
167 // Caller must lock gFTMutex before calling this function. | 167 // Caller must lock gFTMutex before calling this function. |
168 static void unref_ft_library() { | 168 static void unref_ft_library() { |
169 gFTMutex.assertHeld(); | 169 gFTMutex.assertHeld(); |
170 SkASSERT(gFTCount > 0); | 170 SkASSERT(gFTCount > 0); |
171 | 171 |
172 --gFTCount; | 172 --gFTCount; |
173 if (0 == gFTCount) { | 173 if (0 == gFTCount) { |
174 SkASSERT(NULL != gFTLibrary); | 174 SkASSERT(nullptr != gFTLibrary); |
175 delete gFTLibrary; | 175 delete gFTLibrary; |
176 SkDEBUGCODE(gFTLibrary = NULL;) | 176 SkDEBUGCODE(gFTLibrary = nullptr;) |
177 } | 177 } |
178 } | 178 } |
179 | 179 |
180 class SkScalerContext_FreeType : public SkScalerContext_FreeType_Base { | 180 class SkScalerContext_FreeType : public SkScalerContext_FreeType_Base { |
181 public: | 181 public: |
182 SkScalerContext_FreeType(SkTypeface*, const SkDescriptor* desc); | 182 SkScalerContext_FreeType(SkTypeface*, const SkDescriptor* desc); |
183 virtual ~SkScalerContext_FreeType(); | 183 virtual ~SkScalerContext_FreeType(); |
184 | 184 |
185 bool success() const { | 185 bool success() const { |
186 return fFTSize != NULL && fFace != NULL; | 186 return fFTSize != nullptr && fFace != nullptr; |
187 } | 187 } |
188 | 188 |
189 protected: | 189 protected: |
190 unsigned generateGlyphCount() override; | 190 unsigned generateGlyphCount() override; |
191 uint16_t generateCharToGlyph(SkUnichar uni) override; | 191 uint16_t generateCharToGlyph(SkUnichar uni) override; |
192 void generateAdvance(SkGlyph* glyph) override; | 192 void generateAdvance(SkGlyph* glyph) override; |
193 void generateMetrics(SkGlyph* glyph) override; | 193 void generateMetrics(SkGlyph* glyph) override; |
194 void generateImage(const SkGlyph& glyph) override; | 194 void generateImage(const SkGlyph& glyph) override; |
195 void generatePath(const SkGlyph& glyph, SkPath* path) override; | 195 void generatePath(const SkGlyph& glyph, SkPath* path) override; |
196 void generateFontMetrics(SkPaint::FontMetrics*) override; | 196 void generateFontMetrics(SkPaint::FontMetrics*) override; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
250 } | 250 } |
251 count = stream->read(buffer, count); | 251 count = stream->read(buffer, count); |
252 } | 252 } |
253 return count; | 253 return count; |
254 } | 254 } |
255 | 255 |
256 static void sk_ft_stream_close(FT_Stream) {} | 256 static void sk_ft_stream_close(FT_Stream) {} |
257 } | 257 } |
258 | 258 |
259 SkFaceRec::SkFaceRec(SkStreamAsset* stream, uint32_t fontID) | 259 SkFaceRec::SkFaceRec(SkStreamAsset* stream, uint32_t fontID) |
260 : fNext(NULL), fSkStream(stream), fRefCnt(1), fFontID(fontID) | 260 : fNext(nullptr), fSkStream(stream), fRefCnt(1), fFontID(fontID) |
261 { | 261 { |
262 sk_bzero(&fFTStream, sizeof(fFTStream)); | 262 sk_bzero(&fFTStream, sizeof(fFTStream)); |
263 fFTStream.size = fSkStream->getLength(); | 263 fFTStream.size = fSkStream->getLength(); |
264 fFTStream.descriptor.pointer = fSkStream; | 264 fFTStream.descriptor.pointer = fSkStream; |
265 fFTStream.read = sk_ft_stream_io; | 265 fFTStream.read = sk_ft_stream_io; |
266 fFTStream.close = sk_ft_stream_close; | 266 fFTStream.close = sk_ft_stream_close; |
267 } | 267 } |
268 | 268 |
269 static void ft_face_setup_axes(FT_Face face, const SkFontData& data) { | 269 static void ft_face_setup_axes(FT_Face face, const SkFontData& data) { |
270 if (!(face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) { | 270 if (!(face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) { |
271 return; | 271 return; |
272 } | 272 } |
273 | 273 |
274 SkDEBUGCODE( | 274 SkDEBUGCODE( |
275 FT_MM_Var* variations = NULL; | 275 FT_MM_Var* variations = nullptr; |
276 if (FT_Get_MM_Var(face, &variations)) { | 276 if (FT_Get_MM_Var(face, &variations)) { |
277 SkDEBUGF(("INFO: font %s claims variations, but none found.\n", face
->family_name)); | 277 SkDEBUGF(("INFO: font %s claims variations, but none found.\n", face
->family_name)); |
278 return; | 278 return; |
279 } | 279 } |
280 SkAutoFree autoFreeVariations(variations); | 280 SkAutoFree autoFreeVariations(variations); |
281 | 281 |
282 if (static_cast<FT_UInt>(data.getAxisCount()) != variations->num_axis) { | 282 if (static_cast<FT_UInt>(data.getAxisCount()) != variations->num_axis) { |
283 SkDEBUGF(("INFO: font %s has %d variations, but %d were specified.\n
", | 283 SkDEBUGF(("INFO: font %s has %d variations, but %d were specified.\n
", |
284 face->family_name, variations->num_axis, data.getAxisCount()
)); | 284 face->family_name, variations->num_axis, data.getAxisCount()
)); |
285 return; | 285 return; |
(...skipping 21 matching lines...) Expand all Loading... |
307 while (rec) { | 307 while (rec) { |
308 if (rec->fFontID == fontID) { | 308 if (rec->fFontID == fontID) { |
309 SkASSERT(rec->fFace); | 309 SkASSERT(rec->fFace); |
310 rec->fRefCnt += 1; | 310 rec->fRefCnt += 1; |
311 return rec->fFace; | 311 return rec->fFace; |
312 } | 312 } |
313 rec = rec->fNext; | 313 rec = rec->fNext; |
314 } | 314 } |
315 | 315 |
316 SkAutoTDelete<SkFontData> data(typeface->createFontData()); | 316 SkAutoTDelete<SkFontData> data(typeface->createFontData()); |
317 if (NULL == data || !data->hasStream()) { | 317 if (nullptr == data || !data->hasStream()) { |
318 return NULL; | 318 return nullptr; |
319 } | 319 } |
320 | 320 |
321 // this passes ownership of stream to the rec | 321 // this passes ownership of stream to the rec |
322 rec = new SkFaceRec(data->detachStream(), fontID); | 322 rec = new SkFaceRec(data->detachStream(), fontID); |
323 | 323 |
324 FT_Open_Args args; | 324 FT_Open_Args args; |
325 memset(&args, 0, sizeof(args)); | 325 memset(&args, 0, sizeof(args)); |
326 const void* memoryBase = rec->fSkStream->getMemoryBase(); | 326 const void* memoryBase = rec->fSkStream->getMemoryBase(); |
327 if (memoryBase) { | 327 if (memoryBase) { |
328 args.flags = FT_OPEN_MEMORY; | 328 args.flags = FT_OPEN_MEMORY; |
329 args.memory_base = (const FT_Byte*)memoryBase; | 329 args.memory_base = (const FT_Byte*)memoryBase; |
330 args.memory_size = rec->fSkStream->getLength(); | 330 args.memory_size = rec->fSkStream->getLength(); |
331 } else { | 331 } else { |
332 args.flags = FT_OPEN_STREAM; | 332 args.flags = FT_OPEN_STREAM; |
333 args.stream = &rec->fFTStream; | 333 args.stream = &rec->fFTStream; |
334 } | 334 } |
335 | 335 |
336 FT_Error err = FT_Open_Face(gFTLibrary->library(), &args, data->getIndex(),
&rec->fFace); | 336 FT_Error err = FT_Open_Face(gFTLibrary->library(), &args, data->getIndex(),
&rec->fFace); |
337 if (err) { | 337 if (err) { |
338 SkDEBUGF(("ERROR: unable to open font '%x'\n", fontID)); | 338 SkDEBUGF(("ERROR: unable to open font '%x'\n", fontID)); |
339 delete rec; | 339 delete rec; |
340 return NULL; | 340 return nullptr; |
341 } | 341 } |
342 SkASSERT(rec->fFace); | 342 SkASSERT(rec->fFace); |
343 | 343 |
344 ft_face_setup_axes(rec->fFace, *data); | 344 ft_face_setup_axes(rec->fFace, *data); |
345 | 345 |
346 // FreeType will set the charmap to the "most unicode" cmap if it exists. | 346 // FreeType will set the charmap to the "most unicode" cmap if it exists. |
347 // If there are no unicode cmaps, the charmap is set to NULL. | 347 // If there are no unicode cmaps, the charmap is set to nullptr. |
348 // However, "symbol" cmaps should also be considered "fallback unicode" cmap
s | 348 // However, "symbol" cmaps should also be considered "fallback unicode" cmap
s |
349 // because they are effectively private use area only (even if they aren't). | 349 // because they are effectively private use area only (even if they aren't). |
350 // This is the last on the fallback list at | 350 // This is the last on the fallback list at |
351 // https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cma
p.html | 351 // https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cma
p.html |
352 if (!rec->fFace->charmap) { | 352 if (!rec->fFace->charmap) { |
353 FT_Select_Charmap(rec->fFace, FT_ENCODING_MS_SYMBOL); | 353 FT_Select_Charmap(rec->fFace, FT_ENCODING_MS_SYMBOL); |
354 } | 354 } |
355 | 355 |
356 rec->fNext = gFaceRecHead; | 356 rec->fNext = gFaceRecHead; |
357 gFaceRecHead = rec; | 357 gFaceRecHead = rec; |
358 return rec->fFace; | 358 return rec->fFace; |
359 } | 359 } |
360 | 360 |
361 // Caller must lock gFTMutex before calling this function. | 361 // Caller must lock gFTMutex before calling this function. |
362 static void unref_ft_face(FT_Face face) { | 362 static void unref_ft_face(FT_Face face) { |
363 gFTMutex.assertHeld(); | 363 gFTMutex.assertHeld(); |
364 | 364 |
365 SkFaceRec* rec = gFaceRecHead; | 365 SkFaceRec* rec = gFaceRecHead; |
366 SkFaceRec* prev = NULL; | 366 SkFaceRec* prev = nullptr; |
367 while (rec) { | 367 while (rec) { |
368 SkFaceRec* next = rec->fNext; | 368 SkFaceRec* next = rec->fNext; |
369 if (rec->fFace == face) { | 369 if (rec->fFace == face) { |
370 if (--rec->fRefCnt == 0) { | 370 if (--rec->fRefCnt == 0) { |
371 if (prev) { | 371 if (prev) { |
372 prev->fNext = next; | 372 prev->fNext = next; |
373 } else { | 373 } else { |
374 gFaceRecHead = next; | 374 gFaceRecHead = next; |
375 } | 375 } |
376 FT_Done_Face(face); | 376 FT_Done_Face(face); |
377 delete rec; | 377 delete rec; |
378 } | 378 } |
379 return; | 379 return; |
380 } | 380 } |
381 prev = rec; | 381 prev = rec; |
382 rec = next; | 382 rec = next; |
383 } | 383 } |
384 SkDEBUGFAIL("shouldn't get here, face not in list"); | 384 SkDEBUGFAIL("shouldn't get here, face not in list"); |
385 } | 385 } |
386 | 386 |
387 class AutoFTAccess { | 387 class AutoFTAccess { |
388 public: | 388 public: |
389 AutoFTAccess(const SkTypeface* tf) : fFace(NULL) { | 389 AutoFTAccess(const SkTypeface* tf) : fFace(nullptr) { |
390 gFTMutex.acquire(); | 390 gFTMutex.acquire(); |
391 if (!ref_ft_library()) { | 391 if (!ref_ft_library()) { |
392 sk_throw(); | 392 sk_throw(); |
393 } | 393 } |
394 fFace = ref_ft_face(tf); | 394 fFace = ref_ft_face(tf); |
395 } | 395 } |
396 | 396 |
397 ~AutoFTAccess() { | 397 ~AutoFTAccess() { |
398 if (fFace) { | 398 if (fFace) { |
399 unref_ft_face(fFace); | 399 unref_ft_face(fFace); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 (*glyphToUnicode)[glyphIndex] = charCode; | 451 (*glyphToUnicode)[glyphIndex] = charCode; |
452 charCode = FT_Get_Next_Char(face, charCode, &glyphIndex); | 452 charCode = FT_Get_Next_Char(face, charCode, &glyphIndex); |
453 } | 453 } |
454 } | 454 } |
455 | 455 |
456 SkAdvancedTypefaceMetrics* SkTypeface_FreeType::onGetAdvancedTypefaceMetrics( | 456 SkAdvancedTypefaceMetrics* SkTypeface_FreeType::onGetAdvancedTypefaceMetrics( |
457 PerGlyphInfo perGlyphInfo, | 457 PerGlyphInfo perGlyphInfo, |
458 const uint32_t* glyphIDs, | 458 const uint32_t* glyphIDs, |
459 uint32_t glyphIDsCount) const { | 459 uint32_t glyphIDsCount) const { |
460 #if defined(SK_BUILD_FOR_MAC) | 460 #if defined(SK_BUILD_FOR_MAC) |
461 return NULL; | 461 return nullptr; |
462 #else | 462 #else |
463 AutoFTAccess fta(this); | 463 AutoFTAccess fta(this); |
464 FT_Face face = fta.face(); | 464 FT_Face face = fta.face(); |
465 if (!face) { | 465 if (!face) { |
466 return NULL; | 466 return nullptr; |
467 } | 467 } |
468 | 468 |
469 SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics; | 469 SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics; |
470 info->fFontName.set(FT_Get_Postscript_Name(face)); | 470 info->fFontName.set(FT_Get_Postscript_Name(face)); |
471 info->fFlags = SkAdvancedTypefaceMetrics::kEmpty_FontFlag; | 471 info->fFlags = SkAdvancedTypefaceMetrics::kEmpty_FontFlag; |
472 if (FT_HAS_MULTIPLE_MASTERS(face)) { | 472 if (FT_HAS_MULTIPLE_MASTERS(face)) { |
473 info->fFlags = SkTBitOr<SkAdvancedTypefaceMetrics::FontFlags>( | 473 info->fFlags = SkTBitOr<SkAdvancedTypefaceMetrics::FontFlags>( |
474 info->fFlags, SkAdvancedTypefaceMetrics::kMultiMaster_FontFlag); | 474 info->fFlags, SkAdvancedTypefaceMetrics::kMultiMaster_FontFlag); |
475 } | 475 } |
476 if (!canEmbed(face)) { | 476 if (!canEmbed(face)) { |
(...skipping 16 matching lines...) Expand all Loading... |
493 } else if (strcmp(fontType, "CID Type 1") == 0) { | 493 } else if (strcmp(fontType, "CID Type 1") == 0) { |
494 info->fType = SkAdvancedTypefaceMetrics::kType1CID_Font; | 494 info->fType = SkAdvancedTypefaceMetrics::kType1CID_Font; |
495 cid = true; | 495 cid = true; |
496 } else if (strcmp(fontType, "CFF") == 0) { | 496 } else if (strcmp(fontType, "CFF") == 0) { |
497 info->fType = SkAdvancedTypefaceMetrics::kCFF_Font; | 497 info->fType = SkAdvancedTypefaceMetrics::kCFF_Font; |
498 } else if (strcmp(fontType, "TrueType") == 0) { | 498 } else if (strcmp(fontType, "TrueType") == 0) { |
499 info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font; | 499 info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font; |
500 cid = true; | 500 cid = true; |
501 TT_Header* ttHeader; | 501 TT_Header* ttHeader; |
502 if ((ttHeader = (TT_Header*)FT_Get_Sfnt_Table(face, | 502 if ((ttHeader = (TT_Header*)FT_Get_Sfnt_Table(face, |
503 ft_sfnt_head)) != NULL) { | 503 ft_sfnt_head)) != nullptr)
{ |
504 info->fEmSize = ttHeader->Units_Per_EM; | 504 info->fEmSize = ttHeader->Units_Per_EM; |
505 } | 505 } |
506 } else { | 506 } else { |
507 info->fType = SkAdvancedTypefaceMetrics::kOther_Font; | 507 info->fType = SkAdvancedTypefaceMetrics::kOther_Font; |
508 } | 508 } |
509 | 509 |
510 info->fStyle = 0; | 510 info->fStyle = 0; |
511 if (FT_IS_FIXED_WIDTH(face)) | 511 if (FT_IS_FIXED_WIDTH(face)) |
512 info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style; | 512 info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style; |
513 if (face->style_flags & FT_STYLE_FLAG_ITALIC) | 513 if (face->style_flags & FT_STYLE_FLAG_ITALIC) |
514 info->fStyle |= SkAdvancedTypefaceMetrics::kItalic_Style; | 514 info->fStyle |= SkAdvancedTypefaceMetrics::kItalic_Style; |
515 | 515 |
516 PS_FontInfoRec ps_info; | 516 PS_FontInfoRec ps_info; |
517 TT_Postscript* tt_info; | 517 TT_Postscript* tt_info; |
518 if (FT_Get_PS_Font_Info(face, &ps_info) == 0) { | 518 if (FT_Get_PS_Font_Info(face, &ps_info) == 0) { |
519 info->fItalicAngle = ps_info.italic_angle; | 519 info->fItalicAngle = ps_info.italic_angle; |
520 } else if ((tt_info = | 520 } else if ((tt_info = |
521 (TT_Postscript*)FT_Get_Sfnt_Table(face, | 521 (TT_Postscript*)FT_Get_Sfnt_Table(face, |
522 ft_sfnt_post)) != NULL) { | 522 ft_sfnt_post)) != nullptr) { |
523 info->fItalicAngle = SkFixedToScalar(tt_info->italicAngle); | 523 info->fItalicAngle = SkFixedToScalar(tt_info->italicAngle); |
524 } else { | 524 } else { |
525 info->fItalicAngle = 0; | 525 info->fItalicAngle = 0; |
526 } | 526 } |
527 | 527 |
528 info->fAscent = face->ascender; | 528 info->fAscent = face->ascender; |
529 info->fDescent = face->descender; | 529 info->fDescent = face->descender; |
530 | 530 |
531 // Figure out a good guess for StemV - Min width of i, I, !, 1. | 531 // Figure out a good guess for StemV - Min width of i, I, !, 1. |
532 // This probably isn't very good with an italic font. | 532 // This probably isn't very good with an italic font. |
533 int16_t min_width = SHRT_MAX; | 533 int16_t min_width = SHRT_MAX; |
534 info->fStemV = 0; | 534 info->fStemV = 0; |
535 char stem_chars[] = {'i', 'I', '!', '1'}; | 535 char stem_chars[] = {'i', 'I', '!', '1'}; |
536 for (size_t i = 0; i < SK_ARRAY_COUNT(stem_chars); i++) { | 536 for (size_t i = 0; i < SK_ARRAY_COUNT(stem_chars); i++) { |
537 FT_BBox bbox; | 537 FT_BBox bbox; |
538 if (GetLetterCBox(face, stem_chars[i], &bbox)) { | 538 if (GetLetterCBox(face, stem_chars[i], &bbox)) { |
539 int16_t width = bbox.xMax - bbox.xMin; | 539 int16_t width = bbox.xMax - bbox.xMin; |
540 if (width > 0 && width < min_width) { | 540 if (width > 0 && width < min_width) { |
541 min_width = width; | 541 min_width = width; |
542 info->fStemV = min_width; | 542 info->fStemV = min_width; |
543 } | 543 } |
544 } | 544 } |
545 } | 545 } |
546 | 546 |
547 TT_PCLT* pclt_info; | 547 TT_PCLT* pclt_info; |
548 TT_OS2* os2_table; | 548 TT_OS2* os2_table; |
549 if ((pclt_info = (TT_PCLT*)FT_Get_Sfnt_Table(face, ft_sfnt_pclt)) != NULL) { | 549 if ((pclt_info = (TT_PCLT*)FT_Get_Sfnt_Table(face, ft_sfnt_pclt)) != nullptr
) { |
550 info->fCapHeight = pclt_info->CapHeight; | 550 info->fCapHeight = pclt_info->CapHeight; |
551 uint8_t serif_style = pclt_info->SerifStyle & 0x3F; | 551 uint8_t serif_style = pclt_info->SerifStyle & 0x3F; |
552 if (serif_style >= 2 && serif_style <= 6) | 552 if (serif_style >= 2 && serif_style <= 6) |
553 info->fStyle |= SkAdvancedTypefaceMetrics::kSerif_Style; | 553 info->fStyle |= SkAdvancedTypefaceMetrics::kSerif_Style; |
554 else if (serif_style >= 9 && serif_style <= 12) | 554 else if (serif_style >= 9 && serif_style <= 12) |
555 info->fStyle |= SkAdvancedTypefaceMetrics::kScript_Style; | 555 info->fStyle |= SkAdvancedTypefaceMetrics::kScript_Style; |
556 } else if (((os2_table = (TT_OS2*)FT_Get_Sfnt_Table(face, ft_sfnt_os2)) != N
ULL) && | 556 } else if (((os2_table = (TT_OS2*)FT_Get_Sfnt_Table(face, ft_sfnt_os2)) != n
ullptr) && |
557 // sCapHeight is available only when version 2 or later. | 557 // sCapHeight is available only when version 2 or later. |
558 os2_table->version != 0xFFFF && | 558 os2_table->version != 0xFFFF && |
559 os2_table->version >= 2) { | 559 os2_table->version >= 2) { |
560 info->fCapHeight = os2_table->sCapHeight; | 560 info->fCapHeight = os2_table->sCapHeight; |
561 } else { | 561 } else { |
562 // Figure out a good guess for CapHeight: average the height of M and X. | 562 // Figure out a good guess for CapHeight: average the height of M and X. |
563 FT_BBox m_bbox, x_bbox; | 563 FT_BBox m_bbox, x_bbox; |
564 bool got_m, got_x; | 564 bool got_m, got_x; |
565 got_m = GetLetterCBox(face, 'M', &m_bbox); | 565 got_m = GetLetterCBox(face, 'M', &m_bbox); |
566 got_x = GetLetterCBox(face, 'X', &x_bbox); | 566 got_x = GetLetterCBox(face, 'X', &x_bbox); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
659 (bothZero(rec.fPost2x2[0][1], rec.fPost2x2[1][0]) || | 659 (bothZero(rec.fPost2x2[0][1], rec.fPost2x2[1][0]) || |
660 bothZero(rec.fPost2x2[0][0], rec.fPost2x2[1][1])); | 660 bothZero(rec.fPost2x2[0][0], rec.fPost2x2[1][1])); |
661 } | 661 } |
662 | 662 |
663 SkScalerContext* SkTypeface_FreeType::onCreateScalerContext( | 663 SkScalerContext* SkTypeface_FreeType::onCreateScalerContext( |
664 const SkDescriptor* desc) const { | 664 const SkDescriptor* desc) const { |
665 SkScalerContext_FreeType* c = | 665 SkScalerContext_FreeType* c = |
666 new SkScalerContext_FreeType(const_cast<SkTypeface_FreeType*>(this),
desc); | 666 new SkScalerContext_FreeType(const_cast<SkTypeface_FreeType*>(this),
desc); |
667 if (!c->success()) { | 667 if (!c->success()) { |
668 delete c; | 668 delete c; |
669 c = NULL; | 669 c = nullptr; |
670 } | 670 } |
671 return c; | 671 return c; |
672 } | 672 } |
673 | 673 |
674 void SkTypeface_FreeType::onFilterRec(SkScalerContextRec* rec) const { | 674 void SkTypeface_FreeType::onFilterRec(SkScalerContextRec* rec) const { |
675 //BOGUS: http://code.google.com/p/chromium/issues/detail?id=121119 | 675 //BOGUS: http://code.google.com/p/chromium/issues/detail?id=121119 |
676 //Cap the requested size as larger sizes give bogus values. | 676 //Cap the requested size as larger sizes give bogus values. |
677 //Remove when http://code.google.com/p/skia/issues/detail?id=554 is fixed. | 677 //Remove when http://code.google.com/p/skia/issues/detail?id=554 is fixed. |
678 if (rec->fTextSize > SkIntToScalar(1 << 14)) { | 678 if (rec->fTextSize > SkIntToScalar(1 << 14)) { |
679 rec->fTextSize = SkIntToScalar(1 << 14); | 679 rec->fTextSize = SkIntToScalar(1 << 14); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
735 if (err) { | 735 if (err) { |
736 return false; | 736 return false; |
737 } | 737 } |
738 adjustments[i] = delta.x; | 738 adjustments[i] = delta.x; |
739 } | 739 } |
740 return true; | 740 return true; |
741 } | 741 } |
742 | 742 |
743 static FT_Int chooseBitmapStrike(FT_Face face, SkFixed scaleY) { | 743 static FT_Int chooseBitmapStrike(FT_Face face, SkFixed scaleY) { |
744 // early out if face is bad | 744 // early out if face is bad |
745 if (face == NULL) { | 745 if (face == nullptr) { |
746 SkDEBUGF(("chooseBitmapStrike aborted due to NULL face\n")); | 746 SkDEBUGF(("chooseBitmapStrike aborted due to nullptr face\n")); |
747 return -1; | 747 return -1; |
748 } | 748 } |
749 // determine target ppem | 749 // determine target ppem |
750 FT_Pos targetPPEM = SkFixedToFDot6(scaleY); | 750 FT_Pos targetPPEM = SkFixedToFDot6(scaleY); |
751 // find a bitmap strike equal to or just larger than the requested size | 751 // find a bitmap strike equal to or just larger than the requested size |
752 FT_Int chosenStrikeIndex = -1; | 752 FT_Int chosenStrikeIndex = -1; |
753 FT_Pos chosenPPEM = 0; | 753 FT_Pos chosenPPEM = 0; |
754 for (FT_Int strikeIndex = 0; strikeIndex < face->num_fixed_sizes; ++strikeIn
dex) { | 754 for (FT_Int strikeIndex = 0; strikeIndex < face->num_fixed_sizes; ++strikeIn
dex) { |
755 FT_Pos thisPPEM = face->available_sizes[strikeIndex].y_ppem; | 755 FT_Pos thisPPEM = face->available_sizes[strikeIndex].y_ppem; |
756 if (thisPPEM == targetPPEM) { | 756 if (thisPPEM == targetPPEM) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 : SkScalerContext_FreeType_Base(typeface, desc) | 788 : SkScalerContext_FreeType_Base(typeface, desc) |
789 { | 789 { |
790 SkAutoMutexAcquire ac(gFTMutex); | 790 SkAutoMutexAcquire ac(gFTMutex); |
791 | 791 |
792 if (!ref_ft_library()) { | 792 if (!ref_ft_library()) { |
793 sk_throw(); | 793 sk_throw(); |
794 } | 794 } |
795 | 795 |
796 // load the font file | 796 // load the font file |
797 fStrikeIndex = -1; | 797 fStrikeIndex = -1; |
798 fFTSize = NULL; | 798 fFTSize = nullptr; |
799 fFace = ref_ft_face(typeface); | 799 fFace = ref_ft_face(typeface); |
800 if (NULL == fFace) { | 800 if (nullptr == fFace) { |
801 return; | 801 return; |
802 } | 802 } |
803 | 803 |
804 fRec.computeMatrices(SkScalerContextRec::kFull_PreMatrixScale, &fScale, &fMa
trix22Scalar); | 804 fRec.computeMatrices(SkScalerContextRec::kFull_PreMatrixScale, &fScale, &fMa
trix22Scalar); |
805 fMatrix22Scalar.setSkewX(-fMatrix22Scalar.getSkewX()); | 805 fMatrix22Scalar.setSkewX(-fMatrix22Scalar.getSkewX()); |
806 fMatrix22Scalar.setSkewY(-fMatrix22Scalar.getSkewY()); | 806 fMatrix22Scalar.setSkewY(-fMatrix22Scalar.getSkewY()); |
807 | 807 |
808 fScaleX = SkScalarToFixed(fScale.fX); | 808 fScaleX = SkScalarToFixed(fScale.fX); |
809 fScaleY = SkScalarToFixed(fScale.fY); | 809 fScaleY = SkScalarToFixed(fScale.fY); |
810 fMatrix22.xx = SkScalarToFixed(fMatrix22Scalar.getScaleX()); | 810 fMatrix22.xx = SkScalarToFixed(fMatrix22Scalar.getScaleX()); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
879 } | 879 } |
880 | 880 |
881 loadFlags |= FT_LOAD_COLOR; | 881 loadFlags |= FT_LOAD_COLOR; |
882 | 882 |
883 fLoadGlyphFlags = loadFlags; | 883 fLoadGlyphFlags = loadFlags; |
884 } | 884 } |
885 | 885 |
886 FT_Error err = FT_New_Size(fFace, &fFTSize); | 886 FT_Error err = FT_New_Size(fFace, &fFTSize); |
887 if (err != 0) { | 887 if (err != 0) { |
888 SkDEBUGF(("FT_New_Size returned %x for face %s\n", err, fFace->family_na
me)); | 888 SkDEBUGF(("FT_New_Size returned %x for face %s\n", err, fFace->family_na
me)); |
889 fFace = NULL; | 889 fFace = nullptr; |
890 return; | 890 return; |
891 } | 891 } |
892 err = FT_Activate_Size(fFTSize); | 892 err = FT_Activate_Size(fFTSize); |
893 if (err != 0) { | 893 if (err != 0) { |
894 SkDEBUGF(("FT_Activate_Size(%08x, 0x%x, 0x%x) returned 0x%x\n", fFace, f
ScaleX, fScaleY, | 894 SkDEBUGF(("FT_Activate_Size(%08x, 0x%x, 0x%x) returned 0x%x\n", fFace, f
ScaleX, fScaleY, |
895 err)); | 895 err)); |
896 fFTSize = NULL; | 896 fFTSize = nullptr; |
897 return; | 897 return; |
898 } | 898 } |
899 | 899 |
900 if (FT_IS_SCALABLE(fFace)) { | 900 if (FT_IS_SCALABLE(fFace)) { |
901 err = FT_Set_Char_Size(fFace, SkFixedToFDot6(fScaleX), SkFixedToFDot6(fS
caleY), 72, 72); | 901 err = FT_Set_Char_Size(fFace, SkFixedToFDot6(fScaleX), SkFixedToFDot6(fS
caleY), 72, 72); |
902 if (err != 0) { | 902 if (err != 0) { |
903 SkDEBUGF(("FT_Set_CharSize(%08x, 0x%x, 0x%x) returned 0x%x\n", | 903 SkDEBUGF(("FT_Set_CharSize(%08x, 0x%x, 0x%x) returned 0x%x\n", |
904 fFace, fScaleX, fScaleY, err)); | 904 fFace, fScaleX, fScaleY, err)); |
905 fFace = NULL; | 905 fFace = nullptr; |
906 return; | 906 return; |
907 } | 907 } |
908 FT_Set_Transform(fFace, &fMatrix22, NULL); | 908 FT_Set_Transform(fFace, &fMatrix22, nullptr); |
909 } else if (FT_HAS_FIXED_SIZES(fFace)) { | 909 } else if (FT_HAS_FIXED_SIZES(fFace)) { |
910 fStrikeIndex = chooseBitmapStrike(fFace, fScaleY); | 910 fStrikeIndex = chooseBitmapStrike(fFace, fScaleY); |
911 if (fStrikeIndex == -1) { | 911 if (fStrikeIndex == -1) { |
912 SkDEBUGF(("no glyphs for font \"%s\" size %f?\n", | 912 SkDEBUGF(("no glyphs for font \"%s\" size %f?\n", |
913 fFace->family_name, SkFixedToScalar(fScaleY)))
; | 913 fFace->family_name, SkFixedToScalar(fScaleY)))
; |
914 } else { | 914 } else { |
915 // FreeType does no provide linear metrics for bitmap fonts. | 915 // FreeType does no provide linear metrics for bitmap fonts. |
916 linearMetrics = false; | 916 linearMetrics = false; |
917 | 917 |
918 // FreeType documentation says: | 918 // FreeType documentation says: |
919 // FT_LOAD_NO_BITMAP -- Ignore bitmap strikes when loading. | 919 // FT_LOAD_NO_BITMAP -- Ignore bitmap strikes when loading. |
920 // Bitmap-only fonts ignore this flag. | 920 // Bitmap-only fonts ignore this flag. |
921 // | 921 // |
922 // However, in FreeType 2.5.1 color bitmap only fonts do not ignore
this flag. | 922 // However, in FreeType 2.5.1 color bitmap only fonts do not ignore
this flag. |
923 // Force this flag off for bitmap only fonts. | 923 // Force this flag off for bitmap only fonts. |
924 fLoadGlyphFlags &= ~FT_LOAD_NO_BITMAP; | 924 fLoadGlyphFlags &= ~FT_LOAD_NO_BITMAP; |
925 } | 925 } |
926 } else { | 926 } else { |
927 SkDEBUGF(("unknown kind of font \"%s\" size %f?\n", | 927 SkDEBUGF(("unknown kind of font \"%s\" size %f?\n", |
928 fFace->family_name, SkFixedToScalar(fScaleY)))
; | 928 fFace->family_name, SkFixedToScalar(fScaleY)))
; |
929 } | 929 } |
930 | 930 |
931 fDoLinearMetrics = linearMetrics; | 931 fDoLinearMetrics = linearMetrics; |
932 } | 932 } |
933 | 933 |
934 SkScalerContext_FreeType::~SkScalerContext_FreeType() { | 934 SkScalerContext_FreeType::~SkScalerContext_FreeType() { |
935 SkAutoMutexAcquire ac(gFTMutex); | 935 SkAutoMutexAcquire ac(gFTMutex); |
936 | 936 |
937 if (fFTSize != NULL) { | 937 if (fFTSize != nullptr) { |
938 FT_Done_Size(fFTSize); | 938 FT_Done_Size(fFTSize); |
939 } | 939 } |
940 | 940 |
941 if (fFace != NULL) { | 941 if (fFace != nullptr) { |
942 unref_ft_face(fFace); | 942 unref_ft_face(fFace); |
943 } | 943 } |
944 | 944 |
945 unref_ft_library(); | 945 unref_ft_library(); |
946 } | 946 } |
947 | 947 |
948 /* We call this before each use of the fFace, since we may be sharing | 948 /* We call this before each use of the fFace, since we may be sharing |
949 this face with other context (at different sizes). | 949 this face with other context (at different sizes). |
950 */ | 950 */ |
951 FT_Error SkScalerContext_FreeType::setupSize() { | 951 FT_Error SkScalerContext_FreeType::setupSize() { |
952 FT_Error err = FT_Activate_Size(fFTSize); | 952 FT_Error err = FT_Activate_Size(fFTSize); |
953 if (err != 0) { | 953 if (err != 0) { |
954 SkDEBUGF(("SkScalerContext_FreeType::FT_Activate_Size(%s %s, 0x%x, 0x%x)
returned 0x%x\n", | 954 SkDEBUGF(("SkScalerContext_FreeType::FT_Activate_Size(%s %s, 0x%x, 0x%x)
returned 0x%x\n", |
955 fFace->family_name, fFace->style_name, fScaleX, fScaleY, err))
; | 955 fFace->family_name, fFace->style_name, fScaleX, fScaleY, err))
; |
956 fFTSize = NULL; | 956 fFTSize = nullptr; |
957 return err; | 957 return err; |
958 } | 958 } |
959 | 959 |
960 // seems we need to reset this every time (not sure why, but without it | 960 // seems we need to reset this every time (not sure why, but without it |
961 // I get random italics from some other fFTSize) | 961 // I get random italics from some other fFTSize) |
962 FT_Set_Transform(fFace, &fMatrix22, NULL); | 962 FT_Set_Transform(fFace, &fMatrix22, nullptr); |
963 return 0; | 963 return 0; |
964 } | 964 } |
965 | 965 |
966 unsigned SkScalerContext_FreeType::generateGlyphCount() { | 966 unsigned SkScalerContext_FreeType::generateGlyphCount() { |
967 return fFace->num_glyphs; | 967 return fFace->num_glyphs; |
968 } | 968 } |
969 | 969 |
970 uint16_t SkScalerContext_FreeType::generateCharToGlyph(SkUnichar uni) { | 970 uint16_t SkScalerContext_FreeType::generateCharToGlyph(SkUnichar uni) { |
971 return SkToU16(FT_Get_Char_Index( fFace, uni )); | 971 return SkToU16(FT_Get_Char_Index( fFace, uni )); |
972 } | 972 } |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1251 if (fRec.fFlags & SkScalerContext::kVertical_Flag) { | 1251 if (fRec.fFlags & SkScalerContext::kVertical_Flag) { |
1252 FT_Vector vector; | 1252 FT_Vector vector; |
1253 vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metrics.ho
riBearingX; | 1253 vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metrics.ho
riBearingX; |
1254 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metrics.h
oriBearingY; | 1254 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metrics.h
oriBearingY; |
1255 FT_Vector_Transform(&vector, &fMatrix22); | 1255 FT_Vector_Transform(&vector, &fMatrix22); |
1256 path->offset(SkFDot6ToScalar(vector.x), -SkFDot6ToScalar(vector.y)); | 1256 path->offset(SkFDot6ToScalar(vector.x), -SkFDot6ToScalar(vector.y)); |
1257 } | 1257 } |
1258 } | 1258 } |
1259 | 1259 |
1260 void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* metrics
) { | 1260 void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* metrics
) { |
1261 if (NULL == metrics) { | 1261 if (nullptr == metrics) { |
1262 return; | 1262 return; |
1263 } | 1263 } |
1264 | 1264 |
1265 SkAutoMutexAcquire ac(gFTMutex); | 1265 SkAutoMutexAcquire ac(gFTMutex); |
1266 | 1266 |
1267 if (this->setupSize()) { | 1267 if (this->setupSize()) { |
1268 ERROR: | 1268 ERROR: |
1269 sk_bzero(metrics, sizeof(*metrics)); | 1269 sk_bzero(metrics, sizeof(*metrics)); |
1270 return; | 1270 return; |
1271 } | 1271 } |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1466 FT_Face face = fta.face(); | 1466 FT_Face face = fta.face(); |
1467 if (!face) { | 1467 if (!face) { |
1468 if (glyphs) { | 1468 if (glyphs) { |
1469 sk_bzero(glyphs, glyphCount * sizeof(glyphs[0])); | 1469 sk_bzero(glyphs, glyphCount * sizeof(glyphs[0])); |
1470 } | 1470 } |
1471 return 0; | 1471 return 0; |
1472 } | 1472 } |
1473 | 1473 |
1474 EncodingProc next_uni_proc = find_encoding_proc(encoding); | 1474 EncodingProc next_uni_proc = find_encoding_proc(encoding); |
1475 | 1475 |
1476 if (NULL == glyphs) { | 1476 if (nullptr == glyphs) { |
1477 for (int i = 0; i < glyphCount; ++i) { | 1477 for (int i = 0; i < glyphCount; ++i) { |
1478 if (0 == FT_Get_Char_Index(face, next_uni_proc(&chars))) { | 1478 if (0 == FT_Get_Char_Index(face, next_uni_proc(&chars))) { |
1479 return i; | 1479 return i; |
1480 } | 1480 } |
1481 } | 1481 } |
1482 return glyphCount; | 1482 return glyphCount; |
1483 } else { | 1483 } else { |
1484 int first = glyphCount; | 1484 int first = glyphCount; |
1485 for (int i = 0; i < glyphCount; ++i) { | 1485 for (int i = 0; i < glyphCount; ++i) { |
1486 unsigned id = FT_Get_Char_Index(face, next_uni_proc(&chars)); | 1486 unsigned id = FT_Get_Char_Index(face, next_uni_proc(&chars)); |
(...skipping 13 matching lines...) Expand all Loading... |
1500 FT_Face face = fta.face(); | 1500 FT_Face face = fta.face(); |
1501 // if the face failed, we still assign a non-negative value | 1501 // if the face failed, we still assign a non-negative value |
1502 fGlyphCount = face ? face->num_glyphs : 0; | 1502 fGlyphCount = face ? face->num_glyphs : 0; |
1503 } | 1503 } |
1504 return fGlyphCount; | 1504 return fGlyphCount; |
1505 } | 1505 } |
1506 | 1506 |
1507 SkTypeface::LocalizedStrings* SkTypeface_FreeType::onCreateFamilyNameIterator()
const { | 1507 SkTypeface::LocalizedStrings* SkTypeface_FreeType::onCreateFamilyNameIterator()
const { |
1508 SkTypeface::LocalizedStrings* nameIter = | 1508 SkTypeface::LocalizedStrings* nameIter = |
1509 SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this); | 1509 SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this); |
1510 if (NULL == nameIter) { | 1510 if (nullptr == nameIter) { |
1511 SkString familyName; | 1511 SkString familyName; |
1512 this->getFamilyName(&familyName); | 1512 this->getFamilyName(&familyName); |
1513 SkString language("und"); //undetermined | 1513 SkString language("und"); //undetermined |
1514 nameIter = new SkOTUtils::LocalizedStrings_SingleName(familyName, langua
ge); | 1514 nameIter = new SkOTUtils::LocalizedStrings_SingleName(familyName, langua
ge); |
1515 } | 1515 } |
1516 return nameIter; | 1516 return nameIter; |
1517 } | 1517 } |
1518 | 1518 |
1519 int SkTypeface_FreeType::onGetTableTags(SkFontTableTag tags[]) const { | 1519 int SkTypeface_FreeType::onGetTableTags(SkFontTableTag tags[]) const { |
1520 AutoFTAccess fta(this); | 1520 AutoFTAccess fta(this); |
1521 FT_Face face = fta.face(); | 1521 FT_Face face = fta.face(); |
1522 | 1522 |
1523 FT_ULong tableCount = 0; | 1523 FT_ULong tableCount = 0; |
1524 FT_Error error; | 1524 FT_Error error; |
1525 | 1525 |
1526 // When 'tag' is NULL, returns number of tables in 'length'. | 1526 // When 'tag' is nullptr, returns number of tables in 'length'. |
1527 error = FT_Sfnt_Table_Info(face, 0, NULL, &tableCount); | 1527 error = FT_Sfnt_Table_Info(face, 0, nullptr, &tableCount); |
1528 if (error) { | 1528 if (error) { |
1529 return 0; | 1529 return 0; |
1530 } | 1530 } |
1531 | 1531 |
1532 if (tags) { | 1532 if (tags) { |
1533 for (FT_ULong tableIndex = 0; tableIndex < tableCount; ++tableIndex) { | 1533 for (FT_ULong tableIndex = 0; tableIndex < tableCount; ++tableIndex) { |
1534 FT_ULong tableTag; | 1534 FT_ULong tableTag; |
1535 FT_ULong tablelength; | 1535 FT_ULong tablelength; |
1536 error = FT_Sfnt_Table_Info(face, tableIndex, &tableTag, &tablelength
); | 1536 error = FT_Sfnt_Table_Info(face, tableIndex, &tableTag, &tablelength
); |
1537 if (error) { | 1537 if (error) { |
1538 return 0; | 1538 return 0; |
1539 } | 1539 } |
1540 tags[tableIndex] = static_cast<SkFontTableTag>(tableTag); | 1540 tags[tableIndex] = static_cast<SkFontTableTag>(tableTag); |
1541 } | 1541 } |
1542 } | 1542 } |
1543 return tableCount; | 1543 return tableCount; |
1544 } | 1544 } |
1545 | 1545 |
1546 size_t SkTypeface_FreeType::onGetTableData(SkFontTableTag tag, size_t offset, | 1546 size_t SkTypeface_FreeType::onGetTableData(SkFontTableTag tag, size_t offset, |
1547 size_t length, void* data) const | 1547 size_t length, void* data) const |
1548 { | 1548 { |
1549 AutoFTAccess fta(this); | 1549 AutoFTAccess fta(this); |
1550 FT_Face face = fta.face(); | 1550 FT_Face face = fta.face(); |
1551 | 1551 |
1552 FT_ULong tableLength = 0; | 1552 FT_ULong tableLength = 0; |
1553 FT_Error error; | 1553 FT_Error error; |
1554 | 1554 |
1555 // When 'length' is 0 it is overwritten with the full table length; 'offset'
is ignored. | 1555 // When 'length' is 0 it is overwritten with the full table length; 'offset'
is ignored. |
1556 error = FT_Load_Sfnt_Table(face, tag, 0, NULL, &tableLength); | 1556 error = FT_Load_Sfnt_Table(face, tag, 0, nullptr, &tableLength); |
1557 if (error) { | 1557 if (error) { |
1558 return 0; | 1558 return 0; |
1559 } | 1559 } |
1560 | 1560 |
1561 if (offset > tableLength) { | 1561 if (offset > tableLength) { |
1562 return 0; | 1562 return 0; |
1563 } | 1563 } |
1564 FT_ULong size = SkTMin((FT_ULong)length, tableLength - (FT_ULong)offset); | 1564 FT_ULong size = SkTMin((FT_ULong)length, tableLength - (FT_ULong)offset); |
1565 if (data) { | 1565 if (data) { |
1566 error = FT_Load_Sfnt_Table(face, tag, offset, reinterpret_cast<FT_Byte*>
(data), &size); | 1566 error = FT_Load_Sfnt_Table(face, tag, offset, reinterpret_cast<FT_Byte*>
(data), &size); |
1567 if (error) { | 1567 if (error) { |
1568 return 0; | 1568 return 0; |
1569 } | 1569 } |
1570 } | 1570 } |
1571 | 1571 |
1572 return size; | 1572 return size; |
1573 } | 1573 } |
1574 | 1574 |
1575 /////////////////////////////////////////////////////////////////////////////// | 1575 /////////////////////////////////////////////////////////////////////////////// |
1576 /////////////////////////////////////////////////////////////////////////////// | 1576 /////////////////////////////////////////////////////////////////////////////// |
1577 | 1577 |
1578 SkTypeface_FreeType::Scanner::Scanner() : fLibrary(NULL) { | 1578 SkTypeface_FreeType::Scanner::Scanner() : fLibrary(nullptr) { |
1579 if (FT_New_Library(&gFTMemory, &fLibrary)) { | 1579 if (FT_New_Library(&gFTMemory, &fLibrary)) { |
1580 return; | 1580 return; |
1581 } | 1581 } |
1582 FT_Add_Default_Modules(fLibrary); | 1582 FT_Add_Default_Modules(fLibrary); |
1583 } | 1583 } |
1584 SkTypeface_FreeType::Scanner::~Scanner() { | 1584 SkTypeface_FreeType::Scanner::~Scanner() { |
1585 if (fLibrary) { | 1585 if (fLibrary) { |
1586 FT_Done_Library(fLibrary); | 1586 FT_Done_Library(fLibrary); |
1587 } | 1587 } |
1588 } | 1588 } |
1589 | 1589 |
1590 FT_Face SkTypeface_FreeType::Scanner::openFace(SkStream* stream, int ttcIndex, | 1590 FT_Face SkTypeface_FreeType::Scanner::openFace(SkStream* stream, int ttcIndex, |
1591 FT_Stream ftStream) const | 1591 FT_Stream ftStream) const |
1592 { | 1592 { |
1593 if (fLibrary == NULL) { | 1593 if (fLibrary == nullptr) { |
1594 return NULL; | 1594 return nullptr; |
1595 } | 1595 } |
1596 | 1596 |
1597 FT_Open_Args args; | 1597 FT_Open_Args args; |
1598 memset(&args, 0, sizeof(args)); | 1598 memset(&args, 0, sizeof(args)); |
1599 | 1599 |
1600 const void* memoryBase = stream->getMemoryBase(); | 1600 const void* memoryBase = stream->getMemoryBase(); |
1601 | 1601 |
1602 if (memoryBase) { | 1602 if (memoryBase) { |
1603 args.flags = FT_OPEN_MEMORY; | 1603 args.flags = FT_OPEN_MEMORY; |
1604 args.memory_base = (const FT_Byte*)memoryBase; | 1604 args.memory_base = (const FT_Byte*)memoryBase; |
1605 args.memory_size = stream->getLength(); | 1605 args.memory_size = stream->getLength(); |
1606 } else { | 1606 } else { |
1607 memset(ftStream, 0, sizeof(*ftStream)); | 1607 memset(ftStream, 0, sizeof(*ftStream)); |
1608 ftStream->size = stream->getLength(); | 1608 ftStream->size = stream->getLength(); |
1609 ftStream->descriptor.pointer = stream; | 1609 ftStream->descriptor.pointer = stream; |
1610 ftStream->read = sk_ft_stream_io; | 1610 ftStream->read = sk_ft_stream_io; |
1611 ftStream->close = sk_ft_stream_close; | 1611 ftStream->close = sk_ft_stream_close; |
1612 | 1612 |
1613 args.flags = FT_OPEN_STREAM; | 1613 args.flags = FT_OPEN_STREAM; |
1614 args.stream = ftStream; | 1614 args.stream = ftStream; |
1615 } | 1615 } |
1616 | 1616 |
1617 FT_Face face; | 1617 FT_Face face; |
1618 if (FT_Open_Face(fLibrary, &args, ttcIndex, &face)) { | 1618 if (FT_Open_Face(fLibrary, &args, ttcIndex, &face)) { |
1619 return NULL; | 1619 return nullptr; |
1620 } | 1620 } |
1621 return face; | 1621 return face; |
1622 } | 1622 } |
1623 | 1623 |
1624 bool SkTypeface_FreeType::Scanner::recognizedFont(SkStream* stream, int* numFace
s) const { | 1624 bool SkTypeface_FreeType::Scanner::recognizedFont(SkStream* stream, int* numFace
s) const { |
1625 SkAutoMutexAcquire libraryLock(fLibraryMutex); | 1625 SkAutoMutexAcquire libraryLock(fLibraryMutex); |
1626 | 1626 |
1627 FT_StreamRec streamRec; | 1627 FT_StreamRec streamRec; |
1628 FT_Face face = this->openFace(stream, -1, &streamRec); | 1628 FT_Face face = this->openFace(stream, -1, &streamRec); |
1629 if (NULL == face) { | 1629 if (nullptr == face) { |
1630 return false; | 1630 return false; |
1631 } | 1631 } |
1632 | 1632 |
1633 *numFaces = face->num_faces; | 1633 *numFaces = face->num_faces; |
1634 | 1634 |
1635 FT_Done_Face(face); | 1635 FT_Done_Face(face); |
1636 return true; | 1636 return true; |
1637 } | 1637 } |
1638 | 1638 |
1639 #include "SkTSearch.h" | 1639 #include "SkTSearch.h" |
1640 bool SkTypeface_FreeType::Scanner::scanFont( | 1640 bool SkTypeface_FreeType::Scanner::scanFont( |
1641 SkStream* stream, int ttcIndex, | 1641 SkStream* stream, int ttcIndex, |
1642 SkString* name, SkFontStyle* style, bool* isFixedPitch, AxisDefinitions* axe
s) const | 1642 SkString* name, SkFontStyle* style, bool* isFixedPitch, AxisDefinitions* axe
s) const |
1643 { | 1643 { |
1644 SkAutoMutexAcquire libraryLock(fLibraryMutex); | 1644 SkAutoMutexAcquire libraryLock(fLibraryMutex); |
1645 | 1645 |
1646 FT_StreamRec streamRec; | 1646 FT_StreamRec streamRec; |
1647 FT_Face face = this->openFace(stream, ttcIndex, &streamRec); | 1647 FT_Face face = this->openFace(stream, ttcIndex, &streamRec); |
1648 if (NULL == face) { | 1648 if (nullptr == face) { |
1649 return false; | 1649 return false; |
1650 } | 1650 } |
1651 | 1651 |
1652 int weight = SkFontStyle::kNormal_Weight; | 1652 int weight = SkFontStyle::kNormal_Weight; |
1653 int width = SkFontStyle::kNormal_Width; | 1653 int width = SkFontStyle::kNormal_Width; |
1654 SkFontStyle::Slant slant = SkFontStyle::kUpright_Slant; | 1654 SkFontStyle::Slant slant = SkFontStyle::kUpright_Slant; |
1655 if (face->style_flags & FT_STYLE_FLAG_BOLD) { | 1655 if (face->style_flags & FT_STYLE_FLAG_BOLD) { |
1656 weight = SkFontStyle::kBold_Weight; | 1656 weight = SkFontStyle::kBold_Weight; |
1657 } | 1657 } |
1658 if (face->style_flags & FT_STYLE_FLAG_ITALIC) { | 1658 if (face->style_flags & FT_STYLE_FLAG_ITALIC) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1709 name->set(face->family_name); | 1709 name->set(face->family_name); |
1710 } | 1710 } |
1711 if (style) { | 1711 if (style) { |
1712 *style = SkFontStyle(weight, width, slant); | 1712 *style = SkFontStyle(weight, width, slant); |
1713 } | 1713 } |
1714 if (isFixedPitch) { | 1714 if (isFixedPitch) { |
1715 *isFixedPitch = FT_IS_FIXED_WIDTH(face); | 1715 *isFixedPitch = FT_IS_FIXED_WIDTH(face); |
1716 } | 1716 } |
1717 | 1717 |
1718 if (axes && face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS) { | 1718 if (axes && face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS) { |
1719 FT_MM_Var* variations = NULL; | 1719 FT_MM_Var* variations = nullptr; |
1720 FT_Error err = FT_Get_MM_Var(face, &variations); | 1720 FT_Error err = FT_Get_MM_Var(face, &variations); |
1721 if (err) { | 1721 if (err) { |
1722 SkDEBUGF(("INFO: font %s claims to have variations, but none found.\
n", | 1722 SkDEBUGF(("INFO: font %s claims to have variations, but none found.\
n", |
1723 face->family_name)); | 1723 face->family_name)); |
1724 return false; | 1724 return false; |
1725 } | 1725 } |
1726 SkAutoFree autoFreeVariations(variations); | 1726 SkAutoFree autoFreeVariations(variations); |
1727 | 1727 |
1728 axes->reset(variations->num_axis); | 1728 axes->reset(variations->num_axis); |
1729 for (FT_UInt i = 0; i < variations->num_axis; ++i) { | 1729 for (FT_UInt i = 0; i < variations->num_axis; ++i) { |
1730 const FT_Var_Axis& ftAxis = variations->axis[i]; | 1730 const FT_Var_Axis& ftAxis = variations->axis[i]; |
1731 (*axes)[i].fTag = ftAxis.tag; | 1731 (*axes)[i].fTag = ftAxis.tag; |
1732 (*axes)[i].fMinimum = ftAxis.minimum; | 1732 (*axes)[i].fMinimum = ftAxis.minimum; |
1733 (*axes)[i].fDefault = ftAxis.def; | 1733 (*axes)[i].fDefault = ftAxis.def; |
1734 (*axes)[i].fMaximum = ftAxis.maximum; | 1734 (*axes)[i].fMaximum = ftAxis.maximum; |
1735 } | 1735 } |
1736 } | 1736 } |
1737 | 1737 |
1738 FT_Done_Face(face); | 1738 FT_Done_Face(face); |
1739 return true; | 1739 return true; |
1740 } | 1740 } |
OLD | NEW |