Add support for forcing autohinting.
http://codereview.appspot.com/1651044/show
git-svn-id: http://skia.googlecode.com/svn/trunk@580 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h
index 5fef527..722bc5d 100644
--- a/include/core/SkPaint.h
+++ b/include/core/SkPaint.h
@@ -110,10 +110,11 @@
kDevKernText_Flag = 0x100, //!< mask to enable device kerning text
kLCDRenderText_Flag = 0x200, //!< mask to enable subpixel glyph renderering
kEmbeddedBitmapText_Flag = 0x400, //!< mask to enable embedded bitmap strikes
+ kAutoHinting_Flag = 0x800, //!< mask to force Freetype's autohinter
// when adding extra flags, note that the fFlags member is specified
// with a bit-width and you'll have to expand it.
- kAllFlags = 0x7FF
+ kAllFlags = 0xFFF
};
/** Return the paint's flags. Use the Flag enum to test flag values.
@@ -202,6 +203,18 @@
*/
void setEmbeddedBitmapText(bool useEmbeddedBitmapText);
+ bool isAutohinted() const
+ {
+ return SkToBool(this->getFlags() & kAutoHinting_Flag);
+ }
+
+ /** Helper for setFlags(), setting or clearing the kAutoHinting_Flag bit
+ @param useAutohinter true to set the kEmbeddedBitmapText bit in the
+ paint's flags,
+ false to clear it.
+ */
+ void setAutohinted(bool useAutohinter);
+
/** Helper for getFlags(), returning true if kUnderlineText_Flag bit is set
@return true if the underlineText bit is set in the paint's flags.
*/
@@ -823,7 +836,7 @@
SkColor fColor;
SkScalar fWidth;
SkScalar fMiterLimit;
- unsigned fFlags : 11;
+ unsigned fFlags : 12;
unsigned fTextAlign : 2;
unsigned fCapType : 2;
unsigned fJoinType : 2;
diff --git a/include/core/SkScalerContext.h b/include/core/SkScalerContext.h
index 59d7125..7cb0d2f 100644
--- a/include/core/SkScalerContext.h
+++ b/include/core/SkScalerContext.h
@@ -156,6 +156,8 @@
kHintingBit2_Flag = 0x20,
kEmbeddedBitmapText_Flag = 0x40,
kEmbolden_Flag = 0x80,
+ kSubpixelPositioning_Flag = 0x100,
+ kAutohinting_Flag = 0x200,
};
private:
enum {
@@ -167,10 +169,9 @@
SkScalar fTextSize, fPreScaleX, fPreSkewX;
SkScalar fPost2x2[2][2];
SkScalar fFrameWidth, fMiterLimit;
- bool fSubpixelPositioning;
uint8_t fMaskFormat;
uint8_t fStrokeJoin;
- uint8_t fFlags;
+ uint16_t fFlags;
// Warning: when adding members note that the size of this structure
// must be a multiple of 4. SkDescriptor requires that its arguments be
// multiples of four and this structure is put in an SkDescriptor in
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index f28e15c..21b7534 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -160,6 +160,11 @@
this->setFlags(SkSetClearMask(fFlags, doEmbeddedBitmapText, kEmbeddedBitmapText_Flag));
}
+void SkPaint::setAutohinted(bool useAutohinter)
+{
+ this->setFlags(SkSetClearMask(fFlags, useAutohinter, kAutoHinting_Flag));
+}
+
void SkPaint::setLinearText(bool doLinearText)
{
this->setFlags(SkSetClearMask(fFlags, doLinearText, kLinearText_Flag));
@@ -1311,12 +1316,15 @@
rec->fStrokeJoin = 0;
}
- rec->fSubpixelPositioning = paint.isSubpixelText();
rec->fMaskFormat = SkToU8(computeMaskFormat(paint));
rec->fFlags = SkToU8(flags);
rec->setHinting(computeHinting(paint));
if (paint.isEmbeddedBitmapText())
rec->fFlags |= SkScalerContext::kEmbeddedBitmapText_Flag;
+ if (paint.isSubpixelText())
+ rec->fFlags |= SkScalerContext::kSubpixelPositioning_Flag;
+ if (paint.isAutohinted())
+ rec->fFlags |= SkScalerContext::kAutohinting_Flag;
/* Allow the fonthost to modify our rec before we use it as a key into the
cache. This way if we're asking for something that they will ignore,
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp
index fd85bb2..b7645dd 100644
--- a/src/ports/SkFontHost_FreeType.cpp
+++ b/src/ports/SkFontHost_FreeType.cpp
@@ -293,7 +293,8 @@
if (SkPaint::kFull_Hinting == h && !rec->isLCD()) {
// collapse full->normal hinting if we're not doing LCD
h = SkPaint::kNormal_Hinting;
- } else if (rec->fSubpixelPositioning && SkPaint::kNo_Hinting != h) {
+ } else if ((rec->fFlags & SkScalerContext::kSubpixelPositioning_Flag) &&
+ SkPaint::kNo_Hinting != h) {
// to do subpixel, we must have at most slight hinting
h = SkPaint::kSlight_Hinting;
}
@@ -379,9 +380,16 @@
loadFlags = FT_LOAD_TARGET_LIGHT; // This implies FORCE_AUTOHINT
break;
case SkPaint::kNormal_Hinting:
- loadFlags = FT_LOAD_TARGET_NORMAL;
+ if (fRec.fFlags & SkScalerContext::kAutohinting_Flag)
+ loadFlags = FT_LOAD_FORCE_AUTOHINT;
+ else
+ loadFlags = FT_LOAD_NO_AUTOHINT;
break;
case SkPaint::kFull_Hinting:
+ if (fRec.fFlags & SkScalerContext::kAutohinting_Flag) {
+ loadFlags = FT_LOAD_FORCE_AUTOHINT;
+ break;
+ }
loadFlags = FT_LOAD_TARGET_NORMAL;
if (SkMask::kHorizontalLCD_Format == fRec.fMaskFormat)
loadFlags = FT_LOAD_TARGET_LCD;
@@ -587,7 +595,7 @@
}
FT_Outline_Get_CBox(&fFace->glyph->outline, &bbox);
- if (fRec.fSubpixelPositioning) {
+ if (fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) {
int dx = glyph->getSubXFixed() >> 10;
int dy = glyph->getSubYFixed() >> 10;
// negate dy since freetype-y-goes-up and skia-y-goes-down
@@ -624,7 +632,7 @@
goto ERROR;
}
- if (!fRec.fSubpixelPositioning) {
+ if ((fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) == 0) {
glyph->fAdvanceX = SkFDot6ToFixed(fFace->glyph->advance.x);
glyph->fAdvanceY = -SkFDot6ToFixed(fFace->glyph->advance.y);
if (fRec.fFlags & kDevKernText_Flag) {
@@ -684,7 +692,7 @@
}
int dx = 0, dy = 0;
- if (fRec.fSubpixelPositioning) {
+ if (fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) {
dx = glyph.getSubXFixed() >> 10;
dy = glyph.getSubYFixed() >> 10;
// negate dy since freetype-y-goes-up and skia-y-goes-down
diff --git a/src/ports/SkFontHost_mac_atsui.cpp b/src/ports/SkFontHost_mac_atsui.cpp
index a0239e2..9c01dfe 100644
--- a/src/ports/SkFontHost_mac_atsui.cpp
+++ b/src/ports/SkFontHost_mac_atsui.cpp
@@ -246,7 +246,7 @@
return;
}
- if (!fRec.fSubpixelPositioning) {
+ if ((fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) == 0) {
glyph->fAdvanceX = SkFloatToFixed(screenMetrics.deviceAdvance.x);
glyph->fAdvanceY = -SkFloatToFixed(screenMetrics.deviceAdvance.y);
} else {