~gabriel1984sibiu/minitube/qt5.6

« back to all changes in this revision

Viewing changes to src/gui/painting/qstroker_p.h

  • Committer: Grevutiu Gabriel
  • Date: 2017-06-13 08:43:17 UTC
  • Revision ID: gabriel1984sibiu@gmail.com-20170613084317-ek0zqe0u9g3ocvi8
OriginalĀ upstreamĀ code

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2016 The Qt Company Ltd.
 
4
** Contact: https://www.qt.io/licensing/
 
5
**
 
6
** This file is part of the QtGui module of the Qt Toolkit.
 
7
**
 
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.
 
16
**
 
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.
 
24
**
 
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.
 
35
**
 
36
** $QT_END_LICENSE$
 
37
**
 
38
****************************************************************************/
 
39
 
 
40
#ifndef QSTROKER_P_H
 
41
#define QSTROKER_P_H
 
42
 
 
43
//
 
44
//  W A R N I N G
 
45
//  -------------
 
46
//
 
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.
 
50
//
 
51
// We mean it.
 
52
//
 
53
 
 
54
#include "QtGui/qpainterpath.h"
 
55
#include "private/qdatabuffer_p.h"
 
56
#include "private/qnumeric_p.h"
 
57
 
 
58
QT_BEGIN_NAMESPACE
 
59
 
 
60
// #define QFIXED_IS_26_6
 
61
 
 
62
#if defined QFIXED_IS_26_6
 
63
typedef int qfixed;
 
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)
 
68
struct qfixed2d
 
69
{
 
70
    qfixed x;
 
71
    qfixed y;
 
72
 
 
73
    bool operator==(const qfixed2d &other) const { return x == other.x && y == other.y; }
 
74
};
 
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))
 
79
struct qfixed2d
 
80
{
 
81
    qfixed x;
 
82
    qfixed y;
 
83
 
 
84
    bool operator==(const qfixed2d &other) const { return x == other.x && y == other.y; }
 
85
};
 
86
#elif defined QFIXED_IS_16_16
 
87
typedef int qfixed;
 
88
#define qt_real_to_fixed(real) qfixed(real * qreal(1 << 16))
 
89
#define qt_fixed_to_real(fixed) qreal(fixed / qreal(1 << 16))
 
90
struct qfixed2d
 
91
{
 
92
    qfixed x;
 
93
    qfixed y;
 
94
 
 
95
    bool operator==(const qfixed2d &other) const { return x == other.x && y == other.y; }
 
96
};
 
97
#else
 
98
typedef qreal qfixed;
 
99
#define qt_real_to_fixed(real) qfixed(real)
 
100
#define qt_fixed_to_real(fixed) fixed
 
101
struct qfixed2d
 
102
{
 
103
    qfixed x;
 
104
    qfixed y;
 
105
 
 
106
    bool operator==(const qfixed2d &other) const { return qFuzzyCompare(x, other.x)
 
107
                                                       && qFuzzyCompare(y, other.y); }
 
108
};
 
109
#endif
 
110
 
 
111
#define QT_PATH_KAPPA 0.5522847498
 
112
 
 
113
QPointF qt_curves_for_arc(const QRectF &rect, qreal startAngle, qreal sweepLength,
 
114
                          QPointF *controlPoints, int *point_count);
 
115
 
 
116
qreal qt_t_for_arc_angle(qreal angle);
 
117
 
 
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,
 
123
                                    void *data);
 
124
 
 
125
// qtransform.cpp
 
126
Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
 
127
 
 
128
class Q_GUI_EXPORT QStrokerOps
 
129
{
 
130
public:
 
131
    struct Element {
 
132
        QPainterPath::ElementType type;
 
133
        qfixed x;
 
134
        qfixed y;
 
135
 
 
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; }
 
139
 
 
140
        operator qfixed2d () { qfixed2d pt = { x, y }; return pt; }
 
141
    };
 
142
 
 
143
    QStrokerOps();
 
144
    virtual ~QStrokerOps();
 
145
 
 
146
    void setMoveToHook(qStrokerMoveToHook moveToHook) { m_moveTo = moveToHook; }
 
147
    void setLineToHook(qStrokerLineToHook lineToHook) { m_lineTo = lineToHook; }
 
148
    void setCubicToHook(qStrokerCubicToHook cubicToHook) { m_cubicTo = cubicToHook; }
 
149
 
 
150
    virtual void begin(void *customData);
 
151
    virtual void end();
 
152
 
 
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);
 
156
 
 
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);
 
161
 
 
162
    QRectF clipRect() const { return m_clip_rect; }
 
163
    void setClipRect(const QRectF &clip) { m_clip_rect = clip; }
 
164
 
 
165
    void setCurveThresholdFromTransform(const QTransform &transform)
 
166
    {
 
167
        qreal scale;
 
168
        qt_scaleForTransform(transform, &scale);
 
169
        m_dashThreshold = scale == 0 ? qreal(0.5) : (qreal(0.5) / scale);
 
170
    }
 
171
 
 
172
    void setCurveThreshold(qfixed threshold) { m_curveThreshold = threshold; }
 
173
    qfixed curveThreshold() const { return m_curveThreshold; }
 
174
 
 
175
protected:
 
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);
 
179
 
 
180
    virtual void processCurrentSubpath() = 0;
 
181
    QDataBuffer<Element> m_elements;
 
182
 
 
183
    QRectF m_clip_rect;
 
184
    qfixed m_curveThreshold;
 
185
    qfixed m_dashThreshold;
 
186
 
 
187
    void *m_customData;
 
188
    qStrokerMoveToHook m_moveTo;
 
189
    qStrokerLineToHook m_lineTo;
 
190
    qStrokerCubicToHook m_cubicTo;
 
191
 
 
192
};
 
193
 
 
194
class Q_GUI_EXPORT QStroker : public QStrokerOps
 
195
{
 
196
public:
 
197
 
 
198
    enum LineJoinMode {
 
199
        FlatJoin,
 
200
        SquareJoin,
 
201
        MiterJoin,
 
202
        RoundJoin,
 
203
        RoundCap,
 
204
        SvgMiterJoin
 
205
    };
 
206
 
 
207
    QStroker();
 
208
    ~QStroker();
 
209
 
 
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; }
 
212
 
 
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; }
 
216
 
 
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; }
 
220
 
 
221
    void setMiterLimit(qfixed length) { m_miterLimit = length; }
 
222
    qfixed miterLimit() const { return m_miterLimit; }
 
223
 
 
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);
 
228
 
 
229
protected:
 
230
    static Qt::PenCapStyle capForJoinMode(LineJoinMode mode);
 
231
    static LineJoinMode joinModeForCap(Qt::PenCapStyle);
 
232
 
 
233
    static Qt::PenJoinStyle joinForJoinMode(LineJoinMode mode);
 
234
    static LineJoinMode joinModeForJoin(Qt::PenJoinStyle joinStyle);
 
235
 
 
236
    virtual void processCurrentSubpath();
 
237
 
 
238
    qfixed m_strokeWidth;
 
239
    qfixed m_miterLimit;
 
240
 
 
241
    LineJoinMode m_capStyle;
 
242
    LineJoinMode m_joinStyle;
 
243
 
 
244
    qfixed m_back1X;
 
245
    qfixed m_back1Y;
 
246
 
 
247
    qfixed m_back2X;
 
248
    qfixed m_back2Y;
 
249
};
 
250
 
 
251
class Q_GUI_EXPORT QDashStroker : public QStrokerOps
 
252
{
 
253
public:
 
254
    QDashStroker(QStroker *stroker);
 
255
    ~QDashStroker();
 
256
 
 
257
    QStroker *stroker() const { return m_stroker; }
 
258
 
 
259
    static QVector<qfixed> patternForStyle(Qt::PenStyle style);
 
260
 
 
261
    void setDashPattern(const QVector<qfixed> &dashPattern) { m_dashPattern = dashPattern; }
 
262
    QVector<qfixed> dashPattern() const { return m_dashPattern; }
 
263
 
 
264
    void setDashOffset(qreal offset) { m_dashOffset = offset; }
 
265
    qreal dashOffset() const { return m_dashOffset; }
 
266
 
 
267
    virtual void begin(void *data);
 
268
    virtual void end();
 
269
 
 
270
    inline void setStrokeWidth(qreal width) { m_stroke_width = width; }
 
271
    inline void setMiterLimit(qreal limit) { m_miter_limit = limit; }
 
272
 
 
273
protected:
 
274
    virtual void processCurrentSubpath();
 
275
 
 
276
    QStroker *m_stroker;
 
277
    QVector<qfixed> m_dashPattern;
 
278
    qreal m_dashOffset;
 
279
 
 
280
    qreal m_stroke_width;
 
281
    qreal m_miter_limit;
 
282
};
 
283
 
 
284
 
 
285
/*******************************************************************************
 
286
 * QStrokerOps inline membmers
 
287
 */
 
288
 
 
289
inline void QStrokerOps::emitMoveTo(qfixed x, qfixed y)
 
290
{
 
291
    Q_ASSERT(m_moveTo);
 
292
    m_moveTo(x, y, m_customData);
 
293
}
 
294
 
 
295
inline void QStrokerOps::emitLineTo(qfixed x, qfixed y)
 
296
{
 
297
    Q_ASSERT(m_lineTo);
 
298
    m_lineTo(x, y, m_customData);
 
299
}
 
300
 
 
301
inline void QStrokerOps::emitCubicTo(qfixed c1x, qfixed c1y, qfixed c2x, qfixed c2y, qfixed ex, qfixed ey)
 
302
{
 
303
    Q_ASSERT(m_cubicTo);
 
304
    m_cubicTo(c1x, c1y, c2x, c2y, ex, ey, m_customData);
 
305
}
 
306
 
 
307
inline void QStrokerOps::moveTo(qfixed x, qfixed y)
 
308
{
 
309
    if (m_elements.size()>1)
 
310
        processCurrentSubpath();
 
311
    m_elements.reset();
 
312
    Element e = { QPainterPath::MoveToElement, x, y };
 
313
    m_elements.add(e);
 
314
}
 
315
 
 
316
inline void QStrokerOps::lineTo(qfixed x, qfixed y)
 
317
{
 
318
    Element e = { QPainterPath::LineToElement, x, y };
 
319
    m_elements.add(e);
 
320
}
 
321
 
 
322
inline void QStrokerOps::cubicTo(qfixed x1, qfixed y1, qfixed x2, qfixed y2, qfixed ex, qfixed ey)
 
323
{
 
324
    Element c1 = { QPainterPath::CurveToElement, x1, y1 };
 
325
    Element c2 = { QPainterPath::CurveToDataElement, x2, y2 };
 
326
    Element e = { QPainterPath::CurveToDataElement, ex, ey };
 
327
    m_elements.add(c1);
 
328
    m_elements.add(c2);
 
329
    m_elements.add(e);
 
330
}
 
331
 
 
332
/*******************************************************************************
 
333
 * QStroker inline members
 
334
 */
 
335
inline void QStroker::emitMoveTo(qfixed x, qfixed y)
 
336
{
 
337
    m_back2X = m_back1X;
 
338
    m_back2Y = m_back1Y;
 
339
    m_back1X = x;
 
340
    m_back1Y = y;
 
341
    QStrokerOps::emitMoveTo(x, y);
 
342
}
 
343
 
 
344
inline void QStroker::emitLineTo(qfixed x, qfixed y)
 
345
{
 
346
    m_back2X = m_back1X;
 
347
    m_back2Y = m_back1Y;
 
348
    m_back1X = x;
 
349
    m_back1Y = y;
 
350
    QStrokerOps::emitLineTo(x, y);
 
351
}
 
352
 
 
353
inline void QStroker::emitCubicTo(qfixed c1x, qfixed c1y,
 
354
                                  qfixed c2x, qfixed c2y,
 
355
                                  qfixed ex, qfixed ey)
 
356
{
 
357
    if (c2x == ex && c2y == ey) {
 
358
        if (c1x == ex && c1y == ey) {
 
359
            m_back2X = m_back1X;
 
360
            m_back2Y = m_back1Y;
 
361
        } else {
 
362
            m_back2X = c1x;
 
363
            m_back2Y = c1y;
 
364
        }
 
365
    } else {
 
366
        m_back2X = c2x;
 
367
        m_back2Y = c2y;
 
368
    }
 
369
    m_back1X = ex;
 
370
    m_back1Y = ey;
 
371
    QStrokerOps::emitCubicTo(c1x, c1y, c2x, c2y, ex, ey);
 
372
}
 
373
 
 
374
/*******************************************************************************
 
375
 * QDashStroker inline members
 
376
 */
 
377
inline void QDashStroker::begin(void *data)
 
378
{
 
379
    if (m_stroker)
 
380
        m_stroker->begin(data);
 
381
    QStrokerOps::begin(data);
 
382
}
 
383
 
 
384
inline void QDashStroker::end()
 
385
{
 
386
    QStrokerOps::end();
 
387
    if (m_stroker)
 
388
        m_stroker->end();
 
389
}
 
390
 
 
391
QT_END_NAMESPACE
 
392
 
 
393
#endif // QSTROKER_P_H