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