From 02261affef21d3b41e1218083740673b9d63dcbd Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Mon, 18 Jul 2016 15:27:44 -0400 Subject: [PATCH] Bug 1287552 - part 2 - fix transformed bitmaps with Skia and FreeType. r=gw280 MozReview-Commit-ID: BqiLfOfZZwR --HG-- extra : rebase_source : 634873d2cc3069e06e2f9c3ea3dfa9e6c3f66961 --- .../skia/src/ports/SkFontHost_FreeType.cpp | 17 +++++++--- .../src/ports/SkFontHost_FreeType_common.cpp | 34 ++++++++++++------- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/gfx/skia/skia/src/ports/SkFontHost_FreeType.cpp b/gfx/skia/skia/src/ports/SkFontHost_FreeType.cpp index 5c00d1b69719..ab90fcd08b3d 100644 --- a/gfx/skia/skia/src/ports/SkFontHost_FreeType.cpp +++ b/gfx/skia/skia/src/ports/SkFontHost_FreeType.cpp @@ -1163,7 +1163,6 @@ void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph) { 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); } @@ -1172,10 +1171,18 @@ void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph) { glyph->fMaskFormat = SkMask::kARGB32_Format; } - glyph->fWidth = SkToU16(fFace->glyph->bitmap.width); - glyph->fHeight = SkToU16(fFace->glyph->bitmap.rows); - glyph->fTop = -SkToS16(fFace->glyph->bitmap_top); - glyph->fLeft = SkToS16(fFace->glyph->bitmap_left); + SkRect srcRect = SkRect::MakeXYWH( + SkIntToScalar(face->glyph->bitmap_left), + -SkIntToScalar(face->glyph->bitmap_top), + SkIntToScalar(face->glyph->bitmap.width), + SkIntToScalar(face->glyph->bitmap.rows)); + SkRect destRect; + fMatrix22Scalar.mapRect(&destRect, srcRect); + SkIRect glyphRect = destRect.roundOut(); + glyph->fWidth = SkToU16(glyphRect.width()); + glyph->fHeight = SkToU16(glyphRect.height()); + glyph->fTop = SkToS16(SkScalarRoundToInt(destRect.fTop)); + glyph->fLeft = SkToS16(SkScalarRoundToInt(destRect.fLeft)); break; default: diff --git a/gfx/skia/skia/src/ports/SkFontHost_FreeType_common.cpp b/gfx/skia/skia/src/ports/SkFontHost_FreeType_common.cpp index 245ded128357..de4547f8be10 100644 --- a/gfx/skia/skia/src/ports/SkFontHost_FreeType_common.cpp +++ b/gfx/skia/skia/src/ports/SkFontHost_FreeType_common.cpp @@ -402,16 +402,12 @@ void SkScalerContext_FreeType_Base::generateGlyphImage(FT_Face face, const SkGly SkMask::kARGB32_Format == maskFormat || SkMask::kLCD16_Format == maskFormat); - if (fRec.fFlags & SkScalerContext::kEmbolden_Flag && - !(face->style_flags & FT_STYLE_FLAG_BOLD)) - { - FT_GlyphSlot_Own_Bitmap(face->glyph); - FT_Bitmap_Embolden(face->glyph->library, &face->glyph->bitmap, - kBitmapEmboldenStrength, 0); - } - - // If no scaling needed, directly copy glyph bitmap. - if (glyph.fWidth == face->glyph->bitmap.width && + // If no skew or scaling needed, directly copy glyph bitmap. + bool skewed = fRec.fPreSkewX != 0 || + fRec.fPost2x2[0][1] != 0 || + fRec.fPost2x2[1][0] != 0; + if (!skewed && + glyph.fWidth == face->glyph->bitmap.width && glyph.fHeight == face->glyph->bitmap.rows && glyph.fTop == -face->glyph->bitmap_top && glyph.fLeft == face->glyph->bitmap_left) @@ -460,8 +456,22 @@ void SkScalerContext_FreeType_Base::generateGlyphImage(FT_Face face, const SkGly // Scale unscaledBitmap into dstBitmap. SkCanvas canvas(dstBitmap); canvas.clear(SK_ColorTRANSPARENT); - canvas.scale(SkIntToScalar(glyph.fWidth) / SkIntToScalar(face->glyph->bitmap.width), - SkIntToScalar(glyph.fHeight) / SkIntToScalar(face->glyph->bitmap.rows)); + if (skewed) { + // Apply any transforms with the bitmap placed at (0, 0). + SkMatrix matrix; + fRec.getSingleMatrix(&matrix); + SkRect srcRect = SkRect::MakeIWH(face->glyph->bitmap.width, face->glyph->bitmap.rows); + SkRect destRect; + matrix.mapRect(&destRect, srcRect); + matrix.postTranslate(-destRect.fLeft, -destRect.fTop); + // Rescale to the glyph's actual size. + matrix.postScale(SkIntToScalar(glyph.fWidth) / destRect.width(), + SkIntToScalar(glyph.fHeight) / destRect.height()); + canvas.setMatrix(matrix); + } else { + canvas.scale(SkIntToScalar(glyph.fWidth) / SkIntToScalar(face->glyph->bitmap.width), + SkIntToScalar(glyph.fHeight) / SkIntToScalar(face->glyph->bitmap.rows)); + } SkPaint paint; paint.setFilterQuality(kMedium_SkFilterQuality); canvas.drawBitmap(unscaledBitmap, 0, 0, &paint);