From 0aa9b30432cec3b7f366983f451fc9a7f8f83243 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 18 May 2011 15:10:40 +0200 Subject: Fall back to using paths for large fonts in drawStaticText() QStaticText had an implicit risk which meant you had to make sure the text size did not grow unreasonably large. This was intended to avoid hiding the performance impact of using QStaticText for such a purpose, but it's too inconvenient. Thus, the same fall back as in drawTextItem() has been introduced. This will also fix a bug recently introduced when we started using the FT cache to draw static text in the raster engine, since this will fail for large fonts. Task-number: QTBUG-19084, QTBUG-19370 Reviewed-by: Jiang Jiang --- src/gui/painting/qpaintengine_raster.cpp | 12 ++++++-- src/gui/painting/qpaintengineex.cpp | 35 ++++++++++++++++++++++ src/gui/painting/qpaintengineex_p.h | 2 +- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 33 +++++++++++++------- 4 files changed, 68 insertions(+), 14 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index f0bc0d6..4f8af48 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -3029,8 +3029,16 @@ void QRasterPaintEngine::drawStaticTextItem(QStaticTextItem *textItem) ensurePen(); ensureState(); - drawCachedGlyphs(textItem->numGlyphs, textItem->glyphs, textItem->glyphPositions, - textItem->fontEngine()); + QRasterPaintEngineState *s = state(); + + QFontEngine *fontEngine = textItem->fontEngine(); + const qreal pixelSize = fontEngine->fontDef.pixelSize; + if (pixelSize * pixelSize * qAbs(s->matrix.determinant()) < 64 * 64) { + drawCachedGlyphs(textItem->numGlyphs, textItem->glyphs, textItem->glyphPositions, + fontEngine); + } else { + QPaintEngineEx::drawStaticTextItem(textItem); + } } /*! diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index bbdf76f..304e5fc 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -44,6 +44,8 @@ #include "qstroker_p.h" #include "qbezier_p.h" #include +#include +#include #include #include @@ -1057,5 +1059,38 @@ Q_GUI_EXPORT QPainterPath qt_painterPathFromVectorPath(const QVectorPath &path) return p; } +void QPaintEngineEx::drawStaticTextItem(QStaticTextItem *staticTextItem) +{ + QPainterPath path; +#ifndef Q_WS_MAC + path.setFillRule(Qt::WindingFill); +#endif + + if (staticTextItem->numGlyphs == 0) + return; + + QFontEngine *fontEngine = staticTextItem->fontEngine(); + fontEngine->addGlyphsToPath(staticTextItem->glyphs, staticTextItem->glyphPositions, + staticTextItem->numGlyphs, &path, 0); + if (!path.isEmpty()) { + QPainterState *s = state(); + QPainter::RenderHints oldHints = s->renderHints; + bool changedHints = false; + if (bool(oldHints & QPainter::TextAntialiasing) + && !bool(fontEngine->fontDef.styleStrategy & QFont::NoAntialias) + && !bool(oldHints & QPainter::Antialiasing)) { + s->renderHints |= QPainter::Antialiasing; + renderHintsChanged(); + changedHints = true; + } + + fill(qtVectorPathForPath(path), staticTextItem->color); + + if (changedHints) { + s->renderHints = oldHints; + renderHintsChanged(); + } + } +} QT_END_NAMESPACE diff --git a/src/gui/painting/qpaintengineex_p.h b/src/gui/painting/qpaintengineex_p.h index d12c602..7d57eee 100644 --- a/src/gui/painting/qpaintengineex_p.h +++ b/src/gui/painting/qpaintengineex_p.h @@ -202,7 +202,7 @@ public: virtual void updateState(const QPaintEngineState &state); - virtual void drawStaticTextItem(QStaticTextItem *) = 0; + virtual void drawStaticTextItem(QStaticTextItem *); virtual void setState(QPainterState *s); inline QPainterState *state() { return static_cast(QPaintEngine::state); } diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 38bd58d..3cf8faa 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1436,19 +1436,30 @@ void QGL2PaintEngineEx::drawStaticTextItem(QStaticTextItem *textItem) ensureActive(); - QFontEngineGlyphCache::Type glyphType = textItem->fontEngine()->glyphFormat >= 0 - ? QFontEngineGlyphCache::Type(textItem->fontEngine()->glyphFormat) - : d->glyphCacheType; - if (glyphType == QFontEngineGlyphCache::Raster_RGBMask) { - if (d->device->alphaRequested() || state()->matrix.type() > QTransform::TxTranslate - || (state()->composition_mode != QPainter::CompositionMode_Source - && state()->composition_mode != QPainter::CompositionMode_SourceOver)) - { - glyphType = QFontEngineGlyphCache::Raster_A8; + QPainterState *s = state(); + float det = s->matrix.determinant(); + + // don't try to cache huge fonts or vastly transformed fonts + QFontEngine *fontEngine = textItem->fontEngine(); + const qreal pixelSize = fontEngine->fontDef.pixelSize; + if (pixelSize * pixelSize * qAbs(det) < QT_MAX_CACHED_GLYPH_SIZE * QT_MAX_CACHED_GLYPH_SIZE || + det < 0.25f || det > 4.f) { + QFontEngineGlyphCache::Type glyphType = fontEngine->glyphFormat >= 0 + ? QFontEngineGlyphCache::Type(textItem->fontEngine()->glyphFormat) + : d->glyphCacheType; + if (glyphType == QFontEngineGlyphCache::Raster_RGBMask) { + if (d->device->alphaRequested() || s->matrix.type() > QTransform::TxTranslate + || (s->composition_mode != QPainter::CompositionMode_Source + && s->composition_mode != QPainter::CompositionMode_SourceOver)) + { + glyphType = QFontEngineGlyphCache::Raster_A8; + } } - } - d->drawCachedGlyphs(glyphType, textItem); + d->drawCachedGlyphs(glyphType, textItem); + } else { + QPaintEngineEx::drawStaticTextItem(textItem); + } } bool QGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, const QSize &size, const QRectF &src) -- cgit v0.12