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 ****************************************************************************/
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.
56 #include "QtGui/qpainterpath.h"
57 #include "private/qdatabuffer_p.h"
58 #include "private/qnumeric_p.h"
62 // #define QFIXED_IS_26_6
64 #if defined QFIXED_IS_26_6
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)
75 bool operator==(const qfixed2d &other) const { return x == other.x && y == other.y; }
77 #elif defined QFIXED_IS_32_32
78 typedef 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))
86 bool operator==(const qfixed2d &other) const { return x == other.x && y == other.y; }
88 #elif defined QFIXED_IS_16_16
90 #define qt_real_to_fixed(real) qfixed(real * qreal(1 << 16))
91 #define qt_fixed_to_real(fixed) qreal(fixed / qreal(1 << 16))
97 bool operator==(const qfixed2d &other) const { return x == other.x && y == other.y; }
100 typedef qreal qfixed;
101 #define qt_real_to_fixed(real) qfixed(real)
102 #define qt_fixed_to_real(fixed) fixed
108 bool operator==(const qfixed2d &other) const { return qFuzzyCompare(x, other.x)
109 && qFuzzyCompare(y, other.y); }
113 #define QT_PATH_KAPPA 0.5522847498
115 QPointF qt_curves_for_arc(const QRectF &rect, qreal startAngle, qreal sweepLength,
116 QPointF *controlPoints, int *point_count);
118 qreal qt_t_for_arc_angle(qreal angle);
120 typedef void (*qStrokerMoveToHook)(qfixed x, qfixed y, void *data);
121 typedef void (*qStrokerLineToHook)(qfixed x, qfixed y, void *data);
122 typedef void (*qStrokerCubicToHook)(qfixed c1x, qfixed c1y,
123 qfixed c2x, qfixed c2y,
124 qfixed ex, qfixed ey,
128 Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
130 class Q_GUI_EXPORT QStrokerOps
134 QPainterPath::ElementType type;
138 inline bool isMoveTo() const { return type == QPainterPath::MoveToElement; }
139 inline bool isLineTo() const { return type == QPainterPath::LineToElement; }
140 inline bool isCurveTo() const { return type == QPainterPath::CurveToElement; }
142 operator qfixed2d () { qfixed2d pt = { x, y }; return pt; }
146 virtual ~QStrokerOps();
148 void setMoveToHook(qStrokerMoveToHook moveToHook) { m_moveTo = moveToHook; }
149 void setLineToHook(qStrokerLineToHook lineToHook) { m_lineTo = lineToHook; }
150 void setCubicToHook(qStrokerCubicToHook cubicToHook) { m_cubicTo = cubicToHook; }
152 virtual void begin(void *customData);
155 inline void moveTo(qfixed x, qfixed y);
156 inline void lineTo(qfixed x, qfixed y);
157 inline void cubicTo(qfixed x1, qfixed y1, qfixed x2, qfixed y2, qfixed ex, qfixed ey);
159 void strokePath(const QPainterPath &path, void *data, const QTransform &matrix);
160 void strokePolygon(const QPointF *points, int pointCount, bool implicit_close,
161 void *data, const QTransform &matrix);
162 void strokeEllipse(const QRectF &ellipse, void *data, const QTransform &matrix);
164 QRectF clipRect() const { return m_clip_rect; }
165 void setClipRect(const QRectF &clip) { m_clip_rect = clip; }
167 void setCurveThresholdFromTransform(const QTransform &transform)
170 qt_scaleForTransform(transform, &scale);
171 m_dashThreshold = scale == 0 ? qreal(0.5) : (qreal(0.5) / scale);
174 void setCurveThreshold(qfixed threshold) { m_curveThreshold = threshold; }
175 qfixed curveThreshold() const { return m_curveThreshold; }
178 inline void emitMoveTo(qfixed x, qfixed y);
179 inline void emitLineTo(qfixed x, qfixed y);
180 inline void emitCubicTo(qfixed c1x, qfixed c1y, qfixed c2x, qfixed c2y, qfixed ex, qfixed ey);
182 virtual void processCurrentSubpath() = 0;
183 QDataBuffer<Element> m_elements;
186 qfixed m_curveThreshold;
187 qfixed m_dashThreshold;
190 qStrokerMoveToHook m_moveTo;
191 qStrokerLineToHook m_lineTo;
192 qStrokerCubicToHook m_cubicTo;
196 class Q_GUI_EXPORT QStroker : public QStrokerOps
212 void setStrokeWidth(qfixed width) { m_strokeWidth = width; }
213 qfixed strokeWidth() const { return m_strokeWidth; }
215 void setCapStyle(Qt::PenCapStyle capStyle) { m_capStyle = joinModeForCap(capStyle); }
216 Qt::PenCapStyle capStyle() const { return capForJoinMode(m_capStyle); }
217 LineJoinMode capStyleMode() const { return m_capStyle; }
219 void setJoinStyle(Qt::PenJoinStyle style) { m_joinStyle = joinModeForJoin(style); }
220 Qt::PenJoinStyle joinStyle() const { return joinForJoinMode(m_joinStyle); }
221 LineJoinMode joinStyleMode() const { return m_joinStyle; }
223 void setMiterLimit(qfixed length) { m_miterLimit = length; }
224 qfixed miterLimit() const { return m_miterLimit; }
226 void joinPoints(qfixed x, qfixed y, const QLineF &nextLine, LineJoinMode join);
227 inline void emitMoveTo(qfixed x, qfixed y);
228 inline void emitLineTo(qfixed x, qfixed y);
229 inline void emitCubicTo(qfixed c1x, qfixed c1y, qfixed c2x, qfixed c2y, qfixed ex, qfixed ey);
232 static Qt::PenCapStyle capForJoinMode(LineJoinMode mode);
233 static LineJoinMode joinModeForCap(Qt::PenCapStyle);
235 static Qt::PenJoinStyle joinForJoinMode(LineJoinMode mode);
236 static LineJoinMode joinModeForJoin(Qt::PenJoinStyle joinStyle);
238 virtual void processCurrentSubpath();
240 qfixed m_strokeWidth;
243 LineJoinMode m_capStyle;
244 LineJoinMode m_joinStyle;
253 class Q_GUI_EXPORT QDashStroker : public QStrokerOps
256 QDashStroker(QStroker *stroker);
259 QStroker *stroker() const { return m_stroker; }
261 static QVector<qfixed> patternForStyle(Qt::PenStyle style);
263 void setDashPattern(const QVector<qfixed> &dashPattern) { m_dashPattern = dashPattern; }
264 QVector<qfixed> dashPattern() const { return m_dashPattern; }
266 void setDashOffset(qreal offset) { m_dashOffset = offset; }
267 qreal dashOffset() const { return m_dashOffset; }
269 virtual void begin(void *data);
272 inline void setStrokeWidth(qreal width) { m_stroke_width = width; }
273 inline void setMiterLimit(qreal limit) { m_miter_limit = limit; }
276 virtual void processCurrentSubpath();
279 QVector<qfixed> m_dashPattern;
282 qreal m_stroke_width;
287 /*******************************************************************************
288 * QStrokerOps inline membmers
291 inline void QStrokerOps::emitMoveTo(qfixed x, qfixed y)
294 m_moveTo(x, y, m_customData);
297 inline void QStrokerOps::emitLineTo(qfixed x, qfixed y)
300 m_lineTo(x, y, m_customData);
303 inline void QStrokerOps::emitCubicTo(qfixed c1x, qfixed c1y, qfixed c2x, qfixed c2y, qfixed ex, qfixed ey)
306 m_cubicTo(c1x, c1y, c2x, c2y, ex, ey, m_customData);
309 inline void QStrokerOps::moveTo(qfixed x, qfixed y)
311 if (m_elements.size()>1)
312 processCurrentSubpath();
314 Element e = { QPainterPath::MoveToElement, x, y };
318 inline void QStrokerOps::lineTo(qfixed x, qfixed y)
320 Element e = { QPainterPath::LineToElement, x, y };
324 inline void QStrokerOps::cubicTo(qfixed x1, qfixed y1, qfixed x2, qfixed y2, qfixed ex, qfixed ey)
326 Element c1 = { QPainterPath::CurveToElement, x1, y1 };
327 Element c2 = { QPainterPath::CurveToDataElement, x2, y2 };
328 Element e = { QPainterPath::CurveToDataElement, ex, ey };
334 /*******************************************************************************
335 * QStroker inline members
337 inline void QStroker::emitMoveTo(qfixed x, qfixed y)
343 QStrokerOps::emitMoveTo(x, y);
346 inline void QStroker::emitLineTo(qfixed x, qfixed y)
352 QStrokerOps::emitLineTo(x, y);
355 inline void QStroker::emitCubicTo(qfixed c1x, qfixed c1y,
356 qfixed c2x, qfixed c2y,
357 qfixed ex, qfixed ey)
359 if (c2x == ex && c2y == ey) {
360 if (c1x == ex && c1y == ey) {
373 QStrokerOps::emitCubicTo(c1x, c1y, c2x, c2y, ex, ey);
376 /*******************************************************************************
377 * QDashStroker inline members
379 inline void QDashStroker::begin(void *data)
382 m_stroker->begin(data);
383 QStrokerOps::begin(data);
386 inline void QDashStroker::end()
395 #endif // QSTROKER_P_H