summaryrefslogtreecommitdiffstats
path: root/src/gui/painting/qrasterizer.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/qrasterizer.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/qrasterizer.cpp')
-rw-r--r--src/gui/painting/qrasterizer.cpp285
1 files changed, 147 insertions, 138 deletions
diff --git a/src/gui/painting/qrasterizer.cpp b/src/gui/painting/qrasterizer.cpp
index e6f48a79b8..3902b072c9 100644
--- a/src/gui/painting/qrasterizer.cpp
+++ b/src/gui/painting/qrasterizer.cpp
@@ -52,15 +52,20 @@
QT_BEGIN_NAMESPACE
-typedef int Q16Dot16;
-#define Q16Dot16ToFloat(i) ((i)/65536.)
-#define FloatToQ16Dot16(i) (int)((i) * 65536.)
-#define IntToQ16Dot16(i) ((i) * (1 << 16))
-#define Q16Dot16ToInt(i) ((i) >> 16)
-#define Q16Dot16Factor 65536
-
-#define Q16Dot16Multiply(x, y) (int)((qlonglong(x) * qlonglong(y)) >> 16)
-#define Q16Dot16FastMultiply(x, y) (((x) * (y)) >> 16)
+#if Q_PROCESSOR_WORDSIZE == 8
+typedef qint64 QScFixed;
+#else
+typedef int QScFixed;
+#endif
+#define QScFixedToFloat(i) ((i) * (1./65536.))
+#define FloatToQScFixed(i) (QScFixed)((i) * 65536.)
+#define IntToQScFixed(i) ((QScFixed)(i) * (1 << 16))
+#define QScFixedToInt(i) ((i) >> 16)
+#define QScFixedFactor 65536
+#define FTPosToQScFixed(i) ((QScFixed)(i) * (1 << 10))
+
+#define QScFixedMultiply(x, y) (QScFixed)((qlonglong(x) * qlonglong(y)) >> 16)
+#define QScFixedFastMultiply(x, y) (((x) * (y)) >> 16)
#define SPAN_BUFFER_SIZE 256
@@ -88,11 +93,12 @@ public:
flushSpans();
}
- void addSpan(int x, unsigned int len, int y, unsigned char coverage)
+ void addSpan(int x, int len, int y, int coverage)
{
if (!coverage || !len)
return;
+ Q_ASSERT(coverage >= 0 && coverage <= 255);
Q_ASSERT(y >= m_clipRect.top());
Q_ASSERT(y <= m_clipRect.bottom());
Q_ASSERT(x >= m_clipRect.left());
@@ -140,8 +146,8 @@ public:
struct Line
{
- Q16Dot16 x;
- Q16Dot16 delta;
+ QScFixed x;
+ QScFixed delta;
int top, bottom;
@@ -157,7 +163,7 @@ private:
int left, right;
};
- inline bool clip(Q16Dot16 &xFP, int &iTop, int &iBottom, Q16Dot16 slopeFP, Q16Dot16 edgeFP, int winding);
+ inline bool clip(QScFixed &xFP, int &iTop, int &iBottom, QScFixed slopeFP, QScFixed edgeFP, int winding);
inline void mergeIntersection(Intersection *head, const Intersection &isect);
void prepareChunk();
@@ -175,8 +181,8 @@ private:
int m_top;
int m_bottom;
- Q16Dot16 m_leftFP;
- Q16Dot16 m_rightFP;
+ QScFixed m_leftFP;
+ QScFixed m_rightFP;
int m_fillRuleMask;
bool m_legacyRounding;
@@ -228,8 +234,8 @@ void QScanConverter::begin(int top, int bottom, int left, int right,
{
m_top = top;
m_bottom = bottom;
- m_leftFP = IntToQ16Dot16(left);
- m_rightFP = IntToQ16Dot16(right + 1);
+ m_leftFP = IntToQScFixed(left);
+ m_rightFP = IntToQScFixed(right + 1);
m_lines.reset();
@@ -350,7 +356,7 @@ void QScanConverter::scanConvert()
for (int i = 0; i < numActive; ++i) {
QScanConverter::Line *node = m_active.at(i);
- const int current = Q16Dot16ToInt(node->x);
+ const int current = QScFixedToInt(node->x);
if (winding & m_fillRuleMask)
m_spanBuffer->addSpan(x, current - x, y, 0xff);
@@ -414,12 +420,12 @@ void QScanConverter::end()
if (line.delta) {
for (; it != end; ++it) {
- isect.x = Q16Dot16ToInt(line.x);
+ isect.x = QScFixedToInt(line.x);
line.x += line.delta;
mergeIntersection(it, isect);
}
} else {
- isect.x = Q16Dot16ToInt(line.x);
+ isect.x = QScFixedToInt(line.x);
for (; it != end; ++it)
mergeIntersection(it, isect);
}
@@ -516,7 +522,7 @@ void QScanConverter::mergeCurve(const QT_FT_Vector &pa, const QT_FT_Vector &pb,
}
}
-inline bool QScanConverter::clip(Q16Dot16 &xFP, int &iTop, int &iBottom, Q16Dot16 slopeFP, Q16Dot16 edgeFP, int winding)
+inline bool QScanConverter::clip(QScFixed &xFP, int &iTop, int &iBottom, QScFixed slopeFP, QScFixed edgeFP, int winding)
{
bool right = edgeFP == m_rightFP;
@@ -530,7 +536,7 @@ inline bool QScanConverter::clip(Q16Dot16 &xFP, int &iTop, int &iBottom, Q16Dot1
}
}
- Q16Dot16 lastFP = xFP + slopeFP * (iBottom - iTop);
+ QScFixed lastFP = xFP + slopeFP * (iBottom - iTop);
if (lastFP == edgeFP) {
if ((slopeFP < 0) ^ right)
@@ -544,11 +550,11 @@ inline bool QScanConverter::clip(Q16Dot16 &xFP, int &iTop, int &iBottom, Q16Dot1
// does line cross edge?
if ((lastFP < edgeFP) ^ (xFP < edgeFP)) {
- Q16Dot16 deltaY = Q16Dot16((edgeFP - xFP) / Q16Dot16ToFloat(slopeFP));
+ QScFixed deltaY = QScFixed((edgeFP - xFP) / QScFixedToFloat(slopeFP));
if ((xFP < edgeFP) ^ right) {
// top segment needs to be clipped
- int iHeight = Q16Dot16ToInt(deltaY + 1);
+ int iHeight = QScFixedToInt(deltaY + 1);
int iMiddle = iTop + iHeight;
Line line = { edgeFP, 0, iTop, iMiddle, winding };
@@ -561,7 +567,7 @@ inline bool QScanConverter::clip(Q16Dot16 &xFP, int &iTop, int &iBottom, Q16Dot1
return true;
} else {
// bottom segment needs to be clipped
- int iHeight = Q16Dot16ToInt(deltaY);
+ int iHeight = QScFixedToInt(deltaY);
int iMiddle = iTop + iHeight;
if (iMiddle != iBottom) {
@@ -603,7 +609,7 @@ void QScanConverter::mergeLine(QT_FT_Vector a, QT_FT_Vector b)
int iBottom = qMin(m_bottom, int((b.y - 32 - rounding) >> 6));
if (iTop <= iBottom) {
- Q16Dot16 aFP = Q16Dot16Factor/2 + (a.x * (1 << 10)) - rounding;
+ QScFixed aFP = QScFixedFactor/2 + FTPosToQScFixed(a.x - rounding);
if (b.x == a.x) {
Line line = { qBound(m_leftFP, aFP, m_rightFP), 0, iTop, iBottom, winding };
@@ -611,11 +617,11 @@ void QScanConverter::mergeLine(QT_FT_Vector a, QT_FT_Vector b)
} else {
const qreal slope = (b.x - a.x) / qreal(b.y - a.y);
- const Q16Dot16 slopeFP = FloatToQ16Dot16(slope);
+ const QScFixed slopeFP = FloatToQScFixed(slope);
- Q16Dot16 xFP = aFP + Q16Dot16Multiply(slopeFP,
- IntToQ16Dot16(iTop)
- + Q16Dot16Factor/2 - (a.y * (1 << 10)));
+ QScFixed xFP = aFP + QScFixedMultiply(slopeFP,
+ IntToQScFixed(iTop)
+ + QScFixedFactor/2 - FTPosToQScFixed(a.y));
if (clip(xFP, iTop, iBottom, slopeFP, m_leftFP, winding))
return;
@@ -663,37 +669,37 @@ void QRasterizer::setLegacyRoundingEnabled(bool legacyRoundingEnabled)
d->legacyRounding = legacyRoundingEnabled;
}
-static Q16Dot16 intersectPixelFP(int x, Q16Dot16 top, Q16Dot16 bottom, Q16Dot16 leftIntersectX, Q16Dot16 rightIntersectX, Q16Dot16 slope, Q16Dot16 invSlope)
+static QScFixed intersectPixelFP(int x, QScFixed top, QScFixed bottom, QScFixed leftIntersectX, QScFixed rightIntersectX, QScFixed slope, QScFixed invSlope)
{
- Q16Dot16 leftX = IntToQ16Dot16(x);
- Q16Dot16 rightX = IntToQ16Dot16(x) + Q16Dot16Factor;
+ QScFixed leftX = IntToQScFixed(x);
+ QScFixed rightX = IntToQScFixed(x) + QScFixedFactor;
- Q16Dot16 leftIntersectY, rightIntersectY;
+ QScFixed leftIntersectY, rightIntersectY;
if (slope > 0) {
- leftIntersectY = top + Q16Dot16Multiply(leftX - leftIntersectX, invSlope);
+ leftIntersectY = top + QScFixedMultiply(leftX - leftIntersectX, invSlope);
rightIntersectY = leftIntersectY + invSlope;
} else {
- leftIntersectY = top + Q16Dot16Multiply(leftX - rightIntersectX, invSlope);
+ leftIntersectY = top + QScFixedMultiply(leftX - rightIntersectX, invSlope);
rightIntersectY = leftIntersectY + invSlope;
}
if (leftIntersectX >= leftX && rightIntersectX <= rightX) {
- return Q16Dot16Multiply(bottom - top, leftIntersectX - leftX + ((rightIntersectX - leftIntersectX) >> 1));
+ return QScFixedMultiply(bottom - top, leftIntersectX - leftX + ((rightIntersectX - leftIntersectX) >> 1));
} else if (leftIntersectX >= rightX) {
return bottom - top;
} else if (leftIntersectX >= leftX) {
if (slope > 0) {
- return (bottom - top) - Q16Dot16FastMultiply((rightX - leftIntersectX) >> 1, rightIntersectY - top);
+ return (bottom - top) - QScFixedFastMultiply((rightX - leftIntersectX) >> 1, rightIntersectY - top);
} else {
- return (bottom - top) - Q16Dot16FastMultiply((rightX - leftIntersectX) >> 1, bottom - rightIntersectY);
+ return (bottom - top) - QScFixedFastMultiply((rightX - leftIntersectX) >> 1, bottom - rightIntersectY);
}
} else if (rightIntersectX <= leftX) {
return 0;
} else if (rightIntersectX <= rightX) {
if (slope > 0) {
- return Q16Dot16FastMultiply((rightIntersectX - leftX) >> 1, bottom - leftIntersectY);
+ return QScFixedFastMultiply((rightIntersectX - leftX) >> 1, bottom - leftIntersectY);
} else {
- return Q16Dot16FastMultiply((rightIntersectX - leftX) >> 1, leftIntersectY - top);
+ return QScFixedFastMultiply((rightIntersectX - leftX) >> 1, leftIntersectY - top);
}
} else {
if (slope > 0) {
@@ -734,14 +740,14 @@ static inline qreal qSafeDivide(qreal x, qreal y)
too small to fit into INT_MIN, so we need this slightly safer conversion
when floating point exceptions are enabled
*/
-static inline int qSafeFloatToQ16Dot16(qreal x)
+static inline QScFixed qSafeFloatToQScFixed(qreal x)
{
- qreal tmp = x * 65536.;
- if (tmp > qreal(INT_MAX))
- return INT_MAX;
- else if (tmp < qreal(INT_MIN))
- return -INT_MAX;
- return int(tmp);
+ qreal tmp = x * QScFixedFactor;
+ if (tmp > qreal(std::numeric_limits<QScFixed>::max()))
+ return std::numeric_limits<QScFixed>::max();
+ else if (tmp < qreal(std::numeric_limits<QScFixed>::min()))
+ return std::numeric_limits<QScFixed>::min();
+ return QScFixed(tmp);
}
void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, bool squareCap)
@@ -855,30 +861,33 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
return;
if (d->antialiased) {
- const Q16Dot16 iLeft = int(left);
- const Q16Dot16 iRight = int(right);
- const Q16Dot16 leftWidth = IntToQ16Dot16(iLeft + 1)
- - qSafeFloatToQ16Dot16(left);
- const Q16Dot16 rightWidth = qSafeFloatToQ16Dot16(right)
- - IntToQ16Dot16(iRight);
-
- Q16Dot16 coverage[3];
+ const int iLeft = int(left);
+ const int iRight = int(right);
+ const QScFixed leftWidth = IntToQScFixed(iLeft + 1)
+ - qSafeFloatToQScFixed(left);
+ const QScFixed rightWidth = qSafeFloatToQScFixed(right)
+ - IntToQScFixed(iRight);
+
+ QScFixed coverage[3];
int x[3];
int len[3];
int n = 1;
if (iLeft == iRight) {
- coverage[0] = (leftWidth + rightWidth) * 255;
+ if (leftWidth == QScFixedFactor)
+ coverage[0] = rightWidth * 255;
+ else
+ coverage[0] = (leftWidth + rightWidth) * 255;
x[0] = iLeft;
len[0] = 1;
} else {
coverage[0] = leftWidth * 255;
x[0] = iLeft;
len[0] = 1;
- if (leftWidth == Q16Dot16Factor) {
+ if (leftWidth == QScFixedFactor) {
len[0] = iRight - iLeft;
} else if (iRight - iLeft > 1) {
- coverage[1] = IntToQ16Dot16(255);
+ coverage[1] = IntToQScFixed(255);
x[1] = iLeft + 1;
len[1] = iRight - iLeft - 1;
++n;
@@ -891,19 +900,19 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
}
}
- const Q16Dot16 iTopFP = IntToQ16Dot16(int(pa.y()));
- const Q16Dot16 iBottomFP = IntToQ16Dot16(int(pb.y()));
- const Q16Dot16 yPa = qSafeFloatToQ16Dot16(pa.y());
- const Q16Dot16 yPb = qSafeFloatToQ16Dot16(pb.y());
- for (Q16Dot16 yFP = iTopFP; yFP <= iBottomFP; yFP += Q16Dot16Factor) {
- const Q16Dot16 rowHeight = qMin(yFP + Q16Dot16Factor, yPb)
+ const QScFixed iTopFP = IntToQScFixed(int(pa.y()));
+ const QScFixed iBottomFP = IntToQScFixed(int(pb.y()));
+ const QScFixed yPa = qSafeFloatToQScFixed(pa.y());
+ const QScFixed yPb = qSafeFloatToQScFixed(pb.y());
+ for (QScFixed yFP = iTopFP; yFP <= iBottomFP; yFP += QScFixedFactor) {
+ const QScFixed rowHeight = qMin(yFP + QScFixedFactor, yPb)
- qMax(yFP, yPa);
- const int y = Q16Dot16ToInt(yFP);
+ const int y = QScFixedToInt(yFP);
if (y > d->clipRect.bottom())
break;
for (int i = 0; i < n; ++i) {
buffer.addSpan(x[i], len[i], y,
- Q16Dot16ToInt(Q16Dot16Multiply(rowHeight, coverage[i])));
+ QScFixedToInt(QScFixedMultiply(rowHeight, coverage[i])));
}
}
} else { // aliased
@@ -960,111 +969,111 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
const qreal topRightSlope = qSafeDivide(topRightEdge.x(), topRightEdge.y());
const qreal bottomRightSlope = qSafeDivide(bottomRightEdge.x(), bottomRightEdge.y());
- const Q16Dot16 topLeftSlopeFP = qSafeFloatToQ16Dot16(topLeftSlope);
- const Q16Dot16 topRightSlopeFP = qSafeFloatToQ16Dot16(topRightSlope);
+ const QScFixed topLeftSlopeFP = qSafeFloatToQScFixed(topLeftSlope);
+ const QScFixed topRightSlopeFP = qSafeFloatToQScFixed(topRightSlope);
- const Q16Dot16 bottomLeftSlopeFP = qSafeFloatToQ16Dot16(bottomLeftSlope);
- const Q16Dot16 bottomRightSlopeFP = qSafeFloatToQ16Dot16(bottomRightSlope);
+ const QScFixed bottomLeftSlopeFP = qSafeFloatToQScFixed(bottomLeftSlope);
+ const QScFixed bottomRightSlopeFP = qSafeFloatToQScFixed(bottomRightSlope);
- const Q16Dot16 invTopLeftSlopeFP = qSafeFloatToQ16Dot16(qSafeDivide(1, topLeftSlope));
- const Q16Dot16 invTopRightSlopeFP = qSafeFloatToQ16Dot16(qSafeDivide(1, topRightSlope));
+ const QScFixed invTopLeftSlopeFP = qSafeFloatToQScFixed(qSafeDivide(1, topLeftSlope));
+ const QScFixed invTopRightSlopeFP = qSafeFloatToQScFixed(qSafeDivide(1, topRightSlope));
- const Q16Dot16 invBottomLeftSlopeFP = qSafeFloatToQ16Dot16(qSafeDivide(1, bottomLeftSlope));
- const Q16Dot16 invBottomRightSlopeFP = qSafeFloatToQ16Dot16(qSafeDivide(1, bottomRightSlope));
+ const QScFixed invBottomLeftSlopeFP = qSafeFloatToQScFixed(qSafeDivide(1, bottomLeftSlope));
+ const QScFixed invBottomRightSlopeFP = qSafeFloatToQScFixed(qSafeDivide(1, bottomRightSlope));
if (d->antialiased) {
- const Q16Dot16 iTopFP = IntToQ16Dot16(int(topBound));
- const Q16Dot16 iLeftFP = IntToQ16Dot16(int(left.y()));
- const Q16Dot16 iRightFP = IntToQ16Dot16(int(right.y()));
- const Q16Dot16 iBottomFP = IntToQ16Dot16(int(bottomBound));
+ const QScFixed iTopFP = IntToQScFixed(int(topBound));
+ const QScFixed iLeftFP = IntToQScFixed(int(left.y()));
+ const QScFixed iRightFP = IntToQScFixed(int(right.y()));
+ const QScFixed iBottomFP = IntToQScFixed(int(bottomBound));
- Q16Dot16 leftIntersectAf = qSafeFloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * topLeftSlope);
- Q16Dot16 rightIntersectAf = qSafeFloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * topRightSlope);
- Q16Dot16 leftIntersectBf = 0;
- Q16Dot16 rightIntersectBf = 0;
+ QScFixed leftIntersectAf = qSafeFloatToQScFixed(top.x() + (int(topBound) - top.y()) * topLeftSlope);
+ QScFixed rightIntersectAf = qSafeFloatToQScFixed(top.x() + (int(topBound) - top.y()) * topRightSlope);
+ QScFixed leftIntersectBf = 0;
+ QScFixed rightIntersectBf = 0;
if (iLeftFP < iTopFP)
- leftIntersectBf = qSafeFloatToQ16Dot16(left.x() + (int(topBound) - left.y()) * bottomLeftSlope);
+ leftIntersectBf = qSafeFloatToQScFixed(left.x() + (int(topBound) - left.y()) * bottomLeftSlope);
if (iRightFP < iTopFP)
- rightIntersectBf = qSafeFloatToQ16Dot16(right.x() + (int(topBound) - right.y()) * bottomRightSlope);
+ rightIntersectBf = qSafeFloatToQScFixed(right.x() + (int(topBound) - right.y()) * bottomRightSlope);
- Q16Dot16 rowTop, rowBottomLeft, rowBottomRight, rowTopLeft, rowTopRight, rowBottom;
- Q16Dot16 topLeftIntersectAf, topLeftIntersectBf, topRightIntersectAf, topRightIntersectBf;
- Q16Dot16 bottomLeftIntersectAf, bottomLeftIntersectBf, bottomRightIntersectAf, bottomRightIntersectBf;
+ QScFixed rowTop, rowBottomLeft, rowBottomRight, rowTopLeft, rowTopRight, rowBottom;
+ QScFixed topLeftIntersectAf, topLeftIntersectBf, topRightIntersectAf, topRightIntersectBf;
+ QScFixed bottomLeftIntersectAf, bottomLeftIntersectBf, bottomRightIntersectAf, bottomRightIntersectBf;
int leftMin, leftMax, rightMin, rightMax;
- const Q16Dot16 yTopFP = qSafeFloatToQ16Dot16(top.y());
- const Q16Dot16 yLeftFP = qSafeFloatToQ16Dot16(left.y());
- const Q16Dot16 yRightFP = qSafeFloatToQ16Dot16(right.y());
- const Q16Dot16 yBottomFP = qSafeFloatToQ16Dot16(bottom.y());
+ const QScFixed yTopFP = qSafeFloatToQScFixed(top.y());
+ const QScFixed yLeftFP = qSafeFloatToQScFixed(left.y());
+ const QScFixed yRightFP = qSafeFloatToQScFixed(right.y());
+ const QScFixed yBottomFP = qSafeFloatToQScFixed(bottom.y());
rowTop = qMax(iTopFP, yTopFP);
topLeftIntersectAf = leftIntersectAf +
- Q16Dot16Multiply(topLeftSlopeFP, rowTop - iTopFP);
+ QScFixedMultiply(topLeftSlopeFP, rowTop - iTopFP);
topRightIntersectAf = rightIntersectAf +
- Q16Dot16Multiply(topRightSlopeFP, rowTop - iTopFP);
+ QScFixedMultiply(topRightSlopeFP, rowTop - iTopFP);
- Q16Dot16 yFP = iTopFP;
+ QScFixed yFP = iTopFP;
while (yFP <= iBottomFP) {
- rowBottomLeft = qMin(yFP + Q16Dot16Factor, yLeftFP);
- rowBottomRight = qMin(yFP + Q16Dot16Factor, yRightFP);
+ rowBottomLeft = qMin(yFP + QScFixedFactor, yLeftFP);
+ rowBottomRight = qMin(yFP + QScFixedFactor, yRightFP);
rowTopLeft = qMax(yFP, yLeftFP);
rowTopRight = qMax(yFP, yRightFP);
- rowBottom = qMin(yFP + Q16Dot16Factor, yBottomFP);
+ rowBottom = qMin(yFP + QScFixedFactor, yBottomFP);
if (yFP == iLeftFP) {
- const int y = Q16Dot16ToInt(yFP);
- leftIntersectBf = qSafeFloatToQ16Dot16(left.x() + (y - left.y()) * bottomLeftSlope);
- topLeftIntersectBf = leftIntersectBf + Q16Dot16Multiply(bottomLeftSlopeFP, rowTopLeft - yFP);
- bottomLeftIntersectAf = leftIntersectAf + Q16Dot16Multiply(topLeftSlopeFP, rowBottomLeft - yFP);
+ const int y = QScFixedToInt(yFP);
+ leftIntersectBf = qSafeFloatToQScFixed(left.x() + (y - left.y()) * bottomLeftSlope);
+ topLeftIntersectBf = leftIntersectBf + QScFixedMultiply(bottomLeftSlopeFP, rowTopLeft - yFP);
+ bottomLeftIntersectAf = leftIntersectAf + QScFixedMultiply(topLeftSlopeFP, rowBottomLeft - yFP);
} else {
topLeftIntersectBf = leftIntersectBf;
bottomLeftIntersectAf = leftIntersectAf + topLeftSlopeFP;
}
if (yFP == iRightFP) {
- const int y = Q16Dot16ToInt(yFP);
- rightIntersectBf = qSafeFloatToQ16Dot16(right.x() + (y - right.y()) * bottomRightSlope);
- topRightIntersectBf = rightIntersectBf + Q16Dot16Multiply(bottomRightSlopeFP, rowTopRight - yFP);
- bottomRightIntersectAf = rightIntersectAf + Q16Dot16Multiply(topRightSlopeFP, rowBottomRight - yFP);
+ const int y = QScFixedToInt(yFP);
+ rightIntersectBf = qSafeFloatToQScFixed(right.x() + (y - right.y()) * bottomRightSlope);
+ topRightIntersectBf = rightIntersectBf + QScFixedMultiply(bottomRightSlopeFP, rowTopRight - yFP);
+ bottomRightIntersectAf = rightIntersectAf + QScFixedMultiply(topRightSlopeFP, rowBottomRight - yFP);
} else {
topRightIntersectBf = rightIntersectBf;
bottomRightIntersectAf = rightIntersectAf + topRightSlopeFP;
}
if (yFP == iBottomFP) {
- bottomLeftIntersectBf = leftIntersectBf + Q16Dot16Multiply(bottomLeftSlopeFP, rowBottom - yFP);
- bottomRightIntersectBf = rightIntersectBf + Q16Dot16Multiply(bottomRightSlopeFP, rowBottom - yFP);
+ bottomLeftIntersectBf = leftIntersectBf + QScFixedMultiply(bottomLeftSlopeFP, rowBottom - yFP);
+ bottomRightIntersectBf = rightIntersectBf + QScFixedMultiply(bottomRightSlopeFP, rowBottom - yFP);
} else {
bottomLeftIntersectBf = leftIntersectBf + bottomLeftSlopeFP;
bottomRightIntersectBf = rightIntersectBf + bottomRightSlopeFP;
}
if (yFP < iLeftFP) {
- leftMin = Q16Dot16ToInt(bottomLeftIntersectAf);
- leftMax = Q16Dot16ToInt(topLeftIntersectAf);
+ leftMin = QScFixedToInt(bottomLeftIntersectAf);
+ leftMax = QScFixedToInt(topLeftIntersectAf);
} else if (yFP == iLeftFP) {
- leftMin = Q16Dot16ToInt(qMax(bottomLeftIntersectAf, topLeftIntersectBf));
- leftMax = Q16Dot16ToInt(qMax(topLeftIntersectAf, bottomLeftIntersectBf));
+ leftMin = QScFixedToInt(qMax(bottomLeftIntersectAf, topLeftIntersectBf));
+ leftMax = QScFixedToInt(qMax(topLeftIntersectAf, bottomLeftIntersectBf));
} else {
- leftMin = Q16Dot16ToInt(topLeftIntersectBf);
- leftMax = Q16Dot16ToInt(bottomLeftIntersectBf);
+ leftMin = QScFixedToInt(topLeftIntersectBf);
+ leftMax = QScFixedToInt(bottomLeftIntersectBf);
}
leftMin = qBound(d->clipRect.left(), leftMin, d->clipRect.right());
leftMax = qBound(d->clipRect.left(), leftMax, d->clipRect.right());
if (yFP < iRightFP) {
- rightMin = Q16Dot16ToInt(topRightIntersectAf);
- rightMax = Q16Dot16ToInt(bottomRightIntersectAf);
+ rightMin = QScFixedToInt(topRightIntersectAf);
+ rightMax = QScFixedToInt(bottomRightIntersectAf);
} else if (yFP == iRightFP) {
- rightMin = Q16Dot16ToInt(qMin(topRightIntersectAf, bottomRightIntersectBf));
- rightMax = Q16Dot16ToInt(qMin(bottomRightIntersectAf, topRightIntersectBf));
+ rightMin = QScFixedToInt(qMin(topRightIntersectAf, bottomRightIntersectBf));
+ rightMax = QScFixedToInt(qMin(bottomRightIntersectAf, topRightIntersectBf));
} else {
- rightMin = Q16Dot16ToInt(bottomRightIntersectBf);
- rightMax = Q16Dot16ToInt(topRightIntersectBf);
+ rightMin = QScFixedToInt(bottomRightIntersectBf);
+ rightMax = QScFixedToInt(topRightIntersectBf);
}
rightMin = qBound(d->clipRect.left(), rightMin, d->clipRect.right());
@@ -1075,11 +1084,11 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
if (rightMin < leftMin)
rightMin = leftMin;
- Q16Dot16 rowHeight = rowBottom - rowTop;
+ QScFixed rowHeight = rowBottom - rowTop;
int x = leftMin;
while (x <= leftMax) {
- Q16Dot16 excluded = 0;
+ QScFixed excluded = 0;
if (yFP <= iLeftFP)
excluded += intersectPixelFP(x, rowTop, rowBottomLeft,
@@ -1101,18 +1110,18 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
bottomRightSlopeFP, invBottomRightSlopeFP);
}
- Q16Dot16 coverage = rowHeight - excluded;
- buffer.addSpan(x, 1, Q16Dot16ToInt(yFP),
- Q16Dot16ToInt(255 * coverage));
+ QScFixed coverage = rowHeight - excluded;
+ buffer.addSpan(x, 1, QScFixedToInt(yFP),
+ QScFixedToInt(255 * coverage));
++x;
}
if (x < rightMin) {
- buffer.addSpan(x, rightMin - x, Q16Dot16ToInt(yFP),
- Q16Dot16ToInt(255 * rowHeight));
+ buffer.addSpan(x, rightMin - x, QScFixedToInt(yFP),
+ QScFixedToInt(255 * rowHeight));
x = rightMin;
}
while (x <= rightMax) {
- Q16Dot16 excluded = 0;
+ QScFixed excluded = 0;
if (yFP <= iRightFP)
excluded += (rowBottomRight - rowTop) - intersectPixelFP(x, rowTop, rowBottomRight,
topRightIntersectAf, bottomRightIntersectAf,
@@ -1122,9 +1131,9 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
bottomRightIntersectBf, topRightIntersectBf,
bottomRightSlopeFP, invBottomRightSlopeFP);
- Q16Dot16 coverage = rowHeight - excluded;
- buffer.addSpan(x, 1, Q16Dot16ToInt(yFP),
- Q16Dot16ToInt(255 * coverage));
+ QScFixed coverage = rowHeight - excluded;
+ buffer.addSpan(x, 1, QScFixedToInt(yFP),
+ QScFixedToInt(255 * coverage));
++x;
}
@@ -1135,7 +1144,7 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
topLeftIntersectAf = leftIntersectAf;
topRightIntersectAf = rightIntersectAf;
- yFP += Q16Dot16Factor;
+ yFP += QScFixedFactor;
rowTop = yFP;
}
} else { // aliased
@@ -1145,10 +1154,10 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
int iBottom = bottom.y() < 0.5f? -1 : int(bottom.y() - 0.5f);
int iMiddle = qMin(iLeft, iRight);
- Q16Dot16 leftIntersectAf = qSafeFloatToQ16Dot16(top.x() + 0.5f + (iTop + 0.5f - top.y()) * topLeftSlope);
- Q16Dot16 leftIntersectBf = qSafeFloatToQ16Dot16(left.x() + 0.5f + (iLeft + 1.5f - left.y()) * bottomLeftSlope);
- Q16Dot16 rightIntersectAf = qSafeFloatToQ16Dot16(top.x() - 0.5f + (iTop + 0.5f - top.y()) * topRightSlope);
- Q16Dot16 rightIntersectBf = qSafeFloatToQ16Dot16(right.x() - 0.5f + (iRight + 1.5f - right.y()) * bottomRightSlope);
+ QScFixed leftIntersectAf = qSafeFloatToQScFixed(top.x() + 0.5f + (iTop + 0.5f - top.y()) * topLeftSlope);
+ QScFixed leftIntersectBf = qSafeFloatToQScFixed(left.x() + 0.5f + (iLeft + 1.5f - left.y()) * bottomLeftSlope);
+ QScFixed rightIntersectAf = qSafeFloatToQScFixed(top.x() - 0.5f + (iTop + 0.5f - top.y()) * topRightSlope);
+ QScFixed rightIntersectBf = qSafeFloatToQScFixed(right.x() - 0.5f + (iRight + 1.5f - right.y()) * bottomRightSlope);
int ny;
int y = iTop;
@@ -1162,8 +1171,8 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
if (next > d->clipRect.bottom()) \
next = d->clipRect.bottom(); \
for (; y <= next; ++y) { \
- const int x1 = qMax(Q16Dot16ToInt(li), d->clipRect.left()); \
- const int x2 = qMin(Q16Dot16ToInt(ri), d->clipRect.right()); \
+ const int x1 = qMax(QScFixedToInt(li), d->clipRect.left()); \
+ const int x2 = qMin(QScFixedToInt(ri), d->clipRect.right()); \
if (x2 >= x1) \
buffer.addSpan(x1, x2 - x1 + 1, y, 255); \
li += ls; \