| 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 |