aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Ben Wagner <bungeman@google.com>2018-06-08 14:15:47 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-13 22:11:26 +0000
commit082a7a701f30763c4c5cd722cd5a02d4b03da469 (patch)
treef41938df839b3bfe55372a627372b393e2ade657 /src
parent42c2115fc32e43c252284082a6e2473cef76e401 (diff)
Adjust FreeType matrix based on what came back.
In the FreeType backend requests are made for a specific height but that might not be the final height which was created by FreeType. In the bitmap case this is obvious (a nearby size was picked) but this can also happen in the outline case then the requested size was less than one. BUG=skia:8042 Change-Id: Ibe3ae01b3732019870950b726270b9c85baeaffe Reviewed-on: https://skia-review.googlesource.com/133448 Commit-Queue: Ben Wagner <bungeman@google.com> Reviewed-by: Jim Van Verth <jvanverth@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/ports/SkFontHost_FreeType.cpp52
1 files changed, 31 insertions, 21 deletions
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp
index da276b417b..d1a47f8197 100644
--- a/src/ports/SkFontHost_FreeType.cpp
+++ b/src/ports/SkFontHost_FreeType.cpp
@@ -79,6 +79,10 @@ static bool isLCD(const SkScalerContextRec& rec) {
return SkMask::kLCD16_Format == rec.fMaskFormat;
}
+static SkScalar SkFT_FixedToScalar(FT_Fixed x) {
+ return SkFixedToScalar(x);
+}
+
//////////////////////////////////////////////////////////////////////////
extern "C" {
@@ -761,15 +765,6 @@ SkScalerContext_FreeType::SkScalerContext_FreeType(sk_sp<SkTypeface> typeface,
return;
}
- fRec.computeMatrices(SkScalerContextRec::kFull_PreMatrixScale, &fScale, &fMatrix22Scalar);
-
- FT_F26Dot6 scaleX = SkScalarToFDot6(fScale.fX);
- FT_F26Dot6 scaleY = SkScalarToFDot6(fScale.fY);
- fMatrix22.xx = SkScalarToFixed(fMatrix22Scalar.getScaleX());
- fMatrix22.xy = SkScalarToFixed(-fMatrix22Scalar.getSkewX());
- fMatrix22.yx = SkScalarToFixed(-fMatrix22Scalar.getSkewY());
- fMatrix22.yy = SkScalarToFixed(fMatrix22Scalar.getScaleY());
-
fLCDIsVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag);
// compute the flags we send to Load_Glyph
@@ -860,13 +855,31 @@ SkScalerContext_FreeType::SkScalerContext_FreeType(sk_sp<SkTypeface> typeface,
return;
}
+ fRec.computeMatrices(SkScalerContextRec::kFull_PreMatrixScale, &fScale, &fMatrix22Scalar);
+ FT_F26Dot6 scaleX = SkScalarToFDot6(fScale.fX);
+ FT_F26Dot6 scaleY = SkScalarToFDot6(fScale.fY);
+
if (FT_IS_SCALABLE(fFaceRec->fFace)) {
err = FT_Set_Char_Size(fFaceRec->fFace.get(), scaleX, scaleY, 72, 72);
if (err != 0) {
SK_TRACEFTR(err, "FT_Set_CharSize(%s, %f, %f) failed.",
- fFaceRec->fFace->family_name, fScale.fX, fScale.fY);
+ fFaceRec->fFace->family_name, fScale.fX, fScale.fY);
return;
}
+
+#ifndef SK_IGNORE_TINY_FREETYPE_SIZE_FIX
+ // Adjust the matrix to reflect the actually chosen scale.
+ // FreeType currently does not allow requesting sizes less than 1, this allow for scaling.
+ // Don't do this at all sizes as that will interfere with hinting.
+ if (fScale.fX < 1 || fScale.fY < 1) {
+ SkScalar upem = fFaceRec->fFace->units_per_EM;
+ FT_Size_Metrics& ftmetrics = fFaceRec->fFace->size->metrics;
+ SkScalar x_ppem = upem * SkFT_FixedToScalar(ftmetrics.x_scale) / 64.0f;
+ SkScalar y_ppem = upem * SkFT_FixedToScalar(ftmetrics.y_scale) / 64.0f;
+ fMatrix22Scalar.preScale(fScale.x() / x_ppem, fScale.y() / y_ppem);
+ }
+#endif
+
} else if (FT_HAS_FIXED_SIZES(fFaceRec->fFace)) {
fStrikeIndex = chooseBitmapStrike(fFaceRec->fFace.get(), scaleY);
if (fStrikeIndex == -1) {
@@ -878,19 +891,15 @@ SkScalerContext_FreeType::SkScalerContext_FreeType(sk_sp<SkTypeface> typeface,
err = FT_Select_Size(fFaceRec->fFace.get(), fStrikeIndex);
if (err != 0) {
SK_TRACEFTR(err, "FT_Select_Size(%s, %d) failed.",
- fFaceRec->fFace->family_name, fStrikeIndex);
+ fFaceRec->fFace->family_name, fStrikeIndex);
fStrikeIndex = -1;
return;
}
- // A non-ideal size was picked, so recompute the matrix.
- // This adjusts for the difference between FT_Set_Char_Size and FT_Select_Size.
+ // Adjust the matrix to reflect the actually chosen scale.
+ // It is likely that the ppem chosen was not the one requested, this allows for scaling.
fMatrix22Scalar.preScale(fScale.x() / fFaceRec->fFace->size->metrics.x_ppem,
fScale.y() / fFaceRec->fFace->size->metrics.y_ppem);
- fMatrix22.xx = SkScalarToFixed(fMatrix22Scalar.getScaleX());
- fMatrix22.xy = SkScalarToFixed(-fMatrix22Scalar.getSkewX());
- fMatrix22.yx = SkScalarToFixed(-fMatrix22Scalar.getSkewY());
- fMatrix22.yy = SkScalarToFixed(fMatrix22Scalar.getScaleY());
// FreeType does not provide linear metrics for bitmap fonts.
linearMetrics = false;
@@ -907,6 +916,11 @@ SkScalerContext_FreeType::SkScalerContext_FreeType(sk_sp<SkTypeface> typeface,
return;
}
+ fMatrix22.xx = SkScalarToFixed(fMatrix22Scalar.getScaleX());
+ fMatrix22.xy = SkScalarToFixed(-fMatrix22Scalar.getSkewX());
+ fMatrix22.yx = SkScalarToFixed(-fMatrix22Scalar.getSkewY());
+ fMatrix22.yy = SkScalarToFixed(fMatrix22Scalar.getScaleY());
+
fFTSize = ftSize.release();
fFace = fFaceRec->fFace.get();
fDoLinearMetrics = linearMetrics;
@@ -962,10 +976,6 @@ SkUnichar SkScalerContext_FreeType::generateGlyphToChar(uint16_t glyph) {
return 0;
}
-static SkScalar SkFT_FixedToScalar(FT_Fixed x) {
- return SkFixedToScalar(x);
-}
-
void SkScalerContext_FreeType::generateAdvance(SkGlyph* glyph) {
/* unhinted and light hinted text have linearly scaled advances
* which are very cheap to compute with some font formats...