qpathclipper.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/painting/qpathclipper.cpp
Switch to Source codePreprocessed file
LineSourceCount
1-
2-
3-
4-
5static inline bool fuzzyIsNull(qreal d)-
6{-
7 if (sizeof(qreal) == sizeof(double)
sizeof(qreal) ...sizeof(double)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
8 return
never executed: return qAbs(d) <= 1e-12;
qAbs(d) <= 1e-12;
never executed: return qAbs(d) <= 1e-12;
0
9 else-
10 return
never executed: return qAbs(d) <= 1e-5f;
qAbs(d) <= 1e-5f;
never executed: return qAbs(d) <= 1e-5f;
0
11}-
12-
13static inline bool comparePoints(const QPointF &a, const QPointF &b)-
14{-
15 return
never executed: return fuzzyIsNull(a.x() - b.x()) && fuzzyIsNull(a.y() - b.y());
fuzzyIsNull(a.x() - b.x())
never executed: return fuzzyIsNull(a.x() - b.x()) && fuzzyIsNull(a.y() - b.y());
0
16 && fuzzyIsNull(a.y() - b.y());
never executed: return fuzzyIsNull(a.x() - b.x()) && fuzzyIsNull(a.y() - b.y());
0
17}-
18-
19-
20static qreal dot(const QPointF &a, const QPointF &b)-
21{-
22 return
never executed: return a.x() * b.x() + a.y() * b.y();
a.x() * b.x() + a.y() * b.y();
never executed: return a.x() * b.x() + a.y() * b.y();
0
23}-
24-
25static void normalize(double &x, double &y)-
26{-
27 double reciprocal = 1 / qSqrt(x * x + y * y);-
28 x *= reciprocal;-
29 y *= reciprocal;-
30}
never executed: end of block
0
31-
32struct QIntersection-
33{-
34 qreal alphaA;-
35 qreal alphaB;-
36-
37 QPointF pos;-
38};-
39-
40class QIntersectionFinder-
41{-
42public:-
43 void produceIntersections(QPathSegments &segments);-
44 bool hasIntersections(const QPathSegments &a, const QPathSegments &b) const;-
45-
46private:-
47 bool linesIntersect(const QLineF &a, const QLineF &b) const;-
48};-
49-
50bool QIntersectionFinder::linesIntersect(const QLineF &a, const QLineF &b) const-
51{-
52 const QPointF p1 = a.p1();-
53 const QPointF p2 = a.p2();-
54-
55 const QPointF q1 = b.p1();-
56 const QPointF q2 = b.p2();-
57-
58 if (comparePoints(p1, p2)
comparePoints(p1, p2)Description
TRUEnever evaluated
FALSEnever evaluated
|| comparePoints(q1, q2)
comparePoints(q1, q2)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
59 return
never executed: return false;
false;
never executed: return false;
0
60-
61 const bool p1_equals_q1 = comparePoints(p1, q1);-
62 const bool p2_equals_q2 = comparePoints(p2, q2);-
63-
64 if (p1_equals_q1
p1_equals_q1Description
TRUEnever evaluated
FALSEnever evaluated
&& p2_equals_q2
p2_equals_q2Description
TRUEnever evaluated
FALSEnever evaluated
)
0
65 return
never executed: return true;
true;
never executed: return true;
0
66-
67 const bool p1_equals_q2 = comparePoints(p1, q2);-
68 const bool p2_equals_q1 = comparePoints(p2, q1);-
69-
70 if (p1_equals_q2
p1_equals_q2Description
TRUEnever evaluated
FALSEnever evaluated
&& p2_equals_q1
p2_equals_q1Description
TRUEnever evaluated
FALSEnever evaluated
)
0
71 return
never executed: return true;
true;
never executed: return true;
0
72-
73 const QPointF pDelta = p2 - p1;-
74 const QPointF qDelta = q2 - q1;-
75-
76 const qreal par = pDelta.x() * qDelta.y() - pDelta.y() * qDelta.x();-
77-
78 if (qFuzzyIsNull(par)
qFuzzyIsNull(par)Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
79 const QPointF normal(-pDelta.y(), pDelta.x());-
80-
81-
82 if (qFuzzyIsNull(dot(normal, q1 - p1))
qFuzzyIsNull(d...mal, q1 - p1))Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
83 const qreal dp = dot(pDelta, pDelta);-
84-
85 const qreal tq1 = dot(pDelta, q1 - p1);-
86 const qreal tq2 = dot(pDelta, q2 - p1);-
87-
88 if ((tq1 > 0
tq1 > 0Description
TRUEnever evaluated
FALSEnever evaluated
&& tq1 < dp
tq1 < dpDescription
TRUEnever evaluated
FALSEnever evaluated
) || (tq2 > 0
tq2 > 0Description
TRUEnever evaluated
FALSEnever evaluated
&& tq2 < dp
tq2 < dpDescription
TRUEnever evaluated
FALSEnever evaluated
))
0
89 return
never executed: return true;
true;
never executed: return true;
0
90-
91 const qreal dq = dot(qDelta, qDelta);-
92-
93 const qreal tp1 = dot(qDelta, p1 - q1);-
94 const qreal tp2 = dot(qDelta, p2 - q1);-
95-
96 if ((tp1 > 0
tp1 > 0Description
TRUEnever evaluated
FALSEnever evaluated
&& tp1 < dq
tp1 < dqDescription
TRUEnever evaluated
FALSEnever evaluated
) || (tp2 > 0
tp2 > 0Description
TRUEnever evaluated
FALSEnever evaluated
&& tp2 < dq
tp2 < dqDescription
TRUEnever evaluated
FALSEnever evaluated
))
0
97 return
never executed: return true;
true;
never executed: return true;
0
98 }
never executed: end of block
0
99-
100 return
never executed: return false;
false;
never executed: return false;
0
101 }-
102-
103 const qreal invPar = 1 / par;-
104-
105 const qreal tp = (qDelta.y() * (q1.x() - p1.x()) --
106 qDelta.x() * (q1.y() - p1.y())) * invPar;-
107-
108 if (tp < 0
tp < 0Description
TRUEnever evaluated
FALSEnever evaluated
|| tp > 1
tp > 1Description
TRUEnever evaluated
FALSEnever evaluated
)
0
109 return
never executed: return false;
false;
never executed: return false;
0
110-
111 const qreal tq = (pDelta.y() * (q1.x() - p1.x()) --
112 pDelta.x() * (q1.y() - p1.y())) * invPar;-
113-
114 return
never executed: return tq >= 0 && tq <= 1;
tq >= 0 && tq <= 1;
never executed: return tq >= 0 && tq <= 1;
0
115}-
116-
117bool QIntersectionFinder::hasIntersections(const QPathSegments &a, const QPathSegments &b) const-
118{-
119 if (a.segments() == 0
a.segments() == 0Description
TRUEnever evaluated
FALSEnever evaluated
|| b.segments() == 0
b.segments() == 0Description
TRUEnever evaluated
FALSEnever evaluated
)
0
120 return
never executed: return false;
false;
never executed: return false;
0
121-
122 const QRectF &rb0 = b.elementBounds(0);-
123-
124 qreal minX = rb0.left();-
125 qreal minY = rb0.top();-
126 qreal maxX = rb0.right();-
127 qreal maxY = rb0.bottom();-
128-
129 for (int i = 1; i < b.segments()
i < b.segments()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
130 const QRectF &r = b.elementBounds(i);-
131 minX = qMin(minX, r.left());-
132 minY = qMin(minY, r.top());-
133 maxX = qMax(maxX, r.right());-
134 maxY = qMax(maxY, r.bottom());-
135 }
never executed: end of block
0
136-
137 QRectF rb(minX, minY, maxX - minX, maxY - minY);-
138-
139 for (int i = 0; i < a.segments()
i < a.segments()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
140 const QRectF &r1 = a.elementBounds(i);-
141-
142 if (r1.left() > rb.right()
r1.left() > rb.right()Description
TRUEnever evaluated
FALSEnever evaluated
|| rb.left() > r1.right()
rb.left() > r1.right()Description
TRUEnever evaluated
FALSEnever evaluated
)
0
143 continue;
never executed: continue;
0
144 if (r1.top() > rb.bottom()
r1.top() > rb.bottom()Description
TRUEnever evaluated
FALSEnever evaluated
|| rb.top() > r1.bottom()
rb.top() > r1.bottom()Description
TRUEnever evaluated
FALSEnever evaluated
)
0
145 continue;
never executed: continue;
0
146-
147 for (int j = 0; j < b.segments()
j < b.segments()Description
TRUEnever evaluated
FALSEnever evaluated
; ++j) {
0
148 const QRectF &r2 = b.elementBounds(j);-
149-
150 if (r1.left() > r2.right()
r1.left() > r2.right()Description
TRUEnever evaluated
FALSEnever evaluated
|| r2.left() > r1.right()
r2.left() > r1.right()Description
TRUEnever evaluated
FALSEnever evaluated
)
0
151 continue;
never executed: continue;
0
152 if (r1.top() > r2.bottom()
r1.top() > r2.bottom()Description
TRUEnever evaluated
FALSEnever evaluated
|| r2.top() > r1.bottom()
r2.top() > r1.bottom()Description
TRUEnever evaluated
FALSEnever evaluated
)
0
153 continue;
never executed: continue;
0
154-
155 if (linesIntersect(a.lineAt(i), b.lineAt(j))
linesIntersect..., b.lineAt(j))Description
TRUEnever evaluated
FALSEnever evaluated
)
0
156 return
never executed: return true;
true;
never executed: return true;
0
157 }
never executed: end of block
0
158 }
never executed: end of block
0
159-
160 return
never executed: return false;
false;
never executed: return false;
0
161}-
162-
163namespace {-
164struct TreeNode-
165{-
166 qreal splitLeft;-
167 qreal splitRight;-
168 bool leaf;-
169-
170 int lowestLeftIndex;-
171 int lowestRightIndex;-
172-
173 union {-
174 struct {-
175 int first;-
176 int last;-
177 } interval;-
178 struct {-
179 int left;-
180 int right;-
181 } children;-
182 } index;-
183};-
184-
185struct RectF-
186{-
187 qreal x1;-
188 qreal y1;-
189 qreal x2;-
190 qreal y2;-
191};-
192-
193class SegmentTree-
194{-
195public:-
196 SegmentTree(QPathSegments &segments);-
197-
198 void produceIntersections(int segment);-
199-
200private:-
201 TreeNode buildTree(int first, int last, int depth, const RectF &bounds);-
202-
203 void produceIntersectionsLeaf(const TreeNode &node, int segment);-
204 void produceIntersections(const TreeNode &node, int segment, const RectF &segmentBounds, const RectF &nodeBounds, int axis);-
205 void intersectLines(const QLineF &a, const QLineF &b, QDataBuffer<QIntersection> &intersections);-
206-
207 QPathSegments &m_segments;-
208 QVector<int> m_index;-
209-
210 RectF m_bounds;-
211-
212 QVector<TreeNode> m_tree;-
213 QDataBuffer<QIntersection> m_intersections;-
214};-
215-
216SegmentTree::SegmentTree(QPathSegments &segments)-
217 : m_segments(segments),-
218 m_intersections(0)-
219{-
220 m_bounds.x1 = qt_inf();-
221 m_bounds.y1 = qt_inf();-
222 m_bounds.x2 = -qt_inf();-
223 m_bounds.y2 = -qt_inf();-
224-
225 m_index.resize(m_segments.segments());-
226-
227 for (int i = 0; i < m_index.size()
i < m_index.size()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
228 m_index[i] = i;-
229-
230 const QRectF &segmentBounds = m_segments.elementBounds(i);-
231-
232 if (segmentBounds.left() < m_bounds.x1
segmentBounds.... < m_bounds.x1Description
TRUEnever evaluated
FALSEnever evaluated
)
0
233 m_bounds.x1 = segmentBounds.left();
never executed: m_bounds.x1 = segmentBounds.left();
0
234 if (segmentBounds.top() < m_bounds.y1
segmentBounds.... < m_bounds.y1Description
TRUEnever evaluated
FALSEnever evaluated
)
0
235 m_bounds.y1 = segmentBounds.top();
never executed: m_bounds.y1 = segmentBounds.top();
0
236 if (segmentBounds.right() > m_bounds.x2
segmentBounds.... > m_bounds.x2Description
TRUEnever evaluated
FALSEnever evaluated
)
0
237 m_bounds.x2 = segmentBounds.right();
never executed: m_bounds.x2 = segmentBounds.right();
0
238 if (segmentBounds.bottom() > m_bounds.y2
segmentBounds.... > m_bounds.y2Description
TRUEnever evaluated
FALSEnever evaluated
)
0
239 m_bounds.y2 = segmentBounds.bottom();
never executed: m_bounds.y2 = segmentBounds.bottom();
0
240 }
never executed: end of block
0
241-
242 m_tree.resize(1);-
243-
244 TreeNode root = buildTree(0, m_index.size(), 0, m_bounds);-
245 m_tree[0] = root;-
246}
never executed: end of block
0
247-
248static inline qreal coordinate(const QPointF &pos, int axis)-
249{-
250 return
never executed: return axis == 0 ? pos.x() : pos.y();
axis == 0 ? pos.x() : pos.y();
never executed: return axis == 0 ? pos.x() : pos.y();
0
251}-
252-
253TreeNode SegmentTree::buildTree(int first, int last, int depth, const RectF &bounds)-
254{-
255 if (depth >= 24
depth >= 24Description
TRUEnever evaluated
FALSEnever evaluated
|| (
(last - first) <= 10Description
TRUEnever evaluated
FALSEnever evaluated
last - first) <= 10
(last - first) <= 10Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
256 TreeNode node;-
257 node.leaf = true;-
258 node.index.interval.first = first;-
259 node.index.interval.last = last;-
260-
261 return
never executed: return node;
node;
never executed: return node;
0
262 }-
263-
264 int splitAxis = (depth & 1);-
265-
266 TreeNode node;-
267 node.leaf = false;-
268-
269 qreal split = 0.5f * ((&bounds.x1)[splitAxis] + (&bounds.x2)[splitAxis]);-
270-
271 node.splitLeft = (&bounds.x1)[splitAxis];-
272 node.splitRight = (&bounds.x2)[splitAxis];-
273-
274 node.lowestLeftIndex = 2147483647;-
275 node.lowestRightIndex = 2147483647;-
276-
277 const int treeSize = m_tree.size();-
278-
279 node.index.children.left = treeSize;-
280 node.index.children.right = treeSize + 1;-
281-
282 m_tree.resize(treeSize + 2);-
283-
284 int l = first;-
285 int r = last - 1;-
286-
287-
288 while (l <= r
l <= rDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
289 const int index = m_index.at(l);-
290 const QRectF &segmentBounds = m_segments.elementBounds(index);-
291-
292 qreal lowCoordinate = coordinate(segmentBounds.topLeft(), splitAxis);-
293-
294 if (coordinate(segmentBounds.center(), splitAxis) < split
coordinate(seg...tAxis) < splitDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
295 qreal highCoordinate = coordinate(segmentBounds.bottomRight(), splitAxis);-
296 if (highCoordinate > node.splitLeft
highCoordinate...node.splitLeftDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
297 node.splitLeft = highCoordinate;
never executed: node.splitLeft = highCoordinate;
0
298 if (index < node.lowestLeftIndex
index < node.lowestLeftIndexDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
299 node.lowestLeftIndex = index;
never executed: node.lowestLeftIndex = index;
0
300 ++l;-
301 }
never executed: end of block
else {
0
302 if (lowCoordinate < node.splitRight
lowCoordinate ...ode.splitRightDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
303 node.splitRight = lowCoordinate;
never executed: node.splitRight = lowCoordinate;
0
304 if (index < node.lowestRightIndex
index < node.lowestRightIndexDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
305 node.lowestRightIndex = index;
never executed: node.lowestRightIndex = index;
0
306 qSwap(m_index[l], m_index[r]);-
307 --r;-
308 }
never executed: end of block
0
309 }-
310-
311 RectF lbounds = bounds;-
312 (&lbounds.x2)[splitAxis] = node.splitLeft;-
313-
314 RectF rbounds = bounds;-
315 (&rbounds.x1)[splitAxis] = node.splitRight;-
316-
317 TreeNode left = buildTree(first, l, depth + 1, lbounds);-
318 m_tree[node.index.children.left] = left;-
319-
320 TreeNode right = buildTree(l, last, depth + 1, rbounds);-
321 m_tree[node.index.children.right] = right;-
322-
323 return
never executed: return node;
node;
never executed: return node;
0
324}-
325-
326void SegmentTree::intersectLines(const QLineF &a, const QLineF &b, QDataBuffer<QIntersection> &intersections)-
327{-
328 const QPointF p1 = a.p1();-
329 const QPointF p2 = a.p2();-
330-
331 const QPointF q1 = b.p1();-
332 const QPointF q2 = b.p2();-
333-
334 if (comparePoints(p1, p2)
comparePoints(p1, p2)Description
TRUEnever evaluated
FALSEnever evaluated
|| comparePoints(q1, q2)
comparePoints(q1, q2)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
335 return;
never executed: return;
0
336-
337 const bool p1_equals_q1 = comparePoints(p1, q1);-
338 const bool p2_equals_q2 = comparePoints(p2, q2);-
339-
340 if (p1_equals_q1
p1_equals_q1Description
TRUEnever evaluated
FALSEnever evaluated
&& p2_equals_q2
p2_equals_q2Description
TRUEnever evaluated
FALSEnever evaluated
)
0
341 return;
never executed: return;
0
342-
343 const bool p1_equals_q2 = comparePoints(p1, q2);-
344 const bool p2_equals_q1 = comparePoints(p2, q1);-
345-
346 if (p1_equals_q2
p1_equals_q2Description
TRUEnever evaluated
FALSEnever evaluated
&& p2_equals_q1
p2_equals_q1Description
TRUEnever evaluated
FALSEnever evaluated
)
0
347 return;
never executed: return;
0
348-
349 const QPointF pDelta = p2 - p1;-
350 const QPointF qDelta = q2 - q1;-
351-
352 const qreal par = pDelta.x() * qDelta.y() - pDelta.y() * qDelta.x();-
353-
354 if (qFuzzyIsNull(par)
qFuzzyIsNull(par)Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
355 const QPointF normal(-pDelta.y(), pDelta.x());-
356-
357-
358 if (qFuzzyIsNull(dot(normal, q1 - p1))
qFuzzyIsNull(d...mal, q1 - p1))Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
359 const qreal invDp = 1 / dot(pDelta, pDelta);-
360-
361 const qreal tq1 = dot(pDelta, q1 - p1) * invDp;-
362 const qreal tq2 = dot(pDelta, q2 - p1) * invDp;-
363-
364 if (tq1 > 0
tq1 > 0Description
TRUEnever evaluated
FALSEnever evaluated
&& tq1 < 1
tq1 < 1Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
365 QIntersection intersection;-
366 intersection.alphaA = tq1;-
367 intersection.alphaB = 0;-
368 intersection.pos = q1;-
369 intersections.add(intersection);-
370 }
never executed: end of block
0
371-
372 if (tq2 > 0
tq2 > 0Description
TRUEnever evaluated
FALSEnever evaluated
&& tq2 < 1
tq2 < 1Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
373 QIntersection intersection;-
374 intersection.alphaA = tq2;-
375 intersection.alphaB = 1;-
376 intersection.pos = q2;-
377 intersections.add(intersection);-
378 }
never executed: end of block
0
379-
380 const qreal invDq = 1 / dot(qDelta, qDelta);-
381-
382 const qreal tp1 = dot(qDelta, p1 - q1) * invDq;-
383 const qreal tp2 = dot(qDelta, p2 - q1) * invDq;-
384-
385 if (tp1 > 0
tp1 > 0Description
TRUEnever evaluated
FALSEnever evaluated
&& tp1 < 1
tp1 < 1Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
386 QIntersection intersection;-
387 intersection.alphaA = 0;-
388 intersection.alphaB = tp1;-
389 intersection.pos = p1;-
390 intersections.add(intersection);-
391 }
never executed: end of block
0
392-
393 if (tp2 > 0
tp2 > 0Description
TRUEnever evaluated
FALSEnever evaluated
&& tp2 < 1
tp2 < 1Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
394 QIntersection intersection;-
395 intersection.alphaA = 1;-
396 intersection.alphaB = tp2;-
397 intersection.pos = p2;-
398 intersections.add(intersection);-
399 }
never executed: end of block
0
400 }
never executed: end of block
0
401-
402 return;
never executed: return;
0
403 }-
404-
405-
406-
407 if (p1_equals_q1
p1_equals_q1Description
TRUEnever evaluated
FALSEnever evaluated
|| p1_equals_q2
p1_equals_q2Description
TRUEnever evaluated
FALSEnever evaluated
|| p2_equals_q1
p2_equals_q1Description
TRUEnever evaluated
FALSEnever evaluated
|| p2_equals_q2
p2_equals_q2Description
TRUEnever evaluated
FALSEnever evaluated
)
0
408 return;
never executed: return;
0
409-
410-
411 const qreal tp = (qDelta.y() * (q1.x() - p1.x()) --
412 qDelta.x() * (q1.y() - p1.y())) / par;-
413 const qreal tq = (pDelta.y() * (q1.x() - p1.x()) --
414 pDelta.x() * (q1.y() - p1.y())) / par;-
415-
416 if (tp<0
tp<0Description
TRUEnever evaluated
FALSEnever evaluated
|| tp>1
tp>1Description
TRUEnever evaluated
FALSEnever evaluated
|| tq<0
tq<0Description
TRUEnever evaluated
FALSEnever evaluated
|| tq>1
tq>1Description
TRUEnever evaluated
FALSEnever evaluated
)
0
417 return;
never executed: return;
0
418-
419 const bool p_zero = qFuzzyIsNull(tp);-
420 const bool p_one = qFuzzyIsNull(tp - 1);-
421-
422 const bool q_zero = qFuzzyIsNull(tq);-
423 const bool q_one = qFuzzyIsNull(tq - 1);-
424-
425 if ((q_zero
q_zeroDescription
TRUEnever evaluated
FALSEnever evaluated
|| q_one
q_oneDescription
TRUEnever evaluated
FALSEnever evaluated
) && (p_zero
p_zeroDescription
TRUEnever evaluated
FALSEnever evaluated
|| p_one
p_oneDescription
TRUEnever evaluated
FALSEnever evaluated
))
0
426 return;
never executed: return;
0
427-
428 QPointF pt;-
429 if (p_zero
p_zeroDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
430 pt = p1;-
431 }
never executed: end of block
else if (p_one
p_oneDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
432 pt = p2;-
433 }
never executed: end of block
else if (q_zero
q_zeroDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
434 pt = q1;-
435 }
never executed: end of block
else if (q_one
q_oneDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
436 pt = q2;-
437 }
never executed: end of block
else {
0
438 pt = q1 + (q2 - q1) * tq;-
439 }
never executed: end of block
0
440-
441 QIntersection intersection;-
442 intersection.alphaA = tp;-
443 intersection.alphaB = tq;-
444 intersection.pos = pt;-
445 intersections.add(intersection);-
446}
never executed: end of block
0
447-
448void SegmentTree::produceIntersections(int segment)-
449{-
450 const QRectF &segmentBounds = m_segments.elementBounds(segment);-
451-
452 RectF sbounds;-
453 sbounds.x1 = segmentBounds.left();-
454 sbounds.y1 = segmentBounds.top();-
455 sbounds.x2 = segmentBounds.right();-
456 sbounds.y2 = segmentBounds.bottom();-
457-
458 produceIntersections(m_tree.at(0), segment, sbounds, m_bounds, 0);-
459}
never executed: end of block
0
460-
461void SegmentTree::produceIntersectionsLeaf(const TreeNode &node, int segment)-
462{-
463 const QRectF &r1 = m_segments.elementBounds(segment);-
464 const QLineF lineA = m_segments.lineAt(segment);-
465-
466 for (int i = node.index.interval.first; i < node.index.interval.last
i < node.index.interval.lastDescription
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
467 const int other = m_index.at(i);-
468 if (other >= segment
other >= segmentDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
469 continue;
never executed: continue;
0
470-
471 const QRectF &r2 = m_segments.elementBounds(other);-
472-
473 if (r1.left() > r2.right()
r1.left() > r2.right()Description
TRUEnever evaluated
FALSEnever evaluated
|| r2.left() > r1.right()
r2.left() > r1.right()Description
TRUEnever evaluated
FALSEnever evaluated
)
0
474 continue;
never executed: continue;
0
475 if (r1.top() > r2.bottom()
r1.top() > r2.bottom()Description
TRUEnever evaluated
FALSEnever evaluated
|| r2.top() > r1.bottom()
r2.top() > r1.bottom()Description
TRUEnever evaluated
FALSEnever evaluated
)
0
476 continue;
never executed: continue;
0
477-
478 m_intersections.reset();-
479-
480 const QLineF lineB = m_segments.lineAt(other);-
481-
482 intersectLines(lineA, lineB, m_intersections);-
483-
484 for (int k = 0; k < m_intersections.size()
k < m_intersections.size()Description
TRUEnever evaluated
FALSEnever evaluated
; ++k) {
0
485 QPathSegments::Intersection i_isect, j_isect;-
486 i_isect.t = m_intersections.at(k).alphaA;-
487 j_isect.t = m_intersections.at(k).alphaB;-
488-
489 i_isect.vertex = j_isect.vertex = m_segments.addPoint(m_intersections.at(k).pos);-
490-
491 i_isect.next = 0;-
492 j_isect.next = 0;-
493-
494 m_segments.addIntersection(segment, i_isect);-
495 m_segments.addIntersection(other, j_isect);-
496 }
never executed: end of block
0
497 }
never executed: end of block
0
498}
never executed: end of block
0
499-
500void SegmentTree::produceIntersections(const TreeNode &node, int segment, const RectF &segmentBounds, const RectF &nodeBounds, int axis)-
501{-
502 if (node.leaf
node.leafDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
503 produceIntersectionsLeaf(node, segment);-
504 return;
never executed: return;
0
505 }-
506-
507 RectF lbounds = nodeBounds;-
508 (&lbounds.x2)[axis] = node.splitLeft;-
509-
510 RectF rbounds = nodeBounds;-
511 (&rbounds.x1)[axis] = node.splitRight;-
512-
513 if (segment > node.lowestLeftIndex
segment > node.lowestLeftIndexDescription
TRUEnever evaluated
FALSEnever evaluated
&& (
(&segmentBound...node.splitLeftDescription
TRUEnever evaluated
FALSEnever evaluated
&segmentBounds.x1)[axis] <= node.splitLeft
(&segmentBound...node.splitLeftDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
514 produceIntersections(m_tree.at(node.index.children.left), segment, segmentBounds, lbounds, !axis);
never executed: produceIntersections(m_tree.at(node.index.children.left), segment, segmentBounds, lbounds, !axis);
0
515-
516 if (segment > node.lowestRightIndex
segment > node...westRightIndexDescription
TRUEnever evaluated
FALSEnever evaluated
&& (
(&segmentBound...ode.splitRightDescription
TRUEnever evaluated
FALSEnever evaluated
&segmentBounds.x2)[axis] >= node.splitRight
(&segmentBound...ode.splitRightDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
517 produceIntersections(m_tree.at(node.index.children.right), segment, segmentBounds, rbounds, !axis);
never executed: produceIntersections(m_tree.at(node.index.children.right), segment, segmentBounds, rbounds, !axis);
0
518}
never executed: end of block
0
519-
520}-
521-
522void QIntersectionFinder::produceIntersections(QPathSegments &segments)-
523{-
524 SegmentTree tree(segments);-
525-
526 for (int i = 0; i < segments.segments()
i < segments.segments()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i)
0
527 tree.produceIntersections(i);
never executed: tree.produceIntersections(i);
0
528}
never executed: end of block
0
529-
530class QKdPointTree-
531{-
532public:-
533 enum Traversal {-
534 TraverseBoth,-
535 TraverseLeft,-
536 TraverseRight,-
537 TraverseNone-
538 };-
539-
540 struct Node {-
541 int point;-
542 int id;-
543-
544 Node *left;-
545 Node *right;-
546 };-
547-
548 QKdPointTree(const QPathSegments &segments)-
549 : m_segments(&segments)-
550 , m_nodes(m_segments->points())-
551 , m_id(0)-
552 {-
553 m_nodes.resize(m_segments->points());-
554-
555 for (int i = 0; i < m_nodes.size()
i < m_nodes.size()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
556 m_nodes.at(i).point = i;-
557 m_nodes.at(i).id = -1;-
558 }
never executed: end of block
0
559-
560 m_rootNode = build(0, m_nodes.size());-
561 }
never executed: end of block
0
562-
563 int build(int begin, int end, int depth = 0);-
564-
565 Node *rootNode()-
566 {-
567 return
never executed: return &m_nodes.at(m_rootNode);
&m_nodes.at(m_rootNode);
never executed: return &m_nodes.at(m_rootNode);
0
568 }-
569-
570 inline int nextId()-
571 {-
572 return
never executed: return m_id++;
m_id++;
never executed: return m_id++;
0
573 }-
574-
575private:-
576 const QPathSegments *m_segments;-
577 QDataBuffer<Node> m_nodes;-
578-
579 int m_rootNode;-
580 int m_id;-
581};-
582-
583template <typename T>-
584void qTraverseKdPointTree(QKdPointTree::Node &node, T &t, int depth = 0)-
585{-
586 QKdPointTree::Traversal status = t(node, depth);-
587-
588 const bool traverseRight = (status == QKdPointTree::TraverseBoth || status == QKdPointTree::TraverseRight);-
589 const bool traverseLeft = (status == QKdPointTree::TraverseBoth || status == QKdPointTree::TraverseLeft);-
590-
591 if (traverseLeft
traverseLeftDescription
TRUEnever evaluated
FALSEnever evaluated
&& node.left
node.leftDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
592 ::
never executed: ::qTraverseKdPointTree<T>(*node.left, t, depth + 1);
qTraverseKdPointTree<T>(*node.left, t, depth + 1);
never executed: ::qTraverseKdPointTree<T>(*node.left, t, depth + 1);
0
593-
594 if (traverseRight
traverseRightDescription
TRUEnever evaluated
FALSEnever evaluated
&& node.right
node.rightDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
595 ::
never executed: ::qTraverseKdPointTree<T>(*node.right, t, depth + 1);
qTraverseKdPointTree<T>(*node.right, t, depth + 1);
never executed: ::qTraverseKdPointTree<T>(*node.right, t, depth + 1);
0
596}
never executed: end of block
0
597-
598static inline qreal component(const QPointF &point, unsigned int i)-
599{-
600 ((!(i < 2)) ? qt_assert("i < 2",__FILE__,663) : qt_noop());-
601 const qreal components[] = { point.x(), point.y() };-
602 return
never executed: return components[i];
components[i];
never executed: return components[i];
0
603}-
604-
605int QKdPointTree::build(int begin, int end, int depth)-
606{-
607 ((!(end > begin)) ? qt_assert("end > begin",__FILE__,670) : qt_noop());-
608-
609 const qreal pivot = component(m_segments->pointAt(m_nodes.at(begin).point), depth & 1);-
610-
611 int first = begin + 1;-
612 int last = end - 1;-
613-
614 while (first <= last
first <= lastDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
615 const qreal value = component(m_segments->pointAt(m_nodes.at(first).point), depth & 1);-
616-
617 if (value < pivot
value < pivotDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
618 ++
never executed: ++first;
first;
never executed: ++first;
0
619 else {-
620 qSwap(m_nodes.at(first), m_nodes.at(last));-
621 --last;-
622 }
never executed: end of block
0
623 }-
624-
625 qSwap(m_nodes.at(last), m_nodes.at(begin));-
626-
627 if (last > begin
last > beginDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
628 m_nodes.at(last).left = &m_nodes.at(build(begin, last, depth + 1));
never executed: m_nodes.at(last).left = &m_nodes.at(build(begin, last, depth + 1));
0
629 else-
630 m_nodes.at(last).left = 0;
never executed: m_nodes.at(last).left = 0;
0
631-
632 if (last + 1 < end
last + 1 < endDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
633 m_nodes.at(last).right = &m_nodes.at(build(last + 1, end, depth + 1));
never executed: m_nodes.at(last).right = &m_nodes.at(build(last + 1, end, depth + 1));
0
634 else-
635 m_nodes.at(last).right = 0;
never executed: m_nodes.at(last).right = 0;
0
636-
637 return
never executed: return last;
last;
never executed: return last;
0
638}-
639-
640class QKdPointFinder-
641{-
642public:-
643 QKdPointFinder(int point, const QPathSegments &segments, QKdPointTree &tree)-
644 : m_result(-1)-
645 , m_segments(&segments)-
646 , m_tree(&tree)-
647 {-
648 pointComponents[0] = segments.pointAt(point).x();-
649 pointComponents[1] = segments.pointAt(point).y();-
650 }
never executed: end of block
0
651-
652 inline QKdPointTree::Traversal operator()(QKdPointTree::Node &node, int depth)-
653 {-
654 if (m_result != -1
m_result != -1Description
TRUEnever evaluated
FALSEnever evaluated
)
0
655 return
never executed: return QKdPointTree::TraverseNone;
QKdPointTree::TraverseNone;
never executed: return QKdPointTree::TraverseNone;
0
656-
657 const QPointF &nodePoint = m_segments->pointAt(node.point);-
658-
659 const qreal pivotComponents[] = { nodePoint.x(), nodePoint.y() };-
660-
661 const qreal pivot = pivotComponents[depth & 1];-
662 const qreal value = pointComponents[depth & 1];-
663-
664 if (fuzzyIsNull(pivot - value)
fuzzyIsNull(pivot - value)Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
665 const qreal pivot2 = pivotComponents[(depth + 1) & 1];-
666 const qreal value2 = pointComponents[(depth + 1) & 1];-
667-
668 if (fuzzyIsNull(pivot2 - value2)
fuzzyIsNull(pivot2 - value2)Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
669 if (node.id < 0
node.id < 0Description
TRUEnever evaluated
FALSEnever evaluated
)
0
670 node.id = m_tree->nextId();
never executed: node.id = m_tree->nextId();
0
671-
672 m_result = node.id;-
673 return
never executed: return QKdPointTree::TraverseNone;
QKdPointTree::TraverseNone;
never executed: return QKdPointTree::TraverseNone;
0
674 } else-
675 return
never executed: return QKdPointTree::TraverseBoth;
QKdPointTree::TraverseBoth;
never executed: return QKdPointTree::TraverseBoth;
0
676 } else if (value < pivot
value < pivotDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
677 return
never executed: return QKdPointTree::TraverseLeft;
QKdPointTree::TraverseLeft;
never executed: return QKdPointTree::TraverseLeft;
0
678 } else {-
679 return
never executed: return QKdPointTree::TraverseRight;
QKdPointTree::TraverseRight;
never executed: return QKdPointTree::TraverseRight;
0
680 }-
681 }-
682-
683 int result() const-
684 {-
685 return
never executed: return m_result;
m_result;
never executed: return m_result;
0
686 }-
687-
688private:-
689 qreal pointComponents[2];-
690 int m_result;-
691 const QPathSegments *m_segments;-
692 QKdPointTree *m_tree;-
693};-
694-
695-
696void QPathSegments::mergePoints()-
697{-
698 QKdPointTree tree(*this);-
699-
700 if (tree.rootNode()
tree.rootNode()Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
701 QDataBuffer<QPointF> mergedPoints(points());-
702 QDataBuffer<int> pointIndices(points());-
703-
704 for (int i = 0; i < points()
i < points()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
705 QKdPointFinder finder(i, *this, tree);-
706 ::qTraverseKdPointTree<QKdPointFinder>(*tree.rootNode(), finder);-
707-
708 ((!(finder.result() != -1)) ? qt_assert("finder.result() != -1",__FILE__,771) : qt_noop());-
709-
710 if (finder.result() >= mergedPoints.size()
finder.result(...dPoints.size()Description
TRUEnever evaluated
FALSEnever evaluated
)
0
711 mergedPoints << m_points.at(i);
never executed: mergedPoints << m_points.at(i);
0
712-
713 pointIndices << finder.result();-
714 }
never executed: end of block
0
715-
716 for (int i = 0; i < m_segments.size()
i < m_segments.size()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
717 m_segments.at(i).va = pointIndices.at(m_segments.at(i).va);-
718 m_segments.at(i).vb = pointIndices.at(m_segments.at(i).vb);-
719 }
never executed: end of block
0
720-
721 for (int i = 0; i < m_intersections.size()
i < m_intersections.size()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i)
0
722 m_intersections.at(i).vertex = pointIndices.at(m_intersections.at(i).vertex);
never executed: m_intersections.at(i).vertex = pointIndices.at(m_intersections.at(i).vertex);
0
723-
724 m_points.swap(mergedPoints);-
725 }
never executed: end of block
0
726}
never executed: end of block
0
727-
728void QWingedEdge::intersectAndAdd()-
729{-
730 QIntersectionFinder finder;-
731 finder.produceIntersections(m_segments);-
732-
733 m_segments.mergePoints();-
734-
735 for (int i = 0; i < m_segments.points()
i < m_segments.points()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i)
0
736 addVertex(m_segments.pointAt(i));
never executed: addVertex(m_segments.pointAt(i));
0
737-
738 QDataBuffer<QPathSegments::Intersection> intersections(m_segments.segments());-
739 for (int i = 0; i < m_segments.segments()
i < m_segments.segments()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
740 intersections.reset();-
741-
742 int pathId = m_segments.pathId(i);-
743-
744 const QPathSegments::Intersection *isect = m_segments.intersectionAt(i);-
745 while (isect
isectDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
746 intersections << *isect;-
747-
748 if (isect->next
isect->nextDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
749 isect += isect->next;-
750 }
never executed: end of block
else {
0
751 isect = 0;-
752 }
never executed: end of block
0
753 }-
754-
755 std::sort(intersections.data(), intersections.data() + intersections.size());-
756-
757 int first = m_segments.segmentAt(i).va;-
758 int second = m_segments.segmentAt(i).vb;-
759-
760 int last = first;-
761 for (int j = 0; j < intersections.size()
j < intersections.size()Description
TRUEnever evaluated
FALSEnever evaluated
; ++j) {
0
762 const QPathSegments::Intersection &isect = intersections.at(j);-
763-
764 QPathEdge *ep = edge(addEdge(last, isect.vertex));-
765-
766 if (ep
epDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
767 const int dir = m_segments.pointAt(last).y() < m_segments.pointAt(isect.vertex).y()
m_segments.poi...ct.vertex).y()Description
TRUEnever evaluated
FALSEnever evaluated
? 1 : -1;
0
768 if (pathId == 0
pathId == 0Description
TRUEnever evaluated
FALSEnever evaluated
)
0
769 ep->windingA += dir;
never executed: ep->windingA += dir;
0
770 else-
771 ep->windingB += dir;
never executed: ep->windingB += dir;
0
772 }-
773-
774 last = isect.vertex;-
775 }
never executed: end of block
0
776-
777 QPathEdge *ep = edge(addEdge(last, second));-
778-
779 if (ep
epDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
780 const int dir = m_segments.pointAt(last).y() < m_segments.pointAt(second).y()
m_segments.poi...At(second).y()Description
TRUEnever evaluated
FALSEnever evaluated
? 1 : -1;
0
781 if (pathId == 0
pathId == 0Description
TRUEnever evaluated
FALSEnever evaluated
)
0
782 ep->windingA += dir;
never executed: ep->windingA += dir;
0
783 else-
784 ep->windingB += dir;
never executed: ep->windingB += dir;
0
785 }-
786 }
never executed: end of block
0
787}
never executed: end of block
0
788-
789QWingedEdge::QWingedEdge() :-
790 m_edges(0),-
791 m_vertices(0),-
792 m_segments(0)-
793{-
794}
never executed: end of block
0
795-
796QWingedEdge::QWingedEdge(const QPainterPath &subject, const QPainterPath &clip) :-
797 m_edges(subject.elementCount()),-
798 m_vertices(subject.elementCount()),-
799 m_segments(subject.elementCount())-
800{-
801 m_segments.setPath(subject);-
802 m_segments.addPath(clip);-
803-
804 intersectAndAdd();-
805}
never executed: end of block
0
806-
807QWingedEdge::TraversalStatus QWingedEdge::next(const QWingedEdge::TraversalStatus &status) const-
808{-
809 const QPathEdge *sp = edge(status.edge);-
810 ((!(sp)) ? qt_assert("sp",__FILE__,873) : qt_noop());-
811-
812 TraversalStatus result;-
813 result.edge = sp->next(status.traversal, status.direction);-
814 result.traversal = status.traversal;-
815 result.direction = status.direction;-
816-
817 const QPathEdge *rp = edge(result.edge);-
818 ((!(rp)) ? qt_assert("rp",__FILE__,881) : qt_noop());-
819-
820 if (sp->vertex(status.direction) == rp->vertex(status.direction)
sp->vertex(sta...tus.direction)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
821 result.flip();
never executed: result.flip();
0
822-
823 return
never executed: return result;
result;
never executed: return result;
0
824}-
825-
826static bool isLine(const QBezier &bezier)-
827{-
828 const bool equal_1_2 = comparePoints(bezier.pt1(), bezier.pt2());-
829 const bool equal_2_3 = comparePoints(bezier.pt2(), bezier.pt3());-
830 const bool equal_3_4 = comparePoints(bezier.pt3(), bezier.pt4());-
831-
832-
833 if (equal_1_2
equal_1_2Description
TRUEnever evaluated
FALSEnever evaluated
&& equal_2_3
equal_2_3Description
TRUEnever evaluated
FALSEnever evaluated
&& equal_3_4
equal_3_4Description
TRUEnever evaluated
FALSEnever evaluated
)
0
834 return
never executed: return true;
true;
never executed: return true;
0
835-
836 if (comparePoints(bezier.pt1(), bezier.pt4())
comparePoints(... bezier.pt4())Description
TRUEnever evaluated
FALSEnever evaluated
)
0
837 return
never executed: return equal_1_2 || equal_3_4;
equal_1_2 || equal_3_4;
never executed: return equal_1_2 || equal_3_4;
0
838-
839 return
never executed: return (equal_1_2 && equal_3_4) || (equal_1_2 && equal_2_3) || (equal_2_3 && equal_3_4);
(equal_1_2 && equal_3_4) || (equal_1_2 && equal_2_3) || (equal_2_3 && equal_3_4);
never executed: return (equal_1_2 && equal_3_4) || (equal_1_2 && equal_2_3) || (equal_2_3 && equal_3_4);
0
840}-
841-
842void QPathSegments::setPath(const QPainterPath &path)-
843{-
844 m_points.reset();-
845 m_intersections.reset();-
846 m_segments.reset();-
847-
848 m_pathId = 0;-
849-
850 addPath(path);-
851}
never executed: end of block
0
852-
853void QPathSegments::addPath(const QPainterPath &path)-
854{-
855 int firstSegment = m_segments.size();-
856-
857 bool hasMoveTo = false;-
858 int lastMoveTo = 0;-
859 int last = 0;-
860 for (int i = 0; i < path.elementCount()
i < path.elementCount()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
861 int current = m_points.size();-
862-
863 QPointF currentPoint;-
864 if (path.elementAt(i).type == QPainterPath::CurveToElement
path.elementAt...CurveToElementDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
865 currentPoint = path.elementAt(i+2);
never executed: currentPoint = path.elementAt(i+2);
0
866 else-
867 currentPoint = path.elementAt(i);
never executed: currentPoint = path.elementAt(i);
0
868-
869 if (i > 0
i > 0Description
TRUEnever evaluated
FALSEnever evaluated
&& comparePoints(m_points.at(lastMoveTo), currentPoint)
comparePoints(... currentPoint)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
870 current = lastMoveTo;
never executed: current = lastMoveTo;
0
871 else-
872 m_points << currentPoint;
never executed: m_points << currentPoint;
0
873-
874 switch (path.elementAt(i).type) {-
875 case
never executed: case QPainterPath::MoveToElement:
QPainterPath::MoveToElement:
never executed: case QPainterPath::MoveToElement:
0
876 if (hasMoveTo
hasMoveToDescription
TRUEnever evaluated
FALSEnever evaluated
&& last != lastMoveTo
last != lastMoveToDescription
TRUEnever evaluated
FALSEnever evaluated
&& !comparePoints(m_points.at(last), m_points.at(lastMoveTo))
!comparePoints...t(lastMoveTo))Description
TRUEnever evaluated
FALSEnever evaluated
)
0
877 m_segments << Segment(m_pathId, last, lastMoveTo);
never executed: m_segments << Segment(m_pathId, last, lastMoveTo);
0
878 hasMoveTo = true;-
879 last = lastMoveTo = current;-
880 break;
never executed: break;
0
881 case
never executed: case QPainterPath::LineToElement:
QPainterPath::LineToElement:
never executed: case QPainterPath::LineToElement:
0
882 m_segments << Segment(m_pathId, last, current);-
883 last = current;-
884 break;
never executed: break;
0
885 case
never executed: case QPainterPath::CurveToElement:
QPainterPath::CurveToElement:
never executed: case QPainterPath::CurveToElement:
0
886 {-
887 QBezier bezier = QBezier::fromPoints(m_points.at(last), path.elementAt(i), path.elementAt(i+1), path.elementAt(i+2));-
888 if (isLine(bezier)
isLine(bezier)Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
889 m_segments << Segment(m_pathId, last, current);-
890 }
never executed: end of block
else {
0
891 QRectF bounds = bezier.bounds();-
892-
893-
894 int threshold = qMin<float>(64, qMax(bounds.width(), bounds.height()) * (2 * qreal(3.14) / 6));-
895-
896 if (threshold < 3
threshold < 3Description
TRUEnever evaluated
FALSEnever evaluated
) threshold = 3;
never executed: threshold = 3;
0
897 qreal one_over_threshold_minus_1 = qreal(1) / (threshold - 1);-
898-
899 for (int t = 1; t < threshold - 1
t < threshold - 1Description
TRUEnever evaluated
FALSEnever evaluated
; ++t) {
0
900 currentPoint = bezier.pointAt(t * one_over_threshold_minus_1);-
901-
902 int index = m_points.size();-
903 m_segments << Segment(m_pathId, last, index);-
904 last = index;-
905-
906 m_points << currentPoint;-
907 }
never executed: end of block
0
908-
909 m_segments << Segment(m_pathId, last, current);-
910 }
never executed: end of block
0
911 }-
912 last = current;-
913 i += 2;-
914 break;
never executed: break;
0
915 default
never executed: default:
:
never executed: default:
0
916 ((!(false)) ? qt_assert("false",__FILE__,979) : qt_noop());-
917 break;
never executed: break;
0
918 }-
919 }-
920-
921 if (hasMoveTo
hasMoveToDescription
TRUEnever evaluated
FALSEnever evaluated
&& last != lastMoveTo
last != lastMoveToDescription
TRUEnever evaluated
FALSEnever evaluated
&& !comparePoints(m_points.at(last), m_points.at(lastMoveTo))
!comparePoints...t(lastMoveTo))Description
TRUEnever evaluated
FALSEnever evaluated
)
0
922 m_segments << Segment(m_pathId, last, lastMoveTo);
never executed: m_segments << Segment(m_pathId, last, lastMoveTo);
0
923-
924 for (int i = firstSegment; i < m_segments.size()
i < m_segments.size()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
925 const QLineF line = lineAt(i);-
926-
927 qreal x1 = line.p1().x();-
928 qreal y1 = line.p1().y();-
929 qreal x2 = line.p2().x();-
930 qreal y2 = line.p2().y();-
931-
932 if (x2 < x1
x2 < x1Description
TRUEnever evaluated
FALSEnever evaluated
)
0
933 qSwap(x1, x2);
never executed: qSwap(x1, x2);
0
934 if (y2 < y1
y2 < y1Description
TRUEnever evaluated
FALSEnever evaluated
)
0
935 qSwap(y1, y2);
never executed: qSwap(y1, y2);
0
936-
937 m_segments.at(i).bounds = QRectF(x1, y1, x2 - x1, y2 - y1);-
938 }
never executed: end of block
0
939-
940 ++m_pathId;-
941}
never executed: end of block
0
942-
943qreal QWingedEdge::delta(int vertex, int a, int b) const-
944{-
945 const QPathEdge *ap = edge(a);-
946 const QPathEdge *bp = edge(b);-
947-
948 double a_angle = ap->angle;-
949 double b_angle = bp->angle;-
950-
951 if (vertex == ap->second
vertex == ap->secondDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
952 a_angle = ap->invAngle;
never executed: a_angle = ap->invAngle;
0
953-
954 if (vertex == bp->second
vertex == bp->secondDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
955 b_angle = bp->invAngle;
never executed: b_angle = bp->invAngle;
0
956-
957 double result = b_angle - a_angle;-
958-
959 if (result >= 128.
result >= 128.Description
TRUEnever evaluated
FALSEnever evaluated
)
0
960 return
never executed: return result - 128.;
result - 128.;
never executed: return result - 128.;
0
961 else if (result < 0
result < 0Description
TRUEnever evaluated
FALSEnever evaluated
)
0
962 return
never executed: return result + 128.;
result + 128.;
never executed: return result + 128.;
0
963 else-
964 return
never executed: return result;
result;
never executed: return result;
0
965}-
966-
967QWingedEdge::TraversalStatus QWingedEdge::findInsertStatus(int vi, int ei) const-
968{-
969 const QPathVertex *vp = vertex(vi);-
970-
971 ((!(vp)) ? qt_assert("vp",__FILE__,1034) : qt_noop());-
972 ((!(ei >= 0)) ? qt_assert("ei >= 0",__FILE__,1035) : qt_noop());-
973 ((!(vp->edge >= 0)) ? qt_assert("vp->edge >= 0",__FILE__,1036) : qt_noop());-
974-
975 int position = vp->edge;-
976 qreal d = 128.;-
977-
978 TraversalStatus status;-
979 status.direction = edge(vp->edge)->directionTo(vi);-
980 status.traversal = QPathEdge::RightTraversal;-
981 status.edge = vp->edge;-
982-
983-
984-
985-
986-
987-
988 do {-
989 status = next(status);-
990 status.flip();-
991-
992 ((!(edge(status.edge)->vertex(status.direction) == vi)) ? qt_assert("edge(status.edge)->vertex(status.direction) == vi",__FILE__,1055) : qt_noop());-
993 qreal d2 = delta(vi, ei, status.edge);-
994-
995-
996-
997-
998-
999-
1000 if (d2 < d
d2 < dDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
1001 position = status.edge;-
1002 d = d2;-
1003 }
never executed: end of block
0
1004 }
never executed: end of block
while (status.edge != vp->edge
status.edge != vp->edgeDescription
TRUEnever evaluated
FALSEnever evaluated
);
0
1005-
1006 status.traversal = QPathEdge::LeftTraversal;-
1007 status.direction = QPathEdge::Forward;-
1008 status.edge = position;-
1009-
1010 if (edge(status.edge)->vertex(status.direction) != vi
edge(status.ed...rection) != viDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1011 status.flip();
never executed: status.flip();
0
1012-
1013-
1014-
1015-
1016-
1017 ((!(edge(status.edge)->vertex(status.direction) == vi)) ? qt_assert("edge(status.edge)->vertex(status.direction) == vi",__FILE__,1080) : qt_noop());-
1018-
1019 return
never executed: return status;
status;
never executed: return status;
0
1020}-
1021-
1022void QWingedEdge::removeEdge(int ei)-
1023{-
1024 QPathEdge *ep = edge(ei);-
1025-
1026 TraversalStatus status;-
1027 status.direction = QPathEdge::Forward;-
1028 status.traversal = QPathEdge::RightTraversal;-
1029 status.edge = ei;-
1030-
1031 TraversalStatus forwardRight = next(status);-
1032 forwardRight.flipDirection();-
1033-
1034 status.traversal = QPathEdge::LeftTraversal;-
1035 TraversalStatus forwardLeft = next(status);-
1036 forwardLeft.flipDirection();-
1037-
1038 status.direction = QPathEdge::Backward;-
1039 TraversalStatus backwardLeft = next(status);-
1040 backwardLeft.flipDirection();-
1041-
1042 status.traversal = QPathEdge::RightTraversal;-
1043 TraversalStatus backwardRight = next(status);-
1044 backwardRight.flipDirection();-
1045-
1046 edge(forwardRight.edge)->setNext(forwardRight.traversal, forwardRight.direction, forwardLeft.edge);-
1047 edge(forwardLeft.edge)->setNext(forwardLeft.traversal, forwardLeft.direction, forwardRight.edge);-
1048-
1049 edge(backwardRight.edge)->setNext(backwardRight.traversal, backwardRight.direction, backwardLeft.edge);-
1050 edge(backwardLeft.edge)->setNext(backwardLeft.traversal, backwardLeft.direction, backwardRight.edge);-
1051-
1052 ep->setNext(QPathEdge::Forward, ei);-
1053 ep->setNext(QPathEdge::Backward, ei);-
1054-
1055 QPathVertex *a = vertex(ep->first);-
1056 QPathVertex *b = vertex(ep->second);-
1057-
1058 a->edge = backwardRight.edge;-
1059 b->edge = forwardRight.edge;-
1060}
never executed: end of block
0
1061-
1062static int commonEdge(const QWingedEdge &list, int a, int b)-
1063{-
1064 const QPathVertex *ap = list.vertex(a);-
1065 ((!(ap)) ? qt_assert("ap",__FILE__,1128) : qt_noop());-
1066-
1067 const QPathVertex *bp = list.vertex(b);-
1068 ((!(bp)) ? qt_assert("bp",__FILE__,1131) : qt_noop());-
1069-
1070 if (ap->edge < 0
ap->edge < 0Description
TRUEnever evaluated
FALSEnever evaluated
|| bp->edge < 0
bp->edge < 0Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1071 return
never executed: return -1;
-1;
never executed: return -1;
0
1072-
1073 QWingedEdge::TraversalStatus status;-
1074 status.edge = ap->edge;-
1075 status.direction = list.edge(status.edge)->directionTo(a);-
1076 status.traversal = QPathEdge::RightTraversal;-
1077-
1078 do {-
1079 const QPathEdge *ep = list.edge(status.edge);-
1080-
1081 if ((ep->first == a
ep->first == aDescription
TRUEnever evaluated
FALSEnever evaluated
&& ep->second == b
ep->second == bDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1082 || (ep->first == b
ep->first == bDescription
TRUEnever evaluated
FALSEnever evaluated
&& ep->second == a
ep->second == aDescription
TRUEnever evaluated
FALSEnever evaluated
))
0
1083 return
never executed: return status.edge;
status.edge;
never executed: return status.edge;
0
1084-
1085 status = list.next(status);-
1086 status.flip();-
1087 }
never executed: end of block
while (status.edge != ap->edge
status.edge != ap->edgeDescription
TRUEnever evaluated
FALSEnever evaluated
);
0
1088-
1089 return
never executed: return -1;
-1;
never executed: return -1;
0
1090}-
1091-
1092static double computeAngle(const QPointF &v)-
1093{-
1094-
1095 if (v.x() == 0
v.x() == 0Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
1096 return
never executed: return v.y() <= 0 ? 0 : 64.;
v.y() <= 0 ? 0 : 64.;
never executed: return v.y() <= 0 ? 0 : 64.;
0
1097 } else if (v.y() == 0
v.y() == 0Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
1098 return
never executed: return v.x() <= 0 ? 32. : 96.;
v.x() <= 0 ? 32. : 96.;
never executed: return v.x() <= 0 ? 32. : 96.;
0
1099 }-
1100-
1101 double vx = v.x();-
1102 double vy = v.y();-
1103 normalize(vx, vy);-
1104 if (vy < 0
vy < 0Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
1105 if (vx < 0
vx < 0Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
1106 return
never executed: return -32. * vx;
-32. * vx;
never executed: return -32. * vx;
0
1107 } else {-
1108 return
never executed: return 128. - 32. * vx;
128. - 32. * vx;
never executed: return 128. - 32. * vx;
0
1109 }-
1110 } else {-
1111 return
never executed: return 64. + 32. * vx;
64. + 32. * vx;
never executed: return 64. + 32. * vx;
0
1112 }-
1113-
1114-
1115-
1116-
1117}-
1118-
1119int QWingedEdge::addEdge(const QPointF &a, const QPointF &b)-
1120{-
1121 int fi = insert(a);-
1122 int si = insert(b);-
1123-
1124 return
never executed: return addEdge(fi, si);
addEdge(fi, si);
never executed: return addEdge(fi, si);
0
1125}-
1126-
1127int QWingedEdge::addEdge(int fi, int si)-
1128{-
1129 if (fi == si
fi == siDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1130 return
never executed: return -1;
-1;
never executed: return -1;
0
1131-
1132 int common = commonEdge(*this, fi, si);-
1133 if (common >= 0
common >= 0Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1134 return
never executed: return common;
common;
never executed: return common;
0
1135-
1136 m_edges << QPathEdge(fi, si);-
1137-
1138 int ei = m_edges.size() - 1;-
1139-
1140 QPathVertex *fp = vertex(fi);-
1141 QPathVertex *sp = vertex(si);-
1142-
1143 QPathEdge *ep = edge(ei);-
1144-
1145 const QPointF tangent = QPointF(*sp) - QPointF(*fp);-
1146 ep->angle = computeAngle(tangent);-
1147 ep->invAngle = ep->angle + 64;-
1148 if (ep->invAngle >= 128
ep->invAngle >= 128Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1149 ep->invAngle -= 128;
never executed: ep->invAngle -= 128;
0
1150-
1151 QPathVertex *vertices[2] = { fp, sp };-
1152 QPathEdge::Direction dirs[2] = { QPathEdge::Backward, QPathEdge::Forward };-
1153-
1154-
1155-
1156-
1157-
1158 for (int i = 0; i < 2
i < 2Description
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
1159 QPathVertex *vp = vertices[i];-
1160 if (vp->edge < 0
vp->edge < 0Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
1161 vp->edge = ei;-
1162 ep->setNext(dirs[i], ei);-
1163 }
never executed: end of block
else {
0
1164 int vi = ep->vertex(dirs[i]);-
1165 ((!(vertex(vi) == vertices[i])) ? qt_assert("vertex(vi) == vertices[i]",__FILE__,1228) : qt_noop());-
1166-
1167 TraversalStatus os = findInsertStatus(vi, ei);-
1168 QPathEdge *op = edge(os.edge);-
1169-
1170 ((!(vertex(op->vertex(os.direction)) == vertices[i])) ? qt_assert("vertex(op->vertex(os.direction)) == vertices[i]",__FILE__,1233) : qt_noop());-
1171-
1172 TraversalStatus ns = next(os);-
1173 ns.flipDirection();-
1174 QPathEdge *np = edge(ns.edge);-
1175-
1176 op->setNext(os.traversal, os.direction, ei);-
1177 np->setNext(ns.traversal, ns.direction, ei);-
1178-
1179 int oe = os.edge;-
1180 int ne = ns.edge;-
1181-
1182 os = next(os);-
1183 ns = next(ns);-
1184-
1185 os.flipDirection();-
1186 ns.flipDirection();-
1187-
1188 ((!(os.edge == ei)) ? qt_assert("os.edge == ei",__FILE__,1251) : qt_noop());-
1189 ((!(ns.edge == ei)) ? qt_assert("ns.edge == ei",__FILE__,1252) : qt_noop());-
1190-
1191 ep->setNext(os.traversal, os.direction, oe);-
1192 ep->setNext(ns.traversal, ns.direction, ne);-
1193 }
never executed: end of block
0
1194 }-
1195-
1196 ((!(ep->next(QPathEdge::RightTraversal, QPathEdge::Forward) >= 0)) ? qt_assert("ep->next(QPathEdge::RightTraversal, QPathEdge::Forward) >= 0",__FILE__,1259) : qt_noop());-
1197 ((!(ep->next(QPathEdge::RightTraversal, QPathEdge::Backward) >= 0)) ? qt_assert("ep->next(QPathEdge::RightTraversal, QPathEdge::Backward) >= 0",__FILE__,1260) : qt_noop());-
1198 ((!(ep->next(QPathEdge::LeftTraversal, QPathEdge::Forward) >= 0)) ? qt_assert("ep->next(QPathEdge::LeftTraversal, QPathEdge::Forward) >= 0",__FILE__,1261) : qt_noop());-
1199 ((!(ep->next(QPathEdge::LeftTraversal, QPathEdge::Backward) >= 0)) ? qt_assert("ep->next(QPathEdge::LeftTraversal, QPathEdge::Backward) >= 0",__FILE__,1262) : qt_noop());-
1200-
1201 return
never executed: return ei;
ei;
never executed: return ei;
0
1202}-
1203-
1204int QWingedEdge::insert(const QPathVertex &vertex)-
1205{-
1206 if (!m_vertices.isEmpty()
!m_vertices.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
1207 const QPathVertex &last = m_vertices.last();-
1208 if (vertex.x == last.x
vertex.x == last.xDescription
TRUEnever evaluated
FALSEnever evaluated
&& vertex.y == last.y
vertex.y == last.yDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1209 return
never executed: return m_vertices.size() - 1;
m_vertices.size() - 1;
never executed: return m_vertices.size() - 1;
0
1210-
1211 for (int i = 0; i < m_vertices.size()
i < m_vertices.size()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
1212 const QPathVertex &v = m_vertices.at(i);-
1213 if (qFuzzyCompare(v.x, vertex.x)
qFuzzyCompare(v.x, vertex.x)Description
TRUEnever evaluated
FALSEnever evaluated
&& qFuzzyCompare(v.y, vertex.y)
qFuzzyCompare(v.y, vertex.y)Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
1214 return
never executed: return i;
i;
never executed: return i;
0
1215 }-
1216 }
never executed: end of block
0
1217 }
never executed: end of block
0
1218-
1219 m_vertices << vertex;-
1220 return
never executed: return m_vertices.size() - 1;
m_vertices.size() - 1;
never executed: return m_vertices.size() - 1;
0
1221}-
1222-
1223static void addLineTo(QPainterPath &path, const QPointF &point)-
1224{-
1225 const int elementCount = path.elementCount();-
1226 if (elementCount >= 2
elementCount >= 2Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
1227 const QPainterPath::Element &middle = path.elementAt(elementCount - 1);-
1228 if (middle.type == QPainterPath::LineToElement
middle.type ==...:LineToElementDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
1229 const QPointF first = path.elementAt(elementCount - 2);-
1230 const QPointF d1 = point - first;-
1231 const QPointF d2 = middle - first;-
1232-
1233 const QPointF p(-d1.y(), d1.x());-
1234-
1235 if (qFuzzyIsNull(dot(p, d2))
qFuzzyIsNull(dot(p, d2))Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
1236 path.setElementPositionAt(elementCount - 1, point.x(), point.y());-
1237 return;
never executed: return;
0
1238 }-
1239 }
never executed: end of block
0
1240 }
never executed: end of block
0
1241-
1242 path.lineTo(point);-
1243}
never executed: end of block
0
1244-
1245static void add(QPainterPath &path, const QWingedEdge &list, int edge, QPathEdge::Traversal traversal)-
1246{-
1247 QWingedEdge::TraversalStatus status;-
1248 status.edge = edge;-
1249 status.traversal = traversal;-
1250 status.direction = QPathEdge::Forward;-
1251-
1252 path.moveTo(*list.vertex(list.edge(edge)->first));-
1253-
1254 do {-
1255 const QPathEdge *ep = list.edge(status.edge);-
1256-
1257 addLineTo(path, *list.vertex(ep->vertex(status.direction)));-
1258-
1259 if (status.traversal == QPathEdge::LeftTraversal
status.travers...:LeftTraversalDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1260 ep->flag &= ~16;
never executed: ep->flag &= ~16;
0
1261 else-
1262 ep->flag &= ~32;
never executed: ep->flag &= ~32;
0
1263-
1264 status = list.next(status);-
1265 }
never executed: end of block
while (status.edge != edge
status.edge != edgeDescription
TRUEnever evaluated
FALSEnever evaluated
);
0
1266}
never executed: end of block
0
1267-
1268void QWingedEdge::simplify()-
1269{-
1270 for (int i = 0; i < edgeCount()
i < edgeCount()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
1271 const QPathEdge *ep = edge(i);-
1272-
1273-
1274 int flag = 0x3 << 4;-
1275 if ((
(ep->flag & flag) == flagDescription
TRUEnever evaluated
FALSEnever evaluated
ep->flag & flag) == flag
(ep->flag & flag) == flagDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
1276 removeEdge(i);-
1277-
1278 ep->flag &= ~flag;-
1279 }
never executed: end of block
0
1280 }
never executed: end of block
0
1281}
never executed: end of block
0
1282-
1283QPainterPath QWingedEdge::toPath() const-
1284{-
1285 QPainterPath path;-
1286-
1287 for (int i = 0; i < edgeCount()
i < edgeCount()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
1288 const QPathEdge *ep = edge(i);-
1289-
1290 if (ep->flag & 16
ep->flag & 16Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
1291 add(path, *this, i, QPathEdge::LeftTraversal);-
1292 }
never executed: end of block
0
1293-
1294 if (ep->flag & 32
ep->flag & 32Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1295 add(path, *this, i, QPathEdge::RightTraversal);
never executed: add(path, *this, i, QPathEdge::RightTraversal);
0
1296 }
never executed: end of block
0
1297-
1298 return
never executed: return path;
path;
never executed: return path;
0
1299}-
1300-
1301bool QPathClipper::intersect()-
1302{-
1303 if (subjectPath == clipPath
subjectPath == clipPathDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1304 return
never executed: return true;
true;
never executed: return true;
0
1305-
1306 QRectF r1 = subjectPath.controlPointRect();-
1307 QRectF r2 = clipPath.controlPointRect();-
1308 if (qMax(r1.x(), r2.x()) > qMin(r1.x() + r1.width(), r2.x() + r2.width())
qMax(r1.x(), r... + r2.width())Description
TRUEnever evaluated
FALSEnever evaluated
||
0
1309 qMax(r1.y(), r2.y()) > qMin(r1.y() + r1.height(), r2.y() + r2.height())
qMax(r1.y(), r...+ r2.height())Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
1310-
1311 return
never executed: return false;
false;
never executed: return false;
0
1312 }-
1313-
1314 bool subjectIsRect = pathToRect(subjectPath);-
1315 bool clipIsRect = pathToRect(clipPath);-
1316-
1317 if (subjectIsRect
subjectIsRectDescription
TRUEnever evaluated
FALSEnever evaluated
&& clipIsRect
clipIsRectDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1318 return
never executed: return true;
true;
never executed: return true;
0
1319 else if (subjectIsRect
subjectIsRectDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1320 return
never executed: return clipPath.intersects(r1);
clipPath.intersects(r1);
never executed: return clipPath.intersects(r1);
0
1321 else if (clipIsRect
clipIsRectDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1322 return
never executed: return subjectPath.intersects(r2);
subjectPath.intersects(r2);
never executed: return subjectPath.intersects(r2);
0
1323-
1324 QPathSegments a(subjectPath.elementCount());-
1325 a.setPath(subjectPath);-
1326 QPathSegments b(clipPath.elementCount());-
1327 b.setPath(clipPath);-
1328-
1329 QIntersectionFinder finder;-
1330 if (finder.hasIntersections(a, b)
finder.hasIntersections(a, b)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1331 return
never executed: return true;
true;
never executed: return true;
0
1332-
1333 for (int i = 0; i < clipPath.elementCount()
i < clipPath.elementCount()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
1334 if (clipPath.elementAt(i).type == QPainterPath::MoveToElement
clipPath.eleme...:MoveToElementDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
1335 const QPointF point = clipPath.elementAt(i);-
1336 if (r1.contains(point)
r1.contains(point)Description
TRUEnever evaluated
FALSEnever evaluated
&& subjectPath.contains(point)
subjectPath.contains(point)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1337 return
never executed: return true;
true;
never executed: return true;
0
1338 }
never executed: end of block
0
1339 }
never executed: end of block
0
1340-
1341 for (int i = 0; i < subjectPath.elementCount()
i < subjectPath.elementCount()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
1342 if (subjectPath.elementAt(i).type == QPainterPath::MoveToElement
subjectPath.el...:MoveToElementDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
1343 const QPointF point = subjectPath.elementAt(i);-
1344 if (r2.contains(point)
r2.contains(point)Description
TRUEnever evaluated
FALSEnever evaluated
&& clipPath.contains(point)
clipPath.contains(point)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1345 return
never executed: return true;
true;
never executed: return true;
0
1346 }
never executed: end of block
0
1347 }
never executed: end of block
0
1348-
1349 return
never executed: return false;
false;
never executed: return false;
0
1350}-
1351-
1352bool QPathClipper::contains()-
1353{-
1354 if (subjectPath == clipPath
subjectPath == clipPathDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1355 return
never executed: return false;
false;
never executed: return false;
0
1356-
1357 QRectF r1 = subjectPath.controlPointRect();-
1358 QRectF r2 = clipPath.controlPointRect();-
1359 if (qMax(r1.x(), r2.x()) > qMin(r1.x() + r1.width(), r2.x() + r2.width())
qMax(r1.x(), r... + r2.width())Description
TRUEnever evaluated
FALSEnever evaluated
||
0
1360 qMax(r1.y(), r2.y()) > qMin(r1.y() + r1.height(), r2.y() + r2.height())
qMax(r1.y(), r...+ r2.height())Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
1361-
1362 return
never executed: return false;
false;
never executed: return false;
0
1363 }-
1364-
1365 bool clipIsRect = pathToRect(clipPath);-
1366 if (clipIsRect
clipIsRectDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1367 return
never executed: return subjectPath.contains(r2);
subjectPath.contains(r2);
never executed: return subjectPath.contains(r2);
0
1368-
1369 QPathSegments a(subjectPath.elementCount());-
1370 a.setPath(subjectPath);-
1371 QPathSegments b(clipPath.elementCount());-
1372 b.setPath(clipPath);-
1373-
1374 QIntersectionFinder finder;-
1375 if (finder.hasIntersections(a, b)
finder.hasIntersections(a, b)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1376 return
never executed: return false;
false;
never executed: return false;
0
1377-
1378 for (int i = 0; i < clipPath.elementCount()
i < clipPath.elementCount()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
1379 if (clipPath.elementAt(i).type == QPainterPath::MoveToElement
clipPath.eleme...:MoveToElementDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
1380 const QPointF point = clipPath.elementAt(i);-
1381 if (!r1.contains(point)
!r1.contains(point)Description
TRUEnever evaluated
FALSEnever evaluated
|| !subjectPath.contains(point)
!subjectPath.contains(point)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1382 return
never executed: return false;
false;
never executed: return false;
0
1383 }
never executed: end of block
0
1384 }
never executed: end of block
0
1385-
1386 return
never executed: return true;
true;
never executed: return true;
0
1387}-
1388-
1389QPathClipper::QPathClipper(const QPainterPath &subject,-
1390 const QPainterPath &clip)-
1391 : subjectPath(subject)-
1392 , clipPath(clip)-
1393{-
1394 aMask = subjectPath.fillRule() == Qt::WindingFill
subjectPath.fi...t::WindingFillDescription
TRUEnever evaluated
FALSEnever evaluated
? ~0x0 : 0x1;
0
1395 bMask = clipPath.fillRule() == Qt::WindingFill
clipPath.fillR...t::WindingFillDescription
TRUEnever evaluated
FALSEnever evaluated
? ~0x0 : 0x1;
0
1396}
never executed: end of block
0
1397-
1398template <typename Iterator, typename Equality>-
1399Iterator qRemoveDuplicates(Iterator begin, Iterator end, Equality eq)-
1400{-
1401 if (begin == end
begin == endDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1402 return
never executed: return end;
end;
never executed: return end;
0
1403-
1404 Iterator last = begin;-
1405 ++begin;-
1406 Iterator insert = begin;-
1407 for (Iterator it = begin; it != end
it != endDescription
TRUEnever evaluated
FALSEnever evaluated
; ++it) {
0
1408 if (!eq(*it, *last)
!eq(*it, *last)Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
1409 *insert++ = *it;-
1410 last = it;-
1411 }
never executed: end of block
0
1412 }
never executed: end of block
0
1413-
1414 return
never executed: return insert;
insert;
never executed: return insert;
0
1415}-
1416-
1417static void clear(QWingedEdge& list, int edge, QPathEdge::Traversal traversal)-
1418{-
1419 QWingedEdge::TraversalStatus status;-
1420 status.edge = edge;-
1421 status.traversal = traversal;-
1422 status.direction = QPathEdge::Forward;-
1423-
1424 do {-
1425 if (status.traversal == QPathEdge::LeftTraversal
status.travers...:LeftTraversalDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1426 list.edge(status.edge)->flag |= 1;
never executed: list.edge(status.edge)->flag |= 1;
0
1427 else-
1428 list.edge(status.edge)->flag |= 2;
never executed: list.edge(status.edge)->flag |= 2;
0
1429-
1430 status = list.next(status);-
1431 }
never executed: end of block
while (status.edge != edge
status.edge != edgeDescription
TRUEnever evaluated
FALSEnever evaluated
);
0
1432}
never executed: end of block
0
1433-
1434template <typename InputIterator>-
1435InputIterator qFuzzyFind(InputIterator first, InputIterator last, qreal val)-
1436{-
1437 while (first != last
first != lastDescription
TRUEnever evaluated
FALSEnever evaluated
&& !::qFuzzyCompare(qreal(*first), qreal(val))
!::qFuzzyCompa...), qreal(val))Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1438 ++
never executed: ++first;
first;
never executed: ++first;
0
1439 return
never executed: return first;
first;
never executed: return first;
0
1440}-
1441-
1442static bool fuzzyCompare(qreal a, qreal b)-
1443{-
1444 return
never executed: return qFuzzyCompare(a, b);
qFuzzyCompare(a, b);
never executed: return qFuzzyCompare(a, b);
0
1445}-
1446-
1447bool QPathClipper::pathToRect(const QPainterPath &path, QRectF *rect)-
1448{-
1449 if (path.elementCount() != 5
path.elementCount() != 5Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1450 return
never executed: return false;
false;
never executed: return false;
0
1451-
1452 const bool mightBeRect = path.elementAt(0).isMoveTo()
path.elementAt(0).isMoveTo()Description
TRUEnever evaluated
FALSEnever evaluated
0
1453 && path.elementAt(1).isLineTo()
path.elementAt(1).isLineTo()Description
TRUEnever evaluated
FALSEnever evaluated
0
1454 && path.elementAt(2).isLineTo()
path.elementAt(2).isLineTo()Description
TRUEnever evaluated
FALSEnever evaluated
0
1455 && path.elementAt(3).isLineTo()
path.elementAt(3).isLineTo()Description
TRUEnever evaluated
FALSEnever evaluated
0
1456 && path.elementAt(4).isLineTo()
path.elementAt(4).isLineTo()Description
TRUEnever evaluated
FALSEnever evaluated
;
0
1457-
1458 if (!mightBeRect
!mightBeRectDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1459 return
never executed: return false;
false;
never executed: return false;
0
1460-
1461 const qreal x1 = path.elementAt(0).x;-
1462 const qreal y1 = path.elementAt(0).y;-
1463-
1464 const qreal x2 = path.elementAt(1).x;-
1465 const qreal y2 = path.elementAt(2).y;-
1466-
1467 if (path.elementAt(1).y != y1
path.elementAt(1).y != y1Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1468 return
never executed: return false;
false;
never executed: return false;
0
1469-
1470 if (path.elementAt(2).x != x2
path.elementAt(2).x != x2Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1471 return
never executed: return false;
false;
never executed: return false;
0
1472-
1473 if (path.elementAt(3).x != x1
path.elementAt(3).x != x1Description
TRUEnever evaluated
FALSEnever evaluated
|| path.elementAt(3).y != y2
path.elementAt(3).y != y2Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1474 return
never executed: return false;
false;
never executed: return false;
0
1475-
1476 if (path.elementAt(4).x != x1
path.elementAt(4).x != x1Description
TRUEnever evaluated
FALSEnever evaluated
|| path.elementAt(4).y != y1
path.elementAt(4).y != y1Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1477 return
never executed: return false;
false;
never executed: return false;
0
1478-
1479 if (rect
rectDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1480 rect->setCoords(x1, y1, x2, y2);
never executed: rect->setCoords(x1, y1, x2, y2);
0
1481-
1482 return
never executed: return true;
true;
never executed: return true;
0
1483}-
1484-
1485-
1486QPainterPath QPathClipper::clip(Operation operation)-
1487{-
1488 op = operation;-
1489-
1490 if (op != Simplify
op != SimplifyDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
1491 if (subjectPath == clipPath
subjectPath == clipPathDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1492 return
never executed: return op == BoolSub ? QPainterPath() : subjectPath;
op == BoolSub ? QPainterPath() : subjectPath;
never executed: return op == BoolSub ? QPainterPath() : subjectPath;
0
1493-
1494 bool subjectIsRect = pathToRect(subjectPath, 0);-
1495 bool clipIsRect = pathToRect(clipPath, 0);-
1496-
1497 const QRectF clipBounds = clipPath.boundingRect();-
1498 const QRectF subjectBounds = subjectPath.boundingRect();-
1499-
1500 if (!clipBounds.intersects(subjectBounds)
!clipBounds.in...subjectBounds)Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
1501 switch (op) {-
1502 case
never executed: case BoolSub:
BoolSub:
never executed: case BoolSub:
0
1503 return
never executed: return subjectPath;
subjectPath;
never executed: return subjectPath;
0
1504 case
never executed: case BoolAnd:
BoolAnd:
never executed: case BoolAnd:
0
1505 return
never executed: return QPainterPath();
QPainterPath();
never executed: return QPainterPath();
0
1506 case
never executed: case BoolOr:
BoolOr:
never executed: case BoolOr:
{
0
1507 QPainterPath result = subjectPath;-
1508 if (result.fillRule() == clipPath.fillRule()
result.fillRul...ath.fillRule()Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
1509 result.addPath(clipPath);-
1510 }
never executed: end of block
else if (result.fillRule() == Qt::WindingFill
result.fillRul...t::WindingFillDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
1511 result = result.simplified();-
1512 result.addPath(clipPath);-
1513 }
never executed: end of block
else {
0
1514 result.addPath(clipPath.simplified());-
1515 }
never executed: end of block
0
1516 return
never executed: return result;
result;
never executed: return result;
0
1517 }-
1518 default
never executed: default:
:
never executed: default:
0
1519 break;
never executed: break;
0
1520 }-
1521 }-
1522-
1523 if (clipBounds.contains(subjectBounds)
clipBounds.con...subjectBounds)Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
1524 if (clipIsRect
clipIsRectDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
1525 switch (op) {-
1526 case
never executed: case BoolSub:
BoolSub:
never executed: case BoolSub:
0
1527 return
never executed: return QPainterPath();
QPainterPath();
never executed: return QPainterPath();
0
1528 case
never executed: case BoolAnd:
BoolAnd:
never executed: case BoolAnd:
0
1529 return
never executed: return subjectPath;
subjectPath;
never executed: return subjectPath;
0
1530 case
never executed: case BoolOr:
BoolOr:
never executed: case BoolOr:
0
1531 return
never executed: return clipPath;
clipPath;
never executed: return clipPath;
0
1532 default
never executed: default:
:
never executed: default:
0
1533 break;
never executed: break;
0
1534 }-
1535 }-
1536 }
never executed: end of block
else if (subjectBounds.contains(clipBounds)
subjectBounds....ns(clipBounds)Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
1537 if (subjectIsRect
subjectIsRectDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
1538 switch (op) {-
1539 case
never executed: case BoolSub:
BoolSub:
never executed: case BoolSub:
0
1540 if (clipPath.fillRule() == Qt::OddEvenFill
clipPath.fillR...t::OddEvenFillDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
1541 QPainterPath result = clipPath;-
1542 result.addRect(subjectBounds);-
1543 return
never executed: return result;
result;
never executed: return result;
0
1544 } else {-
1545 QPainterPath result = clipPath.simplified();-
1546 result.addRect(subjectBounds);-
1547 return
never executed: return result;
result;
never executed: return result;
0
1548 }-
1549 case
never executed: case BoolAnd:
BoolAnd:
never executed: case BoolAnd:
0
1550 return
never executed: return clipPath;
clipPath;
never executed: return clipPath;
0
1551 case
never executed: case BoolOr:
BoolOr:
never executed: case BoolOr:
0
1552 return
never executed: return subjectPath;
subjectPath;
never executed: return subjectPath;
0
1553 default
never executed: default:
:
never executed: default:
0
1554 break;
never executed: break;
0
1555 }-
1556 }-
1557 }
never executed: end of block
0
1558-
1559 if (op == BoolAnd
op == BoolAndDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
1560 if (subjectIsRect
subjectIsRectDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1561 return
never executed: return intersect(clipPath, subjectBounds);
intersect(clipPath, subjectBounds);
never executed: return intersect(clipPath, subjectBounds);
0
1562 else if (clipIsRect
clipIsRectDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1563 return
never executed: return intersect(subjectPath, clipBounds);
intersect(subjectPath, clipBounds);
never executed: return intersect(subjectPath, clipBounds);
0
1564 }
never executed: end of block
0
1565 }
never executed: end of block
0
1566-
1567 QWingedEdge list(subjectPath, clipPath);-
1568-
1569 doClip(list, ClipMode);-
1570-
1571 QPainterPath path = list.toPath();-
1572 return
never executed: return path;
path;
never executed: return path;
0
1573}-
1574-
1575bool QPathClipper::doClip(QWingedEdge &list, ClipperMode mode)-
1576{-
1577 QVector<qreal> y_coords;-
1578 y_coords.reserve(list.vertexCount());-
1579 for (int i = 0; i < list.vertexCount()
i < list.vertexCount()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i)
0
1580 y_coords << list.vertex(i)->y;
never executed: y_coords << list.vertex(i)->y;
0
1581-
1582 std::sort(y_coords.begin(), y_coords.end());-
1583 y_coords.resize(qRemoveDuplicates(y_coords.begin(), y_coords.end(), fuzzyCompare) - y_coords.begin());-
1584 bool found;-
1585 do {-
1586 found = false;-
1587 int index = 0;-
1588 qreal maxHeight = 0;-
1589 for (int i = 0; i < list.edgeCount()
i < list.edgeCount()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
1590 QPathEdge *edge = list.edge(i);-
1591-
1592-
1593 if ((
(edge->flag & 0x3) == 0x3Description
TRUEnever evaluated
FALSEnever evaluated
edge->flag & 0x3) == 0x3
(edge->flag & 0x3) == 0x3Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1594 continue;
never executed: continue;
0
1595-
1596 QPathVertex *a = list.vertex(edge->first);-
1597 QPathVertex *b = list.vertex(edge->second);-
1598-
1599 if (qFuzzyCompare(a->y, b->y)
qFuzzyCompare(a->y, b->y)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1600 continue;
never executed: continue;
0
1601-
1602 found = true;-
1603-
1604 qreal height = qAbs(a->y - b->y);-
1605 if (height > maxHeight
height > maxHeightDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
1606 index = i;-
1607 maxHeight = height;-
1608 }
never executed: end of block
0
1609 }
never executed: end of block
0
1610-
1611 if (found
foundDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
1612 QPathEdge *edge = list.edge(index);-
1613-
1614 QPathVertex *a = list.vertex(edge->first);-
1615 QPathVertex *b = list.vertex(edge->second);-
1616-
1617-
1618 const int first = qFuzzyFind(y_coords.cbegin(), y_coords.cend(), qMin(a->y, b->y)) - y_coords.cbegin();-
1619 const int last = qFuzzyFind(y_coords.cbegin() + first, y_coords.cend(), qMax(a->y, b->y)) - y_coords.cbegin();-
1620-
1621 ((!(first < y_coords.size() - 1)) ? qt_assert("first < y_coords.size() - 1",__FILE__,1692) : qt_noop());-
1622 ((!(last < y_coords.size())) ? qt_assert("last < y_coords.size()",__FILE__,1693) : qt_noop());-
1623-
1624 qreal biggestGap = y_coords.at(first + 1) - y_coords.at(first);-
1625 int bestIdx = first;-
1626 for (int i = first + 1; i < last
i < lastDescription
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
1627 qreal gap = y_coords.at(i + 1) - y_coords.at(i);-
1628-
1629 if (gap > biggestGap
gap > biggestGapDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
1630 bestIdx = i;-
1631 biggestGap = gap;-
1632 }
never executed: end of block
0
1633 }
never executed: end of block
0
1634 const qreal bestY = 0.5 * (y_coords.at(bestIdx) + y_coords.at(bestIdx + 1));-
1635-
1636-
1637-
1638-
1639-
1640 if (handleCrossingEdges(list, bestY, mode)
handleCrossing..., bestY, mode)Description
TRUEnever evaluated
FALSEnever evaluated
&& mode == CheckMode
mode == CheckModeDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1641 return
never executed: return true;
true;
never executed: return true;
0
1642-
1643 edge->flag |= 0x3;-
1644 }
never executed: end of block
0
1645 }
never executed: end of block
while (found
foundDescription
TRUEnever evaluated
FALSEnever evaluated
);
0
1646-
1647 if (mode == ClipMode
mode == ClipModeDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1648 list.simplify();
never executed: list.simplify();
0
1649-
1650 return
never executed: return false;
false;
never executed: return false;
0
1651}-
1652-
1653static void traverse(QWingedEdge &list, int edge, QPathEdge::Traversal traversal)-
1654{-
1655 QWingedEdge::TraversalStatus status;-
1656 status.edge = edge;-
1657 status.traversal = traversal;-
1658 status.direction = QPathEdge::Forward;-
1659-
1660 do {-
1661 int flag = status.traversal == QPathEdge::LeftTraversal
status.travers...:LeftTraversalDescription
TRUEnever evaluated
FALSEnever evaluated
? 1 : 2;
0
1662-
1663 QPathEdge *ep = list.edge(status.edge);-
1664-
1665 ep->flag |= (flag | (flag << 4));-
1666-
1667-
1668-
1669-
1670-
1671 status = list.next(status);-
1672 }
never executed: end of block
while (status.edge != edge
status.edge != edgeDescription
TRUEnever evaluated
FALSEnever evaluated
);
0
1673}
never executed: end of block
0
1674-
1675struct QCrossingEdge-
1676{-
1677 int edge;-
1678 qreal x;-
1679-
1680 bool operator<(const QCrossingEdge &edge) const-
1681 {-
1682 return
never executed: return x < edge.x;
x < edge.x;
never executed: return x < edge.x;
0
1683 }-
1684};-
1685template<> class QTypeInfo<QCrossingEdge > { public: enum { isComplex = (((Q_PRIMITIVE_TYPE) & Q_PRIMITIVE_TYPE) == 0), isStatic = (((Q_PRIMITIVE_TYPE) & (Q_MOVABLE_TYPE | Q_PRIMITIVE_TYPE)) == 0), isRelocatable = !isStatic || ((Q_PRIMITIVE_TYPE) & Q_RELOCATABLE_TYPE), isLarge = (sizeof(QCrossingEdge)>sizeof(void*)), isPointer = false, isIntegral = QtPrivate::is_integral< QCrossingEdge >::value, isDummy = (((Q_PRIMITIVE_TYPE) & Q_DUMMY_TYPE) != 0), sizeOf = sizeof(QCrossingEdge) }; static inline const char *name() { return "QCrossingEdge"; } };-
1686-
1687static bool bool_op(bool a, bool b, QPathClipper::Operation op)-
1688{-
1689 switch (op) {-
1690 case
never executed: case QPathClipper::BoolAnd:
QPathClipper::BoolAnd:
never executed: case QPathClipper::BoolAnd:
0
1691 return
never executed: return a && b;
a && b;
never executed: return a && b;
0
1692 case
never executed: case QPathClipper::BoolOr:
QPathClipper::BoolOr:
never executed: case QPathClipper::BoolOr:
0
1693 case
never executed: case QPathClipper::Simplify:
QPathClipper::Simplify:
never executed: case QPathClipper::Simplify:
0
1694 return
never executed: return a || b;
a || b;
never executed: return a || b;
0
1695 case
never executed: case QPathClipper::BoolSub:
QPathClipper::BoolSub:
never executed: case QPathClipper::BoolSub:
0
1696 return
never executed: return a && !b;
a && !b;
never executed: return a && !b;
0
1697 default
never executed: default:
:
never executed: default:
0
1698 ((!(false)) ? qt_assert("false",__FILE__,1769) : qt_noop());-
1699 return
never executed: return false;
false;
never executed: return false;
0
1700 }-
1701}-
1702-
1703bool QWingedEdge::isInside(qreal x, qreal y) const-
1704{-
1705 int winding = 0;-
1706 for (int i = 0; i < edgeCount()
i < edgeCount()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
1707 const QPathEdge *ep = edge(i);-
1708-
1709-
1710 int w = ((ep->flag >> 4) ^ (ep->flag >> 5)) & 1;-
1711-
1712 if (!w
!wDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1713 continue;
never executed: continue;
0
1714-
1715 QPointF a = *vertex(ep->first);-
1716 QPointF b = *vertex(ep->second);-
1717-
1718 if ((a.y() < y
a.y() < yDescription
TRUEnever evaluated
FALSEnever evaluated
&& b.y() > y
b.y() > yDescription
TRUEnever evaluated
FALSEnever evaluated
) || (a.y() > y
a.y() > yDescription
TRUEnever evaluated
FALSEnever evaluated
&& b.y() < y
b.y() < yDescription
TRUEnever evaluated
FALSEnever evaluated
)) {
0
1719 qreal intersectionX = a.x() + (b.x() - a.x()) * (y - a.y()) / (b.y() - a.y());-
1720-
1721 if (intersectionX > x
intersectionX > xDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1722 winding += w;
never executed: winding += w;
0
1723 }
never executed: end of block
0
1724 }
never executed: end of block
0
1725-
1726 return
never executed: return winding & 1;
winding & 1;
never executed: return winding & 1;
0
1727}-
1728-
1729static QVector<QCrossingEdge> findCrossings(const QWingedEdge &list, qreal y)-
1730{-
1731 QVector<QCrossingEdge> crossings;-
1732 for (int i = 0; i < list.edgeCount()
i < list.edgeCount()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
1733 const QPathEdge *edge = list.edge(i);-
1734 QPointF a = *list.vertex(edge->first);-
1735 QPointF b = *list.vertex(edge->second);-
1736-
1737 if ((a.y() < y
a.y() < yDescription
TRUEnever evaluated
FALSEnever evaluated
&& b.y() > y
b.y() > yDescription
TRUEnever evaluated
FALSEnever evaluated
) || (a.y() > y
a.y() > yDescription
TRUEnever evaluated
FALSEnever evaluated
&& b.y() < y
b.y() < yDescription
TRUEnever evaluated
FALSEnever evaluated
)) {
0
1738 const qreal intersection = a.x() + (b.x() - a.x()) * (y - a.y()) / (b.y() - a.y());-
1739 const QCrossingEdge edge = { i, intersection };-
1740 crossings << edge;-
1741 }
never executed: end of block
0
1742 }
never executed: end of block
0
1743 return
never executed: return crossings;
crossings;
never executed: return crossings;
0
1744}-
1745-
1746bool QPathClipper::handleCrossingEdges(QWingedEdge &list, qreal y, ClipperMode mode)-
1747{-
1748 QVector<QCrossingEdge> crossings = findCrossings(list, y);-
1749-
1750 ((!(!crossings.isEmpty())) ? qt_assert("!crossings.isEmpty()",__FILE__,1821) : qt_noop());-
1751 std::sort(crossings.begin(), crossings.end());-
1752-
1753 int windingA = 0;-
1754 int windingB = 0;-
1755-
1756 int windingD = 0;-
1757-
1758-
1759-
1760-
1761 for (int i = 0; i < crossings.size() - 1
i < crossings.size() - 1Description
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
1762 int ei = crossings.at(i).edge;-
1763 const QPathEdge *edge = list.edge(ei);-
1764-
1765 windingA += edge->windingA;-
1766 windingB += edge->windingB;-
1767-
1768 const bool hasLeft = (edge->flag >> 4) & 1;-
1769 const bool hasRight = (edge->flag >> 4) & 2;-
1770-
1771 windingD += hasLeft ^ hasRight;-
1772-
1773 const bool inA = (windingA & aMask) != 0;-
1774 const bool inB = (windingB & bMask) != 0;-
1775 const bool inD = (windingD & 0x1) != 0;-
1776-
1777 const bool inside = bool_op(inA, inB, op);-
1778 const bool add = inD ^ inside;-
1779-
1780-
1781-
1782-
1783-
1784 if (add
addDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
1785 if (mode == CheckMode
mode == CheckModeDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1786 return
never executed: return true;
true;
never executed: return true;
0
1787-
1788 qreal y0 = list.vertex(edge->first)->y;-
1789 qreal y1 = list.vertex(edge->second)->y;-
1790-
1791 if (y0 < y1
y0 < y1Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
1792 if (!(edge->flag & 1)
!(edge->flag & 1)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1793 traverse(list, ei, QPathEdge::LeftTraversal);
never executed: traverse(list, ei, QPathEdge::LeftTraversal);
0
1794-
1795 if (!(edge->flag & 2)
!(edge->flag & 2)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1796 clear(list, ei, QPathEdge::RightTraversal);
never executed: clear(list, ei, QPathEdge::RightTraversal);
0
1797 }
never executed: end of block
else {
0
1798 if (!(edge->flag & 1)
!(edge->flag & 1)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1799 clear(list, ei, QPathEdge::LeftTraversal);
never executed: clear(list, ei, QPathEdge::LeftTraversal);
0
1800-
1801 if (!(edge->flag & 2)
!(edge->flag & 2)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1802 traverse(list, ei, QPathEdge::RightTraversal);
never executed: traverse(list, ei, QPathEdge::RightTraversal);
0
1803 }
never executed: end of block
0
1804-
1805 ++windingD;-
1806 }
never executed: end of block
else {
0
1807 if (!(edge->flag & 1)
!(edge->flag & 1)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1808 clear(list, ei, QPathEdge::LeftTraversal);
never executed: clear(list, ei, QPathEdge::LeftTraversal);
0
1809-
1810 if (!(edge->flag & 2)
!(edge->flag & 2)Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1811 clear(list, ei, QPathEdge::RightTraversal);
never executed: clear(list, ei, QPathEdge::RightTraversal);
0
1812 }
never executed: end of block
0
1813 }-
1814-
1815 return
never executed: return false;
false;
never executed: return false;
0
1816}-
1817-
1818namespace {-
1819-
1820QVector<QPainterPath> toSubpaths(const QPainterPath &path)-
1821{-
1822-
1823 QVector<QPainterPath> subpaths;-
1824 if (path.isEmpty()
path.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1825 return
never executed: return subpaths;
subpaths;
never executed: return subpaths;
0
1826-
1827 QPainterPath current;-
1828 for (int i = 0; i < path.elementCount()
i < path.elementCount()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
1829 const QPainterPath::Element &e = path.elementAt(i);-
1830 switch (e.type) {-
1831 case
never executed: case QPainterPath::MoveToElement:
QPainterPath::MoveToElement:
never executed: case QPainterPath::MoveToElement:
0
1832 if (current.elementCount() > 1
current.elementCount() > 1Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1833 subpaths += current;
never executed: subpaths += current;
0
1834 current = QPainterPath();-
1835 current.moveTo(e);-
1836 break;
never executed: break;
0
1837 case
never executed: case QPainterPath::LineToElement:
QPainterPath::LineToElement:
never executed: case QPainterPath::LineToElement:
0
1838 current.lineTo(e);-
1839 break;
never executed: break;
0
1840 case
never executed: case QPainterPath::CurveToElement:
QPainterPath::CurveToElement:
never executed: case QPainterPath::CurveToElement:
{
0
1841 current.cubicTo(e, path.elementAt(i + 1), path.elementAt(i + 2));-
1842 i+=2;-
1843 break;
never executed: break;
0
1844 }-
1845 case
never executed: case QPainterPath::CurveToDataElement:
QPainterPath::CurveToDataElement:
never executed: case QPainterPath::CurveToDataElement:
0
1846 ((!(!"toSubpaths(), bad element type")) ? qt_assert("!\"toSubpaths(), bad element type\"",__FILE__,1917) : qt_noop());-
1847 break;
never executed: break;
0
1848 }-
1849 }
never executed: end of block
0
1850-
1851 if (current.elementCount() > 1
current.elementCount() > 1Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1852 subpaths << current;
never executed: subpaths << current;
0
1853-
1854 return
never executed: return subpaths;
subpaths;
never executed: return subpaths;
0
1855}-
1856-
1857enum Edge-
1858{-
1859 Left, Top, Right, Bottom-
1860};-
1861-
1862static bool isVertical(Edge edge)-
1863{-
1864 return
never executed: return edge == Left || edge == Right;
edge == Left || edge == Right;
never executed: return edge == Left || edge == Right;
0
1865}-
1866-
1867template <Edge edge>-
1868bool compare(const QPointF &p, qreal t)-
1869{-
1870 switch (edge)-
1871 {-
1872 case
never executed: case Left:
Left:
never executed: case Left:
0
1873 return
never executed: return p.x() < t;
p.x() < t;
never executed: return p.x() < t;
0
1874 case
never executed: case Right:
Right:
never executed: case Right:
0
1875 return
never executed: return p.x() > t;
p.x() > t;
never executed: return p.x() > t;
0
1876 case
never executed: case Top:
Top:
never executed: case Top:
0
1877 return
never executed: return p.y() < t;
p.y() < t;
never executed: return p.y() < t;
0
1878 default
never executed: default:
:
never executed: default:
0
1879 return
never executed: return p.y() > t;
p.y() > t;
never executed: return p.y() > t;
0
1880 }-
1881}-
1882-
1883template <Edge edge>-
1884QPointF intersectLine(const QPointF &a, const QPointF &b, qreal t)-
1885{-
1886 QLineF line(a, b);-
1887 switch (edge) {-
1888 case
never executed: case Left:
Left:
never executed: case Left:
0
1889 case
never executed: case Right:
Right:
never executed: case Right:
0
1890 return
never executed: return line.pointAt((t - a.x()) / (b.x() - a.x()));
line.pointAt((t - a.x()) / (b.x() - a.x()));
never executed: return line.pointAt((t - a.x()) / (b.x() - a.x()));
0
1891 default
never executed: default:
:
never executed: default:
0
1892 return
never executed: return line.pointAt((t - a.y()) / (b.y() - a.y()));
line.pointAt((t - a.y()) / (b.y() - a.y()));
never executed: return line.pointAt((t - a.y()) / (b.y() - a.y()));
0
1893 }-
1894}-
1895-
1896void addLine(QPainterPath &path, const QLineF &line)-
1897{-
1898 if (path.elementCount() > 0
path.elementCount() > 0Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1899 path.lineTo(line.p1());
never executed: path.lineTo(line.p1());
0
1900 else-
1901 path.moveTo(line.p1());
never executed: path.moveTo(line.p1());
0
1902-
1903 path.lineTo(line.p2());-
1904}
never executed: end of block
0
1905-
1906template <Edge edge>-
1907void clipLine(const QPointF &a, const QPointF &b, qreal t, QPainterPath &result)-
1908{-
1909 bool outA = compare<edge>(a, t);-
1910 bool outB = compare<edge>(b, t);-
1911 if (outA
outADescription
TRUEnever evaluated
FALSEnever evaluated
&& outB
outBDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1912 return;
never executed: return;
0
1913-
1914 if (outA
outADescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1915 addLine(result, QLineF(intersectLine<edge>(a, b, t), b));
never executed: addLine(result, QLineF(intersectLine<edge>(a, b, t), b));
0
1916 else if(outB
outBDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1917 addLine(result, QLineF(a, intersectLine<edge>(a, b, t)));
never executed: addLine(result, QLineF(a, intersectLine<edge>(a, b, t)));
0
1918 else-
1919 addLine(result, QLineF(a, b));
never executed: addLine(result, QLineF(a, b));
0
1920}-
1921-
1922void addBezier(QPainterPath &path, const QBezier &bezier)-
1923{-
1924 if (path.elementCount() > 0
path.elementCount() > 0Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1925 path.lineTo(bezier.pt1());
never executed: path.lineTo(bezier.pt1());
0
1926 else-
1927 path.moveTo(bezier.pt1());
never executed: path.moveTo(bezier.pt1());
0
1928-
1929 path.cubicTo(bezier.pt2(), bezier.pt3(), bezier.pt4());-
1930}
never executed: end of block
0
1931-
1932template <Edge edge>-
1933void clipBezier(const QPointF &a, const QPointF &b, const QPointF &c, const QPointF &d, qreal t, QPainterPath &result)-
1934{-
1935 QBezier bezier = QBezier::fromPoints(a, b, c, d);-
1936-
1937 bool outA = compare<edge>(a, t);-
1938 bool outB = compare<edge>(b, t);-
1939 bool outC = compare<edge>(c, t);-
1940 bool outD = compare<edge>(d, t);-
1941-
1942 int outCount = int(outA) + int(outB) + int(outC) + int(outD);-
1943-
1944 if (outCount == 4
outCount == 4Description
TRUEnever evaluated
FALSEnever evaluated
)
0
1945 return;
never executed: return;
0
1946-
1947 if (outCount == 0
outCount == 0Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
1948 addBezier(result, bezier);-
1949 return;
never executed: return;
0
1950 }-
1951-
1952 QTransform flip = isVertical(edge)
isVertical(edge)Description
TRUEnever evaluated
FALSEnever evaluated
? QTransform(0, 1, 1, 0, 0, 0) : QTransform();
0
1953 QBezier unflipped = bezier;-
1954 QBezier flipped = bezier.mapBy(flip);-
1955-
1956 qreal t0 = 0, t1 = 1;-
1957 int stationary = flipped.stationaryYPoints(t0, t1);-
1958-
1959 qreal segments[4];-
1960 QPointF points[4];-
1961 points[0] = unflipped.pt1();-
1962 segments[0] = 0;-
1963-
1964 int segmentCount = 0;-
1965 if (stationary > 0
stationary > 0Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
1966 ++segmentCount;-
1967 segments[segmentCount] = t0;-
1968 points[segmentCount] = unflipped.pointAt(t0);-
1969 }
never executed: end of block
0
1970 if (stationary > 1
stationary > 1Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
1971 ++segmentCount;-
1972 segments[segmentCount] = t1;-
1973 points[segmentCount] = unflipped.pointAt(t1);-
1974 }
never executed: end of block
0
1975 ++segmentCount;-
1976 segments[segmentCount] = 1;-
1977 points[segmentCount] = unflipped.pt4();-
1978-
1979 qreal lastIntersection = 0;-
1980 for (int i = 0; i < segmentCount
i < segmentCountDescription
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
1981 outA = compare<edge>(points[i], t);-
1982 outB = compare<edge>(points[i+1], t);-
1983-
1984 if (outA != outB
outA != outBDescription
TRUEnever evaluated
FALSEnever evaluated
) {
0
1985 qreal intersection = flipped.tForY(segments[i], segments[i+1], t);-
1986-
1987 if (outB
outBDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1988 addBezier(result, unflipped.getSubRange(lastIntersection, intersection));
never executed: addBezier(result, unflipped.getSubRange(lastIntersection, intersection));
0
1989-
1990 lastIntersection = intersection;-
1991 }
never executed: end of block
0
1992 }
never executed: end of block
0
1993-
1994 if (!outB
!outBDescription
TRUEnever evaluated
FALSEnever evaluated
)
0
1995 addBezier(result, unflipped.getSubRange(lastIntersection, 1));
never executed: addBezier(result, unflipped.getSubRange(lastIntersection, 1));
0
1996}
never executed: end of block
0
1997-
1998-
1999template <Edge edge>-
2000QPainterPath clip(const QPainterPath &path, qreal t)-
2001{-
2002 QPainterPath result;-
2003 for (int i = 1; i < path.elementCount()
i < path.elementCount()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
2004 const QPainterPath::Element &element = path.elementAt(i);-
2005 ((!(!element.isMoveTo())) ? qt_assert("!element.isMoveTo()",__FILE__,2076) : qt_noop());-
2006 if (element.isLineTo()
element.isLineTo()Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
2007 clipLine<edge>(path.elementAt(i-1), path.elementAt(i), t, result);-
2008 }
never executed: end of block
else {
0
2009 clipBezier<edge>(path.elementAt(i-1), path.elementAt(i), path.elementAt(i+1), path.elementAt(i+2), t, result);-
2010 i += 2;-
2011 }
never executed: end of block
0
2012 }-
2013-
2014 int last = path.elementCount() - 1;-
2015 if (QPointF(path.elementAt(last)) != QPointF(path.elementAt(0))
QPointF(path.e....elementAt(0))Description
TRUEnever evaluated
FALSEnever evaluated
)
0
2016 clipLine<edge>(path.elementAt(last), path.elementAt(0), t, result);
never executed: clipLine<edge>(path.elementAt(last), path.elementAt(0), t, result);
0
2017-
2018 return
never executed: return result;
result;
never executed: return result;
0
2019}-
2020-
2021QPainterPath intersectPath(const QPainterPath &path, const QRectF &rect)-
2022{-
2023 QVector<QPainterPath> subpaths = toSubpaths(path);-
2024-
2025 QPainterPath result;-
2026 result.setFillRule(path.fillRule());-
2027 for (int i = 0; i < subpaths.size()
i < subpaths.size()Description
TRUEnever evaluated
FALSEnever evaluated
; ++i) {
0
2028 QPainterPath subPath = subpaths.at(i);-
2029 QRectF bounds = subPath.boundingRect();-
2030 if (bounds.intersects(rect)
bounds.intersects(rect)Description
TRUEnever evaluated
FALSEnever evaluated
) {
0
2031 if (bounds.left() < rect.left()
bounds.left() < rect.left()Description
TRUEnever evaluated
FALSEnever evaluated
)
0
2032 subPath = clip<Left>(subPath, rect.left());
never executed: subPath = clip<Left>(subPath, rect.left());
0
2033 if (bounds.right() > rect.right()
bounds.right() > rect.right()Description
TRUEnever evaluated
FALSEnever evaluated
)
0
2034 subPath = clip<Right>(subPath, rect.right());
never executed: subPath = clip<Right>(subPath, rect.right());
0
2035-
2036 bounds = subPath.boundingRect();-
2037-
2038 if (bounds.top() < rect.top()
bounds.top() < rect.top()Description
TRUEnever evaluated
FALSEnever evaluated
)
0
2039 subPath = clip<Top>(subPath, rect.top());
never executed: subPath = clip<Top>(subPath, rect.top());
0
2040 if (bounds.bottom() > rect.bottom()
bounds.bottom(... rect.bottom()Description
TRUEnever evaluated
FALSEnever evaluated
)
0
2041 subPath = clip<Bottom>(subPath, rect.bottom());
never executed: subPath = clip<Bottom>(subPath, rect.bottom());
0
2042-
2043 if (subPath.elementCount() > 1
subPath.elementCount() > 1Description
TRUEnever evaluated
FALSEnever evaluated
)
0
2044 result.addPath(subPath);
never executed: result.addPath(subPath);
0
2045 }
never executed: end of block
0
2046 }
never executed: end of block
0
2047 return
never executed: return result;
result;
never executed: return result;
0
2048}-
2049-
2050}-
2051-
2052QPainterPath QPathClipper::intersect(const QPainterPath &path, const QRectF &rect)-
2053{-
2054 return
never executed: return intersectPath(path, rect);
intersectPath(path, rect);
never executed: return intersectPath(path, rect);
0
2055}-
2056-
2057-
Switch to Source codePreprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9