diff options
author | Laszlo Agocs <laszlo.agocs@digia.com> | 2013-09-17 10:14:36 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-20 12:05:52 +0200 |
commit | d18ccbb5be23eaea5eb5f1af2ae0fba334ab21d7 (patch) | |
tree | b792dea13f0fe29c80c9e8a355c55b3539ae6040 | |
parent | 31db0aec22e083f038089052c34fc49c6b07c5f5 (diff) |
Fix memory leaks in the FT font engine
The glyph returned by loadGlpyh() must be freed manually when caching
is not enabled (that is, QT_USE_FT_CACHE is not set).
This change and https://codereview.qt-project.org/#change,65672
together should stop QGLWidget::renderText() from leaking memory
extensively.
Task-number: QTBUG-32792
Change-Id: Iff7e1591a1ea994a97b6a56bc16c64bf544e6713
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
-rw-r--r-- | src/gui/text/qfontengine_ft.cpp | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 61f4781e3f..328931e1eb 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -1583,6 +1583,8 @@ void QFontEngineFT::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlag g = loadGlyph(cacheEnabled ? &defaultGlyphSet : 0, glyphs->glyphs[i], 0, Format_None, true); glyphs->advances_x[i] = design ? QFixed::fromFixed(face->glyph->linearHoriAdvance >> 10) : QFixed::fromFixed(face->glyph->metrics.horiAdvance).round(); + if (!cacheEnabled) + delete g; } glyphs->advances_y[i] = 0; } @@ -1621,6 +1623,8 @@ glyph_metrics_t QFontEngineFT::boundingBox(const QGlyphLayout &glyphs) xmax = qMax(xmax, x + g->width); ymax = qMax(ymax, y + g->height); overall.xoff += g->advance; + if (!cacheEnabled) + delete g; } else { int left = FLOOR(face->glyph->metrics.horiBearingX); int right = CEIL(face->glyph->metrics.horiBearingX + face->glyph->metrics.width); @@ -1662,6 +1666,8 @@ glyph_metrics_t QFontEngineFT::boundingBox(glyph_t glyph) overall.xoff = g->advance; if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) overall.xoff = overall.xoff.round(); + if (!cacheEnabled) + delete g; } else { int left = FLOOR(face->glyph->metrics.horiBearingX); int right = CEIL(face->glyph->metrics.horiBearingX + face->glyph->metrics.width); @@ -1751,6 +1757,8 @@ glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixe overall.width = g->width; overall.height = g->height; overall.xoff = g->advance; + if (!glyphSet) + delete g; } else { int left = FLOOR(face->glyph->metrics.horiBearingX); int right = CEIL(face->glyph->metrics.horiBearingX + face->glyph->metrics.width); @@ -1799,6 +1807,7 @@ QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixe }; QFontEngineFT::Glyph *glyph; + QScopedPointer<QFontEngineFT::Glyph> glyphGuard; if (cacheEnabled) { QFontEngineFT::QGlyphSet *gset = &defaultGlyphSet; QFontEngine::HintStyle hintStyle = default_hint_style; @@ -1834,6 +1843,7 @@ QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixe FT_Set_Transform(freetype->face, &m, 0); freetype->matrix = m; glyph = loadGlyph(0, glyphIndex, subPixelPosition, neededFormat); + glyphGuard.reset(glyph); } if (glyph == 0 || glyph->data == 0 || glyph->width == 0 || glyph->height == 0) { @@ -1861,6 +1871,8 @@ QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixe *offset = QPoint(glyph->x, -glyph->y); currentlyLockedAlphaMap = QImage(glyph->data, glyph->width, glyph->height, pitch, format); + if (!glyphGuard.isNull()) + currentlyLockedAlphaMap = currentlyLockedAlphaMap.copy(); Q_ASSERT(!currentlyLockedAlphaMap.isNull()); QImageData *data = currentlyLockedAlphaMap.data_ptr(); @@ -1886,7 +1898,9 @@ QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition) { lockFace(); - Glyph *glyph = loadGlyphFor(g, subPixelPosition, antialias ? Format_A8 : Format_Mono); + QScopedPointer<Glyph> glyph(loadGlyphFor(g, subPixelPosition, antialias ? Format_A8 : Format_Mono)); + if (cacheEnabled) + glyph.take(); if (!glyph || !glyph->data) { unlockFace(); return QFontEngine::alphaMapForGlyph(g); @@ -1923,7 +1937,9 @@ QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, co lockFace(); - Glyph *glyph = loadGlyphFor(g, subPixelPosition, Format_A32); + QScopedPointer<Glyph> glyph(loadGlyphFor(g, subPixelPosition, Format_A32)); + if (cacheEnabled) + glyph.take(); if (!glyph || !glyph->data) { unlockFace(); return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, t); |