summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorKim Motoyoshi Kalland <kim.kalland@nokia.com>2011-12-12 13:02:13 +0100
committerQt by Nokia <qt-info@nokia.com>2011-12-13 11:11:58 +0100
commitd52fd497f60a3c4456994f4f10e9451d611c9ea4 (patch)
tree260e309b017d7d1575ecf5b46276617a035e4f96 /src/gui
parent0553ab912746ece4a309d9b5b5cf1fd54630ffc2 (diff)
Improved performance of large text when parts are outside view.
Avoid generating paths for the parts of the text that are outside the viewport in the raster paint engine. Task-number: QTBUG-22687 Change-Id: I06159bc4c1aa82a07606f4b2f0336cb25dfd56d2 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp87
1 files changed, 81 insertions, 6 deletions
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 89a8f8a032..60ead45eab 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -2878,11 +2878,47 @@ QRasterPaintEnginePrivate::getPenFunc(const QRectF &rect,
return isUnclipped(rect, penWidth) ? data->unclipped_blend : data->blend;
}
+static QPair<int, int> visibleGlyphRange(const QRectF &clip, QFontEngine *fontEngine,
+ glyph_t *glyphs, QFixedPoint *positions, int numGlyphs)
+{
+ QFixed clipLeft = QFixed::fromReal(clip.left());
+ QFixed clipRight = QFixed::fromReal(clip.right());
+ QFixed clipTop = QFixed::fromReal(clip.top());
+ QFixed clipBottom = QFixed::fromReal(clip.bottom());
+
+ int first = 0;
+ while (first < numGlyphs) {
+ glyph_metrics_t metrics = fontEngine->boundingBox(glyphs[first]);
+ QFixed left = metrics.x + positions[first].x;
+ QFixed top = metrics.y + positions[first].y;
+ QFixed right = left + metrics.width;
+ QFixed bottom = top + metrics.height;
+ if (left < clipRight && right > clipLeft && top < clipBottom && bottom > clipTop)
+ break;
+ ++first;
+ }
+ int last = numGlyphs - 1;
+ while (last > first) {
+ glyph_metrics_t metrics = fontEngine->boundingBox(glyphs[last]);
+ QFixed left = metrics.x + positions[last].x;
+ QFixed top = metrics.y + positions[last].y;
+ QFixed right = left + metrics.width;
+ QFixed bottom = top + metrics.height;
+ if (left < clipRight && right > clipLeft && top < clipBottom && bottom > clipTop)
+ break;
+ --last;
+ }
+ return QPair<int, int>(first, last + 1);
+}
+
/*!
\reimp
*/
void QRasterPaintEngine::drawStaticTextItem(QStaticTextItem *textItem)
{
+ if (textItem->numGlyphs == 0)
+ return;
+
ensurePen();
ensureRasterState();
@@ -2890,6 +2926,20 @@ void QRasterPaintEngine::drawStaticTextItem(QStaticTextItem *textItem)
if (shouldDrawCachedGlyphs(fontEngine->fontDef.pixelSize, state()->matrix)) {
drawCachedGlyphs(textItem->numGlyphs, textItem->glyphs, textItem->glyphPositions,
fontEngine);
+ } else if (state()->matrix.type() < QTransform::TxProject) {
+ bool invertible;
+ QTransform invMat = state()->matrix.inverted(&invertible);
+ if (!invertible)
+ return;
+
+ QPair<int, int> range = visibleGlyphRange(invMat.mapRect(clipBoundingRect()),
+ textItem->fontEngine(), textItem->glyphs,
+ textItem->glyphPositions, textItem->numGlyphs);
+ QStaticTextItem copy = *textItem;
+ copy.glyphs += range.first;
+ copy.glyphPositions += range.first;
+ copy.numGlyphs = range.second - range.first;
+ QPaintEngineEx::drawStaticTextItem(&copy);
} else {
QPaintEngineEx::drawStaticTextItem(textItem);
}
@@ -2901,7 +2951,6 @@ void QRasterPaintEngine::drawStaticTextItem(QStaticTextItem *textItem)
void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
{
const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
- QRasterPaintEngineState *s = state();
#ifdef QT_DEBUG_DRAW
Q_D(QRasterPaintEngine);
@@ -2910,25 +2959,51 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte
d->glyphCacheType);
#endif
+ if (ti.glyphs.numGlyphs == 0)
+ return;
ensurePen();
ensureRasterState();
+ QRasterPaintEngineState *s = state();
+ QTransform matrix = s->matrix;
if (!supportsTransformations(ti.fontEngine)) {
QVarLengthArray<QFixedPoint> positions;
QVarLengthArray<glyph_t> glyphs;
- QTransform matrix = s->matrix;
matrix.translate(p.x(), p.y());
-
ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
drawCachedGlyphs(glyphs.size(), glyphs.constData(), positions.constData(), ti.fontEngine);
- return;
- }
+ } else if (matrix.type() < QTransform::TxProject) {
+ bool invertible;
+ QTransform invMat = matrix.inverted(&invertible);
+ if (!invertible)
+ return;
+
+ QVarLengthArray<QFixedPoint> positions;
+ QVarLengthArray<glyph_t> glyphs;
+
+ ti.fontEngine->getGlyphPositions(ti.glyphs, QTransform::fromTranslate(p.x(), p.y()),
+ ti.flags, glyphs, positions);
+ QPair<int, int> range = visibleGlyphRange(invMat.mapRect(clipBoundingRect()),
+ ti.fontEngine, glyphs.data(), positions.data(),
+ glyphs.size());
+ if (range.first >= range.second)
+ return;
- QPaintEngineEx::drawTextItem(p, ti);
+ QStaticTextItem staticTextItem;
+ staticTextItem.color = s->pen.color();
+ staticTextItem.font = s->font;
+ staticTextItem.setFontEngine(ti.fontEngine);
+ staticTextItem.numGlyphs = range.second - range.first;
+ staticTextItem.glyphs = glyphs.data() + range.first;
+ staticTextItem.glyphPositions = positions.data() + range.first;
+ QPaintEngineEx::drawStaticTextItem(&staticTextItem);
+ } else {
+ QPaintEngineEx::drawTextItem(p, ti);
+ }
}
/*!