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 {