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 QPAINTER_P_H
41 #define QPAINTER_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 <QtCore/qvarlengtharray.h>
55 #include <QtGui/private/qtguiglobal_p.h>
56 #include "QtGui/qbrush.h"
57 #include "QtGui/qcolorspace.h"
58 #include "QtGui/qcolortransform.h"
59 #include "QtGui/qfont.h"
60 #include "QtGui/qpen.h"
61 #include "QtGui/qregion.h"
62 #include "QtGui/qpainter.h"
63 #include "QtGui/qpainterpath.h"
64 #include "QtGui/qpaintengine.h"
65 
66 #include <private/qpen_p.h>
67 
68 QT_BEGIN_NAMESPACE
69 
70 class QPaintEngine;
71 class QEmulationPaintEngine;
72 class QPaintEngineEx;
73 struct QFixedPoint;
74 
75 struct QTLWExtra;
76 
77 struct DataPtrContainer {
78     void *ptr;
79 };
80 
data_ptr(const QTransform & t)81 inline const void *data_ptr(const QTransform &t) { return (const DataPtrContainer *) &t; }
qtransform_fast_equals(const QTransform & a,const QTransform & b)82 inline bool qtransform_fast_equals(const QTransform &a, const QTransform &b) { return data_ptr(a) == data_ptr(b); }
83 
84 // QPen inline functions...
data_ptr(const QPen & p)85 inline QPen::DataPtr &data_ptr(const QPen &p) { return const_cast<QPen &>(p).data_ptr(); }
qpen_fast_equals(const QPen & a,const QPen & b)86 inline bool qpen_fast_equals(const QPen &a, const QPen &b) { return data_ptr(a) == data_ptr(b); }
qpen_brush(const QPen & p)87 inline QBrush qpen_brush(const QPen &p) { return data_ptr(p)->brush; }
qpen_widthf(const QPen & p)88 inline qreal qpen_widthf(const QPen &p) { return data_ptr(p)->width; }
qpen_style(const QPen & p)89 inline Qt::PenStyle qpen_style(const QPen &p) { return data_ptr(p)->style; }
qpen_capStyle(const QPen & p)90 inline Qt::PenCapStyle qpen_capStyle(const QPen &p) { return data_ptr(p)->capStyle; }
qpen_joinStyle(const QPen & p)91 inline Qt::PenJoinStyle qpen_joinStyle(const QPen &p) { return data_ptr(p)->joinStyle; }
92 
93 // QBrush inline functions...
data_ptr(const QBrush & p)94 inline QBrush::DataPtr &data_ptr(const QBrush &p) { return const_cast<QBrush &>(p).data_ptr(); }
qbrush_fast_equals(const QBrush & a,const QBrush & b)95 inline bool qbrush_fast_equals(const QBrush &a, const QBrush &b) { return data_ptr(a) == data_ptr(b); }
qbrush_style(const QBrush & b)96 inline Qt::BrushStyle qbrush_style(const QBrush &b) { return data_ptr(b)->style; }
qbrush_color(const QBrush & b)97 inline const QColor &qbrush_color(const QBrush &b) { return data_ptr(b)->color; }
qbrush_has_transform(const QBrush & b)98 inline bool qbrush_has_transform(const QBrush &b) { return data_ptr(b)->transform.type() > QTransform::TxNone; }
99 
100 class QPainterClipInfo
101 {
102 public:
QPainterClipInfo()103     QPainterClipInfo() {} // for QVector, don't use
104     enum ClipType { RegionClip, PathClip, RectClip, RectFClip };
105 
QPainterClipInfo(const QPainterPath & p,Qt::ClipOperation op,const QTransform & m)106     QPainterClipInfo(const QPainterPath &p, Qt::ClipOperation op, const QTransform &m) :
107         clipType(PathClip), matrix(m), operation(op), path(p) { }
108 
QPainterClipInfo(const QRegion & r,Qt::ClipOperation op,const QTransform & m)109     QPainterClipInfo(const QRegion &r, Qt::ClipOperation op, const QTransform &m) :
110         clipType(RegionClip), matrix(m), operation(op), region(r) { }
111 
QPainterClipInfo(const QRect & r,Qt::ClipOperation op,const QTransform & m)112     QPainterClipInfo(const QRect &r, Qt::ClipOperation op, const QTransform &m) :
113         clipType(RectClip), matrix(m), operation(op), rect(r) { }
114 
QPainterClipInfo(const QRectF & r,Qt::ClipOperation op,const QTransform & m)115     QPainterClipInfo(const QRectF &r, Qt::ClipOperation op, const QTransform &m) :
116         clipType(RectFClip), matrix(m), operation(op), rectf(r) { }
117 
118     ClipType clipType;
119     QTransform matrix;
120     Qt::ClipOperation operation;
121     QPainterPath path;
122     QRegion region;
123     QRect rect;
124     QRectF rectf;
125 
126     // ###
127 //     union {
128 //         QRegionData *d;
129 //         QPainterPathPrivate *pathData;
130 
131 //         struct {
132 //             int x, y, w, h;
133 //         } rectData;
134 //         struct {
135 //             qreal x, y, w, h;
136 //         } rectFData;
137 //     };
138 
139 };
140 
141 Q_DECLARE_TYPEINFO(QPainterClipInfo, Q_MOVABLE_TYPE);
142 
143 class Q_GUI_EXPORT QPainterState : public QPaintEngineState
144 {
145 public:
146     QPainterState();
147     QPainterState(const QPainterState *s);
148     virtual ~QPainterState();
149     void init(QPainter *p);
150 
151     QPointF brushOrigin;
152     QFont font;
153     QFont deviceFont;
154     QPen pen;
155     QBrush brush;
156     QBrush bgBrush = Qt::white; // background brush
157     QRegion clipRegion;
158     QPainterPath clipPath;
159     Qt::ClipOperation clipOperation = Qt::NoClip;
160     QPainter::RenderHints renderHints;
161     QVector<QPainterClipInfo> clipInfo; // ### Make me smaller and faster to copy around...
162     QTransform worldMatrix;       // World transformation matrix, not window and viewport
163     QTransform matrix;            // Complete transformation matrix,
164     QTransform redirectionMatrix;
165     int wx = 0, wy = 0, ww = 0, wh = 0; // window rectangle
166     int vx = 0, vy = 0, vw = 0, vh = 0; // viewport rectangle
167     qreal opacity = 1;
168 
169     uint WxF:1;                 // World transformation
170     uint VxF:1;                 // View transformation
171     uint clipEnabled:1;
172 
173     Qt::BGMode bgMode = Qt::TransparentMode;
174     QPainter *painter = nullptr;
175     Qt::LayoutDirection layoutDirection;
176     QPainter::CompositionMode composition_mode = QPainter::CompositionMode_SourceOver;
177     uint emulationSpecifier = 0;
178     uint changeFlags = 0;
179 };
180 
181 struct QPainterDummyState
182 {
183     QFont font;
184     QPen pen;
185     QBrush brush;
186     QTransform transform;
187 };
188 
189 class QRawFont;
190 class QPainterPrivate
191 {
Q_DECLARE_PUBLIC(QPainter)192     Q_DECLARE_PUBLIC(QPainter)
193 public:
194     QPainterPrivate(QPainter *painter)
195     : q_ptr(painter), d_ptrs(nullptr), state(nullptr), dummyState(nullptr), txinv(0), inDestructor(false), d_ptrs_size(0),
196         refcount(1), device(nullptr), original_device(nullptr), helper_device(nullptr), engine(nullptr), emulationEngine(nullptr),
197         extended(nullptr)
198     {
199     }
200 
201     ~QPainterPrivate();
202 
203     QPainter *q_ptr;
204     QPainterPrivate **d_ptrs;
205 
206     QPainterState *state;
207     QVarLengthArray<QPainterState *, 8> states;
208 
209     mutable QPainterDummyState *dummyState;
210 
211     QTransform invMatrix;
212     uint txinv:1;
213     uint inDestructor : 1;
214     uint d_ptrs_size;
215     uint refcount;
216 
217     enum DrawOperation { StrokeDraw        = 0x1,
218                          FillDraw          = 0x2,
219                          StrokeAndFillDraw = 0x3
220     };
221 
fakeState()222     QPainterDummyState *fakeState() const {
223         if (!dummyState)
224             dummyState = new QPainterDummyState();
225         return dummyState;
226     }
227 
228     void updateEmulationSpecifier(QPainterState *s);
229     void updateStateImpl(QPainterState *state);
230     void updateState(QPainterState *state);
231 
232     void draw_helper(const QPainterPath &path, DrawOperation operation = StrokeAndFillDraw);
233     void drawStretchedGradient(const QPainterPath &path, DrawOperation operation);
234     void drawOpaqueBackground(const QPainterPath &path, DrawOperation operation);
235     void drawTextItem(const QPointF &p, const QTextItem &_ti, QTextEngine *textEngine);
236 
237 #if !defined(QT_NO_RAWFONT)
238     void drawGlyphs(const quint32 *glyphArray, QFixedPoint *positionArray, int glyphCount,
239                     QFontEngine *fontEngine, bool overline = false, bool underline = false,
240                     bool strikeOut = false);
241 #endif
242 
243     void updateMatrix();
244     void updateInvMatrix();
245 
246     void checkEmulation();
247 
get(QPainter * painter)248     static QPainterPrivate *get(QPainter *painter)
249     {
250         return painter->d_ptr.data();
251     }
252 
253     QTransform viewTransform() const;
254     qreal effectiveDevicePixelRatio() const;
255     QTransform hidpiScaleTransform() const;
256     static bool attachPainterPrivate(QPainter *q, QPaintDevice *pdev);
257     void detachPainterPrivate(QPainter *q);
258     void initFrom(const QPaintDevice *device);
259 
260     QPaintDevice *device;
261     QPaintDevice *original_device;
262     QPaintDevice *helper_device;
263     QPaintEngine *engine;
264     QEmulationPaintEngine *emulationEngine;
265     QPaintEngineEx *extended;
266     QBrush colorBrush;          // for fill with solid color
267 };
268 
269 Q_GUI_EXPORT void qt_draw_helper(QPainterPrivate *p, const QPainterPath &path, QPainterPrivate::DrawOperation operation);
270 
271 QString qt_generate_brush_key(const QBrush &brush);
272 
qt_pen_is_cosmetic(const QPen & pen,QPainter::RenderHints hints)273 inline bool qt_pen_is_cosmetic(const QPen &pen, QPainter::RenderHints hints)
274 {
275     return pen.isCosmetic() || (const_cast<QPen &>(pen).data_ptr()->defaultWidth && (hints & QPainter::Qt4CompatiblePainting));
276 }
277 
278 QT_END_NAMESPACE
279 
280 #endif // QPAINTER_P_H
281