Windows: Fix missing glyphs for very large font
When the font size gets to a certain size (at some point after 1200 pixels), DirectWrite will just return an empty rect as the bound for it and does not want to render it. At this point, you might want to consider other ways of rendering the text, but since the same did not happen e.g. with the Freetype backend, it was an unfortunate platform difference. As a fail safe, we detect when this occurs and fall back to the QFontEngine base class approach of drawing the glyph as a QPainterPath instead. [ChangeLog][Windows] Fixed an issue where glyphs might be missing for very large fonts. Fixes: QTBUG-126671 Change-Id: I13cc1e5d71fae114e2a7933a7c5f7b9980237390 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io> (cherry picked from commit a5ddcbb76b674470f0c3d1d5e0bb7697a2828d25) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
9d5e3ffc33
commit
98d03964ac
@ -868,7 +868,7 @@ QFontEngine::Glyph *QFontEngine::glyphData(glyph_t,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QImage QFontEngine::alphaMapForGlyph(glyph_t glyph)
|
||||
QImage QFontEngine::renderedPathForGlyph(glyph_t glyph, const QColor &color)
|
||||
{
|
||||
glyph_metrics_t gm = boundingBox(glyph);
|
||||
int glyph_x = qFloor(gm.x.toReal());
|
||||
@ -889,10 +889,16 @@ QImage QFontEngine::alphaMapForGlyph(glyph_t glyph)
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
addGlyphsToPath(&glyph, &pt, 1, &path, { });
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(Qt::black);
|
||||
p.setBrush(color);
|
||||
p.drawPath(path);
|
||||
p.end();
|
||||
|
||||
return im;
|
||||
}
|
||||
|
||||
QImage QFontEngine::alphaMapForGlyph(glyph_t glyph)
|
||||
{
|
||||
QImage im = renderedPathForGlyph(glyph, Qt::black);
|
||||
QImage alphaMap(im.width(), im.height(), QImage::Format_Alpha8);
|
||||
|
||||
for (int y=0; y<im.height(); ++y) {
|
||||
|
@ -186,6 +186,7 @@ public:
|
||||
virtual QImage alphaMapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform &t);
|
||||
virtual QImage alphaRGBMapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform &t);
|
||||
virtual QImage bitmapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform &t, const QColor &color = QColor());
|
||||
QImage renderedPathForGlyph(glyph_t glyph, const QColor &color);
|
||||
virtual Glyph *glyphData(glyph_t glyph, const QFixedPoint &subPixelPosition, GlyphFormat neededFormat, const QTransform &t);
|
||||
virtual bool hasInternalCaching() const { return false; }
|
||||
|
||||
|
@ -660,19 +660,23 @@ QImage QWindowsFontEngineDirectWrite::alphaMapForGlyph(glyph_t glyph,
|
||||
{
|
||||
QImage im = imageForGlyph(glyph, subPixelPosition, glyphMargin(Format_A8), t);
|
||||
|
||||
QImage alphaMap(im.width(), im.height(), QImage::Format_Alpha8);
|
||||
if (!im.isNull()) {
|
||||
QImage alphaMap(im.width(), im.height(), QImage::Format_Alpha8);
|
||||
|
||||
for (int y=0; y<im.height(); ++y) {
|
||||
const uint *src = reinterpret_cast<const uint *>(im.constScanLine(y));
|
||||
uchar *dst = alphaMap.scanLine(y);
|
||||
for (int x=0; x<im.width(); ++x) {
|
||||
*dst = 255 - (m_fontEngineData->pow_gamma[qGray(0xffffffff - *src)] * 255. / 2047.);
|
||||
++dst;
|
||||
++src;
|
||||
for (int y=0; y<im.height(); ++y) {
|
||||
const uint *src = reinterpret_cast<const uint *>(im.constScanLine(y));
|
||||
uchar *dst = alphaMap.scanLine(y);
|
||||
for (int x=0; x<im.width(); ++x) {
|
||||
*dst = 255 - (m_fontEngineData->pow_gamma[qGray(0xffffffff - *src)] * 255. / 2047.);
|
||||
++dst;
|
||||
++src;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return alphaMap;
|
||||
return alphaMap;
|
||||
} else {
|
||||
return QFontEngine::alphaMapForGlyph(glyph, t);
|
||||
}
|
||||
}
|
||||
|
||||
QImage QWindowsFontEngineDirectWrite::alphaMapForGlyph(glyph_t glyph,
|
||||
@ -794,8 +798,10 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
|
||||
: DWRITE_TEXTURE_CLEARTYPE_3x1,
|
||||
&rect);
|
||||
|
||||
if (rect.top == rect.bottom || rect.left == rect.right)
|
||||
if (rect.top == rect.bottom || rect.left == rect.right) {
|
||||
qCDebug(lcQpaFonts) << __FUNCTION__ << "Cannot get alpha texture bounds. Falling back to slower rendering path.";
|
||||
return QImage();
|
||||
}
|
||||
|
||||
QRect boundingRect = QRect(QPoint(rect.left - margin,
|
||||
rect.top - margin),
|
||||
@ -1009,6 +1015,12 @@ QImage QWindowsFontEngineDirectWrite::alphaRGBMapForGlyph(glyph_t t,
|
||||
glyphMargin(QFontEngine::Format_A32),
|
||||
xform);
|
||||
|
||||
if (mask.isNull()) {
|
||||
mask = QFontEngine::renderedPathForGlyph(t, Qt::white);
|
||||
if (!xform.isIdentity())
|
||||
mask = mask.transformed(xform);
|
||||
}
|
||||
|
||||
return mask.depth() == 32
|
||||
? mask
|
||||
: mask.convertToFormat(QImage::Format_RGB32);
|
||||
@ -1157,7 +1169,7 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph
|
||||
int margin = glyphMargin(format);
|
||||
|
||||
if (rect.left == rect.right || rect.top == rect.bottom)
|
||||
return glyph_metrics_t();
|
||||
return bbox;
|
||||
|
||||
return glyph_metrics_t(rect.left,
|
||||
rect.top,
|
||||
|
Loading…
x
Reference in New Issue
Block a user