4#ifndef QPATHCLIPPER_P_H
5#define QPATHCLIPPER_P_H
18#include <QtGui/private/qtguiglobal_p.h>
19#include <QtGui/qpainterpath.h>
20#include <QtCore/qlist.h>
22#include <private/qbezier_p.h>
23#include <private/qdatabuffer_p.h>
41 QPathClipper(
const QPainterPath &subject,
42 const QPainterPath &clip);
44 QPainterPath clip(Operation op = BoolAnd);
49 static bool pathToRect(
const QPainterPath &path, QRectF *rect =
nullptr);
50 static QPainterPath intersect(
const QPainterPath &path,
const QRectF &rect);
53 Q_DISABLE_COPY_MOVE(QPathClipper)
60 bool handleCrossingEdges(QWingedEdge &list, qreal y, ClipperMode mode);
61 bool doClip(QWingedEdge &list, ClipperMode mode);
63 QPainterPath subjectPath;
64 QPainterPath clipPath;
74 QPathVertex(
const QPointF &p = QPointF(),
int e = -1);
102 explicit QPathEdge(
int a = -1,
int b = -1);
124 int m_next[2][2] = { { -1, -1 }, { -1, -1 } };
167 void setPath(
const QPainterPath &path);
168 void addPath(
const QPainterPath &path);
177 int pathId(
int index)
const;
188 QDataBuffer<QPointF> m_points;
189 QDataBuffer<Segment> m_segments;
190 QDataBuffer<Intersection> m_intersections;
200 struct TraversalStatus
203 QPathEdge::Traversal traversal;
204 QPathEdge::Direction direction;
206 void flipDirection();
207 void flipTraversal();
213 QWingedEdge(
const QPainterPath &subject,
const QPainterPath &clip);
216 QPainterPath toPath()
const;
218 int edgeCount()
const;
220 QPathEdge *edge(
int edge);
221 const QPathEdge *edge(
int edge)
const;
223 int vertexCount()
const;
225 int addVertex(
const QPointF &p);
227 QPathVertex *vertex(
int vertex);
228 const QPathVertex *vertex(
int vertex)
const;
230 TraversalStatus next(
const TraversalStatus &status)
const;
232 int addEdge(
const QPointF &a,
const QPointF &b);
233 int addEdge(
int vertexA,
int vertexB);
235 bool isInside(qreal x, qreal y)
const;
237 static QPathEdge::Traversal flip(QPathEdge::Traversal traversal);
238 static QPathEdge::Direction flip(QPathEdge::Direction direction);
241 void intersectAndAdd();
243 void printNode(
int i, FILE *handle);
245 void removeEdge(
int ei);
247 int insert(
const QPathVertex &vertex);
248 TraversalStatus findInsertStatus(
int vertex,
int edge)
const;
250 qreal delta(
int vertex,
int a,
int b)
const;
252 QDataBuffer<QPathEdge> m_edges;
253 QDataBuffer<QPathVertex> m_vertices;
255 QList<qreal> m_splitPoints;
257 QPathSegments m_segments;
273 return m_next[
int(traversal)][
int(direction)];
278 m_next[
int(traversal)][
int(direction)] = next;
283 m_next[0][
int(direction)] = next;
284 m_next[1][
int(direction)] = next;
304inline QPathVertex::operator QPointF()
const
306 return QPointF(x, y);
319 return m_segments.size();
324 return m_points.size();
329 return m_points.at(i);
335 return m_points.size() - 1;
340 return m_segments.at(index);
345 const Segment &segment = m_segments.at(index);
346 return QLineF(m_points.at(segment.va), m_points.at(segment.vb));
351 return m_segments.at(index).bounds;
356 return m_segments.at(index).path;
361 const int intersection = m_segments.at(index).intersection;
362 if (intersection < 0)
365 return &m_intersections.at(intersection);
370 return m_intersections.size();
375 m_intersections << intersection;
377 Segment &segment = m_segments.at(index);
379 segment.intersection = m_intersections.size() - 1;
381 Intersection *isect = &m_intersections.at(segment.intersection);
386 isect->next = (m_intersections.size() - 1) - (isect - m_intersections.data());
390inline int QWingedEdge::edgeCount()
const
392 return m_edges.size();
395inline QPathEdge *QWingedEdge::edge(
int edge)
397 return edge < 0 ?
nullptr : &m_edges.at(edge);
400inline const QPathEdge *QWingedEdge::edge(
int edge)
const
402 return edge < 0 ?
nullptr : &m_edges.at(edge);
405inline int QWingedEdge::vertexCount()
const
407 return m_vertices.size();
410inline int QWingedEdge::addVertex(
const QPointF &p)
413 return m_vertices.size() - 1;
416inline QPathVertex *QWingedEdge::vertex(
int vertex)
418 return vertex < 0 ?
nullptr : &m_vertices.at(vertex);
421inline const QPathVertex *QWingedEdge::vertex(
int vertex)
const
423 return vertex < 0 ?
nullptr : &m_vertices.at(vertex);
426inline QPathEdge::Traversal QWingedEdge::flip(QPathEdge::Traversal traversal)
428 return traversal == QPathEdge::RightTraversal ? QPathEdge::LeftTraversal : QPathEdge::RightTraversal;
431inline void QWingedEdge::TraversalStatus::flipTraversal()
433 traversal = QWingedEdge::flip(traversal);
436inline QPathEdge::Direction QWingedEdge::flip(QPathEdge::Direction direction)
438 return direction == QPathEdge::Forward ? QPathEdge::Backward : QPathEdge::Forward;
441inline void QWingedEdge::TraversalStatus::flipDirection()
443 direction = QWingedEdge::flip(direction);
446inline 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
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)