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 62 QT_BEGIN_NAMESPACE 63 64 65 class QPaintEngineEx; 66 67 typedef void (*qvectorpath_cache_cleanup)(QPaintEngineEx *engine, void *data); 68 69 struct QRealRect { 70 qreal x1, y1, x2, y2; 71 }; 72 73 class Q_GUI_EXPORT QVectorPath 74 { 75 public: 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) m_elements(elements)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 shape()122 inline Hint shape() const { return (Hint) (m_hints & ShapeMask); } isConvex()123 inline bool isConvex() const { return (m_hints & NonConvexShapeMask) == 0; } isCurved()124 inline bool isCurved() const { return m_hints & CurvedShapeMask; } 125 isCacheable()126 inline bool isCacheable() const { return m_hints & ShouldUseCacheHint; } hasImplicitClose()127 inline bool hasImplicitClose() const { return m_hints & ImplicitClose; } hasExplicitOpen()128 inline bool hasExplicitOpen() const { return m_hints & ExplicitOpen; } hasWindingFill()129 inline bool hasWindingFill() const { return m_hints & WindingFill; } 130 makeCacheable()131 inline void makeCacheable() const { m_hints |= ShouldUseCacheHint; m_cache = nullptr; } hints()132 inline uint hints() const { return m_hints; } 133 elements()134 inline const QPainterPath::ElementType *elements() const { return m_elements; } points()135 inline const qreal *points() const { return m_points; } isEmpty()136 inline bool isEmpty() const { return m_points == nullptr; } 137 elementCount()138 inline int elementCount() const { return m_count; } 139 inline const QPainterPath convertToPainterPath() const; 140 polygonFlags(QPaintEngine::PolygonDrawMode mode)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; lookupCacheData(QPaintEngineEx * engine)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 isRect(const T * pts,int elementCount)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 isRect()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 198 private: 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 211 Q_GUI_EXPORT const QVectorPath &qtVectorPathForPath(const QPainterPath &path); 212 213 QT_END_NAMESPACE 214 215 #endif 216