src/gui/painting/qpaintbuffer_p.h
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 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 QPAINTBUFFER_P_H
       
    43 #define QPAINTBUFFER_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 purely as an
       
    50 // implementation detail.  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 <qpaintdevice.h>
       
    57 
       
    58 #include <private/qpaintengineex_p.h>
       
    59 #include <private/qtextengine_p.h>
       
    60 #include <QDebug>
       
    61 
       
    62 QT_BEGIN_NAMESPACE
       
    63 
       
    64 class QPaintBufferPrivate;
       
    65 class QPaintBufferPlayback;
       
    66 
       
    67 class Q_GUI_EXPORT QPaintBuffer : public QPaintDevice
       
    68 {
       
    69 public:
       
    70     QPaintBuffer();
       
    71     QPaintBuffer(const QPaintBuffer &other);
       
    72     ~QPaintBuffer();
       
    73 
       
    74     bool isEmpty() const;
       
    75 
       
    76     void beginNewFrame();
       
    77     int numFrames() const;
       
    78 
       
    79     void draw(QPainter *painter, int frame = 0) const;
       
    80     void setBoundingRect(const QRectF &rect);
       
    81     QRectF boundingRect() const;
       
    82 
       
    83     virtual QPaintEngine *paintEngine() const;
       
    84     virtual int metric(PaintDeviceMetric m) const;
       
    85     virtual int devType() const;
       
    86 
       
    87     QPaintBuffer &operator=(const QPaintBuffer &other);
       
    88 
       
    89 private:
       
    90     friend class QPainterReplayer;
       
    91     friend class QOpenGLReplayer;
       
    92 
       
    93     friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &stream, const QPaintBuffer &buffer);
       
    94     friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QPaintBuffer &buffer);
       
    95 
       
    96     QPaintBufferPrivate *d_ptr;
       
    97 };
       
    98 
       
    99 Q_GUI_EXPORT QDataStream &operator<<(QDataStream &stream, const QPaintBuffer &buffer);
       
   100 Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QPaintBuffer &buffer);
       
   101 
       
   102 class QPaintBufferEngine;
       
   103 
       
   104 class QTextItemIntCopy
       
   105 {
       
   106 public:
       
   107     QTextItemIntCopy(const QTextItem &item);
       
   108     ~QTextItemIntCopy();
       
   109     QTextItemInt &operator () () {return m_item;}
       
   110 private:
       
   111     QTextItemInt m_item;
       
   112     QFont m_font;
       
   113 };
       
   114 
       
   115 struct QPaintBufferCommand
       
   116 {
       
   117     uint id : 8;
       
   118     uint size : 24;
       
   119 
       
   120     int offset;
       
   121     int offset2;
       
   122     int extra;
       
   123 };
       
   124 
       
   125 QDataStream &operator<<(QDataStream &stream, const QPaintBufferCommand &command);
       
   126 QDataStream &operator>>(QDataStream &stream, QPaintBufferCommand &command);
       
   127 
       
   128 Q_DECLARE_TYPEINFO(QPaintBufferCommand, Q_MOVABLE_TYPE);
       
   129 
       
   130 class QPaintBufferPrivate
       
   131 {
       
   132 public:
       
   133     enum Command {
       
   134         Cmd_Save,
       
   135         Cmd_Restore,
       
   136 
       
   137         Cmd_SetBrush,
       
   138         Cmd_SetBrushOrigin,
       
   139         Cmd_SetClipEnabled,
       
   140         Cmd_SetCompositionMode,
       
   141         Cmd_SetOpacity,
       
   142         Cmd_SetPen,
       
   143         Cmd_SetRenderHints,
       
   144         Cmd_SetTransform,
       
   145         Cmd_SetBackgroundMode,
       
   146 
       
   147         Cmd_ClipPath,
       
   148         Cmd_ClipRect,
       
   149         Cmd_ClipRegion,
       
   150         Cmd_ClipVectorPath,
       
   151 
       
   152         Cmd_DrawVectorPath,
       
   153         Cmd_FillVectorPath,
       
   154         Cmd_StrokeVectorPath,
       
   155 
       
   156         Cmd_DrawConvexPolygonF,
       
   157         Cmd_DrawConvexPolygonI,
       
   158         Cmd_DrawEllipseF,
       
   159         Cmd_DrawEllipseI,
       
   160         Cmd_DrawLineF,
       
   161         Cmd_DrawLineI,
       
   162         Cmd_DrawPath,
       
   163         Cmd_DrawPointsF,
       
   164         Cmd_DrawPointsI,
       
   165         Cmd_DrawPolygonF,
       
   166         Cmd_DrawPolygonI,
       
   167         Cmd_DrawPolylineF,
       
   168         Cmd_DrawPolylineI,
       
   169         Cmd_DrawRectF,
       
   170         Cmd_DrawRectI,
       
   171 
       
   172         Cmd_FillRectBrush,
       
   173         Cmd_FillRectColor,
       
   174 
       
   175         Cmd_DrawText,
       
   176         Cmd_DrawTextItem,
       
   177 
       
   178         Cmd_DrawImagePos,
       
   179         Cmd_DrawImageRect,
       
   180         Cmd_DrawPixmapPos,
       
   181         Cmd_DrawPixmapRect,
       
   182         Cmd_DrawTiledPixmap,
       
   183 
       
   184         Cmd_SystemStateChanged,
       
   185 
       
   186         Cmd_LastCommand
       
   187     };
       
   188 
       
   189     QPaintBufferPrivate();
       
   190     ~QPaintBufferPrivate();
       
   191 
       
   192     int addData(const int *data, int count) {
       
   193         if (count <= 0)
       
   194             return 0;
       
   195         int pos = ints.size();
       
   196         ints.resize(pos + count);
       
   197         memcpy(ints.data() + pos, data, count * sizeof(int));
       
   198         return pos;
       
   199     }
       
   200 
       
   201     int addData(const qreal *data, int count) {
       
   202         if (count <= 0)
       
   203             return 0;
       
   204         int pos = floats.size();
       
   205         floats.resize(pos + count);
       
   206         memcpy(floats.data() + pos, data, count * sizeof(qreal));
       
   207         return pos;
       
   208     }
       
   209 
       
   210     int addData(const QVariant &var) {
       
   211         variants << var;
       
   212         return variants.size() - 1;
       
   213     }
       
   214 
       
   215     QPaintBufferCommand *addCommand(Command command) {
       
   216         QPaintBufferCommand cmd;
       
   217         cmd.id = command;
       
   218         cmd.size = cmd.offset = cmd.offset2 = cmd.extra = 0;
       
   219         commands << cmd;
       
   220         return &commands.last();
       
   221     }
       
   222 
       
   223     QPaintBufferCommand *addCommand(Command command, const QVariant &var) {
       
   224         QPaintBufferCommand cmd;
       
   225         cmd.id = command;
       
   226         cmd.offset = addData(var);
       
   227         cmd.size = cmd.offset2 = cmd.extra = 0;
       
   228         commands << cmd;
       
   229         return &commands.last();
       
   230     }
       
   231 
       
   232     QPaintBufferCommand *addCommand(Command command, const QVectorPath &path) {
       
   233         QPaintBufferCommand cmd;
       
   234         cmd.id = command;
       
   235         cmd.offset = addData(path.points(), path.elementCount() * 2);
       
   236         cmd.offset2 = ints.size();
       
   237         ints << path.hints();
       
   238         // The absence of path elements is indicated by setting the highest bit in 'cmd.offset2'.
       
   239         if (path.elements())
       
   240             addData((const int *) path.elements(), path.elementCount());
       
   241         else
       
   242             cmd.offset2 |= 0x80000000;
       
   243         cmd.size = path.elementCount();
       
   244         cmd.extra = 0;
       
   245         commands << cmd;
       
   246         return &commands.last();
       
   247     }
       
   248 
       
   249     QPaintBufferCommand *addCommand(Command command , const qreal *pts, int arrayLength, int elementCount) {
       
   250         QPaintBufferCommand cmd;
       
   251         cmd.id = command;
       
   252         cmd.offset = addData(pts, arrayLength);
       
   253         cmd.size = elementCount;
       
   254         cmd.offset2 = cmd.extra = 0;
       
   255         commands << cmd;
       
   256         return &commands.last();
       
   257     }
       
   258 
       
   259     QPaintBufferCommand *addCommand(Command command , const int *pts, int arrayLength, int elementCount) {
       
   260         QPaintBufferCommand cmd;
       
   261         cmd.id = command;
       
   262         cmd.offset = addData(pts, arrayLength);
       
   263         cmd.size = elementCount;
       
   264         cmd.offset2 = cmd.extra = 0;
       
   265         commands << cmd;
       
   266         return &commands.last();
       
   267     }
       
   268 
       
   269     inline void updateBoundingRect(const QRectF &rect);
       
   270 
       
   271     QAtomicInt ref;
       
   272 
       
   273     QVector<int> ints;
       
   274     QVector<qreal> floats;
       
   275     QVector<QVariant> variants;
       
   276 
       
   277     QVector<QPaintBufferCommand> commands;
       
   278     QList<int> frames;
       
   279 
       
   280     QPaintBufferEngine *engine;
       
   281     QRectF boundingRect;
       
   282     qreal penWidthAdjustment;
       
   283     uint calculateBoundingRect : 1;
       
   284 
       
   285     void *cache;
       
   286 };
       
   287 
       
   288 
       
   289 struct QVectorPathCmd
       
   290 {
       
   291     // The absence of path elements is indicated by setting the highest bit in 'cmd.offset2'.
       
   292     QVectorPathCmd(QPaintBufferPrivate *d, const QPaintBufferCommand &cmd)
       
   293         : vectorPath(d->floats.constData() + cmd.offset,
       
   294                      cmd.size,
       
   295                      cmd.offset2 & 0x80000000
       
   296                      ? 0
       
   297                      : (const QPainterPath::ElementType *) (d->ints.constData() + cmd.offset2 + 1),
       
   298                      *(d->ints.constData() + (cmd.offset2 & 0x7fffffff))) {}
       
   299 
       
   300     inline const QVectorPath &operator()() const { return vectorPath; }
       
   301 
       
   302     QVectorPath vectorPath;
       
   303 };
       
   304 
       
   305 
       
   306 class Q_GUI_EXPORT QPainterReplayer
       
   307 {
       
   308 public:
       
   309     QPainterReplayer() { }
       
   310 
       
   311     virtual ~QPainterReplayer() { }
       
   312 
       
   313     void setupTransform(QPainter *painter);
       
   314     void process(const QPaintBufferCommand &cmd);
       
   315     void draw(const QPaintBuffer &buffer, QPainter *painter, int frame);
       
   316 
       
   317 protected:
       
   318     QPaintBufferPrivate *d;
       
   319     QTransform m_world_matrix;
       
   320 
       
   321     QPainter *painter;
       
   322 };
       
   323 
       
   324 class Q_GUI_EXPORT QPaintEngineExReplayer : public QPainterReplayer
       
   325 {
       
   326 public:
       
   327     QPaintEngineExReplayer() { }
       
   328 
       
   329     void process(const QPaintBufferCommand &cmd);
       
   330 };
       
   331 
       
   332 class QPaintBufferEnginePrivate;
       
   333 
       
   334 class QPaintBufferEngine : public QPaintEngineEx
       
   335 {
       
   336     Q_DECLARE_PRIVATE(QPaintBufferEngine)
       
   337 public:
       
   338     QPaintBufferEngine(QPaintBufferPrivate *buffer);
       
   339 
       
   340     virtual bool begin(QPaintDevice *device);
       
   341     virtual bool end();
       
   342 
       
   343     virtual Type type() const { return QPaintEngine::PaintBuffer; }
       
   344 
       
   345     virtual QPainterState *createState(QPainterState *orig) const;
       
   346 
       
   347     virtual void draw(const QVectorPath &path);
       
   348     virtual void fill(const QVectorPath &path, const QBrush &brush);
       
   349     virtual void stroke(const QVectorPath &path, const QPen &pen);
       
   350 
       
   351     virtual void clip(const QVectorPath &path, Qt::ClipOperation op);
       
   352     virtual void clip(const QRect &rect, Qt::ClipOperation op);
       
   353     virtual void clip(const QRegion &region, Qt::ClipOperation op);
       
   354     virtual void clip(const QPainterPath &path, Qt::ClipOperation op);
       
   355 
       
   356     virtual void clipEnabledChanged();
       
   357     virtual void penChanged();
       
   358     virtual void brushChanged();
       
   359     virtual void brushOriginChanged();
       
   360     virtual void opacityChanged();
       
   361     virtual void compositionModeChanged();
       
   362     virtual void renderHintsChanged();
       
   363     virtual void transformChanged();
       
   364     virtual void backgroundModeChanged();
       
   365 
       
   366     virtual void fillRect(const QRectF &rect, const QBrush &brush);
       
   367     virtual void fillRect(const QRectF &rect, const QColor &color);
       
   368 
       
   369     virtual void drawRects(const QRect *rects, int rectCount);
       
   370     virtual void drawRects(const QRectF *rects, int rectCount);
       
   371 
       
   372     virtual void drawLines(const QLine *lines, int lineCount);
       
   373     virtual void drawLines(const QLineF *lines, int lineCount);
       
   374 
       
   375     virtual void drawEllipse(const QRectF &r);
       
   376     virtual void drawEllipse(const QRect &r);
       
   377 
       
   378     virtual void drawPath(const QPainterPath &path);
       
   379 
       
   380     virtual void drawPoints(const QPointF *points, int pointCount);
       
   381     virtual void drawPoints(const QPoint *points, int pointCount);
       
   382 
       
   383     virtual void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
       
   384     virtual void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode);
       
   385 
       
   386     virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
       
   387     virtual void drawPixmap(const QPointF &pos, const QPixmap &pm);
       
   388 
       
   389     virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
       
   390                            Qt::ImageConversionFlags flags = Qt::AutoColor);
       
   391     virtual void drawImage(const QPointF &pos, const QImage &image);
       
   392 
       
   393     virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
       
   394 
       
   395     virtual void drawTextItem(const QPointF &pos, const QTextItem &ti);
       
   396 
       
   397     virtual void setState(QPainterState *s);
       
   398     virtual uint flags() const {return QPaintEngineEx::DoNotEmulate;}
       
   399 
       
   400     QPaintBufferPrivate *buffer;
       
   401 
       
   402     mutable int m_begin_detected : 1;
       
   403     mutable int m_save_detected : 1;
       
   404     mutable int m_stream_raw_text_items : 1;
       
   405     mutable int m_unused : 29;
       
   406 
       
   407     mutable QPainterState *m_created_state;
       
   408 };
       
   409 
       
   410 class Q_GUI_EXPORT QPaintBufferSignalProxy : public QObject
       
   411 {
       
   412     Q_OBJECT
       
   413 public:
       
   414     QPaintBufferSignalProxy() : QObject() {}
       
   415     void emitAboutToDestroy(const QPaintBufferPrivate *buffer) {
       
   416         emit aboutToDestroy(buffer);
       
   417     }
       
   418     static QPaintBufferSignalProxy *instance();
       
   419 Q_SIGNALS:
       
   420     void aboutToDestroy(const QPaintBufferPrivate *buffer);
       
   421 };
       
   422 
       
   423 // One resource per paint buffer and vice versa.
       
   424 class Q_GUI_EXPORT QPaintBufferResource : public QObject
       
   425 {
       
   426     Q_OBJECT
       
   427 public:
       
   428     typedef void (*FreeFunc)(void *);
       
   429 
       
   430     QPaintBufferResource(FreeFunc f, QObject *parent = 0);
       
   431     ~QPaintBufferResource();
       
   432     // Set resource 'value' for 'key'.
       
   433     void insert(const QPaintBufferPrivate *key, void *value);
       
   434     // Return resource for 'key'.
       
   435     void *value(const QPaintBufferPrivate *key);
       
   436 public slots:
       
   437     // Remove entry 'key' from cache and delete resource.
       
   438     void remove(const QPaintBufferPrivate *key);
       
   439 private:
       
   440     typedef QHash<const QPaintBufferPrivate *, void *> Cache;
       
   441     Cache m_cache;
       
   442     FreeFunc free;
       
   443 };
       
   444 
       
   445 QT_END_NAMESPACE
       
   446 
       
   447 #endif // QPAINTBUFFER_P_H