source: trunk/src/gui/painting/qstroker_p.h@ 808

Last change on this file since 808 was 651, checked in by Dmitry A. Kuminov, 16 years ago

trunk: Merged in qt 4.6.2 sources.

File size: 11.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
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 [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#ifndef QSTROKER_P_H
43#define QSTROKER_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 purely as an
50// implementation detail. 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 "private/qdatabuffer_p.h"
58#include "private/qnumeric_p.h"
59
60QT_BEGIN_NAMESPACE
61
62// #define QFIXED_IS_26_6
63
64#if defined QFIXED_IS_26_6
65typedef int qfixed;
66#define qt_real_to_fixed(real) qfixed(real * 64)
67#define qt_int_to_fixed(real) qfixed(int(real) << 6)
68#define qt_fixed_to_real(fixed) qreal(fixed / qreal(64))
69#define qt_fixed_to_int(fixed) int(fixed >> 6)
70struct qfixed2d
71{
72 qfixed x;
73 qfixed y;
74
75 bool operator==(const qfixed2d &other) const { return x == other.x && y == other.y; }
76};
77#elif defined QFIXED_IS_32_32
78typedef qint64 qfixed;
79#define qt_real_to_fixed(real) qfixed(real * double(qint64(1) << 32))
80#define qt_fixed_to_real(fixed) qreal(fixed / double(qint64(1) << 32))
81struct qfixed2d
82{
83 qfixed x;
84 qfixed y;
85
86 bool operator==(const qfixed2d &other) const { return x == other.x && y == other.y; }
87};
88#elif defined QFIXED_IS_16_16
89typedef int qfixed;
90#define qt_real_to_fixed(real) qfixed(real * qreal(1 << 16))
91#define qt_fixed_to_real(fixed) qreal(fixed / qreal(1 << 16))
92struct qfixed2d
93{
94 qfixed x;
95 qfixed y;
96
97 bool operator==(const qfixed2d &other) const { return x == other.x && y == other.y; }
98};
99#else
100typedef qreal qfixed;
101#define qt_real_to_fixed(real) qfixed(real)
102#define qt_fixed_to_real(fixed) fixed
103struct qfixed2d
104{
105 qfixed x;
106 qfixed y;
107
108 bool operator==(const qfixed2d &other) const { return qFuzzyCompare(x, other.x)
109 && qFuzzyCompare(y, other.y); }
110};
111#endif
112
113#define QT_PATH_KAPPA 0.5522847498
114
115QPointF qt_curves_for_arc(const QRectF &rect, qreal startAngle, qreal sweepLength,
116 QPointF *controlPoints, int *point_count);
117
118qreal qt_t_for_arc_angle(qreal angle);
119
120typedef void (*qStrokerMoveToHook)(qfixed x, qfixed y, void *data);
121typedef void (*qStrokerLineToHook)(qfixed x, qfixed y, void *data);
122typedef void (*qStrokerCubicToHook)(qfixed c1x, qfixed c1y,
123 qfixed c2x, qfixed c2y,
124 qfixed ex, qfixed ey,
125 void *data);
126
127class Q_GUI_EXPORT QStrokerOps
128{
129public:
130 struct Element {
131 QPainterPath::ElementType type;
132 qfixed x;
133 qfixed y;
134
135 inline bool isMoveTo() const { return type == QPainterPath::MoveToElement; }
136 inline bool isLineTo() const { return type == QPainterPath::LineToElement; }
137 inline bool isCurveTo() const { return type == QPainterPath::CurveToElement; }
138
139 operator qfixed2d () { qfixed2d pt = { x, y }; return pt; }
140 };
141
142 QStrokerOps();
143 virtual ~QStrokerOps();
144
145 void setMoveToHook(qStrokerMoveToHook moveToHook) { m_moveTo = moveToHook; }
146 void setLineToHook(qStrokerLineToHook lineToHook) { m_lineTo = lineToHook; }
147 void setCubicToHook(qStrokerCubicToHook cubicToHook) { m_cubicTo = cubicToHook; }
148
149 virtual void begin(void *customData);
150 virtual void end();
151
152 inline void moveTo(qfixed x, qfixed y);
153 inline void lineTo(qfixed x, qfixed y);
154 inline void cubicTo(qfixed x1, qfixed y1, qfixed x2, qfixed y2, qfixed ex, qfixed ey);
155
156 void strokePath(const QPainterPath &path, void *data, const QTransform &matrix);
157 void strokePolygon(const QPointF *points, int pointCount, bool implicit_close,
158 void *data, const QTransform &matrix);
159 void strokeEllipse(const QRectF &ellipse, void *data, const QTransform &matrix);
160
161 QRectF clipRect() const { return m_clip_rect; }
162 void setClipRect(const QRectF &clip) { m_clip_rect = clip; }
163
164protected:
165 inline void emitMoveTo(qfixed x, qfixed y);
166 inline void emitLineTo(qfixed x, qfixed y);
167 inline void emitCubicTo(qfixed c1x, qfixed c1y, qfixed c2x, qfixed c2y, qfixed ex, qfixed ey);
168
169 virtual void processCurrentSubpath() = 0;
170 QDataBuffer<Element> m_elements;
171
172 QRectF m_clip_rect;
173
174 void *m_customData;
175 qStrokerMoveToHook m_moveTo;
176 qStrokerLineToHook m_lineTo;
177 qStrokerCubicToHook m_cubicTo;
178
179};
180
181class Q_GUI_EXPORT QStroker : public QStrokerOps
182{
183public:
184
185 enum LineJoinMode {
186 FlatJoin,
187 SquareJoin,
188 MiterJoin,
189 RoundJoin,
190 RoundCap,
191 SvgMiterJoin
192 };
193
194 QStroker();
195 ~QStroker();
196
197 void setStrokeWidth(qfixed width) { m_strokeWidth = width; }
198 qfixed strokeWidth() const { return m_strokeWidth; }
199
200 void setCapStyle(Qt::PenCapStyle capStyle) { m_capStyle = joinModeForCap(capStyle); }
201 Qt::PenCapStyle capStyle() const { return capForJoinMode(m_capStyle); }
202 LineJoinMode capStyleMode() const { return m_capStyle; }
203
204 void setJoinStyle(Qt::PenJoinStyle style) { m_joinStyle = joinModeForJoin(style); }
205 Qt::PenJoinStyle joinStyle() const { return joinForJoinMode(m_joinStyle); }
206 LineJoinMode joinStyleMode() const { return m_joinStyle; }
207
208 void setMiterLimit(qfixed length) { m_miterLimit = length; }
209 qfixed miterLimit() const { return m_miterLimit; }
210
211 void setCurveThreshold(qfixed threshold) { m_curveThreshold = threshold; }
212 qfixed curveThreshold() const { return m_curveThreshold; }
213
214 void joinPoints(qfixed x, qfixed y, const QLineF &nextLine, LineJoinMode join);
215 inline void emitMoveTo(qfixed x, qfixed y);
216 inline void emitLineTo(qfixed x, qfixed y);
217 inline void emitCubicTo(qfixed c1x, qfixed c1y, qfixed c2x, qfixed c2y, qfixed ex, qfixed ey);
218
219protected:
220 static Qt::PenCapStyle capForJoinMode(LineJoinMode mode);
221 static LineJoinMode joinModeForCap(Qt::PenCapStyle);
222
223 static Qt::PenJoinStyle joinForJoinMode(LineJoinMode mode);
224 static LineJoinMode joinModeForJoin(Qt::PenJoinStyle joinStyle);
225
226 virtual void processCurrentSubpath();
227
228 qfixed m_strokeWidth;
229 qfixed m_miterLimit;
230 qfixed m_curveThreshold;
231
232 LineJoinMode m_capStyle;
233 LineJoinMode m_joinStyle;
234
235 qfixed m_back1X;
236 qfixed m_back1Y;
237
238 qfixed m_back2X;
239 qfixed m_back2Y;
240};
241
242class Q_GUI_EXPORT QDashStroker : public QStrokerOps
243{
244public:
245 QDashStroker(QStroker *stroker);
246
247 QStroker *stroker() const { return m_stroker; }
248
249 static QVector<qfixed> patternForStyle(Qt::PenStyle style);
250
251 void setDashPattern(const QVector<qfixed> &dashPattern) { m_dashPattern = dashPattern; }
252 QVector<qfixed> dashPattern() const { return m_dashPattern; }
253
254 void setDashOffset(qreal offset) { m_dashOffset = offset; }
255 qreal dashOffset() const { return m_dashOffset; }
256
257 virtual void begin(void *data);
258 virtual void end();
259
260 inline void setStrokeWidth(qreal width) { m_stroke_width = width; }
261 inline void setMiterLimit(qreal limit) { m_miter_limit = limit; }
262
263protected:
264 virtual void processCurrentSubpath();
265
266 QStroker *m_stroker;
267 QVector<qfixed> m_dashPattern;
268 qreal m_dashOffset;
269
270 qreal m_stroke_width;
271 qreal m_miter_limit;
272};
273
274
275/*******************************************************************************
276 * QStrokerOps inline membmers
277 */
278
279inline void QStrokerOps::emitMoveTo(qfixed x, qfixed y)
280{
281 Q_ASSERT(m_moveTo);
282 m_moveTo(x, y, m_customData);
283}
284
285inline void QStrokerOps::emitLineTo(qfixed x, qfixed y)
286{
287 Q_ASSERT(m_lineTo);
288 m_lineTo(x, y, m_customData);
289}
290
291inline void QStrokerOps::emitCubicTo(qfixed c1x, qfixed c1y, qfixed c2x, qfixed c2y, qfixed ex, qfixed ey)
292{
293 Q_ASSERT(m_cubicTo);
294 m_cubicTo(c1x, c1y, c2x, c2y, ex, ey, m_customData);
295}
296
297inline void QStrokerOps::moveTo(qfixed x, qfixed y)
298{
299 if (m_elements.size()>1)
300 processCurrentSubpath();
301 m_elements.reset();
302 Element e = { QPainterPath::MoveToElement, x, y };
303 m_elements.add(e);
304}
305
306inline void QStrokerOps::lineTo(qfixed x, qfixed y)
307{
308 Element e = { QPainterPath::LineToElement, x, y };
309 m_elements.add(e);
310}
311
312inline void QStrokerOps::cubicTo(qfixed x1, qfixed y1, qfixed x2, qfixed y2, qfixed ex, qfixed ey)
313{
314 Element c1 = { QPainterPath::CurveToElement, x1, y1 };
315 Element c2 = { QPainterPath::CurveToDataElement, x2, y2 };
316 Element e = { QPainterPath::CurveToDataElement, ex, ey };
317 m_elements.add(c1);
318 m_elements.add(c2);
319 m_elements.add(e);
320}
321
322/*******************************************************************************
323 * QStroker inline members
324 */
325inline void QStroker::emitMoveTo(qfixed x, qfixed y)
326{
327 m_back2X = m_back1X;
328 m_back2Y = m_back1Y;
329 m_back1X = x;
330 m_back1Y = y;
331 QStrokerOps::emitMoveTo(x, y);
332}
333
334inline void QStroker::emitLineTo(qfixed x, qfixed y)
335{
336 m_back2X = m_back1X;
337 m_back2Y = m_back1Y;
338 m_back1X = x;
339 m_back1Y = y;
340 QStrokerOps::emitLineTo(x, y);
341}
342
343inline void QStroker::emitCubicTo(qfixed c1x, qfixed c1y,
344 qfixed c2x, qfixed c2y,
345 qfixed ex, qfixed ey)
346{
347 if (c2x == ex && c2y == ey) {
348 if (c1x == ex && c1y == ey) {
349 m_back2X = m_back1X;
350 m_back2Y = m_back1Y;
351 } else {
352 m_back2X = c1x;
353 m_back2Y = c1y;
354 }
355 } else {
356 m_back2X = c2x;
357 m_back2Y = c2y;
358 }
359 m_back1X = ex;
360 m_back1Y = ey;
361 QStrokerOps::emitCubicTo(c1x, c1y, c2x, c2y, ex, ey);
362}
363
364/*******************************************************************************
365 * QDashStroker inline members
366 */
367inline void QDashStroker::begin(void *data)
368{
369 if (m_stroker)
370 m_stroker->begin(data);
371 QStrokerOps::begin(data);
372}
373
374inline void QDashStroker::end()
375{
376 QStrokerOps::end();
377 if (m_stroker)
378 m_stroker->end();
379}
380
381QT_END_NAMESPACE
382
383#endif // QSTROKER_P_H
Note: See TracBrowser for help on using the repository browser.