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>bb10
parent
0553ab9127
commit
d52fd497f6
|
|
@ -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(©);
|
||||
} 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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
QPaintEngineEx::drawTextItem(p, ti);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
|||
Loading…
Reference in New Issue