diff options
author | bungeman <bungeman@google.com> | 2016-02-29 11:22:55 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-02-29 11:22:55 -0800 |
commit | 27876bc1156bcdd15cac7f0fe6228eb7806b8e96 (patch) | |
tree | dc5617a6be3255ce9eced721e9c3004dc8f58bcf /src | |
parent | 10d8fc29bc1605c134e98f5b58c2efb73cef6073 (diff) |
Improve horizontal baseline detection.
The goal is to hint the baseline when hinting is possible, which is
to say when the glyphs are be aligned with the pixel grid. The
current code has three shortcomings.
1. correctly snaps when the horizontal baseline is on the x-axis but
not when on the y-axis. Instead it is snapping the horizontal
baseline when there is y-skew.
2. tests against the full device matrix instead of the relaxed
matrix used by the scaler context.
3. has range issues when relaxing the matrix.
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1740163002
Review URL: https://codereview.chromium.org/1740163002
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkFindAndPlaceGlyph.h | 6 | ||||
-rw-r--r-- | src/core/SkPaint.cpp | 2 | ||||
-rw-r--r-- | src/core/SkScalerContext.cpp | 18 | ||||
-rw-r--r-- | src/core/SkScalerContext.h | 29 | ||||
-rw-r--r-- | src/ports/SkFontHost_mac.cpp | 5 |
5 files changed, 31 insertions, 29 deletions
diff --git a/src/core/SkFindAndPlaceGlyph.h b/src/core/SkFindAndPlaceGlyph.h index 78a02c0e4d..18b93f70a4 100644 --- a/src/core/SkFindAndPlaceGlyph.h +++ b/src/core/SkFindAndPlaceGlyph.h @@ -587,9 +587,8 @@ inline void SkFindAndPlaceGlyph::ProcessPosText( SkPaint::Align textAlignment, SkGlyphCache* cache, ProcessOneGlyph&& processOneGlyph) { - SkAxisAlignment axisAlignment = SkComputeAxisAlignmentForHText(matrix); + SkAxisAlignment axisAlignment = cache->getScalerContext()->computeAxisAlignmentForHText(); uint32_t mtype = matrix.getType(); - LookupGlyph glyphFinder(textEncoding, cache); // Specialized code for handling the most common case for blink. The while loop is totally @@ -710,7 +709,8 @@ inline void SkFindAndPlaceGlyph::ProcessText( GlyphFindAndPlace<ProcessOneGlyph> findAndPosition{ [&](typename GlyphFindAndPlace<ProcessOneGlyph>::Variants* to_init) { if (cache->isSubpixel()) { - SkAxisAlignment axisAlignment = SkComputeAxisAlignmentForHText(matrix); + SkAxisAlignment axisAlignment = + cache->getScalerContext()->computeAxisAlignmentForHText(); InitSubpixel<ProcessOneGlyph, SkPaint::kLeft_Align>( to_init, axisAlignment, glyphFinder); } else { diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp index 060e905ec7..017662ff48 100644 --- a/src/core/SkPaint.cpp +++ b/src/core/SkPaint.cpp @@ -1318,7 +1318,7 @@ static bool too_big_for_lcd(const SkScalerContext::Rec& rec, bool checkPost2x2) * typically returns the same looking resuts for tiny changes in the matrix. */ static SkScalar sk_relax(SkScalar x) { - int n = sk_float_round2int(x * 1024); + SkScalar n = SkScalarRoundToScalar(x * 1024); return n / 1024.0f; } diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp index caef2d1377..c67ca3e9fa 100644 --- a/src/core/SkScalerContext.cpp +++ b/src/core/SkScalerContext.cpp @@ -827,13 +827,21 @@ void SkScalerContextRec::computeMatrices(PreMatrixScale preMatrixScale, SkVector } } -SkAxisAlignment SkComputeAxisAlignmentForHText(const SkMatrix& matrix) { - SkASSERT(!matrix.hasPerspective()); - - if (0 == matrix[SkMatrix::kMSkewY]) { +SkAxisAlignment SkScalerContext::computeAxisAlignmentForHText() { + // Why fPost2x2 can be used here. + // getSingleMatrix multiplies in getLocalMatrix, which consists of + // * fTextSize (a scale, which has no effect) + // * fPreScaleX (a scale in x, which has no effect) + // * fPreSkewX (has no effect, but would on vertical text alignment). + // In other words, making the text bigger, stretching it along the + // horizontal axis, or fake italicizing it does not move the baseline. + + if (0 == fRec.fPost2x2[1][0]) { + // The x axis is mapped onto the x axis. return kX_SkAxisAlignment; } - if (0 == matrix[SkMatrix::kMSkewX]) { + if (0 == fRec.fPost2x2[0][0]) { + // The x axis is mapped onto the y axis. return kY_SkAxisAlignment; } return kNone_SkAxisAlignment; diff --git a/src/core/SkScalerContext.h b/src/core/SkScalerContext.h index 302698ee4e..9249bfb2a9 100644 --- a/src/core/SkScalerContext.h +++ b/src/core/SkScalerContext.h @@ -20,6 +20,12 @@ class SkMaskFilter; class SkPathEffect; class SkRasterizer; +enum SkAxisAlignment { + kNone_SkAxisAlignment, + kX_SkAxisAlignment, + kY_SkAxisAlignment +}; + /* * To allow this to be forward-declared, it must be its own typename, rather * than a nested struct inside SkScalerContext (where it started). @@ -245,6 +251,13 @@ public: const Rec& getRec() const { return fRec; } + /** + * Return the axis (if any) that the baseline for horizontal text should land on. + * As an example, the identity matrix will return kX_SkAxisAlignment + */ + SkAxisAlignment computeAxisAlignmentForHText(); + + protected: Rec fRec; @@ -340,22 +353,6 @@ private: /////////////////////////////////////////////////////////////////////////////// -enum SkAxisAlignment { - kNone_SkAxisAlignment, - kX_SkAxisAlignment, - kY_SkAxisAlignment -}; - -/** - * Return the axis (if any) that the baseline for horizontal text will land on - * after running through the specified matrix. - * - * As an example, the identity matrix will return kX_SkAxisAlignment - */ -SkAxisAlignment SkComputeAxisAlignmentForHText(const SkMatrix& matrix); - -/////////////////////////////////////////////////////////////////////////////// - SkPaint::Hinting SkScalerContextRec::getHinting() const { unsigned hint = (fFlags & SkScalerContext::kHinting_Mask) >> SkScalerContext::kHinting_Shift; diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp index c4e80b67c0..f1724b675b 100644 --- a/src/ports/SkFontHost_mac.cpp +++ b/src/ports/SkFontHost_mac.cpp @@ -1359,13 +1359,10 @@ void SkScalerContext_Mac::generatePath(const SkGlyph& glyph, SkPath* path) { * direction, ask for the path, and then scale the path back down. */ if (fDoSubPosition) { - SkMatrix m; - fRec.getSingleMatrix(&m); - // start out by assuming that we want no hining in X and Y scaleX = scaleY = kScaleForSubPixelPositionHinting; // now see if we need to restore hinting for axis-aligned baselines - switch (SkComputeAxisAlignmentForHText(m)) { + switch (this->computeAxisAlignmentForHText()) { case kX_SkAxisAlignment: scaleY = SK_Scalar1; // want hinting in the Y direction break; |