aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2020-04-16 08:00:53 +0200
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2020-04-16 09:42:30 +0000
commitac179e235ba0c01fff6dd5f4ad2cc9696fe78822 (patch)
treeae6421228dcb73958b5f49ae95781859cc009a4b
parent94b46de4050d023ecbb238c2636d7e252f8f5949 (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 <andy.nichols@qt.io>
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwareglyphnode.cpp43
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()));
}
}