author | Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> |
Fri, 19 Feb 2010 23:40:16 +0200 | |
branch | RCL_3 |
changeset 4 | 3b1da2848fc7 |
parent 3 | 41300fa6a67c |
child 14 | c0432d11811c |
permissions | -rw-r--r-- |
0 | 1 |
/**************************************************************************** |
2 |
** |
|
4
3b1da2848fc7
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
3
diff
changeset
|
3 |
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
0 | 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 |
** No Commercial Usage |
|
11 |
** This file contains pre-release code and may not be distributed. |
|
12 |
** You may use this file in accordance with the terms and conditions |
|
13 |
** contained in the Technology Preview License Agreement accompanying |
|
14 |
** this package. |
|
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 |
** If you have questions regarding the use of this file, please contact |
|
29 |
** Nokia at qt-info@nokia.com. |
|
30 |
** |
|
31 |
** |
|
32 |
** |
|
33 |
** |
|
34 |
** |
|
35 |
** |
|
36 |
** |
|
37 |
** |
|
38 |
** $QT_END_LICENSE$ |
|
39 |
** |
|
40 |
****************************************************************************/ |
|
41 |
||
42 |
#include "qpaintengineex_p.h" |
|
43 |
#include "qpainter_p.h" |
|
44 |
#include "qstroker_p.h" |
|
45 |
#include "qbezier_p.h" |
|
46 |
#include <private/qpainterpath_p.h> |
|
47 |
||
48 |
#include <qvarlengtharray.h> |
|
49 |
#include <qdebug.h> |
|
50 |
||
51 |
||
52 |
QT_BEGIN_NAMESPACE |
|
53 |
||
54 |
/******************************************************************************* |
|
55 |
* |
|
56 |
* class QVectorPath |
|
57 |
* |
|
58 |
*/ |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
59 |
QVectorPath::~QVectorPath() |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
60 |
{ |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
61 |
if (m_hints & ShouldUseCacheHint) { |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
62 |
CacheEntry *e = m_cache; |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
63 |
while (e) { |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
64 |
if (e->data) |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
65 |
e->cleanup(e->engine, e->data); |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
66 |
CacheEntry *n = e->next; |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
67 |
delete e; |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
68 |
e = n; |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
69 |
} |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
70 |
} |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
71 |
} |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
72 |
|
0 | 73 |
|
74 |
QRectF QVectorPath::controlPointRect() const |
|
75 |
{ |
|
76 |
if (m_hints & ControlPointRect) |
|
77 |
return QRectF(QPointF(m_cp_rect.x1, m_cp_rect.y1), QPointF(m_cp_rect.x2, m_cp_rect.y2)); |
|
78 |
||
79 |
if (m_count == 0) { |
|
80 |
m_cp_rect.x1 = m_cp_rect.x2 = m_cp_rect.y1 = m_cp_rect.y2 = 0; |
|
81 |
m_hints |= ControlPointRect; |
|
82 |
return QRectF(QPointF(m_cp_rect.x1, m_cp_rect.y1), QPointF(m_cp_rect.x2, m_cp_rect.y2)); |
|
83 |
} |
|
84 |
Q_ASSERT(m_points && m_count > 0); |
|
85 |
||
86 |
const qreal *pts = m_points; |
|
87 |
m_cp_rect.x1 = m_cp_rect.x2 = *pts; |
|
88 |
++pts; |
|
89 |
m_cp_rect.y1 = m_cp_rect.y2 = *pts; |
|
90 |
++pts; |
|
91 |
||
92 |
const qreal *epts = m_points + (m_count << 1); |
|
93 |
while (pts < epts) { |
|
94 |
qreal x = *pts; |
|
95 |
if (x < m_cp_rect.x1) m_cp_rect.x1 = x; |
|
96 |
else if (x > m_cp_rect.x2) m_cp_rect.x2 = x; |
|
97 |
++pts; |
|
98 |
||
99 |
qreal y = *pts; |
|
100 |
if (y < m_cp_rect.y1) m_cp_rect.y1 = y; |
|
101 |
else if (y > m_cp_rect.y2) m_cp_rect.y2 = y; |
|
102 |
++pts; |
|
103 |
} |
|
104 |
||
105 |
m_hints |= ControlPointRect; |
|
106 |
return QRectF(QPointF(m_cp_rect.x1, m_cp_rect.y1), QPointF(m_cp_rect.x2, m_cp_rect.y2)); |
|
107 |
} |
|
108 |
||
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
109 |
|
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
110 |
QVectorPath::CacheEntry *QVectorPath::addCacheData(QPaintEngineEx *engine, void *data, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
111 |
qvectorpath_cache_cleanup cleanup) const{ |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
112 |
Q_ASSERT(!lookupCacheData(engine)); |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
113 |
if ((m_hints & IsCachedHint) == 0) { |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
114 |
m_cache = 0; |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
115 |
m_hints |= IsCachedHint; |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
116 |
} |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
117 |
CacheEntry *e = new CacheEntry; |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
118 |
e->engine = engine; |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
119 |
e->data = data; |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
120 |
e->cleanup = cleanup; |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
121 |
e->next = m_cache; |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
122 |
m_cache = e; |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
123 |
return m_cache; |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
124 |
} |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
125 |
|
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
126 |
|
0 | 127 |
const QVectorPath &qtVectorPathForPath(const QPainterPath &path) |
128 |
{ |
|
129 |
Q_ASSERT(path.d_func()); |
|
130 |
return path.d_func()->vectorPath(); |
|
131 |
} |
|
132 |
||
133 |
#ifndef QT_NO_DEBUG_STREAM |
|
134 |
QDebug Q_GUI_EXPORT &operator<<(QDebug &s, const QVectorPath &path) |
|
135 |
{ |
|
136 |
QRectF rf = path.controlPointRect(); |
|
137 |
s << "QVectorPath(size:" << path.elementCount() |
|
138 |
<< " hints:" << hex << path.hints() |
|
139 |
<< rf << ')'; |
|
140 |
return s; |
|
141 |
} |
|
142 |
#endif |
|
143 |
||
144 |
/******************************************************************************* |
|
145 |
* |
|
146 |
* class QPaintEngineExPrivate: |
|
147 |
* |
|
148 |
*/ |
|
149 |
||
150 |
||
151 |
struct StrokeHandler { |
|
152 |
QDataBuffer<qreal> pts; |
|
153 |
QDataBuffer<QPainterPath::ElementType> types; |
|
154 |
}; |
|
155 |
||
156 |
||
157 |
QPaintEngineExPrivate::QPaintEngineExPrivate() |
|
158 |
: dasher(&stroker), |
|
159 |
strokeHandler(0), |
|
160 |
activeStroker(0), |
|
161 |
strokerPen(Qt::NoPen) |
|
162 |
{ |
|
163 |
} |
|
164 |
||
165 |
||
166 |
QPaintEngineExPrivate::~QPaintEngineExPrivate() |
|
167 |
{ |
|
168 |
delete strokeHandler; |
|
169 |
} |
|
170 |
||
171 |
||
172 |
void QPaintEngineExPrivate::replayClipOperations() |
|
173 |
{ |
|
174 |
Q_Q(QPaintEngineEx); |
|
175 |
||
176 |
QPainter *p = q->painter(); |
|
177 |
if (!p || !p->d_ptr) |
|
178 |
return; |
|
179 |
||
180 |
QList<QPainterClipInfo> clipInfo = p->d_ptr->state->clipInfo; |
|
181 |
||
182 |
QTransform transform = q->state()->matrix; |
|
183 |
||
184 |
for (int i = 0; i < clipInfo.size(); ++i) { |
|
185 |
const QPainterClipInfo &info = clipInfo.at(i); |
|
186 |
||
187 |
if (info.matrix != q->state()->matrix) { |
|
188 |
q->state()->matrix = info.matrix; |
|
189 |
q->transformChanged(); |
|
190 |
} |
|
191 |
||
192 |
switch (info.clipType) { |
|
193 |
case QPainterClipInfo::RegionClip: |
|
194 |
q->clip(info.region, info.operation); |
|
195 |
break; |
|
196 |
case QPainterClipInfo::PathClip: |
|
197 |
q->clip(info.path, info.operation); |
|
198 |
break; |
|
199 |
case QPainterClipInfo::RectClip: |
|
200 |
q->clip(info.rect, info.operation); |
|
201 |
break; |
|
202 |
case QPainterClipInfo::RectFClip: { |
|
203 |
qreal right = info.rectf.x() + info.rectf.width(); |
|
204 |
qreal bottom = info.rectf.y() + info.rectf.height(); |
|
205 |
qreal pts[] = { info.rectf.x(), info.rectf.y(), |
|
206 |
right, info.rectf.y(), |
|
207 |
right, bottom, |
|
208 |
info.rectf.x(), bottom }; |
|
209 |
QVectorPath vp(pts, 4, 0, QVectorPath::RectangleHint); |
|
210 |
q->clip(vp, info.operation); |
|
211 |
break; |
|
212 |
} |
|
213 |
} |
|
214 |
} |
|
215 |
||
216 |
if (transform != q->state()->matrix) { |
|
217 |
q->state()->matrix = transform; |
|
218 |
q->transformChanged(); |
|
219 |
} |
|
220 |
} |
|
221 |
||
222 |
||
223 |
bool QPaintEngineExPrivate::hasClipOperations() const |
|
224 |
{ |
|
225 |
Q_Q(const QPaintEngineEx); |
|
226 |
||
227 |
QPainter *p = q->painter(); |
|
228 |
if (!p || !p->d_ptr) |
|
229 |
return false; |
|
230 |
||
231 |
QList<QPainterClipInfo> clipInfo = p->d_ptr->state->clipInfo; |
|
232 |
||
233 |
return !clipInfo.isEmpty(); |
|
234 |
} |
|
235 |
||
236 |
/******************************************************************************* |
|
237 |
* |
|
238 |
* class QPaintEngineEx: |
|
239 |
* |
|
240 |
*/ |
|
241 |
||
242 |
static QPainterPath::ElementType qpaintengineex_ellipse_types[] = { |
|
243 |
QPainterPath::MoveToElement, |
|
244 |
QPainterPath::CurveToElement, |
|
245 |
QPainterPath::CurveToDataElement, |
|
246 |
QPainterPath::CurveToDataElement, |
|
247 |
||
248 |
QPainterPath::CurveToElement, |
|
249 |
QPainterPath::CurveToDataElement, |
|
250 |
QPainterPath::CurveToDataElement, |
|
251 |
||
252 |
QPainterPath::CurveToElement, |
|
253 |
QPainterPath::CurveToDataElement, |
|
254 |
QPainterPath::CurveToDataElement, |
|
255 |
||
256 |
QPainterPath::CurveToElement, |
|
257 |
QPainterPath::CurveToDataElement, |
|
258 |
QPainterPath::CurveToDataElement |
|
259 |
}; |
|
260 |
||
261 |
static QPainterPath::ElementType qpaintengineex_line_types_16[] = { |
|
262 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, |
|
263 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, |
|
264 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, |
|
265 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, |
|
266 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, |
|
267 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, |
|
268 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, |
|
269 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, |
|
270 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, |
|
271 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, |
|
272 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, |
|
273 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, |
|
274 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, |
|
275 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, |
|
276 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, |
|
277 |
QPainterPath::MoveToElement, QPainterPath::LineToElement |
|
278 |
}; |
|
279 |
||
280 |
static QPainterPath::ElementType qpaintengineex_rect4_types_32[] = { |
|
281 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 1 |
|
282 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 2 |
|
283 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 3 |
|
284 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 4 |
|
285 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 5 |
|
286 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 6 |
|
287 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 7 |
|
288 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 8 |
|
289 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 9 |
|
290 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 10 |
|
291 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 11 |
|
292 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 12 |
|
293 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 13 |
|
294 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 14 |
|
295 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 15 |
|
296 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 16 |
|
297 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 17 |
|
298 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 18 |
|
299 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 19 |
|
300 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 20 |
|
301 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 21 |
|
302 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 22 |
|
303 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 23 |
|
304 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 24 |
|
305 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 25 |
|
306 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 26 |
|
307 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 27 |
|
308 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 28 |
|
309 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 29 |
|
310 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 30 |
|
311 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 31 |
|
312 |
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 32 |
|
313 |
}; |
|
314 |
||
315 |
||
316 |
static QPainterPath::ElementType qpaintengineex_roundedrect_types[] = { |
|
317 |
QPainterPath::MoveToElement, |
|
318 |
QPainterPath::LineToElement, |
|
319 |
QPainterPath::CurveToElement, |
|
320 |
QPainterPath::CurveToDataElement, |
|
321 |
QPainterPath::CurveToDataElement, |
|
322 |
QPainterPath::LineToElement, |
|
323 |
QPainterPath::CurveToElement, |
|
324 |
QPainterPath::CurveToDataElement, |
|
325 |
QPainterPath::CurveToDataElement, |
|
326 |
QPainterPath::LineToElement, |
|
327 |
QPainterPath::CurveToElement, |
|
328 |
QPainterPath::CurveToDataElement, |
|
329 |
QPainterPath::CurveToDataElement, |
|
330 |
QPainterPath::LineToElement, |
|
331 |
QPainterPath::CurveToElement, |
|
332 |
QPainterPath::CurveToDataElement, |
|
333 |
QPainterPath::CurveToDataElement |
|
334 |
}; |
|
335 |
||
336 |
||
337 |
||
338 |
static void qpaintengineex_moveTo(qreal x, qreal y, void *data) { |
|
339 |
((StrokeHandler *) data)->pts.add(x); |
|
340 |
((StrokeHandler *) data)->pts.add(y); |
|
341 |
((StrokeHandler *) data)->types.add(QPainterPath::MoveToElement); |
|
342 |
} |
|
343 |
||
344 |
static void qpaintengineex_lineTo(qreal x, qreal y, void *data) { |
|
345 |
((StrokeHandler *) data)->pts.add(x); |
|
346 |
((StrokeHandler *) data)->pts.add(y); |
|
347 |
((StrokeHandler *) data)->types.add(QPainterPath::LineToElement); |
|
348 |
} |
|
349 |
||
350 |
static void qpaintengineex_cubicTo(qreal c1x, qreal c1y, qreal c2x, qreal c2y, qreal ex, qreal ey, void *data) { |
|
351 |
((StrokeHandler *) data)->pts.add(c1x); |
|
352 |
((StrokeHandler *) data)->pts.add(c1y); |
|
353 |
((StrokeHandler *) data)->types.add(QPainterPath::CurveToElement); |
|
354 |
||
355 |
((StrokeHandler *) data)->pts.add(c2x); |
|
356 |
((StrokeHandler *) data)->pts.add(c2y); |
|
357 |
((StrokeHandler *) data)->types.add(QPainterPath::CurveToDataElement); |
|
358 |
||
359 |
((StrokeHandler *) data)->pts.add(ex); |
|
360 |
((StrokeHandler *) data)->pts.add(ey); |
|
361 |
((StrokeHandler *) data)->types.add(QPainterPath::CurveToDataElement); |
|
362 |
} |
|
363 |
||
364 |
QPaintEngineEx::QPaintEngineEx() |
|
365 |
: QPaintEngine(*new QPaintEngineExPrivate, AllFeatures) |
|
366 |
{ |
|
367 |
extended = true; |
|
368 |
} |
|
369 |
||
370 |
QPaintEngineEx::QPaintEngineEx(QPaintEngineExPrivate &data) |
|
371 |
: QPaintEngine(data, AllFeatures) |
|
372 |
{ |
|
373 |
extended = true; |
|
374 |
} |
|
375 |
||
376 |
QPainterState *QPaintEngineEx::createState(QPainterState *orig) const |
|
377 |
{ |
|
378 |
if (!orig) |
|
379 |
return new QPainterState; |
|
380 |
return new QPainterState(orig); |
|
381 |
} |
|
382 |
||
383 |
extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp |
|
384 |
||
385 |
void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) |
|
386 |
{ |
|
387 |
#ifdef QT_DEBUG_DRAW |
|
388 |
qDebug() << "QPaintEngineEx::stroke()" << pen; |
|
389 |
#endif |
|
390 |
||
391 |
Q_D(QPaintEngineEx); |
|
392 |
||
393 |
if (path.isEmpty()) |
|
394 |
return; |
|
395 |
||
396 |
if (!d->strokeHandler) { |
|
397 |
d->strokeHandler = new StrokeHandler; |
|
398 |
d->stroker.setMoveToHook(qpaintengineex_moveTo); |
|
399 |
d->stroker.setLineToHook(qpaintengineex_lineTo); |
|
400 |
d->stroker.setCubicToHook(qpaintengineex_cubicTo); |
|
401 |
} |
|
402 |
||
403 |
if (!qpen_fast_equals(pen, d->strokerPen)) { |
|
404 |
d->strokerPen = pen; |
|
405 |
d->stroker.setJoinStyle(pen.joinStyle()); |
|
406 |
d->stroker.setCapStyle(pen.capStyle()); |
|
407 |
d->stroker.setMiterLimit(pen.miterLimit()); |
|
408 |
qreal penWidth = pen.widthF(); |
|
409 |
if (penWidth == 0) |
|
410 |
d->stroker.setStrokeWidth(1); |
|
411 |
else |
|
412 |
d->stroker.setStrokeWidth(penWidth); |
|
413 |
||
414 |
Qt::PenStyle style = pen.style(); |
|
415 |
if (style == Qt::SolidLine) { |
|
416 |
d->activeStroker = &d->stroker; |
|
417 |
} else if (style == Qt::NoPen) { |
|
418 |
d->activeStroker = 0; |
|
419 |
} else { |
|
420 |
d->dasher.setDashPattern(pen.dashPattern()); |
|
421 |
d->dasher.setDashOffset(pen.dashOffset()); |
|
422 |
d->activeStroker = &d->dasher; |
|
423 |
} |
|
424 |
} |
|
425 |
||
426 |
if (!d->activeStroker) { |
|
427 |
return; |
|
428 |
} |
|
429 |
||
4
3b1da2848fc7
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
3
diff
changeset
|
430 |
if (pen.style() > Qt::SolidLine) { |
3b1da2848fc7
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
3
diff
changeset
|
431 |
if (pen.isCosmetic()) { |
3b1da2848fc7
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
3
diff
changeset
|
432 |
d->activeStroker->setClipRect(d->exDeviceRect); |
3b1da2848fc7
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
3
diff
changeset
|
433 |
} else { |
3b1da2848fc7
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
3
diff
changeset
|
434 |
QRectF clipRect = state()->matrix.inverted().mapRect(QRectF(d->exDeviceRect)); |
3b1da2848fc7
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
3
diff
changeset
|
435 |
d->activeStroker->setClipRect(clipRect); |
3b1da2848fc7
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
3
diff
changeset
|
436 |
} |
3b1da2848fc7
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
3
diff
changeset
|
437 |
} |
3b1da2848fc7
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
3
diff
changeset
|
438 |
|
0 | 439 |
const QPainterPath::ElementType *types = path.elements(); |
440 |
const qreal *points = path.points(); |
|
441 |
int pointCount = path.elementCount(); |
|
442 |
||
443 |
const qreal *lastPoint = points + (pointCount<<1); |
|
444 |
||
445 |
d->strokeHandler->types.reset(); |
|
446 |
d->strokeHandler->pts.reset(); |
|
447 |
||
448 |
// Some engines might decide to optimize for the non-shape hint later on... |
|
449 |
uint flags = QVectorPath::WindingFill; |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
450 |
|
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
451 |
if (path.elementCount() > 2) |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
452 |
flags |= QVectorPath::NonConvexShapeMask; |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
453 |
|
0 | 454 |
if (d->stroker.capStyle() == Qt::RoundCap || d->stroker.joinStyle() == Qt::RoundJoin) |
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
455 |
flags |= QVectorPath::CurvedShapeMask; |
0 | 456 |
|
457 |
// ### Perspective Xforms are currently not supported... |
|
458 |
if (!pen.isCosmetic()) { |
|
459 |
// We include cosmetic pens in this case to avoid having to |
|
460 |
// change the current transform. Normal transformed, |
|
461 |
// non-cosmetic pens will be transformed as part of fill |
|
462 |
// later, so they are also covered here.. |
|
463 |
d->activeStroker->begin(d->strokeHandler); |
|
464 |
if (types) { |
|
465 |
while (points < lastPoint) { |
|
466 |
switch (*types) { |
|
467 |
case QPainterPath::MoveToElement: |
|
468 |
d->activeStroker->moveTo(points[0], points[1]); |
|
469 |
points += 2; |
|
470 |
++types; |
|
471 |
break; |
|
472 |
case QPainterPath::LineToElement: |
|
473 |
d->activeStroker->lineTo(points[0], points[1]); |
|
474 |
points += 2; |
|
475 |
++types; |
|
476 |
break; |
|
477 |
case QPainterPath::CurveToElement: |
|
478 |
d->activeStroker->cubicTo(points[0], points[1], |
|
479 |
points[2], points[3], |
|
480 |
points[4], points[5]); |
|
481 |
points += 6; |
|
482 |
types += 3; |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
483 |
flags |= QVectorPath::CurvedShapeMask; |
0 | 484 |
break; |
485 |
default: |
|
486 |
break; |
|
487 |
} |
|
488 |
} |
|
489 |
if (path.hasImplicitClose()) |
|
490 |
d->activeStroker->lineTo(path.points()[0], path.points()[1]); |
|
491 |
||
492 |
} else { |
|
493 |
d->activeStroker->moveTo(points[0], points[1]); |
|
494 |
points += 2; |
|
495 |
++types; |
|
496 |
while (points < lastPoint) { |
|
497 |
d->activeStroker->lineTo(points[0], points[1]); |
|
498 |
points += 2; |
|
499 |
++types; |
|
500 |
} |
|
501 |
if (path.hasImplicitClose()) |
|
502 |
d->activeStroker->lineTo(path.points()[0], path.points()[1]); |
|
503 |
} |
|
504 |
d->activeStroker->end(); |
|
505 |
||
506 |
if (!d->strokeHandler->types.size()) // an empty path... |
|
507 |
return; |
|
508 |
||
509 |
QVectorPath strokePath(d->strokeHandler->pts.data(), |
|
510 |
d->strokeHandler->types.size(), |
|
511 |
d->strokeHandler->types.data(), |
|
512 |
flags); |
|
513 |
fill(strokePath, pen.brush()); |
|
514 |
} else { |
|
515 |
// For cosmetic pens we need a bit of trickery... We to process xform the input points |
|
516 |
if (state()->matrix.type() >= QTransform::TxProject) { |
|
517 |
QPainterPath painterPath = state()->matrix.map(path.convertToPainterPath()); |
|
518 |
d->activeStroker->strokePath(painterPath, d->strokeHandler, QTransform()); |
|
519 |
} else { |
|
520 |
d->activeStroker->begin(d->strokeHandler); |
|
521 |
if (types) { |
|
522 |
while (points < lastPoint) { |
|
523 |
switch (*types) { |
|
524 |
case QPainterPath::MoveToElement: { |
|
525 |
QPointF pt = (*(QPointF *) points) * state()->matrix; |
|
526 |
d->activeStroker->moveTo(pt.x(), pt.y()); |
|
527 |
points += 2; |
|
528 |
++types; |
|
529 |
break; |
|
530 |
} |
|
531 |
case QPainterPath::LineToElement: { |
|
532 |
QPointF pt = (*(QPointF *) points) * state()->matrix; |
|
533 |
d->activeStroker->lineTo(pt.x(), pt.y()); |
|
534 |
points += 2; |
|
535 |
++types; |
|
536 |
break; |
|
537 |
} |
|
538 |
case QPainterPath::CurveToElement: { |
|
539 |
QPointF c1 = ((QPointF *) points)[0] * state()->matrix; |
|
540 |
QPointF c2 = ((QPointF *) points)[1] * state()->matrix; |
|
541 |
QPointF e = ((QPointF *) points)[2] * state()->matrix; |
|
542 |
d->activeStroker->cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y()); |
|
543 |
points += 6; |
|
544 |
types += 3; |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
545 |
flags |= QVectorPath::CurvedShapeMask; |
0 | 546 |
break; |
547 |
} |
|
548 |
default: |
|
549 |
break; |
|
550 |
} |
|
551 |
} |
|
552 |
if (path.hasImplicitClose()) { |
|
553 |
QPointF pt = * ((QPointF *) path.points()) * state()->matrix; |
|
554 |
d->activeStroker->lineTo(pt.x(), pt.y()); |
|
555 |
} |
|
556 |
||
557 |
} else { |
|
558 |
QPointF p = ((QPointF *)points)[0] * state()->matrix; |
|
559 |
d->activeStroker->moveTo(p.x(), p.y()); |
|
560 |
points += 2; |
|
561 |
++types; |
|
562 |
while (points < lastPoint) { |
|
563 |
QPointF p = ((QPointF *)points)[0] * state()->matrix; |
|
564 |
d->activeStroker->lineTo(p.x(), p.y()); |
|
565 |
points += 2; |
|
566 |
++types; |
|
567 |
} |
|
568 |
if (path.hasImplicitClose()) |
|
569 |
d->activeStroker->lineTo(p.x(), p.y()); |
|
570 |
} |
|
571 |
d->activeStroker->end(); |
|
572 |
} |
|
573 |
||
574 |
QVectorPath strokePath(d->strokeHandler->pts.data(), |
|
575 |
d->strokeHandler->types.size(), |
|
576 |
d->strokeHandler->types.data(), |
|
577 |
flags); |
|
578 |
||
579 |
QTransform xform = state()->matrix; |
|
580 |
state()->matrix = QTransform(); |
|
581 |
transformChanged(); |
|
582 |
||
583 |
QBrush brush = pen.brush(); |
|
584 |
if (qbrush_style(brush) != Qt::SolidPattern) |
|
585 |
brush.setTransform(brush.transform() * xform); |
|
586 |
||
587 |
fill(strokePath, brush); |
|
588 |
||
589 |
state()->matrix = xform; |
|
590 |
transformChanged(); |
|
591 |
} |
|
592 |
} |
|
593 |
||
594 |
void QPaintEngineEx::draw(const QVectorPath &path) |
|
595 |
{ |
|
596 |
const QBrush &brush = state()->brush; |
|
597 |
if (qbrush_style(brush) != Qt::NoBrush) |
|
598 |
fill(path, brush); |
|
599 |
||
600 |
const QPen &pen = state()->pen; |
|
601 |
if (qpen_style(pen) != Qt::NoPen && qbrush_style(qpen_brush(pen)) != Qt::NoBrush) |
|
602 |
stroke(path, pen); |
|
603 |
} |
|
604 |
||
605 |
||
606 |
void QPaintEngineEx::clip(const QRect &r, Qt::ClipOperation op) |
|
607 |
{ |
|
608 |
qreal right = r.x() + r.width(); |
|
609 |
qreal bottom = r.y() + r.height(); |
|
610 |
qreal pts[] = { r.x(), r.y(), |
|
611 |
right, r.y(), |
|
612 |
right, bottom, |
|
613 |
r.x(), bottom, |
|
614 |
r.x(), r.y() }; |
|
615 |
QVectorPath vp(pts, 5, 0, QVectorPath::RectangleHint); |
|
616 |
clip(vp, op); |
|
617 |
} |
|
618 |
||
619 |
void QPaintEngineEx::clip(const QRegion ®ion, Qt::ClipOperation op) |
|
620 |
{ |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
621 |
if (region.rectCount() == 1) |
0 | 622 |
clip(region.boundingRect(), op); |
623 |
||
624 |
QVector<QRect> rects = region.rects(); |
|
625 |
if (rects.size() <= 32) { |
|
626 |
qreal pts[2*32*4]; |
|
627 |
int pos = 0; |
|
628 |
for (QVector<QRect>::const_iterator i = rects.constBegin(); i != rects.constEnd(); ++i) { |
|
629 |
qreal x1 = i->x(); |
|
630 |
qreal y1 = i->y(); |
|
631 |
qreal x2 = i->x() + i->width(); |
|
632 |
qreal y2 = i->y() + i->height(); |
|
633 |
||
634 |
pts[pos++] = x1; |
|
635 |
pts[pos++] = y1; |
|
636 |
||
637 |
pts[pos++] = x2; |
|
638 |
pts[pos++] = y1; |
|
639 |
||
640 |
pts[pos++] = x2; |
|
641 |
pts[pos++] = y2; |
|
642 |
||
643 |
pts[pos++] = x1; |
|
644 |
pts[pos++] = y2; |
|
645 |
} |
|
646 |
QVectorPath vp(pts, rects.size() * 4, qpaintengineex_rect4_types_32); |
|
647 |
clip(vp, op); |
|
648 |
} else { |
|
649 |
QVarLengthArray<qreal> pts(rects.size() * 2 * 4); |
|
650 |
QVarLengthArray<QPainterPath::ElementType> types(rects.size() * 4); |
|
651 |
int ppos = 0; |
|
652 |
int tpos = 0; |
|
653 |
||
654 |
for (QVector<QRect>::const_iterator i = rects.constBegin(); i != rects.constEnd(); ++i) { |
|
655 |
qreal x1 = i->x(); |
|
656 |
qreal y1 = i->y(); |
|
657 |
qreal x2 = i->x() + i->width(); |
|
658 |
qreal y2 = i->y() + i->height(); |
|
659 |
||
660 |
pts[ppos++] = x1; |
|
661 |
pts[ppos++] = y1; |
|
662 |
||
663 |
pts[ppos++] = x2; |
|
664 |
pts[ppos++] = y1; |
|
665 |
||
666 |
pts[ppos++] = x2; |
|
667 |
pts[ppos++] = y2; |
|
668 |
||
669 |
pts[ppos++] = x1; |
|
670 |
pts[ppos++] = y2; |
|
671 |
||
672 |
types[tpos++] = QPainterPath::MoveToElement; |
|
673 |
types[tpos++] = QPainterPath::LineToElement; |
|
674 |
types[tpos++] = QPainterPath::LineToElement; |
|
675 |
types[tpos++] = QPainterPath::LineToElement; |
|
676 |
} |
|
677 |
||
678 |
QVectorPath vp(pts.data(), rects.size() * 4, types.data()); |
|
679 |
clip(vp, op); |
|
680 |
} |
|
681 |
||
682 |
} |
|
683 |
||
684 |
void QPaintEngineEx::clip(const QPainterPath &path, Qt::ClipOperation op) |
|
685 |
{ |
|
686 |
if (path.isEmpty()) { |
|
687 |
QVectorPath vp(0, 0); |
|
688 |
clip(vp, op); |
|
689 |
} else { |
|
690 |
clip(qtVectorPathForPath(path), op); |
|
691 |
} |
|
692 |
} |
|
693 |
||
694 |
void QPaintEngineEx::fillRect(const QRectF &r, const QBrush &brush) |
|
695 |
{ |
|
696 |
qreal pts[] = { r.x(), r.y(), r.x() + r.width(), r.y(), |
|
697 |
r.x() + r.width(), r.y() + r.height(), r.x(), r.y() + r.height() }; |
|
698 |
QVectorPath vp(pts, 4, 0, QVectorPath::RectangleHint); |
|
699 |
fill(vp, brush); |
|
700 |
} |
|
701 |
||
702 |
void QPaintEngineEx::fillRect(const QRectF &r, const QColor &color) |
|
703 |
{ |
|
704 |
fillRect(r, QBrush(color)); |
|
705 |
} |
|
706 |
||
707 |
void QPaintEngineEx::drawRects(const QRect *rects, int rectCount) |
|
708 |
{ |
|
709 |
for (int i=0; i<rectCount; ++i) { |
|
710 |
const QRect &r = rects[i]; |
|
711 |
// ### Is there a one off here? |
|
712 |
qreal right = r.x() + r.width(); |
|
713 |
qreal bottom = r.y() + r.height(); |
|
714 |
qreal pts[] = { r.x(), r.y(), |
|
715 |
right, r.y(), |
|
716 |
right, bottom, |
|
717 |
r.x(), bottom, |
|
718 |
r.x(), r.y() }; |
|
719 |
QVectorPath vp(pts, 5, 0, QVectorPath::RectangleHint); |
|
720 |
draw(vp); |
|
721 |
} |
|
722 |
} |
|
723 |
||
724 |
void QPaintEngineEx::drawRects(const QRectF *rects, int rectCount) |
|
725 |
{ |
|
726 |
for (int i=0; i<rectCount; ++i) { |
|
727 |
const QRectF &r = rects[i]; |
|
728 |
qreal right = r.x() + r.width(); |
|
729 |
qreal bottom = r.y() + r.height(); |
|
730 |
qreal pts[] = { r.x(), r.y(), |
|
731 |
right, r.y(), |
|
732 |
right, bottom, |
|
733 |
r.x(), bottom, |
|
734 |
r.x(), r.y() }; |
|
735 |
QVectorPath vp(pts, 5, 0, QVectorPath::RectangleHint); |
|
736 |
draw(vp); |
|
737 |
} |
|
738 |
} |
|
739 |
||
740 |
||
741 |
void QPaintEngineEx::drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius, |
|
742 |
Qt::SizeMode mode) |
|
743 |
{ |
|
744 |
qreal x1 = rect.left(); |
|
745 |
qreal x2 = rect.right(); |
|
746 |
qreal y1 = rect.top(); |
|
747 |
qreal y2 = rect.bottom(); |
|
748 |
||
749 |
if (mode == Qt::RelativeSize) { |
|
750 |
xRadius = xRadius * rect.width() / 200.; |
|
751 |
yRadius = yRadius * rect.height() / 200.; |
|
752 |
} |
|
753 |
||
754 |
xRadius = qMin(xRadius, rect.width() / 2); |
|
755 |
yRadius = qMin(yRadius, rect.height() / 2); |
|
756 |
||
757 |
qreal pts[] = { |
|
758 |
x1 + xRadius, y1, // MoveTo |
|
759 |
x2 - xRadius, y1, // LineTo |
|
760 |
x2 - (1 - KAPPA) * xRadius, y1, // CurveTo |
|
761 |
x2, y1 + (1 - KAPPA) * yRadius, |
|
762 |
x2, y1 + yRadius, |
|
763 |
x2, y2 - yRadius, // LineTo |
|
764 |
x2, y2 - (1 - KAPPA) * yRadius, // CurveTo |
|
765 |
x2 - (1 - KAPPA) * xRadius, y2, |
|
766 |
x2 - xRadius, y2, |
|
767 |
x1 + xRadius, y2, // LineTo |
|
768 |
x1 + (1 - KAPPA) * xRadius, y2, // CurveTo |
|
769 |
x1, y2 - (1 - KAPPA) * yRadius, |
|
770 |
x1, y2 - yRadius, |
|
771 |
x1, y1 + yRadius, // LineTo |
|
772 |
x1, y1 + KAPPA * yRadius, // CurveTo |
|
773 |
x1 + (1 - KAPPA) * xRadius, y1, |
|
774 |
x1 + xRadius, y1 |
|
775 |
}; |
|
776 |
||
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
777 |
QVectorPath path(pts, 17, qpaintengineex_roundedrect_types, QVectorPath::RoundedRectHint); |
0 | 778 |
draw(path); |
779 |
} |
|
780 |
||
781 |
||
782 |
||
783 |
void QPaintEngineEx::drawLines(const QLine *lines, int lineCount) |
|
784 |
{ |
|
785 |
int elementCount = lineCount << 1; |
|
786 |
while (elementCount > 0) { |
|
787 |
int count = qMin(elementCount, 32); |
|
788 |
||
789 |
qreal pts[64]; |
|
790 |
int count2 = count<<1; |
|
791 |
#ifdef Q_WS_MAC |
|
792 |
for (int i=0; i<count2; i+=2) { |
|
793 |
pts[i] = ((int *) lines)[i+1]; |
|
794 |
pts[i+1] = ((int *) lines)[i]; |
|
795 |
} |
|
796 |
#else |
|
797 |
for (int i=0; i<count2; ++i) |
|
798 |
pts[i] = ((int *) lines)[i]; |
|
799 |
#endif |
|
800 |
||
801 |
QVectorPath path(pts, count, qpaintengineex_line_types_16, QVectorPath::LinesHint); |
|
802 |
stroke(path, state()->pen); |
|
803 |
||
804 |
elementCount -= 32; |
|
805 |
lines += 16; |
|
806 |
} |
|
807 |
} |
|
808 |
||
809 |
void QPaintEngineEx::drawLines(const QLineF *lines, int lineCount) |
|
810 |
{ |
|
811 |
int elementCount = lineCount << 1; |
|
812 |
while (elementCount > 0) { |
|
813 |
int count = qMin(elementCount, 32); |
|
814 |
||
815 |
QVectorPath path((qreal *) lines, count, qpaintengineex_line_types_16, |
|
816 |
QVectorPath::LinesHint); |
|
817 |
stroke(path, state()->pen); |
|
818 |
||
819 |
elementCount -= 32; |
|
820 |
lines += 16; |
|
821 |
} |
|
822 |
} |
|
823 |
||
824 |
void QPaintEngineEx::drawEllipse(const QRectF &r) |
|
825 |
{ |
|
826 |
qreal pts[26]; // QPointF[13] without constructors... |
|
827 |
union { |
|
828 |
qreal *ptr; |
|
829 |
QPointF *points; |
|
830 |
} x; |
|
831 |
x.ptr = pts; |
|
832 |
||
833 |
int point_count = 0; |
|
834 |
x.points[0] = qt_curves_for_arc(r, 0, -360, x.points + 1, &point_count); |
|
835 |
QVectorPath vp((qreal *) pts, 13, qpaintengineex_ellipse_types, QVectorPath::EllipseHint); |
|
836 |
draw(vp); |
|
837 |
} |
|
838 |
||
839 |
void QPaintEngineEx::drawEllipse(const QRect &r) |
|
840 |
{ |
|
841 |
drawEllipse(QRectF(r)); |
|
842 |
} |
|
843 |
||
844 |
void QPaintEngineEx::drawPath(const QPainterPath &path) |
|
845 |
{ |
|
846 |
if (!path.isEmpty()) |
|
847 |
draw(qtVectorPathForPath(path)); |
|
848 |
} |
|
849 |
||
850 |
||
851 |
void QPaintEngineEx::drawPoints(const QPointF *points, int pointCount) |
|
852 |
{ |
|
853 |
QPen pen = state()->pen; |
|
854 |
if (pen.capStyle() == Qt::FlatCap) |
|
855 |
pen.setCapStyle(Qt::SquareCap); |
|
856 |
||
857 |
if (pen.brush().isOpaque()) { |
|
858 |
while (pointCount > 0) { |
|
859 |
int count = qMin(pointCount, 16); |
|
860 |
qreal pts[64]; |
|
861 |
int oset = -1; |
|
862 |
for (int i=0; i<count; ++i) { |
|
863 |
pts[++oset] = points[i].x(); |
|
864 |
pts[++oset] = points[i].y(); |
|
4
3b1da2848fc7
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
3
diff
changeset
|
865 |
pts[++oset] = points[i].x() + 1/63.; |
0 | 866 |
pts[++oset] = points[i].y(); |
867 |
} |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
868 |
QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath::LinesHint); |
0 | 869 |
stroke(path, pen); |
870 |
pointCount -= 16; |
|
871 |
points += 16; |
|
872 |
} |
|
873 |
} else { |
|
874 |
for (int i=0; i<pointCount; ++i) { |
|
4
3b1da2848fc7
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
3
diff
changeset
|
875 |
qreal pts[] = { points[i].x(), points[i].y(), points[i].x() + 1/63., points[i].y() }; |
0 | 876 |
QVectorPath path(pts, 2, 0); |
877 |
stroke(path, pen); |
|
878 |
} |
|
879 |
} |
|
880 |
} |
|
881 |
||
882 |
void QPaintEngineEx::drawPoints(const QPoint *points, int pointCount) |
|
883 |
{ |
|
884 |
QPen pen = state()->pen; |
|
885 |
if (pen.capStyle() == Qt::FlatCap) |
|
886 |
pen.setCapStyle(Qt::SquareCap); |
|
887 |
||
888 |
if (pen.brush().isOpaque()) { |
|
889 |
while (pointCount > 0) { |
|
890 |
int count = qMin(pointCount, 16); |
|
891 |
qreal pts[64]; |
|
892 |
int oset = -1; |
|
893 |
for (int i=0; i<count; ++i) { |
|
894 |
pts[++oset] = points[i].x(); |
|
895 |
pts[++oset] = points[i].y(); |
|
4
3b1da2848fc7
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
3
diff
changeset
|
896 |
pts[++oset] = points[i].x() + 1/63; |
0 | 897 |
pts[++oset] = points[i].y(); |
898 |
} |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
899 |
QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath::LinesHint); |
0 | 900 |
stroke(path, pen); |
901 |
pointCount -= 16; |
|
902 |
points += 16; |
|
903 |
} |
|
904 |
} else { |
|
905 |
for (int i=0; i<pointCount; ++i) { |
|
4
3b1da2848fc7
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
3
diff
changeset
|
906 |
qreal pts[] = { points[i].x(), points[i].y(), points[i].x() +1/63., points[i].y() }; |
0 | 907 |
QVectorPath path(pts, 2, 0); |
908 |
stroke(path, pen); |
|
909 |
} |
|
910 |
} |
|
911 |
} |
|
912 |
||
913 |
||
914 |
void QPaintEngineEx::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) |
|
915 |
{ |
|
916 |
QVectorPath path((qreal *) points, pointCount, 0, QVectorPath::polygonFlags(mode)); |
|
917 |
||
918 |
if (mode == PolylineMode) |
|
919 |
stroke(path, state()->pen); |
|
920 |
else |
|
921 |
draw(path); |
|
922 |
} |
|
923 |
||
924 |
void QPaintEngineEx::drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) |
|
925 |
{ |
|
926 |
int count = pointCount<<1; |
|
927 |
QVarLengthArray<qreal> pts(count); |
|
928 |
||
929 |
#ifdef Q_WS_MAC |
|
930 |
for (int i=0; i<count; i+=2) { |
|
931 |
pts[i] = ((int *) points)[i+1]; |
|
932 |
pts[i+1] = ((int *) points)[i]; |
|
933 |
} |
|
934 |
#else |
|
935 |
for (int i=0; i<count; ++i) |
|
936 |
pts[i] = ((int *) points)[i]; |
|
937 |
#endif |
|
938 |
||
939 |
QVectorPath path(pts.data(), pointCount, 0, QVectorPath::polygonFlags(mode)); |
|
940 |
||
941 |
if (mode == PolylineMode) |
|
942 |
stroke(path, state()->pen); |
|
943 |
else |
|
944 |
draw(path); |
|
945 |
||
946 |
} |
|
947 |
||
948 |
void QPaintEngineEx::drawPixmap(const QPointF &pos, const QPixmap &pm) |
|
949 |
{ |
|
950 |
drawPixmap(QRectF(pos, pm.size()), pm, pm.rect()); |
|
951 |
} |
|
952 |
||
953 |
void QPaintEngineEx::drawImage(const QPointF &pos, const QImage &image) |
|
954 |
{ |
|
955 |
drawImage(QRectF(pos, image.size()), image, image.rect()); |
|
956 |
} |
|
957 |
||
958 |
void QPaintEngineEx::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s) |
|
959 |
{ |
|
960 |
QBrush brush(state()->pen.color(), pixmap); |
|
961 |
QTransform xform = QTransform::fromTranslate(r.x() - s.x(), r.y() - s.y()); |
|
962 |
brush.setTransform(xform); |
|
963 |
||
964 |
qreal pts[] = { r.x(), r.y(), |
|
965 |
r.x() + r.width(), r.y(), |
|
966 |
r.x() + r.width(), r.y() + r.height(), |
|
967 |
r.x(), r.y() + r.height() }; |
|
968 |
||
969 |
QVectorPath path(pts, 4, 0, QVectorPath::RectangleHint); |
|
970 |
fill(path, brush); |
|
971 |
} |
|
972 |
||
973 |
void QPaintEngineEx::drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints /*hints*/) |
|
974 |
{ |
|
975 |
qreal oldOpacity = state()->opacity; |
|
976 |
QTransform oldTransform = state()->matrix; |
|
977 |
||
978 |
for (int i = 0; i < dataCount; ++i) { |
|
979 |
QTransform transform = oldTransform; |
|
980 |
transform.translate(drawingData[i].point.x(), drawingData[i].point.y()); |
|
981 |
transform.rotate(drawingData[i].rotation); |
|
982 |
state()->opacity = oldOpacity * drawingData[i].opacity; |
|
983 |
state()->matrix = transform; |
|
984 |
opacityChanged(); |
|
985 |
transformChanged(); |
|
986 |
||
987 |
qreal w = drawingData[i].scaleX * drawingData[i].source.width(); |
|
988 |
qreal h = drawingData[i].scaleY * drawingData[i].source.height(); |
|
989 |
drawPixmap(QRectF(-0.5 * w, -0.5 * h, w, h), pixmap, drawingData[i].source); |
|
990 |
} |
|
991 |
||
992 |
state()->opacity = oldOpacity; |
|
993 |
state()->matrix = oldTransform; |
|
994 |
opacityChanged(); |
|
995 |
transformChanged(); |
|
996 |
} |
|
997 |
||
998 |
void QPaintEngineEx::setState(QPainterState *s) |
|
999 |
{ |
|
1000 |
QPaintEngine::state = s; |
|
1001 |
} |
|
1002 |
||
1003 |
||
1004 |
void QPaintEngineEx::updateState(const QPaintEngineState &) |
|
1005 |
{ |
|
1006 |
// do nothing... |
|
1007 |
} |
|
1008 |
||
1009 |
QT_END_NAMESPACE |