Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qstroker_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#ifndef QSTROKER_P_H
6#define QSTROKER_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtGui/private/qtguiglobal_p.h>
20#include "QtGui/qpainterpath.h"
21#include "private/qdatabuffer_p.h"
22#include "private/qnumeric_p.h"
23
25
26// #define QFIXED_IS_26_6
27
28#if defined QFIXED_IS_26_6
29typedef int qfixed;
30#define qt_real_to_fixed(real) qfixed(real * 64)
31#define qt_int_to_fixed(real) qfixed(int(real) << 6)
32#define qt_fixed_to_real(fixed) qreal(fixed / qreal(64))
33#define qt_fixed_to_int(fixed) int(fixed >> 6)
34struct qfixed2d
35{
36 qfixed x;
37 qfixed y;
38
39 bool operator==(const qfixed2d &other) const { return x == other.x && y == other.y; }
40};
41#elif defined QFIXED_IS_32_32
42typedef qint64 qfixed;
43#define qt_real_to_fixed(real) qfixed(real * double(qint64(1) << 32))
44#define qt_fixed_to_real(fixed) qreal(fixed / double(qint64(1) << 32))
45struct qfixed2d
46{
47 qfixed x;
48 qfixed y;
49
50 bool operator==(const qfixed2d &other) const { return x == other.x && y == other.y; }
51};
52#elif defined QFIXED_IS_16_16
53typedef int qfixed;
54#define qt_real_to_fixed(real) qfixed(real * qreal(1 << 16))
55#define qt_fixed_to_real(fixed) qreal(fixed / qreal(1 << 16))
56struct qfixed2d
57{
58 qfixed x;
59 qfixed y;
60
61 bool operator==(const qfixed2d &other) const { return x == other.x && y == other.y; }
62};
63#else
64typedef qreal qfixed;
65#define qt_real_to_fixed(real) qfixed(real)
66#define qt_fixed_to_real(fixed) fixed
68{
71
72 bool isFinite() { return qIsFinite(x) && qIsFinite(y); }
73 bool operator==(const qfixed2d &other) const { return qFuzzyCompare(x, other.x)
74 && qFuzzyCompare(y, other.y); }
75};
76#endif
77
78#define QT_PATH_KAPPA 0.5522847498
79
80QPointF qt_curves_for_arc(const QRectF &rect, qreal startAngle, qreal sweepLength,
81 QPointF *controlPoints, int *point_count);
82
83qreal qt_t_for_arc_angle(qreal angle);
84
85typedef void (*qStrokerMoveToHook)(qfixed x, qfixed y, void *data);
86typedef void (*qStrokerLineToHook)(qfixed x, qfixed y, void *data);
87typedef void (*qStrokerCubicToHook)(qfixed c1x, qfixed c1y,
88 qfixed c2x, qfixed c2y,
89 qfixed ex, qfixed ey,
90 void *data);
91
92// qtransform.cpp
93Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
94
95class Q_GUI_EXPORT QStrokerOps
96{
97public:
98 struct Element {
99 QPainterPath::ElementType type;
100 qfixed x;
101 qfixed y;
102
103 inline bool isMoveTo() const { return type == QPainterPath::MoveToElement; }
104 inline bool isLineTo() const { return type == QPainterPath::LineToElement; }
105 inline bool isCurveTo() const { return type == QPainterPath::CurveToElement; }
106
107 operator qfixed2d () { qfixed2d pt = { x, y }; return pt; }
108 };
109
110 QStrokerOps();
111 virtual ~QStrokerOps();
112
113 void setMoveToHook(qStrokerMoveToHook moveToHook) { m_moveTo = moveToHook; }
114 void setLineToHook(qStrokerLineToHook lineToHook) { m_lineTo = lineToHook; }
115 void setCubicToHook(qStrokerCubicToHook cubicToHook) { m_cubicTo = cubicToHook; }
116
117 virtual void begin(void *customData);
118 virtual void end();
119
120 inline void moveTo(qfixed x, qfixed y);
121 inline void lineTo(qfixed x, qfixed y);
122 inline void cubicTo(qfixed x1, qfixed y1, qfixed x2, qfixed y2, qfixed ex, qfixed ey);
123
124 void strokePath(const QPainterPath &path, void *data, const QTransform &matrix);
125 void strokePolygon(const QPointF *points, int pointCount, bool implicit_close,
126 void *data, const QTransform &matrix);
127 void strokeEllipse(const QRectF &ellipse, void *data, const QTransform &matrix);
128
129 QRectF clipRect() const { return m_clip_rect; }
130 void setClipRect(const QRectF &clip) { m_clip_rect = clip; }
131
132 void setCurveThresholdFromTransform(const QTransform &transform)
133 {
134 qreal scale;
135 qt_scaleForTransform(transform, &scale);
136 m_dashThreshold = scale == 0 ? qreal(0.5) : (qreal(0.5) / scale);
137 }
138
139 void setCurveThreshold(qfixed threshold) { m_curveThreshold = threshold; }
140 qfixed curveThreshold() const { return m_curveThreshold; }
141
142protected:
143 inline void emitMoveTo(qfixed x, qfixed y);
144 inline void emitLineTo(qfixed x, qfixed y);
145 inline void emitCubicTo(qfixed c1x, qfixed c1y, qfixed c2x, qfixed c2y, qfixed ex, qfixed ey);
146
147 virtual void processCurrentSubpath() = 0;
148 QDataBuffer<Element> m_elements;
149
150 QRectF m_clip_rect;
151 qfixed m_curveThreshold;
152 qfixed m_dashThreshold;
153
154 void *m_customData;
155 qStrokerMoveToHook m_moveTo;
156 qStrokerLineToHook m_lineTo;
157 qStrokerCubicToHook m_cubicTo;
158
159};
160
161class Q_GUI_EXPORT QStroker : public QStrokerOps
162{
163public:
164
165 enum LineJoinMode {
166 FlatJoin,
167 SquareJoin,
168 MiterJoin,
169 RoundJoin,
170 RoundCap,
171 SvgMiterJoin
172 };
173
174 QStroker();
175 ~QStroker();
176
177 void setStrokeWidth(qfixed width)
178 {
179 m_strokeWidth = width;
180 m_curveThreshold = qt_real_to_fixed(qBound(0.00025, 1.0 / qt_fixed_to_real(width), 0.25));
181 }
182 qfixed strokeWidth() const { return m_strokeWidth; }
183
184 void setCapStyle(Qt::PenCapStyle capStyle) { m_capStyle = joinModeForCap(capStyle); }
185 Qt::PenCapStyle capStyle() const { return capForJoinMode(m_capStyle); }
186 LineJoinMode capStyleMode() const { return m_capStyle; }
187
188 void setJoinStyle(Qt::PenJoinStyle style) { m_joinStyle = joinModeForJoin(style); }
189 Qt::PenJoinStyle joinStyle() const { return joinForJoinMode(m_joinStyle); }
190 LineJoinMode joinStyleMode() const { return m_joinStyle; }
191
192 void setMiterLimit(qfixed length) { m_miterLimit = length; }
193 qfixed miterLimit() const { return m_miterLimit; }
194
195 void setForceOpen(bool state) { m_forceOpen = state; }
196 bool forceOpen() const { return m_forceOpen; }
197
198 void joinPoints(qfixed x, qfixed y, const QLineF &nextLine, LineJoinMode join);
199 inline void emitMoveTo(qfixed x, qfixed y);
200 inline void emitLineTo(qfixed x, qfixed y);
201 inline void emitCubicTo(qfixed c1x, qfixed c1y, qfixed c2x, qfixed c2y, qfixed ex, qfixed ey);
202
203protected:
204 static Qt::PenCapStyle capForJoinMode(LineJoinMode mode);
205 static LineJoinMode joinModeForCap(Qt::PenCapStyle);
206
207 static Qt::PenJoinStyle joinForJoinMode(LineJoinMode mode);
208 static LineJoinMode joinModeForJoin(Qt::PenJoinStyle joinStyle);
209
210 void processCurrentSubpath() override;
211
212 qfixed m_strokeWidth;
213 qfixed m_miterLimit;
214
215 LineJoinMode m_capStyle;
216 LineJoinMode m_joinStyle;
217
218 qfixed m_back1X;
219 qfixed m_back1Y;
220
221 qfixed m_back2X;
222 qfixed m_back2Y;
223
224 bool m_forceOpen;
225};
226
227class Q_GUI_EXPORT QDashStroker : public QStrokerOps
228{
229public:
230 QDashStroker(QStroker *stroker);
231 ~QDashStroker();
232
233 QStroker *stroker() const { return m_stroker; }
234
235 static QList<qfixed> patternForStyle(Qt::PenStyle style);
236 static int repetitionLimit() { return 10000; }
237
238 void setDashPattern(const QList<qfixed> &dashPattern) { m_dashPattern = dashPattern; }
239 QList<qfixed> dashPattern() const { return m_dashPattern; }
240
241 void setDashOffset(qreal offset) { m_dashOffset = offset; }
242 qreal dashOffset() const { return m_dashOffset; }
243
244 void begin(void *data) override;
245 void end() override;
246
247 inline void setStrokeWidth(qreal width) { m_stroke_width = width; }
248 inline void setMiterLimit(qreal limit) { m_miter_limit = limit; }
249
250protected:
251 void processCurrentSubpath() override;
252
253 QStroker *m_stroker;
254 QList<qfixed> m_dashPattern;
255 qreal m_dashOffset;
256
257 qreal m_stroke_width;
258 qreal m_miter_limit;
259};
260
261
262/*******************************************************************************
263 * QStrokerOps inline membmers
264 */
265
266inline void QStrokerOps::emitMoveTo(qfixed x, qfixed y)
267{
268 Q_ASSERT(m_moveTo);
269 m_moveTo(x, y, m_customData);
270}
271
272inline void QStrokerOps::emitLineTo(qfixed x, qfixed y)
273{
274 Q_ASSERT(m_lineTo);
275 m_lineTo(x, y, m_customData);
276}
277
278inline void QStrokerOps::emitCubicTo(qfixed c1x, qfixed c1y, qfixed c2x, qfixed c2y, qfixed ex, qfixed ey)
279{
280 Q_ASSERT(m_cubicTo);
281 m_cubicTo(c1x, c1y, c2x, c2y, ex, ey, m_customData);
282}
283
284inline void QStrokerOps::moveTo(qfixed x, qfixed y)
285{
286 if (m_elements.size()>1)
287 processCurrentSubpath();
288 m_elements.reset();
289 Element e = { QPainterPath::MoveToElement, x, y };
290 m_elements.add(e);
291}
292
293inline void QStrokerOps::lineTo(qfixed x, qfixed y)
294{
295 Element e = { QPainterPath::LineToElement, x, y };
296 m_elements.add(e);
297}
298
299inline void QStrokerOps::cubicTo(qfixed x1, qfixed y1, qfixed x2, qfixed y2, qfixed ex, qfixed ey)
300{
301 Element c1 = { QPainterPath::CurveToElement, x1, y1 };
302 Element c2 = { QPainterPath::CurveToDataElement, x2, y2 };
303 Element e = { QPainterPath::CurveToDataElement, ex, ey };
304 m_elements.add(c1);
305 m_elements.add(c2);
306 m_elements.add(e);
307}
308
309/*******************************************************************************
310 * QStroker inline members
311 */
312inline void QStroker::emitMoveTo(qfixed x, qfixed y)
313{
314 m_back2X = m_back1X;
315 m_back2Y = m_back1Y;
316 m_back1X = x;
317 m_back1Y = y;
318 QStrokerOps::emitMoveTo(x, y);
319}
320
321inline void QStroker::emitLineTo(qfixed x, qfixed y)
322{
323 m_back2X = m_back1X;
324 m_back2Y = m_back1Y;
325 m_back1X = x;
326 m_back1Y = y;
327 QStrokerOps::emitLineTo(x, y);
328}
329
330inline void QStroker::emitCubicTo(qfixed c1x, qfixed c1y,
331 qfixed c2x, qfixed c2y,
332 qfixed ex, qfixed ey)
333{
334 if (c2x == ex && c2y == ey) {
335 if (c1x == ex && c1y == ey) {
336 m_back2X = m_back1X;
337 m_back2Y = m_back1Y;
338 } else {
339 m_back2X = c1x;
340 m_back2Y = c1y;
341 }
342 } else {
343 m_back2X = c2x;
344 m_back2Y = c2y;
345 }
346 m_back1X = ex;
347 m_back1Y = ey;
348 QStrokerOps::emitCubicTo(c1x, c1y, c2x, c2y, ex, ey);
349}
350
351/*******************************************************************************
352 * QDashStroker inline members
353 */
354inline void QDashStroker::begin(void *data)
355{
356 if (m_stroker)
357 m_stroker->begin(data);
358 QStrokerOps::begin(data);
359}
360
361inline void QDashStroker::end()
362{
363 QStrokerOps::end();
364 if (m_stroker)
365 m_stroker->end();
366}
367
368QT_END_NAMESPACE
369
370#endif // QSTROKER_P_H
\inmodule QtGui
\inmodule QtGui
Definition qstroker_p.h:96
Combined button and popup list for selecting options.
Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale)
static void qpaintengineex_cubicTo(qreal c1x, qreal c1y, qreal c2x, qreal c2y, qreal ex, qreal ey, void *data)
static const QPainterPath::ElementType qpaintengineex_ellipse_types[]
static const QPainterPath::ElementType qpaintengineex_rect4_types_32[]
QDebug Q_GUI_EXPORT & operator<<(QDebug &s, const QVectorPath &path)
const QVectorPath & qtVectorPathForPath(const QPainterPath &path)
static void qpaintengineex_lineTo(qreal x, qreal y, void *data)
#define QT_MAX_CACHED_GLYPH_SIZE
static const QPainterPath::ElementType qpaintengineex_roundedrect_types[]
static const QPainterPath::ElementType qpaintengineex_line_types_16[]
static void qpaintengineex_moveTo(qreal x, qreal y, void *data)
void(* qStrokerCubicToHook)(qfixed c1x, qfixed c1y, qfixed c2x, qfixed c2y, qfixed ex, qfixed ey, void *data)
Definition qstroker_p.h:87
void(* qStrokerLineToHook)(qfixed x, qfixed y, void *data)
Definition qstroker_p.h:86
QPointF qt_curves_for_arc(const QRectF &rect, qreal startAngle, qreal sweepLength, QPointF *controlPoints, int *point_count)
Definition qstroker.cpp:823
void(* qStrokerMoveToHook)(qfixed x, qfixed y, void *data)
Definition qstroker_p.h:85
qreal qt_t_for_arc_angle(qreal angle)
Definition qstroker.cpp:763
#define qt_fixed_to_real(fixed)
Definition qstroker_p.h:66
#define qt_real_to_fixed(real)
Definition qstroker_p.h:65
QT_BEGIN_NAMESPACE typedef qreal qfixed
Definition qstroker_p.h:64
StrokeHandler(int reserve)
QDataBuffer< QPainterPath::ElementType > types
QDataBuffer< qreal > pts
qfixed x
Definition qstroker_p.h:69
bool operator==(const qfixed2d &other) const
Definition qstroker_p.h:73
bool isFinite()
Definition qstroker_p.h:72
qfixed y
Definition qstroker_p.h:70