From 070d9c00c488a5ee6811f04170cf488ead79bf80 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 16 Sep 2011 16:00:04 +0200 Subject: Avoid double caching glyphs in raster/QPA/FreeType MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since FreeType has internal caching, it has had a special code path in the raster engine which avoided using Qt's glyph cache, as that would be redundant. However, when compiling with QPA, we want the same behavior without being able to access the QFontEngineFT class. To achieve this, I've made a new abstraction and added it to QFontEngine which allows the FT engine to provide direct pointers into the alpha maps stored by FT. This requires a locking/unlocking mechanism. Yes, the QFontEngine::alphaMap* API is slowly becoming a horrible mess, but due to time constraints, the task of refactoring these functions into a more flexible API needs to wait. I've added a TODO comment for this. Change-Id: I08237403c2967f8fb952258178676f33a87c0353 Reviewed-on: http://codereview.qt-project.org/5155 Reviewed-by: Qt Sanity Bot Reviewed-by: Samuel Rødal --- src/gui/painting/qpaintengine_raster.cpp | 131 ++++++++----------------------- 1 file changed, 31 insertions(+), 100 deletions(-) (limited to 'src/gui/painting') diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 62701eb569..e2e4ed6b0a 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -54,10 +54,6 @@ #include #include -#if defined (Q_WS_X11) -# include -#endif - // #include // #include #include @@ -88,8 +84,6 @@ # include #elif defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE) # include -#elif defined(Q_WS_QPA) -# include #endif #if defined(Q_OS_WIN64) @@ -2717,91 +2711,33 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, Q_D(QRasterPaintEngine); QRasterPaintEngineState *s = state(); -#if !defined(QT_NO_FREETYPE) - if (fontEngine->type() == QFontEngine::Freetype) { - QFontEngineFT *fe = static_cast(fontEngine); - QFontEngineFT::GlyphFormat neededFormat = + if (fontEngine->hasInternalCaching()) { + QFontEngine::GlyphFormat neededFormat = painter()->device()->devType() == QInternal::Widget - ? fe->defaultGlyphFormat() - : QFontEngineFT::Format_A8; - - if (d_func()->mono_surface - || fe->isBitmapFont() // alphaPenBlt can handle mono, too - ) - neededFormat = QFontEngineFT::Format_Mono; - - if (neededFormat == QFontEngineFT::Format_None) - neededFormat = QFontEngineFT::Format_A8; - - QFontEngineFT::QGlyphSet *gset = fe->defaultGlyphs(); - if (s->matrix.type() >= QTransform::TxScale) { - if (s->matrix.isAffine()) - gset = fe->loadTransformedGlyphSet(s->matrix); - else - gset = 0; - } - - if (!gset || gset->outline_drawing - || !fe->loadGlyphs(gset, glyphs, numGlyphs, positions, neededFormat)) - return false; - - FT_Face lockedFace = 0; + ? QFontEngine::Format_None + : QFontEngine::Format_A8; - int depth; - switch (neededFormat) { - case QFontEngineFT::Format_Mono: - depth = 1; - break; - case QFontEngineFT::Format_A8: - depth = 8; - break; - case QFontEngineFT::Format_A32: - depth = 32; - break; - default: - Q_ASSERT(false); - depth = 0; - }; + if (d_func()->mono_surface) // alphaPenBlt can handle mono, too + neededFormat = QFontEngine::Format_Mono; for (int i = 0; i < numGlyphs; i++) { - QFixed spp = fe->subPixelPositionForX(positions[i].x); - QFontEngineFT::Glyph *glyph = gset->getGlyph(glyphs[i], spp); - - if (!glyph || glyph->format != neededFormat) { - if (!lockedFace) - lockedFace = fe->lockFace(); - glyph = fe->loadGlyph(gset, glyphs[i], spp, neededFormat); - } + QFixed spp = fontEngine->subPixelPositionForX(positions[i].x); - if (!glyph || !glyph->data) + QPoint offset; + QImage *alphaMap = fontEngine->lockedAlphaMapForGlyph(glyphs[i], spp, neededFormat, s->matrix, + &offset); + if (alphaMap == 0) continue; - int pitch; - switch (neededFormat) { - case QFontEngineFT::Format_Mono: - pitch = ((glyph->width + 31) & ~31) >> 3; - break; - case QFontEngineFT::Format_A8: - pitch = (glyph->width + 3) & ~3; - break; - case QFontEngineFT::Format_A32: - pitch = glyph->width * 4; - break; - default: - Q_ASSERT(false); - pitch = 0; - }; - - alphaPenBlt(glyph->data, pitch, depth, - qFloor(positions[i].x) + glyph->x, - qFloor(positions[i].y) - glyph->y, - glyph->width, glyph->height); + alphaPenBlt(alphaMap->bits(), alphaMap->bytesPerLine(), alphaMap->depth(), + qFloor(positions[i].x) + offset.x(), + qFloor(positions[i].y) + offset.y(), + alphaMap->width(), alphaMap->height()); + + fontEngine->unlockAlphaMapForGlyph(); } - if (lockedFace) - fe->unlockFace(); - } else -#endif - { + + } else { QFontEngineGlyphCache::Type glyphType = fontEngine->glyphFormat >= 0 ? QFontEngineGlyphCache::Type(fontEngine->glyphFormat) : d->glyphCacheType; QImageTextureGlyphCache *cache = @@ -3057,28 +2993,23 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte QFontEngine *fontEngine = ti.fontEngine; -#if (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)) && !defined(QT_NO_FREETYPE) +#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) - if (fontEngine->type() != QFontEngine::Freetype) { - QPaintEngineEx::drawTextItem(p, ti); - return; - } + if (fontEngine->type() == QFontEngine::Freetype) { + QTransform matrix = s->matrix; + matrix.translate(p.x(), p.y()); - QFontEngineFT *fe = static_cast(fontEngine); + QVarLengthArray positions; + QVarLengthArray glyphs; + fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); + if (glyphs.size() == 0) + return; - QTransform matrix = s->matrix; - matrix.translate(p.x(), p.y()); + if (!drawCachedGlyphs(glyphs.size(), glyphs.constData(), positions.constData(), fontEngine)) + QPaintEngine::drawTextItem(p, ti); - QVarLengthArray positions; - QVarLengthArray glyphs; - fe->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); - if (glyphs.size() == 0) return; - - if (!drawCachedGlyphs(glyphs.size(), glyphs.constData(), positions.constData(), fontEngine)) - QPaintEngine::drawTextItem(p, ti); - - return; + } #endif #endif -- cgit v1.2.3