5#ifndef QPATHCLIPPER_P_H
6#define QPATHCLIPPER_P_H
19#include <QtGui/private/qtguiglobal_p.h>
20#include <QtGui/qpainterpath.h>
21#include <QtCore/qlist.h>
23#include <private/qbezier_p.h>
24#include <private/qdatabuffer_p.h>
42 QPathClipper(
const QPainterPath &subject,
43 const QPainterPath &clip);
45 QPainterPath clip(Operation op = BoolAnd);
50 static bool pathToRect(
const QPainterPath &path, QRectF *rect =
nullptr);
51 static QPainterPath intersect(
const QPainterPath &path,
const QRectF &rect);
54 Q_DISABLE_COPY_MOVE(QPathClipper)
61 bool handleCrossingEdges(QWingedEdge &list, qreal y, ClipperMode mode);
62 bool doClip(QWingedEdge &list, ClipperMode mode);
64 QPainterPath subjectPath;
65 QPainterPath clipPath;
75 QPathVertex(
const QPointF &p = QPointF(),
int e = -1);
103 explicit QPathEdge(
int a = -1,
int b = -1);
125 int m_next[2][2] = { { -1, -1 }, { -1, -1 } };
168 void setPath(
const QPainterPath &path);
169 void addPath(
const QPainterPath &path);
178 int pathId(
int index)
const;
189 QDataBuffer<QPointF> m_points;
190 QDataBuffer<Segment> m_segments;
191 QDataBuffer<Intersection> m_intersections;
201 struct TraversalStatus
204 QPathEdge::Traversal traversal;
205 QPathEdge::Direction direction;
207 void flipDirection();
208 void flipTraversal();
214 QWingedEdge(
const QPainterPath &subject,
const QPainterPath &clip);
217 QPainterPath toPath()
const;
219 int edgeCount()
const;
221 QPathEdge *edge(
int edge);
222 const QPathEdge *edge(
int edge)
const;
224 int vertexCount()
const;
226 int addVertex(
const QPointF &p);
228 QPathVertex *vertex(
int vertex);
229 const QPathVertex *vertex(
int vertex)
const;
231 TraversalStatus next(
const TraversalStatus &status)
const;
233 int addEdge(
const QPointF &a,
const QPointF &b);
234 int addEdge(
int vertexA,
int vertexB);
236 bool isInside(qreal x, qreal y)
const;
238 static QPathEdge::Traversal flip(QPathEdge::Traversal traversal);
239 static QPathEdge::Direction flip(QPathEdge::Direction direction);
242 void intersectAndAdd();
244 void printNode(
int i, FILE *handle);
246 void removeEdge(
int ei);
248 int insert(
const QPathVertex &vertex);
249 TraversalStatus findInsertStatus(
int vertex,
int edge)
const;
251 qreal delta(
int vertex,
int a,
int b)
const;
253 QDataBuffer<QPathEdge> m_edges;
254 QDataBuffer<QPathVertex> m_vertices;
256 QList<qreal> m_splitPoints;
258 QPathSegments m_segments;
274 return m_next[
int(traversal)][
int(direction)];
279 m_next[
int(traversal)][
int(direction)] = next;
284 m_next[0][
int(direction)] = next;
285 m_next[1][
int(direction)] = next;
305inline QPathVertex::operator QPointF()
const
307 return QPointF(x, y);
320 return m_segments.size();
325 return m_points.size();
330 return m_points.at(i);
336 return m_points.size() - 1;
341 return m_segments.at(index);
346 const Segment &segment = m_segments.at(index);
347 return QLineF(m_points.at(segment.va), m_points.at(segment.vb));
352 return m_segments.at(index).bounds;
357 return m_segments.at(index).path;
362 const int intersection = m_segments.at(index).intersection;
363 if (intersection < 0)
366 return &m_intersections.at(intersection);
371 return m_intersections.size();
376 m_intersections << intersection;
378 Segment &segment = m_segments.at(index);
380 segment.intersection = m_intersections.size() - 1;
382 Intersection *isect = &m_intersections.at(segment.intersection);
387 isect->next = (m_intersections.size() - 1) - (isect - m_intersections.data());
391inline int QWingedEdge::edgeCount()
const
393 return m_edges.size();
396inline QPathEdge *QWingedEdge::edge(
int edge)
398 return edge < 0 ?
nullptr : &m_edges.at(edge);
401inline const QPathEdge *QWingedEdge::edge(
int edge)
const
403 return edge < 0 ?
nullptr : &m_edges.at(edge);
406inline int QWingedEdge::vertexCount()
const
408 return m_vertices.size();
411inline int QWingedEdge::addVertex(
const QPointF &p)
414 return m_vertices.size() - 1;
417inline QPathVertex *QWingedEdge::vertex(
int vertex)
419 return vertex < 0 ?
nullptr : &m_vertices.at(vertex);
422inline const QPathVertex *QWingedEdge::vertex(
int vertex)
const
424 return vertex < 0 ?
nullptr : &m_vertices.at(vertex);
427inline QPathEdge::Traversal QWingedEdge::flip(QPathEdge::Traversal traversal)
429 return traversal == QPathEdge::RightTraversal ? QPathEdge::LeftTraversal : QPathEdge::RightTraversal;
432inline void QWingedEdge::TraversalStatus::flipTraversal()
434 traversal = QWingedEdge::flip(traversal);
437inline QPathEdge::Direction QWingedEdge::flip(QPathEdge::Direction direction)
439 return direction == QPathEdge::Forward ? QPathEdge::Backward : QPathEdge::Forward;
442inline void QWingedEdge::TraversalStatus::flipDirection()
444 direction = QWingedEdge::flip(direction);
447inline void QWingedEdge::TraversalStatus::flip()
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)
QPathEdge(int a=-1, int b=-1)
void setNext(Traversal traversal, Direction direction, int next)
Direction directionTo(int vertex) const
int next(Traversal traversal, Direction direction) const
void setNext(Direction direction, int next)
int vertex(Direction direction) const
int intersections() const
const Segment & segmentAt(int index) const
const Intersection * intersectionAt(int index) const
void setPath(const QPainterPath &path)
void addPath(const QPainterPath &path)
void addIntersection(int index, const Intersection &intersection)
int addPoint(const QPointF &point)
QPathSegments(int reserve)
const QRectF & elementBounds(int index) const
int pathId(int index) const
const QLineF lineAt(int index) const
const QPointF & pointAt(int vertex) const
Combined button and popup list for selecting options.
Q_DECLARE_TYPEINFO(QCrossingEdge, Q_PRIMITIVE_TYPE)
static qreal dot(const QPointF &a, const QPointF &b)
Q_DECLARE_TYPEINFO(QIntersection, Q_PRIMITIVE_TYPE)
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 clear(QWingedEdge &list, int edge, QPathEdge::Traversal traversal)
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)
Q_DECLARE_TYPEINFO(QPathEdge, Q_PRIMITIVE_TYPE)
Q_DECLARE_TYPEINFO(QPathSegments::Segment, Q_PRIMITIVE_TYPE)
Q_DECLARE_TYPEINFO(QPathSegments::Intersection, Q_PRIMITIVE_TYPE)
Q_DECLARE_TYPEINFO(QPathVertex, Q_PRIMITIVE_TYPE)
bool operator<(const QCrossingEdge &edge) const
bool operator<(const Intersection &o) const
Segment(int pathId, int vertexA, int vertexB)
QPathVertex(const QPointF &p=QPointF(), int e=-1)