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 QVECTORPATH_P_H
41#define QVECTORPATH_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/private/qtguiglobal_p.h>
55#include <QtGui/qpaintengine.h>
56
57#include <private/qpaintengine_p.h>
58#include <private/qstroker_p.h>
59#include <private/qpainter_p.h>
60
61
62QT_BEGIN_NAMESPACE
63
64
65class QPaintEngineEx;
66
67typedef void (*qvectorpath_cache_cleanup)(QPaintEngineEx *engine, void *data);
68
69struct QRealRect {
70 qreal x1, y1, x2, y2;
71};
72
73class Q_GUI_EXPORT QVectorPath
74{
75public:
76 enum Hint {
77 // Shape hints, in 0x000000ff, access using shape()
78 AreaShapeMask = 0x0001, // shape covers an area
79 NonConvexShapeMask = 0x0002, // shape is not convex
80 CurvedShapeMask = 0x0004, // shape contains curves...
81 LinesShapeMask = 0x0008,
82 RectangleShapeMask = 0x0010,
83 ShapeMask = 0x001f,
84
85 // Shape hints merged into basic shapes..
86 LinesHint = LinesShapeMask,
87 RectangleHint = AreaShapeMask | RectangleShapeMask,
88 EllipseHint = AreaShapeMask | CurvedShapeMask,
89 ConvexPolygonHint = AreaShapeMask,
90 PolygonHint = AreaShapeMask | NonConvexShapeMask,
91 RoundedRectHint = AreaShapeMask | CurvedShapeMask,
92 ArbitraryShapeHint = AreaShapeMask | NonConvexShapeMask | CurvedShapeMask,
93
94 // Other hints
95 IsCachedHint = 0x0100, // Set if the cache hint is set
96 ShouldUseCacheHint = 0x0200, // Set if the path should be cached when possible..
97 ControlPointRect = 0x0400, // Set if the control point rect has been calculated...
98
99 // Shape rendering specifiers...
100 OddEvenFill = 0x1000,
101 WindingFill = 0x2000,
102 ImplicitClose = 0x4000,
103 ExplicitOpen = 0x8000
104 };
105
106 // ### Falcon: introduca a struct XY for points so lars is not so confused...
107 QVectorPath(const qreal *points,
108 int count,
109 const QPainterPath::ElementType *elements = nullptr,
110 uint hints = ArbitraryShapeHint)
111 : m_elements(elements),
112 m_points(points),
113 m_count(count),
114 m_hints(hints)
115 {
116 }
117
118 ~QVectorPath();
119
120 QRectF controlPointRect() const;
121
122 inline Hint shape() const { return (Hint) (m_hints & ShapeMask); }
123 inline bool isConvex() const { return (m_hints & NonConvexShapeMask) == 0; }
124 inline bool isCurved() const { return m_hints & CurvedShapeMask; }
125
126 inline bool isCacheable() const { return m_hints & ShouldUseCacheHint; }
127 inline bool hasImplicitClose() const { return m_hints & ImplicitClose; }
128 inline bool hasExplicitOpen() const { return m_hints & ExplicitOpen; }
129 inline bool hasWindingFill() const { return m_hints & WindingFill; }
130
131 inline void makeCacheable() const { m_hints |= ShouldUseCacheHint; m_cache = nullptr; }
132 inline uint hints() const { return m_hints; }
133
134 inline const QPainterPath::ElementType *elements() const { return m_elements; }
135 inline const qreal *points() const { return m_points; }
136 inline bool isEmpty() const { return m_points == nullptr; }
137
138 inline int elementCount() const { return m_count; }
139 inline const QPainterPath convertToPainterPath() const;
140
141 static inline uint polygonFlags(QPaintEngine::PolygonDrawMode mode)
142 {
143 switch (mode) {
144 case QPaintEngine::ConvexMode: return ConvexPolygonHint | ImplicitClose;
145 case QPaintEngine::OddEvenMode: return PolygonHint | OddEvenFill | ImplicitClose;
146 case QPaintEngine::WindingMode: return PolygonHint | WindingFill | ImplicitClose;
147 case QPaintEngine::PolylineMode: return PolygonHint | ExplicitOpen;
148 default: return 0;
149 }
150 }
151
152 struct CacheEntry {
153 QPaintEngineEx *engine;
154 void *data;
155 qvectorpath_cache_cleanup cleanup;
156 CacheEntry *next;
157 };
158
159 CacheEntry *addCacheData(QPaintEngineEx *engine, void *data, qvectorpath_cache_cleanup cleanup) const;
160 inline CacheEntry *lookupCacheData(QPaintEngineEx *engine) const {
161 Q_ASSERT(m_hints & ShouldUseCacheHint);
162 CacheEntry *e = m_cache;
163 while (e) {
164 if (e->engine == engine)
165 return e;
166 e = e->next;
167 }
168 return nullptr;
169 }
170
171 template <typename T> static inline bool isRect(const T *pts, int elementCount) {
172 return (elementCount == 5 // 5-point polygon, check for closed rect
173 && pts[0] == pts[8] && pts[1] == pts[9] // last point == first point
174 && pts[0] == pts[6] && pts[2] == pts[4] // x values equal
175 && pts[1] == pts[3] && pts[5] == pts[7] // y values equal...
176 && pts[0] < pts[4] && pts[1] < pts[5]
177 ) ||
178 (elementCount == 4 // 4-point polygon, check for unclosed rect
179 && pts[0] == pts[6] && pts[2] == pts[4] // x values equal
180 && pts[1] == pts[3] && pts[5] == pts[7] // y values equal...
181 && pts[0] < pts[4] && pts[1] < pts[5]
182 );
183 }
184
185 inline bool isRect() const
186 {
187 const QPainterPath::ElementType * const types = elements();
188
189 return (shape() == QVectorPath::RectangleHint)
190 || (isRect(points(), elementCount())
191 && (!types || (types[0] == QPainterPath::MoveToElement
192 && types[1] == QPainterPath::LineToElement
193 && types[2] == QPainterPath::LineToElement
194 && types[3] == QPainterPath::LineToElement)));
195 }
196
197
198private:
199 Q_DISABLE_COPY_MOVE(QVectorPath)
200
201 const QPainterPath::ElementType *m_elements;
202 const qreal *m_points;
203 const int m_count;
204
205 mutable uint m_hints;
206 mutable QRealRect m_cp_rect;
207
208 mutable CacheEntry *m_cache;
209};
210
211Q_GUI_EXPORT const QVectorPath &qtVectorPathForPath(const QPainterPath &path);
212
213QT_END_NAMESPACE
214
215#endif
216