1
/****************************************************************************
3
** Copyright (C) 2016 The Qt Company Ltd.
4
** Contact: https://www.qt.io/licensing/
6
** This file is part of the QtGui module of the Qt Toolkit.
8
** $QT_BEGIN_LICENSE:LGPL$
9
** Commercial License Usage
10
** Licensees holding valid commercial Qt licenses may use this file in
11
** accordance with the commercial license agreement provided with the
12
** Software or, alternatively, in accordance with the terms contained in
13
** a written agreement between you and The Qt Company. For licensing terms
14
** and conditions see https://www.qt.io/terms-conditions. For further
15
** information use the contact form at https://www.qt.io/contact-us.
17
** GNU Lesser General Public License Usage
18
** Alternatively, this file may be used under the terms of the GNU Lesser
19
** General Public License version 3 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL3 included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 3 requirements
23
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25
** GNU General Public License Usage
26
** Alternatively, this file may be used under the terms of the GNU
27
** General Public License version 2.0 or (at your option) the GNU General
28
** Public license version 3 or any later version approved by the KDE Free
29
** Qt Foundation. The licenses are as published by the Free Software
30
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31
** included in the packaging of this file. Please review the following
32
** information to ensure the GNU General Public License requirements will
33
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34
** https://www.gnu.org/licenses/gpl-3.0.html.
38
****************************************************************************/
47
// This file is not part of the Qt API. It exists purely as an
48
// implementation detail. This header file may change from version to
49
// version without notice, or even be removed.
54
#include "QtGui/qpainterpath.h"
55
#include "private/qdatabuffer_p.h"
56
#include "private/qnumeric_p.h"
60
// #define QFIXED_IS_26_6
62
#if defined QFIXED_IS_26_6
64
#define qt_real_to_fixed(real) qfixed(real * 64)
65
#define qt_int_to_fixed(real) qfixed(int(real) << 6)
66
#define qt_fixed_to_real(fixed) qreal(fixed / qreal(64))
67
#define qt_fixed_to_int(fixed) int(fixed >> 6)
73
bool operator==(const qfixed2d &other) const { return x == other.x && y == other.y; }
75
#elif defined QFIXED_IS_32_32
76
typedef qint64 qfixed;
77
#define qt_real_to_fixed(real) qfixed(real * double(qint64(1) << 32))
78
#define qt_fixed_to_real(fixed) qreal(fixed / double(qint64(1) << 32))
84
bool operator==(const qfixed2d &other) const { return x == other.x && y == other.y; }
86
#elif defined QFIXED_IS_16_16
88
#define qt_real_to_fixed(real) qfixed(real * qreal(1 << 16))
89
#define qt_fixed_to_real(fixed) qreal(fixed / qreal(1 << 16))
95
bool operator==(const qfixed2d &other) const { return x == other.x && y == other.y; }
99
#define qt_real_to_fixed(real) qfixed(real)
100
#define qt_fixed_to_real(fixed) fixed
106
bool operator==(const qfixed2d &other) const { return qFuzzyCompare(x, other.x)
107
&& qFuzzyCompare(y, other.y); }
111
#define QT_PATH_KAPPA 0.5522847498
113
QPointF qt_curves_for_arc(const QRectF &rect, qreal startAngle, qreal sweepLength,
114
QPointF *controlPoints, int *point_count);
116
qreal qt_t_for_arc_angle(qreal angle);
118
typedef void (*qStrokerMoveToHook)(qfixed x, qfixed y, void *data);
119
typedef void (*qStrokerLineToHook)(qfixed x, qfixed y, void *data);
120
typedef void (*qStrokerCubicToHook)(qfixed c1x, qfixed c1y,
121
qfixed c2x, qfixed c2y,
122
qfixed ex, qfixed ey,
126
Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
128
class Q_GUI_EXPORT QStrokerOps
132
QPainterPath::ElementType type;
136
inline bool isMoveTo() const { return type == QPainterPath::MoveToElement; }
137
inline bool isLineTo() const { return type == QPainterPath::LineToElement; }
138
inline bool isCurveTo() const { return type == QPainterPath::CurveToElement; }
140
operator qfixed2d () { qfixed2d pt = { x, y }; return pt; }
144
virtual ~QStrokerOps();
146
void setMoveToHook(qStrokerMoveToHook moveToHook) { m_moveTo = moveToHook; }
147
void setLineToHook(qStrokerLineToHook lineToHook) { m_lineTo = lineToHook; }
148
void setCubicToHook(qStrokerCubicToHook cubicToHook) { m_cubicTo = cubicToHook; }
150
virtual void begin(void *customData);
153
inline void moveTo(qfixed x, qfixed y);
154
inline void lineTo(qfixed x, qfixed y);
155
inline void cubicTo(qfixed x1, qfixed y1, qfixed x2, qfixed y2, qfixed ex, qfixed ey);
157
void strokePath(const QPainterPath &path, void *data, const QTransform &matrix);
158
void strokePolygon(const QPointF *points, int pointCount, bool implicit_close,
159
void *data, const QTransform &matrix);
160
void strokeEllipse(const QRectF &ellipse, void *data, const QTransform &matrix);
162
QRectF clipRect() const { return m_clip_rect; }
163
void setClipRect(const QRectF &clip) { m_clip_rect = clip; }
165
void setCurveThresholdFromTransform(const QTransform &transform)
168
qt_scaleForTransform(transform, &scale);
169
m_dashThreshold = scale == 0 ? qreal(0.5) : (qreal(0.5) / scale);
172
void setCurveThreshold(qfixed threshold) { m_curveThreshold = threshold; }
173
qfixed curveThreshold() const { return m_curveThreshold; }
176
inline void emitMoveTo(qfixed x, qfixed y);
177
inline void emitLineTo(qfixed x, qfixed y);
178
inline void emitCubicTo(qfixed c1x, qfixed c1y, qfixed c2x, qfixed c2y, qfixed ex, qfixed ey);
180
virtual void processCurrentSubpath() = 0;
181
QDataBuffer<Element> m_elements;
184
qfixed m_curveThreshold;
185
qfixed m_dashThreshold;
188
qStrokerMoveToHook m_moveTo;
189
qStrokerLineToHook m_lineTo;
190
qStrokerCubicToHook m_cubicTo;
194
class Q_GUI_EXPORT QStroker : public QStrokerOps
210
void setStrokeWidth(qfixed width) { m_strokeWidth = width; m_curveThreshold = qt_real_to_fixed(width > 4 ? 1.0/width : 0.25); }
211
qfixed strokeWidth() const { return m_strokeWidth; }
213
void setCapStyle(Qt::PenCapStyle capStyle) { m_capStyle = joinModeForCap(capStyle); }
214
Qt::PenCapStyle capStyle() const { return capForJoinMode(m_capStyle); }
215
LineJoinMode capStyleMode() const { return m_capStyle; }
217
void setJoinStyle(Qt::PenJoinStyle style) { m_joinStyle = joinModeForJoin(style); }
218
Qt::PenJoinStyle joinStyle() const { return joinForJoinMode(m_joinStyle); }
219
LineJoinMode joinStyleMode() const { return m_joinStyle; }
221
void setMiterLimit(qfixed length) { m_miterLimit = length; }
222
qfixed miterLimit() const { return m_miterLimit; }
224
void joinPoints(qfixed x, qfixed y, const QLineF &nextLine, LineJoinMode join);
225
inline void emitMoveTo(qfixed x, qfixed y);
226
inline void emitLineTo(qfixed x, qfixed y);
227
inline void emitCubicTo(qfixed c1x, qfixed c1y, qfixed c2x, qfixed c2y, qfixed ex, qfixed ey);
230
static Qt::PenCapStyle capForJoinMode(LineJoinMode mode);
231
static LineJoinMode joinModeForCap(Qt::PenCapStyle);
233
static Qt::PenJoinStyle joinForJoinMode(LineJoinMode mode);
234
static LineJoinMode joinModeForJoin(Qt::PenJoinStyle joinStyle);
236
virtual void processCurrentSubpath();
238
qfixed m_strokeWidth;
241
LineJoinMode m_capStyle;
242
LineJoinMode m_joinStyle;
251
class Q_GUI_EXPORT QDashStroker : public QStrokerOps
254
QDashStroker(QStroker *stroker);
257
QStroker *stroker() const { return m_stroker; }
259
static QVector<qfixed> patternForStyle(Qt::PenStyle style);
261
void setDashPattern(const QVector<qfixed> &dashPattern) { m_dashPattern = dashPattern; }
262
QVector<qfixed> dashPattern() const { return m_dashPattern; }
264
void setDashOffset(qreal offset) { m_dashOffset = offset; }
265
qreal dashOffset() const { return m_dashOffset; }
267
virtual void begin(void *data);
270
inline void setStrokeWidth(qreal width) { m_stroke_width = width; }
271
inline void setMiterLimit(qreal limit) { m_miter_limit = limit; }
274
virtual void processCurrentSubpath();
277
QVector<qfixed> m_dashPattern;
280
qreal m_stroke_width;
285
/*******************************************************************************
286
* QStrokerOps inline membmers
289
inline void QStrokerOps::emitMoveTo(qfixed x, qfixed y)
292
m_moveTo(x, y, m_customData);
295
inline void QStrokerOps::emitLineTo(qfixed x, qfixed y)
298
m_lineTo(x, y, m_customData);
301
inline void QStrokerOps::emitCubicTo(qfixed c1x, qfixed c1y, qfixed c2x, qfixed c2y, qfixed ex, qfixed ey)
304
m_cubicTo(c1x, c1y, c2x, c2y, ex, ey, m_customData);
307
inline void QStrokerOps::moveTo(qfixed x, qfixed y)
309
if (m_elements.size()>1)
310
processCurrentSubpath();
312
Element e = { QPainterPath::MoveToElement, x, y };
316
inline void QStrokerOps::lineTo(qfixed x, qfixed y)
318
Element e = { QPainterPath::LineToElement, x, y };
322
inline void QStrokerOps::cubicTo(qfixed x1, qfixed y1, qfixed x2, qfixed y2, qfixed ex, qfixed ey)
324
Element c1 = { QPainterPath::CurveToElement, x1, y1 };
325
Element c2 = { QPainterPath::CurveToDataElement, x2, y2 };
326
Element e = { QPainterPath::CurveToDataElement, ex, ey };
332
/*******************************************************************************
333
* QStroker inline members
335
inline void QStroker::emitMoveTo(qfixed x, qfixed y)
341
QStrokerOps::emitMoveTo(x, y);
344
inline void QStroker::emitLineTo(qfixed x, qfixed y)
350
QStrokerOps::emitLineTo(x, y);
353
inline void QStroker::emitCubicTo(qfixed c1x, qfixed c1y,
354
qfixed c2x, qfixed c2y,
355
qfixed ex, qfixed ey)
357
if (c2x == ex && c2y == ey) {
358
if (c1x == ex && c1y == ey) {
371
QStrokerOps::emitCubicTo(c1x, c1y, c2x, c2y, ex, ey);
374
/*******************************************************************************
375
* QDashStroker inline members
377
inline void QDashStroker::begin(void *data)
380
m_stroker->begin(data);
381
QStrokerOps::begin(data);
384
inline void QDashStroker::end()
393
#endif // QSTROKER_P_H