Bug 1287552 - part 2 - fix transformed bitmaps with Skia and FreeType. r?gw280
MozReview-Commit-ID: BqiLfOfZZwR
--- a/gfx/skia/skia/src/ports/SkFontHost_FreeType.cpp
+++ b/gfx/skia/skia/src/ports/SkFontHost_FreeType.cpp
@@ -1158,29 +1158,36 @@ void SkScalerContext_FreeType::generateM
}
break;
case FT_GLYPH_FORMAT_BITMAP:
if (fRec.fFlags & SkScalerContext::kVertical_Flag) {
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);
}
if (fFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) {
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:
SkDEBUGFAIL("unknown glyph format");
glyph->zeroMetrics();
return;
}
--- a/gfx/skia/skia/src/ports/SkFontHost_FreeType_common.cpp
+++ b/gfx/skia/skia/src/ports/SkFontHost_FreeType_common.cpp
@@ -397,26 +397,22 @@ void SkScalerContext_FreeType_Base::gene
FT_PIXEL_MODE_BGRA == pixel_mode);
// These are the only formats this ScalerContext should request.
SkASSERT(SkMask::kBW_Format == maskFormat ||
SkMask::kA8_Format == maskFormat ||
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)
{
SkMask dstMask;
glyph.toMask(&dstMask);
copyFTBitmap(face->glyph->bitmap, dstMask);
break;
@@ -455,18 +451,32 @@ void SkScalerContext_FreeType_Base::gene
dstBitmap.allocPixels();
} else {
dstBitmap.setPixels(glyph.fImage);
}
// 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);
// If the destination is BW or LCD, convert from A8.
if (SkMask::kBW_Format == maskFormat) {
// Copy the A8 dstBitmap into the A1 glyph.fImage.
SkMask dstMask;