764 pa -= (0.5f * width) * delta;
765 pb += (0.5f * width) * delta;
771 if (!clip.contains(pa) || !clip.contains(pb)) {
775 const qreal o[2] = { pa.
x(), pa.
y() };
776 const qreal d[2] = { pb.
x() - pa.
x(), pb.
y() - pa.
y() };
778 const qreal low[2] = { clip.left(), clip.top() };
779 const qreal high[2] = { clip.right(), clip.bottom() };
781 for (
int i = 0; i < 2; ++i) {
783 if (o[i] <= low[i] || o[i] >= high[i])
787 const qreal d_inv = 1 / d[i];
788 qreal t_low = (low[i] - o[i]) * d_inv;
789 qreal t_high = (high[i] - o[i]) * d_inv;
791 qSwap(t_low, t_high);
800 QPointF npa = pa + (pb - pa) * t1;
801 QPointF npb = pa + (pb - pa) * t2;
807 if (!d->antialiased) {
817 const qreal w0 = d0.
x() * d0.
x() + d0.
y() * d0.
y();
821 const qreal w = d.
x() * d.
x() + d.
y() * d.
y();
827 width *= sqrt(w0 / w);
830 QSpanBuffer buffer(d->blend, d->data, d->clipRect);
833 const qreal x = (pa.
x() + pb.x()) * 0.5f;
834 const qreal dx =
qAbs(pb.x() - pa.
x()) * 0.5f;
837 const qreal dy = width * dx;
849 const qreal dy = pb.y() - pa.
y();
850 const qreal halfWidth = 0.5f * width * dy;
855 left =
qBound(
qreal(d->clipRect.left()), left,
qreal(d->clipRect.right() + 1));
856 right =
qBound(
qreal(d->clipRect.left()), right,
qreal(d->clipRect.right() + 1));
859 pb.ry() =
qBound(
qreal(d->clipRect.top()), pb.y(),
qreal(d->clipRect.bottom() + 1));
864 if (d->antialiased) {
877 if (iLeft == iRight) {
878 coverage[0] = (leftWidth + rightWidth) * 255;
882 coverage[0] = leftWidth * 255;
886 len[0] = iRight - iLeft;
887 }
else if (iRight - iLeft > 1) {
890 len[1] = iRight - iLeft - 1;
894 coverage[n] = rightWidth * 255;
909 if (y > d->clipRect.bottom())
911 for (
int i = 0; i < n; ++i) {
912 buffer.addSpan(x[i], len[i], y,
917 int iTop = int(pa.
y() + 0.5f);
918 int iBottom = pb.y() < 0.5f ? -1 : int(pb.y() - 0.5f);
919 int iLeft = int(left + 0.5f);
920 int iRight = right < 0.5f ? -1 : int(right - 0.5f);
922 int iWidth = iRight - iLeft + 1;
923 for (
int y = iTop; y <= iBottom; ++y)
924 buffer.addSpan(iLeft, iWidth, y, 255);
931 delta *= 0.5f * width;
939 if (pa.x() < pb.x()) {
959 const QPointF topLeftEdge = left - top;
960 const QPointF topRightEdge = right - top;
982 if (d->antialiased) {
993 if (iLeftFP < iTopFP)
994 leftIntersectBf =
FloatToQ16Dot16(left.x() + (int(topBound) - left.y()) * bottomLeftSlope);
996 if (iRightFP < iTopFP)
997 rightIntersectBf =
FloatToQ16Dot16(right.x() + (int(topBound) - right.y()) * bottomRightSlope);
999 Q16Dot16 rowTop, rowBottomLeft, rowBottomRight, rowTopLeft, rowTopRight, rowBottom;
1000 Q16Dot16 topLeftIntersectAf, topLeftIntersectBf, topRightIntersectAf, topRightIntersectBf;
1001 Q16Dot16 bottomLeftIntersectAf, bottomLeftIntersectBf, bottomRightIntersectAf, bottomRightIntersectBf;
1003 int leftMin, leftMax, rightMin, rightMax;
1010 rowTop =
qMax(iTopFP, yTopFP);
1011 topLeftIntersectAf = leftIntersectAf +
1013 topRightIntersectAf = rightIntersectAf +
1017 while (yFP <= iBottomFP) {
1020 rowTopLeft =
qMax(yFP, yLeftFP);
1021 rowTopRight =
qMax(yFP, yRightFP);
1024 if (yFP == iLeftFP) {
1026 leftIntersectBf =
FloatToQ16Dot16(left.x() + (y - left.y()) * bottomLeftSlope);
1027 topLeftIntersectBf = leftIntersectBf +
Q16Dot16Multiply(bottomLeftSlopeFP, rowTopLeft - yFP);
1028 bottomLeftIntersectAf = leftIntersectAf +
Q16Dot16Multiply(topLeftSlopeFP, rowBottomLeft - yFP);
1030 topLeftIntersectBf = leftIntersectBf;
1031 bottomLeftIntersectAf = leftIntersectAf + topLeftSlopeFP;
1034 if (yFP == iRightFP) {
1036 rightIntersectBf =
FloatToQ16Dot16(right.x() + (y - right.y()) * bottomRightSlope);
1037 topRightIntersectBf = rightIntersectBf +
Q16Dot16Multiply(bottomRightSlopeFP, rowTopRight - yFP);
1038 bottomRightIntersectAf = rightIntersectAf +
Q16Dot16Multiply(topRightSlopeFP, rowBottomRight - yFP);
1040 topRightIntersectBf = rightIntersectBf;
1041 bottomRightIntersectAf = rightIntersectAf + topRightSlopeFP;
1044 if (yFP == iBottomFP) {
1045 bottomLeftIntersectBf = leftIntersectBf +
Q16Dot16Multiply(bottomLeftSlopeFP, rowBottom - yFP);
1046 bottomRightIntersectBf = rightIntersectBf +
Q16Dot16Multiply(bottomRightSlopeFP, rowBottom - yFP);
1048 bottomLeftIntersectBf = leftIntersectBf + bottomLeftSlopeFP;
1049 bottomRightIntersectBf = rightIntersectBf + bottomRightSlopeFP;
1052 if (yFP < iLeftFP) {
1055 }
else if (yFP == iLeftFP) {
1063 leftMin =
qBound(d->clipRect.left(), leftMin, d->clipRect.right());
1064 leftMax =
qBound(d->clipRect.left(), leftMax, d->clipRect.right());
1066 if (yFP < iRightFP) {
1069 }
else if (yFP == iRightFP) {
1077 rightMin =
qBound(d->clipRect.left(), rightMin, d->clipRect.right());
1078 rightMax =
qBound(d->clipRect.left(), rightMax, d->clipRect.right());
1080 if (leftMax > rightMax)
1082 if (rightMin < leftMin)
1085 Q16Dot16 rowHeight = rowBottom - rowTop;
1088 while (x <= leftMax) {
1093 bottomLeftIntersectAf, topLeftIntersectAf,
1094 topLeftSlopeFP, invTopLeftSlopeFP);
1097 topLeftIntersectBf, bottomLeftIntersectBf,
1098 bottomLeftSlopeFP, invBottomLeftSlopeFP);
1100 if (x >= rightMin) {
1101 if (yFP <= iRightFP)
1102 excluded += (rowBottomRight - rowTop) -
intersectPixelFP(x, rowTop, rowBottomRight,
1103 topRightIntersectAf, bottomRightIntersectAf,
1104 topRightSlopeFP, invTopRightSlopeFP);
1105 if (yFP >= iRightFP)
1106 excluded += (rowBottom - rowTopRight) -
intersectPixelFP(x, rowTopRight, rowBottom,
1107 bottomRightIntersectBf, topRightIntersectBf,
1108 bottomRightSlopeFP, invBottomRightSlopeFP);
1111 Q16Dot16 coverage = rowHeight - excluded;
1121 while (x <= rightMax) {
1123 if (yFP <= iRightFP)
1124 excluded += (rowBottomRight - rowTop) -
intersectPixelFP(x, rowTop, rowBottomRight,
1125 topRightIntersectAf, bottomRightIntersectAf,
1126 topRightSlopeFP, invTopRightSlopeFP);
1127 if (yFP >= iRightFP)
1128 excluded += (rowBottom - rowTopRight) -
intersectPixelFP(x, rowTopRight, rowBottom,
1129 bottomRightIntersectBf, topRightIntersectBf,
1130 bottomRightSlopeFP, invBottomRightSlopeFP);
1132 Q16Dot16 coverage = rowHeight - excluded;
1138 leftIntersectAf += topLeftSlopeFP;
1139 leftIntersectBf += bottomLeftSlopeFP;
1140 rightIntersectAf += topRightSlopeFP;
1141 rightIntersectBf += bottomRightSlopeFP;
1142 topLeftIntersectAf = leftIntersectAf;
1143 topRightIntersectAf = rightIntersectAf;
1149 int iTop = int(top.y() + 0.5f);
1150 int iLeft = left.y() < 0.5f ? -1 : int(left.y() - 0.5f);
1151 int iRight = right.y() < 0.5f ? -1 : int(right.y() - 0.5f);
1152 int iBottom = bottom.
y() < 0.5f? -1 : int(bottom.
y() - 0.5f);
1153 int iMiddle =
qMin(iLeft, iRight);
1162 #define DO_SEGMENT(next, li, ri, ls, rs) \ 1163 ny = qMin(next + 1, d->clipRect.top()); \ 1165 li += ls * (ny - y); \ 1166 ri += rs * (ny - y); \ 1169 if (next > d->clipRect.bottom()) \ 1170 next = d->clipRect.bottom(); \ 1171 for (; y <= next; ++y) { \ 1172 const int x1 = qMax(Q16Dot16ToInt(li), d->clipRect.left()); \ 1173 const int x2 = qMin(Q16Dot16ToInt(ri), d->clipRect.right()); \ 1175 buffer.addSpan(x1, x2 - x1 + 1, y, 255); \ 1180 DO_SEGMENT(iMiddle, leftIntersectAf, rightIntersectAf, topLeftSlopeFP, topRightSlopeFP)
1181 DO_SEGMENT(iRight, leftIntersectBf, rightIntersectAf, bottomLeftSlopeFP, topRightSlopeFP)
1182 DO_SEGMENT(iLeft, leftIntersectAf, rightIntersectBf, topLeftSlopeFP, bottomRightSlopeFP);
1183 DO_SEGMENT(iBottom, leftIntersectBf, rightIntersectBf, bottomLeftSlopeFP, bottomRightSlopeFP);
#define DO_SEGMENT(next, li, ri, ls, rs)
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
static Q16Dot16 intersectPixelFP(int x, Q16Dot16 top, Q16Dot16 bottom, Q16Dot16 leftIntersectX, Q16Dot16 rightIntersectX, Q16Dot16 slope, Q16Dot16 invSlope)
static int qSafeFloatToQ16Dot16(qreal x)
The QPointF class defines a point in the plane using floating point precision.
static qreal qSafeDivide(qreal x, qreal y)
static bool q26Dot6Compare(qreal p1, qreal p2)
long ASN1_INTEGER_get ASN1_INTEGER * a
Q_DECL_CONSTEXPR T qAbs(const T &t)
Q_CORE_EXPORT QTextStream & right(QTextStream &s)
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
qreal x() const
Returns the x-coordinate of this point.
#define Q16Dot16Multiply(x, y)
qreal & rx()
Returns a reference to the x coordinate of this point.
The QRectF class defines a rectangle in the plane using floating point precision. ...
QPoint bottomRight() const
Returns the position of the rectangle's bottom-right corner.
void qSwap(T &value1, T &value2)
#define FloatToQ16Dot16(i)
bool isEmpty() const
Returns true if the rectangle is empty, otherwise returns false.
static QPointF snapTo26Dot6Grid(const QPointF &p)
The QPoint class defines a point in the plane using integer precision.
Q_DECL_CONSTEXPR const T & qBound(const T &min, const T &val, const T &max)
qreal & ry()
Returns a reference to the y coordinate of this point.
qreal y() const
Returns the y-coordinate of this point.
Q_CORE_EXPORT QTextStream & left(QTextStream &s)
QPoint topLeft() const
Returns the position of the rectangle's top-left corner.