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>
This commit is contained in:
parent
31db0aec22
commit
d18ccbb5be
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user