From f95f135c485305abede487df9a7fd2d0efc0ed20 Mon Sep 17 00:00:00 2001 From: Ben Wagner Date: Fri, 14 Apr 2017 11:39:34 -0400 Subject: [PATCH] Fix advances for aliased text with DirectWrite. The existing code assumes that GetGdiCompatibleGlyphMetrics transform parameter acts the same as the GetGlyphOutlineW lpmat2 parameter. However, it appears this is very much not true. BUG=skia:6499 Change-Id: I88c762b27acd09cc746da4d6e2b901540876908a Reviewed-on: https://skia-review.googlesource.com/13479 Reviewed-by: Ben Wagner Commit-Queue: Ben Wagner --- src/ports/SkScalerContext_win_dw.cpp | 27 +++++++++------------------ src/ports/SkScalerContext_win_dw.h | 8 -------- 2 files changed, 9 insertions(+), 26 deletions(-) diff --git a/src/ports/SkScalerContext_win_dw.cpp b/src/ports/SkScalerContext_win_dw.cpp index 10afb5a..729a738 100644 --- a/src/ports/SkScalerContext_win_dw.cpp +++ b/src/ports/SkScalerContext_win_dw.cpp @@ -236,9 +236,7 @@ SkScalerContext_DW::SkScalerContext_DW(sk_sp typefaceRef, // horizontal glyphs and the subpixel flag should not affect glyph shapes. SkVector scale; - SkMatrix GsA; - fRec.computeMatrices(SkScalerContextRec::kVertical_PreMatrixScale, - &scale, &fSkXform, &GsA, &fG_inv); + fRec.computeMatrices(SkScalerContextRec::kVertical_PreMatrixScale, &scale, &fSkXform); fXform.m11 = SkScalarToFloat(fSkXform.getScaleX()); fXform.m12 = SkScalarToFloat(fSkXform.getSkewY()); @@ -247,13 +245,6 @@ SkScalerContext_DW::SkScalerContext_DW(sk_sp typefaceRef, fXform.dx = 0; fXform.dy = 0; - fGsA.m11 = SkScalarToFloat(GsA.get(SkMatrix::kMScaleX)); - fGsA.m12 = SkScalarToFloat(GsA.get(SkMatrix::kMSkewY)); // This should be ~0. - fGsA.m21 = SkScalarToFloat(GsA.get(SkMatrix::kMSkewX)); - fGsA.m22 = SkScalarToFloat(GsA.get(SkMatrix::kMScaleY)); - fGsA.dx = 0; - fGsA.dy = 0; - // realTextSize is the actual device size we want (as opposed to the size the user requested). // gdiTextSize is the size we request when GDI compatible. // If the scale is negative, this means the matrix will do the flip anyway. @@ -367,7 +358,9 @@ void SkScalerContext_DW::generateAdvance(SkGlyph* glyph) { HRVM(this->getDWriteTypeface()->fDWriteFontFace->GetGdiCompatibleGlyphMetrics( fTextSizeMeasure, 1.0f, // pixelsPerDip - &fGsA, + // This parameter does not act like the lpmat2 parameter to GetGlyphOutlineW. + // If it did then GsA here and G_inv below to mapVectors. + nullptr, DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode, &glyphId, 1, &gm), @@ -387,20 +380,18 @@ void SkScalerContext_DW::generateAdvance(SkGlyph* glyph) { SkIntToScalar(gm.advanceWidth), SkIntToScalar(dwfm.designUnitsPerEm)); - SkVector vecs[1] = { { advanceX, 0 } }; + SkVector advance = { advanceX, 0 }; if (DWRITE_MEASURING_MODE_GDI_CLASSIC == fMeasuringMode || DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode) { // DirectWrite produced 'compatible' metrics, but while close, // the end result is not always an integer as it would be with GDI. - vecs[0].fX = SkScalarRoundToScalar(advanceX); - fG_inv.mapVectors(vecs, SK_ARRAY_COUNT(vecs)); - } else { - fSkXform.mapVectors(vecs, SK_ARRAY_COUNT(vecs)); + advance.fX = SkScalarRoundToScalar(advance.fX); } + fSkXform.mapVectors(&advance, 1); - glyph->fAdvanceX = SkScalarToFloat(vecs[0].fX); - glyph->fAdvanceY = SkScalarToFloat(vecs[0].fY); + glyph->fAdvanceX = SkScalarToFloat(advance.fX); + glyph->fAdvanceY = SkScalarToFloat(advance.fY); } HRESULT SkScalerContext_DW::getBoundingBox(SkGlyph* glyph, diff --git a/src/ports/SkScalerContext_win_dw.h b/src/ports/SkScalerContext_win_dw.h index 7b45c32..695a10f 100644 --- a/src/ports/SkScalerContext_win_dw.h +++ b/src/ports/SkScalerContext_win_dw.h @@ -64,14 +64,6 @@ private: SkMatrix fSkXform; /** The total matrix without the text height scale. */ DWRITE_MATRIX fXform; - /** The non-rotational part of total matrix without the text height scale. - * This is used to find the magnitude of gdi compatible advances. - */ - DWRITE_MATRIX fGsA; - /** The inverse of the rotational part of the total matrix. - * This is used to find the direction of gdi compatible advances. - */ - SkMatrix fG_inv; /** The text size to render with. */ SkScalar fTextSizeRender; /** The text size to measure with. */ -- 2.7.4