Fixed inconsistent QPainter fill rules for aliased painting.
[profile/ivi/qtbase.git] / src / gui / painting / qpaintengine_raster_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
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 Digia.  For licensing terms and
14 ** conditions see http://qt.digia.com/licensing.  For further information
15 ** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights.  These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file.  Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QPAINTENGINE_RASTER_P_H
43 #define QPAINTENGINE_RASTER_P_H
44
45 //
46 //  W A R N I N G
47 //  -------------
48 //
49 // This file is not part of the Qt API.  It exists for the convenience
50 // of other Qt classes.  This header file may change from version to
51 // version without notice, or even be removed.
52 //
53 // We mean it.
54 //
55
56 #include "private/qpaintengineex_p.h"
57 #include "QtGui/qpainterpath.h"
58 #include "private/qdatabuffer_p.h"
59 #include "private/qdrawhelper_p.h"
60 #include "private/qpaintengine_p.h"
61 #include "private/qrasterizer_p.h"
62 #include "private/qstroker_p.h"
63 #include "private/qpainter_p.h"
64 #include "private/qtextureglyphcache_p.h"
65 #include "private/qoutlinemapper_p.h"
66
67 #include <stdlib.h>
68
69 QT_BEGIN_NAMESPACE
70
71 class QOutlineMapper;
72 class QRasterPaintEnginePrivate;
73 class QRasterBuffer;
74 class QClipData;
75
76 class QRasterPaintEngineState : public QPainterState
77 {
78 public:
79     QRasterPaintEngineState(QRasterPaintEngineState &other);
80     QRasterPaintEngineState();
81     ~QRasterPaintEngineState();
82
83
84     QPen lastPen;
85     QSpanData penData;
86     QStrokerOps *stroker;
87     uint strokeFlags;
88
89     QBrush lastBrush;
90     QSpanData brushData;
91     uint fillFlags;
92
93     uint pixmapFlags;
94     int intOpacity;
95
96     qreal txscale;
97
98     QClipData *clip;
99 //     QRect clipRect;
100 //     QRegion clipRegion;
101
102 //     QPainter::RenderHints hints;
103 //     QPainter::CompositionMode compositionMode;
104
105     uint dirty;
106
107     struct Flags {
108         uint has_clip_ownership : 1;        // should delete the clip member..
109         uint fast_pen : 1;                  // cosmetic 1-width pens, using midpoint drawlines
110         uint non_complex_pen : 1;           // can use rasterizer, rather than stroker
111         uint antialiased : 1;
112         uint bilinear : 1;
113         uint legacy_rounding : 1;
114         uint fast_text : 1;
115         uint int_xform : 1;
116         uint tx_noshear : 1;
117         uint fast_images : 1;
118     };
119
120     union {
121         Flags flags;
122         uint flag_bits;
123     };
124 };
125
126
127
128
129 /*******************************************************************************
130  * QRasterPaintEngine
131  */
132 class Q_GUI_EXPORT QRasterPaintEngine : public QPaintEngineEx
133 {
134     Q_DECLARE_PRIVATE(QRasterPaintEngine)
135 public:
136
137     QRasterPaintEngine(QPaintDevice *device);
138     ~QRasterPaintEngine();
139     bool begin(QPaintDevice *device);
140     bool end();
141
142     void penChanged();
143     void brushChanged();
144     void brushOriginChanged();
145     void opacityChanged();
146     void compositionModeChanged();
147     void renderHintsChanged();
148     void transformChanged();
149     void clipEnabledChanged();
150
151     void setState(QPainterState *s);
152     QPainterState *createState(QPainterState *orig) const;
153     inline QRasterPaintEngineState *state() {
154         return static_cast<QRasterPaintEngineState *>(QPaintEngineEx::state());
155     }
156     inline const QRasterPaintEngineState *state() const {
157         return static_cast<const QRasterPaintEngineState *>(QPaintEngineEx::state());
158     }
159
160     void updateBrush(const QBrush &brush);
161     void updatePen(const QPen &pen);
162
163     void updateMatrix(const QTransform &matrix);
164
165     void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
166     void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode);
167     void fillPath(const QPainterPath &path, QSpanData *fillData);
168     void fillPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
169
170     void drawEllipse(const QRectF &rect);
171
172     void fillRect(const QRectF &rect, const QBrush &brush);
173     void fillRect(const QRectF &rect, const QColor &color);
174
175     void drawRects(const QRect  *rects, int rectCount);
176     void drawRects(const QRectF *rects, int rectCount);
177
178     void drawPixmap(const QPointF &p, const QPixmap &pm);
179     void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
180     void drawImage(const QPointF &p, const QImage &img);
181     void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
182                    Qt::ImageConversionFlags flags = Qt::AutoColor);
183     void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr);
184     void drawTextItem(const QPointF &p, const QTextItem &textItem);
185
186     void drawLines(const QLine *line, int lineCount);
187     void drawLines(const QLineF *line, int lineCount);
188
189     void drawPoints(const QPointF *points, int pointCount);
190     void drawPoints(const QPoint *points, int pointCount);
191
192     void stroke(const QVectorPath &path, const QPen &pen);
193     void fill(const QVectorPath &path, const QBrush &brush);
194
195     void clip(const QVectorPath &path, Qt::ClipOperation op);
196     void clip(const QRect &rect, Qt::ClipOperation op);
197     void clip(const QRegion &region, Qt::ClipOperation op);
198     inline const QClipData *clipData() const;
199
200     void drawStaticTextItem(QStaticTextItem *textItem);
201     virtual bool drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFixedPoint *positions,
202                                   QFontEngine *fontEngine);
203
204     enum ClipType {
205         RectClip,
206         ComplexClip
207     };
208     ClipType clipType() const;
209     QRect clipBoundingRect() const;
210
211     void releaseBuffer();
212
213     QSize size() const;
214
215 #ifndef QT_NO_DEBUG
216     void saveBuffer(const QString &s) const;
217 #endif
218
219
220 #ifdef Q_OS_WIN
221     void setDC(HDC hdc);
222     HDC getDC() const;
223     void releaseDC(HDC hdc) const;
224     static bool clearTypeFontsEnabled();
225 #endif
226
227     QRasterBuffer *rasterBuffer();
228     void alphaPenBlt(const void* src, int bpl, int depth, int rx,int ry,int w,int h);
229
230     Type type() const { return Raster; }
231
232     QPoint coordinateOffset() const;
233
234     bool supportsTransformations(QFontEngine *fontEngine) const;
235     bool supportsTransformations(QFontEngine *fontEngine, const QTransform &m) const;
236
237 protected:
238     QRasterPaintEngine(QRasterPaintEnginePrivate &d, QPaintDevice *);
239 private:
240     friend struct QSpanData;
241     friend class QBlitterPaintEngine;
242     friend class QBlitterPaintEnginePrivate;
243     void init();
244
245     void fillRect(const QRectF &rect, QSpanData *data);
246     void drawBitmap(const QPointF &pos, const QImage &image, QSpanData *fill);
247
248     bool setClipRectInDeviceCoords(const QRect &r, Qt::ClipOperation op);
249
250     QRect toNormalizedFillRect(const QRectF &rect);
251
252     inline void ensureBrush(const QBrush &brush) {
253         if (!qbrush_fast_equals(state()->lastBrush, brush) || (brush.style() != Qt::NoBrush && state()->fillFlags))
254             updateBrush(brush);
255     }
256     inline void ensureBrush() { ensureBrush(state()->brush); }
257
258     inline void ensurePen(const QPen &pen) {
259         if (!qpen_fast_equals(state()->lastPen, pen) || (pen.style() != Qt::NoPen && state()->strokeFlags))
260             updatePen(pen);
261     }
262     inline void ensurePen() { ensurePen(state()->pen); }
263
264     void updateOutlineMapper();
265     inline void ensureOutlineMapper();
266
267     void updateRasterState();
268     inline void ensureRasterState() {
269         if (state()->dirty)
270             updateRasterState();
271     }
272 };
273
274
275 /*******************************************************************************
276  * QRasterPaintEnginePrivate
277  */
278 class QRasterPaintEnginePrivate : public QPaintEngineExPrivate
279 {
280     Q_DECLARE_PUBLIC(QRasterPaintEngine)
281 public:
282     QRasterPaintEnginePrivate();
283
284     void rasterizeLine_dashed(QLineF line, qreal width,
285                               int *dashIndex, qreal *dashOffset, bool *inDash);
286     void rasterize(QT_FT_Outline *outline, ProcessSpans callback, QSpanData *spanData, QRasterBuffer *rasterBuffer);
287     void rasterize(QT_FT_Outline *outline, ProcessSpans callback, void *userData, QRasterBuffer *rasterBuffer);
288     void updateMatrixData(QSpanData *spanData, const QBrush &brush, const QTransform &brushMatrix);
289
290     void systemStateChanged();
291
292     void drawImage(const QPointF &pt, const QImage &img, SrcOverBlendFunc func,
293                    const QRect &clip, int alpha, const QRect &sr = QRect());
294
295     QTransform brushMatrix() const {
296         Q_Q(const QRasterPaintEngine);
297         const QRasterPaintEngineState *s = q->state();
298         QTransform m(s->matrix);
299         m.translate(s->brushOrigin.x(), s->brushOrigin.y());
300         return m;
301     }
302
303     bool isUnclipped_normalized(const QRect &rect) const;
304     bool isUnclipped(const QRect &rect, int penWidth) const;
305     bool isUnclipped(const QRectF &rect, int penWidth) const;
306     ProcessSpans getPenFunc(const QRectF &rect, const QSpanData *data) const;
307     ProcessSpans getBrushFunc(const QRect &rect, const QSpanData *data) const;
308     ProcessSpans getBrushFunc(const QRectF &rect, const QSpanData *data) const;
309
310     inline const QClipData *clip() const;
311
312     void initializeRasterizer(QSpanData *data);
313
314     void recalculateFastImages();
315     bool canUseFastImageBlending(QPainter::CompositionMode mode, const QImage &image) const;
316
317     QPaintDevice *device;
318     QScopedPointer<QOutlineMapper> outlineMapper;
319     QScopedPointer<QRasterBuffer>  rasterBuffer;
320
321 #if defined (Q_OS_WIN)
322     HDC hdc;
323 #endif
324
325     QRect deviceRect;
326
327     QStroker basicStroker;
328     QScopedPointer<QDashStroker> dashStroker;
329
330     QScopedPointer<QT_FT_Raster> grayRaster;
331
332     QDataBuffer<QLineF> cachedLines;
333     QSpanData image_filler;
334     QSpanData image_filler_xform;
335     QSpanData solid_color_filler;
336
337
338     QFontEngineGlyphCache::Type glyphCacheType;
339
340     QScopedPointer<QClipData> baseClip;
341
342     int deviceDepth;
343
344     uint mono_surface : 1;
345     uint outlinemapper_xform_dirty : 1;
346
347     QScopedPointer<QRasterizer> rasterizer;
348 };
349
350
351 class QClipData {
352 public:
353     QClipData(int height);
354     ~QClipData();
355
356     int clipSpanHeight;
357     struct ClipLine {
358         int count;
359         QSpan *spans;
360     } *m_clipLines;
361
362     void initialize();
363
364     inline ClipLine *clipLines() {
365         if (!m_clipLines)
366             initialize();
367         return m_clipLines;
368     }
369
370     inline QSpan *spans() {
371         if (!m_spans)
372             initialize();
373         return m_spans;
374     }
375
376     int allocated;
377     int count;
378     QSpan *m_spans;
379     int xmin, xmax, ymin, ymax;
380
381     QRect clipRect;
382     QRegion clipRegion;
383
384     uint enabled : 1;
385     uint hasRectClip : 1;
386     uint hasRegionClip : 1;
387
388     void appendSpan(int x, int length, int y, int coverage);
389     void appendSpans(const QSpan *s, int num);
390
391     // ### Should optimize and actually kill the QSpans if the rect is
392     // ### a subset of The current region. Thus the "fast" clipspan
393     // ### callback can be used
394     void setClipRect(const QRect &rect);
395     void setClipRegion(const QRegion &region);
396     void fixup();
397 };
398
399 inline void QClipData::appendSpan(int x, int length, int y, int coverage)
400 {
401     Q_ASSERT(m_spans); // initialize() has to be called prior to adding spans..
402
403     if (count == allocated) {
404         allocated *= 2;
405         m_spans = (QSpan *)realloc(m_spans, allocated*sizeof(QSpan));
406     }
407     m_spans[count].x = x;
408     m_spans[count].len = length;
409     m_spans[count].y = y;
410     m_spans[count].coverage = coverage;
411     ++count;
412 }
413
414 inline void QClipData::appendSpans(const QSpan *s, int num)
415 {
416     Q_ASSERT(m_spans);
417
418     if (count + num > allocated) {
419         do {
420             allocated *= 2;
421         } while (count + num > allocated);
422         m_spans = (QSpan *)realloc(m_spans, allocated*sizeof(QSpan));
423     }
424     memcpy(m_spans+count, s, num*sizeof(QSpan));
425     count += num;
426 }
427
428 /*******************************************************************************
429  * QRasterBuffer
430  */
431 class QRasterBuffer
432 {
433 public:
434     QRasterBuffer() : m_width(0), m_height(0), m_buffer(0) { init(); }
435
436     ~QRasterBuffer();
437
438     void init();
439
440     QImage::Format prepare(QImage *image);
441     QImage::Format prepare(QPixmap *pix);
442     void prepare(int w, int h);
443     void prepareBuffer(int w, int h);
444
445     void resetBuffer(int val=0);
446
447     uchar *scanLine(int y) { Q_ASSERT(y>=0); Q_ASSERT(y<m_height); return m_buffer + y * bytes_per_line; }
448
449 #ifndef QT_NO_DEBUG
450     QImage bufferImage() const;
451 #endif
452
453     void flushToARGBImage(QImage *image) const;
454
455     int width() const { return m_width; }
456     int height() const { return m_height; }
457     int bytesPerLine() const { return bytes_per_line; }
458     int bytesPerPixel() const { return bytes_per_pixel; }
459
460     uchar *buffer() const { return m_buffer; }
461
462     bool monoDestinationWithClut;
463     QRgb destColor0;
464     QRgb destColor1;
465
466     QPainter::CompositionMode compositionMode;
467     QImage::Format format;
468     DrawHelper *drawHelper;
469     QImage colorizeBitmap(const QImage &image, const QColor &color);
470
471 private:
472     int m_width;
473     int m_height;
474     int bytes_per_line;
475     int bytes_per_pixel;
476     uchar *m_buffer;
477 };
478
479 inline void QRasterPaintEngine::ensureOutlineMapper() {
480     if (d_func()->outlinemapper_xform_dirty)
481         updateOutlineMapper();
482 }
483
484 inline const QClipData *QRasterPaintEnginePrivate::clip() const {
485     Q_Q(const QRasterPaintEngine);
486     if (q->state() && q->state()->clip && q->state()->clip->enabled)
487         return q->state()->clip;
488     return baseClip.data();
489 }
490
491 inline const QClipData *QRasterPaintEngine::clipData() const {
492     Q_D(const QRasterPaintEngine);
493     if (state() && state()->clip && state()->clip->enabled)
494         return state()->clip;
495     return d->baseClip.data();
496 }
497
498 QT_END_NAMESPACE
499 #endif // QPAINTENGINE_RASTER_P_H