OpenCoverage

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

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