52f51fab16a522239061a3d19d0cd33742a36f43
[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 class QCustomRasterPaintDevice;
76
77 class QRasterPaintEngineState : public QPainterState
78 {
79 public:
80     QRasterPaintEngineState(QRasterPaintEngineState &other);
81     QRasterPaintEngineState();
82     ~QRasterPaintEngineState();
83
84
85     QPen lastPen;
86     QSpanData penData;
87     QStrokerOps *stroker;
88     uint strokeFlags;
89
90     QBrush lastBrush;
91     QSpanData brushData;
92     uint fillFlags;
93
94     uint pixmapFlags;
95     int intOpacity;
96
97     qreal txscale;
98
99     QClipData *clip;
100 //     QRect clipRect;
101 //     QRegion clipRegion;
102
103 //     QPainter::RenderHints hints;
104 //     QPainter::CompositionMode compositionMode;
105
106     uint dirty;
107
108     struct Flags {
109         uint has_clip_ownership : 1;        // should delete the clip member..
110         uint fast_pen : 1;                  // cosmetic 1-width pens, using midpoint drawlines
111         uint non_complex_pen : 1;           // can use rasterizer, rather than stroker
112         uint antialiased : 1;
113         uint bilinear : 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
133 #ifdef Q_WS_QWS
134 Q_GUI_EXPORT
135 #endif
136 QRasterPaintEngine : public QPaintEngineEx
137 {
138     Q_DECLARE_PRIVATE(QRasterPaintEngine)
139 public:
140
141     QRasterPaintEngine(QPaintDevice *device);
142     ~QRasterPaintEngine();
143     bool begin(QPaintDevice *device);
144     bool end();
145
146     void penChanged();
147     void brushChanged();
148     void brushOriginChanged();
149     void opacityChanged();
150     void compositionModeChanged();
151     void renderHintsChanged();
152     void transformChanged();
153     void clipEnabledChanged();
154
155     void setState(QPainterState *s);
156     QPainterState *createState(QPainterState *orig) const;
157     inline QRasterPaintEngineState *state() {
158         return static_cast<QRasterPaintEngineState *>(QPaintEngineEx::state());
159     }
160     inline const QRasterPaintEngineState *state() const {
161         return static_cast<const QRasterPaintEngineState *>(QPaintEngineEx::state());
162     }
163
164     void updateBrush(const QBrush &brush);
165     void updatePen(const QPen &pen);
166
167     void updateMatrix(const QTransform &matrix);
168
169     void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
170     void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode);
171     void fillPath(const QPainterPath &path, QSpanData *fillData);
172     void fillPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
173
174     void drawEllipse(const QRectF &rect);
175
176     void fillRect(const QRectF &rect, const QBrush &brush);
177     void fillRect(const QRectF &rect, const QColor &color);
178
179     void drawRects(const QRect  *rects, int rectCount);
180     void drawRects(const QRectF *rects, int rectCount);
181
182     void drawPixmap(const QPointF &p, const QPixmap &pm);
183     void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
184     void drawImage(const QPointF &p, const QImage &img);
185     void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
186                    Qt::ImageConversionFlags falgs = Qt::AutoColor);
187     void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr);
188     void drawTextItem(const QPointF &p, const QTextItem &textItem);
189
190     void drawLines(const QLine *line, int lineCount);
191     void drawLines(const QLineF *line, int lineCount);
192
193     void drawPoints(const QPointF *points, int pointCount);
194     void drawPoints(const QPoint *points, int pointCount);
195
196     void stroke(const QVectorPath &path, const QPen &pen);
197     void fill(const QVectorPath &path, const QBrush &brush);
198
199     void strokePolygonCosmetic(const QPoint *pts, int pointCount, PolygonDrawMode mode);
200     void strokePolygonCosmetic(const QPointF *pt, int pointCount, PolygonDrawMode mode);
201
202     void clip(const QVectorPath &path, Qt::ClipOperation op);
203     void clip(const QRect &rect, Qt::ClipOperation op);
204     void clip(const QRegion &region, Qt::ClipOperation op);
205
206     void drawStaticTextItem(QStaticTextItem *textItem);
207
208     enum ClipType {
209         RectClip,
210         ComplexClip
211     };
212     ClipType clipType() const;
213     QRect clipBoundingRect() const;
214
215 #ifdef Q_NO_USING_KEYWORD
216     inline void drawEllipse(const QRect &rect) { QPaintEngineEx::drawEllipse(rect); }
217 #else
218     using QPaintEngineEx::drawPolygon;
219     using QPaintEngineEx::drawEllipse;
220 #endif
221
222     void releaseBuffer();
223
224     QSize size() const;
225
226 #ifndef QT_NO_DEBUG
227     void saveBuffer(const QString &s) const;
228 #endif
229
230 #ifdef Q_WS_MAC
231     void setCGContext(CGContextRef ref);
232     CGContextRef getCGContext() const;
233 #endif
234
235 #ifdef Q_WS_WIN
236     void setDC(HDC hdc);
237     HDC getDC() const;
238     void releaseDC(HDC hdc) const;
239 #endif
240
241     void alphaPenBlt(const void* src, int bpl, int depth, int rx,int ry,int w,int h);
242
243     Type type() const { return Raster; }
244
245     QPoint coordinateOffset() const;
246
247 #if defined(Q_WS_QWS) && !defined(QT_NO_RASTERCALLBACKS)
248     virtual void drawColorSpans(const QSpan *spans, int count, uint color);
249     virtual void drawBufferSpan(const uint *buffer, int bufsize,
250                                 int x, int y, int length, uint const_alpha);
251 #endif
252
253 protected:
254     QRasterPaintEngine(QRasterPaintEnginePrivate &d, QPaintDevice *);
255 private:
256     friend struct QSpanData;
257     friend class QBlitterPaintEngine;
258     friend class QBlitterPaintEnginePrivate;
259     void init();
260
261     void fillRect(const QRectF &rect, QSpanData *data);
262     void drawBitmap(const QPointF &pos, const QImage &image, QSpanData *fill);
263
264     bool drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFixedPoint *positions,
265                           QFontEngine *fontEngine);
266
267 #if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
268     void drawGlyphsS60(const QPointF &p, const QTextItemInt &ti);
269 #endif // Q_OS_SYMBIAN && QT_NO_FREETYPE
270
271     bool setClipRectInDeviceCoords(const QRect &r, Qt::ClipOperation op);
272
273     inline void ensureBrush(const QBrush &brush) {
274         if (!qbrush_fast_equals(state()->lastBrush, brush) || (brush.style() != Qt::NoBrush && state()->fillFlags))
275             updateBrush(brush);
276     }
277     inline void ensureBrush() { ensureBrush(state()->brush); }
278
279     inline void ensurePen(const QPen &pen) {
280         if (!qpen_fast_equals(state()->lastPen, pen) || (pen.style() != Qt::NoPen && state()->strokeFlags))
281             updatePen(pen);
282     }
283     inline void ensurePen() { ensurePen(state()->pen); }
284
285     void updateOutlineMapper();
286     inline void ensureOutlineMapper();
287
288     void updateState();
289     inline void ensureState() {
290         if (state()->dirty)
291             updateState();
292     }
293 };
294
295
296 /*******************************************************************************
297  * QRasterPaintEnginePrivate
298  */
299 class
300 #ifdef Q_WS_QWS
301 Q_GUI_EXPORT
302 #endif
303 QRasterPaintEnginePrivate : public QPaintEngineExPrivate
304 {
305     Q_DECLARE_PUBLIC(QRasterPaintEngine)
306 public:
307     QRasterPaintEnginePrivate();
308
309     void rasterizeLine_dashed(QLineF line, qreal width,
310                               int *dashIndex, qreal *dashOffset, bool *inDash);
311     void rasterize(QT_FT_Outline *outline, ProcessSpans callback, QSpanData *spanData, QRasterBuffer *rasterBuffer);
312     void rasterize(QT_FT_Outline *outline, ProcessSpans callback, void *userData, QRasterBuffer *rasterBuffer);
313     void updateMatrixData(QSpanData *spanData, const QBrush &brush, const QTransform &brushMatrix);
314
315     void systemStateChanged();
316
317     void drawImage(const QPointF &pt, const QImage &img, SrcOverBlendFunc func,
318                    const QRect &clip, int alpha, const QRect &sr = QRect());
319
320     QTransform brushMatrix() const {
321         Q_Q(const QRasterPaintEngine);
322         const QRasterPaintEngineState *s = q->state();
323         QTransform m(s->matrix);
324         m.translate(s->brushOrigin.x(), s->brushOrigin.y());
325         return m;
326     }
327
328     bool isUnclipped_normalized(const QRect &rect) const;
329     bool isUnclipped(const QRect &rect, int penWidth) const;
330     bool isUnclipped(const QRectF &rect, int penWidth) const;
331     ProcessSpans getPenFunc(const QRect &rect, const QSpanData *data) const;
332     ProcessSpans getPenFunc(const QRectF &rect, const QSpanData *data) const;
333     ProcessSpans getBrushFunc(const QRect &rect, const QSpanData *data) const;
334     ProcessSpans getBrushFunc(const QRectF &rect, const QSpanData *data) const;
335
336 #ifdef Q_WS_QWS
337     void prepare(QCustomRasterPaintDevice *);
338 #endif
339
340     inline const QClipData *clip() const;
341
342     void initializeRasterizer(QSpanData *data);
343
344     void recalculateFastImages();
345     bool canUseFastImageBlending(QPainter::CompositionMode mode, const QImage &image) const;
346
347     QPaintDevice *device;
348     QScopedPointer<QOutlineMapper> outlineMapper;
349     QScopedPointer<QRasterBuffer>  rasterBuffer;
350
351 #if defined (Q_WS_WIN)
352     HDC hdc;
353 #elif defined(Q_WS_MAC)
354     CGContextRef cgContext;
355 #endif
356
357     QRect deviceRect;
358
359     QStroker basicStroker;
360     QScopedPointer<QDashStroker> dashStroker;
361
362     QScopedPointer<QT_FT_Raster> grayRaster;
363
364     QDataBuffer<QLineF> cachedLines;
365     QSpanData image_filler;
366     QSpanData image_filler_xform;
367     QSpanData solid_color_filler;
368
369
370     QFontEngineGlyphCache::Type glyphCacheType;
371
372     QScopedPointer<QClipData> baseClip;
373
374     int deviceDepth;
375
376     uint mono_surface : 1;
377     uint outlinemapper_xform_dirty : 1;
378
379 #ifdef Q_WS_WIN
380     uint isPlain45DegreeRotation : 1;
381 #endif
382
383     QScopedPointer<QRasterizer> rasterizer;
384 };
385
386
387 class
388 #ifdef Q_WS_QWS
389 Q_GUI_EXPORT
390 #endif
391 QClipData {
392 public:
393     QClipData(int height);
394     ~QClipData();
395
396     int clipSpanHeight;
397     struct ClipLine {
398         int count;
399         QSpan *spans;
400     } *m_clipLines;
401
402     void initialize();
403
404     inline ClipLine *clipLines() {
405         if (!m_clipLines)
406             initialize();
407         return m_clipLines;
408     }
409
410     inline QSpan *spans() {
411         if (!m_spans)
412             initialize();
413         return m_spans;
414     }
415
416     int allocated;
417     int count;
418     QSpan *m_spans;
419     int xmin, xmax, ymin, ymax;
420
421     QRect clipRect;
422     QRegion clipRegion;
423
424     uint enabled : 1;
425     uint hasRectClip : 1;
426     uint hasRegionClip : 1;
427
428     void appendSpan(int x, int length, int y, int coverage);
429     void appendSpans(const QSpan *s, int num);
430
431     // ### Should optimize and actually kill the QSpans if the rect is
432     // ### a subset of The current region. Thus the "fast" clipspan
433     // ### callback can be used
434     void setClipRect(const QRect &rect);
435     void setClipRegion(const QRegion &region);
436     void fixup();
437 };
438
439 inline void QClipData::appendSpan(int x, int length, int y, int coverage)
440 {
441     Q_ASSERT(m_spans); // initialize() has to be called prior to adding spans..
442
443     if (count == allocated) {
444         allocated *= 2;
445         m_spans = (QSpan *)realloc(m_spans, allocated*sizeof(QSpan));
446     }
447     m_spans[count].x = x;
448     m_spans[count].len = length;
449     m_spans[count].y = y;
450     m_spans[count].coverage = coverage;
451     ++count;
452 }
453
454 inline void QClipData::appendSpans(const QSpan *s, int num)
455 {
456     Q_ASSERT(m_spans);
457
458     if (count + num > allocated) {
459         do {
460             allocated *= 2;
461         } while (count + num > allocated);
462         m_spans = (QSpan *)realloc(m_spans, allocated*sizeof(QSpan));
463     }
464     memcpy(m_spans+count, s, num*sizeof(QSpan));
465     count += num;
466 }
467
468 #ifdef Q_WS_QWS
469 class Q_GUI_EXPORT QCustomRasterPaintDevice : public QPaintDevice
470 {
471 public:
472     QCustomRasterPaintDevice(QWidget *w) : widget(w) {}
473
474     int devType() const { return QInternal::CustomRaster; }
475
476     virtual int metric(PaintDeviceMetric m) const;
477
478     virtual void* memory() const { return 0; }
479
480     virtual QImage::Format format() const {
481         return QImage::Format_ARGB32_Premultiplied;
482     }
483
484     virtual int bytesPerLine() const;
485
486     virtual QSize size() const {
487         return static_cast<QRasterPaintEngine*>(paintEngine())->size();
488     }
489
490 private:
491     QWidget *widget;
492 };
493 #endif // Q_WS_QWS
494
495 /*******************************************************************************
496  * QRasterBuffer
497  */
498 class
499 #ifdef Q_WS_QWS
500 Q_GUI_EXPORT
501 #endif
502 QRasterBuffer
503 {
504 public:
505     QRasterBuffer() : m_width(0), m_height(0), m_buffer(0) { init(); }
506
507     ~QRasterBuffer();
508
509     void init();
510
511     QImage::Format prepare(QImage *image);
512     QImage::Format prepare(QPixmap *pix);
513 #ifdef Q_WS_QWS
514     void prepare(QCustomRasterPaintDevice *device);
515 #endif
516     void prepare(int w, int h);
517     void prepareBuffer(int w, int h);
518
519     void resetBuffer(int val=0);
520
521     uchar *scanLine(int y) { Q_ASSERT(y>=0); Q_ASSERT(y<m_height); return m_buffer + y * bytes_per_line; }
522
523 #ifndef QT_NO_DEBUG
524     QImage bufferImage() const;
525 #endif
526
527     void flushToARGBImage(QImage *image) const;
528
529     int width() const { return m_width; }
530     int height() const { return m_height; }
531     int bytesPerLine() const { return bytes_per_line; }
532     int bytesPerPixel() const { return bytes_per_pixel; }
533
534     uchar *buffer() const { return m_buffer; }
535
536     bool monoDestinationWithClut;
537     QRgb destColor0;
538     QRgb destColor1;
539
540     QPainter::CompositionMode compositionMode;
541     QImage::Format format;
542     DrawHelper *drawHelper;
543     QImage colorizeBitmap(const QImage &image, const QColor &color);
544
545 private:
546     int m_width;
547     int m_height;
548     int bytes_per_line;
549     int bytes_per_pixel;
550     uchar *m_buffer;
551 };
552
553 inline void QRasterPaintEngine::ensureOutlineMapper() {
554     if (d_func()->outlinemapper_xform_dirty)
555         updateOutlineMapper();
556 }
557
558 inline const QClipData *QRasterPaintEnginePrivate::clip() const {
559     Q_Q(const QRasterPaintEngine);
560     if (q->state() && q->state()->clip && q->state()->clip->enabled)
561         return q->state()->clip;
562     return baseClip.data();
563 }
564
565
566 QT_END_NAMESPACE
567 #endif // QPAINTENGINE_RASTER_P_H