Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: src/ports/SkFontHost_FreeType.cpp

Issue 1180223005: Expose SkFaceRec less. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698