qt5: add fix for font rendering issues in qt-webengine
Since the chromium environment shipped with qt-webengine also bundles the skia library, it is affected by the same font rendering issues as the mozilla products with freetype 2.8.1. This commit adds the patch backported for Firefox ESR from https://bug1393467.bmoattachments.org/attachment.cgi?id=8904705 which also applies to the skia version bundled with qt-5.8.
This commit is contained in:
parent
cedd861295
commit
702b8e1ecd
|
@ -0,0 +1,148 @@
|
||||||
|
# HG changeset patch
|
||||||
|
# User Lee Salzman <lsalzman@mozilla.com>
|
||||||
|
# Date 1504640559 14400
|
||||||
|
# Tue Sep 05 15:42:39 2017 -0400
|
||||||
|
# Node ID 923246286b9858fb103e100f886c03714b97b5ec
|
||||||
|
# Parent 3fff2b174212af40a7b7ba75a047db431f81c780
|
||||||
|
clip FreeType glyph bitmap to mask in Skia (52 ESR)
|
||||||
|
|
||||||
|
diff --git a/gfx/skia/skia/src/ports/SkFontHost_FreeType_common.cpp b/gfx/skia/skia/src/ports/SkFontHost_FreeType_common.cpp
|
||||||
|
--- qtwebengine/src/3rdparty/chromium/third_party/skia/src/ports/SkFontHost_FreeType_common.cpp
|
||||||
|
+++ qtwebengine/src/3rdparty/chromium/third_party/skia/src/ports/SkFontHost_FreeType_common.cpp
|
||||||
|
@@ -350,58 +350,118 @@ void SkScalerContext_FreeType_Base::gene
|
||||||
|
const SkMatrix& bitmapTransform)
|
||||||
|
{
|
||||||
|
const bool doBGR = SkToBool(fRec.fFlags & SkScalerContext::kLCD_BGROrder_Flag);
|
||||||
|
const bool doVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag);
|
||||||
|
|
||||||
|
switch ( face->glyph->format ) {
|
||||||
|
case FT_GLYPH_FORMAT_OUTLINE: {
|
||||||
|
FT_Outline* outline = &face->glyph->outline;
|
||||||
|
- FT_BBox bbox;
|
||||||
|
- FT_Bitmap target;
|
||||||
|
|
||||||
|
int dx = 0, dy = 0;
|
||||||
|
if (fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) {
|
||||||
|
dx = SkFixedToFDot6(glyph.getSubXFixed());
|
||||||
|
dy = SkFixedToFDot6(glyph.getSubYFixed());
|
||||||
|
// negate dy since freetype-y-goes-up and skia-y-goes-down
|
||||||
|
dy = -dy;
|
||||||
|
}
|
||||||
|
- FT_Outline_Get_CBox(outline, &bbox);
|
||||||
|
- /*
|
||||||
|
- what we really want to do for subpixel is
|
||||||
|
- offset(dx, dy)
|
||||||
|
- compute_bounds
|
||||||
|
- offset(bbox & !63)
|
||||||
|
- but that is two calls to offset, so we do the following, which
|
||||||
|
- achieves the same thing with only one offset call.
|
||||||
|
- */
|
||||||
|
- FT_Outline_Translate(outline, dx - ((bbox.xMin + dx) & ~63),
|
||||||
|
- dy - ((bbox.yMin + dy) & ~63));
|
||||||
|
+ memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);
|
||||||
|
|
||||||
|
if (SkMask::kLCD16_Format == glyph.fMaskFormat) {
|
||||||
|
- FT_Render_Glyph(face->glyph, doVert ? FT_RENDER_MODE_LCD_V : FT_RENDER_MODE_LCD);
|
||||||
|
+ FT_Outline_Translate(outline, dx, dy);
|
||||||
|
+ FT_Error err = FT_Render_Glyph(face->glyph, doVert ? FT_RENDER_MODE_LCD_V : FT_RENDER_MODE_LCD);
|
||||||
|
+ if (err) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
SkMask mask;
|
||||||
|
glyph.toMask(&mask);
|
||||||
|
+
|
||||||
|
+ FT_GlyphSlotRec& ftGlyph = *face->glyph;
|
||||||
|
+
|
||||||
|
+ if (!SkIRect::Intersects(mask.fBounds,
|
||||||
|
+ SkIRect::MakeXYWH( ftGlyph.bitmap_left,
|
||||||
|
+ -ftGlyph.bitmap_top,
|
||||||
|
+ ftGlyph.bitmap.width,
|
||||||
|
+ ftGlyph.bitmap.rows)))
|
||||||
|
+ {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // If the FT_Bitmap extent is larger, discard bits of the bitmap outside the mask.
|
||||||
|
+ // If the SkMask extent is larger, shrink mask to fit bitmap (clearing discarded).
|
||||||
|
+ unsigned char* origBuffer = ftGlyph.bitmap.buffer;
|
||||||
|
+ // First align the top left (origin).
|
||||||
|
+ if (-ftGlyph.bitmap_top < mask.fBounds.fTop) {
|
||||||
|
+ int32_t topDiff = mask.fBounds.fTop - (-ftGlyph.bitmap_top);
|
||||||
|
+ ftGlyph.bitmap.buffer += ftGlyph.bitmap.pitch * topDiff;
|
||||||
|
+ ftGlyph.bitmap.rows -= topDiff;
|
||||||
|
+ ftGlyph.bitmap_top = -mask.fBounds.fTop;
|
||||||
|
+ }
|
||||||
|
+ if (ftGlyph.bitmap_left < mask.fBounds.fLeft) {
|
||||||
|
+ int32_t leftDiff = mask.fBounds.fLeft - ftGlyph.bitmap_left;
|
||||||
|
+ ftGlyph.bitmap.buffer += leftDiff;
|
||||||
|
+ ftGlyph.bitmap.width -= leftDiff;
|
||||||
|
+ ftGlyph.bitmap_left = mask.fBounds.fLeft;
|
||||||
|
+ }
|
||||||
|
+ if (mask.fBounds.fTop < -ftGlyph.bitmap_top) {
|
||||||
|
+ mask.fImage += mask.fRowBytes * (-ftGlyph.bitmap_top - mask.fBounds.fTop);
|
||||||
|
+ mask.fBounds.fTop = -ftGlyph.bitmap_top;
|
||||||
|
+ }
|
||||||
|
+ if (mask.fBounds.fLeft < ftGlyph.bitmap_left) {
|
||||||
|
+ mask.fImage += sizeof(uint16_t) * (ftGlyph.bitmap_left - mask.fBounds.fLeft);
|
||||||
|
+ mask.fBounds.fLeft = ftGlyph.bitmap_left;
|
||||||
|
+ }
|
||||||
|
+ // Origins aligned, clean up the width and height.
|
||||||
|
+ int ftVertScale = (doVert ? 3 : 1);
|
||||||
|
+ int ftHoriScale = (doVert ? 1 : 3);
|
||||||
|
+ if (mask.fBounds.height() * ftVertScale < SkToInt(ftGlyph.bitmap.rows)) {
|
||||||
|
+ ftGlyph.bitmap.rows = mask.fBounds.height() * ftVertScale;
|
||||||
|
+ }
|
||||||
|
+ if (mask.fBounds.width() * ftHoriScale < SkToInt(ftGlyph.bitmap.width)) {
|
||||||
|
+ ftGlyph.bitmap.width = mask.fBounds.width() * ftHoriScale;
|
||||||
|
+ }
|
||||||
|
+ if (SkToInt(ftGlyph.bitmap.rows) < mask.fBounds.height() * ftVertScale) {
|
||||||
|
+ mask.fBounds.fBottom = mask.fBounds.fTop + ftGlyph.bitmap.rows / ftVertScale;
|
||||||
|
+ }
|
||||||
|
+ if (SkToInt(ftGlyph.bitmap.width) < mask.fBounds.width() * ftHoriScale) {
|
||||||
|
+ mask.fBounds.fRight = mask.fBounds.fLeft + ftGlyph.bitmap.width / ftHoriScale;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (fPreBlend.isApplicable()) {
|
||||||
|
- copyFT2LCD16<true>(face->glyph->bitmap, mask, doBGR,
|
||||||
|
+ copyFT2LCD16<true>(ftGlyph.bitmap, mask, doBGR,
|
||||||
|
fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
|
||||||
|
} else {
|
||||||
|
- copyFT2LCD16<false>(face->glyph->bitmap, mask, doBGR,
|
||||||
|
+ copyFT2LCD16<false>(ftGlyph.bitmap, mask, doBGR,
|
||||||
|
fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
|
||||||
|
}
|
||||||
|
+ // Restore the buffer pointer so FreeType can properly free it.
|
||||||
|
+ ftGlyph.bitmap.buffer = origBuffer;
|
||||||
|
} else {
|
||||||
|
+ FT_BBox bbox;
|
||||||
|
+ FT_Bitmap target;
|
||||||
|
+ FT_Outline_Get_CBox(outline, &bbox);
|
||||||
|
+ /*
|
||||||
|
+ what we really want to do for subpixel is
|
||||||
|
+ offset(dx, dy)
|
||||||
|
+ compute_bounds
|
||||||
|
+ offset(bbox & !63)
|
||||||
|
+ but that is two calls to offset, so we do the following, which
|
||||||
|
+ achieves the same thing with only one offset call.
|
||||||
|
+ */
|
||||||
|
+ FT_Outline_Translate(outline, dx - ((bbox.xMin + dx) & ~63),
|
||||||
|
+ dy - ((bbox.yMin + dy) & ~63));
|
||||||
|
+
|
||||||
|
target.width = glyph.fWidth;
|
||||||
|
target.rows = glyph.fHeight;
|
||||||
|
target.pitch = glyph.rowBytes();
|
||||||
|
target.buffer = reinterpret_cast<uint8_t*>(glyph.fImage);
|
||||||
|
target.pixel_mode = compute_pixel_mode( (SkMask::Format)fRec.fMaskFormat);
|
||||||
|
target.num_grays = 256;
|
||||||
|
|
||||||
|
- memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);
|
||||||
|
FT_Outline_Get_Bitmap(face->glyph->library, outline, &target);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case FT_GLYPH_FORMAT_BITMAP: {
|
||||||
|
FT_Pixel_Mode pixel_mode = static_cast<FT_Pixel_Mode>(face->glyph->bitmap.pixel_mode);
|
||||||
|
SkMask::Format maskFormat = static_cast<SkMask::Format>(glyph.fMaskFormat);
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Template file for 'qt5'
|
# Template file for 'qt5'
|
||||||
pkgname=qt5
|
pkgname=qt5
|
||||||
version=5.8.0
|
version=5.8.0
|
||||||
revision=7
|
revision=8
|
||||||
wrksrc="qt-everywhere-opensource-src-${version}"
|
wrksrc="qt-everywhere-opensource-src-${version}"
|
||||||
build_style=gnu-configure
|
build_style=gnu-configure
|
||||||
homepage="http://qt.io/"
|
homepage="http://qt.io/"
|
||||||
|
|
Loading…
Reference in New Issue