aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/ports
diff options
context:
space:
mode:
authorGravatar bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-10-03 20:17:51 +0000
committerGravatar bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-10-03 20:17:51 +0000
commit11ba3199f3edc7883ada4fd941d231f8f4883720 (patch)
treeff4a2e66da45036ff0e0a8adacfe3679ddb773b7 /src/ports
parent608ea6508ae2e9ea05ea863ba50fc27d44d2eae9 (diff)
Snap GDI matrix when snapping height.
When using GDI to render, ensure that the GDI matrix does not attempt to add subpixel height. This ensures that rotated text is always the same height as axis aligned text and prevents subpixel drift metrics when they are unwanted. R=reed@google.com Review URL: https://codereview.chromium.org/25739002 git-svn-id: http://skia.googlecode.com/svn/trunk@11592 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/ports')
-rwxr-xr-xsrc/ports/SkFontHost_win.cpp34
1 files changed, 21 insertions, 13 deletions
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp
index 7394755408..a3ed21224f 100755
--- a/src/ports/SkFontHost_win.cpp
+++ b/src/ports/SkFontHost_win.cpp
@@ -663,17 +663,25 @@ SkScalerContext_GDI::SkScalerContext_GDI(SkTypeface* rawTypeface,
SkMatrix GA(G);
GA.preConcat(A);
- // textSize is the actual device size we want (as opposed to the size the user requested).
+ // realTextSize is the actual device size we want (as opposed to the size the user requested).
+ // gdiTextSide is the size we request from GDI.
// If the scale is negative, this means the matrix will do the flip anyway.
- SkScalar textSize = SkScalarAbs(SkScalarRoundToScalar(GA.get(SkMatrix::kMScaleY)));
- if (textSize == 0) {
- textSize = SK_Scalar1;
+ SkScalar realTextSize = SkScalarAbs(GA.get(SkMatrix::kMScaleY));
+ SkScalar gdiTextSize = SkScalarRoundToScalar(realTextSize);
+ if (gdiTextSize == 0) {
+ gdiTextSize = SK_Scalar1;
}
+ // When not hinting, remove only the gdiTextSize scale which will be applied by GDI.
+ // When GDI hinting, remove the entire Y scale to prevent 'subpixel' metrics.
+ SkScalar scale = (fRec.getHinting() == SkPaint::kNo_Hinting ||
+ fRec.getHinting() == SkPaint::kSlight_Hinting)
+ ? SkScalarInvert(gdiTextSize)
+ : SkScalarInvert(realTextSize);
+
// sA is the total matrix A without the textSize (so GDI knows the text size separately).
// When this matrix is used with GetGlyphOutline, no further processing is needed.
SkMatrix sA(A);
- SkScalar scale = SkScalarInvert(textSize);
sA.preScale(scale, scale); //remove text size
// GsA is the non-rotational part of A without the text height scale.
@@ -692,7 +700,7 @@ SkScalerContext_GDI::SkScalerContext_GDI(SkTypeface* rawTypeface,
G.get(SkMatrix::kMPersp0), G.get(SkMatrix::kMPersp1), G.get(SkMatrix::kMPersp2));
LOGFONT lf = typeface->fLogFont;
- lf.lfHeight = -SkScalarTruncToInt(textSize);
+ lf.lfHeight = -SkScalarTruncToInt(gdiTextSize);
lf.lfQuality = compute_quality(fRec);
fFont = CreateFontIndirect(&lf);
if (!fFont) {
@@ -742,7 +750,7 @@ SkScalerContext_GDI::SkScalerContext_GDI(SkTypeface* rawTypeface,
this->forceGenerateImageFromPath();
}
- // Create a hires font if we need linear metrics.
+ // Create a hires matrix if we need linear metrics.
if (this->isSubpixel()) {
OUTLINETEXTMETRIC otm;
UINT success = GetOutlineTextMetrics(fDDC, sizeof(otm), &otm);
@@ -751,17 +759,17 @@ SkScalerContext_GDI::SkScalerContext_GDI(SkTypeface* rawTypeface,
success = GetOutlineTextMetrics(fDDC, sizeof(otm), &otm);
}
if (0 != success) {
- SkScalar scale = SkIntToScalar(otm.otmEMSquare);
+ SkScalar upem = SkIntToScalar(otm.otmEMSquare);
- SkScalar textScale = scale / textSize;
- fHighResMat22.eM11 = float2FIXED(textScale);
+ SkScalar gdiTextSizeToEMScale = upem / gdiTextSize;
+ fHighResMat22.eM11 = float2FIXED(gdiTextSizeToEMScale);
fHighResMat22.eM12 = float2FIXED(0);
fHighResMat22.eM21 = float2FIXED(0);
- fHighResMat22.eM22 = float2FIXED(textScale);
+ fHighResMat22.eM22 = float2FIXED(gdiTextSizeToEMScale);
- SkScalar invScale = SkScalarInvert(scale);
+ SkScalar removeEMScale = SkScalarInvert(upem);
fHiResMatrix = A;
- fHiResMatrix.preScale(invScale, invScale);
+ fHiResMatrix.preScale(removeEMScale, removeEMScale);
}
}