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
(cherry picked from commit 0aa9b30432cec3b7f366983f451fc9a7f8f83243)
bb10
Eskil Abrahamsen Blomfeldt 2011-05-18 15:10:40 +02:00
parent e8c95790d9
commit f4c1c2f939
4 changed files with 69 additions and 15 deletions

View File

@ -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);
}
}
/*!

View File

@ -44,6 +44,8 @@
#include "qstroker_p.h"
#include "qbezier_p.h"
#include <private/qpainterpath_p.h>
#include <private/qfontengine_p.h>
#include <private/qstatictext_p.h>
#include <qvarlengtharray.h>
#include <qdebug.h>
@ -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

View File

@ -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<QPainterState *>(QPaintEngine::state); }

View File

@ -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();
d->drawCachedGlyphs(glyphType, textItem);
// 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);
} else {
QPaintEngineEx::drawStaticTextItem(textItem);
}
}
bool QGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, const QSize &size, const QRectF &src)