From 1f8787a99f15e37c40a1260c9c456ed91f11ba15 Mon Sep 17 00:00:00 2001 From: "wjmaclean@chromium.org" Date: Wed, 12 Sep 2012 15:53:20 +0000 Subject: [PATCH] Using the device scale factor for glyph positioning The master bug is http://code.google.com/p/chromium/issues/detail?id=138101 . The corresponding WebKit changes for this CL are here: https://bugs.webkit.org/show_bug.cgi?id=96137 BUG= Review URL: https://codereview.appspot.com/6506099 git-svn-id: http://skia.googlecode.com/svn/trunk@5508 2bbb7eff-a529-9590-31e7-b0007b416f81 --- gyp/common_conditions.gypi | 1 + include/core/SkPaint.h | 17 ++++++++++++++++ src/core/SkPaint.cpp | 33 +++++++++++++++++++++++++++++++ src/core/SkScalerContext.h | 3 +++ src/ports/SkFontHost_FreeType.cpp | 12 +++++++++++ 5 files changed, 66 insertions(+) diff --git a/gyp/common_conditions.gypi b/gyp/common_conditions.gypi index 1256ef6760..2a03c00607 100644 --- a/gyp/common_conditions.gypi +++ b/gyp/common_conditions.gypi @@ -3,6 +3,7 @@ { 'defines': [ 'SK_ALLOW_STATIC_GLOBAL_INITIALIZERS=<(skia_static_initializers)', + 'SK_SUPPORT_HINTING_SCALE_FACTOR', ], 'conditions' : [ ['skia_gpu == 1', diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h index 50fcdd825e..16b1b84c90 100644 --- a/include/core/SkPaint.h +++ b/include/core/SkPaint.h @@ -668,6 +668,20 @@ public: */ void setTextSkewX(SkScalar skewX); +#ifdef SK_SUPPORT_HINTING_SCALE_FACTOR + /** Return the paint's scale factor used for correctly rendering + glyphs in high DPI mode without text subpixel positioning. + @return the scale factor used for rendering glyphs in high DPI mode. + */ + SkScalar getHintingScaleFactor() const { return fHintingScaleFactor; } + + /** Set the paint's scale factor used for correctly rendering + glyphs in high DPI mode without text subpixel positioning. + @param the scale factor used for rendering glyphs in high DPI mode. + */ + void setHintingScaleFactor(SkScalar hintingScaleFactor); +#endif + /** Describes how to interpret the text parameters that are passed to paint methods like measureText() and getTextWidths(). */ @@ -910,6 +924,9 @@ private: SkScalar fTextSize; SkScalar fTextScaleX; SkScalar fTextSkewX; +#ifdef SK_SUPPORT_HINTING_SCALE_FACTOR + SkScalar fHintingScaleFactor; +#endif SkPathEffect* fPathEffect; SkShader* fShader; diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp index 7e0ea97cdc..506db0e9c3 100644 --- a/src/core/SkPaint.cpp +++ b/src/core/SkPaint.cpp @@ -64,6 +64,9 @@ SkPaint::SkPaint() { fTextSize = SkPaintDefaults_TextSize; fTextScaleX = SK_Scalar1; +#ifdef SK_SUPPORT_HINTING_SCALE_FACTOR + fHintingScaleFactor = SK_Scalar1; +#endif fColor = SK_ColorBLACK; fMiterLimit = SkPaintDefaults_MiterLimit; fFlags = SkPaintDefaults_Flags; @@ -343,6 +346,13 @@ void SkPaint::setTextSkewX(SkScalar skewX) { fTextSkewX = skewX; } +#ifdef SK_SUPPORT_HINTING_SCALE_FACTOR +void SkPaint::setHintingScaleFactor(SkScalar hintingScaleFactor) { + GEN_ID_INC_EVAL(hintingScaleFactor != fHintingScaleFactor); + fHintingScaleFactor = hintingScaleFactor; +} +#endif + void SkPaint::setTextEncoding(TextEncoding encoding) { if ((unsigned)encoding <= kGlyphID_TextEncoding) { GEN_ID_INC_EVAL((unsigned)encoding != fTextEncoding); @@ -1500,6 +1510,9 @@ void SkScalerContext::MakeRec(const SkPaint& paint, rec->fTextSize = paint.getTextSize(); rec->fPreScaleX = paint.getTextScaleX(); rec->fPreSkewX = paint.getTextSkewX(); +#ifdef SK_SUPPORT_HINTING_SCALE_FACTOR + rec->fHintingScaleFactor = paint.getHintingScaleFactor(); +#endif if (deviceMatrix) { rec->fPost2x2[0][0] = sk_relax(deviceMatrix->getScaleX()); @@ -1948,10 +1961,18 @@ enum FlatFlags { }; // The size of a flat paint's POD fields + +#ifdef SK_SUPPORT_HINTING_SCALE_FACTOR +static const uint32_t kPODPaintSize = 6 * sizeof(SkScalar) + + 1 * sizeof(SkColor) + + 1 * sizeof(uint16_t) + + 6 * sizeof(uint8_t); +#else static const uint32_t kPODPaintSize = 5 * sizeof(SkScalar) + 1 * sizeof(SkColor) + 1 * sizeof(uint16_t) + 6 * sizeof(uint8_t); +#endif /* To save space/time, we analyze the paint, and write a truncated version of it if there are not tricky elements like shaders, etc. @@ -1981,6 +2002,9 @@ void SkPaint::flatten(SkFlattenableWriteBuffer& buffer) const { ptr = write_scalar(ptr, this->getTextSize()); ptr = write_scalar(ptr, this->getTextScaleX()); ptr = write_scalar(ptr, this->getTextSkewX()); +#ifdef SK_SUPPORT_HINTING_SCALE_FACTOR + ptr = write_scalar(ptr, this->getHintingScaleFactor()); +#endif ptr = write_scalar(ptr, this->getStrokeWidth()); ptr = write_scalar(ptr, this->getStrokeMiter()); *ptr++ = this->getColor(); @@ -1997,6 +2021,9 @@ void SkPaint::flatten(SkFlattenableWriteBuffer& buffer) const { buffer.writeScalar(fTextSize); buffer.writeScalar(fTextScaleX); buffer.writeScalar(fTextSkewX); +#ifdef SK_SUPPORT_HINTING_SCALE_FACTOR + buffer.writeScalar(fHintingScaleFactor); +#endif buffer.writeScalar(fWidth); buffer.writeScalar(fMiterLimit); buffer.writeColor(fColor); @@ -2042,6 +2069,9 @@ void SkPaint::unflatten(SkFlattenableReadBuffer& buffer) { this->setTextSize(read_scalar(pod)); this->setTextScaleX(read_scalar(pod)); this->setTextSkewX(read_scalar(pod)); +#ifdef SK_SUPPORT_HINTING_SCALE_FACTOR + this->setHintingScaleFactor(read_scalar(pod)); +#endif this->setStrokeWidth(read_scalar(pod)); this->setStrokeMiter(read_scalar(pod)); this->setColor(*pod++); @@ -2068,6 +2098,9 @@ void SkPaint::unflatten(SkFlattenableReadBuffer& buffer) { this->setTextSize(buffer.readScalar()); this->setTextScaleX(buffer.readScalar()); this->setTextSkewX(buffer.readScalar()); +#ifdef SK_SUPPORT_HINTING_SCALE_FACTOR + this->setHintingScaleFactor(buffer.readScalar()); +#endif this->setStrokeWidth(buffer.readScalar()); this->setStrokeMiter(buffer.readScalar()); this->setColor(buffer.readColor()); diff --git a/src/core/SkScalerContext.h b/src/core/SkScalerContext.h index 2443aafe6e..8175582522 100644 --- a/src/core/SkScalerContext.h +++ b/src/core/SkScalerContext.h @@ -34,6 +34,9 @@ struct SkScalerContextRec { SkScalar fTextSize, fPreScaleX, fPreSkewX; SkScalar fPost2x2[2][2]; SkScalar fFrameWidth, fMiterLimit; +#ifdef SK_SUPPORT_HINTING_SCALE_FACTOR + SkScalar fHintingScaleFactor; +#endif //These describe the parameters to create (uniquely identify) the pre-blend. uint32_t fLumBits; diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp index f25223f750..ba0afd88a6 100644 --- a/src/ports/SkFontHost_FreeType.cpp +++ b/src/ports/SkFontHost_FreeType.cpp @@ -752,8 +752,20 @@ SkScalerContext_FreeType::SkScalerContext_FreeType(const SkDescriptor* desc) fMatrix22.xy = fMatrix22.yx = 0; } +#ifdef SK_SUPPORT_HINTING_SCALE_FACTOR + SkScalar hintingScaleFactor = fRec.fHintingScaleFactor; + + fScaleX = SkScalarToFixed(sx / hintingScaleFactor); + fScaleY = SkScalarToFixed(sy / hintingScaleFactor); + + fMatrix22.xx *= hintingScaleFactor; + fMatrix22.xy *= hintingScaleFactor; + fMatrix22.yx *= hintingScaleFactor; + fMatrix22.yy *= hintingScaleFactor; +#else fScaleX = SkScalarToFixed(sx); fScaleY = SkScalarToFixed(sy); +#endif fLCDIsVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag);