qpainterpath.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/painting/qpainterpath.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2015 The Qt Company Ltd.-
4** Contact: http://www.qt.io/licensing/-
5**-
6** This file is part of the QtGui module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL21$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see http://www.qt.io/terms-conditions. For further-
15** information use the contact form at http://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 2.1 or version 3 as published by the Free-
20** Software Foundation and appearing in the file LICENSE.LGPLv21 and-
21** LICENSE.LGPLv3 included in the packaging of this file. Please review the-
22** following information to ensure the GNU Lesser General Public License-
23** requirements will be met: https://www.gnu.org/licenses/lgpl.html and-
24** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.-
25**-
26** As a special exception, The Qt Company gives you certain additional-
27** rights. These rights are described in The Qt Company LGPL Exception-
28** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.-
29**-
30** $QT_END_LICENSE$-
31**-
32****************************************************************************/-
33-
34#include "qpainterpath.h"-
35#include "qpainterpath_p.h"-
36-
37#include <qbitmap.h>-
38#include <qdebug.h>-
39#include <qiodevice.h>-
40#include <qlist.h>-
41#include <qmatrix.h>-
42#include <qpen.h>-
43#include <qpolygon.h>-
44#include <qtextlayout.h>-
45#include <qvarlengtharray.h>-
46#include <qmath.h>-
47-
48#include <private/qbezier_p.h>-
49#include <private/qfontengine_p.h>-
50#include <private/qnumeric_p.h>-
51#include <private/qobject_p.h>-
52#include <private/qpathclipper_p.h>-
53#include <private/qstroker_p.h>-
54#include <private/qtextengine_p.h>-
55-
56#include <limits.h>-
57-
58#if 0-
59#include <performance.h>-
60#else-
61#define PM_INIT-
62#define PM_MEASURE(x)-
63#define PM_DISPLAY-
64#endif-
65-
66QT_BEGIN_NAMESPACE-
67-
68struct QPainterPathPrivateDeleter-
69{-
70 static inline void cleanup(QPainterPathPrivate *d)-
71 {-
72 // note - we must up-cast to QPainterPathData since QPainterPathPrivate-
73 // has a non-virtual destructor!-
74 if (d && !d->ref.deref())
dDescription
TRUEnever evaluated
FALSEnever evaluated
!d->ref.deref()Description
TRUEnever evaluated
FALSEnever evaluated
0
75 delete static_cast<QPainterPathData *>(d);
never executed: delete static_cast<QPainterPathData *>(d);
0
76 }
never executed: end of block
0
77};-
78-
79// This value is used to determine the length of control point vectors-
80// when approximating arc segments as curves. The factor is multiplied-
81// with the radius of the circle.-
82-
83// #define QPP_DEBUG-
84// #define QPP_STROKE_DEBUG-
85//#define QPP_FILLPOLYGONS_DEBUG-
86-
87QPainterPath qt_stroke_dash(const QPainterPath &path, qreal *dashes, int dashCount);-
88-
89void qt_find_ellipse_coords(const QRectF &r, qreal angle, qreal length,-
90 QPointF* startPoint, QPointF *endPoint)-
91{-
92 if (r.isNull()) {
r.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
93 if (startPoint)
startPointDescription
TRUEnever evaluated
FALSEnever evaluated
0
94 *startPoint = QPointF();
never executed: *startPoint = QPointF();
0
95 if (endPoint)
endPointDescription
TRUEnever evaluated
FALSEnever evaluated
0
96 *endPoint = QPointF();
never executed: *endPoint = QPointF();
0
97 return;
never executed: return;
0
98 }-
99-
100 qreal w2 = r.width() / 2;-
101 qreal h2 = r.height() / 2;-
102-
103 qreal angles[2] = { angle, angle + length };-
104 QPointF *points[2] = { startPoint, endPoint };-
105-
106 for (int i = 0; i < 2; ++i) {
i < 2Description
TRUEnever evaluated
FALSEnever evaluated
0
107 if (!points[i])
!points[i]Description
TRUEnever evaluated
FALSEnever evaluated
0
108 continue;
never executed: continue;
0
109-
110 qreal theta = angles[i] - 360 * qFloor(angles[i] / 360);-
111 qreal t = theta / 90;-
112 // truncate-
113 int quadrant = int(t);-
114 t -= quadrant;-
115-
116 t = qt_t_for_arc_angle(90 * t);-
117-
118 // swap x and y?-
119 if (quadrant & 1)
quadrant & 1Description
TRUEnever evaluated
FALSEnever evaluated
0
120 t = 1 - t;
never executed: t = 1 - t;
0
121-
122 qreal a, b, c, d;-
123 QBezier::coefficients(t, a, b, c, d);-
124 QPointF p(a + b + c*QT_PATH_KAPPA, d + c + b*QT_PATH_KAPPA);-
125-
126 // left quadrants-
127 if (quadrant == 1 || quadrant == 2)
quadrant == 1Description
TRUEnever evaluated
FALSEnever evaluated
quadrant == 2Description
TRUEnever evaluated
FALSEnever evaluated
0
128 p.rx() = -p.x();
never executed: p.rx() = -p.x();
0
129-
130 // top quadrants-
131 if (quadrant == 0 || quadrant == 1)
quadrant == 0Description
TRUEnever evaluated
FALSEnever evaluated
quadrant == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
132 p.ry() = -p.y();
never executed: p.ry() = -p.y();
0
133-
134 *points[i] = r.center() + QPointF(w2 * p.x(), h2 * p.y());-
135 }
never executed: end of block
0
136}
never executed: end of block
0
137-
138#ifdef QPP_DEBUG-
139static void qt_debug_path(const QPainterPath &path)-
140{-
141 const char *names[] = {-
142 "MoveTo ",-
143 "LineTo ",-
144 "CurveTo ",-
145 "CurveToData"-
146 };-
147-
148 printf("\nQPainterPath: elementCount=%d\n", path.elementCount());-
149 for (int i=0; i<path.elementCount(); ++i) {-
150 const QPainterPath::Element &e = path.elementAt(i);-
151 Q_ASSERT(e.type >= 0 && e.type <= QPainterPath::CurveToDataElement);-
152 printf(" - %3d:: %s, (%.2f, %.2f)\n", i, names[e.type], e.x, e.y);-
153 }-
154}-
155#endif-
156-
157/*!-
158 \class QPainterPath-
159 \ingroup painting-
160 \ingroup shared-
161 \inmodule QtGui-
162-
163 \brief The QPainterPath class provides a container for painting operations,-
164 enabling graphical shapes to be constructed and reused.-
165-
166 A painter path is an object composed of a number of graphical-
167 building blocks, such as rectangles, ellipses, lines, and curves.-
168 Building blocks can be joined in closed subpaths, for example as a-
169 rectangle or an ellipse. A closed path has coinciding start and-
170 end points. Or they can exist independently as unclosed subpaths,-
171 such as lines and curves.-
172-
173 A QPainterPath object can be used for filling, outlining, and-
174 clipping. To generate fillable outlines for a given painter path,-
175 use the QPainterPathStroker class. The main advantage of painter-
176 paths over normal drawing operations is that complex shapes only-
177 need to be created once; then they can be drawn many times using-
178 only calls to the QPainter::drawPath() function.-
179-
180 QPainterPath provides a collection of functions that can be used-
181 to obtain information about the path and its elements. In addition-
182 it is possible to reverse the order of the elements using the-
183 toReversed() function. There are also several functions to convert-
184 this painter path object into a polygon representation.-
185-
186 \tableofcontents-
187-
188 \section1 Composing a QPainterPath-
189-
190 A QPainterPath object can be constructed as an empty path, with a-
191 given start point, or as a copy of another QPainterPath object.-
192 Once created, lines and curves can be added to the path using the-
193 lineTo(), arcTo(), cubicTo() and quadTo() functions. The lines and-
194 curves stretch from the currentPosition() to the position passed-
195 as argument.-
196-
197 The currentPosition() of the QPainterPath object is always the end-
198 position of the last subpath that was added (or the initial start-
199 point). Use the moveTo() function to move the currentPosition()-
200 without adding a component. The moveTo() function implicitly-
201 starts a new subpath, and closes the previous one. Another way of-
202 starting a new subpath is to call the closeSubpath() function-
203 which closes the current path by adding a line from the-
204 currentPosition() back to the path's start position. Note that the-
205 new path will have (0, 0) as its initial currentPosition().-
206-
207 QPainterPath class also provides several convenience functions to-
208 add closed subpaths to a painter path: addEllipse(), addPath(),-
209 addRect(), addRegion() and addText(). The addPolygon() function-
210 adds an \e unclosed subpath. In fact, these functions are all-
211 collections of moveTo(), lineTo() and cubicTo() operations.-
212-
213 In addition, a path can be added to the current path using the-
214 connectPath() function. But note that this function will connect-
215 the last element of the current path to the first element of given-
216 one by adding a line.-
217-
218 Below is a code snippet that shows how a QPainterPath object can-
219 be used:-
220-
221 \table 70%-
222 \row-
223 \li \inlineimage qpainterpath-construction.png-
224 \li-
225 \snippet code/src_gui_painting_qpainterpath.cpp 0-
226 \endtable-
227-
228 The painter path is initially empty when constructed. We first add-
229 a rectangle, which is a closed subpath. Then we add two bezier-
230 curves which together form a closed subpath even though they are-
231 not closed individually. Finally we draw the entire path. The path-
232 is filled using the default fill rule, Qt::OddEvenFill. Qt-
233 provides two methods for filling paths:-
234-
235 \table-
236 \header-
237 \li Qt::OddEvenFill-
238 \li Qt::WindingFill-
239 \row-
240 \li \inlineimage qt-fillrule-oddeven.png-
241 \li \inlineimage qt-fillrule-winding.png-
242 \endtable-
243-
244 See the Qt::FillRule documentation for the definition of the-
245 rules. A painter path's currently set fill rule can be retrieved-
246 using the fillRule() function, and altered using the setFillRule()-
247 function.-
248-
249 \section1 QPainterPath Information-
250-
251 The QPainterPath class provides a collection of functions that-
252 returns information about the path and its elements.-
253-
254 The currentPosition() function returns the end point of the last-
255 subpath that was added (or the initial start point). The-
256 elementAt() function can be used to retrieve the various subpath-
257 elements, the \e number of elements can be retrieved using the-
258 elementCount() function, and the isEmpty() function tells whether-
259 this QPainterPath object contains any elements at all.-
260-
261 The controlPointRect() function returns the rectangle containing-
262 all the points and control points in this path. This function is-
263 significantly faster to compute than the exact boundingRect()-
264 which returns the bounding rectangle of this painter path with-
265 floating point precision.-
266-
267 Finally, QPainterPath provides the contains() function which can-
268 be used to determine whether a given point or rectangle is inside-
269 the path, and the intersects() function which determines if any of-
270 the points inside a given rectangle also are inside this path.-
271-
272 \section1 QPainterPath Conversion-
273-
274 For compatibility reasons, it might be required to simplify the-
275 representation of a painter path: QPainterPath provides the-
276 toFillPolygon(), toFillPolygons() and toSubpathPolygons()-
277 functions which convert the painter path into a polygon. The-
278 toFillPolygon() returns the painter path as one single polygon,-
279 while the two latter functions return a list of polygons.-
280-
281 The toFillPolygons() and toSubpathPolygons() functions are-
282 provided because it is usually faster to draw several small-
283 polygons than to draw one large polygon, even though the total-
284 number of points drawn is the same. The difference between the two-
285 is the \e number of polygons they return: The toSubpathPolygons()-
286 creates one polygon for each subpath regardless of intersecting-
287 subpaths (i.e. overlapping bounding rectangles), while the-
288 toFillPolygons() functions creates only one polygon for-
289 overlapping subpaths.-
290-
291 The toFillPolygon() and toFillPolygons() functions first convert-
292 all the subpaths to polygons, then uses a rewinding technique to-
293 make sure that overlapping subpaths can be filled using the-
294 correct fill rule. Note that rewinding inserts additional lines in-
295 the polygon so the outline of the fill polygon does not match the-
296 outline of the path.-
297-
298 \section1 Examples-
299-
300 Qt provides the \l {painting/painterpaths}{Painter Paths Example}-
301 and the \l {painting/deform}{Vector Deformation example} which are-
302 located in Qt's example directory.-
303-
304 The \l {painting/painterpaths}{Painter Paths Example} shows how-
305 painter paths can be used to build complex shapes for rendering-
306 and lets the user experiment with the filling and stroking. The-
307 \l {painting/deform}{Vector Deformation Example} shows how to use-
308 QPainterPath to draw text.-
309-
310 \table-
311 \header-
312 \li \l {painting/painterpaths}{Painter Paths Example}-
313 \li \l {painting/deform}{Vector Deformation Example}-
314 \row-
315 \li \inlineimage qpainterpath-example.png-
316 \li \inlineimage qpainterpath-demo.png-
317 \endtable-
318-
319 \sa QPainterPathStroker, QPainter, QRegion, {Painter Paths Example}-
320*/-
321-
322/*!-
323 \enum QPainterPath::ElementType-
324-
325 This enum describes the types of elements used to connect vertices-
326 in subpaths.-
327-
328 Note that elements added as closed subpaths using the-
329 addEllipse(), addPath(), addPolygon(), addRect(), addRegion() and-
330 addText() convenience functions, is actually added to the path as-
331 a collection of separate elements using the moveTo(), lineTo() and-
332 cubicTo() functions.-
333-
334 \value MoveToElement A new subpath. See also moveTo().-
335 \value LineToElement A line. See also lineTo().-
336 \value CurveToElement A curve. See also cubicTo() and quadTo().-
337 \value CurveToDataElement The extra data required to describe a curve in-
338 a CurveToElement element.-
339-
340 \sa elementAt(), elementCount()-
341*/-
342-
343/*!-
344 \class QPainterPath::Element-
345 \inmodule QtGui-
346-
347 \brief The QPainterPath::Element class specifies the position and-
348 type of a subpath.-
349-
350 Once a QPainterPath object is constructed, subpaths like lines and-
351 curves can be added to the path (creating-
352 QPainterPath::LineToElement and QPainterPath::CurveToElement-
353 components).-
354-
355 The lines and curves stretch from the currentPosition() to the-
356 position passed as argument. The currentPosition() of the-
357 QPainterPath object is always the end position of the last subpath-
358 that was added (or the initial start point). The moveTo() function-
359 can be used to move the currentPosition() without adding a line or-
360 curve, creating a QPainterPath::MoveToElement component.-
361-
362 \sa QPainterPath-
363*/-
364-
365/*!-
366 \variable QPainterPath::Element::x-
367 \brief the x coordinate of the element's position.-
368-
369 \sa {operator QPointF()}-
370*/-
371-
372/*!-
373 \variable QPainterPath::Element::y-
374 \brief the y coordinate of the element's position.-
375-
376 \sa {operator QPointF()}-
377*/-
378-
379/*!-
380 \variable QPainterPath::Element::type-
381 \brief the type of element-
382-
383 \sa isCurveTo(), isLineTo(), isMoveTo()-
384*/-
385-
386/*!-
387 \fn bool QPainterPath::Element::operator==(const Element &other) const-
388 \since 4.2-
389-
390 Returns \c true if this element is equal to \a other;-
391 otherwise returns \c false.-
392-
393 \sa operator!=()-
394*/-
395-
396/*!-
397 \fn bool QPainterPath::Element::operator!=(const Element &other) const-
398 \since 4.2-
399-
400 Returns \c true if this element is not equal to \a other;-
401 otherwise returns \c false.-
402-
403 \sa operator==()-
404*/-
405-
406/*!-
407 \fn bool QPainterPath::Element::isCurveTo () const-
408-
409 Returns \c true if the element is a curve, otherwise returns \c false.-
410-
411 \sa type, QPainterPath::CurveToElement-
412*/-
413-
414/*!-
415 \fn bool QPainterPath::Element::isLineTo () const-
416-
417 Returns \c true if the element is a line, otherwise returns \c false.-
418-
419 \sa type, QPainterPath::LineToElement-
420*/-
421-
422/*!-
423 \fn bool QPainterPath::Element::isMoveTo () const-
424-
425 Returns \c true if the element is moving the current position,-
426 otherwise returns \c false.-
427-
428 \sa type, QPainterPath::MoveToElement-
429*/-
430-
431/*!-
432 \fn QPainterPath::Element::operator QPointF () const-
433-
434 Returns the element's position.-
435-
436 \sa x, y-
437*/-
438-
439/*!-
440 \fn void QPainterPath::addEllipse(qreal x, qreal y, qreal width, qreal height)-
441 \overload-
442-
443 Creates an ellipse within the bounding rectangle defined by its top-left-
444 corner at (\a x, \a y), \a width and \a height, and adds it to the-
445 painter path as a closed subpath.-
446*/-
447-
448/*!-
449 \since 4.4-
450-
451 \fn void QPainterPath::addEllipse(const QPointF &center, qreal rx, qreal ry)-
452 \overload-
453-
454 Creates an ellipse positioned at \a{center} with radii \a{rx} and \a{ry},-
455 and adds it to the painter path as a closed subpath.-
456*/-
457-
458/*!-
459 \fn void QPainterPath::addText(qreal x, qreal y, const QFont &font, const QString &text)-
460 \overload-
461-
462 Adds the given \a text to this path as a set of closed subpaths created-
463 from the \a font supplied. The subpaths are positioned so that the left-
464 end of the text's baseline lies at the point specified by (\a x, \a y).-
465*/-
466-
467/*!-
468 \fn int QPainterPath::elementCount() const-
469-
470 Returns the number of path elements in the painter path.-
471-
472 \sa ElementType, elementAt(), isEmpty()-
473*/-
474-
475int QPainterPath::elementCount() const-
476{-
477 return d_ptr ? d_ptr->elements.size() : 0;
never executed: return d_ptr ? d_ptr->elements.size() : 0;
d_ptrDescription
TRUEnever evaluated
FALSEnever evaluated
0
478}-
479-
480/*!-
481 \fn QPainterPath::Element QPainterPath::elementAt(int index) const-
482-
483 Returns the element at the given \a index in the painter path.-
484-
485 \sa ElementType, elementCount(), isEmpty()-
486*/-
487-
488QPainterPath::Element QPainterPath::elementAt(int i) const-
489{-
490 Q_ASSERT(d_ptr);-
491 Q_ASSERT(i >= 0 && i < elementCount());-
492 return d_ptr->elements.at(i);
never executed: return d_ptr->elements.at(i);
0
493}-
494-
495/*!-
496 \fn void QPainterPath::setElementPositionAt(int index, qreal x, qreal y)-
497 \since 4.2-
498-
499 Sets the x and y coordinate of the element at index \a index to \a-
500 x and \a y.-
501*/-
502-
503void QPainterPath::setElementPositionAt(int i, qreal x, qreal y)-
504{-
505 Q_ASSERT(d_ptr);-
506 Q_ASSERT(i >= 0 && i < elementCount());-
507 detach();-
508 QPainterPath::Element &e = d_ptr->elements[i];-
509 e.x = x;-
510 e.y = y;-
511}
never executed: end of block
0
512-
513-
514/*###-
515 \fn QPainterPath &QPainterPath::operator +=(const QPainterPath &other)-
516-
517 Appends the \a other painter path to this painter path and returns a-
518 reference to the result.-
519*/-
520-
521/*!-
522 Constructs an empty QPainterPath object.-
523*/-
524QPainterPath::QPainterPath() Q_DECL_NOEXCEPT-
525 : d_ptr(0)-
526{-
527}
never executed: end of block
0
528-
529/*!-
530 \fn QPainterPath::QPainterPath(const QPainterPath &path)-
531-
532 Creates a QPainterPath object that is a copy of the given \a path.-
533-
534 \sa operator=()-
535*/-
536QPainterPath::QPainterPath(const QPainterPath &other)-
537 : d_ptr(other.d_ptr.data())-
538{-
539 if (d_ptr)
d_ptrDescription
TRUEnever evaluated
FALSEnever evaluated
0
540 d_ptr->ref.ref();
never executed: d_ptr->ref.ref();
0
541}
never executed: end of block
0
542-
543/*!-
544 Creates a QPainterPath object with the given \a startPoint as its-
545 current position.-
546*/-
547-
548QPainterPath::QPainterPath(const QPointF &startPoint)-
549 : d_ptr(new QPainterPathData)-
550{-
551 Element e = { startPoint.x(), startPoint.y(), MoveToElement };-
552 d_func()->elements << e;-
553}
never executed: end of block
0
554-
555void QPainterPath::detach()-
556{-
557 if (d_ptr->ref.load() != 1)
d_ptr->ref.load() != 1Description
TRUEnever evaluated
FALSEnever evaluated
0
558 detach_helper();
never executed: detach_helper();
0
559 setDirty(true);-
560}
never executed: end of block
0
561-
562/*!-
563 \internal-
564*/-
565void QPainterPath::detach_helper()-
566{-
567 QPainterPathPrivate *data = new QPainterPathData(*d_func());-
568 d_ptr.reset(data);-
569}
never executed: end of block
0
570-
571/*!-
572 \internal-
573*/-
574void QPainterPath::ensureData_helper()-
575{-
576 QPainterPathPrivate *data = new QPainterPathData;-
577 data->elements.reserve(16);-
578 QPainterPath::Element e = { 0, 0, QPainterPath::MoveToElement };-
579 data->elements << e;-
580 d_ptr.reset(data);-
581 Q_ASSERT(d_ptr != 0);-
582}
never executed: end of block
0
583-
584/*!-
585 \fn QPainterPath &QPainterPath::operator=(const QPainterPath &path)-
586-
587 Assigns the given \a path to this painter path.-
588-
589 \sa QPainterPath()-
590*/-
591QPainterPath &QPainterPath::operator=(const QPainterPath &other)-
592{-
593 if (other.d_func() != d_func()) {
other.d_func() != d_func()Description
TRUEnever evaluated
FALSEnever evaluated
0
594 QPainterPathPrivate *data = other.d_func();-
595 if (data)
dataDescription
TRUEnever evaluated
FALSEnever evaluated
0
596 data->ref.ref();
never executed: data->ref.ref();
0
597 d_ptr.reset(data);-
598 }
never executed: end of block
0
599 return *this;
never executed: return *this;
0
600}-
601-
602/*!-
603 \fn QPainterPath &QPainterPath::operator=(QPainterPath &&other)-
604-
605 Move-assigns \a other to this QPainterPath instance.-
606-
607 \since 5.2-
608*/-
609-
610/*!-
611 \fn void QPainterPath::swap(QPainterPath &other)-
612 \since 4.8-
613-
614 Swaps painter path \a other with this painter path. This operation is very-
615 fast and never fails.-
616*/-
617-
618/*!-
619 Destroys this QPainterPath object.-
620*/-
621QPainterPath::~QPainterPath()-
622{-
623}-
624-
625/*!-
626 Closes the current subpath by drawing a line to the beginning of-
627 the subpath, automatically starting a new path. The current point-
628 of the new path is (0, 0).-
629-
630 If the subpath does not contain any elements, this function does-
631 nothing.-
632-
633 \sa moveTo(), {QPainterPath#Composing a QPainterPath}{Composing-
634 a QPainterPath}-
635 */-
636void QPainterPath::closeSubpath()-
637{-
638#ifdef QPP_DEBUG-
639 printf("QPainterPath::closeSubpath()\n");-
640#endif-
641 if (isEmpty())
isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
642 return;
never executed: return;
0
643 detach();-
644-
645 d_func()->close();-
646}
never executed: end of block
0
647-
648/*!-
649 \fn void QPainterPath::moveTo(qreal x, qreal y)-
650-
651 \overload-
652-
653 Moves the current position to (\a{x}, \a{y}) and starts a new-
654 subpath, implicitly closing the previous path.-
655*/-
656-
657/*!-
658 \fn void QPainterPath::moveTo(const QPointF &point)-
659-
660 Moves the current point to the given \a point, implicitly starting-
661 a new subpath and closing the previous one.-
662-
663 \sa closeSubpath(), {QPainterPath#Composing a-
664 QPainterPath}{Composing a QPainterPath}-
665*/-
666void QPainterPath::moveTo(const QPointF &p)-
667{-
668#ifdef QPP_DEBUG-
669 printf("QPainterPath::moveTo() (%.2f,%.2f)\n", p.x(), p.y());-
670#endif-
671-
672 if (!qt_is_finite(p.x()) || !qt_is_finite(p.y())) {
!qt_is_finite(p.x())Description
TRUEnever evaluated
FALSEnever evaluated
!qt_is_finite(p.y())Description
TRUEnever evaluated
FALSEnever evaluated
0
673#ifndef QT_NO_DEBUG-
674 qWarning("QPainterPath::moveTo: Adding point where x or y is NaN or Inf, ignoring call");-
675#endif-
676 return;
never executed: return;
0
677 }-
678-
679 ensureData();-
680 detach();-
681-
682 QPainterPathData *d = d_func();-
683 Q_ASSERT(!d->elements.isEmpty());-
684-
685 d->require_moveTo = false;-
686-
687 if (d->elements.last().type == MoveToElement) {
d->elements.la... MoveToElementDescription
TRUEnever evaluated
FALSEnever evaluated
0
688 d->elements.last().x = p.x();-
689 d->elements.last().y = p.y();-
690 } else {
never executed: end of block
0
691 Element elm = { p.x(), p.y(), MoveToElement };-
692 d->elements.append(elm);-
693 }
never executed: end of block
0
694 d->cStart = d->elements.size() - 1;-
695}
never executed: end of block
0
696-
697/*!-
698 \fn void QPainterPath::lineTo(qreal x, qreal y)-
699-
700 \overload-
701-
702 Draws a line from the current position to the point (\a{x},-
703 \a{y}).-
704*/-
705-
706/*!-
707 \fn void QPainterPath::lineTo(const QPointF &endPoint)-
708-
709 Adds a straight line from the current position to the given \a-
710 endPoint. After the line is drawn, the current position is updated-
711 to be at the end point of the line.-
712-
713 \sa addPolygon(), addRect(), {QPainterPath#Composing a-
714 QPainterPath}{Composing a QPainterPath}-
715 */-
716void QPainterPath::lineTo(const QPointF &p)-
717{-
718#ifdef QPP_DEBUG-
719 printf("QPainterPath::lineTo() (%.2f,%.2f)\n", p.x(), p.y());-
720#endif-
721-
722 if (!qt_is_finite(p.x()) || !qt_is_finite(p.y())) {
!qt_is_finite(p.x())Description
TRUEnever evaluated
FALSEnever evaluated
!qt_is_finite(p.y())Description
TRUEnever evaluated
FALSEnever evaluated
0
723#ifndef QT_NO_DEBUG-
724 qWarning("QPainterPath::lineTo: Adding point where x or y is NaN or Inf, ignoring call");-
725#endif-
726 return;
never executed: return;
0
727 }-
728-
729 ensureData();-
730 detach();-
731-
732 QPainterPathData *d = d_func();-
733 Q_ASSERT(!d->elements.isEmpty());-
734 d->maybeMoveTo();-
735 if (p == QPointF(d->elements.last()))
p == QPointF(d...ements.last())Description
TRUEnever evaluated
FALSEnever evaluated
0
736 return;
never executed: return;
0
737 Element elm = { p.x(), p.y(), LineToElement };-
738 d->elements.append(elm);-
739-
740 d->convex = d->elements.size() == 3 || (d->elements.size() == 4 && d->isClosed());
d->elements.size() == 3Description
TRUEnever evaluated
FALSEnever evaluated
d->elements.size() == 4Description
TRUEnever evaluated
FALSEnever evaluated
d->isClosed()Description
TRUEnever evaluated
FALSEnever evaluated
0
741}
never executed: end of block
0
742-
743/*!-
744 \fn void QPainterPath::cubicTo(qreal c1X, qreal c1Y, qreal c2X,-
745 qreal c2Y, qreal endPointX, qreal endPointY);-
746-
747 \overload-
748-
749 Adds a cubic Bezier curve between the current position and the end-
750 point (\a{endPointX}, \a{endPointY}) with control points specified-
751 by (\a{c1X}, \a{c1Y}) and (\a{c2X}, \a{c2Y}).-
752*/-
753-
754/*!-
755 \fn void QPainterPath::cubicTo(const QPointF &c1, const QPointF &c2, const QPointF &endPoint)-
756-
757 Adds a cubic Bezier curve between the current position and the-
758 given \a endPoint using the control points specified by \a c1, and-
759 \a c2.-
760-
761 After the curve is added, the current position is updated to be at-
762 the end point of the curve.-
763-
764 \table 100%-
765 \row-
766 \li \inlineimage qpainterpath-cubicto.png-
767 \li-
768 \snippet code/src_gui_painting_qpainterpath.cpp 1-
769 \endtable-
770-
771 \sa quadTo(), {QPainterPath#Composing a QPainterPath}{Composing-
772 a QPainterPath}-
773*/-
774void QPainterPath::cubicTo(const QPointF &c1, const QPointF &c2, const QPointF &e)-
775{-
776#ifdef QPP_DEBUG-
777 printf("QPainterPath::cubicTo() (%.2f,%.2f), (%.2f,%.2f), (%.2f,%.2f)\n",-
778 c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y());-
779#endif-
780-
781 if (!qt_is_finite(c1.x()) || !qt_is_finite(c1.y()) || !qt_is_finite(c2.x()) || !qt_is_finite(c2.y())
!qt_is_finite(c1.x())Description
TRUEnever evaluated
FALSEnever evaluated
!qt_is_finite(c1.y())Description
TRUEnever evaluated
FALSEnever evaluated
!qt_is_finite(c2.x())Description
TRUEnever evaluated
FALSEnever evaluated
!qt_is_finite(c2.y())Description
TRUEnever evaluated
FALSEnever evaluated
0
782 || !qt_is_finite(e.x()) || !qt_is_finite(e.y())) {
!qt_is_finite(e.x())Description
TRUEnever evaluated
FALSEnever evaluated
!qt_is_finite(e.y())Description
TRUEnever evaluated
FALSEnever evaluated
0
783#ifndef QT_NO_DEBUG-
784 qWarning("QPainterPath::cubicTo: Adding point where x or y is NaN or Inf, ignoring call");-
785#endif-
786 return;
never executed: return;
0
787 }-
788-
789 ensureData();-
790 detach();-
791-
792 QPainterPathData *d = d_func();-
793 Q_ASSERT(!d->elements.isEmpty());-
794-
795-
796 // Abort on empty curve as a stroker cannot handle this and the-
797 // curve is irrelevant anyway.-
798 if (d->elements.last() == c1 && c1 == c2 && c2 == e)
d->elements.last() == c1Description
TRUEnever evaluated
FALSEnever evaluated
c1 == c2Description
TRUEnever evaluated
FALSEnever evaluated
c2 == eDescription
TRUEnever evaluated
FALSEnever evaluated
0
799 return;
never executed: return;
0
800-
801 d->maybeMoveTo();-
802-
803 Element ce1 = { c1.x(), c1.y(), CurveToElement };-
804 Element ce2 = { c2.x(), c2.y(), CurveToDataElement };-
805 Element ee = { e.x(), e.y(), CurveToDataElement };-
806 d->elements << ce1 << ce2 << ee;-
807}
never executed: end of block
0
808-
809/*!-
810 \fn void QPainterPath::quadTo(qreal cx, qreal cy, qreal endPointX, qreal endPointY);-
811-
812 \overload-
813-
814 Adds a quadratic Bezier curve between the current point and the endpoint-
815 (\a{endPointX}, \a{endPointY}) with the control point specified by-
816 (\a{cx}, \a{cy}).-
817*/-
818-
819/*!-
820 \fn void QPainterPath::quadTo(const QPointF &c, const QPointF &endPoint)-
821-
822 Adds a quadratic Bezier curve between the current position and the-
823 given \a endPoint with the control point specified by \a c.-
824-
825 After the curve is added, the current point is updated to be at-
826 the end point of the curve.-
827-
828 \sa cubicTo(), {QPainterPath#Composing a QPainterPath}{Composing a-
829 QPainterPath}-
830*/-
831void QPainterPath::quadTo(const QPointF &c, const QPointF &e)-
832{-
833#ifdef QPP_DEBUG-
834 printf("QPainterPath::quadTo() (%.2f,%.2f), (%.2f,%.2f)\n",-
835 c.x(), c.y(), e.x(), e.y());-
836#endif-
837-
838 if (!qt_is_finite(c.x()) || !qt_is_finite(c.y()) || !qt_is_finite(e.x()) || !qt_is_finite(e.y())) {
!qt_is_finite(c.x())Description
TRUEnever evaluated
FALSEnever evaluated
!qt_is_finite(c.y())Description
TRUEnever evaluated
FALSEnever evaluated
!qt_is_finite(e.x())Description
TRUEnever evaluated
FALSEnever evaluated
!qt_is_finite(e.y())Description
TRUEnever evaluated
FALSEnever evaluated
0
839#ifndef QT_NO_DEBUG-
840 qWarning("QPainterPath::quadTo: Adding point where x or y is NaN or Inf, ignoring call");-
841#endif-
842 return;
never executed: return;
0
843 }-
844-
845 ensureData();-
846 detach();-
847-
848 Q_D(QPainterPath);-
849 Q_ASSERT(!d->elements.isEmpty());-
850 const QPainterPath::Element &elm = d->elements.at(elementCount()-1);-
851 QPointF prev(elm.x, elm.y);-
852-
853 // Abort on empty curve as a stroker cannot handle this and the-
854 // curve is irrelevant anyway.-
855 if (prev == c && c == e)
prev == cDescription
TRUEnever evaluated
FALSEnever evaluated
c == eDescription
TRUEnever evaluated
FALSEnever evaluated
0
856 return;
never executed: return;
0
857-
858 QPointF c1((prev.x() + 2*c.x()) / 3, (prev.y() + 2*c.y()) / 3);-
859 QPointF c2((e.x() + 2*c.x()) / 3, (e.y() + 2*c.y()) / 3);-
860 cubicTo(c1, c2, e);-
861}
never executed: end of block
0
862-
863/*!-
864 \fn void QPainterPath::arcTo(qreal x, qreal y, qreal width, qreal-
865 height, qreal startAngle, qreal sweepLength)-
866-
867 \overload-
868-
869 Creates an arc that occupies the rectangle QRectF(\a x, \a y, \a-
870 width, \a height), beginning at the specified \a startAngle and-
871 extending \a sweepLength degrees counter-clockwise.-
872-
873*/-
874-
875/*!-
876 \fn void QPainterPath::arcTo(const QRectF &rectangle, qreal startAngle, qreal sweepLength)-
877-
878 Creates an arc that occupies the given \a rectangle, beginning at-
879 the specified \a startAngle and extending \a sweepLength degrees-
880 counter-clockwise.-
881-
882 Angles are specified in degrees. Clockwise arcs can be specified-
883 using negative angles.-
884-
885 Note that this function connects the starting point of the arc to-
886 the current position if they are not already connected. After the-
887 arc has been added, the current position is the last point in-
888 arc. To draw a line back to the first point, use the-
889 closeSubpath() function.-
890-
891 \table 100%-
892 \row-
893 \li \inlineimage qpainterpath-arcto.png-
894 \li-
895 \snippet code/src_gui_painting_qpainterpath.cpp 2-
896 \endtable-
897-
898 \sa arcMoveTo(), addEllipse(), QPainter::drawArc(), QPainter::drawPie(),-
899 {QPainterPath#Composing a QPainterPath}{Composing a-
900 QPainterPath}-
901*/-
902void QPainterPath::arcTo(const QRectF &rect, qreal startAngle, qreal sweepLength)-
903{-
904#ifdef QPP_DEBUG-
905 printf("QPainterPath::arcTo() (%.2f, %.2f, %.2f, %.2f, angle=%.2f, sweep=%.2f\n",-
906 rect.x(), rect.y(), rect.width(), rect.height(), startAngle, sweepLength);-
907#endif-
908-
909 if ((!qt_is_finite(rect.x()) && !qt_is_finite(rect.y())) || !qt_is_finite(rect.width()) || !qt_is_finite(rect.height())
!qt_is_finite(rect.x())Description
TRUEnever evaluated
FALSEnever evaluated
!qt_is_finite(rect.y())Description
TRUEnever evaluated
FALSEnever evaluated
!qt_is_finite(rect.width())Description
TRUEnever evaluated
FALSEnever evaluated
!qt_is_finite(rect.height())Description
TRUEnever evaluated
FALSEnever evaluated
0
910 || !qt_is_finite(startAngle) || !qt_is_finite(sweepLength)) {
!qt_is_finite(startAngle)Description
TRUEnever evaluated
FALSEnever evaluated
!qt_is_finite(sweepLength)Description
TRUEnever evaluated
FALSEnever evaluated
0
911#ifndef QT_NO_DEBUG-
912 qWarning("QPainterPath::arcTo: Adding arc where a parameter is NaN or Inf, ignoring call");-
913#endif-
914 return;
never executed: return;
0
915 }-
916-
917 if (rect.isNull())
rect.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
918 return;
never executed: return;
0
919-
920 ensureData();-
921 detach();-
922-
923 int point_count;-
924 QPointF pts[15];-
925 QPointF curve_start = qt_curves_for_arc(rect, startAngle, sweepLength, pts, &point_count);-
926-
927 lineTo(curve_start);-
928 for (int i=0; i<point_count; i+=3) {
i<point_countDescription
TRUEnever evaluated
FALSEnever evaluated
0
929 cubicTo(pts[i].x(), pts[i].y(),-
930 pts[i+1].x(), pts[i+1].y(),-
931 pts[i+2].x(), pts[i+2].y());-
932 }
never executed: end of block
0
933-
934}
never executed: end of block
0
935-
936-
937/*!-
938 \fn void QPainterPath::arcMoveTo(qreal x, qreal y, qreal width, qreal height, qreal angle)-
939 \overload-
940 \since 4.2-
941-
942 Creates a move to that lies on the arc that occupies the-
943 QRectF(\a x, \a y, \a width, \a height) at \a angle.-
944*/-
945-
946-
947/*!-
948 \fn void QPainterPath::arcMoveTo(const QRectF &rectangle, qreal angle)-
949 \since 4.2-
950-
951 Creates a move to that lies on the arc that occupies the given \a-
952 rectangle at \a angle.-
953-
954 Angles are specified in degrees. Clockwise arcs can be specified-
955 using negative angles.-
956-
957 \sa moveTo(), arcTo()-
958*/-
959-
960void QPainterPath::arcMoveTo(const QRectF &rect, qreal angle)-
961{-
962 if (rect.isNull())
rect.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
963 return;
never executed: return;
0
964-
965 QPointF pt;-
966 qt_find_ellipse_coords(rect, angle, 0, &pt, 0);-
967 moveTo(pt);-
968}
never executed: end of block
0
969-
970-
971-
972/*!-
973 \fn QPointF QPainterPath::currentPosition() const-
974-
975 Returns the current position of the path.-
976*/-
977QPointF QPainterPath::currentPosition() const-
978{-
979 return !d_ptr || d_func()->elements.isEmpty()
never executed: return !d_ptr || d_func()->elements.isEmpty() ? QPointF() : QPointF(d_func()->elements.last().x, d_func()->elements.last().y);
!d_ptrDescription
TRUEnever evaluated
FALSEnever evaluated
d_func()->elements.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
980 ? QPointF()
never executed: return !d_ptr || d_func()->elements.isEmpty() ? QPointF() : QPointF(d_func()->elements.last().x, d_func()->elements.last().y);
0
981 : QPointF(d_func()->elements.last().x, d_func()->elements.last().y);
never executed: return !d_ptr || d_func()->elements.isEmpty() ? QPointF() : QPointF(d_func()->elements.last().x, d_func()->elements.last().y);
0
982}-
983-
984-
985/*!-
986 \fn void QPainterPath::addRect(qreal x, qreal y, qreal width, qreal height)-
987-
988 \overload-
989-
990 Adds a rectangle at position (\a{x}, \a{y}), with the given \a-
991 width and \a height, as a closed subpath.-
992*/-
993-
994/*!-
995 \fn void QPainterPath::addRect(const QRectF &rectangle)-
996-
997 Adds the given \a rectangle to this path as a closed subpath.-
998-
999 The \a rectangle is added as a clockwise set of lines. The painter-
1000 path's current position after the \a rectangle has been added is-
1001 at the top-left corner of the rectangle.-
1002-
1003 \table 100%-
1004 \row-
1005 \li \inlineimage qpainterpath-addrectangle.png-
1006 \li-
1007 \snippet code/src_gui_painting_qpainterpath.cpp 3-
1008 \endtable-
1009-
1010 \sa addRegion(), lineTo(), {QPainterPath#Composing a-
1011 QPainterPath}{Composing a QPainterPath}-
1012*/-
1013void QPainterPath::addRect(const QRectF &r)-
1014{-
1015 if (!qt_is_finite(r.x()) || !qt_is_finite(r.y()) || !qt_is_finite(r.width()) || !qt_is_finite(r.height())) {
!qt_is_finite(r.x())Description
TRUEnever evaluated
FALSEnever evaluated
!qt_is_finite(r.y())Description
TRUEnever evaluated
FALSEnever evaluated
!qt_is_finite(r.width())Description
TRUEnever evaluated
FALSEnever evaluated
!qt_is_finite(r.height())Description
TRUEnever evaluated
FALSEnever evaluated
0
1016#ifndef QT_NO_DEBUG-
1017 qWarning("QPainterPath::addRect: Adding rect where a parameter is NaN or Inf, ignoring call");-
1018#endif-
1019 return;
never executed: return;
0
1020 }-
1021-
1022 if (r.isNull())
r.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
1023 return;
never executed: return;
0
1024-
1025 ensureData();-
1026 detach();-
1027-
1028 bool first = d_func()->elements.size() < 2;-
1029-
1030 d_func()->elements.reserve(d_func()->elements.size() + 5);-
1031 moveTo(r.x(), r.y());-
1032-
1033 Element l1 = { r.x() + r.width(), r.y(), LineToElement };-
1034 Element l2 = { r.x() + r.width(), r.y() + r.height(), LineToElement };-
1035 Element l3 = { r.x(), r.y() + r.height(), LineToElement };-
1036 Element l4 = { r.x(), r.y(), LineToElement };-
1037-
1038 d_func()->elements << l1 << l2 << l3 << l4;-
1039 d_func()->require_moveTo = true;-
1040 d_func()->convex = first;-
1041}
never executed: end of block
0
1042-
1043/*!-
1044 Adds the given \a polygon to the path as an (unclosed) subpath.-
1045-
1046 Note that the current position after the polygon has been added,-
1047 is the last point in \a polygon. To draw a line back to the first-
1048 point, use the closeSubpath() function.-
1049-
1050 \table 100%-
1051 \row-
1052 \li \inlineimage qpainterpath-addpolygon.png-
1053 \li-
1054 \snippet code/src_gui_painting_qpainterpath.cpp 4-
1055 \endtable-
1056-
1057 \sa lineTo(), {QPainterPath#Composing a QPainterPath}{Composing-
1058 a QPainterPath}-
1059*/-
1060void QPainterPath::addPolygon(const QPolygonF &polygon)-
1061{-
1062 if (polygon.isEmpty())
polygon.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
1063 return;
never executed: return;
0
1064-
1065 ensureData();-
1066 detach();-
1067-
1068 d_func()->elements.reserve(d_func()->elements.size() + polygon.size());-
1069-
1070 moveTo(polygon.first());-
1071 for (int i=1; i<polygon.size(); ++i) {
i<polygon.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1072 Element elm = { polygon.at(i).x(), polygon.at(i).y(), LineToElement };-
1073 d_func()->elements << elm;-
1074 }
never executed: end of block
0
1075}
never executed: end of block
0
1076-
1077/*!-
1078 \fn void QPainterPath::addEllipse(const QRectF &boundingRectangle)-
1079-
1080 Creates an ellipse within the specified \a boundingRectangle-
1081 and adds it to the painter path as a closed subpath.-
1082-
1083 The ellipse is composed of a clockwise curve, starting and-
1084 finishing at zero degrees (the 3 o'clock position).-
1085-
1086 \table 100%-
1087 \row-
1088 \li \inlineimage qpainterpath-addellipse.png-
1089 \li-
1090 \snippet code/src_gui_painting_qpainterpath.cpp 5-
1091 \endtable-
1092-
1093 \sa arcTo(), QPainter::drawEllipse(), {QPainterPath#Composing a-
1094 QPainterPath}{Composing a QPainterPath}-
1095*/-
1096void QPainterPath::addEllipse(const QRectF &boundingRect)-
1097{-
1098 if (!qt_is_finite(boundingRect.x()) || !qt_is_finite(boundingRect.y())
!qt_is_finite(...ndingRect.x())Description
TRUEnever evaluated
FALSEnever evaluated
!qt_is_finite(...ndingRect.y())Description
TRUEnever evaluated
FALSEnever evaluated
0
1099 || !qt_is_finite(boundingRect.width()) || !qt_is_finite(boundingRect.height())) {
!qt_is_finite(...gRect.width())Description
TRUEnever evaluated
FALSEnever evaluated
!qt_is_finite(...Rect.height())Description
TRUEnever evaluated
FALSEnever evaluated
0
1100#ifndef QT_NO_DEBUG-
1101 qWarning("QPainterPath::addEllipse: Adding ellipse where a parameter is NaN or Inf, ignoring call");-
1102#endif-
1103 return;
never executed: return;
0
1104 }-
1105-
1106 if (boundingRect.isNull())
boundingRect.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
1107 return;
never executed: return;
0
1108-
1109 ensureData();-
1110 detach();-
1111-
1112 Q_D(QPainterPath);-
1113 bool first = d_func()->elements.size() < 2;-
1114 d->elements.reserve(d->elements.size() + 13);-
1115-
1116 QPointF pts[12];-
1117 int point_count;-
1118 QPointF start = qt_curves_for_arc(boundingRect, 0, -360, pts, &point_count);-
1119-
1120 moveTo(start);-
1121 cubicTo(pts[0], pts[1], pts[2]); // 0 -> 270-
1122 cubicTo(pts[3], pts[4], pts[5]); // 270 -> 180-
1123 cubicTo(pts[6], pts[7], pts[8]); // 180 -> 90-
1124 cubicTo(pts[9], pts[10], pts[11]); // 90 - >0-
1125 d_func()->require_moveTo = true;-
1126-
1127 d_func()->convex = first;-
1128}
never executed: end of block
0
1129-
1130/*!-
1131 \fn void QPainterPath::addText(const QPointF &point, const QFont &font, const QString &text)-
1132-
1133 Adds the given \a text to this path as a set of closed subpaths-
1134 created from the \a font supplied. The subpaths are positioned so-
1135 that the left end of the text's baseline lies at the specified \a-
1136 point.-
1137-
1138 \table 100%-
1139 \row-
1140 \li \inlineimage qpainterpath-addtext.png-
1141 \li-
1142 \snippet code/src_gui_painting_qpainterpath.cpp 6-
1143 \endtable-
1144-
1145 \sa QPainter::drawText(), {QPainterPath#Composing a-
1146 QPainterPath}{Composing a QPainterPath}-
1147*/-
1148void QPainterPath::addText(const QPointF &point, const QFont &f, const QString &text)-
1149{-
1150 if (text.isEmpty())
text.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
1151 return;
never executed: return;
0
1152-
1153 ensureData();-
1154 detach();-
1155-
1156 QTextLayout layout(text, f);-
1157 layout.setCacheEnabled(true);-
1158 QTextEngine *eng = layout.engine();-
1159 layout.beginLayout();-
1160 QTextLine line = layout.createLine();-
1161 Q_UNUSED(line);-
1162 layout.endLayout();-
1163 const QScriptLine &sl = eng->lines[0];-
1164 if (!sl.length || !eng->layoutData)
!sl.lengthDescription
TRUEnever evaluated
FALSEnever evaluated
!eng->layoutDataDescription
TRUEnever evaluated
FALSEnever evaluated
0
1165 return;
never executed: return;
0
1166-
1167 int nItems = eng->layoutData->items.size();-
1168-
1169 qreal x(point.x());-
1170 qreal y(point.y());-
1171-
1172 QVarLengthArray<int> visualOrder(nItems);-
1173 QVarLengthArray<uchar> levels(nItems);-
1174 for (int i = 0; i < nItems; ++i)
i < nItemsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1175 levels[i] = eng->layoutData->items[i].analysis.bidiLevel;
never executed: levels[i] = eng->layoutData->items[i].analysis.bidiLevel;
0
1176 QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data());-
1177-
1178 for (int i = 0; i < nItems; ++i) {
i < nItemsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1179 int item = visualOrder[i];-
1180 QScriptItem &si = eng->layoutData->items[item];-
1181-
1182 if (si.analysis.flags < QScriptAnalysis::TabOrObject) {
si.analysis.fl...s::TabOrObjectDescription
TRUEnever evaluated
FALSEnever evaluated
0
1183 QGlyphLayout glyphs = eng->shapedGlyphs(&si);-
1184 QFontEngine *fe = f.d->engineForScript(si.analysis.script);-
1185 Q_ASSERT(fe);-
1186 fe->addOutlineToPath(x, y, glyphs, this,-
1187 si.analysis.bidiLevel % 2-
1188 ? QTextItem::RenderFlags(QTextItem::RightToLeft)-
1189 : QTextItem::RenderFlags(0));-
1190-
1191 const qreal lw = fe->lineThickness().toReal();-
1192 if (f.d->underline) {
f.d->underlineDescription
TRUEnever evaluated
FALSEnever evaluated
0
1193 qreal pos = fe->underlinePosition().toReal();-
1194 addRect(x, y + pos, si.width.toReal(), lw);-
1195 }
never executed: end of block
0
1196 if (f.d->overline) {
f.d->overlineDescription
TRUEnever evaluated
FALSEnever evaluated
0
1197 qreal pos = fe->ascent().toReal() + 1;-
1198 addRect(x, y - pos, si.width.toReal(), lw);-
1199 }
never executed: end of block
0
1200 if (f.d->strikeOut) {
f.d->strikeOutDescription
TRUEnever evaluated
FALSEnever evaluated
0
1201 qreal pos = fe->ascent().toReal() / 3;-
1202 addRect(x, y - pos, si.width.toReal(), lw);-
1203 }
never executed: end of block
0
1204 }
never executed: end of block
0
1205 x += si.width.toReal();-
1206 }
never executed: end of block
0
1207}
never executed: end of block
0
1208-
1209/*!-
1210 \fn void QPainterPath::addPath(const QPainterPath &path)-
1211-
1212 Adds the given \a path to \e this path as a closed subpath.-
1213-
1214 \sa connectPath(), {QPainterPath#Composing a-
1215 QPainterPath}{Composing a QPainterPath}-
1216*/-
1217void QPainterPath::addPath(const QPainterPath &other)-
1218{-
1219 if (other.isEmpty())
other.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
1220 return;
never executed: return;
0
1221-
1222 ensureData();-
1223 detach();-
1224-
1225 QPainterPathData *d = reinterpret_cast<QPainterPathData *>(d_func());-
1226 // Remove last moveto so we don't get multiple moveto's-
1227 if (d->elements.last().type == MoveToElement)
d->elements.la... MoveToElementDescription
TRUEnever evaluated
FALSEnever evaluated
0
1228 d->elements.remove(d->elements.size()-1);
never executed: d->elements.remove(d->elements.size()-1);
0
1229-
1230 // Locate where our own current subpath will start after the other path is added.-
1231 int cStart = d->elements.size() + other.d_func()->cStart;-
1232 d->elements += other.d_func()->elements;-
1233 d->cStart = cStart;-
1234-
1235 d->require_moveTo = other.d_func()->isClosed();-
1236}
never executed: end of block
0
1237-
1238-
1239/*!-
1240 \fn void QPainterPath::connectPath(const QPainterPath &path)-
1241-
1242 Connects the given \a path to \e this path by adding a line from the-
1243 last element of this path to the first element of the given path.-
1244-
1245 \sa addPath(), {QPainterPath#Composing a QPainterPath}{Composing-
1246 a QPainterPath}-
1247*/-
1248void QPainterPath::connectPath(const QPainterPath &other)-
1249{-
1250 if (other.isEmpty())
other.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
1251 return;
never executed: return;
0
1252-
1253 ensureData();-
1254 detach();-
1255-
1256 QPainterPathData *d = reinterpret_cast<QPainterPathData *>(d_func());-
1257 // Remove last moveto so we don't get multiple moveto's-
1258 if (d->elements.last().type == MoveToElement)
d->elements.la... MoveToElementDescription
TRUEnever evaluated
FALSEnever evaluated
0
1259 d->elements.remove(d->elements.size()-1);
never executed: d->elements.remove(d->elements.size()-1);
0
1260-
1261 // Locate where our own current subpath will start after the other path is added.-
1262 int cStart = d->elements.size() + other.d_func()->cStart;-
1263 int first = d->elements.size();-
1264 d->elements += other.d_func()->elements;-
1265-
1266 if (first != 0)
first != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1267 d->elements[first].type = LineToElement;
never executed: d->elements[first].type = LineToElement;
0
1268-
1269 // avoid duplicate points-
1270 if (first > 0 && QPointF(d->elements[first]) == QPointF(d->elements[first - 1])) {
first > 0Description
TRUEnever evaluated
FALSEnever evaluated
QPointF(d->ele...ts[first - 1])Description
TRUEnever evaluated
FALSEnever evaluated
0
1271 d->elements.remove(first--);-
1272 --cStart;-
1273 }
never executed: end of block
0
1274-
1275 if (cStart != first)
cStart != firstDescription
TRUEnever evaluated
FALSEnever evaluated
0
1276 d->cStart = cStart;
never executed: d->cStart = cStart;
0
1277}
never executed: end of block
0
1278-
1279/*!-
1280 Adds the given \a region to the path by adding each rectangle in-
1281 the region as a separate closed subpath.-
1282-
1283 \sa addRect(), {QPainterPath#Composing a QPainterPath}{Composing-
1284 a QPainterPath}-
1285*/-
1286void QPainterPath::addRegion(const QRegion &region)-
1287{-
1288 ensureData();-
1289 detach();-
1290-
1291 QVector<QRect> rects = region.rects();-
1292 d_func()->elements.reserve(rects.size() * 5);-
1293 for (int i=0; i<rects.size(); ++i)
i<rects.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1294 addRect(rects.at(i));
never executed: addRect(rects.at(i));
0
1295}
never executed: end of block
0
1296-
1297-
1298/*!-
1299 Returns the painter path's currently set fill rule.-
1300-
1301 \sa setFillRule()-
1302*/-
1303Qt::FillRule QPainterPath::fillRule() const-
1304{-
1305 return isEmpty() ? Qt::OddEvenFill : d_func()->fillRule;
never executed: return isEmpty() ? Qt::OddEvenFill : d_func()->fillRule;
isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
1306}-
1307-
1308/*!-
1309 \fn void QPainterPath::setFillRule(Qt::FillRule fillRule)-
1310-
1311 Sets the fill rule of the painter path to the given \a-
1312 fillRule. Qt provides two methods for filling paths:-
1313-
1314 \table-
1315 \header-
1316 \li Qt::OddEvenFill (default)-
1317 \li Qt::WindingFill-
1318 \row-
1319 \li \inlineimage qt-fillrule-oddeven.png-
1320 \li \inlineimage qt-fillrule-winding.png-
1321 \endtable-
1322-
1323 \sa fillRule()-
1324*/-
1325void QPainterPath::setFillRule(Qt::FillRule fillRule)-
1326{-
1327 ensureData();-
1328 if (d_func()->fillRule == fillRule)
d_func()->fillRule == fillRuleDescription
TRUEnever evaluated
FALSEnever evaluated
0
1329 return;
never executed: return;
0
1330 detach();-
1331-
1332 d_func()->fillRule = fillRule;-
1333}
never executed: end of block
0
1334-
1335#define QT_BEZIER_A(bezier, coord) 3 * (-bezier.coord##1 \-
1336 + 3*bezier.coord##2 \-
1337 - 3*bezier.coord##3 \-
1338 +bezier.coord##4)-
1339-
1340#define QT_BEZIER_B(bezier, coord) 6 * (bezier.coord##1 \-
1341 - 2*bezier.coord##2 \-
1342 + bezier.coord##3)-
1343-
1344#define QT_BEZIER_C(bezier, coord) 3 * (- bezier.coord##1 \-
1345 + bezier.coord##2)-
1346-
1347#define QT_BEZIER_CHECK_T(bezier, t) \-
1348 if (t >= 0 && t <= 1) { \-
1349 QPointF p(b.pointAt(t)); \-
1350 if (p.x() < minx) minx = p.x(); \-
1351 else if (p.x() > maxx) maxx = p.x(); \-
1352 if (p.y() < miny) miny = p.y(); \-
1353 else if (p.y() > maxy) maxy = p.y(); \-
1354 }-
1355-
1356-
1357static QRectF qt_painterpath_bezier_extrema(const QBezier &b)-
1358{-
1359 qreal minx, miny, maxx, maxy;-
1360-
1361 // initialize with end points-
1362 if (b.x1 < b.x4) {
b.x1 < b.x4Description
TRUEnever evaluated
FALSEnever evaluated
0
1363 minx = b.x1;-
1364 maxx = b.x4;-
1365 } else {
never executed: end of block
0
1366 minx = b.x4;-
1367 maxx = b.x1;-
1368 }
never executed: end of block
0
1369 if (b.y1 < b.y4) {
b.y1 < b.y4Description
TRUEnever evaluated
FALSEnever evaluated
0
1370 miny = b.y1;-
1371 maxy = b.y4;-
1372 } else {
never executed: end of block
0
1373 miny = b.y4;-
1374 maxy = b.y1;-
1375 }
never executed: end of block
0
1376-
1377 // Update for the X extrema-
1378 {-
1379 qreal ax = QT_BEZIER_A(b, x);-
1380 qreal bx = QT_BEZIER_B(b, x);-
1381 qreal cx = QT_BEZIER_C(b, x);-
1382 // specialcase quadratic curves to avoid div by zero-
1383 if (qFuzzyIsNull(ax)) {
qFuzzyIsNull(ax)Description
TRUEnever evaluated
FALSEnever evaluated
0
1384-
1385 // linear curves are covered by initialization.-
1386 if (!qFuzzyIsNull(bx)) {
!qFuzzyIsNull(bx)Description
TRUEnever evaluated
FALSEnever evaluated
0
1387 qreal t = -cx / bx;-
1388 QT_BEZIER_CHECK_T(b, t);
never executed: minx = p.x();
never executed: maxx = p.x();
never executed: miny = p.y();
never executed: maxy = p.y();
never executed: end of block
p.x() > maxxDescription
TRUEnever evaluated
FALSEnever evaluated
p.y() > maxyDescription
TRUEnever evaluated
FALSEnever evaluated
p.x() < minxDescription
TRUEnever evaluated
FALSEnever evaluated
p.y() < minyDescription
TRUEnever evaluated
FALSEnever evaluated
t >= 0Description
TRUEnever evaluated
FALSEnever evaluated
t <= 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1389 }
never executed: end of block
0
1390-
1391 } else {
never executed: end of block
0
1392 const qreal tx = bx * bx - 4 * ax * cx;-
1393-
1394 if (tx >= 0) {
tx >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1395 qreal temp = qSqrt(tx);-
1396 qreal rcp = 1 / (2 * ax);-
1397 qreal t1 = (-bx + temp) * rcp;-
1398 QT_BEZIER_CHECK_T(b, t1);
never executed: minx = p.x();
never executed: maxx = p.x();
never executed: miny = p.y();
never executed: maxy = p.y();
never executed: end of block
p.x() > maxxDescription
TRUEnever evaluated
FALSEnever evaluated
p.y() > maxyDescription
TRUEnever evaluated
FALSEnever evaluated
p.x() < minxDescription
TRUEnever evaluated
FALSEnever evaluated
p.y() < minyDescription
TRUEnever evaluated
FALSEnever evaluated
t1 >= 0Description
TRUEnever evaluated
FALSEnever evaluated
t1 <= 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1399-
1400 qreal t2 = (-bx - temp) * rcp;-
1401 QT_BEZIER_CHECK_T(b, t2);
never executed: minx = p.x();
never executed: maxx = p.x();
never executed: miny = p.y();
never executed: maxy = p.y();
never executed: end of block
p.x() > maxxDescription
TRUEnever evaluated
FALSEnever evaluated
p.y() > maxyDescription
TRUEnever evaluated
FALSEnever evaluated
p.x() < minxDescription
TRUEnever evaluated
FALSEnever evaluated
p.y() < minyDescription
TRUEnever evaluated
FALSEnever evaluated
t2 >= 0Description
TRUEnever evaluated
FALSEnever evaluated
t2 <= 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1402 }
never executed: end of block
0
1403 }
never executed: end of block
0
1404 }-
1405-
1406 // Update for the Y extrema-
1407 {-
1408 qreal ay = QT_BEZIER_A(b, y);-
1409 qreal by = QT_BEZIER_B(b, y);-
1410 qreal cy = QT_BEZIER_C(b, y);-
1411-
1412 // specialcase quadratic curves to avoid div by zero-
1413 if (qFuzzyIsNull(ay)) {
qFuzzyIsNull(ay)Description
TRUEnever evaluated
FALSEnever evaluated
0
1414-
1415 // linear curves are covered by initialization.-
1416 if (!qFuzzyIsNull(by)) {
!qFuzzyIsNull(by)Description
TRUEnever evaluated
FALSEnever evaluated
0
1417 qreal t = -cy / by;-
1418 QT_BEZIER_CHECK_T(b, t);
never executed: minx = p.x();
never executed: maxx = p.x();
never executed: miny = p.y();
never executed: maxy = p.y();
never executed: end of block
p.x() > maxxDescription
TRUEnever evaluated
FALSEnever evaluated
p.y() > maxyDescription
TRUEnever evaluated
FALSEnever evaluated
p.x() < minxDescription
TRUEnever evaluated
FALSEnever evaluated
p.y() < minyDescription
TRUEnever evaluated
FALSEnever evaluated
t >= 0Description
TRUEnever evaluated
FALSEnever evaluated
t <= 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1419 }
never executed: end of block
0
1420-
1421 } else {
never executed: end of block
0
1422 const qreal ty = by * by - 4 * ay * cy;-
1423-
1424 if (ty > 0) {
ty > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1425 qreal temp = qSqrt(ty);-
1426 qreal rcp = 1 / (2 * ay);-
1427 qreal t1 = (-by + temp) * rcp;-
1428 QT_BEZIER_CHECK_T(b, t1);
never executed: minx = p.x();
never executed: maxx = p.x();
never executed: miny = p.y();
never executed: maxy = p.y();
never executed: end of block
p.x() > maxxDescription
TRUEnever evaluated
FALSEnever evaluated
p.y() > maxyDescription
TRUEnever evaluated
FALSEnever evaluated
p.x() < minxDescription
TRUEnever evaluated
FALSEnever evaluated
p.y() < minyDescription
TRUEnever evaluated
FALSEnever evaluated
t1 >= 0Description
TRUEnever evaluated
FALSEnever evaluated
t1 <= 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1429-
1430 qreal t2 = (-by - temp) * rcp;-
1431 QT_BEZIER_CHECK_T(b, t2);
never executed: minx = p.x();
never executed: maxx = p.x();
never executed: miny = p.y();
never executed: maxy = p.y();
never executed: end of block
p.x() > maxxDescription
TRUEnever evaluated
FALSEnever evaluated
p.y() > maxyDescription
TRUEnever evaluated
FALSEnever evaluated
p.x() < minxDescription
TRUEnever evaluated
FALSEnever evaluated
p.y() < minyDescription
TRUEnever evaluated
FALSEnever evaluated
t2 >= 0Description
TRUEnever evaluated
FALSEnever evaluated
t2 <= 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1432 }
never executed: end of block
0
1433 }
never executed: end of block
0
1434 }-
1435 return QRectF(minx, miny, maxx - minx, maxy - miny);
never executed: return QRectF(minx, miny, maxx - minx, maxy - miny);
0
1436}-
1437-
1438/*!-
1439 Returns the bounding rectangle of this painter path as a rectangle with-
1440 floating point precision.-
1441-
1442 \sa controlPointRect()-
1443*/-
1444QRectF QPainterPath::boundingRect() const-
1445{-
1446 if (!d_ptr)
!d_ptrDescription
TRUEnever evaluated
FALSEnever evaluated
0
1447 return QRectF();
never executed: return QRectF();
0
1448 QPainterPathData *d = d_func();-
1449-
1450 if (d->dirtyBounds)
d->dirtyBoundsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1451 computeBoundingRect();
never executed: computeBoundingRect();
0
1452 return d->bounds;
never executed: return d->bounds;
0
1453}-
1454-
1455/*!-
1456 Returns the rectangle containing all the points and control points-
1457 in this path.-
1458-
1459 This function is significantly faster to compute than the exact-
1460 boundingRect(), and the returned rectangle is always a superset of-
1461 the rectangle returned by boundingRect().-
1462-
1463 \sa boundingRect()-
1464*/-
1465QRectF QPainterPath::controlPointRect() const-
1466{-
1467 if (!d_ptr)
!d_ptrDescription
TRUEnever evaluated
FALSEnever evaluated
0
1468 return QRectF();
never executed: return QRectF();
0
1469 QPainterPathData *d = d_func();-
1470-
1471 if (d->dirtyControlBounds)
d->dirtyControlBoundsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1472 computeControlPointRect();
never executed: computeControlPointRect();
0
1473 return d->controlBounds;
never executed: return d->controlBounds;
0
1474}-
1475-
1476-
1477/*!-
1478 \fn bool QPainterPath::isEmpty() const-
1479-
1480 Returns \c true if either there are no elements in this path, or if the only-
1481 element is a MoveToElement; otherwise returns \c false.-
1482-
1483 \sa elementCount()-
1484*/-
1485-
1486bool QPainterPath::isEmpty() const-
1487{-
1488 return !d_ptr || (d_ptr->elements.size() == 1 && d_ptr->elements.first().type == MoveToElement);
never executed: return !d_ptr || (d_ptr->elements.size() == 1 && d_ptr->elements.first().type == MoveToElement);
!d_ptrDescription
TRUEnever evaluated
FALSEnever evaluated
d_ptr->elements.size() == 1Description
TRUEnever evaluated
FALSEnever evaluated
d_ptr->element... MoveToElementDescription
TRUEnever evaluated
FALSEnever evaluated
0
1489}-
1490-
1491/*!-
1492 Creates and returns a reversed copy of the path.-
1493-
1494 It is the order of the elements that is reversed: If a-
1495 QPainterPath is composed by calling the moveTo(), lineTo() and-
1496 cubicTo() functions in the specified order, the reversed copy is-
1497 composed by calling cubicTo(), lineTo() and moveTo().-
1498*/-
1499QPainterPath QPainterPath::toReversed() const-
1500{-
1501 Q_D(const QPainterPath);-
1502 QPainterPath rev;-
1503-
1504 if (isEmpty()) {
isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
1505 rev = *this;-
1506 return rev;
never executed: return rev;
0
1507 }-
1508-
1509 rev.moveTo(d->elements.at(d->elements.size()-1).x, d->elements.at(d->elements.size()-1).y);-
1510-
1511 for (int i=d->elements.size()-1; i>=1; --i) {
i>=1Description
TRUEnever evaluated
FALSEnever evaluated
0
1512 const QPainterPath::Element &elm = d->elements.at(i);-
1513 const QPainterPath::Element &prev = d->elements.at(i-1);-
1514 switch (elm.type) {-
1515 case LineToElement:
never executed: case LineToElement:
0
1516 rev.lineTo(prev.x, prev.y);-
1517 break;
never executed: break;
0
1518 case MoveToElement:
never executed: case MoveToElement:
0
1519 rev.moveTo(prev.x, prev.y);-
1520 break;
never executed: break;
0
1521 case CurveToDataElement:
never executed: case CurveToDataElement:
0
1522 {-
1523 Q_ASSERT(i>=3);-
1524 const QPainterPath::Element &cp1 = d->elements.at(i-2);-
1525 const QPainterPath::Element &sp = d->elements.at(i-3);-
1526 Q_ASSERT(prev.type == CurveToDataElement);-
1527 Q_ASSERT(cp1.type == CurveToElement);-
1528 rev.cubicTo(prev.x, prev.y, cp1.x, cp1.y, sp.x, sp.y);-
1529 i -= 2;-
1530 break;
never executed: break;
0
1531 }-
1532 default:
never executed: default:
0
1533 Q_ASSERT(!"qt_reversed_path");-
1534 break;
never executed: break;
0
1535 }-
1536 }-
1537 //qt_debug_path(rev);-
1538 return rev;
never executed: return rev;
0
1539}-
1540-
1541/*!-
1542 Converts the path into a list of polygons using the QTransform-
1543 \a matrix, and returns the list.-
1544-
1545 This function creates one polygon for each subpath regardless of-
1546 intersecting subpaths (i.e. overlapping bounding rectangles). To-
1547 make sure that such overlapping subpaths are filled correctly, use-
1548 the toFillPolygons() function instead.-
1549-
1550 \sa toFillPolygons(), toFillPolygon(), {QPainterPath#QPainterPath-
1551 Conversion}{QPainterPath Conversion}-
1552*/-
1553QList<QPolygonF> QPainterPath::toSubpathPolygons(const QTransform &matrix) const-
1554{-
1555-
1556 Q_D(const QPainterPath);-
1557 QList<QPolygonF> flatCurves;-
1558 if (isEmpty())
isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
1559 return flatCurves;
never executed: return flatCurves;
0
1560-
1561 QPolygonF current;-
1562 for (int i=0; i<elementCount(); ++i) {
i<elementCount()Description
TRUEnever evaluated
FALSEnever evaluated
0
1563 const QPainterPath::Element &e = d->elements.at(i);-
1564 switch (e.type) {-
1565 case QPainterPath::MoveToElement:
never executed: case QPainterPath::MoveToElement:
0
1566 if (current.size() > 1)
current.size() > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1567 flatCurves += current;
never executed: flatCurves += current;
0
1568 current.clear();-
1569 current.reserve(16);-
1570 current += QPointF(e.x, e.y) * matrix;-
1571 break;
never executed: break;
0
1572 case QPainterPath::LineToElement:
never executed: case QPainterPath::LineToElement:
0
1573 current += QPointF(e.x, e.y) * matrix;-
1574 break;
never executed: break;
0
1575 case QPainterPath::CurveToElement: {
never executed: case QPainterPath::CurveToElement:
0
1576 Q_ASSERT(d->elements.at(i+1).type == QPainterPath::CurveToDataElement);-
1577 Q_ASSERT(d->elements.at(i+2).type == QPainterPath::CurveToDataElement);-
1578 QBezier bezier = QBezier::fromPoints(QPointF(d->elements.at(i-1).x, d->elements.at(i-1).y) * matrix,-
1579 QPointF(e.x, e.y) * matrix,-
1580 QPointF(d->elements.at(i+1).x, d->elements.at(i+1).y) * matrix,-
1581 QPointF(d->elements.at(i+2).x, d->elements.at(i+2).y) * matrix);-
1582 bezier.addToPolygon(&current);-
1583 i+=2;-
1584 break;
never executed: break;
0
1585 }-
1586 case QPainterPath::CurveToDataElement:
never executed: case QPainterPath::CurveToDataElement:
0
1587 Q_ASSERT(!"QPainterPath::toSubpathPolygons(), bad element type");-
1588 break;
never executed: break;
0
1589 }-
1590 }
never executed: end of block
0
1591-
1592 if (current.size()>1)
current.size()>1Description
TRUEnever evaluated
FALSEnever evaluated
0
1593 flatCurves += current;
never executed: flatCurves += current;
0
1594-
1595 return flatCurves;
never executed: return flatCurves;
0
1596}-
1597-
1598/*!-
1599 \overload-
1600 */-
1601QList<QPolygonF> QPainterPath::toSubpathPolygons(const QMatrix &matrix) const-
1602{-
1603 return toSubpathPolygons(QTransform(matrix));
never executed: return toSubpathPolygons(QTransform(matrix));
0
1604}-
1605-
1606/*!-
1607 Converts the path into a list of polygons using the-
1608 QTransform \a matrix, and returns the list.-
1609-
1610 The function differs from the toFillPolygon() function in that it-
1611 creates several polygons. It is provided because it is usually-
1612 faster to draw several small polygons than to draw one large-
1613 polygon, even though the total number of points drawn is the same.-
1614-
1615 The toFillPolygons() function differs from the toSubpathPolygons()-
1616 function in that it create only polygon for subpaths that have-
1617 overlapping bounding rectangles.-
1618-
1619 Like the toFillPolygon() function, this function uses a rewinding-
1620 technique to make sure that overlapping subpaths can be filled-
1621 using the correct fill rule. Note that rewinding inserts addition-
1622 lines in the polygons so the outline of the fill polygon does not-
1623 match the outline of the path.-
1624-
1625 \sa toSubpathPolygons(), toFillPolygon(),-
1626 {QPainterPath#QPainterPath Conversion}{QPainterPath Conversion}-
1627*/-
1628QList<QPolygonF> QPainterPath::toFillPolygons(const QTransform &matrix) const-
1629{-
1630-
1631 QList<QPolygonF> polys;-
1632-
1633 QList<QPolygonF> subpaths = toSubpathPolygons(matrix);-
1634 int count = subpaths.size();-
1635-
1636 if (count == 0)
count == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1637 return polys;
never executed: return polys;
0
1638-
1639 QVector<QRectF> bounds;-
1640 bounds.reserve(count);-
1641 for (int i=0; i<count; ++i)
i<countDescription
TRUEnever evaluated
FALSEnever evaluated
0
1642 bounds += subpaths.at(i).boundingRect();
never executed: bounds += subpaths.at(i).boundingRect();
0
1643-
1644#ifdef QPP_FILLPOLYGONS_DEBUG-
1645 printf("QPainterPath::toFillPolygons, subpathCount=%d\n", count);-
1646 for (int i=0; i<bounds.size(); ++i)-
1647 qDebug() << " bounds" << i << bounds.at(i);-
1648#endif-
1649-
1650 QVector< QList<int> > isects;-
1651 isects.resize(count);-
1652-
1653 // find all intersections-
1654 for (int j=0; j<count; ++j) {
j<countDescription
TRUEnever evaluated
FALSEnever evaluated
0
1655 if (subpaths.at(j).size() <= 2)
subpaths.at(j).size() <= 2Description
TRUEnever evaluated
FALSEnever evaluated
0
1656 continue;
never executed: continue;
0
1657 QRectF cbounds = bounds.at(j);-
1658 for (int i=0; i<count; ++i) {
i<countDescription
TRUEnever evaluated
FALSEnever evaluated
0
1659 if (cbounds.intersects(bounds.at(i))) {
cbounds.inters...(bounds.at(i))Description
TRUEnever evaluated
FALSEnever evaluated
0
1660 isects[j] << i;-
1661 }
never executed: end of block
0
1662 }
never executed: end of block
0
1663 }
never executed: end of block
0
1664-
1665#ifdef QPP_FILLPOLYGONS_DEBUG-
1666 printf("Intersections before flattening:\n");-
1667 for (int i = 0; i < count; ++i) {-
1668 printf("%d: ", i);-
1669 for (int j = 0; j < isects[i].size(); ++j) {-
1670 printf("%d ", isects[i][j]);-
1671 }-
1672 printf("\n");-
1673 }-
1674#endif-
1675-
1676 // flatten the sets of intersections-
1677 for (int i=0; i<count; ++i) {
i<countDescription
TRUEnever evaluated
FALSEnever evaluated
0
1678 const QList<int> &current_isects = isects.at(i);-
1679 for (int j=0; j<current_isects.size(); ++j) {
j<current_isects.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1680 int isect_j = current_isects.at(j);-
1681 if (isect_j == i)
isect_j == iDescription
TRUEnever evaluated
FALSEnever evaluated
0
1682 continue;
never executed: continue;
0
1683 for (int k=0; k<isects[isect_j].size(); ++k) {
k<isects[isect_j].size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1684 int isect_k = isects[isect_j][k];-
1685 if (isect_k != i && !isects.at(i).contains(isect_k)) {
isect_k != iDescription
TRUEnever evaluated
FALSEnever evaluated
!isects.at(i)....tains(isect_k)Description
TRUEnever evaluated
FALSEnever evaluated
0
1686 isects[i] += isect_k;-
1687 }
never executed: end of block
0
1688 }
never executed: end of block
0
1689 isects[isect_j].clear();-
1690 }
never executed: end of block
0
1691 }
never executed: end of block
0
1692-
1693#ifdef QPP_FILLPOLYGONS_DEBUG-
1694 printf("Intersections after flattening:\n");-
1695 for (int i = 0; i < count; ++i) {-
1696 printf("%d: ", i);-
1697 for (int j = 0; j < isects[i].size(); ++j) {-
1698 printf("%d ", isects[i][j]);-
1699 }-
1700 printf("\n");-
1701 }-
1702#endif-
1703-
1704 // Join the intersected subpaths as rewinded polygons-
1705 for (int i=0; i<count; ++i) {
i<countDescription
TRUEnever evaluated
FALSEnever evaluated
0
1706 const QList<int> &subpath_list = isects[i];-
1707 if (!subpath_list.isEmpty()) {
!subpath_list.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
1708 QPolygonF buildUp;-
1709 for (int j=0; j<subpath_list.size(); ++j) {
j<subpath_list.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1710 const QPolygonF &subpath = subpaths.at(subpath_list.at(j));-
1711 buildUp += subpath;-
1712 if (!subpath.isClosed())
!subpath.isClosed()Description
TRUEnever evaluated
FALSEnever evaluated
0
1713 buildUp += subpath.first();
never executed: buildUp += subpath.first();
0
1714 if (!buildUp.isClosed())
!buildUp.isClosed()Description
TRUEnever evaluated
FALSEnever evaluated
0
1715 buildUp += buildUp.first();
never executed: buildUp += buildUp.first();
0
1716 }
never executed: end of block
0
1717 polys += buildUp;-
1718 }
never executed: end of block
0
1719 }
never executed: end of block
0
1720-
1721 return polys;
never executed: return polys;
0
1722}-
1723-
1724/*!-
1725 \overload-
1726 */-
1727QList<QPolygonF> QPainterPath::toFillPolygons(const QMatrix &matrix) const-
1728{-
1729 return toFillPolygons(QTransform(matrix));
never executed: return toFillPolygons(QTransform(matrix));
0
1730}-
1731-
1732//same as qt_polygon_isect_line in qpolygon.cpp-
1733static void qt_painterpath_isect_line(const QPointF &p1,-
1734 const QPointF &p2,-
1735 const QPointF &pos,-
1736 int *winding)-
1737{-
1738 qreal x1 = p1.x();-
1739 qreal y1 = p1.y();-
1740 qreal x2 = p2.x();-
1741 qreal y2 = p2.y();-
1742 qreal y = pos.y();-
1743-
1744 int dir = 1;-
1745-
1746 if (qFuzzyCompare(y1, y2)) {
qFuzzyCompare(y1, y2)Description
TRUEnever evaluated
FALSEnever evaluated
0
1747 // ignore horizontal lines according to scan conversion rule-
1748 return;
never executed: return;
0
1749 } else if (y2 < y1) {
y2 < y1Description
TRUEnever evaluated
FALSEnever evaluated
0
1750 qreal x_tmp = x2; x2 = x1; x1 = x_tmp;-
1751 qreal y_tmp = y2; y2 = y1; y1 = y_tmp;-
1752 dir = -1;-
1753 }
never executed: end of block
0
1754-
1755 if (y >= y1 && y < y2) {
y >= y1Description
TRUEnever evaluated
FALSEnever evaluated
y < y2Description
TRUEnever evaluated
FALSEnever evaluated
0
1756 qreal x = x1 + ((x2 - x1) / (y2 - y1)) * (y - y1);-
1757-
1758 // count up the winding number if we're-
1759 if (x<=pos.x()) {
x<=pos.x()Description
TRUEnever evaluated
FALSEnever evaluated
0
1760 (*winding) += dir;-
1761 }
never executed: end of block
0
1762 }
never executed: end of block
0
1763}
never executed: end of block
0
1764-
1765static void qt_painterpath_isect_curve(const QBezier &bezier, const QPointF &pt,-
1766 int *winding, int depth = 0)-
1767{-
1768 qreal y = pt.y();-
1769 qreal x = pt.x();-
1770 QRectF bounds = bezier.bounds();-
1771-
1772 // potential intersection, divide and try again...-
1773 // Please note that a sideeffect of the bottom exclusion is that-
1774 // horizontal lines are dropped, but this is correct according to-
1775 // scan conversion rules.-
1776 if (y >= bounds.y() && y < bounds.y() + bounds.height()) {
y >= bounds.y()Description
TRUEnever evaluated
FALSEnever evaluated
y < bounds.y()...ounds.height()Description
TRUEnever evaluated
FALSEnever evaluated
0
1777-
1778 // hit lower limit... This is a rough threshold, but its a-
1779 // tradeoff between speed and precision.-
1780 const qreal lower_bound = qreal(.001);-
1781 if (depth == 32 || (bounds.width() < lower_bound && bounds.height() < lower_bound)) {
depth == 32Description
TRUEnever evaluated
FALSEnever evaluated
bounds.width() < lower_boundDescription
TRUEnever evaluated
FALSEnever evaluated
bounds.height() < lower_boundDescription
TRUEnever evaluated
FALSEnever evaluated
0
1782 // We make the assumption here that the curve starts to-
1783 // approximate a line after while (i.e. that it doesn't-
1784 // change direction drastically during its slope)-
1785 if (bezier.pt1().x() <= x) {
bezier.pt1().x() <= xDescription
TRUEnever evaluated
FALSEnever evaluated
0
1786 (*winding) += (bezier.pt4().y() > bezier.pt1().y() ? 1 : -1);
bezier.pt4().y...zier.pt1().y()Description
TRUEnever evaluated
FALSEnever evaluated
0
1787 }
never executed: end of block
0
1788 return;
never executed: return;
0
1789 }-
1790-
1791 // split curve and try again...-
1792 QBezier first_half, second_half;-
1793 bezier.split(&first_half, &second_half);-
1794 qt_painterpath_isect_curve(first_half, pt, winding, depth + 1);-
1795 qt_painterpath_isect_curve(second_half, pt, winding, depth + 1);-
1796 }
never executed: end of block
0
1797}
never executed: end of block
0
1798-
1799/*!-
1800 \fn bool QPainterPath::contains(const QPointF &point) const-
1801-
1802 Returns \c true if the given \a point is inside the path, otherwise-
1803 returns \c false.-
1804-
1805 \sa intersects()-
1806*/-
1807bool QPainterPath::contains(const QPointF &pt) const-
1808{-
1809 if (isEmpty() || !controlPointRect().contains(pt))
isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
!controlPointR...).contains(pt)Description
TRUEnever evaluated
FALSEnever evaluated
0
1810 return false;
never executed: return false;
0
1811-
1812 QPainterPathData *d = d_func();-
1813-
1814 int winding_number = 0;-
1815-
1816 QPointF last_pt;-
1817 QPointF last_start;-
1818 for (int i=0; i<d->elements.size(); ++i) {
i<d->elements.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1819 const Element &e = d->elements.at(i);-
1820-
1821 switch (e.type) {-
1822-
1823 case MoveToElement:
never executed: case MoveToElement:
0
1824 if (i > 0) // implicitly close all paths.
i > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1825 qt_painterpath_isect_line(last_pt, last_start, pt, &winding_number);
never executed: qt_painterpath_isect_line(last_pt, last_start, pt, &winding_number);
0
1826 last_start = last_pt = e;-
1827 break;
never executed: break;
0
1828-
1829 case LineToElement:
never executed: case LineToElement:
0
1830 qt_painterpath_isect_line(last_pt, e, pt, &winding_number);-
1831 last_pt = e;-
1832 break;
never executed: break;
0
1833-
1834 case CurveToElement:
never executed: case CurveToElement:
0
1835 {-
1836 const QPainterPath::Element &cp2 = d->elements.at(++i);-
1837 const QPainterPath::Element &ep = d->elements.at(++i);-
1838 qt_painterpath_isect_curve(QBezier::fromPoints(last_pt, e, cp2, ep),-
1839 pt, &winding_number);-
1840 last_pt = ep;-
1841-
1842 }-
1843 break;
never executed: break;
0
1844-
1845 default:
never executed: default:
0
1846 break;
never executed: break;
0
1847 }-
1848 }-
1849-
1850 // implicitly close last subpath-
1851 if (last_pt != last_start)
last_pt != last_startDescription
TRUEnever evaluated
FALSEnever evaluated
0
1852 qt_painterpath_isect_line(last_pt, last_start, pt, &winding_number);
never executed: qt_painterpath_isect_line(last_pt, last_start, pt, &winding_number);
0
1853-
1854 return (d->fillRule == Qt::WindingFill
never executed: return (d->fillRule == Qt::WindingFill ? (winding_number != 0) : ((winding_number % 2) != 0));
d->fillRule == Qt::WindingFillDescription
TRUEnever evaluated
FALSEnever evaluated
0
1855 ? (winding_number != 0)
never executed: return (d->fillRule == Qt::WindingFill ? (winding_number != 0) : ((winding_number % 2) != 0));
0
1856 : ((winding_number % 2) != 0));
never executed: return (d->fillRule == Qt::WindingFill ? (winding_number != 0) : ((winding_number % 2) != 0));
0
1857}-
1858-
1859static bool qt_painterpath_isect_line_rect(qreal x1, qreal y1, qreal x2, qreal y2,-
1860 const QRectF &rect)-
1861{-
1862 qreal left = rect.left();-
1863 qreal right = rect.right();-
1864 qreal top = rect.top();-
1865 qreal bottom = rect.bottom();-
1866-
1867 enum { Left, Right, Top, Bottom };-
1868 // clip the lines, after cohen-sutherland, see e.g. http://www.nondot.org/~sabre/graphpro/line6.html-
1869 int p1 = ((x1 < left) << Left)-
1870 | ((x1 > right) << Right)-
1871 | ((y1 < top) << Top)-
1872 | ((y1 > bottom) << Bottom);-
1873 int p2 = ((x2 < left) << Left)-
1874 | ((x2 > right) << Right)-
1875 | ((y2 < top) << Top)-
1876 | ((y2 > bottom) << Bottom);-
1877-
1878 if (p1 & p2)
p1 & p2Description
TRUEnever evaluated
FALSEnever evaluated
0
1879 // completely inside-
1880 return false;
never executed: return false;
0
1881-
1882 if (p1 | p2) {
p1 | p2Description
TRUEnever evaluated
FALSEnever evaluated
0
1883 qreal dx = x2 - x1;-
1884 qreal dy = y2 - y1;-
1885-
1886 // clip x coordinates-
1887 if (x1 < left) {
x1 < leftDescription
TRUEnever evaluated
FALSEnever evaluated
0
1888 y1 += dy/dx * (left - x1);-
1889 x1 = left;-
1890 } else if (x1 > right) {
never executed: end of block
x1 > rightDescription
TRUEnever evaluated
FALSEnever evaluated
0
1891 y1 -= dy/dx * (x1 - right);-
1892 x1 = right;-
1893 }
never executed: end of block
0
1894 if (x2 < left) {
x2 < leftDescription
TRUEnever evaluated
FALSEnever evaluated
0
1895 y2 += dy/dx * (left - x2);-
1896 x2 = left;-
1897 } else if (x2 > right) {
never executed: end of block
x2 > rightDescription
TRUEnever evaluated
FALSEnever evaluated
0
1898 y2 -= dy/dx * (x2 - right);-
1899 x2 = right;-
1900 }
never executed: end of block
0
1901-
1902 p1 = ((y1 < top) << Top)-
1903 | ((y1 > bottom) << Bottom);-
1904 p2 = ((y2 < top) << Top)-
1905 | ((y2 > bottom) << Bottom);-
1906-
1907 if (p1 & p2)
p1 & p2Description
TRUEnever evaluated
FALSEnever evaluated
0
1908 return false;
never executed: return false;
0
1909-
1910 // clip y coordinates-
1911 if (y1 < top) {
y1 < topDescription
TRUEnever evaluated
FALSEnever evaluated
0
1912 x1 += dx/dy * (top - y1);-
1913 y1 = top;-
1914 } else if (y1 > bottom) {
never executed: end of block
y1 > bottomDescription
TRUEnever evaluated
FALSEnever evaluated
0
1915 x1 -= dx/dy * (y1 - bottom);-
1916 y1 = bottom;-
1917 }
never executed: end of block
0
1918 if (y2 < top) {
y2 < topDescription
TRUEnever evaluated
FALSEnever evaluated
0
1919 x2 += dx/dy * (top - y2);-
1920 y2 = top;-
1921 } else if (y2 > bottom) {
never executed: end of block
y2 > bottomDescription
TRUEnever evaluated
FALSEnever evaluated
0
1922 x2 -= dx/dy * (y2 - bottom);-
1923 y2 = bottom;-
1924 }
never executed: end of block
0
1925-
1926 p1 = ((x1 < left) << Left)-
1927 | ((x1 > right) << Right);-
1928 p2 = ((x2 < left) << Left)-
1929 | ((x2 > right) << Right);-
1930-
1931 if (p1 & p2)
p1 & p2Description
TRUEnever evaluated
FALSEnever evaluated
0
1932 return false;
never executed: return false;
0
1933-
1934 return true;
never executed: return true;
0
1935 }-
1936 return false;
never executed: return false;
0
1937}-
1938-
1939static bool qt_isect_curve_horizontal(const QBezier &bezier, qreal y, qreal x1, qreal x2, int depth = 0)-
1940{-
1941 QRectF bounds = bezier.bounds();-
1942-
1943 if (y >= bounds.top() && y < bounds.bottom()
y >= bounds.top()Description
TRUEnever evaluated
FALSEnever evaluated
y < bounds.bottom()Description
TRUEnever evaluated
FALSEnever evaluated
0
1944 && bounds.right() >= x1 && bounds.left() < x2) {
bounds.right() >= x1Description
TRUEnever evaluated
FALSEnever evaluated
bounds.left() < x2Description
TRUEnever evaluated
FALSEnever evaluated
0
1945 const qreal lower_bound = qreal(.01);-
1946 if (depth == 32 || (bounds.width() < lower_bound && bounds.height() < lower_bound))
depth == 32Description
TRUEnever evaluated
FALSEnever evaluated
bounds.width() < lower_boundDescription
TRUEnever evaluated
FALSEnever evaluated
bounds.height() < lower_boundDescription
TRUEnever evaluated
FALSEnever evaluated
0
1947 return true;
never executed: return true;
0
1948-
1949 QBezier first_half, second_half;-
1950 bezier.split(&first_half, &second_half);-
1951 if (qt_isect_curve_horizontal(first_half, y, x1, x2, depth + 1)
qt_isect_curve...x2, depth + 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
1952 || qt_isect_curve_horizontal(second_half, y, x1, x2, depth + 1))
qt_isect_curve...x2, depth + 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
1953 return true;
never executed: return true;
0
1954 }
never executed: end of block
0
1955 return false;
never executed: return false;
0
1956}-
1957-
1958static bool qt_isect_curve_vertical(const QBezier &bezier, qreal x, qreal y1, qreal y2, int depth = 0)-
1959{-
1960 QRectF bounds = bezier.bounds();-
1961-
1962 if (x >= bounds.left() && x < bounds.right()
x >= bounds.left()Description
TRUEnever evaluated
FALSEnever evaluated
x < bounds.right()Description
TRUEnever evaluated
FALSEnever evaluated
0
1963 && bounds.bottom() >= y1 && bounds.top() < y2) {
bounds.bottom() >= y1Description
TRUEnever evaluated
FALSEnever evaluated
bounds.top() < y2Description
TRUEnever evaluated
FALSEnever evaluated
0
1964 const qreal lower_bound = qreal(.01);-
1965 if (depth == 32 || (bounds.width() < lower_bound && bounds.height() < lower_bound))
depth == 32Description
TRUEnever evaluated
FALSEnever evaluated
bounds.width() < lower_boundDescription
TRUEnever evaluated
FALSEnever evaluated
bounds.height() < lower_boundDescription
TRUEnever evaluated
FALSEnever evaluated
0
1966 return true;
never executed: return true;
0
1967-
1968 QBezier first_half, second_half;-
1969 bezier.split(&first_half, &second_half);-
1970 if (qt_isect_curve_vertical(first_half, x, y1, y2, depth + 1)
qt_isect_curve...y2, depth + 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
1971 || qt_isect_curve_vertical(second_half, x, y1, y2, depth + 1))
qt_isect_curve...y2, depth + 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
1972 return true;
never executed: return true;
0
1973 }
never executed: end of block
0
1974 return false;
never executed: return false;
0
1975}-
1976-
1977/*-
1978 Returns \c true if any lines or curves cross the four edges in of rect-
1979*/-
1980static bool qt_painterpath_check_crossing(const QPainterPath *path, const QRectF &rect)-
1981{-
1982 QPointF last_pt;-
1983 QPointF last_start;-
1984 for (int i=0; i<path->elementCount(); ++i) {
i<path->elementCount()Description
TRUEnever evaluated
FALSEnever evaluated
0
1985 const QPainterPath::Element &e = path->elementAt(i);-
1986-
1987 switch (e.type) {-
1988-
1989 case QPainterPath::MoveToElement:
never executed: case QPainterPath::MoveToElement:
0
1990 if (i > 0
i > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1991 && qFuzzyCompare(last_pt.x(), last_start.x())
qFuzzyCompare(...ast_start.x())Description
TRUEnever evaluated
FALSEnever evaluated
0
1992 && qFuzzyCompare(last_pt.y(), last_start.y())
qFuzzyCompare(...ast_start.y())Description
TRUEnever evaluated
FALSEnever evaluated
0
1993 && qt_painterpath_isect_line_rect(last_pt.x(), last_pt.y(),
qt_painterpath...art.y(), rect)Description
TRUEnever evaluated
FALSEnever evaluated
0
1994 last_start.x(), last_start.y(), rect))
qt_painterpath...art.y(), rect)Description
TRUEnever evaluated
FALSEnever evaluated
0
1995 return true;
never executed: return true;
0
1996 last_start = last_pt = e;-
1997 break;
never executed: break;
0
1998-
1999 case QPainterPath::LineToElement:
never executed: case QPainterPath::LineToElement:
0
2000 if (qt_painterpath_isect_line_rect(last_pt.x(), last_pt.y(), e.x, e.y, rect))
qt_painterpath....x, e.y, rect)Description
TRUEnever evaluated
FALSEnever evaluated
0
2001 return true;
never executed: return true;
0
2002 last_pt = e;-
2003 break;
never executed: break;
0
2004-
2005 case QPainterPath::CurveToElement:
never executed: case QPainterPath::CurveToElement:
0
2006 {-
2007 QPointF cp2 = path->elementAt(++i);-
2008 QPointF ep = path->elementAt(++i);-
2009 QBezier bezier = QBezier::fromPoints(last_pt, e, cp2, ep);-
2010 if (qt_isect_curve_horizontal(bezier, rect.top(), rect.left(), rect.right())
qt_isect_curve... rect.right())Description
TRUEnever evaluated
FALSEnever evaluated
0
2011 || qt_isect_curve_horizontal(bezier, rect.bottom(), rect.left(), rect.right())
qt_isect_curve... rect.right())Description
TRUEnever evaluated
FALSEnever evaluated
0
2012 || qt_isect_curve_vertical(bezier, rect.left(), rect.top(), rect.bottom())
qt_isect_curve...rect.bottom())Description
TRUEnever evaluated
FALSEnever evaluated
0
2013 || qt_isect_curve_vertical(bezier, rect.right(), rect.top(), rect.bottom()))
qt_isect_curve...rect.bottom())Description
TRUEnever evaluated
FALSEnever evaluated
0
2014 return true;
never executed: return true;
0
2015 last_pt = ep;-
2016 }-
2017 break;
never executed: break;
0
2018-
2019 default:
never executed: default:
0
2020 break;
never executed: break;
0
2021 }-
2022 }-
2023-
2024 // implicitly close last subpath-
2025 if (last_pt != last_start
last_pt != last_startDescription
TRUEnever evaluated
FALSEnever evaluated
0
2026 && qt_painterpath_isect_line_rect(last_pt.x(), last_pt.y(),
qt_painterpath...art.y(), rect)Description
TRUEnever evaluated
FALSEnever evaluated
0
2027 last_start.x(), last_start.y(), rect))
qt_painterpath...art.y(), rect)Description
TRUEnever evaluated
FALSEnever evaluated
0
2028 return true;
never executed: return true;
0
2029-
2030 return false;
never executed: return false;
0
2031}-
2032-
2033/*!-
2034 \fn bool QPainterPath::intersects(const QRectF &rectangle) const-
2035-
2036 Returns \c true if any point in the given \a rectangle intersects the-
2037 path; otherwise returns \c false.-
2038-
2039 There is an intersection if any of the lines making up the-
2040 rectangle crosses a part of the path or if any part of the-
2041 rectangle overlaps with any area enclosed by the path. This-
2042 function respects the current fillRule to determine what is-
2043 considered inside the path.-
2044-
2045 \sa contains()-
2046*/-
2047bool QPainterPath::intersects(const QRectF &rect) const-
2048{-
2049 if (elementCount() == 1 && rect.contains(elementAt(0)))
elementCount() == 1Description
TRUEnever evaluated
FALSEnever evaluated
rect.contains(elementAt(0))Description
TRUEnever evaluated
FALSEnever evaluated
0
2050 return true;
never executed: return true;
0
2051-
2052 if (isEmpty())
isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
2053 return false;
never executed: return false;
0
2054-
2055 QRectF cp = controlPointRect();-
2056 QRectF rn = rect.normalized();-
2057-
2058 // QRectF::intersects returns false if one of the rects is a null rect-
2059 // which would happen for a painter path consisting of a vertical or-
2060 // horizontal line-
2061 if (qMax(rn.left(), cp.left()) > qMin(rn.right(), cp.right())
qMax(rn.left()...), cp.right())Description
TRUEnever evaluated
FALSEnever evaluated
0
2062 || qMax(rn.top(), cp.top()) > qMin(rn.bottom(), cp.bottom()))
qMax(rn.top(),..., cp.bottom())Description
TRUEnever evaluated
FALSEnever evaluated
0
2063 return false;
never executed: return false;
0
2064-
2065 // If any path element cross the rect its bound to be an intersection-
2066 if (qt_painterpath_check_crossing(this, rect))
qt_painterpath...ng(this, rect)Description
TRUEnever evaluated
FALSEnever evaluated
0
2067 return true;
never executed: return true;
0
2068-
2069 if (contains(rect.center()))
contains(rect.center())Description
TRUEnever evaluated
FALSEnever evaluated
0
2070 return true;
never executed: return true;
0
2071-
2072 Q_D(QPainterPath);-
2073-
2074 // Check if the rectangle surounds any subpath...-
2075 for (int i=0; i<d->elements.size(); ++i) {
i<d->elements.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
2076 const Element &e = d->elements.at(i);-
2077 if (e.type == QPainterPath::MoveToElement && rect.contains(e))
e.type == QPai...:MoveToElementDescription
TRUEnever evaluated
FALSEnever evaluated
rect.contains(e)Description
TRUEnever evaluated
FALSEnever evaluated
0
2078 return true;
never executed: return true;
0
2079 }
never executed: end of block
0
2080-
2081 return false;
never executed: return false;
0
2082}-
2083-
2084/*!-
2085 Translates all elements in the path by (\a{dx}, \a{dy}).-
2086-
2087 \since 4.6-
2088 \sa translated()-
2089*/-
2090void QPainterPath::translate(qreal dx, qreal dy)-
2091{-
2092 if (!d_ptr || (dx == 0 && dy == 0))
!d_ptrDescription
TRUEnever evaluated
FALSEnever evaluated
dx == 0Description
TRUEnever evaluated
FALSEnever evaluated
dy == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2093 return;
never executed: return;
0
2094-
2095 int elementsLeft = d_ptr->elements.size();-
2096 if (elementsLeft <= 0)
elementsLeft <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2097 return;
never executed: return;
0
2098-
2099 detach();-
2100 QPainterPath::Element *element = d_func()->elements.data();-
2101 Q_ASSERT(element);-
2102 while (elementsLeft--) {
elementsLeft--Description
TRUEnever evaluated
FALSEnever evaluated
0
2103 element->x += dx;-
2104 element->y += dy;-
2105 ++element;-
2106 }
never executed: end of block
0
2107}
never executed: end of block
0
2108-
2109/*!-
2110 \fn void QPainterPath::translate(const QPointF &offset)-
2111 \overload-
2112 \since 4.6-
2113-
2114 Translates all elements in the path by the given \a offset.-
2115-
2116 \sa translated()-
2117*/-
2118-
2119/*!-
2120 Returns a copy of the path that is translated by (\a{dx}, \a{dy}).-
2121-
2122 \since 4.6-
2123 \sa translate()-
2124*/-
2125QPainterPath QPainterPath::translated(qreal dx, qreal dy) const-
2126{-
2127 QPainterPath copy(*this);-
2128 copy.translate(dx, dy);-
2129 return copy;
never executed: return copy;
0
2130}-
2131-
2132/*!-
2133 \fn QPainterPath QPainterPath::translated(const QPointF &offset) const;-
2134 \overload-
2135 \since 4.6-
2136-
2137 Returns a copy of the path that is translated by the given \a offset.-
2138-
2139 \sa translate()-
2140*/-
2141-
2142/*!-
2143 \fn bool QPainterPath::contains(const QRectF &rectangle) const-
2144-
2145 Returns \c true if the given \a rectangle is inside the path,-
2146 otherwise returns \c false.-
2147*/-
2148bool QPainterPath::contains(const QRectF &rect) const-
2149{-
2150 Q_D(QPainterPath);-
2151-
2152 // the path is empty or the control point rect doesn't completely-
2153 // cover the rectangle we abort stratight away.-
2154 if (isEmpty() || !controlPointRect().contains(rect))
isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
!controlPointR...contains(rect)Description
TRUEnever evaluated
FALSEnever evaluated
0
2155 return false;
never executed: return false;
0
2156-
2157 // if there are intersections, chances are that the rect is not-
2158 // contained, except if we have winding rule, in which case it-
2159 // still might.-
2160 if (qt_painterpath_check_crossing(this, rect)) {
qt_painterpath...ng(this, rect)Description
TRUEnever evaluated
FALSEnever evaluated
0
2161 if (fillRule() == Qt::OddEvenFill) {
fillRule() == Qt::OddEvenFillDescription
TRUEnever evaluated
FALSEnever evaluated
0
2162 return false;
never executed: return false;
0
2163 } else {-
2164 // Do some wague sampling in the winding case. This is not-
2165 // precise but it should mostly be good enough.-
2166 if (!contains(rect.topLeft()) ||
!contains(rect.topLeft())Description
TRUEnever evaluated
FALSEnever evaluated
0
2167 !contains(rect.topRight()) ||
!contains(rect.topRight())Description
TRUEnever evaluated
FALSEnever evaluated
0
2168 !contains(rect.bottomRight()) ||
!contains(rect.bottomRight())Description
TRUEnever evaluated
FALSEnever evaluated
0
2169 !contains(rect.bottomLeft()))
!contains(rect.bottomLeft())Description
TRUEnever evaluated
FALSEnever evaluated
0
2170 return false;
never executed: return false;
0
2171 }
never executed: end of block
0
2172 }-
2173-
2174 // If there exists a point inside that is not part of the path its-
2175 // because: rectangle lies completely outside path or a subpath-
2176 // excludes parts of the rectangle. Both cases mean that the rect-
2177 // is not contained-
2178 if (!contains(rect.center()))
!contains(rect.center())Description
TRUEnever evaluated
FALSEnever evaluated
0
2179 return false;
never executed: return false;
0
2180-
2181 // If there are any subpaths inside this rectangle we need to-
2182 // check if they are still contained as a result of the fill-
2183 // rule. This can only be the case for WindingFill though. For-
2184 // OddEvenFill the rect will never be contained if it surrounds a-
2185 // subpath. (the case where two subpaths are completely identical-
2186 // can be argued but we choose to neglect it).-
2187 for (int i=0; i<d->elements.size(); ++i) {
i<d->elements.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
2188 const Element &e = d->elements.at(i);-
2189 if (e.type == QPainterPath::MoveToElement && rect.contains(e)) {
e.type == QPai...:MoveToElementDescription
TRUEnever evaluated
FALSEnever evaluated
rect.contains(e)Description
TRUEnever evaluated
FALSEnever evaluated
0
2190 if (fillRule() == Qt::OddEvenFill)
fillRule() == Qt::OddEvenFillDescription
TRUEnever evaluated
FALSEnever evaluated
0
2191 return false;
never executed: return false;
0
2192-
2193 bool stop = false;-
2194 for (; !stop && i<d->elements.size(); ++i) {
!stopDescription
TRUEnever evaluated
FALSEnever evaluated
i<d->elements.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
2195 const Element &el = d->elements.at(i);-
2196 switch (el.type) {-
2197 case MoveToElement:
never executed: case MoveToElement:
0
2198 stop = true;-
2199 break;
never executed: break;
0
2200 case LineToElement:
never executed: case LineToElement:
0
2201 if (!contains(el))
!contains(el)Description
TRUEnever evaluated
FALSEnever evaluated
0
2202 return false;
never executed: return false;
0
2203 break;
never executed: break;
0
2204 case CurveToElement:
never executed: case CurveToElement:
0
2205 if (!contains(d->elements.at(i+2)))
!contains(d->elements.at(i+2))Description
TRUEnever evaluated
FALSEnever evaluated
0
2206 return false;
never executed: return false;
0
2207 i += 2;-
2208 break;
never executed: break;
0
2209 default:
never executed: default:
0
2210 break;
never executed: break;
0
2211 }-
2212 }-
2213-
2214 // compensate for the last ++i in the inner for-
2215 --i;-
2216 }
never executed: end of block
0
2217 }
never executed: end of block
0
2218-
2219 return true;
never executed: return true;
0
2220}-
2221-
2222static inline bool epsilonCompare(const QPointF &a, const QPointF &b, const QSizeF &epsilon)-
2223{-
2224 return qAbs(a.x() - b.x()) <= epsilon.width()
never executed: return qAbs(a.x() - b.x()) <= epsilon.width() && qAbs(a.y() - b.y()) <= epsilon.height();
qAbs(a.x() - b...psilon.width()Description
TRUEnever evaluated
FALSEnever evaluated
0
2225 && qAbs(a.y() - b.y()) <= epsilon.height();
never executed: return qAbs(a.x() - b.x()) <= epsilon.width() && qAbs(a.y() - b.y()) <= epsilon.height();
qAbs(a.y() - b...silon.height()Description
TRUEnever evaluated
FALSEnever evaluated
0
2226}-
2227-
2228/*!-
2229 Returns \c true if this painterpath is equal to the given \a path.-
2230-
2231 Note that comparing paths may involve a per element comparison-
2232 which can be slow for complex paths.-
2233-
2234 \sa operator!=()-
2235*/-
2236-
2237bool QPainterPath::operator==(const QPainterPath &path) const-
2238{-
2239 QPainterPathData *d = reinterpret_cast<QPainterPathData *>(d_func());-
2240 if (path.d_func() == d)
path.d_func() == dDescription
TRUEnever evaluated
FALSEnever evaluated
0
2241 return true;
never executed: return true;
0
2242 else if (!d || !path.d_func())
!dDescription
TRUEnever evaluated
FALSEnever evaluated
!path.d_func()Description
TRUEnever evaluated
FALSEnever evaluated
0
2243 return false;
never executed: return false;
0
2244 else if (d->fillRule != path.d_func()->fillRule)
d->fillRule !=...nc()->fillRuleDescription
TRUEnever evaluated
FALSEnever evaluated
0
2245 return false;
never executed: return false;
0
2246 else if (d->elements.size() != path.d_func()->elements.size())
d->elements.si...lements.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
2247 return false;
never executed: return false;
0
2248-
2249 const qreal qt_epsilon = sizeof(qreal) == sizeof(double) ? 1e-12 : qreal(1e-5);
sizeof(qreal) ...sizeof(double)Description
TRUEnever evaluated
FALSEnever evaluated
0
2250-
2251 QSizeF epsilon = boundingRect().size();-
2252 epsilon.rwidth() *= qt_epsilon;-
2253 epsilon.rheight() *= qt_epsilon;-
2254-
2255 for (int i = 0; i < d->elements.size(); ++i)
i < d->elements.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
2256 if (d->elements.at(i).type != path.d_func()->elements.at(i).type
d->elements.at...nts.at(i).typeDescription
TRUEnever evaluated
FALSEnever evaluated
0
2257 || !epsilonCompare(d->elements.at(i), path.d_func()->elements.at(i), epsilon))
!epsilonCompar...t(i), epsilon)Description
TRUEnever evaluated
FALSEnever evaluated
0
2258 return false;
never executed: return false;
0
2259-
2260 return true;
never executed: return true;
0
2261}-
2262-
2263/*!-
2264 Returns \c true if this painter path differs from the given \a path.-
2265-
2266 Note that comparing paths may involve a per element comparison-
2267 which can be slow for complex paths.-
2268-
2269 \sa operator==()-
2270*/-
2271-
2272bool QPainterPath::operator!=(const QPainterPath &path) const-
2273{-
2274 return !(*this==path);
never executed: return !(*this==path);
0
2275}-
2276-
2277/*!-
2278 \since 4.5-
2279-
2280 Returns the intersection of this path and the \a other path.-
2281-
2282 \sa intersected(), operator&=(), united(), operator|()-
2283*/-
2284QPainterPath QPainterPath::operator&(const QPainterPath &other) const-
2285{-
2286 return intersected(other);
never executed: return intersected(other);
0
2287}-
2288-
2289/*!-
2290 \since 4.5-
2291-
2292 Returns the union of this path and the \a other path.-
2293-
2294 \sa united(), operator|=(), intersected(), operator&()-
2295*/-
2296QPainterPath QPainterPath::operator|(const QPainterPath &other) const-
2297{-
2298 return united(other);
never executed: return united(other);
0
2299}-
2300-
2301/*!-
2302 \since 4.5-
2303-
2304 Returns the union of this path and the \a other path. This function is equivalent-
2305 to operator|().-
2306-
2307 \sa united(), operator+=(), operator-()-
2308*/-
2309QPainterPath QPainterPath::operator+(const QPainterPath &other) const-
2310{-
2311 return united(other);
never executed: return united(other);
0
2312}-
2313-
2314/*!-
2315 \since 4.5-
2316-
2317 Subtracts the \a other path from a copy of this path, and returns the copy.-
2318-
2319 \sa subtracted(), operator-=(), operator+()-
2320*/-
2321QPainterPath QPainterPath::operator-(const QPainterPath &other) const-
2322{-
2323 return subtracted(other);
never executed: return subtracted(other);
0
2324}-
2325-
2326/*!-
2327 \since 4.5-
2328-
2329 Intersects this path with \a other and returns a reference to this path.-
2330-
2331 \sa intersected(), operator&(), operator|=()-
2332*/-
2333QPainterPath &QPainterPath::operator&=(const QPainterPath &other)-
2334{-
2335 return *this = (*this & other);
never executed: return *this = (*this & other);
0
2336}-
2337-
2338/*!-
2339 \since 4.5-
2340-
2341 Unites this path with \a other and returns a reference to this path.-
2342-
2343 \sa united(), operator|(), operator&=()-
2344*/-
2345QPainterPath &QPainterPath::operator|=(const QPainterPath &other)-
2346{-
2347 return *this = (*this | other);
never executed: return *this = (*this | other);
0
2348}-
2349-
2350/*!-
2351 \since 4.5-
2352-
2353 Unites this path with \a other, and returns a reference to this path. This-
2354 is equivalent to operator|=().-
2355-
2356 \sa united(), operator+(), operator-=()-
2357*/-
2358QPainterPath &QPainterPath::operator+=(const QPainterPath &other)-
2359{-
2360 return *this = (*this + other);
never executed: return *this = (*this + other);
0
2361}-
2362-
2363/*!-
2364 \since 4.5-
2365-
2366 Subtracts \a other from this path, and returns a reference to this-
2367 path.-
2368-
2369 \sa subtracted(), operator-(), operator+=()-
2370*/-
2371QPainterPath &QPainterPath::operator-=(const QPainterPath &other)-
2372{-
2373 return *this = (*this - other);
never executed: return *this = (*this - other);
0
2374}-
2375-
2376#ifndef QT_NO_DATASTREAM-
2377/*!-
2378 \fn QDataStream &operator<<(QDataStream &stream, const QPainterPath &path)-
2379 \relates QPainterPath-
2380-
2381 Writes the given painter \a path to the given \a stream, and-
2382 returns a reference to the \a stream.-
2383-
2384 \sa {Serializing Qt Data Types}-
2385*/-
2386QDataStream &operator<<(QDataStream &s, const QPainterPath &p)-
2387{-
2388 if (p.isEmpty()) {
p.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
2389 s << 0;-
2390 return s;
never executed: return s;
0
2391 }-
2392-
2393 s << p.elementCount();-
2394 for (int i=0; i < p.d_func()->elements.size(); ++i) {
i < p.d_func()...lements.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
2395 const QPainterPath::Element &e = p.d_func()->elements.at(i);-
2396 s << int(e.type);-
2397 s << double(e.x) << double(e.y);-
2398 }
never executed: end of block
0
2399 s << p.d_func()->cStart;-
2400 s << int(p.d_func()->fillRule);-
2401 return s;
never executed: return s;
0
2402}-
2403-
2404/*!-
2405 \fn QDataStream &operator>>(QDataStream &stream, QPainterPath &path)-
2406 \relates QPainterPath-
2407-
2408 Reads a painter path from the given \a stream into the specified \a path,-
2409 and returns a reference to the \a stream.-
2410-
2411 \sa {Serializing Qt Data Types}-
2412*/-
2413QDataStream &operator>>(QDataStream &s, QPainterPath &p)-
2414{-
2415 int size;-
2416 s >> size;-
2417-
2418 if (size == 0)
size == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2419 return s;
never executed: return s;
0
2420-
2421 p.ensureData(); // in case if p.d_func() == 0-
2422 if (p.d_func()->elements.size() == 1) {
p.d_func()->el...ts.size() == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
2423 Q_ASSERT(p.d_func()->elements.at(0).type == QPainterPath::MoveToElement);-
2424 p.d_func()->elements.clear();-
2425 }
never executed: end of block
0
2426 p.d_func()->elements.reserve(p.d_func()->elements.size() + size);-
2427 for (int i=0; i<size; ++i) {
i<sizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
2428 int type;-
2429 double x, y;-
2430 s >> type;-
2431 s >> x;-
2432 s >> y;-
2433 Q_ASSERT(type >= 0 && type <= 3);-
2434 if (!qt_is_finite(x) || !qt_is_finite(y)) {
!qt_is_finite(x)Description
TRUEnever evaluated
FALSEnever evaluated
!qt_is_finite(y)Description
TRUEnever evaluated
FALSEnever evaluated
0
2435#ifndef QT_NO_DEBUG-
2436 qWarning("QDataStream::operator>>: NaN or Inf element found in path, skipping it");-
2437#endif-
2438 continue;
never executed: continue;
0
2439 }-
2440 QPainterPath::Element elm = { qreal(x), qreal(y), QPainterPath::ElementType(type) };-
2441 p.d_func()->elements.append(elm);-
2442 }
never executed: end of block
0
2443 s >> p.d_func()->cStart;-
2444 int fillRule;-
2445 s >> fillRule;-
2446 Q_ASSERT(fillRule == Qt::OddEvenFill || Qt::WindingFill);-
2447 p.d_func()->fillRule = Qt::FillRule(fillRule);-
2448 p.d_func()->dirtyBounds = true;-
2449 p.d_func()->dirtyControlBounds = true;-
2450 return s;
never executed: return s;
0
2451}-
2452#endif // QT_NO_DATASTREAM-
2453-
2454-
2455/*******************************************************************************-
2456 * class QPainterPathStroker-
2457 */-
2458-
2459void qt_path_stroke_move_to(qfixed x, qfixed y, void *data)-
2460{-
2461 ((QPainterPath *) data)->moveTo(qt_fixed_to_real(x), qt_fixed_to_real(y));-
2462}
never executed: end of block
0
2463-
2464void qt_path_stroke_line_to(qfixed x, qfixed y, void *data)-
2465{-
2466 ((QPainterPath *) data)->lineTo(qt_fixed_to_real(x), qt_fixed_to_real(y));-
2467}
never executed: end of block
0
2468-
2469void qt_path_stroke_cubic_to(qfixed c1x, qfixed c1y,-
2470 qfixed c2x, qfixed c2y,-
2471 qfixed ex, qfixed ey,-
2472 void *data)-
2473{-
2474 ((QPainterPath *) data)->cubicTo(qt_fixed_to_real(c1x), qt_fixed_to_real(c1y),-
2475 qt_fixed_to_real(c2x), qt_fixed_to_real(c2y),-
2476 qt_fixed_to_real(ex), qt_fixed_to_real(ey));-
2477}
never executed: end of block
0
2478-
2479/*!-
2480 \since 4.1-
2481 \class QPainterPathStroker-
2482 \ingroup painting-
2483 \inmodule QtGui-
2484-
2485 \brief The QPainterPathStroker class is used to generate fillable-
2486 outlines for a given painter path.-
2487-
2488 By calling the createStroke() function, passing a given-
2489 QPainterPath as argument, a new painter path representing the-
2490 outline of the given path is created. The newly created painter-
2491 path can then be filled to draw the original painter path's-
2492 outline.-
2493-
2494 You can control the various design aspects (width, cap styles,-
2495 join styles and dash pattern) of the outlining using the following-
2496 functions:-
2497-
2498 \list-
2499 \li setWidth()-
2500 \li setCapStyle()-
2501 \li setJoinStyle()-
2502 \li setDashPattern()-
2503 \endlist-
2504-
2505 The setDashPattern() function accepts both a Qt::PenStyle object-
2506 and a vector representation of the pattern as argument.-
2507-
2508 In addition you can specify a curve's threshold, controlling the-
2509 granularity with which a curve is drawn, using the-
2510 setCurveThreshold() function. The default threshold is a well-
2511 adjusted value (0.25), and normally you should not need to modify-
2512 it. However, you can make the curve's appearance smoother by-
2513 decreasing its value.-
2514-
2515 You can also control the miter limit for the generated outline-
2516 using the setMiterLimit() function. The miter limit describes how-
2517 far from each join the miter join can extend. The limit is-
2518 specified in the units of width so the pixelwise miter limit will-
2519 be \c {miterlimit * width}. This value is only used if the join-
2520 style is Qt::MiterJoin.-
2521-
2522 The painter path generated by the createStroke() function should-
2523 only be used for outlining the given painter path. Otherwise it-
2524 may cause unexpected behavior. Generated outlines also require the-
2525 Qt::WindingFill rule which is set by default.-
2526-
2527 \sa QPen, QBrush-
2528*/-
2529-
2530QPainterPathStrokerPrivate::QPainterPathStrokerPrivate()-
2531 : dashOffset(0)-
2532{-
2533 stroker.setMoveToHook(qt_path_stroke_move_to);-
2534 stroker.setLineToHook(qt_path_stroke_line_to);-
2535 stroker.setCubicToHook(qt_path_stroke_cubic_to);-
2536}
never executed: end of block
0
2537-
2538/*!-
2539 Creates a new stroker.-
2540 */-
2541QPainterPathStroker::QPainterPathStroker()-
2542 : d_ptr(new QPainterPathStrokerPrivate)-
2543{-
2544}
never executed: end of block
0
2545-
2546/*!-
2547 Creates a new stroker based on \a pen.-
2548-
2549 \since 5.3-
2550 */-
2551QPainterPathStroker::QPainterPathStroker(const QPen &pen)-
2552 : d_ptr(new QPainterPathStrokerPrivate)-
2553{-
2554 setWidth(pen.widthF());-
2555 setCapStyle(pen.capStyle());-
2556 setJoinStyle(pen.joinStyle());-
2557 setMiterLimit(pen.miterLimit());-
2558 setDashOffset(pen.dashOffset());-
2559-
2560 if (pen.style() == Qt::CustomDashLine)
pen.style() ==...CustomDashLineDescription
TRUEnever evaluated
FALSEnever evaluated
0
2561 setDashPattern(pen.dashPattern());
never executed: setDashPattern(pen.dashPattern());
0
2562 else-
2563 setDashPattern(pen.style());
never executed: setDashPattern(pen.style());
0
2564}-
2565-
2566/*!-
2567 Destroys the stroker.-
2568*/-
2569QPainterPathStroker::~QPainterPathStroker()-
2570{-
2571}-
2572-
2573-
2574/*!-
2575 Generates a new path that is a fillable area representing the-
2576 outline of the given \a path.-
2577-
2578 The various design aspects of the outline are based on the-
2579 stroker's properties: width(), capStyle(), joinStyle(),-
2580 dashPattern(), curveThreshold() and miterLimit().-
2581-
2582 The generated path should only be used for outlining the given-
2583 painter path. Otherwise it may cause unexpected-
2584 behavior. Generated outlines also require the Qt::WindingFill rule-
2585 which is set by default.-
2586*/-
2587QPainterPath QPainterPathStroker::createStroke(const QPainterPath &path) const-
2588{-
2589 QPainterPathStrokerPrivate *d = const_cast<QPainterPathStrokerPrivate *>(d_func());-
2590 QPainterPath stroke;-
2591 if (path.isEmpty())
path.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
2592 return path;
never executed: return path;
0
2593 if (d->dashPattern.isEmpty()) {
d->dashPattern.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
2594 d->stroker.strokePath(path, &stroke, QTransform());-
2595 } else {
never executed: end of block
0
2596 QDashStroker dashStroker(&d->stroker);-
2597 dashStroker.setDashPattern(d->dashPattern);-
2598 dashStroker.setDashOffset(d->dashOffset);-
2599 dashStroker.setClipRect(d->stroker.clipRect());-
2600 dashStroker.strokePath(path, &stroke, QTransform());-
2601 }
never executed: end of block
0
2602 stroke.setFillRule(Qt::WindingFill);-
2603 return stroke;
never executed: return stroke;
0
2604}-
2605-
2606/*!-
2607 Sets the width of the generated outline painter path to \a width.-
2608-
2609 The generated outlines will extend approximately 50% of \a width-
2610 to each side of the given input path's original outline.-
2611*/-
2612void QPainterPathStroker::setWidth(qreal width)-
2613{-
2614 Q_D(QPainterPathStroker);-
2615 if (width <= 0)
width <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2616 width = 1;
never executed: width = 1;
0
2617 d->stroker.setStrokeWidth(qt_real_to_fixed(width));-
2618}
never executed: end of block
0
2619-
2620/*!-
2621 Returns the width of the generated outlines.-
2622*/-
2623qreal QPainterPathStroker::width() const-
2624{-
2625 return qt_fixed_to_real(d_func()->stroker.strokeWidth());
never executed: return d_func()->stroker.strokeWidth();
0
2626}-
2627-
2628-
2629/*!-
2630 Sets the cap style of the generated outlines to \a style. If a-
2631 dash pattern is set, each segment of the pattern is subject to the-
2632 cap \a style.-
2633*/-
2634void QPainterPathStroker::setCapStyle(Qt::PenCapStyle style)-
2635{-
2636 d_func()->stroker.setCapStyle(style);-
2637}
never executed: end of block
0
2638-
2639-
2640/*!-
2641 Returns the cap style of the generated outlines.-
2642*/-
2643Qt::PenCapStyle QPainterPathStroker::capStyle() const-
2644{-
2645 return d_func()->stroker.capStyle();
never executed: return d_func()->stroker.capStyle();
0
2646}-
2647-
2648/*!-
2649 Sets the join style of the generated outlines to \a style.-
2650*/-
2651void QPainterPathStroker::setJoinStyle(Qt::PenJoinStyle style)-
2652{-
2653 d_func()->stroker.setJoinStyle(style);-
2654}
never executed: end of block
0
2655-
2656/*!-
2657 Returns the join style of the generated outlines.-
2658*/-
2659Qt::PenJoinStyle QPainterPathStroker::joinStyle() const-
2660{-
2661 return d_func()->stroker.joinStyle();
never executed: return d_func()->stroker.joinStyle();
0
2662}-
2663-
2664/*!-
2665 Sets the miter limit of the generated outlines to \a limit.-
2666-
2667 The miter limit describes how far from each join the miter join-
2668 can extend. The limit is specified in units of the currently set-
2669 width. So the pixelwise miter limit will be \c { miterlimit *-
2670 width}.-
2671-
2672 This value is only used if the join style is Qt::MiterJoin.-
2673*/-
2674void QPainterPathStroker::setMiterLimit(qreal limit)-
2675{-
2676 d_func()->stroker.setMiterLimit(qt_real_to_fixed(limit));-
2677}
never executed: end of block
0
2678-
2679/*!-
2680 Returns the miter limit for the generated outlines.-
2681*/-
2682qreal QPainterPathStroker::miterLimit() const-
2683{-
2684 return qt_fixed_to_real(d_func()->stroker.miterLimit());
never executed: return d_func()->stroker.miterLimit();
0
2685}-
2686-
2687-
2688/*!-
2689 Specifies the curve flattening \a threshold, controlling the-
2690 granularity with which the generated outlines' curve is drawn.-
2691-
2692 The default threshold is a well adjusted value (0.25), and-
2693 normally you should not need to modify it. However, you can make-
2694 the curve's appearance smoother by decreasing its value.-
2695*/-
2696void QPainterPathStroker::setCurveThreshold(qreal threshold)-
2697{-
2698 d_func()->stroker.setCurveThreshold(qt_real_to_fixed(threshold));-
2699}
never executed: end of block
0
2700-
2701/*!-
2702 Returns the curve flattening threshold for the generated-
2703 outlines.-
2704*/-
2705qreal QPainterPathStroker::curveThreshold() const-
2706{-
2707 return qt_fixed_to_real(d_func()->stroker.curveThreshold());
never executed: return d_func()->stroker.curveThreshold();
0
2708}-
2709-
2710/*!-
2711 Sets the dash pattern for the generated outlines to \a style.-
2712*/-
2713void QPainterPathStroker::setDashPattern(Qt::PenStyle style)-
2714{-
2715 d_func()->dashPattern = QDashStroker::patternForStyle(style);-
2716}
never executed: end of block
0
2717-
2718/*!-
2719 \overload-
2720-
2721 Sets the dash pattern for the generated outlines to \a-
2722 dashPattern. This function makes it possible to specify custom-
2723 dash patterns.-
2724-
2725 Each element in the vector contains the lengths of the dashes and spaces-
2726 in the stroke, beginning with the first dash in the first element, the-
2727 first space in the second element, and alternating between dashes and-
2728 spaces for each following pair of elements.-
2729-
2730 The vector can contain an odd number of elements, in which case the last-
2731 element will be extended by the length of the first element when the-
2732 pattern repeats.-
2733*/-
2734void QPainterPathStroker::setDashPattern(const QVector<qreal> &dashPattern)-
2735{-
2736 d_func()->dashPattern.clear();-
2737 for (int i=0; i<dashPattern.size(); ++i)
i<dashPattern.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
2738 d_func()->dashPattern << qt_real_to_fixed(dashPattern.at(i));
never executed: d_func()->dashPattern << qfixed(dashPattern.at(i));
0
2739}
never executed: end of block
0
2740-
2741/*!-
2742 Returns the dash pattern for the generated outlines.-
2743*/-
2744QVector<qreal> QPainterPathStroker::dashPattern() const-
2745{-
2746 return d_func()->dashPattern;
never executed: return d_func()->dashPattern;
0
2747}-
2748-
2749/*!-
2750 Returns the dash offset for the generated outlines.-
2751 */-
2752qreal QPainterPathStroker::dashOffset() const-
2753{-
2754 return d_func()->dashOffset;
never executed: return d_func()->dashOffset;
0
2755}-
2756-
2757/*!-
2758 Sets the dash offset for the generated outlines to \a offset.-
2759-
2760 See the documentation for QPen::setDashOffset() for a description of the-
2761 dash offset.-
2762 */-
2763void QPainterPathStroker::setDashOffset(qreal offset)-
2764{-
2765 d_func()->dashOffset = offset;-
2766}
never executed: end of block
0
2767-
2768/*!-
2769 Converts the path into a polygon using the QTransform-
2770 \a matrix, and returns the polygon.-
2771-
2772 The polygon is created by first converting all subpaths to-
2773 polygons, then using a rewinding technique to make sure that-
2774 overlapping subpaths can be filled using the correct fill rule.-
2775-
2776 Note that rewinding inserts addition lines in the polygon so-
2777 the outline of the fill polygon does not match the outline of-
2778 the path.-
2779-
2780 \sa toSubpathPolygons(), toFillPolygons(),-
2781 {QPainterPath#QPainterPath Conversion}{QPainterPath Conversion}-
2782*/-
2783QPolygonF QPainterPath::toFillPolygon(const QTransform &matrix) const-
2784{-
2785-
2786 QList<QPolygonF> flats = toSubpathPolygons(matrix);-
2787 QPolygonF polygon;-
2788 if (flats.isEmpty())
flats.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
2789 return polygon;
never executed: return polygon;
0
2790 QPointF first = flats.first().first();-
2791 for (int i=0; i<flats.size(); ++i) {
i<flats.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
2792 polygon += flats.at(i);-
2793 if (!flats.at(i).isClosed())
!flats.at(i).isClosed()Description
TRUEnever evaluated
FALSEnever evaluated
0
2794 polygon += flats.at(i).first();
never executed: polygon += flats.at(i).first();
0
2795 if (i > 0)
i > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2796 polygon += first;
never executed: polygon += first;
0
2797 }
never executed: end of block
0
2798 return polygon;
never executed: return polygon;
0
2799}-
2800-
2801/*!-
2802 \overload-
2803*/-
2804QPolygonF QPainterPath::toFillPolygon(const QMatrix &matrix) const-
2805{-
2806 return toFillPolygon(QTransform(matrix));
never executed: return toFillPolygon(QTransform(matrix));
0
2807}-
2808-
2809-
2810//derivative of the equation-
2811static inline qreal slopeAt(qreal t, qreal a, qreal b, qreal c, qreal d)-
2812{-
2813 return 3*t*t*(d - 3*c + 3*b - a) + 6*t*(c - 2*b + a) + 3*(b - a);
never executed: return 3*t*t*(d - 3*c + 3*b - a) + 6*t*(c - 2*b + a) + 3*(b - a);
0
2814}-
2815-
2816/*!-
2817 Returns the length of the current path.-
2818*/-
2819qreal QPainterPath::length() const-
2820{-
2821 Q_D(QPainterPath);-
2822 if (isEmpty())
isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
2823 return 0;
never executed: return 0;
0
2824-
2825 qreal len = 0;-
2826 for (int i=1; i<d->elements.size(); ++i) {
i<d->elements.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
2827 const Element &e = d->elements.at(i);-
2828-
2829 switch (e.type) {-
2830 case MoveToElement:
never executed: case MoveToElement:
0
2831 break;
never executed: break;
0
2832 case LineToElement:
never executed: case LineToElement:
0
2833 {-
2834 len += QLineF(d->elements.at(i-1), e).length();-
2835 break;
never executed: break;
0
2836 }-
2837 case CurveToElement:
never executed: case CurveToElement:
0
2838 {-
2839 QBezier b = QBezier::fromPoints(d->elements.at(i-1),-
2840 e,-
2841 d->elements.at(i+1),-
2842 d->elements.at(i+2));-
2843 len += b.length();-
2844 i += 2;-
2845 break;
never executed: break;
0
2846 }-
2847 default:
never executed: default:
0
2848 break;
never executed: break;
0
2849 }-
2850 }-
2851 return len;
never executed: return len;
0
2852}-
2853-
2854/*!-
2855 Returns percentage of the whole path at the specified length \a len.-
2856-
2857 Note that similarly to other percent methods, the percentage measurement-
2858 is not linear with regards to the length, if curves are present-
2859 in the path. When curves are present the percentage argument is mapped-
2860 to the t parameter of the Bezier equations.-
2861*/-
2862qreal QPainterPath::percentAtLength(qreal len) const-
2863{-
2864 Q_D(QPainterPath);-
2865 if (isEmpty() || len <= 0)
isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
len <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2866 return 0;
never executed: return 0;
0
2867-
2868 qreal totalLength = length();-
2869 if (len > totalLength)
len > totalLengthDescription
TRUEnever evaluated
FALSEnever evaluated
0
2870 return 1;
never executed: return 1;
0
2871-
2872 qreal curLen = 0;-
2873 for (int i=1; i<d->elements.size(); ++i) {
i<d->elements.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
2874 const Element &e = d->elements.at(i);-
2875-
2876 switch (e.type) {-
2877 case MoveToElement:
never executed: case MoveToElement:
0
2878 break;
never executed: break;
0
2879 case LineToElement:
never executed: case LineToElement:
0
2880 {-
2881 QLineF line(d->elements.at(i-1), e);-
2882 qreal llen = line.length();-
2883 curLen += llen;-
2884 if (curLen >= len) {
curLen >= lenDescription
TRUEnever evaluated
FALSEnever evaluated
0
2885 return len/totalLength ;
never executed: return len/totalLength ;
0
2886 }-
2887-
2888 break;
never executed: break;
0
2889 }-
2890 case CurveToElement:
never executed: case CurveToElement:
0
2891 {-
2892 QBezier b = QBezier::fromPoints(d->elements.at(i-1),-
2893 e,-
2894 d->elements.at(i+1),-
2895 d->elements.at(i+2));-
2896 qreal blen = b.length();-
2897 qreal prevLen = curLen;-
2898 curLen += blen;-
2899-
2900 if (curLen >= len) {
curLen >= lenDescription
TRUEnever evaluated
FALSEnever evaluated
0
2901 qreal res = b.tAtLength(len - prevLen);-
2902 return (res * blen + prevLen)/totalLength;
never executed: return (res * blen + prevLen)/totalLength;
0
2903 }-
2904-
2905 i += 2;-
2906 break;
never executed: break;
0
2907 }-
2908 default:
never executed: default:
0
2909 break;
never executed: break;
0
2910 }-
2911 }-
2912-
2913 return 0;
never executed: return 0;
0
2914}-
2915-
2916static inline QBezier bezierAtT(const QPainterPath &path, qreal t, qreal *startingLength, qreal *bezierLength)-
2917{-
2918 *startingLength = 0;-
2919 if (t > 1)
t > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
2920 return QBezier();
never executed: return QBezier();
0
2921-
2922 qreal curLen = 0;-
2923 qreal totalLength = path.length();-
2924-
2925 const int lastElement = path.elementCount() - 1;-
2926 for (int i=0; i <= lastElement; ++i) {
i <= lastElementDescription
TRUEnever evaluated
FALSEnever evaluated
0
2927 const QPainterPath::Element &e = path.elementAt(i);-
2928-
2929 switch (e.type) {-
2930 case QPainterPath::MoveToElement:
never executed: case QPainterPath::MoveToElement:
0
2931 break;
never executed: break;
0
2932 case QPainterPath::LineToElement:
never executed: case QPainterPath::LineToElement:
0
2933 {-
2934 QLineF line(path.elementAt(i-1), e);-
2935 qreal llen = line.length();-
2936 curLen += llen;-
2937 if (i == lastElement || curLen/totalLength >= t) {
i == lastElementDescription
TRUEnever evaluated
FALSEnever evaluated
curLen/totalLength >= tDescription
TRUEnever evaluated
FALSEnever evaluated
0
2938 *bezierLength = llen;-
2939 QPointF a = path.elementAt(i-1);-
2940 QPointF delta = e - a;-
2941 return QBezier::fromPoints(a, a + delta / 3, a + 2 * delta / 3, e);
never executed: return QBezier::fromPoints(a, a + delta / 3, a + 2 * delta / 3, e);
0
2942 }-
2943 break;
never executed: break;
0
2944 }-
2945 case QPainterPath::CurveToElement:
never executed: case QPainterPath::CurveToElement:
0
2946 {-
2947 QBezier b = QBezier::fromPoints(path.elementAt(i-1),-
2948 e,-
2949 path.elementAt(i+1),-
2950 path.elementAt(i+2));-
2951 qreal blen = b.length();-
2952 curLen += blen;-
2953-
2954 if (i + 2 == lastElement || curLen/totalLength >= t) {
i + 2 == lastElementDescription
TRUEnever evaluated
FALSEnever evaluated
curLen/totalLength >= tDescription
TRUEnever evaluated
FALSEnever evaluated
0
2955 *bezierLength = blen;-
2956 return b;
never executed: return b;
0
2957 }-
2958-
2959 i += 2;-
2960 break;
never executed: break;
0
2961 }-
2962 default:
never executed: default:
0
2963 break;
never executed: break;
0
2964 }-
2965 *startingLength = curLen;-
2966 }
never executed: end of block
0
2967 return QBezier();
never executed: return QBezier();
0
2968}-
2969-
2970/*!-
2971 Returns the point at at the percentage \a t of the current path.-
2972 The argument \a t has to be between 0 and 1.-
2973-
2974 Note that similarly to other percent methods, the percentage measurement-
2975 is not linear with regards to the length, if curves are present-
2976 in the path. When curves are present the percentage argument is mapped-
2977 to the t parameter of the Bezier equations.-
2978*/-
2979QPointF QPainterPath::pointAtPercent(qreal t) const-
2980{-
2981 if (t < 0 || t > 1) {
t < 0Description
TRUEnever evaluated
FALSEnever evaluated
t > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
2982 qWarning("QPainterPath::pointAtPercent accepts only values between 0 and 1");-
2983 return QPointF();
never executed: return QPointF();
0
2984 }-
2985-
2986 if (!d_ptr || d_ptr->elements.size() == 0)
!d_ptrDescription
TRUEnever evaluated
FALSEnever evaluated
d_ptr->elements.size() == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2987 return QPointF();
never executed: return QPointF();
0
2988-
2989 if (d_ptr->elements.size() == 1)
d_ptr->elements.size() == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
2990 return d_ptr->elements.at(0);
never executed: return d_ptr->elements.at(0);
0
2991-
2992 qreal totalLength = length();-
2993 qreal curLen = 0;-
2994 qreal bezierLen = 0;-
2995 QBezier b = bezierAtT(*this, t, &curLen, &bezierLen);-
2996 qreal realT = (totalLength * t - curLen) / bezierLen;-
2997-
2998 return b.pointAt(qBound(qreal(0), realT, qreal(1)));
never executed: return b.pointAt(qBound(qreal(0), realT, qreal(1)));
0
2999}-
3000-
3001/*!-
3002 Returns the angle of the path tangent at the percentage \a t.-
3003 The argument \a t has to be between 0 and 1.-
3004-
3005 Positive values for the angles mean counter-clockwise while negative values-
3006 mean the clockwise direction. Zero degrees is at the 3 o'clock position.-
3007-
3008 Note that similarly to the other percent methods, the percentage measurement-
3009 is not linear with regards to the length if curves are present-
3010 in the path. When curves are present the percentage argument is mapped-
3011 to the t parameter of the Bezier equations.-
3012*/-
3013qreal QPainterPath::angleAtPercent(qreal t) const-
3014{-
3015 if (t < 0 || t > 1) {
t < 0Description
TRUEnever evaluated
FALSEnever evaluated
t > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
3016 qWarning("QPainterPath::angleAtPercent accepts only values between 0 and 1");-
3017 return 0;
never executed: return 0;
0
3018 }-
3019-
3020 qreal totalLength = length();-
3021 qreal curLen = 0;-
3022 qreal bezierLen = 0;-
3023 QBezier bez = bezierAtT(*this, t, &curLen, &bezierLen);-
3024 qreal realT = (totalLength * t - curLen) / bezierLen;-
3025-
3026 qreal m1 = slopeAt(realT, bez.x1, bez.x2, bez.x3, bez.x4);-
3027 qreal m2 = slopeAt(realT, bez.y1, bez.y2, bez.y3, bez.y4);-
3028-
3029 return QLineF(0, 0, m1, m2).angle();
never executed: return QLineF(0, 0, m1, m2).angle();
0
3030}-
3031-
3032-
3033/*!-
3034 Returns the slope of the path at the percentage \a t. The-
3035 argument \a t has to be between 0 and 1.-
3036-
3037 Note that similarly to other percent methods, the percentage measurement-
3038 is not linear with regards to the length, if curves are present-
3039 in the path. When curves are present the percentage argument is mapped-
3040 to the t parameter of the Bezier equations.-
3041*/-
3042qreal QPainterPath::slopeAtPercent(qreal t) const-
3043{-
3044 if (t < 0 || t > 1) {
t < 0Description
TRUEnever evaluated
FALSEnever evaluated
t > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
3045 qWarning("QPainterPath::slopeAtPercent accepts only values between 0 and 1");-
3046 return 0;
never executed: return 0;
0
3047 }-
3048-
3049 qreal totalLength = length();-
3050 qreal curLen = 0;-
3051 qreal bezierLen = 0;-
3052 QBezier bez = bezierAtT(*this, t, &curLen, &bezierLen);-
3053 qreal realT = (totalLength * t - curLen) / bezierLen;-
3054-
3055 qreal m1 = slopeAt(realT, bez.x1, bez.x2, bez.x3, bez.x4);-
3056 qreal m2 = slopeAt(realT, bez.y1, bez.y2, bez.y3, bez.y4);-
3057 //tangent line-
3058 qreal slope = 0;-
3059-
3060 if (m1)
m1Description
TRUEnever evaluated
FALSEnever evaluated
0
3061 slope = m2/m1;
never executed: slope = m2/m1;
0
3062 else {-
3063 if (std::numeric_limits<qreal>::has_infinity) {
std::numeric_l...::has_infinityDescription
TRUEnever evaluated
FALSEnever evaluated
0
3064 slope = (m2 < 0) ? -std::numeric_limits<qreal>::infinity()
(m2 < 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3065 : std::numeric_limits<qreal>::infinity();-
3066 } else {
never executed: end of block
0
3067 if (sizeof(qreal) == sizeof(double)) {
sizeof(qreal) ...sizeof(double)Description
TRUEnever evaluated
FALSEnever evaluated
0
3068 return 1.79769313486231570e+308;
never executed: return 1.79769313486231570e+308;
0
3069 } else {-
3070 return ((qreal)3.40282346638528860e+38);
never executed: return ((qreal)3.40282346638528860e+38);
0
3071 }-
3072 }-
3073 }-
3074-
3075 return slope;
never executed: return slope;
0
3076}-
3077-
3078/*!-
3079 \since 4.4-
3080-
3081 Adds the given rectangle \a rect with rounded corners to the path.-
3082-
3083 The \a xRadius and \a yRadius arguments specify the radii of-
3084 the ellipses defining the corners of the rounded rectangle.-
3085 When \a mode is Qt::RelativeSize, \a xRadius and-
3086 \a yRadius are specified in percentage of half the rectangle's-
3087 width and height respectively, and should be in the range 0.0 to 100.0.-
3088-
3089 \sa addRect()-
3090*/-
3091void QPainterPath::addRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius,-
3092 Qt::SizeMode mode)-
3093{-
3094 QRectF r = rect.normalized();-
3095-
3096 if (r.isNull())
r.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
3097 return;
never executed: return;
0
3098-
3099 if (mode == Qt::AbsoluteSize) {
mode == Qt::AbsoluteSizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
3100 qreal w = r.width() / 2;-
3101 qreal h = r.height() / 2;-
3102-
3103 if (w == 0) {
w == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3104 xRadius = 0;-
3105 } else {
never executed: end of block
0
3106 xRadius = 100 * qMin(xRadius, w) / w;-
3107 }
never executed: end of block
0
3108 if (h == 0) {
h == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3109 yRadius = 0;-
3110 } else {
never executed: end of block
0
3111 yRadius = 100 * qMin(yRadius, h) / h;-
3112 }
never executed: end of block
0
3113 } else {-
3114 if (xRadius > 100) // fix ranges
xRadius > 100Description
TRUEnever evaluated
FALSEnever evaluated
0
3115 xRadius = 100;
never executed: xRadius = 100;
0
3116-
3117 if (yRadius > 100)
yRadius > 100Description
TRUEnever evaluated
FALSEnever evaluated
0
3118 yRadius = 100;
never executed: yRadius = 100;
0
3119 }
never executed: end of block
0
3120-
3121 if (xRadius <= 0 || yRadius <= 0) { // add normal rectangle
xRadius <= 0Description
TRUEnever evaluated
FALSEnever evaluated
yRadius <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3122 addRect(r);-
3123 return;
never executed: return;
0
3124 }-
3125-
3126 qreal x = r.x();-
3127 qreal y = r.y();-
3128 qreal w = r.width();-
3129 qreal h = r.height();-
3130 qreal rxx2 = w*xRadius/100;-
3131 qreal ryy2 = h*yRadius/100;-
3132-
3133 ensureData();-
3134 detach();-
3135-
3136 bool first = d_func()->elements.size() < 2;-
3137-
3138 arcMoveTo(x, y, rxx2, ryy2, 180);-
3139 arcTo(x, y, rxx2, ryy2, 180, -90);-
3140 arcTo(x+w-rxx2, y, rxx2, ryy2, 90, -90);-
3141 arcTo(x+w-rxx2, y+h-ryy2, rxx2, ryy2, 0, -90);-
3142 arcTo(x, y+h-ryy2, rxx2, ryy2, 270, -90);-
3143 closeSubpath();-
3144-
3145 d_func()->require_moveTo = true;-
3146 d_func()->convex = first;-
3147}
never executed: end of block
0
3148-
3149/*!-
3150 \fn void QPainterPath::addRoundedRect(qreal x, qreal y, qreal w, qreal h, qreal xRadius, qreal yRadius, Qt::SizeMode mode = Qt::AbsoluteSize);-
3151 \since 4.4-
3152 \overload-
3153-
3154 Adds the given rectangle \a x, \a y, \a w, \a h with rounded corners to the path.-
3155 */-
3156-
3157/*!-
3158 \obsolete-
3159-
3160 Adds a rectangle \a r with rounded corners to the path.-
3161-
3162 The \a xRnd and \a yRnd arguments specify how rounded the corners-
3163 should be. 0 is angled corners, 99 is maximum roundedness.-
3164-
3165 \sa addRoundedRect()-
3166*/-
3167void QPainterPath::addRoundRect(const QRectF &r, int xRnd, int yRnd)-
3168{-
3169 if(xRnd >= 100) // fix ranges
xRnd >= 100Description
TRUEnever evaluated
FALSEnever evaluated
0
3170 xRnd = 99;
never executed: xRnd = 99;
0
3171 if(yRnd >= 100)
yRnd >= 100Description
TRUEnever evaluated
FALSEnever evaluated
0
3172 yRnd = 99;
never executed: yRnd = 99;
0
3173 if(xRnd <= 0 || yRnd <= 0) { // add normal rectangle
xRnd <= 0Description
TRUEnever evaluated
FALSEnever evaluated
yRnd <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3174 addRect(r);-
3175 return;
never executed: return;
0
3176 }-
3177-
3178 QRectF rect = r.normalized();-
3179-
3180 if (rect.isNull())
rect.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
3181 return;
never executed: return;
0
3182-
3183 qreal x = rect.x();-
3184 qreal y = rect.y();-
3185 qreal w = rect.width();-
3186 qreal h = rect.height();-
3187 qreal rxx2 = w*xRnd/100;-
3188 qreal ryy2 = h*yRnd/100;-
3189-
3190 ensureData();-
3191 detach();-
3192-
3193 bool first = d_func()->elements.size() < 2;-
3194-
3195 arcMoveTo(x, y, rxx2, ryy2, 180);-
3196 arcTo(x, y, rxx2, ryy2, 180, -90);-
3197 arcTo(x+w-rxx2, y, rxx2, ryy2, 90, -90);-
3198 arcTo(x+w-rxx2, y+h-ryy2, rxx2, ryy2, 0, -90);-
3199 arcTo(x, y+h-ryy2, rxx2, ryy2, 270, -90);-
3200 closeSubpath();-
3201-
3202 d_func()->require_moveTo = true;-
3203 d_func()->convex = first;-
3204}
never executed: end of block
0
3205-
3206/*!-
3207 \obsolete-
3208-
3209 \fn bool QPainterPath::addRoundRect(const QRectF &rect, int roundness);-
3210 \since 4.3-
3211 \overload-
3212-
3213 Adds a rounded rectangle, \a rect, to the path.-
3214-
3215 The \a roundness argument specifies uniform roundness for the-
3216 rectangle. Vertical and horizontal roundness factors will be-
3217 adjusted accordingly to act uniformly around both axes. Use this-
3218 method if you want a rectangle equally rounded across both the X and-
3219 Y axis.-
3220-
3221 \sa addRoundedRect()-
3222*/-
3223-
3224/*!-
3225 \obsolete-
3226-
3227 \fn void QPainterPath::addRoundRect(qreal x, qreal y, qreal w, qreal h, int xRnd, int yRnd);-
3228 \overload-
3229-
3230 Adds a rectangle with rounded corners to the path. The rectangle-
3231 is constructed from \a x, \a y, and the width and height \a w-
3232 and \a h.-
3233-
3234 The \a xRnd and \a yRnd arguments specify how rounded the corners-
3235 should be. 0 is angled corners, 99 is maximum roundedness.-
3236-
3237 \sa addRoundedRect()-
3238 */-
3239-
3240/*!-
3241 \obsolete-
3242-
3243 \fn bool QPainterPath::addRoundRect(qreal x, qreal y, qreal width, qreal height, int roundness);-
3244 \since 4.3-
3245 \overload-
3246-
3247 Adds a rounded rectangle to the path, defined by the coordinates \a-
3248 x and \a y with the specified \a width and \a height.-
3249-
3250 The \a roundness argument specifies uniform roundness for the-
3251 rectangle. Vertical and horizontal roundness factors will be-
3252 adjusted accordingly to act uniformly around both axes. Use this-
3253 method if you want a rectangle equally rounded across both the X and-
3254 Y axis.-
3255-
3256 \sa addRoundedRect()-
3257*/-
3258-
3259/*!-
3260 \since 4.3-
3261-
3262 Returns a path which is the union of this path's fill area and \a p's fill area.-
3263-
3264 Set operations on paths will treat the paths as areas. Non-closed-
3265 paths will be treated as implicitly closed.-
3266 Bezier curves may be flattened to line segments due to numerical instability of-
3267 doing bezier curve intersections.-
3268-
3269 \sa intersected(), subtracted()-
3270*/-
3271QPainterPath QPainterPath::united(const QPainterPath &p) const-
3272{-
3273 if (isEmpty() || p.isEmpty())
isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
p.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
3274 return isEmpty() ? p : *this;
never executed: return isEmpty() ? p : *this;
isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
3275 QPathClipper clipper(*this, p);-
3276 return clipper.clip(QPathClipper::BoolOr);
never executed: return clipper.clip(QPathClipper::BoolOr);
0
3277}-
3278-
3279/*!-
3280 \since 4.3-
3281-
3282 Returns a path which is the intersection of this path's fill area and \a p's fill area.-
3283 Bezier curves may be flattened to line segments due to numerical instability of-
3284 doing bezier curve intersections.-
3285*/-
3286QPainterPath QPainterPath::intersected(const QPainterPath &p) const-
3287{-
3288 if (isEmpty() || p.isEmpty())
isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
p.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
3289 return QPainterPath();
never executed: return QPainterPath();
0
3290 QPathClipper clipper(*this, p);-
3291 return clipper.clip(QPathClipper::BoolAnd);
never executed: return clipper.clip(QPathClipper::BoolAnd);
0
3292}-
3293-
3294/*!-
3295 \since 4.3-
3296-
3297 Returns a path which is \a p's fill area subtracted from this path's fill area.-
3298-
3299 Set operations on paths will treat the paths as areas. Non-closed-
3300 paths will be treated as implicitly closed.-
3301 Bezier curves may be flattened to line segments due to numerical instability of-
3302 doing bezier curve intersections.-
3303*/-
3304QPainterPath QPainterPath::subtracted(const QPainterPath &p) const-
3305{-
3306 if (isEmpty() || p.isEmpty())
isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
p.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
3307 return *this;
never executed: return *this;
0
3308 QPathClipper clipper(*this, p);-
3309 return clipper.clip(QPathClipper::BoolSub);
never executed: return clipper.clip(QPathClipper::BoolSub);
0
3310}-
3311-
3312/*!-
3313 \since 4.3-
3314 \obsolete-
3315-
3316 Use subtracted() instead.-
3317-
3318 \sa subtracted()-
3319*/-
3320QPainterPath QPainterPath::subtractedInverted(const QPainterPath &p) const-
3321{-
3322 return p.subtracted(*this);
never executed: return p.subtracted(*this);
0
3323}-
3324-
3325/*!-
3326 \since 4.4-
3327-
3328 Returns a simplified version of this path. This implies merging all subpaths that intersect,-
3329 and returning a path containing no intersecting edges. Consecutive parallel lines will also-
3330 be merged. The simplified path will always use the default fill rule, Qt::OddEvenFill.-
3331 Bezier curves may be flattened to line segments due to numerical instability of-
3332 doing bezier curve intersections.-
3333*/-
3334QPainterPath QPainterPath::simplified() const-
3335{-
3336 if(isEmpty())
isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
3337 return *this;
never executed: return *this;
0
3338 QPathClipper clipper(*this, QPainterPath());-
3339 return clipper.clip(QPathClipper::Simplify);
never executed: return clipper.clip(QPathClipper::Simplify);
0
3340}-
3341-
3342/*!-
3343 \since 4.3-
3344-
3345 Returns \c true if the current path intersects at any point the given path \a p.-
3346 Also returns \c true if the current path contains or is contained by any part of \a p.-
3347-
3348 Set operations on paths will treat the paths as areas. Non-closed-
3349 paths will be treated as implicitly closed.-
3350-
3351 \sa contains()-
3352 */-
3353bool QPainterPath::intersects(const QPainterPath &p) const-
3354{-
3355 if (p.elementCount() == 1)
p.elementCount() == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
3356 return contains(p.elementAt(0));
never executed: return contains(p.elementAt(0));
0
3357 if (isEmpty() || p.isEmpty())
isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
p.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
3358 return false;
never executed: return false;
0
3359 QPathClipper clipper(*this, p);-
3360 return clipper.intersect();
never executed: return clipper.intersect();
0
3361}-
3362-
3363/*!-
3364 \since 4.3-
3365-
3366 Returns \c true if the given path \a p is contained within-
3367 the current path. Returns \c false if any edges of the current path and-
3368 \a p intersect.-
3369-
3370 Set operations on paths will treat the paths as areas. Non-closed-
3371 paths will be treated as implicitly closed.-
3372-
3373 \sa intersects()-
3374 */-
3375bool QPainterPath::contains(const QPainterPath &p) const-
3376{-
3377 if (p.elementCount() == 1)
p.elementCount() == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
3378 return contains(p.elementAt(0));
never executed: return contains(p.elementAt(0));
0
3379 if (isEmpty() || p.isEmpty())
isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
p.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
3380 return false;
never executed: return false;
0
3381 QPathClipper clipper(*this, p);-
3382 return clipper.contains();
never executed: return clipper.contains();
0
3383}-
3384-
3385void QPainterPath::setDirty(bool dirty)-
3386{-
3387 d_func()->dirtyBounds = dirty;-
3388 d_func()->dirtyControlBounds = dirty;-
3389 delete d_func()->pathConverter;-
3390 d_func()->pathConverter = 0;-
3391 d_func()->convex = false;-
3392}
never executed: end of block
0
3393-
3394void QPainterPath::computeBoundingRect() const-
3395{-
3396 QPainterPathData *d = d_func();-
3397 d->dirtyBounds = false;-
3398 if (!d_ptr) {
!d_ptrDescription
TRUEnever evaluated
FALSEnever evaluated
0
3399 d->bounds = QRect();-
3400 return;
never executed: return;
0
3401 }-
3402-
3403 qreal minx, maxx, miny, maxy;-
3404 minx = maxx = d->elements.at(0).x;-
3405 miny = maxy = d->elements.at(0).y;-
3406 for (int i=1; i<d->elements.size(); ++i) {
i<d->elements.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
3407 const Element &e = d->elements.at(i);-
3408-
3409 switch (e.type) {-
3410 case MoveToElement:
never executed: case MoveToElement:
0
3411 case LineToElement:
never executed: case LineToElement:
0
3412 if (e.x > maxx) maxx = e.x;
never executed: maxx = e.x;
e.x > maxxDescription
TRUEnever evaluated
FALSEnever evaluated
0
3413 else if (e.x < minx) minx = e.x;
never executed: minx = e.x;
e.x < minxDescription
TRUEnever evaluated
FALSEnever evaluated
0
3414 if (e.y > maxy) maxy = e.y;
never executed: maxy = e.y;
e.y > maxyDescription
TRUEnever evaluated
FALSEnever evaluated
0
3415 else if (e.y < miny) miny = e.y;
never executed: miny = e.y;
e.y < minyDescription
TRUEnever evaluated
FALSEnever evaluated
0
3416 break;
never executed: break;
0
3417 case CurveToElement:
never executed: case CurveToElement:
0
3418 {-
3419 QBezier b = QBezier::fromPoints(d->elements.at(i-1),-
3420 e,-
3421 d->elements.at(i+1),-
3422 d->elements.at(i+2));-
3423 QRectF r = qt_painterpath_bezier_extrema(b);-
3424 qreal right = r.right();-
3425 qreal bottom = r.bottom();-
3426 if (r.x() < minx) minx = r.x();
never executed: minx = r.x();
r.x() < minxDescription
TRUEnever evaluated
FALSEnever evaluated
0
3427 if (right > maxx) maxx = right;
never executed: maxx = right;
right > maxxDescription
TRUEnever evaluated
FALSEnever evaluated
0
3428 if (r.y() < miny) miny = r.y();
never executed: miny = r.y();
r.y() < minyDescription
TRUEnever evaluated
FALSEnever evaluated
0
3429 if (bottom > maxy) maxy = bottom;
never executed: maxy = bottom;
bottom > maxyDescription
TRUEnever evaluated
FALSEnever evaluated
0
3430 i += 2;-
3431 }-
3432 break;
never executed: break;
0
3433 default:
never executed: default:
0
3434 break;
never executed: break;
0
3435 }-
3436 }-
3437 d->bounds = QRectF(minx, miny, maxx - minx, maxy - miny);-
3438}
never executed: end of block
0
3439-
3440-
3441void QPainterPath::computeControlPointRect() const-
3442{-
3443 QPainterPathData *d = d_func();-
3444 d->dirtyControlBounds = false;-
3445 if (!d_ptr) {
!d_ptrDescription
TRUEnever evaluated
FALSEnever evaluated
0
3446 d->controlBounds = QRect();-
3447 return;
never executed: return;
0
3448 }-
3449-
3450 qreal minx, maxx, miny, maxy;-
3451 minx = maxx = d->elements.at(0).x;-
3452 miny = maxy = d->elements.at(0).y;-
3453 for (int i=1; i<d->elements.size(); ++i) {
i<d->elements.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
3454 const Element &e = d->elements.at(i);-
3455 if (e.x > maxx) maxx = e.x;
never executed: maxx = e.x;
e.x > maxxDescription
TRUEnever evaluated
FALSEnever evaluated
0
3456 else if (e.x < minx) minx = e.x;
never executed: minx = e.x;
e.x < minxDescription
TRUEnever evaluated
FALSEnever evaluated
0
3457 if (e.y > maxy) maxy = e.y;
never executed: maxy = e.y;
e.y > maxyDescription
TRUEnever evaluated
FALSEnever evaluated
0
3458 else if (e.y < miny) miny = e.y;
never executed: miny = e.y;
e.y < minyDescription
TRUEnever evaluated
FALSEnever evaluated
0
3459 }
never executed: end of block
0
3460 d->controlBounds = QRectF(minx, miny, maxx - minx, maxy - miny);-
3461}
never executed: end of block
0
3462-
3463#ifndef QT_NO_DEBUG_STREAM-
3464QDebug operator<<(QDebug s, const QPainterPath &p)-
3465{-
3466 s.nospace() << "QPainterPath: Element count=" << p.elementCount() << endl;-
3467 const char *types[] = {"MoveTo", "LineTo", "CurveTo", "CurveToData"};-
3468 for (int i=0; i<p.elementCount(); ++i) {
i<p.elementCount()Description
TRUEnever evaluated
FALSEnever evaluated
0
3469 s.nospace() << " -> " << types[p.elementAt(i).type] << "(x=" << p.elementAt(i).x << ", y=" << p.elementAt(i).y << ')' << endl;-
3470-
3471 }
never executed: end of block
0
3472 return s;
never executed: return s;
0
3473}-
3474#endif-
3475-
3476QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

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