Make QRegion not need to be friends with QVector
[profile/ivi/qtbase.git] / src / gui / painting / qpaintengine_raster_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
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 fast_text : 1;
114         uint int_xform : 1;
115         uint tx_noshear : 1;
116         uint fast_images : 1;
117     };
118
119     union {
120         Flags flags;
121         uint flag_bits;
122     };
123 };
124
125
126
127
128 /*******************************************************************************
129  * QRasterPaintEngine
130  */
131 class Q_GUI_EXPORT QRasterPaintEngine : public QPaintEngineEx
132 {
133     Q_DECLARE_PRIVATE(QRasterPaintEngine)
134 public:
135
136     QRasterPaintEngine(QPaintDevice *device);
137     ~QRasterPaintEngine();
138     bool begin(QPaintDevice *device);
139     bool end();
140
141     void penChanged();
142     void brushChanged();
143     void brushOriginChanged();
144     void opacityChanged();
145     void compositionModeChanged();
146     void renderHintsChanged();
147     void transformChanged();
148     void clipEnabledChanged();
149
150     void setState(QPainterState *s);
151     QPainterState *createState(QPainterState *orig) const;
152     inline QRasterPaintEngineState *state() {
153         return static_cast<QRasterPaintEngineState *>(QPaintEngineEx::state());
154     }
155     inline const QRasterPaintEngineState *state() const {
156         return static_cast<const QRasterPaintEngineState *>(QPaintEngineEx::state());
157     }
158
159     void updateBrush(const QBrush &brush);
160     void updatePen(const QPen &pen);
161
162     void updateMatrix(const QTransform &matrix);
163
164     void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
165     void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode);
166     void fillPath(const QPainterPath &path, QSpanData *fillData);
167     void fillPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
168
169     void drawEllipse(const QRectF &rect);
170
171     void fillRect(const QRectF &rect, const QBrush &brush);
172     void fillRect(const QRectF &rect, const QColor &color);
173
174     void drawRects(const QRect  *rects, int rectCount);
175     void drawRects(const QRectF *rects, int rectCount);
176
177     void drawPixmap(const QPointF &p, const QPixmap &pm);
178     void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
179     void drawImage(const QPointF &p, const QImage &img);
180     void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
181                    Qt::ImageConversionFlags flags = Qt::AutoColor);
182     void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr);
183     void drawTextItem(const QPointF &p, const QTextItem &textItem);
184
185     void drawLines(const QLine *line, int lineCount);
186     void drawLines(const QLineF *line, int lineCount);
187
188     void drawPoints(const QPointF *points, int pointCount);
189     void drawPoints(const QPoint *points, int pointCount);
190
191     void stroke(const QVectorPath &path, const QPen &pen);
192     void fill(const QVectorPath &path, const QBrush &brush);
193
194     void clip(const QVectorPath &path, Qt::ClipOperation op);
195     void clip(const QRect &rect, Qt::ClipOperation op);
196     void clip(const QRegion &region, Qt::ClipOperation op);
197     inline const QClipData *clipData() const;
198
199     void drawStaticTextItem(QStaticTextItem *textItem);
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     QRect clipBoundingRect() const;
209
210     void releaseBuffer();
211
212     QSize size() const;
213
214 #ifndef QT_NO_DEBUG
215     void saveBuffer(const QString &s) const;
216 #endif
217
218
219 #ifdef Q_OS_WIN
220     void setDC(HDC hdc);
221     HDC getDC() const;
222     void releaseDC(HDC hdc) const;
223     static bool clearTypeFontsEnabled();
224 #endif
225
226     QRasterBuffer *rasterBuffer();
227     void alphaPenBlt(const void* src, int bpl, int depth, int rx,int ry,int w,int h);
228
229     Type type() const { return Raster; }
230
231     QPoint coordinateOffset() const;
232
233     bool supportsTransformations(QFontEngine *fontEngine) const;
234     bool supportsTransformations(QFontEngine *fontEngine, const QTransform &m) const;
235
236 protected:
237     QRasterPaintEngine(QRasterPaintEnginePrivate &d, QPaintDevice *);
238 private:
239     friend struct QSpanData;
240     friend class QBlitterPaintEngine;
241     friend class QBlitterPaintEnginePrivate;
242     void init();
243
244     void fillRect(const QRectF &rect, QSpanData *data);
245     void drawBitmap(const QPointF &pos, const QImage &image, QSpanData *fill);
246
247     bool setClipRectInDeviceCoords(const QRect &r, Qt::ClipOperation op);
248
249     inline void ensureBrush(const QBrush &brush) {
250         if (!qbrush_fast_equals(state()->lastBrush, brush) || (brush.style() != Qt::NoBrush && state()->fillFlags))
251             updateBrush(brush);
252     }
253     inline void ensureBrush() { ensureBrush(state()->brush); }
254
255     inline void ensurePen(const QPen &pen) {
256         if (!qpen_fast_equals(state()->lastPen, pen) || (pen.style() != Qt::NoPen && state()->strokeFlags))
257             updatePen(pen);
258     }
259     inline void ensurePen() { ensurePen(state()->pen); }
260
261     void updateOutlineMapper();
262     inline void ensureOutlineMapper();
263
264     void updateRasterState();
265     inline void ensureRasterState() {
266         if (state()->dirty)
267             updateRasterState();
268     }
269 };
270
271
272 /*******************************************************************************
273  * QRasterPaintEnginePrivate
274  */
275 class QRasterPaintEnginePrivate : public QPaintEngineExPrivate
276 {
277     Q_DECLARE_PUBLIC(QRasterPaintEngine)
278 public:
279     QRasterPaintEnginePrivate();
280
281     void rasterizeLine_dashed(QLineF line, qreal width,
282                               int *dashIndex, qreal *dashOffset, bool *inDash);
283     void rasterize(QT_FT_Outline *outline, ProcessSpans callback, QSpanData *spanData, QRasterBuffer *rasterBuffer);
284     void rasterize(QT_FT_Outline *outline, ProcessSpans callback, void *userData, QRasterBuffer *rasterBuffer);
285     void updateMatrixData(QSpanData *spanData, const QBrush &brush, const QTransform &brushMatrix);
286
287     void systemStateChanged();
288
289     void drawImage(const QPointF &pt, const QImage &img, SrcOverBlendFunc func,
290                    const QRect &clip, int alpha, const QRect &sr = QRect());
291
292     QTransform brushMatrix() const {
293         Q_Q(const QRasterPaintEngine);
294         const QRasterPaintEngineState *s = q->state();
295         QTransform m(s->matrix);
296         m.translate(s->brushOrigin.x(), s->brushOrigin.y());
297         return m;
298     }
299
300     bool isUnclipped_normalized(const QRect &rect) const;
301     bool isUnclipped(const QRect &rect, int penWidth) const;
302     bool isUnclipped(const QRectF &rect, int penWidth) const;
303     ProcessSpans getPenFunc(const QRectF &rect, const QSpanData *data) const;
304     ProcessSpans getBrushFunc(const QRect &rect, const QSpanData *data) const;
305     ProcessSpans getBrushFunc(const QRectF &rect, const QSpanData *data) const;
306
307     inline const QClipData *clip() const;
308
309     void initializeRasterizer(QSpanData *data);
310
311     void recalculateFastImages();
312     bool canUseFastImageBlending(QPainter::CompositionMode mode, const QImage &image) const;
313
314     QPaintDevice *device;
315     QScopedPointer<QOutlineMapper> outlineMapper;
316     QScopedPointer<QRasterBuffer>  rasterBuffer;
317
318 #if defined (Q_OS_WIN)
319     HDC hdc;
320 #endif
321
322     QRect deviceRect;
323
324     QStroker basicStroker;
325     QScopedPointer<QDashStroker> dashStroker;
326
327     QScopedPointer<QT_FT_Raster> grayRaster;
328
329     QDataBuffer<QLineF> cachedLines;
330     QSpanData image_filler;
331     QSpanData image_filler_xform;
332     QSpanData solid_color_filler;
333
334
335     QFontEngineGlyphCache::Type glyphCacheType;
336
337     QScopedPointer<QClipData> baseClip;
338
339     int deviceDepth;
340
341     uint mono_surface : 1;
342     uint outlinemapper_xform_dirty : 1;
343
344     QScopedPointer<QRasterizer> rasterizer;
345 };
346
347
348 class QClipData {
349 public:
350     QClipData(int height);
351     ~QClipData();
352
353     int clipSpanHeight;
354     struct ClipLine {
355         int count;
356         QSpan *spans;
357     } *m_clipLines;
358
359     void initialize();
360
361     inline ClipLine *clipLines() {
362         if (!m_clipLines)
363             initialize();
364         return m_clipLines;
365     }
366
367     inline QSpan *spans() {
368         if (!m_spans)
369             initialize();
370         return m_spans;
371     }
372
373     int allocated;
374     int count;
375     QSpan *m_spans;
376     int xmin, xmax, ymin, ymax;
377
378     QRect clipRect;
379     QRegion clipRegion;
380
381     uint enabled : 1;
382     uint hasRectClip : 1;
383     uint hasRegionClip : 1;
384
385     void appendSpan(int x, int length, int y, int coverage);
386     void appendSpans(const QSpan *s, int num);
387
388     // ### Should optimize and actually kill the QSpans if the rect is
389     // ### a subset of The current region. Thus the "fast" clipspan
390     // ### callback can be used
391     void setClipRect(const QRect &rect);
392     void setClipRegion(const QRegion &region);
393     void fixup();
394 };
395
396 inline void QClipData::appendSpan(int x, int length, int y, int coverage)
397 {
398     Q_ASSERT(m_spans); // initialize() has to be called prior to adding spans..
399
400     if (count == allocated) {
401         allocated *= 2;
402         m_spans = (QSpan *)realloc(m_spans, allocated*sizeof(QSpan));
403     }
404     m_spans[count].x = x;
405     m_spans[count].len = length;
406     m_spans[count].y = y;
407     m_spans[count].coverage = coverage;
408     ++count;
409 }
410
411 inline void QClipData::appendSpans(const QSpan *s, int num)
412 {
413     Q_ASSERT(m_spans);
414
415     if (count + num > allocated) {
416         do {
417             allocated *= 2;
418         } while (count + num > allocated);
419         m_spans = (QSpan *)realloc(m_spans, allocated*sizeof(QSpan));
420     }
421     memcpy(m_spans+count, s, num*sizeof(QSpan));
422     count += num;
423 }
424
425 /*******************************************************************************
426  * QRasterBuffer
427  */
428 class QRasterBuffer
429 {
430 public:
431     QRasterBuffer() : m_width(0), m_height(0), m_buffer(0) { init(); }
432
433     ~QRasterBuffer();
434
435     void init();
436
437     QImage::Format prepare(QImage *image);
438     QImage::Format prepare(QPixmap *pix);
439     void prepare(int w, int h);
440     void prepareBuffer(int w, int h);
441
442     void resetBuffer(int val=0);
443
444     uchar *scanLine(int y) { Q_ASSERT(y>=0); Q_ASSERT(y<m_height); return m_buffer + y * bytes_per_line; }
445
446 #ifndef QT_NO_DEBUG
447     QImage bufferImage() const;
448 #endif
449
450     void flushToARGBImage(QImage *image) const;
451
452     int width() const { return m_width; }
453     int height() const { return m_height; }
454     int bytesPerLine() const { return bytes_per_line; }
455     int bytesPerPixel() const { return bytes_per_pixel; }
456
457     uchar *buffer() const { return m_buffer; }
458
459     bool monoDestinationWithClut;
460     QRgb destColor0;
461     QRgb destColor1;
462
463     QPainter::CompositionMode compositionMode;
464     QImage::Format format;
465     DrawHelper *drawHelper;
466     QImage colorizeBitmap(const QImage &image, const QColor &color);
467
468 private:
469     int m_width;
470     int m_height;
471     int bytes_per_line;
472     int bytes_per_pixel;
473     uchar *m_buffer;
474 };
475
476 inline void QRasterPaintEngine::ensureOutlineMapper() {
477     if (d_func()->outlinemapper_xform_dirty)
478         updateOutlineMapper();
479 }
480
481 inline const QClipData *QRasterPaintEnginePrivate::clip() const {
482     Q_Q(const QRasterPaintEngine);
483     if (q->state() && q->state()->clip && q->state()->clip->enabled)
484         return q->state()->clip;
485     return baseClip.data();
486 }
487
488 inline const QClipData *QRasterPaintEngine::clipData() const {
489     Q_D(const QRasterPaintEngine);
490     if (state() && state()->clip && state()->clip->enabled)
491         return state()->clip;
492     return d->baseClip.data();
493 }
494
495 QT_END_NAMESPACE
496 #endif // QPAINTENGINE_RASTER_P_H