diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2019-06-06 08:42:38 +0200 |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com> | 2019-06-06 08:53:33 +0200 |
commit | 3faae687554f0e48261bb4fc838c249e445c1e0c (patch) | |
tree | 02b9c9249b370ebbbfd1a50d753c3f36f1ca4307 /src | |
parent | 02c2de54446824b80e3cee8c610fc3e3fc11419a (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.cpp | 15 |
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; |