summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@digia.com>2013-09-17 10:14:36 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-20 12:05:52 +0200
commitd18ccbb5be23eaea5eb5f1af2ae0fba334ab21d7 (patch)
treeb792dea13f0fe29c80c9e8a355c55b3539ae6040
parent31db0aec22e083f038089052c34fc49c6b07c5f5 (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.cpp20
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);