diff options
author | Eskil Abrahamsen Blomfeldt <[email protected]> | 2020-04-16 08:00:53 +0200 |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <[email protected]> | 2020-04-16 09:42:30 +0000 |
commit | ac179e235ba0c01fff6dd5f4ad2cc9696fe78822 (patch) | |
tree | ae6421228dcb73958b5f49ae95781859cc009a4b /src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp | |
parent | 94b46de4050d023ecbb238c2636d7e252f8f5949 (diff) |
Fix clipping of text with software backend
QRawFont::boundingRect() returns the bounding rect of the glyph
as reported by the system. On Windows, this unfortunately
does not always include the antialiasing on the edges when
the ClearType renderer is used (probably for compatibility
reasons, since it matches the rendered size of the 8-bit alphamap.)
Therefore, we have traditionally been applying a margin around
rendering for 32-bit alpha maps, since there is no way to know
for certain the exact rendered size with ClearType.
It is tempting to expose the alphaMapBoundingBox through
QRawFont (either replace the implementation of boundingRect()
or add a new function) to avoid using private APIs here, but since
it is a work-around and we hope the need for it will go away when
we start using DirectWrite instead, it is better to keep it
locked away for now. It is also too late to do such a change in
Qt 5.15, so we can revisit the idea for Qt 6.x.
[ChangeLog][Software Renderer] Fixed a bug where the last column of
pixels in text would sometimes be clipped away.
Fixes: QTBUG-80180
Change-Id: Ic611a80aef3e0e9b9cee0f3a22c9e24f717d5dfe
Reviewed-by: Andy Nichols <[email protected]>
Diffstat (limited to 'src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp')
-rw-r--r-- | src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp | 43 |
1 files changed, 27 insertions, 16 deletions
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp index dd789b78c7..04e9b361ca 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp @@ -38,6 +38,7 @@ ****************************************************************************/ #include "qsgsoftwareglyphnode_p.h" +#include <QtGui/private/qrawfont_p.h> QT_BEGIN_NAMESPACE @@ -52,28 +53,38 @@ QSGSoftwareGlyphNode::QSGSoftwareGlyphNode() namespace { QRectF calculateBoundingRect(const QPointF &position, const QGlyphRun &glyphs) { - qreal minX = 0; - qreal minY = 0; - qreal maxX = 0; - qreal maxY = 0; + QFixed minX; + QFixed minY; + QFixed maxX; + QFixed maxY; - for (int i = 0, n = qMin(glyphs.glyphIndexes().size(), glyphs.positions().size()); i < n; ++i) { - QRectF glyphRect = glyphs.rawFont().boundingRect(glyphs.glyphIndexes()[i]); - glyphRect.translate(glyphs.positions()[i]); + QRawFontPrivate *rawFontD = QRawFontPrivate::get(glyphs.rawFont()); + QFontEngine *fontEngine = rawFontD->fontEngine; + + QFontEngine::GlyphFormat glyphFormat = fontEngine->glyphFormat != QFontEngine::Format_None ? fontEngine->glyphFormat : QFontEngine::Format_A32; + + const QVector<uint> glyphIndexes = glyphs.glyphIndexes(); + const QVector<QPointF> glyphPositions = glyphs.positions(); + for (int i = 0, n = qMin(glyphIndexes.size(), glyphPositions.size()); i < n; ++i) { + glyph_metrics_t gm = fontEngine->alphaMapBoundingBox(glyphIndexes.at(i), QFixed(), QTransform(), glyphFormat); + + gm.x += QFixed::fromReal(glyphPositions.at(i).x()); + gm.y += QFixed::fromReal(glyphPositions.at(i).y()); if (i == 0) { - minX = glyphRect.left(); - minY = glyphRect.top(); - maxX = glyphRect.right(); - maxY = glyphRect.bottom(); + minX = gm.x; + minY = gm.y; + maxX = gm.x + gm.width; + maxY = gm.y + gm.height; } else { - minX = qMin(glyphRect.left(), minX); - minY = qMin(glyphRect.top(), minY); - maxX = qMax(glyphRect.right(),maxX); - maxY = qMax(glyphRect.bottom(), maxY); + minX = qMin(gm.x, minX); + minY = qMin(gm.y, minY); + maxX = qMax(gm.x + gm.width, maxX); + maxY = qMax(gm.y + gm.height, maxY); } } - QRectF boundingRect(QPointF(minX, minY), QPointF(maxX, maxY)); + + QRectF boundingRect(QPointF(minX.toReal(), minY.toReal()), QPointF(maxX.toReal(), maxY.toReal())); return boundingRect.translated(position - QPointF(0.0, glyphs.rawFont().ascent())); } } |