|
@@ -1,163 +0,0 @@
|
|
|
-From 307bc02e379e63aa9b7a3d21bbcd9c84d34c600f Mon Sep 17 00:00:00 2001
|
|
|
-From: Eirik Aavitsland <eirik.aavitsland@qt.io>
|
|
|
-Date: Tue, 13 Apr 2021 14:23:45 +0200
|
|
|
-Subject: [PATCH] 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.
|
|
|
-
|
|
|
-Pick-to: 6.1 6.0 5.15
|
|
|
-Change-Id: I9e9f7861257ad5bce46a0cf113d1a9d7824911e6
|
|
|
-Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
|
|
|
-(cherry picked from commit f4d791b330d02777fcaf02938732892eb3167e9b)
|
|
|
-
|
|
|
-* asturmlechner 2021-08-21:
|
|
|
-Conflict from preceding 94dd2ceb in dev branch:
|
|
|
- src/gui/painting/qpaintengineex.cpp
|
|
|
- Resolved via:
|
|
|
-
|
|
|
- if (pen.style() > Qt::SolidLine) {
|
|
|
- QRectF cpRect = path.controlPointRect();
|
|
|
- const QTransform &xf = state()->matrix;
|
|
|
-- if (pen.isCosmetic()) {
|
|
|
-+ if (qt_pen_is_cosmetic(pen, state()->renderHints)){
|
|
|
- clipRect = d->exDeviceRect;
|
|
|
- cpRect.translate(xf.dx(), xf.dy());
|
|
|
- } else {
|
|
|
-
|
|
|
-FTBFS from preceding 471e4fcb in dev branch changing QVector to QList:
|
|
|
- Resolved via:
|
|
|
-
|
|
|
- QRectF extentRect = cpRect.adjusted(-pw, -pw, pw, pw) & clipRect;
|
|
|
- qreal extent = qMax(extentRect.width(), extentRect.height());
|
|
|
- qreal patternLength = 0;
|
|
|
-- const QList<qreal> pattern = pen.dashPattern();
|
|
|
-+ 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));
|
|
|
-
|
|
|
-[Retrieved from: https://invent.kde.org/qt/qt/qtbase/-/commit/081d835c040a90f8ee76807354355062ac521dfb]
|
|
|
-Signed-off-by: Quentin Schulz <quentin.schulz@theobroma-systems.com>
|
|
|
----
|
|
|
- src/gui/painting/qpaintengineex.cpp | 44 +++++++++++++++----
|
|
|
- .../other/lancelot/scripts/tinydashes.qps | 34 ++++++++++++++
|
|
|
- 2 files changed, 69 insertions(+), 9 deletions(-)
|
|
|
- create mode 100644 tests/auto/other/lancelot/scripts/tinydashes.qps
|
|
|
-
|
|
|
-diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
|
|
|
-index 5d8f89eadd..55fdb0c2a0 100644
|
|
|
---- a/src/gui/painting/qpaintengineex.cpp
|
|
|
-+++ b/src/gui/painting/qpaintengineex.cpp
|
|
|
-@@ -385,7 +385,7 @@ QPainterState *QPaintEngineEx::createState(QPainterState *orig) const
|
|
|
-
|
|
|
- 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;
|
|
|
-@@ -403,6 +403,38 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
|
|
|
- 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
|
|
|
-+ QRectF extentRect = cpRect & 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));
|
|
|
-+ 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)) {
|
|
|
- d->strokerPen = pen;
|
|
|
- d->stroker.setJoinStyle(pen.joinStyle());
|
|
|
-@@ -430,14 +462,8 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
|
|
|
- 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());
|
|
|
-diff --git a/tests/auto/other/lancelot/scripts/tinydashes.qps b/tests/auto/other/lancelot/scripts/tinydashes.qps
|
|
|
-new file mode 100644
|
|
|
-index 0000000000..d41ced7f5f
|
|
|
---- /dev/null
|
|
|
-+++ b/tests/auto/other/lancelot/scripts/tinydashes.qps
|
|
|
-@@ -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
|
|
|
---
|
|
|
-2.34.1
|
|
|
-
|