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

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

Issue 14736005: reimplement generateFontMetrics to keep all calculations in SkScalar, avoiding the (Closed) Base URL: http://skia.googlecode.com/svn/
Patch Set: Created 7 years, 7 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 | Annotate | Revision Log
« 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 /* 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 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 private: 182 private:
183 SkFaceRec* fFaceRec; 183 SkFaceRec* fFaceRec;
184 FT_Face fFace; // reference to shared face in gFaceRecHead 184 FT_Face fFace; // reference to shared face in gFaceRecHead
185 FT_Size fFTSize; // our own copy 185 FT_Size fFTSize; // our own copy
186 SkFixed fScaleX, fScaleY; 186 SkFixed fScaleX, fScaleY;
187 FT_Matrix fMatrix22; 187 FT_Matrix fMatrix22;
188 uint32_t fLoadGlyphFlags; 188 uint32_t fLoadGlyphFlags;
189 bool fDoLinearMetrics; 189 bool fDoLinearMetrics;
190 bool fLCDIsVert; 190 bool fLCDIsVert;
191 191
192 // Need scalar versions for generateFontMetrics
193 SkVector fScale;
194 SkMatrix fMatrix22Scalar;
195
192 FT_Error setupSize(); 196 FT_Error setupSize();
193 void getBBoxForCurrentGlyph(SkGlyph* glyph, FT_BBox* bbox, 197 void getBBoxForCurrentGlyph(SkGlyph* glyph, FT_BBox* bbox,
194 bool snapToPixelBoundary = false); 198 bool snapToPixelBoundary = false);
195 // Caller must lock gFTMutex before calling this function. 199 // Caller must lock gFTMutex before calling this function.
196 void updateGlyphIfLCD(SkGlyph* glyph); 200 void updateGlyphIfLCD(SkGlyph* glyph);
197 }; 201 };
198 202
199 /////////////////////////////////////////////////////////////////////////// 203 ///////////////////////////////////////////////////////////////////////////
200 /////////////////////////////////////////////////////////////////////////// 204 ///////////////////////////////////////////////////////////////////////////
201 205
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 SkScalarToFloat(fRec.fPreScaleX), SkScalarToFloat(fRec.fPreSkewX), 753 SkScalarToFloat(fRec.fPreScaleX), SkScalarToFloat(fRec.fPreSkewX),
750 SkScalarToFloat(fRec.fPost2x2[0][0]), SkScalarToFloat(fRec.fPost2x2[0 ][1]), 754 SkScalarToFloat(fRec.fPost2x2[0][0]), SkScalarToFloat(fRec.fPost2x2[0 ][1]),
751 SkScalarToFloat(fRec.fPost2x2[1][0]), SkScalarToFloat(fRec.fPost2x2[1 ][1]), 755 SkScalarToFloat(fRec.fPost2x2[1][0]), SkScalarToFloat(fRec.fPost2x2[1 ][1]),
752 fRec.getHinting(), fRec.fMaskFormat, keyString.c_str()); 756 fRec.getHinting(), fRec.fMaskFormat, keyString.c_str());
753 #endif 757 #endif
754 758
755 // now compute our scale factors 759 // now compute our scale factors
756 SkScalar sx = m.getScaleX(); 760 SkScalar sx = m.getScaleX();
757 SkScalar sy = m.getScaleY(); 761 SkScalar sy = m.getScaleY();
758 762
763 fMatrix22Scalar.reset();
764
759 if (m.getSkewX() || m.getSkewY() || sx < 0 || sy < 0) { 765 if (m.getSkewX() || m.getSkewY() || sx < 0 || sy < 0) {
760 // sort of give up on hinting 766 // sort of give up on hinting
761 sx = SkMaxScalar(SkScalarAbs(sx), SkScalarAbs(m.getSkewX())); 767 sx = SkMaxScalar(SkScalarAbs(sx), SkScalarAbs(m.getSkewX()));
762 sy = SkMaxScalar(SkScalarAbs(m.getSkewY()), SkScalarAbs(sy)); 768 sy = SkMaxScalar(SkScalarAbs(m.getSkewY()), SkScalarAbs(sy));
763 sx = sy = SkScalarAve(sx, sy); 769 sx = sy = SkScalarAve(sx, sy);
764 770
765 SkScalar inv = SkScalarInvert(sx); 771 SkScalar inv = SkScalarInvert(sx);
766 772
767 // flip the skew elements to go from our Y-down system to FreeType's 773 // flip the skew elements to go from our Y-down system to FreeType's
768 fMatrix22.xx = SkScalarToFixed(SkScalarMul(m.getScaleX(), inv)); 774 fMatrix22.xx = SkScalarToFixed(SkScalarMul(m.getScaleX(), inv));
769 fMatrix22.xy = -SkScalarToFixed(SkScalarMul(m.getSkewX(), inv)); 775 fMatrix22.xy = -SkScalarToFixed(SkScalarMul(m.getSkewX(), inv));
770 fMatrix22.yx = -SkScalarToFixed(SkScalarMul(m.getSkewY(), inv)); 776 fMatrix22.yx = -SkScalarToFixed(SkScalarMul(m.getSkewY(), inv));
771 fMatrix22.yy = SkScalarToFixed(SkScalarMul(m.getScaleY(), inv)); 777 fMatrix22.yy = SkScalarToFixed(SkScalarMul(m.getScaleY(), inv));
778
779 fMatrix22Scalar.setScaleX(SkScalarMul(m.getScaleX(), inv));
780 fMatrix22Scalar.setSkewX(-SkScalarMul(m.getSkewX(), inv));
781 fMatrix22Scalar.setSkewY(-SkScalarMul(m.getSkewY(), inv));
782 fMatrix22Scalar.setScaleY(SkScalarMul(m.getScaleY(), inv));
772 } else { 783 } else {
773 fMatrix22.xx = fMatrix22.yy = SK_Fixed1; 784 fMatrix22.xx = fMatrix22.yy = SK_Fixed1;
774 fMatrix22.xy = fMatrix22.yx = 0; 785 fMatrix22.xy = fMatrix22.yx = 0;
775 } 786 }
776 787
777 #ifdef SK_SUPPORT_HINTING_SCALE_FACTOR 788 #ifdef SK_SUPPORT_HINTING_SCALE_FACTOR
778 if (fRec.getHinting() == SkPaint::kNo_Hinting) { 789 if (fRec.getHinting() == SkPaint::kNo_Hinting) {
790 fScale.set(sx, sy);
779 fScaleX = SkScalarToFixed(sx); 791 fScaleX = SkScalarToFixed(sx);
780 fScaleY = SkScalarToFixed(sy); 792 fScaleY = SkScalarToFixed(sy);
781 } else { 793 } else {
782 SkScalar hintingScaleFactor = fRec.fHintingScaleFactor; 794 SkScalar hintingScaleFactor = fRec.fHintingScaleFactor;
783 795
784 fScaleX = SkScalarToFixed(sx / hintingScaleFactor); 796 fScale.set(sx / hintingScaleFactor, sy / hintingScaleFactor);
785 fScaleY = SkScalarToFixed(sy / hintingScaleFactor); 797 fScaleX = SkScalarToFixed(fScale.fX);
798 fScaleY = SkScalarToFixed(fScale.fY);
786 799
787 fMatrix22.xx *= hintingScaleFactor; 800 fMatrix22.xx *= hintingScaleFactor;
788 fMatrix22.xy *= hintingScaleFactor; 801 fMatrix22.xy *= hintingScaleFactor;
789 fMatrix22.yx *= hintingScaleFactor; 802 fMatrix22.yx *= hintingScaleFactor;
790 fMatrix22.yy *= hintingScaleFactor; 803 fMatrix22.yy *= hintingScaleFactor;
804
805 fMatrix22Scalar.setScaleX(fMatrix22Scalar.getScaleX() * hintingScaleFact or);
806 fMatrix22Scalar.setSkewX(fMatrix22Scalar..getSkewX() * hintingScaleFacto r);
807 fMatrix22Scalar.setSkewY(fMatrix22Scalar..getSkewY() * hintingScaleFacto r);
808 fMatrix22Scalar.setScaleY(fMatrix22Scalar..getScaleY() * hintingScaleFac tor);
791 } 809 }
792 #else 810 #else
811 fScale.set(sx, sy);
793 fScaleX = SkScalarToFixed(sx); 812 fScaleX = SkScalarToFixed(sx);
794 fScaleY = SkScalarToFixed(sy); 813 fScaleY = SkScalarToFixed(sy);
795 #endif 814 #endif
796 815
797 fLCDIsVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag); 816 fLCDIsVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag);
798 817
799 // compute the flags we send to Load_Glyph 818 // compute the flags we send to Load_Glyph
800 { 819 {
801 FT_Int32 loadFlags = FT_LOAD_DEFAULT; 820 FT_Int32 loadFlags = FT_LOAD_DEFAULT;
802 bool linearMetrics = SkToBool(fRec.fFlags & SkScalerContext::kSubpixelPo sitioning_Flag); 821 bool linearMetrics = SkToBool(fRec.fFlags & SkScalerContext::kSubpixelPo sitioning_Flag);
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
1224 } 1243 }
1225 1244
1226 FT_Face face = fFace; 1245 FT_Face face = fFace;
1227 int upem = face->units_per_EM; 1246 int upem = face->units_per_EM;
1228 if (upem <= 0) { 1247 if (upem <= 0) {
1229 goto ERROR; 1248 goto ERROR;
1230 } 1249 }
1231 1250
1232 SkPoint pts[6]; 1251 SkPoint pts[6];
1233 SkFixed ys[6]; 1252 SkFixed ys[6];
1234 SkFixed scaleY = fScaleY; 1253 SkScalar scaleY = fScale.y();
1235 SkFixed mxy = fMatrix22.xy; 1254 SkScalar mxy = fMatrix22Scalar.getSkewX();
1236 SkFixed myy = fMatrix22.yy; 1255 SkScalar myy = fMatrix22Scalar.getScaleY();
1237 SkScalar xmin = SkIntToScalar(face->bbox.xMin) / upem; 1256 SkScalar xmin = SkIntToScalar(face->bbox.xMin) / upem;
1238 SkScalar xmax = SkIntToScalar(face->bbox.xMax) / upem; 1257 SkScalar xmax = SkIntToScalar(face->bbox.xMax) / upem;
1239 1258
1240 int leading = face->height - (face->ascender + -face->descender); 1259 int leading = face->height - (face->ascender + -face->descender);
1241 if (leading < 0) { 1260 if (leading < 0) {
1242 leading = 0; 1261 leading = 0;
1243 } 1262 }
1244 1263
1245 // Try to get the OS/2 table from the font. This contains the specific 1264 // Try to get the OS/2 table from the font. This contains the specific
1246 // average font width metrics which Windows uses. 1265 // average font width metrics which Windows uses.
1247 TT_OS2* os2 = (TT_OS2*) FT_Get_Sfnt_Table(face, ft_sfnt_os2); 1266 TT_OS2* os2 = (TT_OS2*) FT_Get_Sfnt_Table(face, ft_sfnt_os2);
1248 1267
1249 ys[0] = -face->bbox.yMax; 1268 ys[0] = -face->bbox.yMax;
1250 ys[1] = -face->ascender; 1269 ys[1] = -face->ascender;
1251 ys[2] = -face->descender; 1270 ys[2] = -face->descender;
1252 ys[3] = -face->bbox.yMin; 1271 ys[3] = -face->bbox.yMin;
1253 ys[4] = leading; 1272 ys[4] = leading;
1254 ys[5] = os2 ? os2->xAvgCharWidth : 0; 1273 ys[5] = os2 ? os2->xAvgCharWidth : 0;
1255 1274
1256 SkScalar x_height; 1275 SkScalar x_height;
1257 if (os2 && os2->sxHeight) { 1276 if (os2 && os2->sxHeight) {
1258 x_height = SkFixedToScalar(SkMulDiv(fScaleX, os2->sxHeight, upem)); 1277 x_height = fScale.x() * os2->sxHeight / upem;
1259 } else { 1278 } else {
1260 const FT_UInt x_glyph = FT_Get_Char_Index(fFace, 'x'); 1279 const FT_UInt x_glyph = FT_Get_Char_Index(fFace, 'x');
1261 if (x_glyph) { 1280 if (x_glyph) {
1262 FT_BBox bbox; 1281 FT_BBox bbox;
1263 FT_Load_Glyph(fFace, x_glyph, fLoadGlyphFlags); 1282 FT_Load_Glyph(fFace, x_glyph, fLoadGlyphFlags);
1264 if (fRec.fFlags & kEmbolden_Flag) { 1283 if (fRec.fFlags & kEmbolden_Flag) {
1265 emboldenOutline(fFace, &fFace->glyph->outline); 1284 emboldenOutline(fFace, &fFace->glyph->outline);
1266 } 1285 }
1267 FT_Outline_Get_CBox(&fFace->glyph->outline, &bbox); 1286 FT_Outline_Get_CBox(&fFace->glyph->outline, &bbox);
1268 x_height = SkFixedToScalar(SkFDot6ToFixed(bbox.yMax)); 1287 x_height = bbox.yMax / 64.0f;
1269 } else { 1288 } else {
1270 x_height = 0; 1289 x_height = 0;
1271 } 1290 }
1272 } 1291 }
1273 1292
1274 // convert upem-y values into scalar points 1293 // convert upem-y values into scalar points
1275 for (int i = 0; i < 6; i++) { 1294 for (int i = 0; i < 6; i++) {
1276 SkFixed y = SkMulDiv(scaleY, ys[i], upem); 1295 SkScalar y = scaleY * ys[i] / upem;
1277 SkFixed x = SkFixedMul(mxy, y); 1296 pts[i].set(y * mxy, y * myy);
1278 y = SkFixedMul(myy, y);
1279 pts[i].set(SkFixedToScalar(x), SkFixedToScalar(y));
1280 } 1297 }
1281 1298
1282 if (mx) { 1299 if (mx) {
1283 mx->fTop = pts[0].fX; 1300 mx->fTop = pts[0].fX;
1284 mx->fAscent = pts[1].fX; 1301 mx->fAscent = pts[1].fX;
1285 mx->fDescent = pts[2].fX; 1302 mx->fDescent = pts[2].fX;
1286 mx->fBottom = pts[3].fX; 1303 mx->fBottom = pts[3].fX;
1287 mx->fLeading = pts[4].fX; 1304 mx->fLeading = pts[4].fX;
1288 mx->fAvgCharWidth = pts[5].fX; 1305 mx->fAvgCharWidth = pts[5].fX;
1289 mx->fXMin = xmin; 1306 mx->fXMin = xmin;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1358 *style = (SkTypeface::Style) tempStyle; 1375 *style = (SkTypeface::Style) tempStyle;
1359 } 1376 }
1360 if (isFixedPitch) { 1377 if (isFixedPitch) {
1361 *isFixedPitch = FT_IS_FIXED_WIDTH(face); 1378 *isFixedPitch = FT_IS_FIXED_WIDTH(face);
1362 } 1379 }
1363 1380
1364 FT_Done_Face(face); 1381 FT_Done_Face(face);
1365 FT_Done_FreeType(library); 1382 FT_Done_FreeType(library);
1366 return true; 1383 return true;
1367 } 1384 }
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