This patch allows the use of the native FreeType emboldening
authorsenorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 5 Feb 2010 23:08:20 +0000 (23:08 +0000)
committersenorblanco@chromium.org <senorblanco@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 5 Feb 2010 23:08:20 +0000 (23:08 +0000)
algorithm when "fake bold" text is used in SkPaint.

It's enabled by #defining SK_USE_FREETYPE_EMBOLDEN.

Review URL:  http://codereview.appspot.com/198077

git-svn-id: http://skia.googlecode.com/svn/trunk@490 2bbb7eff-a529-9590-31e7-b0007b416f81

include/core/SkScalerContext.h
src/core/SkPaint.cpp
src/ports/SkFontHost_FreeType.cpp

index 6aae316..59d7125 100644 (file)
@@ -155,6 +155,7 @@ public:
         kHintingBit1_Flag   = 0x10,
         kHintingBit2_Flag   = 0x20,
         kEmbeddedBitmapText_Flag = 0x40,
+        kEmbolden_Flag      = 0x80,
     };
 private:
     enum {
index 0261ca6..a013412 100644 (file)
@@ -1252,8 +1252,13 @@ void SkScalerContext::MakeRec(const SkPaint& paint,
     SkPaint::Style  style = paint.getStyle();
     SkScalar        strokeWidth = paint.getStrokeWidth();
     
+    unsigned flags = SkFontHost::ComputeGammaFlag(paint);
+
     if (paint.isFakeBoldText())
     {
+#ifdef SK_USE_FREETYPE_EMBOLDEN
+        flags |= SkScalerContext::kEmbolden_Flag;
+#else
         SkScalar fakeBoldScale = interpolate(paint.getTextSize(), pointSizes, multipliers, 2);
         SkScalar extra = SkScalarMul(paint.getTextSize(), fakeBoldScale);
         
@@ -1264,10 +1269,9 @@ void SkScalerContext::MakeRec(const SkPaint& paint,
         }
         else
             strokeWidth += extra;
+#endif
     }
 
-    unsigned flags = SkFontHost::ComputeGammaFlag(paint);
-
     if (paint.isDevKernText())
         flags |= SkScalerContext::kDevKernText_Flag;
     
index ae5f738..d734b8e 100644 (file)
@@ -126,6 +126,7 @@ private:
     uint32_t    fLoadGlyphFlags;
 
     FT_Error setupSize();
+    void emboldenOutline(FT_Outline* outline);
 };
 
 ///////////////////////////////////////////////////////////////////////////
@@ -463,6 +464,13 @@ FT_Error SkScalerContext_FreeType::setupSize() {
     return err;
 }
 
+void SkScalerContext_FreeType::emboldenOutline(FT_Outline* outline) {
+    FT_Pos strength;
+    strength = FT_MulFix(fFace->units_per_EM, fFace->size->metrics.y_scale)
+               / 24;
+    FT_Outline_Embolden(outline, strength);
+}
+
 unsigned SkScalerContext_FreeType::generateGlyphCount() const {
     return fFace->num_glyphs;
 }
@@ -558,6 +566,9 @@ void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph) {
       case FT_GLYPH_FORMAT_OUTLINE:
         FT_BBox bbox;
 
+        if (fRec.fFlags & kEmbolden_Flag) {
+            emboldenOutline(&fFace->glyph->outline);
+        }
         FT_Outline_Get_CBox(&fFace->glyph->outline, &bbox);
 
         if (fRec.fSubpixelPositioning) {
@@ -648,6 +659,10 @@ void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) {
             FT_BBox     bbox;
             FT_Bitmap   target;
 
+            if (fRec.fFlags & kEmbolden_Flag) {
+                emboldenOutline(outline);
+            }
+
             int dx = 0, dy = 0;
             if (fRec.fSubpixelPositioning) {
                 dx = glyph.getSubXFixed() >> 10;
@@ -820,6 +835,10 @@ void SkScalerContext_FreeType::generatePath(const SkGlyph& glyph,
         return;
     }
 
+    if (fRec.fFlags & kEmbolden_Flag) {
+        emboldenOutline(&fFace->glyph->outline);
+    }
+
     FT_Outline_Funcs    funcs;
 
     funcs.move_to   = move_proc;
@@ -898,6 +917,9 @@ void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* mx,
         if (x_glyph) {
             FT_BBox bbox;
             FT_Load_Glyph(fFace, x_glyph, fLoadGlyphFlags);
+            if (fRec.fFlags & kEmbolden_Flag) {
+                emboldenOutline(&fFace->glyph->outline);
+            }
             FT_Outline_Get_CBox(&fFace->glyph->outline, &bbox);
             x_height = SkIntToScalar(bbox.yMax) / 64;
         } else {