Qt 4.8
Public Functions | Properties | List of all members
QRasterizer Class Reference

#include <qrasterizer_p.h>

Public Functions

void initialize (ProcessSpans blend, void *data)
 
 QRasterizer ()
 
void rasterize (const QT_FT_Outline *outline, Qt::FillRule fillRule)
 
void rasterize (const QPainterPath &path, Qt::FillRule fillRule)
 
void rasterizeLine (const QPointF &a, const QPointF &b, qreal width, bool squareCap=false)
 
void setAntialiased (bool antialiased)
 
void setClipRect (const QRect &clipRect)
 
 ~QRasterizer ()
 

Properties

QRasterizerPrivated
 

Detailed Description

Definition at line 68 of file qrasterizer_p.h.

Constructors and Destructors

◆ QRasterizer()

QRasterizer::QRasterizer ( )

Definition at line 635 of file qrasterizer.cpp.

636  : d(new QRasterizerPrivate)
637 {
638 }
QRasterizerPrivate * d
Definition: qrasterizer_p.h:90

◆ ~QRasterizer()

QRasterizer::~QRasterizer ( )

Definition at line 640 of file qrasterizer.cpp.

641 {
642  delete d;
643 }
QRasterizerPrivate * d
Definition: qrasterizer_p.h:90

Functions

◆ initialize()

void QRasterizer::initialize ( ProcessSpans  blend,
void *  data 
)

Definition at line 650 of file qrasterizer.cpp.

651 {
652  d->blend = blend;
653  d->data = data;
654 }
static const char * data(const QByteArray &arr)
ProcessSpans blend
QRasterizerPrivate * d
Definition: qrasterizer_p.h:90

◆ rasterize() [1/2]

void QRasterizer::rasterize ( const QT_FT_Outline outline,
Qt::FillRule  fillRule 
)

Definition at line 1189 of file qrasterizer.cpp.

Referenced by QRasterPaintEngine::fillPath().

1190 {
1191  if (outline->n_points < 3 || outline->n_contours == 0)
1192  return;
1193 
1194  const QT_FT_Vector *points = outline->points;
1195 
1196  QSpanBuffer buffer(d->blend, d->data, d->clipRect);
1197 
1198  // ### QT_FT_Outline already has a bounding rect which is
1199  // ### precomputed at this point, so we should probably just be
1200  // ### using that instead...
1201  QT_FT_Pos min_y = points[0].y, max_y = points[0].y;
1202  for (int i = 1; i < outline->n_points; ++i) {
1203  const QT_FT_Vector &p = points[i];
1204  min_y = qMin(p.y, min_y);
1205  max_y = qMax(p.y, max_y);
1206  }
1207 
1208  int iTopBound = qMax(d->clipRect.top(), int((min_y + 32 + COORD_OFFSET - COORD_ROUNDING) >> 6));
1209  int iBottomBound = qMin(d->clipRect.bottom(), int((max_y - 32 + COORD_OFFSET - COORD_ROUNDING) >> 6));
1210 
1211  if (iTopBound > iBottomBound)
1212  return;
1213 
1214  d->scanConverter.begin(iTopBound, iBottomBound, d->clipRect.left(), d->clipRect.right(), fillRule, &buffer);
1215 
1216  int first = 0;
1217  for (int i = 0; i < outline->n_contours; ++i) {
1218  const int last = outline->contours[i];
1219  for (int j = first; j < last; ++j) {
1220  if (outline->tags[j+1] == QT_FT_CURVE_TAG_CUBIC) {
1221  Q_ASSERT(outline->tags[j+2] == QT_FT_CURVE_TAG_CUBIC);
1222  d->scanConverter.mergeCurve(points[j], points[j+1], points[j+2], points[j+3]);
1223  j += 2;
1224  } else {
1225  d->scanConverter.mergeLine(points[j], points[j+1]);
1226  }
1227  }
1228 
1229  first = last + 1;
1230  }
1231 
1232  d->scanConverter.end();
1233 }
void begin(int top, int bottom, int left, int right, Qt::FillRule fillRule, QSpanBuffer *spanBuffer)
#define QT_FT_CURVE_TAG_CUBIC
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
void mergeCurve(const QT_FT_Vector &a, const QT_FT_Vector &b, const QT_FT_Vector &c, const QT_FT_Vector &d)
QScanConverter scanConverter
#define COORD_OFFSET
Definition: qrasterizer.cpp:66
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
QT_FT_Vector * points
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
void mergeLine(QT_FT_Vector a, QT_FT_Vector b)
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246
ProcessSpans blend
QT_FT_BEGIN_HEADER typedef signed int QT_FT_Pos
#define COORD_ROUNDING
Definition: qrasterizer.cpp:65
QRasterizerPrivate * d
Definition: qrasterizer_p.h:90

◆ rasterize() [2/2]

void QRasterizer::rasterize ( const QPainterPath path,
Qt::FillRule  fillRule 
)

Definition at line 1235 of file qrasterizer.cpp.

1236 {
1237  if (path.isEmpty())
1238  return;
1239 
1240  QSpanBuffer buffer(d->blend, d->data, d->clipRect);
1241 
1242  QRectF bounds = path.controlPointRect();
1243 
1244  int iTopBound = qMax(d->clipRect.top(), int(bounds.top() + qreal(0.5) + (COORD_OFFSET - COORD_ROUNDING)/qreal(64.)));
1245  int iBottomBound = qMin(d->clipRect.bottom(), int(bounds.bottom() - qreal(0.5) + (COORD_OFFSET - COORD_ROUNDING)/qreal(64.)));
1246 
1247  if (iTopBound > iBottomBound)
1248  return;
1249 
1250  d->scanConverter.begin(iTopBound, iBottomBound, d->clipRect.left(), d->clipRect.right(), fillRule, &buffer);
1251 
1252  int subpathStart = 0;
1253  QT_FT_Vector last = { 0, 0 };
1254  for (int i = 0; i < path.elementCount(); ++i) {
1255  switch (path.elementAt(i).type) {
1257  {
1258  QT_FT_Vector p1 = last;
1259  QT_FT_Vector p2 = PointToVector(path.elementAt(i));
1260  d->scanConverter.mergeLine(p1, p2);
1261  last = p2;
1262  break;
1263  }
1265  {
1266  if (i != 0) {
1267  QT_FT_Vector first = PointToVector(path.elementAt(subpathStart));
1268  // close previous subpath
1269  if (first.x != last.x || first.y != last.y)
1270  d->scanConverter.mergeLine(last, first);
1271  }
1272  subpathStart = i;
1273  last = PointToVector(path.elementAt(i));
1274  break;
1275  }
1277  {
1278  QT_FT_Vector p1 = last;
1279  QT_FT_Vector p2 = PointToVector(path.elementAt(i));
1280  QT_FT_Vector p3 = PointToVector(path.elementAt(++i));
1281  QT_FT_Vector p4 = PointToVector(path.elementAt(++i));
1282  d->scanConverter.mergeCurve(p1, p2, p3, p4);
1283  last = p4;
1284  break;
1285  }
1286  default:
1287  Q_ASSERT(false);
1288  break;
1289  }
1290  }
1291 
1292  QT_FT_Vector first = PointToVector(path.elementAt(subpathStart));
1293 
1294  // close path
1295  if (first.x != last.x || first.y != last.y)
1296  d->scanConverter.mergeLine(last, first);
1297 
1298  d->scanConverter.end();
1299 }
ElementType type
the type of element
Definition: qpainterpath.h:81
void begin(int top, int bottom, int left, int right, Qt::FillRule fillRule, QSpanBuffer *spanBuffer)
bool isEmpty() const
Returns true if either there are no elements in this path, or if the only element is a MoveToElement;...
Definition: qpainterpath.h:392
double qreal
Definition: qglobal.h:1193
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
void mergeCurve(const QT_FT_Vector &a, const QT_FT_Vector &b, const QT_FT_Vector &c, const QT_FT_Vector &d)
QScanConverter scanConverter
#define COORD_OFFSET
Definition: qrasterizer.cpp:66
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
const QPainterPath::Element & elementAt(int i) const
Returns the element at the given index in the painter path.
Definition: qpainterpath.h:402
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
static QT_FT_Vector PointToVector(const QPointF &p)
Definition: qrasterizer.cpp:68
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
void mergeLine(QT_FT_Vector a, QT_FT_Vector b)
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246
QRectF controlPointRect() const
Returns the rectangle containing all the points and control points in this path.
ProcessSpans blend
qreal top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:526
int elementCount() const
Returns the number of path elements in the painter path.
Definition: qpainterpath.h:397
qreal bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:528
#define COORD_ROUNDING
Definition: qrasterizer.cpp:65
QRasterizerPrivate * d
Definition: qrasterizer_p.h:90

◆ rasterizeLine()

void QRasterizer::rasterizeLine ( const QPointF a,
const QPointF b,
qreal  width,
bool  squareCap = false 
)

Definition at line 752 of file qrasterizer.cpp.

Referenced by QRasterPaintEngine::drawImage(), QRasterPaintEngine::drawRects(), QRasterPaintEngine::drawTiledPixmap(), QRasterPaintEngine::fill(), QRasterPaintEngine::fillRect(), and QRasterPaintEngine::stroke().

753 {
754  if (a == b || width == 0 || d->clipRect.isEmpty())
755  return;
756 
757  Q_ASSERT(width > 0.0);
758 
759  QPointF pa = a;
760  QPointF pb = b;
761 
762  if (squareCap) {
763  QPointF delta = pb - pa;
764  pa -= (0.5f * width) * delta;
765  pb += (0.5f * width) * delta;
766  }
767 
768  QPointF offs = QPointF(qAbs(b.y() - a.y()), qAbs(b.x() - a.x())) * width * 0.5;
769  const QRectF clip(d->clipRect.topLeft() - offs, d->clipRect.bottomRight() + QPoint(1, 1) + offs);
770 
771  if (!clip.contains(pa) || !clip.contains(pb)) {
772  qreal t1 = 0;
773  qreal t2 = 1;
774 
775  const qreal o[2] = { pa.x(), pa.y() };
776  const qreal d[2] = { pb.x() - pa.x(), pb.y() - pa.y() };
777 
778  const qreal low[2] = { clip.left(), clip.top() };
779  const qreal high[2] = { clip.right(), clip.bottom() };
780 
781  for (int i = 0; i < 2; ++i) {
782  if (d[i] == 0) {
783  if (o[i] <= low[i] || o[i] >= high[i])
784  return;
785  continue;
786  }
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;
790  if (t_low > t_high)
791  qSwap(t_low, t_high);
792  if (t1 < t_low)
793  t1 = t_low;
794  if (t2 > t_high)
795  t2 = t_high;
796  if (t1 >= t2)
797  return;
798  }
799 
800  QPointF npa = pa + (pb - pa) * t1;
801  QPointF npb = pa + (pb - pa) * t2;
802 
803  pa = npa;
804  pb = npb;
805  }
806 
807  if (!d->antialiased) {
808  pa.rx() += (COORD_OFFSET - COORD_ROUNDING)/64.;
809  pa.ry() += (COORD_OFFSET - COORD_ROUNDING)/64.;
810  pb.rx() += (COORD_OFFSET - COORD_ROUNDING)/64.;
811  pb.ry() += (COORD_OFFSET - COORD_ROUNDING)/64.;
812  }
813 
814  {
815  // old delta
816  const QPointF d0 = a - b;
817  const qreal w0 = d0.x() * d0.x() + d0.y() * d0.y();
818 
819  // new delta
820  const QPointF d = pa - pb;
821  const qreal w = d.x() * d.x() + d.y() * d.y();
822 
823  if (w == 0)
824  return;
825 
826  // adjust width which is given relative to |b - a|
827  width *= sqrt(w0 / w);
828  }
829 
830  QSpanBuffer buffer(d->blend, d->data, d->clipRect);
831 
832  if (q26Dot6Compare(pa.y(), pb.y())) {
833  const qreal x = (pa.x() + pb.x()) * 0.5f;
834  const qreal dx = qAbs(pb.x() - pa.x()) * 0.5f;
835 
836  const qreal y = pa.y();
837  const qreal dy = width * dx;
838 
839  pa = QPointF(x, y - dy);
840  pb = QPointF(x, y + dy);
841 
842  width = 1 / width;
843  }
844 
845  if (q26Dot6Compare(pa.x(), pb.x())) {
846  if (pa.y() > pb.y())
847  qSwap(pa, pb);
848 
849  const qreal dy = pb.y() - pa.y();
850  const qreal halfWidth = 0.5f * width * dy;
851 
852  qreal left = pa.x() - halfWidth;
853  qreal right = pa.x() + halfWidth;
854 
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));
857 
858  pa.ry() = qBound(qreal(d->clipRect.top()), pa.y(), qreal(d->clipRect.bottom() + 1));
859  pb.ry() = qBound(qreal(d->clipRect.top()), pb.y(), qreal(d->clipRect.bottom() + 1));
860 
861  if (q26Dot6Compare(left, right) || q26Dot6Compare(pa.y(), pb.y()))
862  return;
863 
864  if (d->antialiased) {
865  const Q16Dot16 iLeft = int(left);
866  const Q16Dot16 iRight = int(right);
867  const Q16Dot16 leftWidth = IntToQ16Dot16(iLeft + 1)
868  - FloatToQ16Dot16(left);
869  const Q16Dot16 rightWidth = FloatToQ16Dot16(right)
870  - IntToQ16Dot16(iRight);
871 
872  Q16Dot16 coverage[3];
873  int x[3];
874  int len[3];
875 
876  int n = 1;
877  if (iLeft == iRight) {
878  coverage[0] = (leftWidth + rightWidth) * 255;
879  x[0] = iLeft;
880  len[0] = 1;
881  } else {
882  coverage[0] = leftWidth * 255;
883  x[0] = iLeft;
884  len[0] = 1;
885  if (leftWidth == Q16Dot16Factor) {
886  len[0] = iRight - iLeft;
887  } else if (iRight - iLeft > 1) {
888  coverage[1] = IntToQ16Dot16(255);
889  x[1] = iLeft + 1;
890  len[1] = iRight - iLeft - 1;
891  ++n;
892  }
893  if (rightWidth) {
894  coverage[n] = rightWidth * 255;
895  x[n] = iRight;
896  len[n] = 1;
897  ++n;
898  }
899  }
900 
901  const Q16Dot16 iTopFP = IntToQ16Dot16(int(pa.y()));
902  const Q16Dot16 iBottomFP = IntToQ16Dot16(int(pb.y()));
903  const Q16Dot16 yPa = FloatToQ16Dot16(pa.y());
904  const Q16Dot16 yPb = FloatToQ16Dot16(pb.y());
905  for (Q16Dot16 yFP = iTopFP; yFP <= iBottomFP; yFP += Q16Dot16Factor) {
906  const Q16Dot16 rowHeight = qMin(yFP + Q16Dot16Factor, yPb)
907  - qMax(yFP, yPa);
908  const int y = Q16Dot16ToInt(yFP);
909  if (y > d->clipRect.bottom())
910  break;
911  for (int i = 0; i < n; ++i) {
912  buffer.addSpan(x[i], len[i], y,
913  Q16Dot16ToInt(Q16Dot16Multiply(rowHeight, coverage[i])));
914  }
915  }
916  } else { // aliased
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);
921 
922  int iWidth = iRight - iLeft + 1;
923  for (int y = iTop; y <= iBottom; ++y)
924  buffer.addSpan(iLeft, iWidth, y, 255);
925  }
926  } else {
927  if (pa.y() > pb.y())
928  qSwap(pa, pb);
929 
930  QPointF delta = pb - pa;
931  delta *= 0.5f * width;
932  const QPointF perp(delta.y(), -delta.x());
933 
934  QPointF top;
935  QPointF left;
936  QPointF right;
937  QPointF bottom;
938 
939  if (pa.x() < pb.x()) {
940  top = pa + perp;
941  left = pa - perp;
942  right = pb + perp;
943  bottom = pb - perp;
944  } else {
945  top = pa - perp;
946  left = pb - perp;
947  right = pa + perp;
948  bottom = pb + perp;
949  }
950 
951  top = snapTo26Dot6Grid(top);
952  bottom = snapTo26Dot6Grid(bottom);
953  left = snapTo26Dot6Grid(left);
954  right = snapTo26Dot6Grid(right);
955 
956  const qreal topBound = qBound(qreal(d->clipRect.top()), top.y(), qreal(d->clipRect.bottom()));
957  const qreal bottomBound = qBound(qreal(d->clipRect.top()), bottom.y(), qreal(d->clipRect.bottom()));
958 
959  const QPointF topLeftEdge = left - top;
960  const QPointF topRightEdge = right - top;
961  const QPointF bottomLeftEdge = bottom - left;
962  const QPointF bottomRightEdge = bottom - right;
963 
964  const qreal topLeftSlope = qSafeDivide(topLeftEdge.x(), topLeftEdge.y());
965  const qreal bottomLeftSlope = qSafeDivide(bottomLeftEdge.x(), bottomLeftEdge.y());
966 
967  const qreal topRightSlope = qSafeDivide(topRightEdge.x(), topRightEdge.y());
968  const qreal bottomRightSlope = qSafeDivide(bottomRightEdge.x(), bottomRightEdge.y());
969 
970  const Q16Dot16 topLeftSlopeFP = qSafeFloatToQ16Dot16(topLeftSlope);
971  const Q16Dot16 topRightSlopeFP = qSafeFloatToQ16Dot16(topRightSlope);
972 
973  const Q16Dot16 bottomLeftSlopeFP = qSafeFloatToQ16Dot16(bottomLeftSlope);
974  const Q16Dot16 bottomRightSlopeFP = qSafeFloatToQ16Dot16(bottomRightSlope);
975 
976  const Q16Dot16 invTopLeftSlopeFP = qSafeFloatToQ16Dot16(qSafeDivide(1, topLeftSlope));
977  const Q16Dot16 invTopRightSlopeFP = qSafeFloatToQ16Dot16(qSafeDivide(1, topRightSlope));
978 
979  const Q16Dot16 invBottomLeftSlopeFP = qSafeFloatToQ16Dot16(qSafeDivide(1, bottomLeftSlope));
980  const Q16Dot16 invBottomRightSlopeFP = qSafeFloatToQ16Dot16(qSafeDivide(1, bottomRightSlope));
981 
982  if (d->antialiased) {
983  const Q16Dot16 iTopFP = IntToQ16Dot16(int(topBound));
984  const Q16Dot16 iLeftFP = IntToQ16Dot16(int(left.y()));
985  const Q16Dot16 iRightFP = IntToQ16Dot16(int(right.y()));
986  const Q16Dot16 iBottomFP = IntToQ16Dot16(int(bottomBound));
987 
988  Q16Dot16 leftIntersectAf = FloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * topLeftSlope);
989  Q16Dot16 rightIntersectAf = FloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * topRightSlope);
990  Q16Dot16 leftIntersectBf = 0;
991  Q16Dot16 rightIntersectBf = 0;
992 
993  if (iLeftFP < iTopFP)
994  leftIntersectBf = FloatToQ16Dot16(left.x() + (int(topBound) - left.y()) * bottomLeftSlope);
995 
996  if (iRightFP < iTopFP)
997  rightIntersectBf = FloatToQ16Dot16(right.x() + (int(topBound) - right.y()) * bottomRightSlope);
998 
999  Q16Dot16 rowTop, rowBottomLeft, rowBottomRight, rowTopLeft, rowTopRight, rowBottom;
1000  Q16Dot16 topLeftIntersectAf, topLeftIntersectBf, topRightIntersectAf, topRightIntersectBf;
1001  Q16Dot16 bottomLeftIntersectAf, bottomLeftIntersectBf, bottomRightIntersectAf, bottomRightIntersectBf;
1002 
1003  int leftMin, leftMax, rightMin, rightMax;
1004 
1005  const Q16Dot16 yTopFP = FloatToQ16Dot16(top.y());
1006  const Q16Dot16 yLeftFP = FloatToQ16Dot16(left.y());
1007  const Q16Dot16 yRightFP = FloatToQ16Dot16(right.y());
1008  const Q16Dot16 yBottomFP = FloatToQ16Dot16(bottom.y());
1009 
1010  rowTop = qMax(iTopFP, yTopFP);
1011  topLeftIntersectAf = leftIntersectAf +
1012  Q16Dot16Multiply(topLeftSlopeFP, rowTop - iTopFP);
1013  topRightIntersectAf = rightIntersectAf +
1014  Q16Dot16Multiply(topRightSlopeFP, rowTop - iTopFP);
1015 
1016  Q16Dot16 yFP = iTopFP;
1017  while (yFP <= iBottomFP) {
1018  rowBottomLeft = qMin(yFP + Q16Dot16Factor, yLeftFP);
1019  rowBottomRight = qMin(yFP + Q16Dot16Factor, yRightFP);
1020  rowTopLeft = qMax(yFP, yLeftFP);
1021  rowTopRight = qMax(yFP, yRightFP);
1022  rowBottom = qMin(yFP + Q16Dot16Factor, yBottomFP);
1023 
1024  if (yFP == iLeftFP) {
1025  const int y = Q16Dot16ToInt(yFP);
1026  leftIntersectBf = FloatToQ16Dot16(left.x() + (y - left.y()) * bottomLeftSlope);
1027  topLeftIntersectBf = leftIntersectBf + Q16Dot16Multiply(bottomLeftSlopeFP, rowTopLeft - yFP);
1028  bottomLeftIntersectAf = leftIntersectAf + Q16Dot16Multiply(topLeftSlopeFP, rowBottomLeft - yFP);
1029  } else {
1030  topLeftIntersectBf = leftIntersectBf;
1031  bottomLeftIntersectAf = leftIntersectAf + topLeftSlopeFP;
1032  }
1033 
1034  if (yFP == iRightFP) {
1035  const int y = Q16Dot16ToInt(yFP);
1036  rightIntersectBf = FloatToQ16Dot16(right.x() + (y - right.y()) * bottomRightSlope);
1037  topRightIntersectBf = rightIntersectBf + Q16Dot16Multiply(bottomRightSlopeFP, rowTopRight - yFP);
1038  bottomRightIntersectAf = rightIntersectAf + Q16Dot16Multiply(topRightSlopeFP, rowBottomRight - yFP);
1039  } else {
1040  topRightIntersectBf = rightIntersectBf;
1041  bottomRightIntersectAf = rightIntersectAf + topRightSlopeFP;
1042  }
1043 
1044  if (yFP == iBottomFP) {
1045  bottomLeftIntersectBf = leftIntersectBf + Q16Dot16Multiply(bottomLeftSlopeFP, rowBottom - yFP);
1046  bottomRightIntersectBf = rightIntersectBf + Q16Dot16Multiply(bottomRightSlopeFP, rowBottom - yFP);
1047  } else {
1048  bottomLeftIntersectBf = leftIntersectBf + bottomLeftSlopeFP;
1049  bottomRightIntersectBf = rightIntersectBf + bottomRightSlopeFP;
1050  }
1051 
1052  if (yFP < iLeftFP) {
1053  leftMin = Q16Dot16ToInt(bottomLeftIntersectAf);
1054  leftMax = Q16Dot16ToInt(topLeftIntersectAf);
1055  } else if (yFP == iLeftFP) {
1056  leftMin = Q16Dot16ToInt(qMax(bottomLeftIntersectAf, topLeftIntersectBf));
1057  leftMax = Q16Dot16ToInt(qMax(topLeftIntersectAf, bottomLeftIntersectBf));
1058  } else {
1059  leftMin = Q16Dot16ToInt(topLeftIntersectBf);
1060  leftMax = Q16Dot16ToInt(bottomLeftIntersectBf);
1061  }
1062 
1063  leftMin = qBound(d->clipRect.left(), leftMin, d->clipRect.right());
1064  leftMax = qBound(d->clipRect.left(), leftMax, d->clipRect.right());
1065 
1066  if (yFP < iRightFP) {
1067  rightMin = Q16Dot16ToInt(topRightIntersectAf);
1068  rightMax = Q16Dot16ToInt(bottomRightIntersectAf);
1069  } else if (yFP == iRightFP) {
1070  rightMin = Q16Dot16ToInt(qMin(topRightIntersectAf, bottomRightIntersectBf));
1071  rightMax = Q16Dot16ToInt(qMin(bottomRightIntersectAf, topRightIntersectBf));
1072  } else {
1073  rightMin = Q16Dot16ToInt(bottomRightIntersectBf);
1074  rightMax = Q16Dot16ToInt(topRightIntersectBf);
1075  }
1076 
1077  rightMin = qBound(d->clipRect.left(), rightMin, d->clipRect.right());
1078  rightMax = qBound(d->clipRect.left(), rightMax, d->clipRect.right());
1079 
1080  if (leftMax > rightMax)
1081  leftMax = rightMax;
1082  if (rightMin < leftMin)
1083  rightMin = leftMin;
1084 
1085  Q16Dot16 rowHeight = rowBottom - rowTop;
1086 
1087  int x = leftMin;
1088  while (x <= leftMax) {
1089  Q16Dot16 excluded = 0;
1090 
1091  if (yFP <= iLeftFP)
1092  excluded += intersectPixelFP(x, rowTop, rowBottomLeft,
1093  bottomLeftIntersectAf, topLeftIntersectAf,
1094  topLeftSlopeFP, invTopLeftSlopeFP);
1095  if (yFP >= iLeftFP)
1096  excluded += intersectPixelFP(x, rowTopLeft, rowBottom,
1097  topLeftIntersectBf, bottomLeftIntersectBf,
1098  bottomLeftSlopeFP, invBottomLeftSlopeFP);
1099 
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);
1109  }
1110 
1111  Q16Dot16 coverage = rowHeight - excluded;
1112  buffer.addSpan(x, 1, Q16Dot16ToInt(yFP),
1113  Q16Dot16ToInt(255 * coverage));
1114  ++x;
1115  }
1116  if (x < rightMin) {
1117  buffer.addSpan(x, rightMin - x, Q16Dot16ToInt(yFP),
1118  Q16Dot16ToInt(255 * rowHeight));
1119  x = rightMin;
1120  }
1121  while (x <= rightMax) {
1122  Q16Dot16 excluded = 0;
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);
1131 
1132  Q16Dot16 coverage = rowHeight - excluded;
1133  buffer.addSpan(x, 1, Q16Dot16ToInt(yFP),
1134  Q16Dot16ToInt(255 * coverage));
1135  ++x;
1136  }
1137 
1138  leftIntersectAf += topLeftSlopeFP;
1139  leftIntersectBf += bottomLeftSlopeFP;
1140  rightIntersectAf += topRightSlopeFP;
1141  rightIntersectBf += bottomRightSlopeFP;
1142  topLeftIntersectAf = leftIntersectAf;
1143  topRightIntersectAf = rightIntersectAf;
1144 
1145  yFP += Q16Dot16Factor;
1146  rowTop = yFP;
1147  }
1148  } else { // aliased
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);
1154 
1155  Q16Dot16 leftIntersectAf = qSafeFloatToQ16Dot16(top.x() + 0.5f + (iTop + 0.5f - top.y()) * topLeftSlope);
1156  Q16Dot16 leftIntersectBf = qSafeFloatToQ16Dot16(left.x() + 0.5f + (iLeft + 1.5f - left.y()) * bottomLeftSlope);
1157  Q16Dot16 rightIntersectAf = qSafeFloatToQ16Dot16(top.x() - 0.5f + (iTop + 0.5f - top.y()) * topRightSlope);
1158  Q16Dot16 rightIntersectBf = qSafeFloatToQ16Dot16(right.x() - 0.5f + (iRight + 1.5f - right.y()) * bottomRightSlope);
1159 
1160  int ny;
1161  int y = iTop;
1162 #define DO_SEGMENT(next, li, ri, ls, rs) \
1163  ny = qMin(next + 1, d->clipRect.top()); \
1164  if (y < ny) { \
1165  li += ls * (ny - y); \
1166  ri += rs * (ny - y); \
1167  y = ny; \
1168  } \
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()); \
1174  if (x2 >= x1) \
1175  buffer.addSpan(x1, x2 - x1 + 1, y, 255); \
1176  li += ls; \
1177  ri += rs; \
1178  }
1179 
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);
1184 #undef DO_SEGMENT
1185  }
1186  }
1187 }
double qreal
Definition: qglobal.h:1193
#define DO_SEGMENT(next, li, ri, ls, rs)
#define Q16Dot16Factor
Definition: qrasterizer.cpp:58
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
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.
Definition: qpoint.h:214
#define COORD_OFFSET
Definition: qrasterizer.cpp:66
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)
Definition: qglobal.h:1201
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
Q_CORE_EXPORT QTextStream & right(QTextStream &s)
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
qreal x() const
Returns the x-coordinate of this point.
Definition: qpoint.h:282
#define Q16Dot16Multiply(x, y)
Definition: qrasterizer.cpp:60
qreal & rx()
Returns a reference to the x coordinate of this point.
Definition: qpoint.h:302
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
QPoint bottomRight() const
Returns the position of the rectangle&#39;s bottom-right corner.
Definition: qrect.h:291
void qSwap(T &value1, T &value2)
Definition: qglobal.h:2181
#define FloatToQ16Dot16(i)
Definition: qrasterizer.cpp:55
static int perp(bool vertical, const QSize &size)
bool isEmpty() const
Returns true if the rectangle is empty, otherwise returns false.
Definition: qrect.h:234
#define IntToQ16Dot16(i)
Definition: qrasterizer.cpp:56
static QPointF snapTo26Dot6Grid(const QPointF &p)
#define Q16Dot16ToInt(i)
Definition: qrasterizer.cpp:57
int Q16Dot16
Definition: qrasterizer.cpp:53
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
Q_DECL_CONSTEXPR const T & qBound(const T &min, const T &val, const T &max)
Definition: qglobal.h:1219
qreal & ry()
Returns a reference to the y coordinate of this point.
Definition: qpoint.h:307
qreal y() const
Returns the y-coordinate of this point.
Definition: qpoint.h:287
Q_CORE_EXPORT QTextStream & left(QTextStream &s)
#define COORD_ROUNDING
Definition: qrasterizer.cpp:65
QRasterizerPrivate * d
Definition: qrasterizer_p.h:90
QPoint topLeft() const
Returns the position of the rectangle&#39;s top-left corner.
Definition: qrect.h:288

◆ setAntialiased()

void QRasterizer::setAntialiased ( bool  antialiased)

Definition at line 645 of file qrasterizer.cpp.

Referenced by QRasterPaintEngine::drawImage(), and QRasterPaintEngine::drawTiledPixmap().

646 {
647  d->antialiased = antialiased;
648 }
QRasterizerPrivate * d
Definition: qrasterizer_p.h:90

◆ setClipRect()

void QRasterizer::setClipRect ( const QRect clipRect)

Definition at line 656 of file qrasterizer.cpp.

657 {
658  d->clipRect = clipRect;
659 }
QRasterizerPrivate * d
Definition: qrasterizer_p.h:90

Properties

◆ d

QRasterizerPrivate* QRasterizer::d
private

The documentation for this class was generated from the following files: