Avoid processing-intensive painting of high number of tiny dashes
When stroking a dashed path, an unnecessary amount of processing would be spent if there is a huge number of dashes visible, e.g. because of scaling. Since the dashes are too small to be indivdually visible anyway, just replace with a semi-transparent solid line for such cases. Change-Id: I9e9f7861257ad5bce46a0cf113d1a9d7824911e6 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> (cherry picked from commit f4d791b330d02777fcaf02938732892eb3167e9b) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
0ba9a4f832
commit
ada12ec960
@ -385,7 +385,7 @@ QPainterState *QPaintEngineEx::createState(QPainterState *orig) const
|
|||||||
|
|
||||||
Q_GUI_EXPORT extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp
|
Q_GUI_EXPORT extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp
|
||||||
|
|
||||||
void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
|
void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &inPen)
|
||||||
{
|
{
|
||||||
#ifdef QT_DEBUG_DRAW
|
#ifdef QT_DEBUG_DRAW
|
||||||
qDebug() << "QPaintEngineEx::stroke()" << pen;
|
qDebug() << "QPaintEngineEx::stroke()" << pen;
|
||||||
@ -403,6 +403,38 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
|
|||||||
d->stroker.setCubicToHook(qpaintengineex_cubicTo);
|
d->stroker.setCubicToHook(qpaintengineex_cubicTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRectF clipRect;
|
||||||
|
QPen pen = inPen;
|
||||||
|
if (pen.style() > Qt::SolidLine) {
|
||||||
|
QRectF cpRect = path.controlPointRect();
|
||||||
|
const QTransform &xf = state()->matrix;
|
||||||
|
if (pen.isCosmetic()) {
|
||||||
|
clipRect = d->exDeviceRect;
|
||||||
|
cpRect.translate(xf.dx(), xf.dy());
|
||||||
|
} else {
|
||||||
|
clipRect = xf.inverted().mapRect(QRectF(d->exDeviceRect));
|
||||||
|
}
|
||||||
|
// Check to avoid generating unwieldy amount of dashes that will not be visible anyway
|
||||||
|
QRectF extentRect = cpRect & clipRect;
|
||||||
|
qreal extent = qMax(extentRect.width(), extentRect.height());
|
||||||
|
qreal patternLength = 0;
|
||||||
|
const QList<qreal> pattern = pen.dashPattern();
|
||||||
|
const int patternSize = qMin(pattern.size(), 32);
|
||||||
|
for (int i = 0; i < patternSize; i++)
|
||||||
|
patternLength += qMax(pattern.at(i), qreal(0));
|
||||||
|
if (pen.widthF())
|
||||||
|
patternLength *= pen.widthF();
|
||||||
|
if (qFuzzyIsNull(patternLength)) {
|
||||||
|
pen.setStyle(Qt::NoPen);
|
||||||
|
} else if (extent / patternLength > 10000) {
|
||||||
|
// approximate stream of tiny dashes with semi-transparent solid line
|
||||||
|
pen.setStyle(Qt::SolidLine);
|
||||||
|
QColor color(pen.color());
|
||||||
|
color.setAlpha(color.alpha() / 2);
|
||||||
|
pen.setColor(color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!qpen_fast_equals(pen, d->strokerPen)) {
|
if (!qpen_fast_equals(pen, d->strokerPen)) {
|
||||||
d->strokerPen = pen;
|
d->strokerPen = pen;
|
||||||
d->stroker.setJoinStyle(pen.joinStyle());
|
d->stroker.setJoinStyle(pen.joinStyle());
|
||||||
@ -430,14 +462,8 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pen.style() > Qt::SolidLine) {
|
if (!clipRect.isNull())
|
||||||
if (pen.isCosmetic()) {
|
d->activeStroker->setClipRect(clipRect);
|
||||||
d->activeStroker->setClipRect(d->exDeviceRect);
|
|
||||||
} else {
|
|
||||||
QRectF clipRect = state()->matrix.inverted().mapRect(QRectF(d->exDeviceRect));
|
|
||||||
d->activeStroker->setClipRect(clipRect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d->activeStroker == &d->stroker)
|
if (d->activeStroker == &d->stroker)
|
||||||
d->stroker.setForceOpen(path.hasExplicitOpen());
|
d->stroker.setForceOpen(path.hasExplicitOpen());
|
||||||
|
34
tests/auto/other/lancelot/scripts/tinydashes.qps
Normal file
34
tests/auto/other/lancelot/scripts/tinydashes.qps
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# Version: 1
|
||||||
|
# CheckVsReference: 5%
|
||||||
|
|
||||||
|
path_addEllipse mypath 20.0 20.0 200.0 200.0
|
||||||
|
|
||||||
|
save
|
||||||
|
setPen blue 20 SolidLine FlatCap
|
||||||
|
pen_setCosmetic true
|
||||||
|
pen_setDashPattern [ 0.0004 0.0004 ]
|
||||||
|
setBrush yellow
|
||||||
|
|
||||||
|
drawPath mypath
|
||||||
|
translate 300 0
|
||||||
|
setRenderHint Antialiasing true
|
||||||
|
drawPath mypath
|
||||||
|
restore
|
||||||
|
|
||||||
|
path_addEllipse bigpath 200000.0 200000.0 2000000.0 2000000.0
|
||||||
|
|
||||||
|
setPen blue 20 DotLine FlatCap
|
||||||
|
setBrush yellow
|
||||||
|
|
||||||
|
save
|
||||||
|
translate 0 300
|
||||||
|
scale 0.0001 0.00011
|
||||||
|
drawPath bigpath
|
||||||
|
restore
|
||||||
|
|
||||||
|
save
|
||||||
|
translate 300 300
|
||||||
|
setRenderHint Antialiasing true
|
||||||
|
scale 0.0001 0.00011
|
||||||
|
drawPath bigpath
|
||||||
|
restore
|
Loading…
x
Reference in New Issue
Block a user