summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2019-06-06 08:42:38 +0200
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>2019-06-06 08:53:33 +0200
commit3faae687554f0e48261bb4fc838c249e445c1e0c (patch)
tree02b9c9249b370ebbbfd1a50d753c3f36f1ca4307 /src
parent02c2de54446824b80e3cee8c610fc3e3fc11419a (diff)
Work around memory leak in QRawFont::setPixelSize()
When QRawFont::setPixelSize() is used in combination with QTextLayout, we end up creating a multi font engine for the cloned engine and putting this into the font cache. This is a bug in itself, but it is especially severe on Freetype, because another bug prevents the engines from being garbage collected when the cache gets full. See QTBUG-76219. The result was that all changes to text in Qt 3D Runtime would leak memory. Since the distance field text is done in design metrics, we don't really need the correct pixel size to make the layouts. We can do them in the pixel size of the font we get from the database and just scale the results. We have to also scale the input to the layout in that case. This is both a work-around for the memory leak but also a performance improvement, so it should stay even when QTBUG-76219 is fixed. Task-number: QT3DS-3617 Change-Id: I2f1bdc7a041debf2384319b3459f1684fa4066fa Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io> Reviewed-by: Jari Karppinen <jari.karppinen@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/runtime/q3dsscenemanager.cpp15
1 files changed, 10 insertions, 5 deletions
diff --git a/src/runtime/q3dsscenemanager.cpp b/src/runtime/q3dsscenemanager.cpp
index 71cb74e..8eeaf4c 100644
--- a/src/runtime/q3dsscenemanager.cpp
+++ b/src/runtime/q3dsscenemanager.cpp
@@ -4919,10 +4919,10 @@ Qt3DCore::QEntity *Q3DSSceneManager::buildText(Q3DSTextNode *text3DS, Q3DSLayerN
QVector2D boundingBox = text3DS->boundingBox();
QRawFont font = m_fontDatabase->findFont(text3DS->font());
- font.setPixelSize(qreal(text3DS->size()));
+ qreal scaleFactor = font.pixelSize() / text3DS->size();
- const qreal maximumWidth = boundingBox.isNull() ? qreal(0x01000000) : qreal(boundingBox.x());
- const qreal maximumHeight = boundingBox.isNull() ? qreal(0x01000000) : qreal(boundingBox.y());
+ const qreal maximumWidth = boundingBox.isNull() ? qreal(0x01000000) : qreal(boundingBox.x()) * scaleFactor;
+ const qreal maximumHeight = boundingBox.isNull() ? qreal(0x01000000) : qreal(boundingBox.y()) * scaleFactor;
QTextLayout layout;
QTextOption option = layout.textOption();
@@ -4956,7 +4956,7 @@ Qt3DCore::QEntity *Q3DSSceneManager::buildText(Q3DSTextNode *text3DS, Q3DSLayerN
layout.clearLayout();
- float leading = text3DS->leading();
+ float leading = text3DS->leading() * scaleFactor;
width = 0.0;
height = qreal(-leading);
@@ -4966,7 +4966,7 @@ Qt3DCore::QEntity *Q3DSSceneManager::buildText(Q3DSTextNode *text3DS, Q3DSLayerN
formatRange.start = 0;
formatRange.length = text.length();
formatRange.format.setFontLetterSpacingType(QFont::AbsoluteSpacing);
- formatRange.format.setFontLetterSpacing(qreal(text3DS->tracking()));
+ formatRange.format.setFontLetterSpacing(qreal(text3DS->tracking()) * scaleFactor);
formatRanges.append(formatRange);
layout.setFormats(formatRanges);
@@ -5187,6 +5187,11 @@ Qt3DCore::QEntity *Q3DSSceneManager::buildText(Q3DSTextNode *text3DS, Q3DSLayerN
float cy1 = float(position.y() - metrics.baselineY) + offsetY;
float cy2 = cy1 + float(metrics.height);
+ cx1 /= scaleFactor;
+ cy1 /= scaleFactor;
+ cx2 /= scaleFactor;
+ cy2 /= scaleFactor;
+
if (text3DS->shadow()) {
if (shadowOffsetX < 0.0)
cx1 += shadowOffsetX * fontScale;