Get rid of QCustomRasterPaintDevice / QWS stuff in raster engine.
[profile/ivi/qtbase.git] / src / gui / painting / qpaintengine_raster_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtGui module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file.  Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **
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 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 falgs = 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 strokePolygonCosmetic(const QPoint *pts, int pointCount, PolygonDrawMode mode);
195     void strokePolygonCosmetic(const QPointF *pt, int pointCount, PolygonDrawMode mode);
196
197     void clip(const QVectorPath &path, Qt::ClipOperation op);
198     void clip(const QRect &rect, Qt::ClipOperation op);
199     void clip(const QRegion &region, Qt::ClipOperation op);
200
201     void drawStaticTextItem(QStaticTextItem *textItem);
202
203     enum ClipType {
204         RectClip,
205         ComplexClip
206     };
207     ClipType clipType() const;
208     QRect clipBoundingRect() const;
209
210 #ifdef Q_NO_USING_KEYWORD
211     inline void drawEllipse(const QRect &rect) { QPaintEngineEx::drawEllipse(rect); }
212 #else
213     using QPaintEngineEx::drawPolygon;
214     using QPaintEngineEx::drawEllipse;
215 #endif
216
217     void releaseBuffer();
218
219     QSize size() const;
220
221 #ifndef QT_NO_DEBUG
222     void saveBuffer(const QString &s) const;
223 #endif
224
225 #ifdef Q_WS_MAC
226     void setCGContext(CGContextRef ref);
227     CGContextRef getCGContext() const;
228 #endif
229
230 #ifdef Q_WS_WIN
231     void setDC(HDC hdc);
232     HDC getDC() const;
233     void releaseDC(HDC hdc) const;
234 #endif
235
236     void alphaPenBlt(const void* src, int bpl, int depth, int rx,int ry,int w,int h);
237
238     Type type() const { return Raster; }
239
240     QPoint coordinateOffset() const;
241
242 protected:
243     QRasterPaintEngine(QRasterPaintEnginePrivate &d, QPaintDevice *);
244 private:
245     friend struct QSpanData;
246     friend class QBlitterPaintEngine;
247     friend class QBlitterPaintEnginePrivate;
248     void init();
249
250     void fillRect(const QRectF &rect, QSpanData *data);
251     void drawBitmap(const QPointF &pos, const QImage &image, QSpanData *fill);
252
253     bool drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFixedPoint *positions,
254                           QFontEngine *fontEngine);
255
256 #if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
257     void drawGlyphsS60(const QPointF &p, const QTextItemInt &ti);
258 #endif // Q_OS_SYMBIAN && QT_NO_FREETYPE
259
260     bool setClipRectInDeviceCoords(const QRect &r, Qt::ClipOperation op);
261
262     inline void ensureBrush(const QBrush &brush) {
263         if (!qbrush_fast_equals(state()->lastBrush, brush) || (brush.style() != Qt::NoBrush && state()->fillFlags))
264             updateBrush(brush);
265     }
266     inline void ensureBrush() { ensureBrush(state()->brush); }
267
268     inline void ensurePen(const QPen &pen) {
269         if (!qpen_fast_equals(state()->lastPen, pen) || (pen.style() != Qt::NoPen && state()->strokeFlags))
270             updatePen(pen);
271     }
272     inline void ensurePen() { ensurePen(state()->pen); }
273
274     void updateOutlineMapper();
275     inline void ensureOutlineMapper();
276
277     void updateState();
278     inline void ensureState() {
279         if (state()->dirty)
280             updateState();
281     }
282 };
283
284
285 /*******************************************************************************
286  * QRasterPaintEnginePrivate
287  */
288 class QRasterPaintEnginePrivate : public QPaintEngineExPrivate
289 {
290     Q_DECLARE_PUBLIC(QRasterPaintEngine)
291 public:
292     QRasterPaintEnginePrivate();
293
294     void rasterizeLine_dashed(QLineF line, qreal width,
295                               int *dashIndex, qreal *dashOffset, bool *inDash);
296     void rasterize(QT_FT_Outline *outline, ProcessSpans callback, QSpanData *spanData, QRasterBuffer *rasterBuffer);
297     void rasterize(QT_FT_Outline *outline, ProcessSpans callback, void *userData, QRasterBuffer *rasterBuffer);
298     void updateMatrixData(QSpanData *spanData, const QBrush &brush, const QTransform &brushMatrix);
299
300     void systemStateChanged();
301
302     void drawImage(const QPointF &pt, const QImage &img, SrcOverBlendFunc func,
303                    const QRect &clip, int alpha, const QRect &sr = QRect());
304
305     QTransform brushMatrix() const {
306         Q_Q(const QRasterPaintEngine);
307         const QRasterPaintEngineState *s = q->state();
308         QTransform m(s->matrix);
309         m.translate(s->brushOrigin.x(), s->brushOrigin.y());
310         return m;
311     }
312
313     bool isUnclipped_normalized(const QRect &rect) const;
314     bool isUnclipped(const QRect &rect, int penWidth) const;
315     bool isUnclipped(const QRectF &rect, int penWidth) const;
316     ProcessSpans getPenFunc(const QRect &rect, const QSpanData *data) const;
317     ProcessSpans getPenFunc(const QRectF &rect, const QSpanData *data) const;
318     ProcessSpans getBrushFunc(const QRect &rect, const QSpanData *data) const;
319     ProcessSpans getBrushFunc(const QRectF &rect, const QSpanData *data) const;
320
321     inline const QClipData *clip() const;
322
323     void initializeRasterizer(QSpanData *data);
324
325     void recalculateFastImages();
326     bool canUseFastImageBlending(QPainter::CompositionMode mode, const QImage &image) const;
327
328     QPaintDevice *device;
329     QScopedPointer<QOutlineMapper> outlineMapper;
330     QScopedPointer<QRasterBuffer>  rasterBuffer;
331
332 #if defined (Q_WS_WIN)
333     HDC hdc;
334 #elif defined(Q_WS_MAC)
335     CGContextRef cgContext;
336 #endif
337
338     QRect deviceRect;
339
340     QStroker basicStroker;
341     QScopedPointer<QDashStroker> dashStroker;
342
343     QScopedPointer<QT_FT_Raster> grayRaster;
344
345     QDataBuffer<QLineF> cachedLines;
346     QSpanData image_filler;
347     QSpanData image_filler_xform;
348     QSpanData solid_color_filler;
349
350
351     QFontEngineGlyphCache::Type glyphCacheType;
352
353     QScopedPointer<QClipData> baseClip;
354
355     int deviceDepth;
356
357     uint mono_surface : 1;
358     uint outlinemapper_xform_dirty : 1;
359
360 #ifdef Q_WS_WIN
361     uint isPlain45DegreeRotation : 1;
362 #endif
363
364     QScopedPointer<QRasterizer> rasterizer;
365 };
366
367
368 class QClipData {
369 public:
370     QClipData(int height);
371     ~QClipData();
372
373     int clipSpanHeight;
374     struct ClipLine {
375         int count;
376         QSpan *spans;
377     } *m_clipLines;
378
379     void initialize();
380
381     inline ClipLine *clipLines() {
382         if (!m_clipLines)
383             initialize();
384         return m_clipLines;
385     }
386
387     inline QSpan *spans() {
388         if (!m_spans)
389             initialize();
390         return m_spans;
391     }
392
393     int allocated;
394     int count;
395     QSpan *m_spans;
396     int xmin, xmax, ymin, ymax;
397
398     QRect clipRect;
399     QRegion clipRegion;
400
401     uint enabled : 1;
402     uint hasRectClip : 1;
403     uint hasRegionClip : 1;
404
405     void appendSpan(int x, int length, int y, int coverage);
406     void appendSpans(const QSpan *s, int num);
407
408     // ### Should optimize and actually kill the QSpans if the rect is
409     // ### a subset of The current region. Thus the "fast" clipspan
410     // ### callback can be used
411     void setClipRect(const QRect &rect);
412     void setClipRegion(const QRegion &region);
413     void fixup();
414 };
415
416 inline void QClipData::appendSpan(int x, int length, int y, int coverage)
417 {
418     Q_ASSERT(m_spans); // initialize() has to be called prior to adding spans..
419
420     if (count == allocated) {
421         allocated *= 2;
422         m_spans = (QSpan *)realloc(m_spans, allocated*sizeof(QSpan));
423     }
424     m_spans[count].x = x;
425     m_spans[count].len = length;
426     m_spans[count].y = y;
427     m_spans[count].coverage = coverage;
428     ++count;
429 }
430
431 inline void QClipData::appendSpans(const QSpan *s, int num)
432 {
433     Q_ASSERT(m_spans);
434
435     if (count + num > allocated) {
436         do {
437             allocated *= 2;
438         } while (count + num > allocated);
439         m_spans = (QSpan *)realloc(m_spans, allocated*sizeof(QSpan));
440     }
441     memcpy(m_spans+count, s, num*sizeof(QSpan));
442     count += num;
443 }
444
445 /*******************************************************************************
446  * QRasterBuffer
447  */
448 class QRasterBuffer
449 {
450 public:
451     QRasterBuffer() : m_width(0), m_height(0), m_buffer(0) { init(); }
452
453     ~QRasterBuffer();
454
455     void init();
456
457     QImage::Format prepare(QImage *image);
458     QImage::Format prepare(QPixmap *pix);
459     void prepare(int w, int h);
460     void prepareBuffer(int w, int h);
461
462     void resetBuffer(int val=0);
463
464     uchar *scanLine(int y) { Q_ASSERT(y>=0); Q_ASSERT(y<m_height); return m_buffer + y * bytes_per_line; }
465
466 #ifndef QT_NO_DEBUG
467     QImage bufferImage() const;
468 #endif
469
470     void flushToARGBImage(QImage *image) const;
471
472     int width() const { return m_width; }
473     int height() const { return m_height; }
474     int bytesPerLine() const { return bytes_per_line; }
475     int bytesPerPixel() const { return bytes_per_pixel; }
476
477     uchar *buffer() const { return m_buffer; }
478
479     bool monoDestinationWithClut;
480     QRgb destColor0;
481     QRgb destColor1;
482
483     QPainter::CompositionMode compositionMode;
484     QImage::Format format;
485     DrawHelper *drawHelper;
486     QImage colorizeBitmap(const QImage &image, const QColor &color);
487
488 private:
489     int m_width;
490     int m_height;
491     int bytes_per_line;
492     int bytes_per_pixel;
493     uchar *m_buffer;
494 };
495
496 inline void QRasterPaintEngine::ensureOutlineMapper() {
497     if (d_func()->outlinemapper_xform_dirty)
498         updateOutlineMapper();
499 }
500
501 inline const QClipData *QRasterPaintEnginePrivate::clip() const {
502     Q_Q(const QRasterPaintEngine);
503     if (q->state() && q->state()->clip && q->state()->clip->enabled)
504         return q->state()->clip;
505     return baseClip.data();
506 }
507
508
509 QT_END_NAMESPACE
510 #endif // QPAINTENGINE_RASTER_P_H