source: trunk/src/gui/painting/qpainterpath_p.h

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 8.4 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#ifndef QPAINTERPATH_P_H
43#define QPAINTERPATH_P_H
44
45//
46// W A R N I N G
47// -------------
48//
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.
52//
53// We mean it.
54//
55
56#include "QtGui/qpainterpath.h"
57#include "QtGui/qregion.h"
58#include "QtCore/qlist.h"
59#include "QtCore/qvarlengtharray.h"
60
61#include <qdebug.h>
62
63#include <private/qvectorpath_p.h>
64#include <private/qstroker_p.h>
65
66QT_BEGIN_NAMESPACE
67
68class QPainterPathStrokerPrivate
69{
70public:
71 QPainterPathStrokerPrivate();
72
73 QStroker stroker;
74 QVector<qfixed> dashPattern;
75 qreal dashOffset;
76};
77
78class QPolygonF;
79class QVectorPathConverter;
80
81class QVectorPathConverter
82{
83public:
84 QVectorPathConverter(const QVector<QPainterPath::Element> &path, uint fillRule, bool convex)
85 : pathData(path, fillRule, convex),
86 path(pathData.points.data(), path.size(),
87 pathData.elements.data(), pathData.flags) {}
88
89 const QVectorPath &vectorPath() {
90 return path;
91 }
92
93 struct QVectorPathData {
94 QVectorPathData(const QVector<QPainterPath::Element> &path, uint fillRule, bool convex)
95 : elements(path.size()),
96 points(path.size() * 2),
97 flags(0)
98 {
99 int ptsPos = 0;
100 bool isLines = true;
101 for (int i=0; i<path.size(); ++i) {
102 const QPainterPath::Element &e = path.at(i);
103 elements[i] = e.type;
104 points[ptsPos++] = e.x;
105 points[ptsPos++] = e.y;
106 if (e.type == QPainterPath::CurveToElement)
107 flags |= QVectorPath::CurvedShapeMask;
108
109 // This is to check if the path contains only alternating lineTo/moveTo,
110 // in which case we can set the LinesHint in the path. MoveTo is 0 and
111 // LineTo is 1 so the i%2 gets us what we want cheaply.
112 isLines = isLines && e.type == (QPainterPath::ElementType) (i%2);
113 }
114
115 if (fillRule == Qt::WindingFill)
116 flags |= QVectorPath::WindingFill;
117 else
118 flags |= QVectorPath::OddEvenFill;
119
120 if (isLines)
121 flags |= QVectorPath::LinesShapeMask;
122 else {
123 flags |= QVectorPath::AreaShapeMask;
124 if (!convex)
125 flags |= QVectorPath::NonConvexShapeMask;
126 }
127
128 }
129 QVarLengthArray<QPainterPath::ElementType> elements;
130 QVarLengthArray<qreal> points;
131 uint flags;
132 };
133
134 QVectorPathData pathData;
135 QVectorPath path;
136
137private:
138 Q_DISABLE_COPY(QVectorPathConverter)
139};
140
141class QPainterPathData : public QPainterPathPrivate
142{
143public:
144 QPainterPathData() :
145 cStart(0),
146 fillRule(Qt::OddEvenFill),
147 dirtyBounds(false),
148 dirtyControlBounds(false),
149 pathConverter(0)
150 {
151 ref = 1;
152 require_moveTo = false;
153 convex = false;
154 }
155
156 QPainterPathData(const QPainterPathData &other) :
157 QPainterPathPrivate(), cStart(other.cStart), fillRule(other.fillRule),
158 bounds(other.bounds),
159 controlBounds(other.controlBounds),
160 dirtyBounds(other.dirtyBounds),
161 dirtyControlBounds(other.dirtyControlBounds),
162 convex(other.convex),
163 pathConverter(0)
164 {
165 ref = 1;
166 require_moveTo = false;
167 elements = other.elements;
168 }
169
170 ~QPainterPathData() {
171 delete pathConverter;
172 }
173
174 inline bool isClosed() const;
175 inline void close();
176 inline void maybeMoveTo();
177
178 const QVectorPath &vectorPath() {
179 if (!pathConverter)
180 pathConverter = new QVectorPathConverter(elements, fillRule, convex);
181 return pathConverter->path;
182 }
183
184 int cStart;
185 Qt::FillRule fillRule;
186
187 QRectF bounds;
188 QRectF controlBounds;
189
190 uint require_moveTo : 1;
191 uint dirtyBounds : 1;
192 uint dirtyControlBounds : 1;
193 uint convex : 1;
194
195 QVectorPathConverter *pathConverter;
196};
197
198
199inline const QPainterPath QVectorPath::convertToPainterPath() const
200{
201 QPainterPath path;
202 path.ensureData();
203 QPainterPathData *data = path.d_func();
204 data->elements.reserve(m_count);
205 int index = 0;
206 data->elements[0].x = m_points[index++];
207 data->elements[0].y = m_points[index++];
208
209 if (m_elements) {
210 data->elements[0].type = m_elements[0];
211 for (int i=1; i<m_count; ++i) {
212 QPainterPath::Element element;
213 element.x = m_points[index++];
214 element.y = m_points[index++];
215 element.type = m_elements[i];
216 data->elements << element;
217 }
218 } else {
219 data->elements[0].type = QPainterPath::MoveToElement;
220 for (int i=1; i<m_count; ++i) {
221 QPainterPath::Element element;
222 element.x = m_points[index++];
223 element.y = m_points[index++];
224 element.type = QPainterPath::LineToElement;
225 data->elements << element;
226 }
227 }
228
229 if (m_hints & OddEvenFill)
230 data->fillRule = Qt::OddEvenFill;
231 else
232 data->fillRule = Qt::WindingFill;
233 return path;
234}
235
236void Q_GUI_EXPORT qt_find_ellipse_coords(const QRectF &r, qreal angle, qreal length,
237 QPointF* startPoint, QPointF *endPoint);
238
239inline bool QPainterPathData::isClosed() const
240{
241 const QPainterPath::Element &first = elements.at(cStart);
242 const QPainterPath::Element &last = elements.last();
243 return first.x == last.x && first.y == last.y;
244}
245
246inline void QPainterPathData::close()
247{
248 Q_ASSERT(ref == 1);
249 require_moveTo = true;
250 const QPainterPath::Element &first = elements.at(cStart);
251 QPainterPath::Element &last = elements.last();
252 if (first.x != last.x || first.y != last.y) {
253 if (qFuzzyCompare(first.x, last.x) && qFuzzyCompare(first.y, last.y)) {
254 last.x = first.x;
255 last.y = first.y;
256 } else {
257 QPainterPath::Element e = { first.x, first.y, QPainterPath::LineToElement };
258 elements << e;
259 }
260 }
261}
262
263inline void QPainterPathData::maybeMoveTo()
264{
265 if (require_moveTo) {
266 QPainterPath::Element e = elements.last();
267 e.type = QPainterPath::MoveToElement;
268 elements.append(e);
269 require_moveTo = false;
270 }
271}
272
273#define KAPPA 0.5522847498
274
275
276QT_END_NAMESPACE
277
278#endif // QPAINTERPATH_P_H
Note: See TracBrowser for help on using the repository browser.