| Index: src/ports/SkFontHost_FreeType.cpp
|
| ===================================================================
|
| --- src/ports/SkFontHost_FreeType.cpp (revision 13916)
|
| +++ src/ports/SkFontHost_FreeType.cpp (working copy)
|
| @@ -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 @@
|
|
|
| ///////////////////////////////////////////////////////////////////////////
|
|
|
| -#define BLACK_LUMINANCE_LIMIT 0x40
|
| -#define WHITE_LUMINANCE_LIMIT 0xA0
|
| -
|
| static bool bothZero(SkScalar a, SkScalar b) {
|
| return 0 == a && 0 == b;
|
| }
|
| @@ -849,53 +849,60 @@
|
| }
|
| fFace = fFaceRec->fFace;
|
|
|
| - // compute our factors from the record
|
| + // A is the total matrix.
|
| + SkMatrix A;
|
| + fRec.getSingleMatrix(&A);
|
|
|
| - SkMatrix m;
|
| + SkScalar sx = A.getScaleX();
|
| + SkScalar sy = A.getScaleY();
|
| + fMatrix22Scalar.reset();
|
|
|
| - fRec.getSingleMatrix(&m);
|
| + // 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);
|
|
|
| -#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
|
| + // G is the Givens Matrix for A (rotational matrix where GA[0][1] == 0).
|
| + SkMatrix G;
|
| + Sk2x2Givens(h, &G);
|
|
|
| - // now compute our scale factors
|
| - SkScalar sx = m.getScaleX();
|
| - SkScalar sy = m.getScaleY();
|
| + // GA is the matrix A with rotation removed.
|
| + SkMatrix GA(G);
|
| + GA.preConcat(A);
|
|
|
| - fMatrix22Scalar.reset();
|
| + sx = SkScalarAbs(GA.get(SkMatrix::kMScaleX));
|
| + sy = SkScalarAbs(GA.get(SkMatrix::kMScaleY));
|
|
|
| - if (m.getSkewX() || m.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 = sy = SkScalarAve(sx, sy);
|
| + // sA is the total matrix A without the text scale.
|
| + SkMatrix sA(A);
|
| + sA.preScale(SkScalarInvert(sx), SkScalarInvert(sy)); //remove text size
|
|
|
| - 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));
|
| - } else {
|
| - fMatrix22.xx = fMatrix22.yy = SK_Fixed1;
|
| - fMatrix22.xy = fMatrix22.yx = 0;
|
| + 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());
|
|
|
| fLCDIsVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag);
|
|
|
|
|