diff options
author | Derek Sollenberger <djsollen@google.com> | 2012-09-25 11:37:27 -0400 |
---|---|---|
committer | Derek Sollenberger <djsollen@google.com> | 2012-09-25 11:44:49 -0400 |
commit | 9c1f88b83a41904064023c69f3f0eb67548f4e80 (patch) | |
tree | 83ef4b483e37d72962e2690358a135cb948dc358 /src | |
parent | faa8dc5be4452ffc0e189e44734c075652158d7d (diff) | |
download | external_skia-9c1f88b83a41904064023c69f3f0eb67548f4e80.zip external_skia-9c1f88b83a41904064023c69f3f0eb67548f4e80.tar.gz external_skia-9c1f88b83a41904064023c69f3f0eb67548f4e80.tar.bz2 |
Update Skia's handling of vertical text when freetype metrics are available.
This is a cherry-pick of a larger change going into upstream Skia at...
https://codereview.appspot.com/6554064/
bug: 7124435
Change-Id: Id8b030afaf493741e133b592a4e08a3fd90ec2f3
Diffstat (limited to 'src')
-rw-r--r-- | src/ports/SkFontHost_FreeType.cpp | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp index d77ebb9..6c03bf9 100644 --- a/src/ports/SkFontHost_FreeType.cpp +++ b/src/ports/SkFontHost_FreeType.cpp @@ -174,6 +174,7 @@ private: FT_Matrix fMatrix22; uint32_t fLoadGlyphFlags; bool fDoLinearMetrics; + bool fUseVertMetrics; FT_Error setupSize(); void emboldenOutline(FT_Outline* outline); @@ -777,6 +778,7 @@ SkScalerContext_FreeType::SkScalerContext_FreeType(const SkDescriptor* desc) fScaleY = SkScalarToFixed(sy); // compute the flags we send to Load_Glyph + fUseVertMetrics = false; { FT_Int32 loadFlags = FT_LOAD_DEFAULT; bool linearMetrics = false; @@ -833,6 +835,12 @@ SkScalerContext_FreeType::SkScalerContext_FreeType(const SkDescriptor* desc) // See http://code.google.com/p/skia/issues/detail?id=222. loadFlags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH; + // Use vertical layout if requested and supported. + if ((fRec.fFlags & SkScalerContext::kVertical_Flag) && FT_HAS_VERTICAL(fFace)) { + loadFlags |= FT_LOAD_VERTICAL_LAYOUT; + fUseVertMetrics = true; + } + fLoadGlyphFlags = loadFlags; fDoLinearMetrics = linearMetrics; } @@ -1002,6 +1010,20 @@ void SkScalerContext_FreeType::getBBoxForCurrentGlyph(SkGlyph* glyph, bbox->xMax = (bbox->xMax + 63) & ~63; bbox->yMax = (bbox->yMax + 63) & ~63; } + + // Must come after snapToPixelBoundary so that the width and height are + // consistent. Otherwise asserts will fire later on when generating the + // glyph image. + if (fUseVertMetrics) { + FT_Vector vector; + vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metrics.horiBearingX; + vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metrics.horiBearingY; + FT_Vector_Transform(&vector, &fMatrix22); + bbox->xMin += vector.x; + bbox->xMax += vector.x; + bbox->yMin += vector.y; + bbox->yMax += vector.y; + } } void SkScalerContext_FreeType::updateGlyphIfLCD(SkGlyph* glyph) { @@ -1072,6 +1094,16 @@ void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph) { FT_GlyphSlot_Own_Bitmap(fFace->glyph); FT_Bitmap_Embolden(gFTLibrary, &fFace->glyph->bitmap, kBitmapEmboldenStrength, 0); } + + if (fUseVertMetrics) { + FT_Vector vector; + vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metrics.horiBearingX; + vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metrics.horiBearingY; + FT_Vector_Transform(&vector, &fMatrix22); + fFace->glyph->bitmap_left += SkFDot6Floor(vector.x); + fFace->glyph->bitmap_top += SkFDot6Floor(vector.y); + } + glyph->fWidth = SkToU16(fFace->glyph->bitmap.width); glyph->fHeight = SkToU16(fFace->glyph->bitmap.rows); glyph->fTop = -SkToS16(fFace->glyph->bitmap_top); @@ -1095,8 +1127,17 @@ void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph) { glyph->fAdvanceY = -SkFixedMul(fMatrix22.yx, fFace->glyph->linearHoriAdvance); } - if ((fRec.fFlags & SkScalerContext::kVertical_Flag) - && fFace->glyph->format == FT_GLYPH_FORMAT_OUTLINE) { + if (fUseVertMetrics) { + if (fDoLinearMetrics) { + glyph->fAdvanceX = -SkFixedMul(fMatrix22.xy, fFace->glyph->linearVertAdvance); + glyph->fAdvanceY = SkFixedMul(fMatrix22.yy, fFace->glyph->linearVertAdvance); + } else { + glyph->fAdvanceX = -SkFDot6ToFixed(fFace->glyph->advance.x); + glyph->fAdvanceY = SkFDot6ToFixed(fFace->glyph->advance.y); + } + + } else if ((fRec.fFlags & SkScalerContext::kVertical_Flag) + && fFace->glyph->format == FT_GLYPH_FORMAT_OUTLINE) { //TODO: do we need to specially handle SubpixelPositioning and Kerning? @@ -1537,6 +1578,14 @@ void SkScalerContext_FreeType::generatePath(const SkGlyph& glyph, emboldenOutline(&fFace->glyph->outline); } + if (fUseVertMetrics) { + FT_Vector vector; + vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metrics.horiBearingX; + vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metrics.horiBearingY; + FT_Vector_Transform(&vector, &fMatrix22); + FT_Outline_Translate(&fFace->glyph->outline, vector.x, vector.y); + } + FT_Outline_Funcs funcs; funcs.move_to = move_proc; |