summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-05-17 14:04:41 +0000
committerreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-05-17 14:04:41 +0000
commit664a648948e576fb5ad0cbc62d3da90a66e17e14 (patch)
tree44304e83331b9cf9a8e9d9d6b7921ccce103f0fd
parentfcaa7dfdeca3101d3ce6e4ec852e790bce1b7b48 (diff)
downloadsrc-664a648948e576fb5ad0cbc62d3da90a66e17e14.tar.gz
use hires metrics when rotated (or subpixel is requested)
git-svn-id: http://skia.googlecode.com/svn/trunk/src@1342 2bbb7eff-a529-9590-31e7-b0007b416f81
-rwxr-xr-xports/SkFontHost_win.cpp50
1 files changed, 48 insertions, 2 deletions
diff --git a/ports/SkFontHost_win.cpp b/ports/SkFontHost_win.cpp
index e274a988..f406f767 100755
--- a/ports/SkFontHost_win.cpp
+++ b/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;