85 lines
3.5 KiB
Diff
85 lines
3.5 KiB
Diff
Description: 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 individually visible
|
|
anyway, just replace with a semi-transparent solid line for such
|
|
cases.
|
|
Origin: upstream, commits:
|
|
https://code.qt.io/cgit/qt/qtbase.git/commit/?id=f4d791b330d02777
|
|
https://code.qt.io/cgit/qt/qtbase.git/commit/?id=6b400e3147dcfd8c
|
|
https://code.qt.io/cgit/qt/qtbase.git/commit/?id=84aba80944a2e1c3
|
|
https://code.qt.io/cgit/qt/qtbase.git/commit/?id=cca8ed0547405b1c
|
|
Last-Update: 2021-11-27
|
|
|
|
--- a/src/gui/painting/qpaintengineex.cpp
|
|
+++ b/src/gui/painting/qpaintengineex.cpp
|
|
@@ -385,10 +385,10 @@ QPainterState *QPaintEngineEx::createSta
|
|
|
|
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
|
|
- qDebug() << "QPaintEngineEx::stroke()" << pen;
|
|
+ qDebug() << "QPaintEngineEx::stroke()" << inPen;
|
|
#endif
|
|
|
|
Q_D(QPaintEngineEx);
|
|
@@ -403,6 +403,38 @@ void QPaintEngineEx::stroke(const QVecto
|
|
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 (qt_pen_is_cosmetic(pen, state()->renderHints)) {
|
|
+ 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
|
|
+ qreal pw = pen.widthF() ? pen.widthF() : 1;
|
|
+ QRectF extentRect = cpRect.adjusted(-pw, -pw, pw, pw) & clipRect;
|
|
+ qreal extent = qMax(extentRect.width(), extentRect.height());
|
|
+ qreal patternLength = 0;
|
|
+ const QVector<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));
|
|
+ patternLength *= pw;
|
|
+ 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)) {
|
|
d->strokerPen = pen;
|
|
d->stroker.setJoinStyle(pen.joinStyle());
|
|
@@ -430,14 +462,8 @@ void QPaintEngineEx::stroke(const QVecto
|
|
return;
|
|
}
|
|
|
|
- if (pen.style() > Qt::SolidLine) {
|
|
- if (qt_pen_is_cosmetic(pen, state()->renderHints)){
|
|
- d->activeStroker->setClipRect(d->exDeviceRect);
|
|
- } else {
|
|
- QRectF clipRect = state()->matrix.inverted().mapRect(QRectF(d->exDeviceRect));
|
|
- d->activeStroker->setClipRect(clipRect);
|
|
- }
|
|
- }
|
|
+ if (!clipRect.isNull())
|
|
+ d->activeStroker->setClipRect(clipRect);
|
|
|
|
if (d->activeStroker == &d->stroker)
|
|
d->stroker.setForceOpen(path.hasExplicitOpen());
|