aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/ports
diff options
context:
space:
mode:
Diffstat (limited to 'src/ports')
-rw-r--r--src/ports/SkFontHost_FreeType.cpp104
-rwxr-xr-xsrc/ports/SkFontHost_win.cpp30
2 files changed, 73 insertions, 61 deletions
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp
index 97caab4b6b..e1d62c027e 100644
--- a/src/ports/SkFontHost_FreeType.cpp
+++ b/src/ports/SkFontHost_FreeType.cpp
@@ -18,6 +18,7 @@
#include "SkGlyph.h"
#include "SkMask.h"
#include "SkMaskGamma.h"
+#include "SkMatrix22.h"
#include "SkOTUtils.h"
#include "SkOnce.h"
#include "SkScalerContext.h"
@@ -43,6 +44,8 @@
#include FT_LCD_FILTER_H
#endif
+// Defined in FreeType 2.3.8 and later.
+// This is a silly build time check, we would need a runtime check if we really cared.
#ifdef FT_ADVANCES_H
#include FT_ADVANCES_H
#endif
@@ -693,9 +696,6 @@ SkAdvancedTypefaceMetrics* SkTypeface_FreeType::onGetAdvancedTypefaceMetrics(
///////////////////////////////////////////////////////////////////////////
-#define BLACK_LUMINANCE_LIMIT 0x40
-#define WHITE_LUMINANCE_LIMIT 0xA0
-
static bool bothZero(SkScalar a, SkScalar b) {
return 0 == a && 0 == b;
}
@@ -849,46 +849,34 @@ SkScalerContext_FreeType::SkScalerContext_FreeType(SkTypeface* typeface,
}
fFace = fFaceRec->fFace;
- // compute our factors from the record
-
- SkMatrix m;
-
- fRec.getSingleMatrix(&m);
-
-#ifdef DUMP_STRIKE_CREATION
- SkString keyString;
- SkFontHost::GetDescriptorKeyString(desc, &keyString);
- printf("========== strike [%g %g %g] [%g %g %g %g] hints %d format %d %s\n", SkScalarToFloat(fRec.fTextSize),
- SkScalarToFloat(fRec.fPreScaleX), SkScalarToFloat(fRec.fPreSkewX),
- SkScalarToFloat(fRec.fPost2x2[0][0]), SkScalarToFloat(fRec.fPost2x2[0][1]),
- SkScalarToFloat(fRec.fPost2x2[1][0]), SkScalarToFloat(fRec.fPost2x2[1][1]),
- fRec.getHinting(), fRec.fMaskFormat, keyString.c_str());
-#endif
-
- // now compute our scale factors
- SkScalar sx = m.getScaleX();
- SkScalar sy = m.getScaleY();
+ // A is the total matrix.
+ SkMatrix A;
+ fRec.getSingleMatrix(&A);
+ SkScalar sx = A.getScaleX();
+ SkScalar sy = A.getScaleY();
fMatrix22Scalar.reset();
- if (m.getSkewX() || m.getSkewY() || sx < 0 || sy < 0) {
+//#define SK_IGNORE_FREETYPE_ROTATION_FIX
+#ifdef SK_IGNORE_FREETYPE_ROTATION_FIX
+ if (A.getSkewX() || A.getSkewY() || sx < 0 || sy < 0) {
// sort of give up on hinting
- sx = SkMaxScalar(SkScalarAbs(sx), SkScalarAbs(m.getSkewX()));
- sy = SkMaxScalar(SkScalarAbs(m.getSkewY()), SkScalarAbs(sy));
+ sx = SkMaxScalar(SkScalarAbs(sx), SkScalarAbs(A.getSkewX()));
+ sy = SkMaxScalar(SkScalarAbs(A.getSkewY()), SkScalarAbs(sy));
sx = sy = SkScalarAve(sx, sy);
SkScalar inv = SkScalarInvert(sx);
// flip the skew elements to go from our Y-down system to FreeType's
- fMatrix22.xx = SkScalarToFixed(SkScalarMul(m.getScaleX(), inv));
- fMatrix22.xy = -SkScalarToFixed(SkScalarMul(m.getSkewX(), inv));
- fMatrix22.yx = -SkScalarToFixed(SkScalarMul(m.getSkewY(), inv));
- fMatrix22.yy = SkScalarToFixed(SkScalarMul(m.getScaleY(), inv));
-
- fMatrix22Scalar.setScaleX(SkScalarMul(m.getScaleX(), inv));
- fMatrix22Scalar.setSkewX(-SkScalarMul(m.getSkewX(), inv));
- fMatrix22Scalar.setSkewY(-SkScalarMul(m.getSkewY(), inv));
- fMatrix22Scalar.setScaleY(SkScalarMul(m.getScaleY(), inv));
+ fMatrix22.xx = SkScalarToFixed(SkScalarMul(A.getScaleX(), inv));
+ fMatrix22.xy = -SkScalarToFixed(SkScalarMul(A.getSkewX(), inv));
+ fMatrix22.yx = -SkScalarToFixed(SkScalarMul(A.getSkewY(), inv));
+ fMatrix22.yy = SkScalarToFixed(SkScalarMul(A.getScaleY(), inv));
+
+ fMatrix22Scalar.setScaleX(SkScalarMul(A.getScaleX(), inv));
+ fMatrix22Scalar.setSkewX(-SkScalarMul(A.getSkewX(), inv));
+ fMatrix22Scalar.setSkewY(-SkScalarMul(A.getSkewY(), inv));
+ fMatrix22Scalar.setScaleY(SkScalarMul(A.getScaleY(), inv));
} else {
fMatrix22.xx = fMatrix22.yy = SK_Fixed1;
fMatrix22.xy = fMatrix22.yx = 0;
@@ -896,6 +884,54 @@ SkScalerContext_FreeType::SkScalerContext_FreeType(SkTypeface* typeface,
fScale.set(sx, sy);
fScaleX = SkScalarToFixed(sx);
fScaleY = SkScalarToFixed(sy);
+#else
+ // In GDI, the hinter is aware of the current transformation
+ // (the transform is in some sense applied before/with the hinting).
+ // The bytecode can then test if it is rotated or stretched and decide
+ // to apply instructions or not.
+ //
+ // FreeType, however, always does the transformation strictly after hinting.
+ // It just sets 'rotated' and 'stretched' to false and only applies the
+ // size before hinting.
+ //
+ // Also, FreeType respects the head::flags::IntegerScaling flag,
+ // (although this is patched out on most major distros)
+ // so it is critical to get the size correct on the request.
+ //
+ // This also gets us the actual closest size on bitmap fonts as well.
+ if (A.getSkewX() || A.getSkewY() || sx < 0 || sy < 0) {
+ // h is where A maps the horizontal baseline.
+ SkPoint h = SkPoint::Make(SK_Scalar1, 0);
+ A.mapPoints(&h, 1);
+
+ // G is the Givens Matrix for A (rotational matrix where GA[0][1] == 0).
+ SkMatrix G;
+ SkComputeGivensRotation(h, &G);
+
+ // GA is the matrix A with rotation removed.
+ SkMatrix GA(G);
+ GA.preConcat(A);
+
+ sx = SkScalarAbs(GA.get(SkMatrix::kMScaleX));
+ sy = SkScalarAbs(GA.get(SkMatrix::kMScaleY));
+
+ // sA is the total matrix A without the text scale.
+ SkMatrix sA(A);
+ sA.preScale(SkScalarInvert(sx), SkScalarInvert(sy)); //remove text size
+
+ fMatrix22Scalar.setScaleX(sA.getScaleX());
+ fMatrix22Scalar.setSkewX(-sA.getSkewX());
+ fMatrix22Scalar.setSkewY(-sA.getSkewY());
+ fMatrix22Scalar.setScaleY(sA.getScaleY());
+ }
+ fScale.set(sx, sy);
+ fScaleX = SkScalarToFixed(sx);
+ fScaleY = SkScalarToFixed(sy);
+ fMatrix22.xx = SkScalarToFixed(fMatrix22Scalar.getScaleX());
+ fMatrix22.xy = SkScalarToFixed(fMatrix22Scalar.getSkewX());
+ fMatrix22.yx = SkScalarToFixed(fMatrix22Scalar.getSkewY());
+ fMatrix22.yy = SkScalarToFixed(fMatrix22Scalar.getScaleY());
+#endif
fLCDIsVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag);
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp
index 8ed3b666aa..47a29c0024 100755
--- a/src/ports/SkFontHost_win.cpp
+++ b/src/ports/SkFontHost_win.cpp
@@ -16,6 +16,7 @@
#include "SkGlyph.h"
#include "SkHRESULT.h"
#include "SkMaskGamma.h"
+#include "SkMatrix22.h"
#include "SkOTTable_maxp.h"
#include "SkOTTable_name.h"
#include "SkOTUtils.h"
@@ -636,34 +637,9 @@ SkScalerContext_GDI::SkScalerContext_GDI(SkTypeface* rawTypeface,
fRec.getSingleMatrix(&A);
A.mapPoints(&h, 1);
- // Find the Given's matrix [[c, -s],[s, c]] which rotates the baseline vector h
- // (where the baseline is mapped to) to the positive horizontal axis.
- const SkScalar& a = h.fX;
- const SkScalar& b = h.fY;
- SkScalar c, s;
- if (0 == b) {
- c = SkDoubleToScalar(_copysign(SK_Scalar1, a));
- s = 0;
- } else if (0 == a) {
- c = 0;
- s = SkDoubleToScalar(-_copysign(SK_Scalar1, b));
- } else if (SkScalarAbs(b) > SkScalarAbs(a)) {
- SkScalar t = a / b;
- SkScalar u = SkDoubleToScalar(_copysign(SkScalarSqrt(SK_Scalar1 + t*t), b));
- s = -1 / u;
- c = -s * t;
- } else {
- SkScalar t = b / a;
- SkScalar u = SkDoubleToScalar(_copysign(SkScalarSqrt(SK_Scalar1 + t*t), a));
- c = 1 / u;
- s = -c * t;
- }
-
- // G is the Given's Matrix for A (rotational matrix such that GA[0][1] == 0).
+ // G is the Givens Matrix for A (rotational matrix where GA[0][1] == 0).
SkMatrix G;
- G.setAll(c, -s, 0,
- s, c, 0,
- 0, 0, SkScalarToPersp(SK_Scalar1));
+ SkComputeGivensRotation(h, &G);
// GA is the matrix A with rotation removed.
SkMatrix GA(G);