summaryrefslogtreecommitdiffstats
path: root/src/gui/painting/qcosmeticstroker.cpp
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-05-29 11:56:16 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-11-09 14:04:13 +0100
commit04413b9dd8f3983fd5471354a48ad1257ca4f290 (patch)
treed5483c6d5f07251c18306e7f29ccbe5430b0761c /src/gui/painting/qcosmeticstroker.cpp
parentccc205bf38ffbe60180a069939a4aff01e7734e5 (diff)
Allow painting above INT16_MAX on 64-bit architectures
The logic in qgrayraster was ready for it except for an intermediate format. qrasterizer.cpp and qcosmeticstroker.cpp uses a dot-16 fixed point format, and had to be changed to handle higher coordinates on 64-bit architectures. Fixes: QTBUG-84428 Change-Id: I85ab7a04e38bd0dbcefa9f16c16ccc84785a33cf Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/gui/painting/qcosmeticstroker.cpp')
-rw-r--r--src/gui/painting/qcosmeticstroker.cpp40
1 files changed, 25 insertions, 15 deletions
diff --git a/src/gui/painting/qcosmeticstroker.cpp b/src/gui/painting/qcosmeticstroker.cpp
index 74e4fcb96f..9e06a3f109 100644
--- a/src/gui/painting/qcosmeticstroker.cpp
+++ b/src/gui/painting/qcosmeticstroker.cpp
@@ -58,6 +58,12 @@ inline QString capString(int caps)
}
#endif
+#if Q_PROCESSOR_WORDSIZE == 8
+typedef qint64 FDot16;
+#else
+typedef int FDot16;
+#endif
+
#define toF26Dot6(x) ((int)((x)*64.))
static inline uint sourceOver(uint d, uint color)
@@ -65,11 +71,15 @@ static inline uint sourceOver(uint d, uint color)
return color + BYTE_MUL(d, qAlpha(~color));
}
-inline static int F16Dot16FixedDiv(int x, int y)
+inline static FDot16 FDot16FixedDiv(int x, int y)
{
+#if Q_PROCESSOR_WORDSIZE == 8
+ return FDot16(x) * (1<<16) / y;
+#else
if (qAbs(x) > 0x7fff)
return qlonglong(x) * (1<<16) / y;
return x * (1<<16) / y;
+#endif
}
typedef void (*DrawPixel)(QCosmeticStroker *stroker, int x, int y, int coverage);
@@ -157,7 +167,7 @@ inline void drawPixel(QCosmeticStroker *stroker, int x, int y, int coverage)
}
}
- stroker->spans[stroker->current_span].x = ushort(x);
+ stroker->spans[stroker->current_span].x = x;
stroker->spans[stroker->current_span].len = 1;
stroker->spans[stroker->current_span].y = y;
stroker->spans[stroker->current_span].coverage = coverage*stroker->opacity >> 8;
@@ -441,8 +451,8 @@ void QCosmeticStroker::calculateLastPoint(qreal rx1, qreal ry1, qreal rx2, qreal
qSwap(y1, y2);
qSwap(x1, x2);
}
- int xinc = F16Dot16FixedDiv(x2 - x1, y2 - y1);
- int x = x1 * (1<<10);
+ FDot16 xinc = FDot16FixedDiv(x2 - x1, y2 - y1);
+ FDot16 x = FDot16(x1) * (1<<10);
int y = (y1 + 32) >> 6;
int ys = (y2 + 32) >> 6;
@@ -473,8 +483,8 @@ void QCosmeticStroker::calculateLastPoint(qreal rx1, qreal ry1, qreal rx2, qreal
qSwap(x1, x2);
qSwap(y1, y2);
}
- int yinc = F16Dot16FixedDiv(y2 - y1, x2 - x1);
- int y = y1 * (1 << 10);
+ FDot16 yinc = FDot16FixedDiv(y2 - y1, x2 - x1);
+ FDot16 y = FDot16(y1) * (1 << 10);
int x = (x1 + 32) >> 6;
int xs = (x2 + 32) >> 6;
@@ -715,7 +725,7 @@ static inline int swapCaps(int caps)
}
// adjust line by half a pixel
-static inline void capAdjust(int caps, int &x1, int &x2, int &y, int yinc)
+static inline void capAdjust(int caps, int &x1, int &x2, FDot16 &y, FDot16 yinc)
{
if (caps & QCosmeticStroker::CapBegin) {
x1 -= 32;
@@ -763,8 +773,8 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
caps = swapCaps(caps);
dir = QCosmeticStroker::BottomToTop;
}
- int xinc = F16Dot16FixedDiv(x2 - x1, y2 - y1);
- int x = x1 * (1<<10);
+ FDot16 xinc = FDot16FixedDiv(x2 - x1, y2 - y1);
+ FDot16 x = FDot16(x1) * (1<<10);
if ((stroker->lastDir ^ QCosmeticStroker::VerticalMask) == dir)
caps |= swapped ? QCosmeticStroker::CapEnd : QCosmeticStroker::CapBegin;
@@ -853,8 +863,8 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
caps = swapCaps(caps);
dir = QCosmeticStroker::RightToLeft;
}
- int yinc = F16Dot16FixedDiv(y2 - y1, x2 - x1);
- int y = y1 * (1<<10);
+ FDot16 yinc = FDot16FixedDiv(y2 - y1, x2 - x1);
+ FDot16 y = FDot16(y1) * (1<<10);
if ((stroker->lastDir ^ QCosmeticStroker::HorizontalMask) == dir)
caps |= swapped ? QCosmeticStroker::CapEnd : QCosmeticStroker::CapBegin;
@@ -950,7 +960,7 @@ static bool drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx
if (qAbs(dx) < qAbs(dy)) {
// vertical
- int xinc = F16Dot16FixedDiv(dx, dy);
+ FDot16 xinc = FDot16FixedDiv(dx, dy);
bool swapped = false;
if (y1 > y2) {
@@ -960,7 +970,7 @@ static bool drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx
caps = swapCaps(caps);
}
- int x = (x1 - 32) * (1<<10);
+ FDot16 x = FDot16(x1 - 32) * (1<<10);
x -= ( ((y1 & 63) - 32) * xinc ) >> 6;
capAdjust(caps, y1, y2, x, xinc);
@@ -1013,7 +1023,7 @@ static bool drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx
if (!dx)
return true;
- int yinc = F16Dot16FixedDiv(dy, dx);
+ FDot16 yinc = FDot16FixedDiv(dy, dx);
bool swapped = false;
if (x1 > x2) {
@@ -1023,7 +1033,7 @@ static bool drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx
caps = swapCaps(caps);
}
- int y = (y1 - 32) * (1<<10);
+ FDot16 y = FDot16(y1 - 32) * (1<<10);
y -= ( ((x1 & 63) - 32) * yinc ) >> 6;
capAdjust(caps, x1, x2, y, yinc);