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

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

Issue 103923002: Speed up generateImage by re-using the outline/bitmap that has already been loaded. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | src/ports/SkFontHost_FreeType_common.h » ('j') | 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 /* 2 /*
3 * Copyright 2006 The Android Open Source Project 3 * Copyright 2006 The Android Open Source Project
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include "SkBitmap.h" 9 #include "SkBitmap.h"
10 #include "SkCanvas.h" 10 #include "SkCanvas.h"
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 private: 183 private:
184 SkFaceRec* fFaceRec; 184 SkFaceRec* fFaceRec;
185 FT_Face fFace; // reference to shared face in gFaceRecHead 185 FT_Face fFace; // reference to shared face in gFaceRecHead
186 FT_Size fFTSize; // our own copy 186 FT_Size fFTSize; // our own copy
187 SkFixed fScaleX, fScaleY; 187 SkFixed fScaleX, fScaleY;
188 FT_Matrix fMatrix22; 188 FT_Matrix fMatrix22;
189 uint32_t fLoadGlyphFlags; 189 uint32_t fLoadGlyphFlags;
190 bool fDoLinearMetrics; 190 bool fDoLinearMetrics;
191 bool fLCDIsVert; 191 bool fLCDIsVert;
192 192
193 // since different scalercontext may share the same face
194 // using a ID to identify which settings are activated
195 // this can help us to skip some unnecessary FreeType2 calls
196 uint32_t fUniqueID;
197
193 // Need scalar versions for generateFontMetrics 198 // Need scalar versions for generateFontMetrics
194 SkVector fScale; 199 SkVector fScale;
195 SkMatrix fMatrix22Scalar; 200 SkMatrix fMatrix22Scalar;
196 201
197 FT_Error setupSize(); 202 FT_Error setupSize();
198 void getBBoxForCurrentGlyph(SkGlyph* glyph, FT_BBox* bbox, 203 void getBBoxForCurrentGlyph(SkGlyph* glyph, FT_BBox* bbox,
199 bool snapToPixelBoundary = false); 204 bool snapToPixelBoundary = false);
200 // Caller must lock gFTMutex before calling this function. 205 // Caller must lock gFTMutex before calling this function.
201 void updateGlyphIfLCD(SkGlyph* glyph); 206 void updateGlyphIfLCD(SkGlyph* glyph);
202 }; 207 };
203 208
204 /////////////////////////////////////////////////////////////////////////// 209 ///////////////////////////////////////////////////////////////////////////
205 /////////////////////////////////////////////////////////////////////////// 210 ///////////////////////////////////////////////////////////////////////////
206 211
207 struct SkFaceRec { 212 struct SkFaceRec {
208 SkFaceRec* fNext; 213 SkFaceRec* fNext;
209 FT_Face fFace; 214 FT_Face fFace;
210 FT_StreamRec fFTStream; 215 FT_StreamRec fFTStream;
211 SkStream* fSkStream; 216 SkStream* fSkStream;
212 uint32_t fRefCnt; 217 uint32_t fRefCnt;
213 uint32_t fFontID; 218 uint32_t fFontID;
214 219
220 // record some information about the last glyph loaded
221 // drawText will generateImage just after generateMetrics in most cases
222 // a simple check can help us to skip the unnecessary call to FT_Load_Glyph
223 // which is time consuming, especially for composite glyphs
224 uint32_t fActivatedContextID;
225 // glyph that has been already loaded, which is also ready for generateImage
226 uint16_t fGlyphLoaded;
227
215 // assumes ownership of the stream, will call unref() when its done 228 // assumes ownership of the stream, will call unref() when its done
216 SkFaceRec(SkStream* strm, uint32_t fontID); 229 SkFaceRec(SkStream* strm, uint32_t fontID);
217 ~SkFaceRec() { 230 ~SkFaceRec() {
218 fSkStream->unref(); 231 fSkStream->unref();
219 } 232 }
220 }; 233 };
221 234
222 extern "C" { 235 extern "C" {
223 static unsigned long sk_stream_read(FT_Stream stream, 236 static unsigned long sk_stream_read(FT_Stream stream,
224 unsigned long offset, 237 unsigned long offset,
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 AutoFTAccess(const SkTypeface* tf) : fRec(NULL), fFace(NULL) { 355 AutoFTAccess(const SkTypeface* tf) : fRec(NULL), fFace(NULL) {
343 gFTMutex.acquire(); 356 gFTMutex.acquire();
344 if (1 == ++gFTCount) { 357 if (1 == ++gFTCount) {
345 if (!InitFreetype()) { 358 if (!InitFreetype()) {
346 sk_throw(); 359 sk_throw();
347 } 360 }
348 } 361 }
349 fRec = ref_ft_face(tf); 362 fRec = ref_ft_face(tf);
350 if (fRec) { 363 if (fRec) {
351 fFace = fRec->fFace; 364 fFace = fRec->fFace;
365 // someone will access to the FreeType face
366 fRec->fActivatedContextID = 0;
367 fRec->fGlyphLoaded = 0;
352 } 368 }
353 } 369 }
354 370
355 ~AutoFTAccess() { 371 ~AutoFTAccess() {
356 if (fFace) { 372 if (fFace) {
357 unref_ft_face(fFace); 373 unref_ft_face(fFace);
358 } 374 }
359 if (0 == --gFTCount) { 375 if (0 == --gFTCount) {
360 FT_Done_FreeType(gFTLibrary); 376 FT_Done_FreeType(gFTLibrary);
361 } 377 }
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 781
766 // load the font file 782 // load the font file
767 fFTSize = NULL; 783 fFTSize = NULL;
768 fFace = NULL; 784 fFace = NULL;
769 fFaceRec = ref_ft_face(typeface); 785 fFaceRec = ref_ft_face(typeface);
770 if (NULL == fFaceRec) { 786 if (NULL == fFaceRec) {
771 return; 787 return;
772 } 788 }
773 fFace = fFaceRec->fFace; 789 fFace = fFaceRec->fFace;
774 790
791 // set ID for current scaler context
792 // start from 1, regarding 0 as invalid
793 static uint32_t gScalerContextID = 1;
794 fUniqueID = gScalerContextID++;
795
775 // compute our factors from the record 796 // compute our factors from the record
776 797
777 SkMatrix m; 798 SkMatrix m;
778 799
779 fRec.getSingleMatrix(&m); 800 fRec.getSingleMatrix(&m);
780 801
781 #ifdef DUMP_STRIKE_CREATION 802 #ifdef DUMP_STRIKE_CREATION
782 SkString keyString; 803 SkString keyString;
783 SkFontHost::GetDescriptorKeyString(desc, &keyString); 804 SkFontHost::GetDescriptorKeyString(desc, &keyString);
784 printf("========== strike [%g %g %g] [%g %g %g %g] hints %d format %d %s\n", SkScalarToFloat(fRec.fTextSize), 805 printf("========== strike [%g %g %g] [%g %g %g %g] hints %d format %d %s\n", SkScalarToFloat(fRec.fTextSize),
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
885 906
886 fLoadGlyphFlags = loadFlags; 907 fLoadGlyphFlags = loadFlags;
887 fDoLinearMetrics = linearMetrics; 908 fDoLinearMetrics = linearMetrics;
888 } 909 }
889 910
890 // now create the FT_Size 911 // now create the FT_Size
891 912
892 { 913 {
893 FT_Error err; 914 FT_Error err;
894 915
916 // no activated scaler context setting for the face
917 fFaceRec->fActivatedContextID = 0;
918 // regarding glyph 0 as an invalid glyph outline that we need to reload
919 fFaceRec->fGlyphLoaded = 0;
920
895 err = FT_New_Size(fFace, &fFTSize); 921 err = FT_New_Size(fFace, &fFTSize);
896 if (err != 0) { 922 if (err != 0) {
897 SkDEBUGF(("SkScalerContext_FreeType::FT_New_Size(%x): FT_Set_Char_Si ze(0x%x, 0x%x) returned 0x%x\n", 923 SkDEBUGF(("SkScalerContext_FreeType::FT_New_Size(%x): FT_Set_Char_Si ze(0x%x, 0x%x) returned 0x%x\n",
898 fFaceRec->fFontID, fScaleX, fScaleY, err)); 924 fFaceRec->fFontID, fScaleX, fScaleY, err));
899 fFace = NULL; 925 fFace = NULL;
900 return; 926 return;
901 } 927 }
902 928
903 err = FT_Activate_Size(fFTSize); 929 err = FT_Activate_Size(fFTSize);
904 if (err != 0) { 930 if (err != 0) {
905 SkDEBUGF(("SkScalerContext_FreeType::FT_Activate_Size(%x, 0x%x, 0x%x ) returned 0x%x\n", 931 SkDEBUGF(("SkScalerContext_FreeType::FT_Activate_Size(%x, 0x%x, 0x%x ) returned 0x%x\n",
906 fFaceRec->fFontID, fScaleX, fScaleY, err)); 932 fFaceRec->fFontID, fScaleX, fScaleY, err));
907 fFTSize = NULL; 933 fFTSize = NULL;
908 } 934 }
909 935
910 err = FT_Set_Char_Size( fFace, 936 err = FT_Set_Char_Size( fFace,
911 SkFixedToFDot6(fScaleX), SkFixedToFDot6(fScaleY) , 937 SkFixedToFDot6(fScaleX), SkFixedToFDot6(fScaleY) ,
912 72, 72); 938 72, 72);
913 if (err != 0) { 939 if (err != 0) {
914 SkDEBUGF(("SkScalerContext_FreeType::FT_Set_Char_Size(%x, 0x%x, 0x%x ) returned 0x%x\n", 940 SkDEBUGF(("SkScalerContext_FreeType::FT_Set_Char_Size(%x, 0x%x, 0x%x ) returned 0x%x\n",
915 fFaceRec->fFontID, fScaleX, fScaleY, err)); 941 fFaceRec->fFontID, fScaleX, fScaleY, err));
916 fFace = NULL; 942 fFace = NULL;
917 return; 943 return;
918 } 944 }
919 945
920 FT_Set_Transform( fFace, &fMatrix22, NULL); 946 FT_Set_Transform( fFace, &fMatrix22, NULL);
947
948 // current scaler context setting is enabled for the face
949 fFaceRec->fActivatedContextID = fUniqueID;
921 } 950 }
922 } 951 }
923 952
924 SkScalerContext_FreeType::~SkScalerContext_FreeType() { 953 SkScalerContext_FreeType::~SkScalerContext_FreeType() {
925 SkAutoMutexAcquire ac(gFTMutex); 954 SkAutoMutexAcquire ac(gFTMutex);
926 955
927 if (fFTSize != NULL) { 956 if (fFTSize != NULL) {
928 FT_Done_Size(fFTSize); 957 FT_Done_Size(fFTSize);
929 } 958 }
930 959
931 if (fFace != NULL) { 960 if (fFace != NULL) {
932 unref_ft_face(fFace); 961 unref_ft_face(fFace);
933 } 962 }
934 if (--gFTCount == 0) { 963 if (--gFTCount == 0) {
935 // SkDEBUGF(("FT_Done_FreeType\n")); 964 // SkDEBUGF(("FT_Done_FreeType\n"));
936 FT_Done_FreeType(gFTLibrary); 965 FT_Done_FreeType(gFTLibrary);
937 SkDEBUGCODE(gFTLibrary = NULL;) 966 SkDEBUGCODE(gFTLibrary = NULL;)
938 } 967 }
939 } 968 }
940 969
941 /* We call this before each use of the fFace, since we may be sharing 970 /* We call this before each use of the fFace, since we may be sharing
942 this face with other context (at different sizes). 971 this face with other context (at different sizes).
943 */ 972 */
944 FT_Error SkScalerContext_FreeType::setupSize() { 973 FT_Error SkScalerContext_FreeType::setupSize() {
945 FT_Error err = FT_Activate_Size(fFTSize); 974 FT_Error err = 0;
946 975
947 if (err != 0) { 976 if (fFaceRec->fActivatedContextID != fUniqueID) {
948 SkDEBUGF(("SkScalerContext_FreeType::FT_Activate_Size(%x, 0x%x, 0x%x) re turned 0x%x\n", 977 // no scalercontext settings are activated for the FreeType face now
949 fFaceRec->fFontID, fScaleX, fScaleY, err)); 978 fFaceRec->fActivatedContextID = 0;
950 fFTSize = NULL; 979 fFaceRec->fGlyphLoaded = 0;
951 } else { 980 err = FT_Activate_Size(fFTSize);
952 // seems we need to reset this every time (not sure why, but without it 981 if (err != 0) {
953 // I get random italics from some other fFTSize) 982 SkDEBUGF(("SkScalerContext_FreeType::FT_Activate_Size(%x, 0x%x, 0x%x ) returned 0x%x\n",
954 FT_Set_Transform( fFace, &fMatrix22, NULL); 983 fFaceRec->fFontID, fScaleX, fScaleY, err));
984 fFTSize = NULL;
985 } else {
986 // seems we need to reset this every time (not sure why, but without it
987 // I get random italics from some other fFTSize)
988 FT_Set_Transform( fFace, &fMatrix22, NULL);
989 // current scalercontext settings are activated
990 fFaceRec->fActivatedContextID = fUniqueID;
991 }
955 } 992 }
956 return err; 993 return err;
957 } 994 }
958 995
959 unsigned SkScalerContext_FreeType::generateGlyphCount() { 996 unsigned SkScalerContext_FreeType::generateGlyphCount() {
960 return fFace->num_glyphs; 997 return fFace->num_glyphs;
961 } 998 }
962 999
963 uint16_t SkScalerContext_FreeType::generateCharToGlyph(SkUnichar uni) { 1000 uint16_t SkScalerContext_FreeType::generateCharToGlyph(SkUnichar uni) {
964 return SkToU16(FT_Get_Char_Index( fFace, uni )); 1001 return SkToU16(FT_Get_Char_Index( fFace, uni ));
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1068 1105
1069 glyph->fRsbDelta = 0; 1106 glyph->fRsbDelta = 0;
1070 glyph->fLsbDelta = 0; 1107 glyph->fLsbDelta = 0;
1071 1108
1072 FT_Error err; 1109 FT_Error err;
1073 1110
1074 if (this->setupSize()) { 1111 if (this->setupSize()) {
1075 goto ERROR; 1112 goto ERROR;
1076 } 1113 }
1077 1114
1078 err = FT_Load_Glyph( fFace, glyph->getGlyphID(fBaseGlyphCount), fLoadGlyphFl ags ); 1115 // this glyph will be loaded to FreeType glyph slot
1116 fFaceRec->fGlyphLoaded = glyph->getGlyphID(fBaseGlyphCount);
1117 err = FT_Load_Glyph( fFace, fFaceRec->fGlyphLoaded, fLoadGlyphFlags );
1079 if (err != 0) { 1118 if (err != 0) {
1080 #if 0 1119 #if 0
1081 SkDEBUGF(("SkScalerContext_FreeType::generateMetrics(%x): FT_Load_Glyph( glyph:%d flags:%x) returned 0x%x\n", 1120 SkDEBUGF(("SkScalerContext_FreeType::generateMetrics(%x): FT_Load_Glyph( glyph:%d flags:%x) returned 0x%x\n",
1082 fFaceRec->fFontID, glyph->getGlyphID(fBaseGlyphCount), fLoad GlyphFlags, err)); 1121 fFaceRec->fFontID, glyph->getGlyphID(fBaseGlyphCount), fLoad GlyphFlags, err));
1083 #endif 1122 #endif
1084 ERROR: 1123 ERROR:
1085 glyph->zeroMetrics(); 1124 glyph->zeroMetrics();
1125 // glyph not loadded
1126 fFaceRec->fGlyphLoaded = 0;
1086 return; 1127 return;
1087 } 1128 }
1129 emboldenIfNeeded(fFace, fFace->glyph);
1088 1130
1089 switch ( fFace->glyph->format ) { 1131 switch ( fFace->glyph->format ) {
1090 case FT_GLYPH_FORMAT_OUTLINE: { 1132 case FT_GLYPH_FORMAT_OUTLINE: {
1091 FT_BBox bbox; 1133 FT_BBox bbox;
1092 1134
1093 if (0 == fFace->glyph->outline.n_contours) { 1135 if (0 == fFace->glyph->outline.n_contours) {
1094 glyph->fWidth = 0; 1136 glyph->fWidth = 0;
1095 glyph->fHeight = 0; 1137 glyph->fHeight = 0;
1096 glyph->fTop = 0; 1138 glyph->fTop = 0;
1097 glyph->fLeft = 0; 1139 glyph->fLeft = 0;
1098 break; 1140 break;
1099 } 1141 }
1100 1142
1101 if (fRec.fFlags & kEmbolden_Flag) {
1102 emboldenOutline(fFace, &fFace->glyph->outline);
1103 }
1104
1105 getBBoxForCurrentGlyph(glyph, &bbox, true); 1143 getBBoxForCurrentGlyph(glyph, &bbox, true);
1106 1144
1107 glyph->fWidth = SkToU16(SkFDot6Floor(bbox.xMax - bbox.xMin)); 1145 glyph->fWidth = SkToU16(SkFDot6Floor(bbox.xMax - bbox.xMin));
1108 glyph->fHeight = SkToU16(SkFDot6Floor(bbox.yMax - bbox.yMin)); 1146 glyph->fHeight = SkToU16(SkFDot6Floor(bbox.yMax - bbox.yMin));
1109 glyph->fTop = -SkToS16(SkFDot6Floor(bbox.yMax)); 1147 glyph->fTop = -SkToS16(SkFDot6Floor(bbox.yMax));
1110 glyph->fLeft = SkToS16(SkFDot6Floor(bbox.xMin)); 1148 glyph->fLeft = SkToS16(SkFDot6Floor(bbox.xMin));
1111 1149
1112 updateGlyphIfLCD(glyph); 1150 updateGlyphIfLCD(glyph);
1113 1151
1114 break; 1152 break;
1115 } 1153 }
1116 1154
1117 case FT_GLYPH_FORMAT_BITMAP: 1155 case FT_GLYPH_FORMAT_BITMAP:
1118 if (fRec.fFlags & kEmbolden_Flag) {
1119 FT_GlyphSlot_Own_Bitmap(fFace->glyph);
1120 FT_Bitmap_Embolden(gFTLibrary, &fFace->glyph->bitmap, kBitmapEmbolde nStrength, 0);
1121 }
1122
1123 if (fRec.fFlags & SkScalerContext::kVertical_Flag) { 1156 if (fRec.fFlags & SkScalerContext::kVertical_Flag) {
1124 FT_Vector vector; 1157 FT_Vector vector;
1125 vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metric s.horiBearingX; 1158 vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metric s.horiBearingX;
1126 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metri cs.horiBearingY; 1159 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metri cs.horiBearingY;
1127 FT_Vector_Transform(&vector, &fMatrix22); 1160 FT_Vector_Transform(&vector, &fMatrix22);
1128 fFace->glyph->bitmap_left += SkFDot6Floor(vector.x); 1161 fFace->glyph->bitmap_left += SkFDot6Floor(vector.x);
1129 fFace->glyph->bitmap_top += SkFDot6Floor(vector.y); 1162 fFace->glyph->bitmap_top += SkFDot6Floor(vector.y);
1130 } 1163 }
1131 1164
1132 glyph->fWidth = SkToU16(fFace->glyph->bitmap.width); 1165 glyph->fWidth = SkToU16(fFace->glyph->bitmap.width);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 SkDEBUGF(("FT_Set_Char_Size(this:%p sx:%x sy:%x ", this, fScaleX, fScaleY)); 1201 SkDEBUGF(("FT_Set_Char_Size(this:%p sx:%x sy:%x ", this, fScaleX, fScaleY));
1169 SkDEBUGF(("Metrics(glyph:%d flags:0x%x) w:%d\n", glyph->getGlyphID(fBaseGlyp hCount), fLoadGlyphFlags, glyph->fWidth)); 1202 SkDEBUGF(("Metrics(glyph:%d flags:0x%x) w:%d\n", glyph->getGlyphID(fBaseGlyp hCount), fLoadGlyphFlags, glyph->fWidth));
1170 #endif 1203 #endif
1171 } 1204 }
1172 1205
1173 1206
1174 void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) { 1207 void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) {
1175 SkAutoMutexAcquire ac(gFTMutex); 1208 SkAutoMutexAcquire ac(gFTMutex);
1176 1209
1177 FT_Error err; 1210 FT_Error err;
1211 uint16_t glyphLoaded;
1178 1212
1179 if (this->setupSize()) { 1213 if (this->setupSize()) {
1180 goto ERROR; 1214 goto ERROR;
1181 } 1215 }
1182 1216
1183 err = FT_Load_Glyph( fFace, glyph.getGlyphID(fBaseGlyphCount), fLoadGlyphFla gs); 1217 glyphLoaded = fFaceRec->fGlyphLoaded;
1184 if (err != 0) { 1218 // no need to remember what is in the FreeType glyph slot
1185 SkDEBUGF(("SkScalerContext_FreeType::generateImage: FT_Load_Glyph(glyph: %d width:%d height:%d rb:%d flags:%d) returned 0x%x\n", 1219 // since the skia glyph cache won't query image for the same glyph shortly
1186 glyph.getGlyphID(fBaseGlyphCount), glyph.fWidth, glyph.fHeig ht, glyph.rowBytes(), fLoadGlyphFlags, err)); 1220 fFaceRec->fGlyphLoaded = 0;
1187 ERROR: 1221 if (glyphLoaded == 0 || glyphLoaded != glyph.getGlyphID(fBaseGlyphCount)) {
1188 memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight); 1222 err = FT_Load_Glyph( fFace, glyph.getGlyphID(fBaseGlyphCount), fLoadGlyp hFlags);
1189 return; 1223 if (err != 0) {
1224 SkDEBUGF(("SkScalerContext_FreeType::generateImage: FT_Load_Glyph(gl yph:%d width:%d height:%d rb:%d flags:%d) returned 0x%x\n",
1225 glyph.getGlyphID(fBaseGlyphCount), glyph.fWidth, glyph.f Height, glyph.rowBytes(), fLoadGlyphFlags, err));
1226 ERROR:
1227 memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);
1228 return;
1229 }
1230 emboldenIfNeeded(fFace, fFace->glyph);
1190 } 1231 }
1191 1232
1192 generateGlyphImage(fFace, glyph); 1233 generateGlyphImage(fFace, glyph);
1193 } 1234 }
1194 1235
1195 1236
1196 void SkScalerContext_FreeType::generatePath(const SkGlyph& glyph, 1237 void SkScalerContext_FreeType::generatePath(const SkGlyph& glyph,
1197 SkPath* path) { 1238 SkPath* path) {
1198 SkAutoMutexAcquire ac(gFTMutex); 1239 SkAutoMutexAcquire ac(gFTMutex);
1199 1240
1200 SkASSERT(&glyph && path); 1241 SkASSERT(&glyph && path);
1201 1242
1202 if (this->setupSize()) { 1243 if (this->setupSize()) {
1203 path->reset(); 1244 path->reset();
1204 return; 1245 return;
1205 } 1246 }
1206 1247
1207 uint32_t flags = fLoadGlyphFlags; 1248 uint32_t flags = fLoadGlyphFlags;
1208 flags |= FT_LOAD_NO_BITMAP; // ignore embedded bitmaps so we're sure to get the outline 1249 flags |= FT_LOAD_NO_BITMAP; // ignore embedded bitmaps so we're sure to get the outline
1209 flags &= ~FT_LOAD_RENDER; // don't scan convert (we just want the outline) 1250 flags &= ~FT_LOAD_RENDER; // don't scan convert (we just want the outline)
1210 1251
1252 // FreeType glyph slot will be invalid for generateImage
1253 fFaceRec->fGlyphLoaded = 0;
1211 FT_Error err = FT_Load_Glyph( fFace, glyph.getGlyphID(fBaseGlyphCount), flag s); 1254 FT_Error err = FT_Load_Glyph( fFace, glyph.getGlyphID(fBaseGlyphCount), flag s);
1212 1255
1213 if (err != 0) { 1256 if (err != 0) {
1214 SkDEBUGF(("SkScalerContext_FreeType::generatePath: FT_Load_Glyph(glyph:% d flags:%d) returned 0x%x\n", 1257 SkDEBUGF(("SkScalerContext_FreeType::generatePath: FT_Load_Glyph(glyph:% d flags:%d) returned 0x%x\n",
1215 glyph.getGlyphID(fBaseGlyphCount), flags, err)); 1258 glyph.getGlyphID(fBaseGlyphCount), flags, err));
1216 path->reset(); 1259 path->reset();
1217 return; 1260 return;
1218 } 1261 }
1262 emboldenIfNeeded(fFace, fFace->glyph);
1219 1263
1220 generateGlyphPath(fFace, path); 1264 generateGlyphPath(fFace, path);
1221 1265
1222 // The path's origin from FreeType is always the horizontal layout origin. 1266 // The path's origin from FreeType is always the horizontal layout origin.
1223 // Offset the path so that it is relative to the vertical origin if needed. 1267 // Offset the path so that it is relative to the vertical origin if needed.
1224 if (fRec.fFlags & SkScalerContext::kVertical_Flag) { 1268 if (fRec.fFlags & SkScalerContext::kVertical_Flag) {
1225 FT_Vector vector; 1269 FT_Vector vector;
1226 vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metrics.ho riBearingX; 1270 vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metrics.ho riBearingX;
1227 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metrics.h oriBearingY; 1271 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metrics.h oriBearingY;
1228 FT_Vector_Transform(&vector, &fMatrix22); 1272 FT_Vector_Transform(&vector, &fMatrix22);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1279 ys[4] = leading; 1323 ys[4] = leading;
1280 ys[5] = os2 ? os2->xAvgCharWidth : 0; 1324 ys[5] = os2 ? os2->xAvgCharWidth : 0;
1281 1325
1282 SkScalar x_height; 1326 SkScalar x_height;
1283 if (os2 && os2->sxHeight) { 1327 if (os2 && os2->sxHeight) {
1284 x_height = fScale.x() * os2->sxHeight / upem; 1328 x_height = fScale.x() * os2->sxHeight / upem;
1285 } else { 1329 } else {
1286 const FT_UInt x_glyph = FT_Get_Char_Index(fFace, 'x'); 1330 const FT_UInt x_glyph = FT_Get_Char_Index(fFace, 'x');
1287 if (x_glyph) { 1331 if (x_glyph) {
1288 FT_BBox bbox; 1332 FT_BBox bbox;
1333 // just set the glyph to be invalid for generateImage
1334 fFaceRec->fGlyphLoaded = 0;
1289 FT_Load_Glyph(fFace, x_glyph, fLoadGlyphFlags); 1335 FT_Load_Glyph(fFace, x_glyph, fLoadGlyphFlags);
1290 if (fRec.fFlags & kEmbolden_Flag) { 1336 emboldenIfNeeded(fFace, fFace->glyph);
1291 emboldenOutline(fFace, &fFace->glyph->outline);
1292 }
1293 FT_Outline_Get_CBox(&fFace->glyph->outline, &bbox); 1337 FT_Outline_Get_CBox(&fFace->glyph->outline, &bbox);
1294 x_height = bbox.yMax / 64.0f; 1338 x_height = bbox.yMax / 64.0f;
1295 } else { 1339 } else {
1296 x_height = 0; 1340 x_height = 0;
1297 } 1341 }
1298 } 1342 }
1299 1343
1300 // convert upem-y values into scalar points 1344 // convert upem-y values into scalar points
1301 for (int i = 0; i < 6; i++) { 1345 for (int i = 0; i < 6; i++) {
1302 SkScalar y = scaleY * ys[i] / upem; 1346 SkScalar y = scaleY * ys[i] / upem;
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
1523 *style = (SkTypeface::Style) tempStyle; 1567 *style = (SkTypeface::Style) tempStyle;
1524 } 1568 }
1525 if (isFixedPitch) { 1569 if (isFixedPitch) {
1526 *isFixedPitch = FT_IS_FIXED_WIDTH(face); 1570 *isFixedPitch = FT_IS_FIXED_WIDTH(face);
1527 } 1571 }
1528 1572
1529 FT_Done_Face(face); 1573 FT_Done_Face(face);
1530 FT_Done_FreeType(library); 1574 FT_Done_FreeType(library);
1531 return true; 1575 return true;
1532 } 1576 }
OLDNEW
« no previous file with comments | « no previous file | src/ports/SkFontHost_FreeType_common.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698