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 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 SkDEBUGCODE(gFTLibrary = NULL;) | 175 SkDEBUGCODE(gFTLibrary = NULL;) |
176 } | 176 } |
177 } | 177 } |
178 | 178 |
179 class SkScalerContext_FreeType : public SkScalerContext_FreeType_Base { | 179 class SkScalerContext_FreeType : public SkScalerContext_FreeType_Base { |
180 public: | 180 public: |
181 SkScalerContext_FreeType(SkTypeface*, const SkDescriptor* desc); | 181 SkScalerContext_FreeType(SkTypeface*, const SkDescriptor* desc); |
182 virtual ~SkScalerContext_FreeType(); | 182 virtual ~SkScalerContext_FreeType(); |
183 | 183 |
184 bool success() const { | 184 bool success() const { |
185 return fFaceRec != NULL && | 185 return fFTSize != NULL && fFace != NULL; |
186 fFTSize != NULL && | |
187 fFace != NULL; | |
188 } | 186 } |
189 | 187 |
190 protected: | 188 protected: |
191 unsigned generateGlyphCount() override; | 189 unsigned generateGlyphCount() override; |
192 uint16_t generateCharToGlyph(SkUnichar uni) override; | 190 uint16_t generateCharToGlyph(SkUnichar uni) override; |
193 void generateAdvance(SkGlyph* glyph) override; | 191 void generateAdvance(SkGlyph* glyph) override; |
194 void generateMetrics(SkGlyph* glyph) override; | 192 void generateMetrics(SkGlyph* glyph) override; |
195 void generateImage(const SkGlyph& glyph) override; | 193 void generateImage(const SkGlyph& glyph) override; |
196 void generatePath(const SkGlyph& glyph, SkPath* path) override; | 194 void generatePath(const SkGlyph& glyph, SkPath* path) override; |
197 void generateFontMetrics(SkPaint::FontMetrics*) override; | 195 void generateFontMetrics(SkPaint::FontMetrics*) override; |
198 SkUnichar generateGlyphToChar(uint16_t glyph) override; | 196 SkUnichar generateGlyphToChar(uint16_t glyph) override; |
199 | 197 |
200 private: | 198 private: |
201 SkFaceRec* fFaceRec; | |
202 FT_Face fFace; // reference to shared face in gFaceRecHead | 199 FT_Face fFace; // reference to shared face in gFaceRecHead |
203 FT_Size fFTSize; // our own copy | 200 FT_Size fFTSize; // our own copy |
204 FT_Int fStrikeIndex; | 201 FT_Int fStrikeIndex; |
205 SkFixed fScaleX, fScaleY; | 202 SkFixed fScaleX, fScaleY; |
206 FT_Matrix fMatrix22; | 203 FT_Matrix fMatrix22; |
207 uint32_t fLoadGlyphFlags; | 204 uint32_t fLoadGlyphFlags; |
208 bool fDoLinearMetrics; | 205 bool fDoLinearMetrics; |
209 bool fLCDIsVert; | 206 bool fLCDIsVert; |
210 | 207 |
211 // Need scalar versions for generateFontMetrics | 208 // Need scalar versions for generateFontMetrics |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 } | 291 } |
295 if (FT_Set_Var_Design_Coordinates(face, data.getAxisCount(), coords.get()))
{ | 292 if (FT_Set_Var_Design_Coordinates(face, data.getAxisCount(), coords.get()))
{ |
296 SkDEBUGF(("INFO: font %s has variations, but specified variations could
not be set.\n", | 293 SkDEBUGF(("INFO: font %s has variations, but specified variations could
not be set.\n", |
297 face->family_name)); | 294 face->family_name)); |
298 return; | 295 return; |
299 } | 296 } |
300 } | 297 } |
301 | 298 |
302 // Will return 0 on failure | 299 // Will return 0 on failure |
303 // Caller must lock gFTMutex before calling this function. | 300 // Caller must lock gFTMutex before calling this function. |
304 static SkFaceRec* ref_ft_face(const SkTypeface* typeface) { | 301 static FT_Face ref_ft_face(const SkTypeface* typeface) { |
305 gFTMutex.assertHeld(); | 302 gFTMutex.assertHeld(); |
306 | 303 |
307 const SkFontID fontID = typeface->uniqueID(); | 304 const SkFontID fontID = typeface->uniqueID(); |
308 SkFaceRec* rec = gFaceRecHead; | 305 SkFaceRec* rec = gFaceRecHead; |
309 while (rec) { | 306 while (rec) { |
310 if (rec->fFontID == fontID) { | 307 if (rec->fFontID == fontID) { |
311 SkASSERT(rec->fFace); | 308 SkASSERT(rec->fFace); |
312 rec->fRefCnt += 1; | 309 rec->fRefCnt += 1; |
313 return rec; | 310 return rec->fFace; |
314 } | 311 } |
315 rec = rec->fNext; | 312 rec = rec->fNext; |
316 } | 313 } |
317 | 314 |
318 SkAutoTDelete<SkFontData> data(typeface->createFontData()); | 315 SkAutoTDelete<SkFontData> data(typeface->createFontData()); |
319 if (NULL == data || !data->hasStream()) { | 316 if (NULL == data || !data->hasStream()) { |
320 return NULL; | 317 return NULL; |
321 } | 318 } |
322 | 319 |
323 // this passes ownership of stream to the rec | 320 // this passes ownership of stream to the rec |
(...skipping 26 matching lines...) Expand all Loading... |
350 // However, "symbol" cmaps should also be considered "fallback unicode" cmap
s | 347 // However, "symbol" cmaps should also be considered "fallback unicode" cmap
s |
351 // because they are effectively private use area only (even if they aren't). | 348 // because they are effectively private use area only (even if they aren't). |
352 // This is the last on the fallback list at | 349 // This is the last on the fallback list at |
353 // https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cma
p.html | 350 // https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cma
p.html |
354 if (!rec->fFace->charmap) { | 351 if (!rec->fFace->charmap) { |
355 FT_Select_Charmap(rec->fFace, FT_ENCODING_MS_SYMBOL); | 352 FT_Select_Charmap(rec->fFace, FT_ENCODING_MS_SYMBOL); |
356 } | 353 } |
357 | 354 |
358 rec->fNext = gFaceRecHead; | 355 rec->fNext = gFaceRecHead; |
359 gFaceRecHead = rec; | 356 gFaceRecHead = rec; |
360 return rec; | 357 return rec->fFace; |
361 } | 358 } |
362 | 359 |
363 // Caller must lock gFTMutex before calling this function. | 360 // Caller must lock gFTMutex before calling this function. |
364 static void unref_ft_face(FT_Face face) { | 361 static void unref_ft_face(FT_Face face) { |
365 gFTMutex.assertHeld(); | 362 gFTMutex.assertHeld(); |
366 | 363 |
367 SkFaceRec* rec = gFaceRecHead; | 364 SkFaceRec* rec = gFaceRecHead; |
368 SkFaceRec* prev = NULL; | 365 SkFaceRec* prev = NULL; |
369 while (rec) { | 366 while (rec) { |
370 SkFaceRec* next = rec->fNext; | 367 SkFaceRec* next = rec->fNext; |
(...skipping 10 matching lines...) Expand all Loading... |
381 return; | 378 return; |
382 } | 379 } |
383 prev = rec; | 380 prev = rec; |
384 rec = next; | 381 rec = next; |
385 } | 382 } |
386 SkDEBUGFAIL("shouldn't get here, face not in list"); | 383 SkDEBUGFAIL("shouldn't get here, face not in list"); |
387 } | 384 } |
388 | 385 |
389 class AutoFTAccess { | 386 class AutoFTAccess { |
390 public: | 387 public: |
391 AutoFTAccess(const SkTypeface* tf) : fRec(NULL), fFace(NULL) { | 388 AutoFTAccess(const SkTypeface* tf) : fFace(NULL) { |
392 gFTMutex.acquire(); | 389 gFTMutex.acquire(); |
393 if (!ref_ft_library()) { | 390 if (!ref_ft_library()) { |
394 sk_throw(); | 391 sk_throw(); |
395 } | 392 } |
396 fRec = ref_ft_face(tf); | 393 fFace = ref_ft_face(tf); |
397 if (fRec) { | |
398 fFace = fRec->fFace; | |
399 } | |
400 } | 394 } |
401 | 395 |
402 ~AutoFTAccess() { | 396 ~AutoFTAccess() { |
403 if (fFace) { | 397 if (fFace) { |
404 unref_ft_face(fFace); | 398 unref_ft_face(fFace); |
405 } | 399 } |
406 unref_ft_library(); | 400 unref_ft_library(); |
407 gFTMutex.release(); | 401 gFTMutex.release(); |
408 } | 402 } |
409 | 403 |
410 SkFaceRec* rec() { return fRec; } | |
411 FT_Face face() { return fFace; } | 404 FT_Face face() { return fFace; } |
412 | 405 |
413 private: | 406 private: |
414 SkFaceRec* fRec; | |
415 FT_Face fFace; | 407 FT_Face fFace; |
416 }; | 408 }; |
417 | 409 |
418 /////////////////////////////////////////////////////////////////////////// | 410 /////////////////////////////////////////////////////////////////////////// |
419 | 411 |
420 static bool canEmbed(FT_Face face) { | 412 static bool canEmbed(FT_Face face) { |
421 FT_UShort fsType = FT_Get_FSType_Flags(face); | 413 FT_UShort fsType = FT_Get_FSType_Flags(face); |
422 return (fsType & (FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING | | 414 return (fsType & (FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING | |
423 FT_FSTYPE_BITMAP_EMBEDDING_ONLY)) == 0; | 415 FT_FSTYPE_BITMAP_EMBEDDING_ONLY)) == 0; |
424 } | 416 } |
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
785 FT_Error err = FT_Select_Size(face, chosenStrikeIndex); | 777 FT_Error err = FT_Select_Size(face, chosenStrikeIndex); |
786 if (err != 0) { | 778 if (err != 0) { |
787 SkDEBUGF(("FT_Select_Size(%s, %d) returned 0x%x\n", face->family_nam
e, | 779 SkDEBUGF(("FT_Select_Size(%s, %d) returned 0x%x\n", face->family_nam
e, |
788 chosenStrikeIndex, err)); | 780 chosenStrikeIndex, err)); |
789 chosenStrikeIndex = -1; | 781 chosenStrikeIndex = -1; |
790 } | 782 } |
791 } | 783 } |
792 return chosenStrikeIndex; | 784 return chosenStrikeIndex; |
793 } | 785 } |
794 | 786 |
795 SkScalerContext_FreeType::SkScalerContext_FreeType(SkTypeface* typeface, | 787 SkScalerContext_FreeType::SkScalerContext_FreeType(SkTypeface* typeface, const S
kDescriptor* desc) |
796 const SkDescriptor* desc) | 788 : SkScalerContext_FreeType_Base(typeface, desc) |
797 : SkScalerContext_FreeType_Base(typeface, desc) { | 789 { |
798 SkAutoMutexAcquire ac(gFTMutex); | 790 SkAutoMutexAcquire ac(gFTMutex); |
799 | 791 |
800 if (!ref_ft_library()) { | 792 if (!ref_ft_library()) { |
801 sk_throw(); | 793 sk_throw(); |
802 } | 794 } |
803 | 795 |
804 // load the font file | 796 // load the font file |
805 fStrikeIndex = -1; | 797 fStrikeIndex = -1; |
806 fFTSize = NULL; | 798 fFTSize = NULL; |
807 fFace = NULL; | 799 fFace = ref_ft_face(typeface); |
808 fFaceRec = ref_ft_face(typeface); | 800 if (NULL == fFace) { |
809 if (NULL == fFaceRec) { | |
810 return; | 801 return; |
811 } | 802 } |
812 fFace = fFaceRec->fFace; | |
813 | 803 |
814 fRec.computeMatrices(SkScalerContextRec::kFull_PreMatrixScale, &fScale, &fMa
trix22Scalar); | 804 fRec.computeMatrices(SkScalerContextRec::kFull_PreMatrixScale, &fScale, &fMa
trix22Scalar); |
815 fMatrix22Scalar.setSkewX(-fMatrix22Scalar.getSkewX()); | 805 fMatrix22Scalar.setSkewX(-fMatrix22Scalar.getSkewX()); |
816 fMatrix22Scalar.setSkewY(-fMatrix22Scalar.getSkewY()); | 806 fMatrix22Scalar.setSkewY(-fMatrix22Scalar.getSkewY()); |
817 | 807 |
818 fScaleX = SkScalarToFixed(fScale.fX); | 808 fScaleX = SkScalarToFixed(fScale.fX); |
819 fScaleY = SkScalarToFixed(fScale.fY); | 809 fScaleY = SkScalarToFixed(fScale.fY); |
820 fMatrix22.xx = SkScalarToFixed(fMatrix22Scalar.getScaleX()); | 810 fMatrix22.xx = SkScalarToFixed(fMatrix22Scalar.getScaleX()); |
821 fMatrix22.xy = SkScalarToFixed(fMatrix22Scalar.getSkewX()); | 811 fMatrix22.xy = SkScalarToFixed(fMatrix22Scalar.getSkewX()); |
822 fMatrix22.yx = SkScalarToFixed(fMatrix22Scalar.getSkewY()); | 812 fMatrix22.yx = SkScalarToFixed(fMatrix22Scalar.getSkewY()); |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
954 | 944 |
955 unref_ft_library(); | 945 unref_ft_library(); |
956 } | 946 } |
957 | 947 |
958 /* 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 |
959 this face with other context (at different sizes). | 949 this face with other context (at different sizes). |
960 */ | 950 */ |
961 FT_Error SkScalerContext_FreeType::setupSize() { | 951 FT_Error SkScalerContext_FreeType::setupSize() { |
962 FT_Error err = FT_Activate_Size(fFTSize); | 952 FT_Error err = FT_Activate_Size(fFTSize); |
963 if (err != 0) { | 953 if (err != 0) { |
964 SkDEBUGF(("SkScalerContext_FreeType::FT_Activate_Size(%x, 0x%x, 0x%x) re
turned 0x%x\n", | 954 SkDEBUGF(("SkScalerContext_FreeType::FT_Activate_Size(%s %s, 0x%x, 0x%x)
returned 0x%x\n", |
965 fFaceRec->fFontID, fScaleX, fScaleY, err)); | 955 fFace->family_name, fFace->style_name, fScaleX, fScaleY, err))
; |
966 fFTSize = NULL; | 956 fFTSize = NULL; |
967 return err; | 957 return err; |
968 } | 958 } |
969 | 959 |
970 // 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 |
971 // I get random italics from some other fFTSize) | 961 // I get random italics from some other fFTSize) |
972 FT_Set_Transform(fFace, &fMatrix22, NULL); | 962 FT_Set_Transform(fFace, &fMatrix22, NULL); |
973 return 0; | 963 return 0; |
974 } | 964 } |
975 | 965 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1105 | 1095 |
1106 void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph) { | 1096 void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph) { |
1107 SkAutoMutexAcquire ac(gFTMutex); | 1097 SkAutoMutexAcquire ac(gFTMutex); |
1108 | 1098 |
1109 glyph->fRsbDelta = 0; | 1099 glyph->fRsbDelta = 0; |
1110 glyph->fLsbDelta = 0; | 1100 glyph->fLsbDelta = 0; |
1111 | 1101 |
1112 FT_Error err; | 1102 FT_Error err; |
1113 | 1103 |
1114 if (this->setupSize()) { | 1104 if (this->setupSize()) { |
1115 goto ERROR; | 1105 glyph->zeroMetrics(); |
| 1106 return; |
1116 } | 1107 } |
1117 | 1108 |
1118 err = FT_Load_Glyph( fFace, glyph->getGlyphID(), fLoadGlyphFlags ); | 1109 err = FT_Load_Glyph( fFace, glyph->getGlyphID(), fLoadGlyphFlags ); |
1119 if (err != 0) { | 1110 if (err != 0) { |
1120 #if 0 | |
1121 SkDEBUGF(("SkScalerContext_FreeType::generateMetrics(%x): FT_Load_Glyph(
glyph:%d flags:%x) returned 0x%x\n", | |
1122 fFaceRec->fFontID, glyph->getGlyphID(), fLoadGlyphFlags, err
)); | |
1123 #endif | |
1124 ERROR: | |
1125 glyph->zeroMetrics(); | 1111 glyph->zeroMetrics(); |
1126 return; | 1112 return; |
1127 } | 1113 } |
1128 emboldenIfNeeded(fFace, fFace->glyph); | 1114 emboldenIfNeeded(fFace, fFace->glyph); |
1129 | 1115 |
1130 switch ( fFace->glyph->format ) { | 1116 switch ( fFace->glyph->format ) { |
1131 case FT_GLYPH_FORMAT_OUTLINE: | 1117 case FT_GLYPH_FORMAT_OUTLINE: |
1132 if (0 == fFace->glyph->outline.n_contours) { | 1118 if (0 == fFace->glyph->outline.n_contours) { |
1133 glyph->fWidth = 0; | 1119 glyph->fWidth = 0; |
1134 glyph->fHeight = 0; | 1120 glyph->fHeight = 0; |
(...skipping 27 matching lines...) Expand all Loading... |
1162 } | 1148 } |
1163 | 1149 |
1164 glyph->fWidth = SkToU16(fFace->glyph->bitmap.width); | 1150 glyph->fWidth = SkToU16(fFace->glyph->bitmap.width); |
1165 glyph->fHeight = SkToU16(fFace->glyph->bitmap.rows); | 1151 glyph->fHeight = SkToU16(fFace->glyph->bitmap.rows); |
1166 glyph->fTop = -SkToS16(fFace->glyph->bitmap_top); | 1152 glyph->fTop = -SkToS16(fFace->glyph->bitmap_top); |
1167 glyph->fLeft = SkToS16(fFace->glyph->bitmap_left); | 1153 glyph->fLeft = SkToS16(fFace->glyph->bitmap_left); |
1168 break; | 1154 break; |
1169 | 1155 |
1170 default: | 1156 default: |
1171 SkDEBUGFAIL("unknown glyph format"); | 1157 SkDEBUGFAIL("unknown glyph format"); |
1172 goto ERROR; | 1158 glyph->zeroMetrics(); |
| 1159 return; |
1173 } | 1160 } |
1174 | 1161 |
1175 if (fRec.fFlags & SkScalerContext::kVertical_Flag) { | 1162 if (fRec.fFlags & SkScalerContext::kVertical_Flag) { |
1176 if (fDoLinearMetrics) { | 1163 if (fDoLinearMetrics) { |
1177 glyph->fAdvanceX = -SkFixedMul(fMatrix22.xy, fFace->glyph->linearVer
tAdvance); | 1164 glyph->fAdvanceX = -SkFixedMul(fMatrix22.xy, fFace->glyph->linearVer
tAdvance); |
1178 glyph->fAdvanceY = SkFixedMul(fMatrix22.yy, fFace->glyph->linearVert
Advance); | 1165 glyph->fAdvanceY = SkFixedMul(fMatrix22.yy, fFace->glyph->linearVert
Advance); |
1179 } else { | 1166 } else { |
1180 glyph->fAdvanceX = -SkFDot6ToFixed(fFace->glyph->advance.x); | 1167 glyph->fAdvanceX = -SkFDot6ToFixed(fFace->glyph->advance.x); |
1181 glyph->fAdvanceY = SkFDot6ToFixed(fFace->glyph->advance.y); | 1168 glyph->fAdvanceY = SkFDot6ToFixed(fFace->glyph->advance.y); |
1182 } | 1169 } |
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1744 (*axes)[i].fTag = ftAxis.tag; | 1731 (*axes)[i].fTag = ftAxis.tag; |
1745 (*axes)[i].fMinimum = ftAxis.minimum; | 1732 (*axes)[i].fMinimum = ftAxis.minimum; |
1746 (*axes)[i].fDefault = ftAxis.def; | 1733 (*axes)[i].fDefault = ftAxis.def; |
1747 (*axes)[i].fMaximum = ftAxis.maximum; | 1734 (*axes)[i].fMaximum = ftAxis.maximum; |
1748 } | 1735 } |
1749 } | 1736 } |
1750 | 1737 |
1751 FT_Done_Face(face); | 1738 FT_Done_Face(face); |
1752 return true; | 1739 return true; |
1753 } | 1740 } |
OLD | NEW |