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 QPAINTENGINE_RASTER_P_H
41#define QPAINTENGINE_RASTER_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 for the convenience
48// of other Qt classes. 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 "private/qpaintengineex_p.h"
56#include "QtGui/qpainterpath.h"
57#include "private/qdatabuffer_p.h"
58#include "private/qdrawhelper_p.h"
59#include "private/qpaintengine_p.h"
60#include "private/qrasterizer_p.h"
61#include "private/qstroker_p.h"
62#include "private/qpainter_p.h"
63#include "private/qtextureglyphcache_p.h"
64#include "private/qoutlinemapper_p.h"
65
66#include <stdlib.h>
67
68QT_BEGIN_NAMESPACE
69
70class QOutlineMapper;
71class QRasterPaintEnginePrivate;
72class QRasterBuffer;
73class QClipData;
74
75class QRasterPaintEngineState : public QPainterState
76{
77public:
78 QRasterPaintEngineState(QRasterPaintEngineState &other);
79 QRasterPaintEngineState();
80 ~QRasterPaintEngineState();
81
82
83 QPen lastPen;
84 QSpanData penData;
85 QStrokerOps *stroker;
86 uint strokeFlags;
87
88 QBrush lastBrush;
89 QSpanData brushData;
90 uint fillFlags;
91
92 uint pixmapFlags;
93 int intOpacity;
94
95 qreal txscale;
96
97 QClipData *clip;
98// QRect clipRect;
99// QRegion clipRegion;
100
101// QPainter::RenderHints hints;
102// QPainter::CompositionMode compositionMode;
103
104 uint dirty;
105
106 struct Flags {
107 uint has_clip_ownership : 1; // should delete the clip member..
108 uint fast_pen : 1; // cosmetic 1-width pens, using midpoint drawlines
109 uint non_complex_pen : 1; // can use rasterizer, rather than stroker
110 uint antialiased : 1;
111 uint bilinear : 1;
112 uint legacy_rounding : 1;
113 uint fast_text : 1;
114 uint tx_noshear : 1;
115 uint fast_images : 1;
116 };
117
118 union {
119 Flags flags;
120 uint flag_bits;
121 };
122};
123
124
125
126
127/*******************************************************************************
128 * QRasterPaintEngine
129 */
130class Q_GUI_EXPORT QRasterPaintEngine : public QPaintEngineEx
131{
132 Q_DECLARE_PRIVATE(QRasterPaintEngine)
133public:
134
135 QRasterPaintEngine(QPaintDevice *device);
136 ~QRasterPaintEngine();
137 bool begin(QPaintDevice *device) override;
138 bool end() override;
139
140 void penChanged() override;
141 void brushChanged() override;
142 void brushOriginChanged() override;
143 void opacityChanged() override;
144 void compositionModeChanged() override;
145 void renderHintsChanged() override;
146 void transformChanged() override;
147 void clipEnabledChanged() override;
148
149 void setState(QPainterState *s) override;
150 QPainterState *createState(QPainterState *orig) const override;
151 inline QRasterPaintEngineState *state() {
152 return static_cast<QRasterPaintEngineState *>(QPaintEngineEx::state());
153 }
154 inline const QRasterPaintEngineState *state() const {
155 return static_cast<const QRasterPaintEngineState *>(QPaintEngineEx::state());
156 }
157
158 void updateBrush(const QBrush &brush);
159 void updatePen(const QPen &pen);
160
161 void updateMatrix(const QTransform &matrix);
162
163 virtual void fillPath(const QPainterPath &path, QSpanData *fillData);
164 virtual void fillPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
165
166 void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) override;
167 void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) override;
168
169 void drawEllipse(const QRectF &rect) override;
170
171 void fillRect(const QRectF &rect, const QBrush &brush) override;
172 void fillRect(const QRectF &rect, const QColor &color) override;
173
174 void drawRects(const QRect *rects, int rectCount) override;
175 void drawRects(const QRectF *rects, int rectCount) override;
176
177 void drawPixmap(const QPointF &p, const QPixmap &pm) override;
178 void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) override;
179 void drawImage(const QPointF &p, const QImage &img) override;
180 void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
181 Qt::ImageConversionFlags flags = Qt::AutoColor) override;
182 void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr) override;
183 void drawTextItem(const QPointF &p, const QTextItem &textItem) override;
184
185 void drawLines(const QLine *line, int lineCount) override;
186 void drawLines(const QLineF *line, int lineCount) override;
187
188 void drawPoints(const QPointF *points, int pointCount) override;
189 void drawPoints(const QPoint *points, int pointCount) override;
190
191 void stroke(const QVectorPath &path, const QPen &pen) override;
192 void fill(const QVectorPath &path, const QBrush &brush) override;
193
194 void clip(const QVectorPath &path, Qt::ClipOperation op) override;
195 void clip(const QRect &rect, Qt::ClipOperation op) override;
196 void clip(const QRegion &region, Qt::ClipOperation op) override;
197 inline const QClipData *clipData() const;
198
199 void drawStaticTextItem(QStaticTextItem *textItem) override;
200 virtual bool drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFixedPoint *positions,
201 QFontEngine *fontEngine);
202
203 enum ClipType {
204 RectClip,
205 ComplexClip
206 };
207 ClipType clipType() const;
208 QRectF clipBoundingRect() const;
209
210#ifdef Q_OS_WIN
211 void setDC(HDC hdc);
212 HDC getDC() const;
213 void releaseDC(HDC hdc) const;
214 static bool clearTypeFontsEnabled();
215#endif
216
217 QRasterBuffer *rasterBuffer();
218 void alphaPenBlt(const void* src, int bpl, int depth, int rx,int ry,int w,int h, bool useGammaCorrection);
219
220 Type type() const override { return Raster; }
221
222 QPoint coordinateOffset() const override;
223
224 bool requiresPretransformedGlyphPositions(QFontEngine *fontEngine, const QTransform &m) const override;
225 bool shouldDrawCachedGlyphs(QFontEngine *fontEngine, const QTransform &m) const override;
226
227protected:
228 QRasterPaintEngine(QRasterPaintEnginePrivate &d, QPaintDevice *);
229private:
230 friend struct QSpanData;
231 friend class QBlitterPaintEngine;
232 friend class QBlitterPaintEnginePrivate;
233 void init();
234
235 void fillRect(const QRectF &rect, QSpanData *data);
236 void drawBitmap(const QPointF &pos, const QImage &image, QSpanData *fill);
237
238 bool setClipRectInDeviceCoords(const QRect &r, Qt::ClipOperation op);
239
240 QRect toNormalizedFillRect(const QRectF &rect);
241
242 inline void ensureBrush(const QBrush &brush) {
243 if (!qbrush_fast_equals(a: state()->lastBrush, b: brush) || state()->fillFlags)
244 updateBrush(brush);
245 }
246 inline void ensureBrush() { ensureBrush(brush: state()->brush); }
247
248 inline void ensurePen(const QPen &pen) {
249 if (!qpen_fast_equals(a: state()->lastPen, b: pen) || (pen.style() != Qt::NoPen && state()->strokeFlags))
250 updatePen(pen);
251 }
252 inline void ensurePen() { ensurePen(pen: state()->pen); }
253
254 void updateOutlineMapper();
255 inline void ensureOutlineMapper();
256
257 void updateRasterState();
258 inline void ensureRasterState() {
259 if (state()->dirty)
260 updateRasterState();
261 }
262};
263
264
265/*******************************************************************************
266 * QRasterPaintEnginePrivate
267 */
268class QRasterPaintEnginePrivate : public QPaintEngineExPrivate
269{
270 Q_DECLARE_PUBLIC(QRasterPaintEngine)
271public:
272 QRasterPaintEnginePrivate();
273
274 void rasterizeLine_dashed(QLineF line, qreal width,
275 int *dashIndex, qreal *dashOffset, bool *inDash);
276 void rasterize(QT_FT_Outline *outline, ProcessSpans callback, QSpanData *spanData, QRasterBuffer *rasterBuffer);
277 void rasterize(QT_FT_Outline *outline, ProcessSpans callback, void *userData, QRasterBuffer *rasterBuffer);
278 void updateMatrixData(QSpanData *spanData, const QBrush &brush, const QTransform &brushMatrix);
279
280 void systemStateChanged() override;
281
282 void drawImage(const QPointF &pt, const QImage &img, SrcOverBlendFunc func,
283 const QRect &clip, int alpha, const QRect &sr = QRect());
284 void blitImage(const QPointF &pt, const QImage &img,
285 const QRect &clip, const QRect &sr = QRect());
286
287 QTransform brushMatrix() const {
288 Q_Q(const QRasterPaintEngine);
289 const QRasterPaintEngineState *s = q->state();
290 QTransform m(s->matrix);
291 m.translate(dx: s->brushOrigin.x(), dy: s->brushOrigin.y());
292 return m;
293 }
294
295 bool isUnclipped_normalized(const QRect &rect) const;
296 bool isUnclipped(const QRect &rect, int penWidth) const;
297 bool isUnclipped(const QRectF &rect, int penWidth) const;
298 ProcessSpans getPenFunc(const QRectF &rect, const QSpanData *data) const;
299 ProcessSpans getBrushFunc(const QRect &rect, const QSpanData *data) const;
300 ProcessSpans getBrushFunc(const QRectF &rect, const QSpanData *data) const;
301
302 inline const QClipData *clip() const;
303
304 void initializeRasterizer(QSpanData *data);
305
306 void recalculateFastImages();
307 bool canUseFastImageBlending(QPainter::CompositionMode mode, const QImage &image) const;
308 bool canUseImageBlitting(QPainter::CompositionMode mode, const QImage &image, const QPointF &pt, const QRectF &sr) const;
309
310 QPaintDevice *device;
311 QScopedPointer<QOutlineMapper> outlineMapper;
312 QScopedPointer<QRasterBuffer> rasterBuffer;
313
314#if defined (Q_OS_WIN)
315 HDC hdc;
316#endif
317
318 QRect deviceRect;
319 QRect deviceRectUnclipped;
320
321 QStroker basicStroker;
322 QScopedPointer<QDashStroker> dashStroker;
323
324 QScopedPointer<QT_FT_Raster> grayRaster;
325
326 QDataBuffer<QLineF> cachedLines;
327 QSpanData image_filler;
328 QSpanData image_filler_xform;
329 QSpanData solid_color_filler;
330
331
332 QFontEngine::GlyphFormat glyphCacheFormat;
333
334 QScopedPointer<QClipData> baseClip;
335
336 int deviceDepth;
337
338 uint mono_surface : 1;
339 uint outlinemapper_xform_dirty : 1;
340
341 QScopedPointer<QRasterizer> rasterizer;
342};
343
344
345class QClipData {
346public:
347 QClipData(int height);
348 ~QClipData();
349
350 int clipSpanHeight;
351 struct ClipLine {
352 int count;
353 QSpan *spans;
354 } *m_clipLines;
355
356 void initialize();
357
358 inline ClipLine *clipLines() {
359 if (!m_clipLines)
360 initialize();
361 return m_clipLines;
362 }
363
364 inline QSpan *spans() {
365 if (!m_spans)
366 initialize();
367 return m_spans;
368 }
369
370 int allocated;
371 int count;
372 QSpan *m_spans;
373 int xmin, xmax, ymin, ymax;
374
375 QRect clipRect;
376 QRegion clipRegion;
377
378 uint enabled : 1;
379 uint hasRectClip : 1;
380 uint hasRegionClip : 1;
381
382 void appendSpan(int x, int length, int y, int coverage);
383 void appendSpans(const QSpan *s, int num);
384
385 // ### Should optimize and actually kill the QSpans if the rect is
386 // ### a subset of The current region. Thus the "fast" clipspan
387 // ### callback can be used
388 void setClipRect(const QRect &rect);
389 void setClipRegion(const QRegion &region);
390 void fixup();
391};
392
393inline void QClipData::appendSpan(int x, int length, int y, int coverage)
394{
395 Q_ASSERT(m_spans); // initialize() has to be called prior to adding spans..
396
397 if (count == allocated) {
398 allocated *= 2;
399 m_spans = (QSpan *)realloc(ptr: m_spans, size: allocated*sizeof(QSpan));
400 }
401 m_spans[count].x = x;
402 m_spans[count].len = length;
403 m_spans[count].y = y;
404 m_spans[count].coverage = coverage;
405 ++count;
406}
407
408inline void QClipData::appendSpans(const QSpan *s, int num)
409{
410 Q_ASSERT(m_spans);
411
412 if (count + num > allocated) {
413 do {
414 allocated *= 2;
415 } while (count + num > allocated);
416 m_spans = (QSpan *)realloc(ptr: m_spans, size: allocated*sizeof(QSpan));
417 }
418 memcpy(dest: m_spans+count, src: s, n: num*sizeof(QSpan));
419 count += num;
420}
421
422/*******************************************************************************
423 * QRasterBuffer
424 */
425class QRasterBuffer
426{
427public:
428 QRasterBuffer() : m_width(0), m_height(0), m_buffer(nullptr) { init(); }
429
430 ~QRasterBuffer();
431
432 void init();
433
434 QImage::Format prepare(QImage *image);
435
436 uchar *scanLine(int y) { Q_ASSERT(y>=0); Q_ASSERT(y<m_height); return m_buffer + y * qsizetype(bytes_per_line); }
437
438 int width() const { return m_width; }
439 int height() const { return m_height; }
440 int bytesPerLine() const { return bytes_per_line; }
441 int bytesPerPixel() const { return bytes_per_pixel; }
442 template<typename T>
443 int stride() { return bytes_per_line / sizeof(T); }
444
445 uchar *buffer() const { return m_buffer; }
446
447 bool monoDestinationWithClut;
448 QRgb destColor0;
449 QRgb destColor1;
450
451 QPainter::CompositionMode compositionMode;
452 QImage::Format format;
453 QImage colorizeBitmap(const QImage &image, const QColor &color);
454
455private:
456 int m_width;
457 int m_height;
458 int bytes_per_line;
459 int bytes_per_pixel;
460 uchar *m_buffer;
461};
462
463inline void QRasterPaintEngine::ensureOutlineMapper() {
464 if (d_func()->outlinemapper_xform_dirty)
465 updateOutlineMapper();
466}
467
468inline const QClipData *QRasterPaintEnginePrivate::clip() const {
469 Q_Q(const QRasterPaintEngine);
470 if (q->state() && q->state()->clip && q->state()->clip->enabled)
471 return q->state()->clip;
472 return baseClip.data();
473}
474
475inline const QClipData *QRasterPaintEngine::clipData() const {
476 Q_D(const QRasterPaintEngine);
477 if (state() && state()->clip && state()->clip->enabled)
478 return state()->clip;
479 return d->baseClip.data();
480}
481
482QT_END_NAMESPACE
483#endif // QPAINTENGINE_RASTER_P_H
484

source code of qtbase/src/gui/painting/qpaintengine_raster_p.h