OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |