1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtGui module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #ifndef QPAINTERPATH_P_H
43 #define QPAINTERPATH_P_H
49 // This file is not part of the Qt API. It exists for the convenience
50 // of other Qt classes. This header file may change from version to
51 // version without notice, or even be removed.
56 #include "QtGui/qpainterpath.h"
57 #include "QtGui/qregion.h"
58 #include "QtCore/qlist.h"
59 #include "QtCore/qvarlengtharray.h"
63 #include <private/qvectorpath_p.h>
64 #include <private/qstroker_p.h>
68 class QPainterPathPrivate
71 friend class QPainterPath;
72 friend class QPainterPathData;
73 friend class QPainterPathStroker;
74 friend class QPainterPathStrokerPrivate;
76 friend class QTransform;
77 friend class QVectorPath;
78 friend struct QPainterPathPrivateDeleter;
79 #ifndef QT_NO_DATASTREAM
80 friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QPainterPath &);
81 friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QPainterPath &);
84 QPainterPathPrivate() : ref(1) {}
88 QVector<QPainterPath::Element> elements;
91 class QPainterPathStrokerPrivate
94 QPainterPathStrokerPrivate();
97 QVector<qfixed> dashPattern;
102 class QVectorPathConverter;
104 class QVectorPathConverter
107 QVectorPathConverter(const QVector<QPainterPath::Element> &path, uint fillRule, bool convex)
108 : pathData(path, fillRule, convex),
109 path(pathData.points.data(), path.size(),
110 pathData.elements.data(), pathData.flags) {}
112 const QVectorPath &vectorPath() {
116 struct QVectorPathData {
117 QVectorPathData(const QVector<QPainterPath::Element> &path, uint fillRule, bool convex)
118 : elements(path.size()),
119 points(path.size() * 2),
124 for (int i=0; i<path.size(); ++i) {
125 const QPainterPath::Element &e = path.at(i);
126 elements[i] = e.type;
127 points[ptsPos++] = e.x;
128 points[ptsPos++] = e.y;
129 if (e.type == QPainterPath::CurveToElement)
130 flags |= QVectorPath::CurvedShapeMask;
132 // This is to check if the path contains only alternating lineTo/moveTo,
133 // in which case we can set the LinesHint in the path. MoveTo is 0 and
134 // LineTo is 1 so the i%2 gets us what we want cheaply.
135 isLines = isLines && e.type == (QPainterPath::ElementType) (i%2);
138 if (fillRule == Qt::WindingFill)
139 flags |= QVectorPath::WindingFill;
141 flags |= QVectorPath::OddEvenFill;
144 flags |= QVectorPath::LinesShapeMask;
146 flags |= QVectorPath::AreaShapeMask;
148 flags |= QVectorPath::NonConvexShapeMask;
152 QVarLengthArray<QPainterPath::ElementType> elements;
153 QVarLengthArray<qreal> points;
157 QVectorPathData pathData;
161 Q_DISABLE_COPY(QVectorPathConverter)
164 class QPainterPathData : public QPainterPathPrivate
169 fillRule(Qt::OddEvenFill),
171 dirtyControlBounds(false),
174 require_moveTo = false;
178 QPainterPathData(const QPainterPathData &other) :
179 QPainterPathPrivate(), cStart(other.cStart), fillRule(other.fillRule),
180 bounds(other.bounds),
181 controlBounds(other.controlBounds),
182 dirtyBounds(other.dirtyBounds),
183 dirtyControlBounds(other.dirtyControlBounds),
184 convex(other.convex),
187 require_moveTo = false;
188 elements = other.elements;
191 ~QPainterPathData() {
192 delete pathConverter;
195 inline bool isClosed() const;
197 inline void maybeMoveTo();
199 const QVectorPath &vectorPath() {
201 pathConverter = new QVectorPathConverter(elements, fillRule, convex);
202 return pathConverter->path;
206 Qt::FillRule fillRule;
209 QRectF controlBounds;
211 uint require_moveTo : 1;
212 uint dirtyBounds : 1;
213 uint dirtyControlBounds : 1;
216 QVectorPathConverter *pathConverter;
220 inline const QPainterPath QVectorPath::convertToPainterPath() const
224 QPainterPathData *data = path.d_func();
225 data->elements.reserve(m_count);
227 data->elements[0].x = m_points[index++];
228 data->elements[0].y = m_points[index++];
231 data->elements[0].type = m_elements[0];
232 for (int i=1; i<m_count; ++i) {
233 QPainterPath::Element element;
234 element.x = m_points[index++];
235 element.y = m_points[index++];
236 element.type = m_elements[i];
237 data->elements << element;
240 data->elements[0].type = QPainterPath::MoveToElement;
241 for (int i=1; i<m_count; ++i) {
242 QPainterPath::Element element;
243 element.x = m_points[index++];
244 element.y = m_points[index++];
245 element.type = QPainterPath::LineToElement;
246 data->elements << element;
250 if (m_hints & OddEvenFill)
251 data->fillRule = Qt::OddEvenFill;
253 data->fillRule = Qt::WindingFill;
257 void Q_GUI_EXPORT qt_find_ellipse_coords(const QRectF &r, qreal angle, qreal length,
258 QPointF* startPoint, QPointF *endPoint);
260 inline bool QPainterPathData::isClosed() const
262 const QPainterPath::Element &first = elements.at(cStart);
263 const QPainterPath::Element &last = elements.last();
264 return first.x == last.x && first.y == last.y;
267 inline void QPainterPathData::close()
269 Q_ASSERT(ref.load() == 1);
270 require_moveTo = true;
271 const QPainterPath::Element &first = elements.at(cStart);
272 QPainterPath::Element &last = elements.last();
273 if (first.x != last.x || first.y != last.y) {
274 if (qFuzzyCompare(first.x, last.x) && qFuzzyCompare(first.y, last.y)) {
278 QPainterPath::Element e = { first.x, first.y, QPainterPath::LineToElement };
284 inline void QPainterPathData::maybeMoveTo()
286 if (require_moveTo) {
287 QPainterPath::Element e = elements.last();
288 e.type = QPainterPath::MoveToElement;
290 require_moveTo = false;
294 #define KAPPA qreal(0.5522847498)
299 #endif // QPAINTERPATH_P_H