6#include <private/qbezier_p.h>
7#include <private/qdatabuffer_p.h>
8#include <private/qnumeric_p.h>
34 if (
sizeof(
qreal) ==
sizeof(
double))
37 return qAbs(
d) <= 1e-5f;
49 return a.x() *
b.x() +
a.y() *
b.y();
54 double reciprocal = 1 /
qSqrt(
x *
x +
y *
y);
78bool QIntersectionFinder::linesIntersect(
const QLineF &
a,
const QLineF &
b)
const
92 if (p1_equals_q1 && p2_equals_q2)
98 if (p1_equals_q2 && p2_equals_q1)
102 const QPointF qDelta = q2 - q1;
104 const qreal par = pDelta.
x() * qDelta.
y() - pDelta.
y() * qDelta.
x();
107 const QPointF normal(-pDelta.
y(), pDelta.
x());
111 const qreal dp =
dot(pDelta, pDelta);
116 if ((tq1 > 0 && tq1 < dp) || (tq2 > 0 && tq2 < dp))
119 const qreal dq =
dot(qDelta, qDelta);
124 if ((tp1 > 0 && tp1 < dq) || (tp2 > 0 && tp2 < dq))
131 const qreal invPar = 1 / par;
133 const qreal tp = (qDelta.
y() * (q1.x() -
p1.x()) -
134 qDelta.
x() * (q1.y() -
p1.y())) * invPar;
136 if (tp < 0 || tp > 1)
139 const qreal tq = (pDelta.
y() * (q1.x() -
p1.x()) -
140 pDelta.
x() * (q1.y() -
p1.y())) * invPar;
142 return tq >= 0 && tq <= 1;
147 if (
a.segments() == 0 ||
b.segments() == 0)
150 const QRectF &rb0 =
b.elementBounds(0);
157 for (
int i = 1;
i <
b.segments(); ++
i) {
159 minX =
qMin(minX,
r.left());
167 for (
int i = 0;
i <
a.segments(); ++
i) {
175 for (
int j = 0;
j <
b.segments(); ++
j) {
183 if (linesIntersect(
a.lineAt(
i),
b.lineAt(
j)))
199 int lowestRightIndex;
226 void produceIntersections(
int segment);
229 TreeNode buildTree(
int first,
int last,
int depth,
const RectF &bounds);
231 void produceIntersectionsLeaf(
const TreeNode &node,
int segment);
232 void produceIntersections(
const TreeNode &node,
int segment,
const RectF &segmentBounds,
const RectF &nodeBounds,
int axis);
253 m_index.resize(m_segments.segments());
255 for (
int i = 0;
i < m_index.size(); ++
i) {
258 const QRectF &segmentBounds = m_segments.elementBounds(
i);
260 if (segmentBounds.
left() < m_bounds.x1)
261 m_bounds.x1 = segmentBounds.
left();
262 if (segmentBounds.
top() < m_bounds.y1)
263 m_bounds.y1 = segmentBounds.
top();
264 if (segmentBounds.
right() > m_bounds.x2)
265 m_bounds.x2 = segmentBounds.
right();
266 if (segmentBounds.
bottom() > m_bounds.y2)
267 m_bounds.y2 = segmentBounds.
bottom();
272 TreeNode root = buildTree(0, m_index.size(), 0, m_bounds);
278 return axis == 0 ?
pos.x() :
pos.y();
281TreeNode SegmentTree::buildTree(
int first,
int last,
int depth,
const RectF &bounds)
286 node.index.interval.first =
first;
287 node.index.interval.last = last;
292 int splitAxis = (
depth & 1);
297 qreal split = 0.5f * ((&bounds.x1)[splitAxis] + (&bounds.x2)[splitAxis]);
299 node.splitLeft = (&bounds.x1)[splitAxis];
300 node.splitRight = (&bounds.x2)[splitAxis];
302 node.lowestLeftIndex = INT_MAX;
303 node.lowestRightIndex = INT_MAX;
305 const int treeSize = m_tree.size();
307 node.index.children.left = treeSize;
308 node.index.children.right = treeSize + 1;
310 m_tree.resize(treeSize + 2);
317 const int index = m_index.at(l);
318 const QRectF &segmentBounds = m_segments.elementBounds(
index);
320 qreal lowCoordinate = coordinate(segmentBounds.
topLeft(), splitAxis);
322 if (coordinate(segmentBounds.
center(), splitAxis) <
split) {
324 if (highCoordinate > node.splitLeft)
325 node.splitLeft = highCoordinate;
326 if (
index < node.lowestLeftIndex)
327 node.lowestLeftIndex =
index;
330 if (lowCoordinate < node.splitRight)
331 node.splitRight = lowCoordinate;
332 if (
index < node.lowestRightIndex)
333 node.lowestRightIndex =
index;
334 qSwap(m_index[l], m_index[
r]);
339 RectF lbounds = bounds;
340 (&lbounds.x2)[splitAxis] = node.splitLeft;
342 RectF rbounds = bounds;
343 (&rbounds.x1)[splitAxis] = node.splitRight;
346 m_tree[node.index.children.left] =
left;
348 TreeNode
right = buildTree(l, last,
depth + 1, rbounds);
349 m_tree[node.index.children.right] =
right;
368 if (p1_equals_q1 && p2_equals_q2)
374 if (p1_equals_q2 && p2_equals_q1)
378 const QPointF qDelta = q2 - q1;
380 const qreal par = pDelta.
x() * qDelta.
y() - pDelta.
y() * qDelta.
x();
383 const QPointF normal(-pDelta.
y(), pDelta.
x());
387 const qreal invDp = 1 /
dot(pDelta, pDelta);
389 const qreal tq1 =
dot(pDelta, q1 -
p1) * invDp;
390 const qreal tq2 =
dot(pDelta, q2 -
p1) * invDp;
392 if (tq1 > 0 && tq1 < 1) {
394 intersection.
alphaA = tq1;
396 intersection.
pos = q1;
397 intersections.
add(intersection);
400 if (tq2 > 0 && tq2 < 1) {
402 intersection.
alphaA = tq2;
404 intersection.
pos = q2;
405 intersections.
add(intersection);
408 const qreal invDq = 1 /
dot(qDelta, qDelta);
410 const qreal tp1 =
dot(qDelta,
p1 - q1) * invDq;
411 const qreal tp2 =
dot(qDelta,
p2 - q1) * invDq;
413 if (tp1 > 0 && tp1 < 1) {
416 intersection.
alphaB = tp1;
417 intersection.
pos =
p1;
418 intersections.
add(intersection);
421 if (tp2 > 0 && tp2 < 1) {
424 intersection.
alphaB = tp2;
425 intersection.
pos =
p2;
426 intersections.
add(intersection);
435 if (p1_equals_q1 || p1_equals_q2 || p2_equals_q1 || p2_equals_q2)
439 const qreal tp = (qDelta.
y() * (q1.x() -
p1.x()) -
440 qDelta.
x() * (q1.y() -
p1.y())) / par;
441 const qreal tq = (pDelta.
y() * (q1.x() -
p1.x()) -
442 pDelta.
x() * (q1.y() -
p1.y())) / par;
444 if (tp<0 || tp>1 || tq<0 || tq>1)
453 if ((q_zero || q_one) && (p_zero || p_one))
466 pt = q1 + (q2 - q1) * tq;
472 intersection.
pos = pt;
473 intersections.
add(intersection);
476void SegmentTree::produceIntersections(
int segment)
478 const QRectF &segmentBounds = m_segments.elementBounds(
segment);
481 sbounds.x1 = segmentBounds.
left();
482 sbounds.y1 = segmentBounds.
top();
483 sbounds.x2 = segmentBounds.
right();
484 sbounds.y2 = segmentBounds.
bottom();
486 produceIntersections(m_tree.at(0),
segment, sbounds, m_bounds, 0);
489void SegmentTree::produceIntersectionsLeaf(
const TreeNode &node,
int segment)
494 for (
int i = node.index.interval.first;
i < node.index.interval.last; ++
i) {
495 const int other = m_index.at(
i);
506 m_intersections.reset();
510 intersectLines(lineA, lineB, m_intersections);
512 for (
int k = 0; k < m_intersections.size(); ++k) {
514 i_isect.
t = m_intersections.at(k).alphaA;
515 j_isect.
t = m_intersections.at(k).alphaB;
517 i_isect.
vertex = j_isect.
vertex = m_segments.addPoint(m_intersections.at(k).pos);
522 m_segments.addIntersection(
segment, i_isect);
523 m_segments.addIntersection(
other, j_isect);
528void SegmentTree::produceIntersections(
const TreeNode &node,
int segment,
const RectF &segmentBounds,
const RectF &nodeBounds,
int axis)
531 produceIntersectionsLeaf(node,
segment);
535 RectF lbounds = nodeBounds;
536 (&lbounds.x2)[axis] = node.splitLeft;
538 RectF rbounds = nodeBounds;
539 (&rbounds.x1)[axis] = node.splitRight;
541 if (
segment > node.lowestLeftIndex && (&segmentBounds.x1)[axis] <= node.splitLeft)
542 produceIntersections(m_tree.at(node.index.children.left),
segment, segmentBounds, lbounds, !axis);
544 if (
segment > node.lowestRightIndex && (&segmentBounds.x2)[axis] >= node.splitRight)
545 produceIntersections(m_tree.at(node.index.children.right),
segment, segmentBounds, rbounds, !axis);
555 tree.produceIntersections(
i);
578 , m_nodes(m_segments->
points())
581 m_nodes.resize(m_segments->
points());
583 for (
int i = 0;
i < m_nodes.size(); ++
i) {
584 m_nodes.at(
i).point =
i;
585 m_nodes.at(
i).id = -1;
588 m_rootNode =
build(0, m_nodes.size());
595 return &m_nodes.at(m_rootNode);
619 if (traverseLeft && node.
left)
622 if (traverseRight && node.
right)
642 while (
first <= last) {
658 m_nodes.at(last).left =
nullptr;
661 m_nodes.at(last).right = &m_nodes.at(
build(last + 1,
end,
depth + 1));
663 m_nodes.at(last).right =
nullptr;
676 pointComponents[0] =
segments.pointAt(point).x();
677 pointComponents[1] =
segments.pointAt(point).y();
687 const qreal pivotComponents[] = { nodePoint.
x(), nodePoint.
y() };
689 const qreal pivot = pivotComponents[
depth & 1];
693 const qreal pivot2 = pivotComponents[(
depth + 1) & 1];
704 }
else if (
value < pivot) {
717 qreal pointComponents[2];
739 mergedPoints << m_points.
at(
i);
741 pointIndices << finder.
result();
744 for (
int i = 0;
i < m_segments.size(); ++
i) {
745 m_segments.at(
i).va = pointIndices.
at(m_segments.at(
i).va);
746 m_segments.at(
i).vb = pointIndices.
at(m_segments.at(
i).vb);
749 for (
int i = 0;
i < m_intersections.
size(); ++
i)
752 m_points.
swap(mergedPoints);
756void QWingedEdge::intersectAndAdd()
763 for (
int i = 0;
i < m_segments.
points(); ++
i)
768 intersections.
reset();
770 int pathId = m_segments.
pathId(
i);
774 intersections << *isect;
777 isect += isect->
next;
783 std::sort(intersections.
data(), intersections.
data() + intersections.
size());
789 for (
int j = 0;
j < intersections.
size(); ++
j) {
825 m_edges(subject.elementCount()),
826 m_vertices(subject.elementCount()),
827 m_segments(subject.elementCount())
861 if (equal_1_2 && equal_2_3 && equal_3_4)
865 return equal_1_2 || equal_3_4;
867 return (equal_1_2 && equal_3_4) || (equal_1_2 && equal_2_3) || (equal_2_3 && equal_3_4);
873 m_intersections.
reset();
883 int firstSegment = m_segments.size();
885 bool hasMoveTo =
false;
888 for (
int i = 0;
i <
path.elementCount(); ++
i) {
889 int current = m_points.
size();
893 currentPoint =
path.elementAt(
i+2);
895 currentPoint =
path.elementAt(
i);
898 current = lastMoveTo;
900 m_points << currentPoint;
902 switch (
path.elementAt(
i).type) {
904 if (hasMoveTo && last != lastMoveTo && !
comparePoints(m_points.
at(last), m_points.
at(lastMoveTo)))
905 m_segments <<
Segment(m_pathId, last, lastMoveTo);
907 last = lastMoveTo = current;
910 m_segments <<
Segment(m_pathId, last, current);
917 m_segments <<
Segment(m_pathId, last, current);
924 if (threshold < 3) threshold = 3;
925 qreal one_over_threshold_minus_1 =
qreal(1) / (threshold - 1);
927 for (
int t = 1;
t < threshold - 1; ++
t) {
928 currentPoint = bezier.
pointAt(
t * one_over_threshold_minus_1);
934 m_points << currentPoint;
937 m_segments <<
Segment(m_pathId, last, current);
949 if (hasMoveTo && last != lastMoveTo && !
comparePoints(m_points.
at(last), m_points.
at(lastMoveTo)))
950 m_segments <<
Segment(m_pathId, last, lastMoveTo);
952 for (
int i = firstSegment;
i < m_segments.size(); ++
i) {
971qreal QWingedEdge::delta(
int vertex,
int a,
int b)
const
976 double a_angle = ap->
angle;
977 double b_angle = bp->
angle;
985 double result = b_angle - a_angle;
1006 TraversalStatus status;
1009 status.edge = vp->
edge;
1011#ifdef QDEBUG_CLIPPER
1013 qDebug() <<
"Finding insert status for edge" << ei <<
"at vertex" <<
QPointF(*vp) <<
", angles: " << ep->
angle << ep->
invAngle;
1017 status =
next(status);
1021 qreal d2 = delta(vi, ei, status.edge);
1023#ifdef QDEBUG_CLIPPER
1032 }
while (status.edge != vp->
edge);
1038 if (
edge(status.edge)->
vertex(status.direction) != vi)
1041#ifdef QDEBUG_CLIPPER
1050void QWingedEdge::removeEdge(
int ei)
1054 TraversalStatus status;
1059 TraversalStatus forwardRight =
next(status);
1060 forwardRight.flipDirection();
1063 TraversalStatus forwardLeft =
next(status);
1064 forwardLeft.flipDirection();
1067 TraversalStatus backwardLeft =
next(status);
1068 backwardLeft.flipDirection();
1071 TraversalStatus backwardRight =
next(status);
1072 backwardRight.flipDirection();
1074 edge(forwardRight.edge)->
setNext(forwardRight.traversal, forwardRight.direction, forwardLeft.edge);
1075 edge(forwardLeft.edge)->
setNext(forwardLeft.traversal, forwardLeft.direction, forwardRight.edge);
1077 edge(backwardRight.edge)->
setNext(backwardRight.traversal, backwardRight.direction, backwardLeft.edge);
1078 edge(backwardLeft.edge)->
setNext(backwardLeft.traversal, backwardLeft.direction, backwardRight.edge);
1086 a->edge = backwardRight.edge;
1087 b->edge = forwardRight.edge;
1113 status =
list.next(status);
1124 return v.y() <= 0 ? 0 : 64.;
1125 }
else if (
v.y() == 0) {
1126 return v.x() <= 0 ? 32. : 96.;
1136 return 128. - 32. * vx;
1139 return 64. + 32. * vx;
1166 int ei = m_edges.
size() - 1;
1182#ifdef QDEBUG_CLIPPER
1183 printf(
"** Adding edge %d / vertices: %.07f %.07f, %.07f %.07f\n", ei,
fp->x,
fp->y,
sp->x,
sp->y);
1186 for (
int i = 0;
i < 2; ++
i) {
1237 return m_vertices.
size() - 1;
1239 for (
int i = 0;
i < m_vertices.
size(); ++
i) {
1248 return m_vertices.
size() - 1;
1253 const int elementCount =
path.elementCount();
1254 if (elementCount >= 2) {
1264 path.setElementPositionAt(elementCount - 1, point.
x(), point.
y());
1292 status =
list.next(status);
1293 }
while (status.
edge != edge);
1302 int flag = 0x3 << 4;
1303 if ((ep->
flag & flag) == flag) {
1318 if (ep->
flag & 16) {
1331 if (subjectPath == clipPath)
1342 bool subjectIsRect =
pathToRect(subjectPath);
1345 if (subjectIsRect && clipIsRect)
1347 else if (subjectIsRect)
1349 else if (clipIsRect)
1353 a.setPath(subjectPath);
1355 b.setPath(clipPath);
1382 if (subjectPath == clipPath)
1398 a.setPath(subjectPath);
1400 b.setPath(clipPath);
1419 : subjectPath(subject)
1439 status =
list.next(status);
1440 }
while (status.
edge != edge);
1443template <
typename InputIterator>
1458 if (
path.elementCount() != 5)
1461 const bool mightBeRect =
path.elementAt(0).isMoveTo()
1462 &&
path.elementAt(1).isLineTo()
1463 &&
path.elementAt(2).isLineTo()
1464 &&
path.elementAt(3).isLineTo()
1465 &&
path.elementAt(4).isLineTo();
1476 if (
path.elementAt(1).y !=
y1)
1479 if (
path.elementAt(2).x !=
x2)
1482 if (
path.elementAt(3).x !=
x1 ||
path.elementAt(3).y !=
y2)
1485 if (
path.elementAt(4).x !=
x1 ||
path.elementAt(4).y !=
y1)
1500 if (subjectPath == clipPath)
1503 bool subjectIsRect =
pathToRect(subjectPath,
nullptr);
1504 bool clipIsRect =
pathToRect(clipPath,
nullptr);
1521 result.addPath(clipPath);
1532 if (clipBounds.
contains(subjectBounds)) {
1545 }
else if (subjectBounds.
contains(clipBounds)) {
1546 if (subjectIsRect) {
1570 return intersect(clipPath, subjectBounds);
1571 else if (clipIsRect)
1572 return intersect(subjectPath, clipBounds);
1578 doClip(
list, ClipMode);
1588 for (
int i = 0;
i <
list.vertexCount(); ++
i)
1589 y_coords <<
list.vertex(
i)->y;
1591 std::sort(y_coords.
begin(), y_coords.
end());
1594#ifdef QDEBUG_CLIPPER
1595 printf(
"sorted y coords:\n");
1596 for (
int i = 0;
i < y_coords.
size(); ++
i) {
1597 printf(
"%.9f\n", y_coords.
at(
i));
1605 qreal maxHeight = 0;
1606 for (
int i = 0;
i <
list.edgeCount(); ++
i) {
1610 if ((edge->
flag & 0x3) == 0x3)
1622 if (
height > maxHeight) {
1642 int bestIdx =
first;
1643 for (
int i =
first + 1;
i < last; ++
i) {
1646 if (gap > biggestGap) {
1651 const qreal bestY = 0.5 * (y_coords.
at(bestIdx) + y_coords.
at(bestIdx + 1));
1653#ifdef QDEBUG_CLIPPER
1654 printf(
"y: %.9f, gap: %.9f\n", bestY, biggestGap);
1657 if (handleCrossingEdges(
list, bestY,
mode) &&
mode == CheckMode)
1664 if (
mode == ClipMode)
1682 ep->
flag |= (flag | (flag << 4));
1684#ifdef QDEBUG_CLIPPER
1685 qDebug() <<
"traverse: adding edge " << status.
edge <<
", mask:" << (flag << 4) <<ep->
flag;
1688 status =
list.next(status);
1689 }
while (status.
edge != edge);
1727 int w = ((ep->
flag >> 4) ^ (ep->
flag >> 5)) & 1;
1735 if ((
a.y() <
y &&
b.y() >
y) || (
a.y() >
y &&
b.y() <
y)) {
1736 qreal intersectionX =
a.x() + (
b.x() -
a.x()) * (
y -
a.y()) / (
b.y() -
a.y());
1738 if (intersectionX >
x)
1749 for (
int i = 0;
i <
list.edgeCount(); ++
i) {
1754 if ((
a.y() <
y &&
b.y() >
y) || (
a.y() >
y &&
b.y() <
y)) {
1755 const qreal intersection =
a.x() + (
b.x() -
a.x()) * (
y -
a.y()) / (
b.y() -
a.y());
1768 std::sort(crossings.
begin(), crossings.
end());
1775#ifdef QDEBUG_CLIPPER
1776 qDebug() <<
"crossings:" << crossings.
size();
1778 for (
int i = 0;
i < crossings.
size() - 1; ++
i) {
1779 int ei = crossings.
at(
i).edge;
1785 const bool hasLeft = (edge->
flag >> 4) & 1;
1786 const bool hasRight = (edge->
flag >> 4) & 2;
1788 windingD += hasLeft ^ hasRight;
1790 const bool inA = (windingA & aMask) != 0;
1791 const bool inB = (windingB & bMask) != 0;
1792 const bool inD = (windingD & 0x1) != 0;
1794 const bool inside =
bool_op(inA, inB, op);
1795 const bool add = inD ^ inside;
1797#ifdef QDEBUG_CLIPPER
1798 printf(
"y %f, x %f, inA: %d, inB: %d, inD: %d, inside: %d, flag: %x, bezier: %p, edge: %d\n",
y, crossings.
at(
i).x, inA, inB, inD, inside, edge->
flag, edge->bezier, ei);
1802 if (
mode == CheckMode)
1809 if (!(edge->
flag & 1))
1812 if (!(edge->
flag & 2))
1815 if (!(edge->
flag & 1))
1818 if (!(edge->
flag & 2))
1824 if (!(edge->
flag & 1))
1827 if (!(edge->
flag & 2))
1845 for (
int i = 0;
i <
path.elementCount(); ++
i) {
1850 subpaths += current;
1863 Q_ASSERT(!
"toSubpaths(), bad element type");
1869 subpaths << current;
1879static bool isVertical(Edge edge)
1907 return line.pointAt((
t -
a.x()) / (
b.x() -
a.x()));
1909 return line.pointAt((
t -
a.y()) / (
b.y() -
a.y()));
1915 if (
path.elementCount() > 0)
1926 bool outA = compare<edge>(
a,
t);
1927 bool outB = compare<edge>(
b,
t);
1941 if (
path.elementCount() > 0)
1954 bool outA = compare<edge>(
a,
t);
1955 bool outB = compare<edge>(
b,
t);
1956 bool outC = compare<edge>(
c,
t);
1957 bool outD = compare<edge>(
d,
t);
1959 int outCount = int(outA) + int(outB) + int(outC) + int(outD);
1964 if (outCount == 0) {
1965 addBezier(
result, bezier);
1982 if (stationary > 0) {
1987 if (stationary > 1) {
1996 qreal lastIntersection = 0;
1998 outA = compare<edge>(
points[
i],
t);
1999 outB = compare<edge>(
points[
i+1],
t);
2007 lastIntersection = intersection;
2020 for (
int i = 1;
i <
path.elementCount(); ++
i) {
2031 int last =
path.elementCount() - 1;
2044 for (
int i = 0;
i < subpaths.
size(); ++
i) {
2053 bounds =
subPath.boundingRect();
2055 if (bounds.
top() <
rect.top())
2060 if (
subPath.elementCount() > 1)
2066 if (
result.boundingRect().isEmpty())
qreal tForY(qreal t0, qreal t1, qreal y) const
static QBezier fromPoints(const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &p4)
QPointF pointAt(qreal t) const
int stationaryYPoints(qreal &t0, qreal &t1) const
QBezier mapBy(const QTransform &transform) const
QBezier getSubRange(qreal t0, qreal t1) const
void swap(QDataBuffer< Type > &other)
bool hasIntersections(const QPathSegments &a, const QPathSegments &b) const
void produceIntersections(QPathSegments &segments)
QKdPointFinder(int point, const QPathSegments &segments, QKdPointTree &tree)
QKdPointTree::Traversal operator()(QKdPointTree::Node &node, int depth)
QKdPointTree(const QPathSegments &segments)
int build(int begin, int end, int depth=0)
qsizetype size() const noexcept
bool isEmpty() const noexcept
iterator erase(const_iterator begin, const_iterator end)
const_reference at(qsizetype i) const noexcept
void reserve(qsizetype size)
const_iterator cend() const noexcept
const_iterator cbegin() const noexcept
bool isMoveTo() const
Returns true if the element is moving the current position, otherwise returns false.
bool isLineTo() const
Returns true if the element is a line, otherwise returns false.
void addRect(const QRectF &rect)
Adds the given rectangle to this path as a closed subpath.
void moveTo(const QPointF &p)
Moves the current point to the given point, implicitly starting a new subpath and closing the previou...
QPainterPath::Element elementAt(int i) const
Returns the element at the given index in the painter path.
int elementCount() const
Returns the number of path elements in the painter path.
QPainterPath simplified() const
void addPath(const QPainterPath &path)
Adds the given path to this path as a closed subpath.
QRectF controlPointRect() const
Returns the rectangle containing all the points and control points in this path.
bool intersects(const QRectF &rect) const
Returns true if any point in the given rectangle intersects the path; otherwise returns false.
QRectF boundingRect() const
Returns the bounding rectangle of this painter path as a rectangle with floating point precision.
bool contains(const QPointF &pt) const
Returns true if the given point is inside the path, otherwise returns false.
Qt::FillRule fillRule() const
Returns the painter path's currently set fill rule.
void lineTo(const QPointF &p)
Adds a straight line from the current position to the given endPoint.
void cubicTo(const QPointF &ctrlPt1, const QPointF &ctrlPt2, const QPointF &endPt)
Adds a cubic Bezier curve between the current position and the given endPoint using the control point...
QPathClipper(const QPainterPath &subject, const QPainterPath &clip)
static bool pathToRect(const QPainterPath &path, QRectF *rect=nullptr)
QPainterPath clip(Operation op=BoolAnd)
void setNext(Traversal traversal, Direction direction, int next)
Direction directionTo(int vertex) const
int next(Traversal traversal, Direction direction) const
int vertex(Direction direction) const
const Segment & segmentAt(int index) const
const Intersection * intersectionAt(int index) const
void setPath(const QPainterPath &path)
void addPath(const QPainterPath &path)
int pathId(int index) const
const QLineF lineAt(int index) const
const QPointF & pointAt(int vertex) const
\inmodule QtCore\reentrant
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
\inmodule QtCore\reentrant
constexpr qreal bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
constexpr qreal height() const noexcept
Returns the height of the rectangle.
constexpr qreal width() const noexcept
Returns the width of the rectangle.
bool contains(const QRectF &r) const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
constexpr qreal left() const noexcept
Returns the x-coordinate of the rectangle's left edge.
bool intersects(const QRectF &r) const noexcept
Returns true if this rectangle intersects with the given rectangle (i.e.
constexpr QPointF topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
constexpr QPointF center() const noexcept
Returns the center point of the rectangle.
constexpr QPointF bottomRight() const noexcept
Returns the position of the rectangle's bottom-right corner.
constexpr qreal top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
constexpr qreal right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
constexpr int height() const noexcept
Returns the height of the rectangle.
constexpr int bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
constexpr int top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
bool contains(const QRect &r, bool proper=false) const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
constexpr int left() const noexcept
Returns the x-coordinate of the rectangle's left edge.
constexpr int x() const noexcept
Returns the x-coordinate of the rectangle's left edge.
constexpr int width() const noexcept
Returns the width of the rectangle.
constexpr int y() const noexcept
Returns the y-coordinate of the rectangle's top edge.
constexpr int right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
int addEdge(const QPointF &a, const QPointF &b)
bool isInside(qreal x, qreal y) const
TraversalStatus next(const TraversalStatus &status) const
QPathEdge * edge(int edge)
QPainterPath toPath() const
int addVertex(const QPointF &p)
QPathVertex * vertex(int vertex)
Combined button and popup list for selecting options.
void flip(QMatrix4x4 &matrix)
static const QPainterPath::ElementType * subPath(const QPainterPath::ElementType *t, const QPainterPath::ElementType *end, const qreal *points, bool *closed)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
bool qFuzzyIsNull(qfloat16 f) noexcept
qfloat16 qSqrt(qfloat16 f)
void uint64_t uint64_t uint64_t value2
static QT_BEGIN_NAMESPACE const qreal Q_PI
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qMax(const T &a, const T &b)
constexpr T qAbs(const T &t)
constexpr static Q_DECL_CONST_FUNCTION double qt_inf() noexcept
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]
GLint GLenum GLsizei GLsizei GLsizei depth
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLfloat GLfloat GLfloat GLfloat GLfloat maxY
GLboolean GLboolean GLboolean GLboolean a
[7]
GLint GLenum GLint components
GLuint GLfloat GLfloat GLfloat GLfloat y1
GLuint GLfloat GLfloat GLfloat x1
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
[4]
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t0
GLuint GLfloat GLfloat y0
GLfloat GLfloat GLfloat GLfloat maxX
GLfixed GLfixed GLint GLint GLfixed points
GLfixed GLfixed GLfixed y2
GLsizei const GLchar *const * path
static bool clipLine(QLineF *line, const QRect &rect)
static qreal dot(const QPointF &a, const QPointF &b)
static QList< QCrossingEdge > findCrossings(const QWingedEdge &list, qreal y)
static bool bool_op(bool a, bool b, QPathClipper::Operation op)
static void normalize(double &x, double &y)
static QT_BEGIN_NAMESPACE bool fuzzyIsNull(qreal d)
static bool fuzzyCompare(qreal a, qreal b)
static bool comparePoints(const QPointF &a, const QPointF &b)
static void add(QPainterPath &path, const QWingedEdge &list, int edge, QPathEdge::Traversal traversal)
void qTraverseKdPointTree(QKdPointTree::Node &node, T &t, int depth=0)
static qreal component(const QPointF &point, unsigned int i)
static void addLineTo(QPainterPath &path, const QPointF &point)
static int commonEdge(const QWingedEdge &list, int a, int b)
static bool isLine(const QBezier &bezier)
InputIterator qFuzzyFind(InputIterator first, InputIterator last, qreal val)
static double computeAngle(const QPointF &v)
static void traverse(QWingedEdge &list, int edge, QPathEdge::Traversal traversal)
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
static int segmentCount(const QPainterPath &path, qreal pathLength)
static void split(QT_FT_Vector *b)
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
static int compare(quint64 a, quint64 b)
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
QT_END_NAMESPACE typedef QT_PREPEND_NAMESPACE(quintptr) WId
QFileInfo fi("c:/temp/foo")
[newstuff]
bool operator<(const QCrossingEdge &edge) const
QPathEdge::Traversal traversal
QPathEdge::Direction direction