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