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