0012-Refix-for-avoiding-huge-number-of-tiny-dashes.patch 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. From 3b1a60f651776a7b2d155803b07a52a9e27bdf78 Mon Sep 17 00:00:00 2001
  2. From: Eirik Aavitsland <eirik.aavitsland@qt.io>
  3. Date: Fri, 30 Jul 2021 13:03:49 +0200
  4. Subject: [PATCH] Refix for avoiding huge number of tiny dashes
  5. Previous fix hit too widely so some valid horizontal and vertical
  6. lines were affected; the root problem being that such lines have an
  7. empty control point rect (width or height is 0). Fix by caculating in
  8. the pen width.
  9. Pick-to: 6.2 6.1 5.15
  10. Change-Id: I7a436e873f6d485028f6759d0e2c6456f07eebdc
  11. Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
  12. (cherry picked from commit 84aba80944a2e1c3058d7a1372e0e66676411884)
  13. [Retrieved from: https://invent.kde.org/qt/qt/qtbase/-/commit/427df34efdcb56582a9ae9f7d2d1f39eeff70328]
  14. Signed-off-by: Quentin Schulz <quentin.schulz@theobroma-systems.com>
  15. ---
  16. src/gui/painting/qpaintengineex.cpp | 8 ++---
  17. .../gui/painting/qpainter/tst_qpainter.cpp | 31 +++++++++++++++++++
  18. 2 files changed, 35 insertions(+), 4 deletions(-)
  19. diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
  20. index 19e4b23423..9fe510827a 100644
  21. --- a/src/gui/painting/qpaintengineex.cpp
  22. +++ b/src/gui/painting/qpaintengineex.cpp
  23. @@ -415,18 +415,18 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &inPen)
  24. clipRect = xf.inverted().mapRect(QRectF(d->exDeviceRect));
  25. }
  26. // Check to avoid generating unwieldy amount of dashes that will not be visible anyway
  27. - QRectF extentRect = cpRect & clipRect;
  28. + qreal pw = pen.widthF() ? pen.widthF() : 1;
  29. + QRectF extentRect = cpRect.adjusted(-pw, -pw, pw, pw) & clipRect;
  30. qreal extent = qMax(extentRect.width(), extentRect.height());
  31. qreal patternLength = 0;
  32. const QVector<qreal> pattern = pen.dashPattern();
  33. const int patternSize = qMin(pattern.size(), 32);
  34. for (int i = 0; i < patternSize; i++)
  35. patternLength += qMax(pattern.at(i), qreal(0));
  36. - if (pen.widthF())
  37. - patternLength *= pen.widthF();
  38. + patternLength *= pw;
  39. if (qFuzzyIsNull(patternLength)) {
  40. pen.setStyle(Qt::NoPen);
  41. - } else if (qFuzzyIsNull(extent) || extent / patternLength > 10000) {
  42. + } else if (extent / patternLength > 10000) {
  43. // approximate stream of tiny dashes with semi-transparent solid line
  44. pen.setStyle(Qt::SolidLine);
  45. QColor color(pen.color());
  46. diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
  47. index 42e98ce363..d7c3f95f1d 100644
  48. --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
  49. +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
  50. @@ -308,6 +308,7 @@ private slots:
  51. void fillPolygon();
  52. void drawImageAtPointF();
  53. + void scaledDashes();
  54. private:
  55. void fillData();
  56. @@ -5468,6 +5469,36 @@ void tst_QPainter::drawImageAtPointF()
  57. paint.end();
  58. }
  59. +void tst_QPainter::scaledDashes()
  60. +{
  61. + // Test that we do not hit the limit-huge-number-of-dashes path
  62. + QRgb fore = qRgb(0, 0, 0xff);
  63. + QRgb back = qRgb(0xff, 0xff, 0);
  64. + QImage image(5, 32, QImage::Format_RGB32);
  65. + image.fill(back);
  66. + QPainter p(&image);
  67. + QPen pen(QColor(fore), 3, Qt::DotLine);
  68. + p.setPen(pen);
  69. + p.scale(1, 2);
  70. + p.drawLine(2, 0, 2, 16);
  71. + p.end();
  72. +
  73. + bool foreFound = false;
  74. + bool backFound = false;
  75. + int i = 0;
  76. + while (i < 32 && (!foreFound || !backFound)) {
  77. + QRgb pix = image.pixel(3, i);
  78. + if (pix == fore)
  79. + foreFound = true;
  80. + else if (pix == back)
  81. + backFound = true;
  82. + i++;
  83. + }
  84. +
  85. + QVERIFY(foreFound);
  86. + QVERIFY(backFound);
  87. +}
  88. +
  89. QTEST_MAIN(tst_QPainter)
  90. #include "tst_qpainter.moc"
  91. --
  92. 2.34.1