| |   |
| /**************************************************************************** |
| ** |
| ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
| ** Contact: Nokia Corporation (qt-info@nokia.com) |
| ** |
| ** This file is part of the QtGui module of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:LGPL$ |
| ** No Commercial Usage |
| ** This file contains pre-release code and may not be distributed. |
| ** You may use this file in accordance with the terms and conditions |
| ** contained in the Technology Preview License Agreement accompanying |
| ** this package. |
| ** |
| ** GNU Lesser General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Lesser |
| ** General Public License version 2.1 as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.LGPL included in the |
| ** packaging of this file. Please review the following information to |
| ** ensure the GNU Lesser General Public License version 2.1 requirements |
| ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
| ** |
| ** In addition, as a special exception, Nokia gives you certain |
| ** additional rights. These rights are described in the Nokia Qt LGPL |
| ** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this |
| ** package. |
| ** |
| ** If you have questions regarding the use of this file, please contact |
| ** Nokia at qt-info@nokia.com. |
| ** |
| ** |
| ** |
| ** |
| ** |
| ** |
| ** |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| #include <qmath.h> |
| #include <private/qpainterpath_p.h> |
| #include <private/qpaintbuffer_p.h> |
| //#include <private/qtextengine_p.h> |
| #include <private/qfontengine_p.h> |
| #include <private/qemulationpaintengine_p.h> |
|
| #include <QDebug> |
|
| //#define QPAINTBUFFER_DEBUG_DRAW |
|
| extern int qt_defaultDpiX(); |
| extern int qt_defaultDpiY(); |
| extern void qt_format_text(const QFont &font, |
| const QRectF &_r, int tf, const QTextOption *option, const QString& str, QRectF *brect, |
| int tabstops, int* tabarray, int tabarraylen, |
| QPainter *painter); |
|
| QTextItemIntCopy::QTextItemIntCopy(const QTextItem &item) |
| : m_item(static_cast<const QTextItemInt &>(item)) |
| { |
| QChar *chars = new QChar[m_item.num_chars]; |
| unsigned short *logClusters = new unsigned short[m_item.num_chars]; |
| memcpy(chars, m_item.chars, m_item.num_chars * sizeof(QChar)); |
| memcpy(logClusters, m_item.logClusters, m_item.num_chars * sizeof(unsigned short)); |
| m_item.chars = chars; |
| m_item.logClusters = logClusters; |
|
| const int size = QGlyphLayout::spaceNeededForGlyphLayout(m_item.glyphs.numGlyphs); |
| char *glyphLayoutData = new char[size]; |
| QGlyphLayout glyphs(glyphLayoutData, m_item.glyphs.numGlyphs); |
| memcpy(glyphs.offsets, m_item.glyphs.offsets, m_item.glyphs.numGlyphs * sizeof(QFixedPoint)); |
| memcpy(glyphs.glyphs, m_item.glyphs.glyphs, m_item.glyphs.numGlyphs * sizeof(HB_Glyph)); |
| memcpy(glyphs.advances_x, m_item.glyphs.advances_x, m_item.glyphs.numGlyphs * sizeof(QFixed)); |
| memcpy(glyphs.advances_y, m_item.glyphs.advances_y, m_item.glyphs.numGlyphs * sizeof(QFixed)); |
| memcpy(glyphs.justifications, m_item.glyphs.justifications, m_item.glyphs.numGlyphs * sizeof(QGlyphJustification)); |
| memcpy(glyphs.attributes, m_item.glyphs.attributes, m_item.glyphs.numGlyphs * sizeof(HB_GlyphAttributes)); |
| m_item.glyphs = glyphs; |
|
| m_font = *m_item.f; |
| m_item.f = &m_font; |
|
| m_item.fontEngine->ref.ref(); // Increment reference count. |
| } |
|
| QTextItemIntCopy::~QTextItemIntCopy() |
| { |
| delete m_item.chars; |
| delete m_item.logClusters; |
| delete m_item.glyphs.data(); |
| if (!m_item.fontEngine->ref.deref()) |
| delete m_item.fontEngine; |
| } |
|
| /************************************************************************ |
| * |
| * QPaintBufferSignalProxy |
| * |
| ************************************************************************/ |
|
| Q_GLOBAL_STATIC(QPaintBufferSignalProxy, theSignalProxy) |
|
| QPaintBufferSignalProxy *QPaintBufferSignalProxy::instance() |
| { |
| return theSignalProxy(); |
| } |
|
| /************************************************************************ |
| * |
| * QPaintBufferPrivate |
| * |
| ************************************************************************/ |
|
| QPaintBufferPrivate::QPaintBufferPrivate() |
| : ref(1), engine(0), penWidthAdjustment(0) |
| , calculateBoundingRect(true) |
| , cache(0) |
| { |
| } |
|
| QPaintBufferPrivate::~QPaintBufferPrivate() |
| { |
| QPaintBufferSignalProxy::instance()->emitAboutToDestroy(this); |
|
| for (int i = 0; i < commands.size(); ++i) { |
| const QPaintBufferCommand &cmd = commands.at(i); |
| if (cmd.id == QPaintBufferPrivate::Cmd_DrawTextItem) |
| delete reinterpret_cast<QTextItemIntCopy *>(qVariantValue<void *>(variants.at(cmd.offset))); |
| } |
| } |
|
|
| inline void QPaintBufferPrivate::updateBoundingRect(const QRectF &br) |
| { |
| // transform to device coords and adjust for pen width |
| Q_ASSERT(engine && engine->painter()); |
| QPainter *painter = engine->painter(); |
| const QTransform transform = painter->transform(); |
| QRectF devRect = transform.mapRect(br); |
| if (penWidthAdjustment > 0) { |
| devRect = devRect.adjusted(-penWidthAdjustment, -penWidthAdjustment, |
| penWidthAdjustment, penWidthAdjustment); |
| } |
|
| if (boundingRect.isEmpty()) { |
| boundingRect = devRect; |
| } else { |
| qreal min_x = qMin(devRect.left(), boundingRect.left()); |
| qreal min_y = qMin(devRect.top(), boundingRect.top()); |
| qreal max_x = qMax(devRect.right(), boundingRect.right()); |
| qreal max_y = qMax(devRect.bottom(), boundingRect.bottom()); |
| boundingRect = QRectF(min_x, min_y, max_x - min_x, max_y - min_y); |
| } |
| if (painter->hasClipping()) |
| boundingRect &= transform.mapRect(painter->clipRegion().boundingRect()); |
| } |
|
|
| /************************************************************************ |
| * |
| * QPaintBuffer |
| * |
| ************************************************************************/ |
|
|
|
| QPaintBuffer::QPaintBuffer() |
| : d_ptr(new QPaintBufferPrivate) |
| { |
| } |
|
| QPaintBuffer::~QPaintBuffer() |
| { |
| if (!d_ptr->ref.deref()) |
| delete d_ptr; |
| } |
|
| QPaintBuffer::QPaintBuffer(const QPaintBuffer &other) |
| : QPaintDevice(), d_ptr(other.d_ptr) |
| { |
| d_ptr->ref.ref(); |
| } |
|
| QPaintEngine *QPaintBuffer::paintEngine() const |
| { |
| QPaintBufferPrivate *d = const_cast<QPaintBuffer *>(this)->d_ptr; |
| if (!d->engine) |
| d->engine = new QPaintBufferEngine(d); |
| return d->engine; |
| } |
|
|
| int QPaintBuffer::metric(PaintDeviceMetric metric) const |
| { |
| int val = 0; |
| switch (metric) { |
| case PdmWidth: |
| val = qCeil(d_ptr->boundingRect.width()); |
| break; |
| case PdmHeight: |
| val = qCeil(d_ptr->boundingRect.height()); |
| break; |
| case PdmDpiX: |
| case PdmPhysicalDpiX: |
| val = qt_defaultDpiX(); |
| break; |
| case PdmDpiY: |
| case PdmPhysicalDpiY: |
| val = qt_defaultDpiY(); |
| break; |
| default: |
| val = QPaintDevice::metric(metric); |
| } |
|
| return val; |
| } |
|
| int QPaintBuffer::devType() const |
| { |
| return QInternal::PaintBuffer; |
| } |
|
| QPaintBuffer &QPaintBuffer::operator=(const QPaintBuffer &other) |
| { |
| if (other.d_ptr != d_ptr) { |
| QPaintBufferPrivate *data = other.d_ptr; |
| data->ref.ref(); |
| if (d_ptr->ref.deref()) |
| delete d_ptr; |
| d_ptr = data; |
| } |
| return *this; |
| } |
|
| bool QPaintBuffer::isEmpty() const |
| { |
| return d_ptr->commands.isEmpty(); |
| } |
|
|
|
| void QPaintBuffer::draw(QPainter *painter) const |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBuffer::draw() --------------------------------"; |
|
| // printf("Float buffer:"); |
| // for (int i=0; i<d->floats.size(); i++) { |
| // if ((i % 10) == 0) { |
| // printf("\n%4d-%4d: ", i, i+9); |
| // } |
| // printf("%4.2f ", d->floats[i]); |
| // } |
| // printf("\n"); |
|
| // printf("Int Buffer:"); |
| // for (int i=0; i<d->ints.size(); i++) { |
| // if ((i % 10) == 0) { |
| // printf("\n%4d-%4d: ", i, i+10); |
| // } |
| // printf("%5d", d->ints[i]); |
| // } |
| // printf("\n"); |
| #endif |
|
| if (painter && !painter->isActive()) |
| return; |
|
| QPaintEngineEx *xengine = painter->paintEngine()->isExtended() |
| ? (QPaintEngineEx *) painter->paintEngine() : 0; |
| if (xengine) { |
| QPaintEngineExReplayer player; |
| player.draw(*this, painter); |
| } else { |
| QPainterReplayer player; |
| player.draw(*this, painter); |
| } |
|
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBuffer::draw() -------------------------------- DONE!"; |
| #endif |
| } |
|
|
| QRectF QPaintBuffer::boundingRect() const |
| { |
| return d_ptr->boundingRect; |
| } |
|
| void QPaintBuffer::setBoundingRect(const QRectF &rect) |
| { |
| d_ptr->boundingRect = rect; |
| d_ptr->calculateBoundingRect = false; |
| } |
|
|
| class QPaintBufferEnginePrivate : public QPaintEngineExPrivate |
| { |
| Q_DECLARE_PUBLIC(QPaintBufferEngine) |
| public: |
| void systemStateChanged() { |
| Q_Q(QPaintBufferEngine); |
| q->buffer->addCommand(QPaintBufferPrivate::Cmd_SystemStateChanged, QVariant(systemClip)); |
| } |
| }; |
|
|
| /************************************************************************ |
| * |
| * QPaintBufferEngine |
| * |
| ************************************************************************/ |
|
| QPaintBufferEngine::QPaintBufferEngine(QPaintBufferPrivate *b) |
| : QPaintEngineEx(*(new QPaintBufferEnginePrivate)) |
| , buffer(b) |
| , m_begin_detected(false) |
| , m_save_detected(false) |
| , m_stream_raw_text_items(false) |
| { |
| } |
|
| bool QPaintBufferEngine::begin(QPaintDevice *) |
| { |
| Q_D(QPaintBufferEngine); |
| painter()->save(); |
| d->systemStateChanged(); |
| return true; |
| } |
|
| bool QPaintBufferEngine::end() |
| { |
| painter()->restore(); |
| m_created_state = 0; |
| return true; |
| } |
|
| QPainterState *QPaintBufferEngine::createState(QPainterState *orig) const |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: createState, orig=" << orig << ", current=" << state(); |
| #endif |
|
| Q_ASSERT(!m_begin_detected); |
| Q_ASSERT(!m_save_detected); |
|
| if (orig == 0) { |
| m_begin_detected = true; |
| return new QPainterState(); |
| } else { |
| m_save_detected = true; |
| return new QPainterState(orig); |
| } |
| } |
|
| void QPaintBufferEngine::clip(const QVectorPath &path, Qt::ClipOperation op) |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: clip vpath:" << path.elementCount() << "op:" << op; |
| #endif |
| QPaintBufferCommand *cmd = |
| buffer->addCommand(QPaintBufferPrivate::Cmd_ClipVectorPath, path); |
| cmd->extra = op; |
| } |
|
| void QPaintBufferEngine::clip(const QRect &rect, Qt::ClipOperation op) |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: clip rect:" << rect << "op:" << op; |
| #endif |
| QPaintBufferCommand *cmd = |
| buffer->addCommand(QPaintBufferPrivate::Cmd_ClipRect, (int *) &rect, 4, 1); |
| cmd->extra = op; |
| } |
|
| void QPaintBufferEngine::clip(const QRegion ®ion, Qt::ClipOperation op) |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: clip region br:" << region.boundingRect() << "op:" << op; |
| #endif |
| QPaintBufferCommand *cmd = |
| buffer->addCommand(QPaintBufferPrivate::Cmd_ClipRegion, QVariant(region)); |
| cmd->extra = op; |
| } |
|
| void QPaintBufferEngine::clip(const QPainterPath &path, Qt::ClipOperation op) |
| { |
| // ### TODO |
| // QPaintBufferCommand *cmd = |
| // buffer->addCommand(QPaintBufferPrivate::Cmd_ClipPath, QVariant(path)); |
| // cmd->extra = op; |
| QPaintEngineEx::clip(path, op); |
| } |
|
| void QPaintBufferEngine::clipEnabledChanged() |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: clip enable change" << state()->clipEnabled; |
| #endif |
|
| buffer->addCommand(QPaintBufferPrivate::Cmd_SetClipEnabled, state()->clipEnabled); |
| } |
|
| void QPaintBufferEngine::penChanged() |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine:" << state()->pen; |
| #endif |
| const QPen &pen = state()->pen; |
|
| if (!buffer->commands.isEmpty() |
| && buffer->commands.last().id == QPaintBufferPrivate::Cmd_SetPen) { |
| buffer->variants[buffer->commands.last().offset] = pen; |
| return; |
| } |
| if (buffer->calculateBoundingRect) { |
| if (pen.style() == Qt::NoPen) { |
| buffer->penWidthAdjustment = 0; |
| } else { |
| qreal penWidth = (pen.widthF() == 0) ? 1 : pen.widthF(); |
| QPointF transformedWidth(penWidth, penWidth); |
| if (!pen.isCosmetic()) |
| transformedWidth = painter()->transform().map(transformedWidth); |
| buffer->penWidthAdjustment = transformedWidth.x() / 2.0; |
| } |
| } |
| buffer->addCommand(QPaintBufferPrivate::Cmd_SetPen, pen); |
| } |
|
| void QPaintBufferEngine::brushChanged() |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine:" << state()->brush; |
| #endif |
| const QBrush &brush = state()->brush; |
|
| if (!buffer->commands.isEmpty() |
| && buffer->commands.last().id == QPaintBufferPrivate::Cmd_SetBrush) { |
| buffer->variants[buffer->commands.last().offset] = brush; |
| return; |
| } |
|
| buffer->addCommand(QPaintBufferPrivate::Cmd_SetBrush, brush); |
| } |
|
| void QPaintBufferEngine::brushOriginChanged() |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: brush origin changed" << state()->brushOrigin; |
| #endif |
| buffer->addCommand(QPaintBufferPrivate::Cmd_SetBrushOrigin, state()->brushOrigin); |
| } |
|
| void QPaintBufferEngine::opacityChanged() |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: opacity changed" << state()->opacity; |
| #endif |
| buffer->addCommand(QPaintBufferPrivate::Cmd_SetOpacity, state()->opacity); |
| } |
|
| void QPaintBufferEngine::compositionModeChanged() |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: composition mode" << state()->composition_mode; |
| #endif |
| QPaintBufferCommand *cmd = |
| buffer->addCommand(QPaintBufferPrivate::Cmd_SetCompositionMode); |
| cmd->extra = state()->composition_mode; |
| } |
|
| void QPaintBufferEngine::renderHintsChanged() |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: render hints changed" << state()->renderHints; |
| #endif |
| QPaintBufferCommand *cmd = |
| buffer->addCommand(QPaintBufferPrivate::Cmd_SetRenderHints); |
| cmd->extra = state()->renderHints; |
| } |
|
| void QPaintBufferEngine::transformChanged() |
| { |
| // ### accumulate, like in QBrush case... |
| if (!buffer->commands.isEmpty() |
| && buffer->commands.last().id == QPaintBufferPrivate::Cmd_SetTransform) { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: compressing " << state()->matrix; |
| #endif |
| buffer->variants[buffer->commands.last().offset] = state()->matrix; |
| return; |
| } |
|
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: " << state()->matrix; |
| #endif |
| buffer->addCommand(QPaintBufferPrivate::Cmd_SetTransform, state()->matrix); |
| } |
|
| void QPaintBufferEngine::backgroundModeChanged() |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintEngineBuffer: background mode changed" << state()->bgMode; |
| #endif |
| QPaintBufferCommand *cmd = buffer->addCommand(QPaintBufferPrivate::Cmd_SetBackgroundMode); |
| cmd->extra = state()->bgMode; |
| } |
|
| void QPaintBufferEngine::draw(const QVectorPath &path) |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: draw vpath:" << path.elementCount(); |
| #endif |
| buffer->addCommand(QPaintBufferPrivate::Cmd_DrawVectorPath, path); |
| // if (buffer->calculateBoundingRect) { |
| // QRealRect r = path.controlPointRect(); |
| // buffer->updateBoundingRect(QRectF(r.x1, r.y1, r.x2 - r.x1, r.y2 - r.y1)); |
| // } |
| } |
|
| void QPaintBufferEngine::fill(const QVectorPath &path, const QBrush &brush) |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: fill vpath:" << path.elementCount() << brush; |
| #endif |
| QPaintBufferCommand *cmd = |
| buffer->addCommand(QPaintBufferPrivate::Cmd_FillVectorPath, path); |
| cmd->extra = buffer->addData(QVariant(brush)); |
| // if (buffer->calculateBoundingRect) { |
| // QRealRect r = path.controlPointRect(); |
| // buffer->updateBoundingRect(QRectF(r.x1, r.y1, r.x2 - r.x1, r.y2 - r.y1)); |
| // } |
| } |
|
| void QPaintBufferEngine::stroke(const QVectorPath &path, const QPen &pen) |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: stroke vpath:" << path.elementCount() << pen; |
| #endif |
| QPaintBufferCommand *cmd = |
| buffer->addCommand(QPaintBufferPrivate::Cmd_StrokeVectorPath, path); |
| cmd->extra = buffer->addData(QVariant(pen)); |
| // if (buffer->calculateBoundingRect) { |
| // QRealRect r = path.controlPointRect(); |
| // buffer->updateBoundingRect(QRectF(r.x1, r.y1, r.x2 - r.x1, r.y2 - r.y1)); |
| // } |
| } |
|
| void QPaintBufferEngine::fillRect(const QRectF &rect, const QBrush &brush) |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: fillRect brush:" << rect << brush; |
| #endif |
| QPaintBufferCommand *cmd = |
| buffer->addCommand(QPaintBufferPrivate::Cmd_FillRectBrush, (qreal *) &rect, 4, 1); |
| cmd->extra = buffer->addData(brush); |
| if (buffer->calculateBoundingRect) |
| buffer->updateBoundingRect(rect); |
| } |
|
| void QPaintBufferEngine::fillRect(const QRectF &rect, const QColor &color) |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: fillRect color:" << rect << color; |
| #endif |
| QPaintBufferCommand *cmd = |
| buffer->addCommand(QPaintBufferPrivate::Cmd_FillRectColor, (qreal *) &rect, 4, 1); |
| cmd->extra = buffer->addData(color); |
| if (buffer->calculateBoundingRect) |
| buffer->updateBoundingRect(rect); |
| } |
|
| void QPaintBufferEngine::drawRects(const QRect *rects, int rectCount) |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: drawRectsI:" << rectCount; |
| #endif |
| QPaintBufferCommand *cmd = |
| buffer->addCommand(QPaintBufferPrivate::Cmd_DrawRectI, (int *) rects, 4 * rectCount, rectCount); |
| cmd->extra = rectCount; |
|
| if (buffer->calculateBoundingRect) { |
| if (rectCount == 1) { |
| buffer->updateBoundingRect(rects[0]); |
| } else { |
| int min_x = rects[0].left(); |
| int min_y = rects[0].top(); |
| int max_x = rects[0].left() + rects[0].width(); |
| int max_y = rects[0].top() + rects[0].height(); |
| for (int i=1; i< rectCount; ++i) { |
| if (rects[i].left() < min_x) |
| min_x = rects[i].left(); |
| if (rects[i].top() < min_y) |
| min_y = rects[i].top(); |
| if (rects[i].right() > max_x) |
| max_x = rects[i].left() + rects[i].width(); |
| if (rects[i].bottom() > max_y) |
| max_y = rects[i].top() + rects[i].height(); |
|
| } |
| buffer->updateBoundingRect(QRectF(min_x, min_y, max_x - min_x, max_y - min_y)); |
| } |
| } |
| } |
|
| void QPaintBufferEngine::drawRects(const QRectF *rects, int rectCount) |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: drawRectsF:" << rectCount; |
| #endif |
| QPaintBufferCommand *cmd = |
| buffer->addCommand(QPaintBufferPrivate::Cmd_DrawRectF, (qreal *) rects, 4 * rectCount, rectCount); |
| cmd->extra = rectCount; |
|
| if (buffer->calculateBoundingRect) { |
| if (rectCount == 1) { |
| buffer->updateBoundingRect(rects[0]); |
| } else { |
| qreal min_x = rects[0].left(); |
| qreal min_y = rects[0].top(); |
| qreal max_x = rects[0].right(); |
| qreal max_y = rects[0].bottom(); |
| for (int i=1; i< rectCount; ++i) { |
| if (rects[i].left() < min_x) |
| min_x = rects[i].left(); |
| if (rects[i].top() < min_y) |
| min_y = rects[i].top(); |
| if (rects[i].right() > max_x) |
| max_x = rects[i].right(); |
| if (rects[i].bottom() > max_y) |
| max_y = rects[i].bottom(); |
|
| } |
| buffer->updateBoundingRect(QRectF(min_x, min_y, max_x - min_x, max_y - min_y)); |
| } |
| } |
| } |
|
| void QPaintBufferEngine::drawLines(const QLine *lines, int lineCount) |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: drawLinesI:" << lineCount; |
| #endif |
| QPaintBufferCommand *cmd = |
| buffer->addCommand(QPaintBufferPrivate::Cmd_DrawLineI, (int *) lines, 4 * lineCount, lineCount); |
| cmd->extra = lineCount; |
|
| if (buffer->calculateBoundingRect) { |
| int min_x = lines[0].p1().x(); |
| int min_y = lines[0].p1().y(); |
| int max_x = lines[0].p2().x(); |
| int max_y = lines[0].p2().y(); |
| if (min_x > max_x) |
| qSwap(min_x, max_x); |
| if (min_y > max_y) |
| qSwap(min_y, max_y); |
| for (int i=1; i < lineCount; ++i) { |
| int p1_x = lines[i].p1().x(); |
| int p1_y = lines[i].p1().y(); |
| int p2_x = lines[i].p2().x(); |
| int p2_y = lines[i].p2().y(); |
| if (p1_x > p2_x) { |
| min_x = qMin(p2_x, min_x); |
| max_x = qMax(p1_x, max_x); |
| } else { |
| min_x = qMin(p1_x, min_x); |
| max_x = qMax(p2_x, max_x); |
| } |
| if (p1_y > p2_y) { |
| min_y = qMin(p2_y, min_y); |
| max_y = qMax(p1_y, max_y); |
| } else { |
| min_y = qMin(p1_y, min_y); |
| max_y = qMax(p2_y, max_y); |
| } |
| } |
| buffer->updateBoundingRect(QRectF(min_x, min_y, max_x - min_x, max_y - min_y)); |
| } |
| } |
|
| void QPaintBufferEngine::drawLines(const QLineF *lines, int lineCount) |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: drawLinesF:" << lineCount; |
| #endif |
| QPaintBufferCommand *cmd = |
| buffer->addCommand(QPaintBufferPrivate::Cmd_DrawLineF, (qreal *) lines, 4 * lineCount, lineCount); |
| cmd->extra = lineCount; |
|
| if (buffer->calculateBoundingRect) { |
| qreal min_x = lines[0].p1().x(); |
| qreal min_y = lines[0].p1().y(); |
| qreal max_x = lines[0].p2().x(); |
| qreal max_y = lines[0].p2().y(); |
| if (min_x > max_x) |
| qSwap(min_x, max_x); |
| if (min_y > max_y) |
| qSwap(min_y, max_y); |
| for (int i=1; i < lineCount; ++i) { |
| qreal p1_x = lines[i].p1().x(); |
| qreal p1_y = lines[i].p1().y(); |
| qreal p2_x = lines[i].p2().x(); |
| qreal p2_y = lines[i].p2().y(); |
| if (p1_x > p2_x) { |
| min_x = qMin(p2_x, min_x); |
| max_x = qMax(p1_x, max_x); |
| } else { |
| min_x = qMin(p1_x, min_x); |
| max_x = qMax(p2_x, max_x); |
| } |
| if (p1_y > p2_y) { |
| min_y = qMin(p2_y, min_y); |
| max_y = qMax(p1_y, max_y); |
| } else { |
| min_y = qMin(p1_y, min_y); |
| max_y = qMax(p2_y, max_y); |
| } |
| } |
| buffer->updateBoundingRect(QRectF(min_x, min_y, max_x - min_x, max_y - min_y)); |
| } |
| } |
|
| void QPaintBufferEngine::drawEllipse(const QRectF &r) |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: drawEllipseF:" << r; |
| #endif |
| buffer->addCommand(QPaintBufferPrivate::Cmd_DrawEllipseF, (qreal *) &r, 4, 1); |
| if (buffer->calculateBoundingRect) |
| buffer->updateBoundingRect(r); |
| } |
|
| void QPaintBufferEngine::drawEllipse(const QRect &r) |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: drawEllipseI:" << r; |
| #endif |
| buffer->addCommand(QPaintBufferPrivate::Cmd_DrawEllipseI, (int *) &r, 4, 1); |
| if (buffer->calculateBoundingRect) |
| buffer->updateBoundingRect(r); |
| } |
|
| void QPaintBufferEngine::drawPath(const QPainterPath &path) |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: drawPath: element count:" << path.elementCount(); |
| #endif |
| // ### Path -> QVariant |
| // buffer->addCommand(QPaintBufferPrivate::Cmd_DrawPath, QVariant(path)); |
| QPaintEngineEx::drawPath(path); |
|
| if (buffer->calculateBoundingRect) |
| buffer->updateBoundingRect(path.boundingRect()); |
| } |
|
| void QPaintBufferEngine::drawPoints(const QPoint *points, int pointCount) |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: drawPointsI: " << pointCount; |
| #endif |
| buffer->addCommand(QPaintBufferPrivate::Cmd_DrawPointsI, (int *) points, 2 * pointCount, pointCount); |
|
| if (buffer->calculateBoundingRect) { |
| int min_x = points[0].x(); |
| int min_y = points[0].y(); |
| int max_x = points[0].x()+1; |
| int max_y = points[0].y()+1; |
| for (int i=1; i<pointCount; ++i) { |
| int x = points[i].x(); |
| int y = points[i].y(); |
| min_x = qMin(min_x, x); |
| min_y = qMin(min_y, y); |
| max_x = qMax(max_x, x+1); |
| max_y = qMax(max_y, y+1); |
| } |
| buffer->updateBoundingRect(QRectF(min_x, min_y, max_x - min_x, max_y - min_y)); |
| } |
| } |
|
| void QPaintBufferEngine::drawPoints(const QPointF *points, int pointCount) |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: drawPointsF: " << pointCount; |
| #endif |
| buffer->addCommand(QPaintBufferPrivate::Cmd_DrawPointsF, (qreal *) points, 2 * pointCount, pointCount); |
|
| if (buffer->calculateBoundingRect) { |
| qreal min_x = points[0].x(); |
| qreal min_y = points[0].y(); |
| qreal max_x = points[0].x()+1; |
| qreal max_y = points[0].y()+1; |
| for (int i=1; i<pointCount; ++i) { |
| qreal x = points[i].x(); |
| qreal y = points[i].y(); |
| min_x = qMin(min_x, x); |
| min_y = qMin(min_y, y); |
| max_x = qMax(max_x, x+1); |
| max_y = qMax(max_y, y+1); |
| } |
| buffer->updateBoundingRect(QRectF(min_x, min_y, max_x - min_x, max_y - min_y)); |
| } |
| } |
|
| void QPaintBufferEngine::drawPolygon(const QPoint *pts, int count, PolygonDrawMode mode) |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: drawPolygonI: size:" << count << ", mode:" << mode; |
| #endif |
| if (mode == QPaintEngine::OddEvenMode || mode == QPaintEngine::WindingMode) { |
| QPaintBufferCommand *cmd = buffer->addCommand(QPaintBufferPrivate::Cmd_DrawPolygonI, |
| (int *) pts, 2 * count, count); |
| cmd->extra = mode; |
| } else if (mode == QPaintEngine::PolylineMode) { |
| buffer->addCommand(QPaintBufferPrivate::Cmd_DrawPolylineI, (int *) pts, 2 * count, count); |
| } else { |
| buffer->addCommand(QPaintBufferPrivate::Cmd_DrawConvexPolygonI, (int *) pts, 2 * count, count); |
| } |
|
| if (buffer->calculateBoundingRect) { |
| int min_x = pts[0].x(); |
| int min_y = pts[0].y(); |
| int max_x = pts[0].x(); |
| int max_y = pts[0].y(); |
| for (int i=1; i<count; ++i) { |
| int x = pts[i].x(); |
| int y = pts[i].y(); |
| min_x = qMin(min_x, x); |
| min_y = qMin(min_y, y); |
| max_x = qMax(max_x, x); |
| max_y = qMax(max_y, y); |
| } |
| buffer->updateBoundingRect(QRectF(min_x, min_y, max_x - min_x, max_y - min_y)); |
| } |
| } |
|
| void QPaintBufferEngine::drawPolygon(const QPointF *pts, int count, PolygonDrawMode mode) |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: drawPolygonF: size:" << count << ", mode:" << mode; |
| #endif |
| if (mode == QPaintEngine::OddEvenMode || mode == QPaintEngine::WindingMode) { |
| QPaintBufferCommand *cmd = buffer->addCommand(QPaintBufferPrivate::Cmd_DrawPolygonF, |
| (qreal *) pts, 2 * count, count); |
| cmd->extra = mode; |
| } else if (mode == QPaintEngine::PolylineMode) { |
| buffer->addCommand(QPaintBufferPrivate::Cmd_DrawPolylineF, (qreal *) pts, 2 * count, count); |
| } else { |
| buffer->addCommand(QPaintBufferPrivate::Cmd_DrawConvexPolygonF, (qreal *) pts, 2 * count, count); |
| } |
|
| if (buffer->calculateBoundingRect) { |
| qreal min_x = pts[0].x(); |
| qreal min_y = pts[0].y(); |
| qreal max_x = pts[0].x(); |
| qreal max_y = pts[0].y(); |
| for (int i=1; i<count; ++i) { |
| qreal x = pts[i].x(); |
| qreal y = pts[i].y(); |
| min_x = qMin(min_x, x); |
| min_y = qMin(min_y, y); |
| max_x = qMax(max_x, x); |
| max_y = qMax(max_y, y); |
| } |
| buffer->updateBoundingRect(QRectF(min_x, min_y, max_x - min_x, max_y - min_y)); |
| } |
| } |
|
| void QPaintBufferEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: drawPixmap: src/dest rects " << r << sr; |
| #endif |
| QPaintBufferCommand *cmd = |
| buffer->addCommand(QPaintBufferPrivate::Cmd_DrawPixmapRect, QVariant(pm)); |
| cmd->extra = buffer->addData((qreal *) &r, 4); |
| buffer->addData((qreal *) &sr, 4); |
| if (buffer->calculateBoundingRect) |
| buffer->updateBoundingRect(r); |
| } |
|
| void QPaintBufferEngine::drawPixmap(const QPointF &pos, const QPixmap &pm) |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: drawPixmap: pos:" << pos; |
| #endif |
| QPaintBufferCommand *cmd = |
| buffer->addCommand(QPaintBufferPrivate::Cmd_DrawPixmapPos, QVariant(pm)); |
| cmd->extra = buffer->addData((qreal *) &pos, 2); |
| if (buffer->calculateBoundingRect) |
| buffer->updateBoundingRect(QRectF(pos, pm.size())); |
| } |
|
| void QPaintBufferEngine::drawImage(const QRectF &r, const QImage &image, const QRectF &sr, |
| Qt::ImageConversionFlags /*flags */) |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: drawImage: src/dest rects " << r << sr; |
| #endif |
| QPaintBufferCommand *cmd = |
| buffer->addCommand(QPaintBufferPrivate::Cmd_DrawPixmapRect, QVariant(image)); |
| cmd->extra = buffer->addData((qreal *) &r, 4); |
| buffer->addData((qreal *) &sr, 4); |
| // ### flags... |
| if (buffer->calculateBoundingRect) |
| buffer->updateBoundingRect(r); |
| } |
|
| void QPaintBufferEngine::drawImage(const QPointF &pos, const QImage &image) |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: drawImage: pos:" << pos; |
| #endif |
| QPaintBufferCommand *cmd = |
| buffer->addCommand(QPaintBufferPrivate::Cmd_DrawImagePos, QVariant(image)); |
| cmd->extra = buffer->addData((qreal *) &pos, 2); |
| if (buffer->calculateBoundingRect) |
| buffer->updateBoundingRect(QRectF(pos, image.size())); |
| } |
|
| void QPaintBufferEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &s) |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: drawTiledPixmap: src rect/offset:" << r << s; |
| #endif |
| QPaintBufferCommand *cmd = |
| buffer->addCommand(QPaintBufferPrivate::Cmd_DrawTiledPixmap, QVariant(pm)); |
| cmd->extra = buffer->addData((qreal *) &r, 4); |
| buffer->addData((qreal *) &s, 2); |
| if (buffer->calculateBoundingRect) |
| buffer->updateBoundingRect(r); |
| } |
|
| void QPaintBufferEngine::drawTextItem(const QPointF &pos, const QTextItem &ti) |
| { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: drawTextItem: pos:" << pos << ti.text(); |
| #endif |
| if (m_stream_raw_text_items) { |
| QPaintBufferCommand *cmd = buffer->addCommand(QPaintBufferPrivate::Cmd_DrawTextItem, qVariantFromValue<void *>(new QTextItemIntCopy(ti))); |
|
| QFont font(ti.font()); |
| font.setUnderline(false); |
| font.setStrikeOut(false); |
| font.setOverline(false); |
|
| const QTextItemInt &si = static_cast<const QTextItemInt &>(ti); |
| qreal justificationWidth = 0; |
| if (si.justified) |
| justificationWidth = si.width.toReal(); |
| int renderFlags = ti.renderFlags(); |
| qreal scaleFactor = font.d->dpi/qreal(qt_defaultDpiY()); |
|
| buffer->addData(QVariant(font)); |
| cmd->extra = buffer->addData((qreal *) &pos, 2); |
| buffer->addData((qreal *) &justificationWidth, 1); |
| buffer->addData((qreal *) &scaleFactor, 1); |
| cmd->offset2 = buffer->addData((int *) &renderFlags, 1); |
| } else { |
| QList<QVariant> variants; |
| variants << QVariant(ti.font()) << QVariant(ti.text()); |
| QPaintBufferCommand *cmd = buffer->addCommand(QPaintBufferPrivate::Cmd_DrawText, QVariant(variants)); |
| cmd->extra = buffer->addData((qreal *) &pos, 2); |
| } |
|
| if (buffer->calculateBoundingRect) |
| buffer->updateBoundingRect(QRectF(pos, QSize(ti.width(), ti.ascent() + ti.descent() + 1))); |
| } |
|
|
| void QPaintBufferEngine::setState(QPainterState *s) |
| { |
| if (m_begin_detected) { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: setState: begin, ignoring."; |
| #endif |
| m_begin_detected = false; |
| } else if (m_save_detected) { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: setState: save."; |
| #endif |
| m_save_detected = false; |
| buffer->addCommand(QPaintBufferPrivate::Cmd_Save); |
| } else { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << "QPaintBufferEngine: setState: restore."; |
| #endif |
| buffer->addCommand(QPaintBufferPrivate::Cmd_Restore); |
| } |
|
| QPaintEngineEx::setState(s); |
| } |
|
|
| /*********************************************************************** |
| * |
| * class QPaintBufferPlayback_Painter |
| * |
| */ |
|
| // QFakeDevice is used to create fonts with a custom DPI |
| // |
| class QFakeDevice : public QPaintDevice |
| { |
| public: |
| QFakeDevice() { dpi_x = qt_defaultDpiX(); dpi_y = qt_defaultDpiY(); } |
| void setDpiX(int dpi) { dpi_x = dpi; } |
| void setDpiY(int dpi) { dpi_y = dpi; } |
| QPaintEngine *paintEngine() const { return 0; } |
| int metric(PaintDeviceMetric m) const |
| { |
| switch(m) { |
| case PdmPhysicalDpiX: |
| case PdmDpiX: |
| return dpi_x; |
| case PdmPhysicalDpiY: |
| case PdmDpiY: |
| return dpi_y; |
| default: |
| return QPaintDevice::metric(m); |
| } |
| } |
|
| private: |
| int dpi_x; |
| int dpi_y; |
| }; |
|
|
| void QPainterReplayer::setupTransform(QPainter *_painter) |
| { |
| painter = _painter; |
| m_world_matrix = painter->transform(); |
| m_world_matrix.scale(qreal(painter->device()->logicalDpiX()) / qreal(qt_defaultDpiX()), |
| qreal(painter->device()->logicalDpiY()) / qreal(qt_defaultDpiY())); |
| painter->setTransform(m_world_matrix); |
| } |
|
| void QPainterReplayer::draw(const QPaintBuffer &buffer, QPainter *_painter) |
| { |
| d = buffer.d_ptr; |
| setupTransform(_painter); |
|
| for (int cmdIndex=0; cmdIndex<d->commands.size(); ++cmdIndex) { |
| const QPaintBufferCommand &cmd = d->commands.at(cmdIndex); |
| process(cmd); |
| } |
| } |
|
| void QPainterReplayer::process(const QPaintBufferCommand &cmd) |
| { |
| switch (cmd.id) { |
| case QPaintBufferPrivate::Cmd_Save: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_Save"; |
| #endif |
| painter->save(); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_Restore: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_Restore"; |
| #endif |
| painter->restore(); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_SetPen: { |
| QPen pen = qVariantValue<QPen>(d->variants.at(cmd.offset)); |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_SetPen: " << pen; |
| #endif |
| painter->setPen(pen); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_SetBrush: { |
| QBrush brush = qVariantValue<QBrush>(d->variants.at(cmd.offset)); |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_SetBrush: " << brush; |
| #endif |
| painter->setBrush(brush); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_SetBrushOrigin: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_SetBrushOrigin: " << d->variants.at(cmd.offset).toPointF(); |
| #endif |
| painter->setBrushOrigin(d->variants.at(cmd.offset).toPointF()); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_SetTransform: { |
| QTransform xform = qVariantValue<QTransform>(d->variants.at(cmd.offset)); |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_SetTransform, offset: " << cmd.offset << xform; |
| #endif |
| painter->setTransform(xform * m_world_matrix); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_SetCompositionMode: { |
| QPainter::CompositionMode mode = (QPainter::CompositionMode) cmd.extra; |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_SetCompositionMode, mode: " << mode; |
| #endif |
| painter->setCompositionMode(mode); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_SetRenderHints: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_SetRenderHints, hints: " << cmd.extra; |
| #endif |
| QPainter::RenderHints ph = painter->renderHints(); |
| QPainter::RenderHints nh = (QPainter::RenderHints) cmd.extra; |
| QPainter::RenderHints xored = ph ^ nh; |
| if (xored & QPainter::Antialiasing) |
| painter->setRenderHint(QPainter::Antialiasing, nh & QPainter::Antialiasing); |
| if (xored & QPainter::HighQualityAntialiasing) |
| painter->setRenderHint(QPainter::HighQualityAntialiasing, nh & QPainter::HighQualityAntialiasing); |
| if (xored & QPainter::TextAntialiasing) |
| painter->setRenderHint(QPainter::TextAntialiasing, nh & QPainter::TextAntialiasing); |
| if (xored & QPainter::SmoothPixmapTransform) |
| painter->setRenderHint(QPainter::SmoothPixmapTransform, nh & QPainter::SmoothPixmapTransform); |
| if (xored & QPainter::NonCosmeticDefaultPen) |
| painter->setRenderHint(QPainter::NonCosmeticDefaultPen, nh & QPainter::NonCosmeticDefaultPen); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_SetOpacity: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_SetOpacity: " << d->variants.at(cmd.offset).toDouble(); |
| #endif |
| painter->setOpacity(d->variants.at(cmd.offset).toDouble()); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_SetBackgroundMode: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_SetBackgroundMode: " << cmd.extra; |
| #endif |
| painter->setBackgroundMode((Qt::BGMode)cmd.extra); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawVectorPath: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_DrawVectorPath: size: " << cmd.size |
| // << ", hints:" << d->ints[cmd.offset2+cmd.size] |
| << "pts/elms:" << cmd.offset << cmd.offset2; |
| #endif |
| QVectorPathCmd path(d, cmd); |
| painter->drawPath(path().convertToPainterPath()); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_StrokeVectorPath: { |
| QPen pen = qVariantValue<QPen>(d->variants.at(cmd.extra)); |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_StrokeVectorPath: size: " << cmd.size |
| // << ", hints:" << d->ints[cmd.offset2+cmd.size] |
| << "pts/elms:" << cmd.offset << cmd.offset2; |
| #endif |
| QVectorPathCmd path(d, cmd); |
| painter->strokePath(path().convertToPainterPath(), pen); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_FillVectorPath: { |
| QBrush brush = qVariantValue<QBrush>(d->variants.at(cmd.extra)); |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_FillVectorPath: size: " << cmd.size |
| // << ", hints:" << d->ints[cmd.offset2+cmd.size] |
| << "pts/elms:" << cmd.offset << cmd.offset2 << brush; |
| #endif |
| QVectorPathCmd path(d, cmd); |
| painter->fillPath(path().convertToPainterPath(), brush); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawPolygonF: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_DrawPolygonF, offset: " << cmd.offset << " size: " << cmd.size |
| << " mode: " << cmd.extra |
| << d->floats.at(cmd.offset) |
| << d->floats.at(cmd.offset+1); |
| #endif |
| Qt::FillRule fill = (QPaintEngine::PolygonDrawMode) cmd.extra == QPaintEngine::OddEvenMode |
| ? Qt::OddEvenFill : Qt::WindingFill; |
| painter->drawPolygon((QPointF *) (d->floats.constData() + cmd.offset), cmd.size, fill); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawPolygonI: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_DrawPolygonI, offset: " << cmd.offset << " size: " << cmd.size |
| << " mode: " << cmd.extra |
| << d->ints.at(cmd.offset) |
| << d->ints.at(cmd.offset+1); |
| #endif |
| Qt::FillRule fill = (QPaintEngine::PolygonDrawMode) cmd.extra == QPaintEngine::OddEvenMode |
| ? Qt::OddEvenFill : Qt::WindingFill; |
| painter->drawPolygon((QPoint *) (d->ints.constData() + cmd.offset), cmd.size, fill); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawPolylineF: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_DrawPolylineF, offset: " << cmd.offset << " size: " << cmd.size; |
| #endif |
| painter->drawPolyline((QPointF *) (d->floats.constData() + cmd.offset), cmd.size); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawPolylineI: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_DrawPolylineI, offset: " << cmd.offset << " size: " << cmd.size; |
| #endif |
| painter->drawPolyline((QPoint *) (d->ints.constData() + cmd.offset), cmd.size); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawConvexPolygonF: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_DrawConvexPolygonF, offset: " << cmd.offset << " size: " << cmd.size; |
| #endif |
| painter->drawConvexPolygon((QPointF *) (d->floats.constData() + cmd.offset), cmd.size); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawConvexPolygonI: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_DrawConvexPolygonI, offset: " << cmd.offset << " size: " << cmd.size; |
| #endif |
| painter->drawConvexPolygon((QPoint *) (d->ints.constData() + cmd.offset), cmd.size); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawEllipseF: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_DrawEllipseF, offset: " << cmd.offset; |
| #endif |
| painter->drawEllipse(*(QRectF *)(d->floats.constData() + cmd.offset)); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawEllipseI: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_DrawEllipseI, offset: " << cmd.offset; |
| #endif |
| painter->drawEllipse(*(QRect *)(d->ints.constData() + cmd.offset)); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawLineF: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_DrawLineF, offset: " << cmd.offset << " size: " << cmd.size; |
| #endif |
| painter->drawLines((QLineF *)(d->floats.constData() + cmd.offset), cmd.size); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawLineI: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_DrawLineI, offset: " << cmd.offset << " size: " << cmd.size; |
| #endif |
| painter->drawLines((QLine *)(d->ints.constData() + cmd.offset), cmd.size); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawPointsF: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_DrawPointsF, offset: " << cmd.offset << " size: " << cmd.size; |
| #endif |
| painter->drawPoints((QPointF *)(d->floats.constData() + cmd.offset), cmd.size); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawPointsI: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_DrawPointsI, offset: " << cmd.offset << " size: " << cmd.size; |
| #endif |
| painter->drawPoints((QPoint *)(d->ints.constData() + cmd.offset), cmd.size); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawPixmapRect: { |
| QPixmap pm(d->variants.at(cmd.offset).value<QPixmap>()); |
| QRectF r(d->floats.at(cmd.extra), d->floats.at(cmd.extra+1), |
| d->floats.at(cmd.extra+2), d->floats.at(cmd.extra+3)); |
|
| QRectF sr(d->floats.at(cmd.extra+4), d->floats.at(cmd.extra+5), |
| d->floats.at(cmd.extra+6), d->floats.at(cmd.extra+7)); |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_DrawPixmapRect:" << r << sr; |
| #endif |
| painter->drawPixmap(r, pm, sr); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawPixmapPos: { |
| QPixmap pm(d->variants.at(cmd.offset).value<QPixmap>()); |
| QPointF pos(d->floats.at(cmd.extra), d->floats.at(cmd.extra+1)); |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_DrawPixmapPos:" << pos; |
| #endif |
| painter->drawPixmap(pos, pm); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawTiledPixmap: { |
| QPixmap pm(d->variants.at(cmd.offset).value<QPixmap>()); |
| QRectF r(d->floats.at(cmd.extra), d->floats.at(cmd.extra+1), |
| d->floats.at(cmd.extra+2), d->floats.at(cmd.extra+3)); |
|
| QPointF offset(d->floats.at(cmd.extra+4), d->floats.at(cmd.extra+5)); |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_DrawTiledPixmap:" << r << offset; |
| #endif |
| painter->drawTiledPixmap(r, pm, offset); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawImageRect: { |
| QImage image(d->variants.at(cmd.offset).value<QImage>()); |
| QRectF r(d->floats.at(cmd.extra), d->floats.at(cmd.extra+1), |
| d->floats.at(cmd.extra+2), d->floats.at(cmd.extra+3)); |
| QRectF sr(d->floats.at(cmd.extra+4), d->floats.at(cmd.extra+5), |
| d->floats.at(cmd.extra+6), d->floats.at(cmd.extra+7)); |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_DrawImageRect:" << r << sr; |
| #endif |
| painter->drawImage(r, image, sr); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawImagePos: { |
| QImage image(d->variants.at(cmd.offset).value<QImage>()); |
| QPointF pos(d->floats.at(cmd.extra), d->floats.at(cmd.extra+1)); |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_DrawImagePos:" << pos; |
| #endif |
| painter->drawImage(pos, image); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawRectF: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_DrawRectF, offset: " << cmd.offset; |
| #endif |
| painter->drawRects((QRectF *)(d->floats.constData() + cmd.offset), cmd.size); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawRectI: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_DrawRectI, offset: " << cmd.offset; |
| #endif |
| painter->drawRects((QRect *)(d->ints.constData() + cmd.offset), cmd.size); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_FillRectBrush: { |
| QBrush brush = qVariantValue<QBrush>(d->variants.at(cmd.extra)); |
| QRectF *rect = (QRectF *)(d->floats.constData() + cmd.offset); |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_FillRectBrush, offset: " << cmd.offset << " rect: " << *rect << " brush: " << brush; |
| #endif |
| painter->fillRect(*rect, brush); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_FillRectColor: { |
| QColor color = qVariantValue<QColor>(d->variants.at(cmd.extra)); |
| QRectF *rect = (QRectF *)(d->floats.constData() + cmd.offset); |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_FillRectBrush, offset: " << cmd.offset << " rect: " << *rect << " color: " << color; |
| #endif |
| painter->fillRect(*rect, color); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_SetClipEnabled: { |
| bool clipEnabled = d->variants.at(cmd.offset).toBool(); |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_SetClipEnabled:" << clipEnabled; |
| #endif |
| painter->setClipping(clipEnabled); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_ClipVectorPath: { |
| QVectorPathCmd path(d, cmd); |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_ClipVectorPath:" << path().elementCount(); |
| #endif |
| painter->setClipPath(path().convertToPainterPath(), Qt::ClipOperation(cmd.extra)); |
| break; } |
|
|
| case QPaintBufferPrivate::Cmd_ClipRect: { |
| QRect rect(QPoint(d->ints.at(cmd.offset), d->ints.at(cmd.offset + 1)), |
| QPoint(d->ints.at(cmd.offset + 2), d->ints.at(cmd.offset + 3))); |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_ClipRect:" << rect << cmd.extra; |
| #endif |
| painter->setClipRect(rect, Qt::ClipOperation(cmd.extra)); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_ClipRegion: { |
| QRegion region(d->variants.at(cmd.offset).value<QRegion>()); |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_ClipRegion:" << region.boundingRect() << cmd.extra; |
| #endif |
| painter->setClipRegion(region, Qt::ClipOperation(cmd.extra)); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawText: { |
| QPointF pos(d->floats.at(cmd.extra), d->floats.at(cmd.extra+1)); |
| QList<QVariant> variants(d->variants.at(cmd.offset).value<QList<QVariant> >()); |
|
| QFont font(variants.at(0).value<QFont>()); |
| QString text(variants.at(1).value<QString>()); |
|
| painter->setFont(font); |
| painter->drawText(pos, text); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawTextItem: { |
| QPointF pos(d->floats.at(cmd.extra), d->floats.at(cmd.extra+1)); |
| QTextItemIntCopy *tiCopy = reinterpret_cast<QTextItemIntCopy *>(qVariantValue<void *>(d->variants.at(cmd.offset))); |
| QTextItemInt &ti = (*tiCopy)(); |
| QString text(ti.text()); |
|
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_DrawTextItem:" << pos << " " << text << " " << scaleFactor; |
| #endif |
|
| QFont font(ti.font()); |
| font.setUnderline(false); |
| font.setStrikeOut(false); |
| font.setOverline(false); |
|
| const QTextItemInt &si = static_cast<const QTextItemInt &>(ti); |
| qreal justificationWidth = 0; |
| if (si.justified) |
| justificationWidth = si.width.toReal(); |
| qreal scaleFactor = font.d->dpi/qreal(qt_defaultDpiY()); |
|
| if (scaleFactor != 1.0) { |
| QFont fnt(font); |
| QFakeDevice fake; |
| fake.setDpiX(qRound(scaleFactor*qt_defaultDpiX())); |
| fake.setDpiY(qRound(scaleFactor*qt_defaultDpiY())); |
| font = QFont(fnt, &fake); |
| } |
|
| int flags = Qt::TextSingleLine | Qt::TextDontClip | Qt::TextForceLeftToRight; |
| QSizeF size(1, 1); |
| if (justificationWidth > 0) { |
| size.setWidth(justificationWidth); |
| flags |= Qt::TextJustificationForced; |
| flags |= Qt::AlignJustify; |
| } |
|
| QFontMetrics fm(font); |
| QPointF pt(pos.x(), pos.y() - fm.ascent()); |
| qt_format_text(font, QRectF(pt, size), flags, /*opt*/0, |
| text, /*brect=*/0, /*tabstops=*/0, /*...*/0, /*tabarraylen=*/0, painter); |
| break; } |
| case QPaintBufferPrivate::Cmd_SystemStateChanged: { |
| QRegion systemClip(d->variants.at(cmd.offset).value<QRegion>()); |
|
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> Cmd_SystemStateChanged:" << systemClip; |
| #endif |
|
| painter->paintEngine()->setSystemClip(systemClip); |
| painter->paintEngine()->d_ptr->systemStateChanged(); |
| break; } |
| } |
| } |
|
| void QPaintEngineExReplayer::process(const QPaintBufferCommand &cmd) |
| { |
| Q_ASSERT(painter->paintEngine()->isExtended()); |
| QPaintEngineEx *xengine = static_cast<QPaintEngineEx *>(painter->paintEngine()); |
|
| switch (cmd.id) { |
| case QPaintBufferPrivate::Cmd_SetBrushOrigin: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> ExCmd_SetBrushOrigin: " << d->variants.at(cmd.offset).toPointF(); |
| #endif |
| xengine->state()->brushOrigin = d->variants.at(cmd.offset).toPointF(); |
| xengine->brushOriginChanged(); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_SetCompositionMode: { |
| QPainter::CompositionMode mode = (QPainter::CompositionMode) cmd.extra; |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> ExCmd_SetCompositionMode, mode: " << mode; |
| #endif |
| xengine->state()->composition_mode = mode; |
| xengine->compositionModeChanged(); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_SetOpacity: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> ExCmd_SetOpacity: " << d->variants.at(cmd.offset).toDouble(); |
| #endif |
| xengine->state()->opacity = d->variants.at(cmd.offset).toDouble(); |
| xengine->opacityChanged(); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawVectorPath: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> ExCmd_DrawVectorPath: size: " << cmd.size |
| // << ", hints:" << d->ints[cmd.offset2+cmd.size] |
| << "pts/elms:" << cmd.offset << cmd.offset2; |
| #endif |
| QVectorPathCmd path(d, cmd); |
| xengine->draw(path()); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_StrokeVectorPath: { |
| QPen pen = qVariantValue<QPen>(d->variants.at(cmd.extra)); |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> ExCmd_StrokeVectorPath: size: " << cmd.size |
| // << ", hints:" << d->ints[cmd.offset2+cmd.size] |
| << "pts/elms:" << cmd.offset << cmd.offset2; |
| #endif |
| QVectorPathCmd path(d, cmd); |
| xengine->stroke(path(), pen); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_FillVectorPath: { |
| QBrush brush = qVariantValue<QBrush>(d->variants.at(cmd.extra)); |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> ExCmd_FillVectorPath: size: " << cmd.size |
| // << ", hints:" << d->ints[cmd.offset2+cmd.size] |
| << "pts/elms:" << cmd.offset << cmd.offset2 << brush; |
| #endif |
| QVectorPathCmd path(d, cmd); |
| xengine->fill(path(), brush); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_FillRectBrush: { |
| QBrush brush = qVariantValue<QBrush>(d->variants.at(cmd.extra)); |
| QRectF *rect = (QRectF *)(d->floats.constData() + cmd.offset); |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> ExCmd_FillRectBrush, offset: " << cmd.offset << " rect: " << *rect << " brush: " << brush; |
| #endif |
| xengine->fillRect(*rect, brush); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_FillRectColor: { |
| QColor color = qVariantValue<QColor>(d->variants.at(cmd.extra)); |
| QRectF *rect = (QRectF *)(d->floats.constData() + cmd.offset); |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> ExCmd_FillRectBrush, offset: " << cmd.offset << " rect: " << *rect << " color: " << color; |
| #endif |
| xengine->fillRect(*rect, color); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawPolygonF: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> ExCmd_DrawPolygonF, offset: " << cmd.offset << " size: " << cmd.size |
| << " mode: " << cmd.extra |
| << d->floats.at(cmd.offset) |
| << d->floats.at(cmd.offset+1); |
| #endif |
| xengine->drawPolygon((QPointF *) (d->floats.constData() + cmd.offset), cmd.size, |
| (QPaintEngine::PolygonDrawMode) cmd.extra); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawPolygonI: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> ExCmd_DrawPolygonI, offset: " << cmd.offset << " size: " << cmd.size |
| << " mode: " << cmd.extra |
| << d->ints.at(cmd.offset) |
| << d->ints.at(cmd.offset+1); |
| #endif |
| xengine->drawPolygon((QPoint *) (d->ints.constData() + cmd.offset), cmd.size, |
| (QPaintEngine::PolygonDrawMode) cmd.extra); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawEllipseF: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> ExCmd_DrawEllipseF, offset: " << cmd.offset; |
| #endif |
| xengine->drawEllipse(*(QRectF *)(d->floats.constData() + cmd.offset)); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawEllipseI: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> ExCmd_DrawEllipseI, offset: " << cmd.offset; |
| #endif |
| xengine->drawEllipse(*(QRect *)(d->ints.constData() + cmd.offset)); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawLineF: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> ExCmd_DrawLineF, offset: " << cmd.offset << " size: " << cmd.size; |
| #endif |
| xengine->drawLines((QLineF *)(d->floats.constData() + cmd.offset), cmd.size); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawLineI: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> ExCmd_DrawLineI, offset: " << cmd.offset << " size: " << cmd.size; |
| #endif |
| xengine->drawLines((QLine *)(d->ints.constData() + cmd.offset), cmd.size); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawPointsF: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> ExCmd_DrawPointsF, offset: " << cmd.offset << " size: " << cmd.size; |
| #endif |
| xengine->drawPoints((QPointF *)(d->floats.constData() + cmd.offset), cmd.size); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawPointsI: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> ExCmd_DrawPointsI, offset: " << cmd.offset << " size: " << cmd.size; |
| #endif |
| xengine->drawPoints((QPoint *)(d->ints.constData() + cmd.offset), cmd.size); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawPolylineF: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> ExCmd_DrawPolylineF, offset: " << cmd.offset << " size: " << cmd.size; |
| #endif |
| xengine->drawPolygon((QPointF *) (d->floats.constData() + cmd.offset), cmd.size, QPaintEngine::PolylineMode); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawPolylineI: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> ExCmd_DrawPolylineI, offset: " << cmd.offset << " size: " << cmd.size; |
| #endif |
| xengine->drawPolygon((QPoint *) (d->ints.constData() + cmd.offset), cmd.size, QPaintEngine::PolylineMode); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawRectF: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> ExCmd_DrawRectF, offset: " << cmd.offset << " size: " << cmd.size; |
| #endif |
| xengine->drawRects((QRectF *) (d->floats.constData() + cmd.offset), cmd.size); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_DrawRectI: { |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> ExCmd_DrawRectI, offset: " << cmd.offset << " size: " << cmd.size; |
| #endif |
| xengine->drawRects((QRect *) (d->ints.constData() + cmd.offset), cmd.size); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_SetClipEnabled: { |
| bool clipEnabled = d->variants.at(cmd.offset).toBool(); |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> ExCmd_SetClipEnabled:" << clipEnabled; |
| #endif |
| xengine->state()->clipEnabled = clipEnabled; |
| xengine->clipEnabledChanged(); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_ClipVectorPath: { |
| QVectorPathCmd path(d, cmd); |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> ExCmd_ClipVectorPath:" << path().elementCount(); |
| #endif |
| xengine->clip(path(), Qt::ClipOperation(cmd.extra)); |
| break; } |
|
|
| case QPaintBufferPrivate::Cmd_ClipRect: { |
| QRect rect(QPoint(d->ints.at(cmd.offset), d->ints.at(cmd.offset + 1)), |
| QPoint(d->ints.at(cmd.offset + 2), d->ints.at(cmd.offset + 3))); |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> ExCmd_ClipRect:" << rect << cmd.extra; |
| #endif |
| xengine->clip(rect, Qt::ClipOperation(cmd.extra)); |
| break; } |
|
| case QPaintBufferPrivate::Cmd_ClipRegion: { |
| QRegion region(d->variants.at(cmd.offset).value<QRegion>()); |
| #ifdef QPAINTBUFFER_DEBUG_DRAW |
| qDebug() << " -> ExCmd_ClipRegion:" << region.boundingRect() << cmd.extra; |
| #endif |
| xengine->clip(region, Qt::ClipOperation(cmd.extra)); |
| break; } |
|
| default: |
| QPainterReplayer::process(cmd); |
| break; |
| } |
| } |
|
| QPaintBufferResource::QPaintBufferResource(FreeFunc f, QObject *parent) : QObject(parent), free(f) |
| { |
| connect(QPaintBufferSignalProxy::instance(), SIGNAL(aboutToDestroy(const QPaintBufferPrivate *)), this, SLOT(remove(const QPaintBufferPrivate *))); |
| } |
|
| QPaintBufferResource::~QPaintBufferResource() |
| { |
| for (Cache::iterator it = m_cache.begin(); it != m_cache.end(); ++it) |
| free(it.value()); |
| } |
|
| void QPaintBufferResource::insert(const QPaintBufferPrivate *key, void *value) |
| { |
| Cache::iterator it = m_cache.find(key); |
| if (it != m_cache.end()) { |
| free(it.value()); |
| it.value() = value; |
| } else { |
| m_cache.insert(key, value); |
| } |
| } |
|
| void *QPaintBufferResource::value(const QPaintBufferPrivate *key) |
| { |
| Cache::iterator it = m_cache.find(key); |
| if (it != m_cache.end()) |
| return it.value(); |
| return 0; |
| } |
|
| void QPaintBufferResource::remove(const QPaintBufferPrivate *key) |
| { |
| Cache::iterator it = m_cache.find(key); |
| if (it != m_cache.end()) { |
| free(it.value()); |
| m_cache.erase(it); |
| } |
| } |
|
| QDataStream &operator<<(QDataStream &stream, const QPaintBufferCommand &command) |
| { |
| quint32 id = command.id; |
| quint32 size = command.size; |
| stream << id << size; |
| stream << command.offset << command.offset2 << command.extra; |
| return stream; |
| } |
|
| QDataStream &operator>>(QDataStream &stream, QPaintBufferCommand &command) |
| { |
| quint32 id; |
| quint32 size; |
| stream >> id >> size; |
| stream >> command.offset >> command.offset2 >> command.extra; |
| command.id = id; |
| command.size = size; |
| return stream; |
| } |
|
| QDataStream &operator<<(QDataStream &stream, const QPaintBuffer &buffer) |
| { |
| stream << buffer.d_ptr->ints; |
| stream << buffer.d_ptr->floats; |
| stream << buffer.d_ptr->variants; |
| stream << buffer.d_ptr->commands; |
| stream << buffer.d_ptr->boundingRect; |
|
| return stream; |
| } |
|
| QDataStream &operator>>(QDataStream &stream, QPaintBuffer &buffer) |
| { |
| stream >> buffer.d_ptr->ints; |
| stream >> buffer.d_ptr->floats; |
| stream >> buffer.d_ptr->variants; |
| stream >> buffer.d_ptr->commands; |
| stream >> buffer.d_ptr->boundingRect; |
|
| return stream; |
| } |