From 4526a847da6dc738dc73103ec4d47cc0dbdec478 Mon Sep 17 00:00:00 2001 From: "senorblanco@chromium.org" Date: Fri, 5 Feb 2010 23:08:20 +0000 Subject: [PATCH] This patch allows the use of the native FreeType emboldening 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 | 1 + src/core/SkPaint.cpp | 8 ++++++-- src/ports/SkFontHost_FreeType.cpp | 22 ++++++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/include/core/SkScalerContext.h b/include/core/SkScalerContext.h index 6aae31644..59d7125d5 100644 --- a/include/core/SkScalerContext.h +++ b/include/core/SkScalerContext.h @@ -155,6 +155,7 @@ public: kHintingBit1_Flag = 0x10, kHintingBit2_Flag = 0x20, kEmbeddedBitmapText_Flag = 0x40, + kEmbolden_Flag = 0x80, }; private: enum { diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp index 0261ca68d..a0134123d 100644 --- a/src/core/SkPaint.cpp +++ b/src/core/SkPaint.cpp @@ -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; diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp index ae5f738de..d734b8e78 100644 --- a/src/ports/SkFontHost_FreeType.cpp +++ b/src/ports/SkFontHost_FreeType.cpp @@ -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 {