diff options
author | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-05-17 14:04:41 +0000 |
---|---|---|
committer | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-05-17 14:04:41 +0000 |
commit | 1dd17a133f4fa5c5a0c752e6b9a6f7af6f329fb8 (patch) | |
tree | f065be816c67eb2111981d40a0e65a77e7e6d937 /src | |
parent | a9015f897cd32f549349994e8163ead1db442088 (diff) |
use hires metrics when rotated (or subpixel is requested)
git-svn-id: http://skia.googlecode.com/svn/trunk@1342 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src')
-rwxr-xr-x | src/ports/SkFontHost_win.cpp | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp index e274a9884b..f406f7673e 100755 --- a/src/ports/SkFontHost_win.cpp +++ b/src/ports/SkFontHost_win.cpp @@ -272,6 +272,10 @@ private: HFONT fFont; SCRIPT_CACHE fSC; int fGlyphCount; + + HFONT fHiResFont; + MAT2 fMat22Identity; + SkMatrix fHiResMatrix; }; static float mul2float(SkScalar a, SkScalar b) { @@ -284,6 +288,16 @@ static FIXED float2FIXED(float x) { static SkMutex gFTMutex; +#define HIRES_TEXTSIZE 2048 +#define HIRES_SHIFT 11 +static inline SkFixed HiResToFixed(int value) { + return value << (16 - HIRES_SHIFT); +} + +static bool needHiResMetrics(const SkScalar mat[2][2]) { + return mat[1][0] || mat[0][1]; +} + SkScalerContext_Windows::SkScalerContext_Windows(const SkDescriptor* desc) : SkScalerContext(desc), fDDC(0), fFont(0), fSavefont(0), fSC(0) , fGlyphCount(-1) { @@ -304,6 +318,7 @@ SkScalerContext_Windows::SkScalerContext_Windows(const SkDescriptor* desc) fMat22.eM22 = float2FIXED(-fXform.eM22); fDDC = ::CreateCompatibleDC(NULL); + SetGraphicsMode(fDDC, GM_ADVANCED); SetBkMode(fDDC, TRANSPARENT); // Scaling by the DPI is inconsistent with how Skia draws elsewhere @@ -312,6 +327,21 @@ SkScalerContext_Windows::SkScalerContext_Windows(const SkDescriptor* desc) GetLogFontByID(fRec.fFontID, &lf); lf.lfHeight = -gCanonicalTextSize; fFont = CreateFontIndirect(&lf); + + // if we're rotated, or want fractional widths, create a hires font + fHiResFont = 0; + if (needHiResMetrics(fRec.fPost2x2) || (fRec.fFlags & kSubpixelPositioning_Flag)) { + lf.lfHeight = -HIRES_TEXTSIZE; + fHiResFont = CreateFontIndirect(&lf); + + fMat22Identity.eM11 = fMat22Identity.eM22 = SkFixedToFIXED(SK_Fixed1); + fMat22Identity.eM12 = fMat22Identity.eM21 = SkFixedToFIXED(0); + + // construct a matrix to go from HIRES logical units to our device units + fRec.getSingleMatrix(&fHiResMatrix); + SkScalar scale = SkScalarInvert(SkIntToScalar(HIRES_TEXTSIZE)); + fHiResMatrix.preScale(scale, scale); + } fSavefont = (HFONT)SelectObject(fDDC, fFont); } @@ -323,6 +353,9 @@ SkScalerContext_Windows::~SkScalerContext_Windows() { if (fFont) { ::DeleteObject(fFont); } + if (fHiResFont) { + ::DeleteObject(fHiResFont); + } if (fSC) { ::ScriptFreeCache(&fSC); } @@ -369,7 +402,7 @@ void SkScalerContext_Windows::generateMetrics(SkGlyph* glyph) { SkASSERT(fDDC); GLYPHMETRICS gm; - memset(&gm, 0, sizeof(gm)); + sk_bzero(&gm, sizeof(gm)); glyph->fRsbDelta = 0; glyph->fLsbDelta = 0; @@ -400,6 +433,19 @@ void SkScalerContext_Windows::generateMetrics(SkGlyph* glyph) { glyph->fTop -= 1; glyph->fLeft -= 1; } + + if (fHiResFont) { + SelectObject(fDDC, fHiResFont); + sk_bzero(&gm, sizeof(gm)); + ret = GetGlyphOutlineW(fDDC, glyph->getGlyphID(0), GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, NULL, &fMat22Identity); + if (GDI_ERROR != ret) { + SkPoint advance; + fHiResMatrix.mapXY(SkIntToScalar(gm.gmCellIncX), SkIntToScalar(gm.gmCellIncY), &advance); + glyph->fAdvanceX = SkScalarToFixed(advance.fX); + glyph->fAdvanceY = SkScalarToFixed(advance.fY); + } + SelectObject(fDDC, fFont); + } } else { glyph->fWidth = 0; } @@ -479,9 +525,9 @@ void SkScalerContext_Windows::generateImage(const SkGlyph& glyph) { size_t size = glyph.fHeight * srcRB; memset(bits, 0xFF, size); + SetGraphicsMode(dc, GM_ADVANCED); SetBkMode(dc, TRANSPARENT); SetTextAlign(dc, TA_LEFT | TA_BASELINE); - SetGraphicsMode(dc, GM_ADVANCED); XFORM xform = fXform; xform.eDx = (float)-glyph.fLeft; |