From 71e661ffead018735a9571a0c9d91b33b0c56912 Mon Sep 17 00:00:00 2001 From: Charles Yin Date: Fri, 24 Jun 2011 11:10:34 +1000 Subject: [PATCH] add drawRegion signal for canvas item Change-Id: I8dadcb292b5c99d5f520672ab02db3490b21e8fa --- src/declarative/items/qsgcanvasitem.cpp | 15 ++ src/declarative/items/qsgcanvasitem_p.h | 5 +- src/declarative/items/qsgcontext2d.cpp | 374 ++------------------------------ src/declarative/items/qsgcontext2d_p.h | 5 - 4 files changed, 37 insertions(+), 362 deletions(-) diff --git a/src/declarative/items/qsgcanvasitem.cpp b/src/declarative/items/qsgcanvasitem.cpp index eddaf95..a37f939 100644 --- a/src/declarative/items/qsgcanvasitem.cpp +++ b/src/declarative/items/qsgcanvasitem.cpp @@ -94,11 +94,26 @@ void QSGCanvasItem::paint(QPainter *painter) Q_D(QSGCanvasItem); if (d->context) { + emit drawRegion(getContext(), QRect(0, 0, width(), height())); d->context->paint(painter); emit canvasUpdated(); } } +void QSGCanvasItem::componentComplete() +{ + const QMetaObject *metaObject = this->metaObject(); + int propertyCount = metaObject->propertyCount(); + int requestPaintMethod = metaObject->indexOfMethod("requestPaint()"); + for (int ii = QSGCanvasItem::staticMetaObject.propertyCount(); ii < propertyCount; ++ii) { + QMetaProperty p = metaObject->property(ii); + if (p.hasNotifySignal()) + QMetaObject::connect(this, p.notifySignalIndex(), this, requestPaintMethod, 0, 0); + } + QSGPaintedItem::componentComplete(); +} + + QDeclarativeV8Handle QSGCanvasItem::getContext(const QString &contextId) { Q_D(QSGCanvasItem); diff --git a/src/declarative/items/qsgcanvasitem_p.h b/src/declarative/items/qsgcanvasitem_p.h index 1845a6a..7949ea6 100644 --- a/src/declarative/items/qsgcanvasitem_p.h +++ b/src/declarative/items/qsgcanvasitem_p.h @@ -65,8 +65,10 @@ public: QSGCanvasItem(QSGItem *parent = 0); ~QSGCanvasItem(); -signals: +Q_SIGNALS: void canvasUpdated(); + void drawRegion(QDeclarativeV8Handle context, const QRect ®ion); + public Q_SLOTS: QString toDataURL(const QString& type = QLatin1String("image/png")) const; QDeclarativeV8Handle getContext(const QString & = QLatin1String("2d")); @@ -77,6 +79,7 @@ public Q_SLOTS: protected: void paint(QPainter *painter); + virtual void componentComplete(); private: Q_DECLARE_PRIVATE(QSGCanvasItem) friend class QSGContext2D; diff --git a/src/declarative/items/qsgcontext2d.cpp b/src/declarative/items/qsgcontext2d.cpp index c694cf3..9f335f9 100644 --- a/src/declarative/items/qsgcontext2d.cpp +++ b/src/declarative/items/qsgcontext2d.cpp @@ -412,6 +412,17 @@ static v8::Handle ctx2d_restore(const v8::Arguments &args) return v8::Undefined(); } +static v8::Handle ctx2d_reset(const v8::Arguments &args) +{ + QV8Context2DResource *r = v8_resource_cast(args.This()); + if (!r || !r->context) + V8THROW_ERROR("Not a Context2D object"); + + r->context->reset(); + + return v8::Undefined(); +} + static v8::Handle ctx2d_save(const v8::Arguments &args) { QV8Context2DResource *r = v8_resource_cast(args.This()); @@ -3122,6 +3133,7 @@ QSGContext2DEngineData::QSGContext2DEngineData(QV8Engine *engine) ft->PrototypeTemplate()->Set(v8::String::New("sync"), V8FUNCTION(ctx2d_sync, engine)); ft->PrototypeTemplate()->SetAccessor(v8::String::New("canvas"), ctx2d_canvas, 0, v8::External::Wrap(engine)); ft->PrototypeTemplate()->Set(v8::String::New("restore"), V8FUNCTION(ctx2d_restore, engine)); + ft->PrototypeTemplate()->Set(v8::String::New("reset"), V8FUNCTION(ctx2d_reset, engine)); ft->PrototypeTemplate()->Set(v8::String::New("save"), V8FUNCTION(ctx2d_save, engine)); ft->PrototypeTemplate()->Set(v8::String::New("rotate"), V8FUNCTION(ctx2d_rotate, engine)); ft->PrototypeTemplate()->Set(v8::String::New("scale"), V8FUNCTION(ctx2d_scale, engine)); @@ -3218,353 +3230,6 @@ void QSGContext2D::release() } } - -bool QSGContext2D::inWorkerThread() const -{ - Q_D(const QSGContext2D); - return d->agentData != 0; -} -const QString& QSGContext2D::agentScript() const -{ - static QString script; - if (script.isEmpty()) { - script = QString::fromLatin1( - "function CanvasImageData(w, h, d) {" - " this.width = w;" - " this.height = h;" - " this.data = d;" - "}" - "function Context2DAgent(_ctx2d) {" - " this._ctx = _ctx2d;" - " this._fillColor = '#000000';" - " this._fillStyle = '#000000';" - " this._strokeColor = '#000000';" - " this._strokeStyle = '#000000';" - " this._globalCompositeOperation = \"source-over\";" - " this._commands = [];" - " this.createImageData = function() {" - " var d = null;" - " if (arguments.length == 1 && arguments[0] instanceof CanvasImageData) {" - " d = new CanvasImageData(arguments[0].width," - " arguments[0].height," - " new Array(arguments[0].width * arguments[0].height * 4));" - " } else if (arguments.length == 2) {" - " d = new CanvasImageData(arguments[0], arguments[1], new Array(arguments[0] * arguments[1] * 4));" - " }" - " if (d)" - " for (var i=0; i= dirtyX && x < dirtyX+dirtyWidth" - " && y >= dirtyY && y < dirtyY+dirtyHeight;" - " });" - " this._commands.push([%2, filteredData, dx, dy, dirtyWidth, dirtyHeight]);" - " }" - "};").arg(PutImageData).arg(PutImageData)); - script.append(QString::fromLatin1("}")); - } - return script; -} - -QSGContext2D *QSGContext2D::agent() -{ - Q_D(QSGContext2D); - - if (d->agent) - return d->agent; - - d->agent = new QSGContext2D(this, new QSGContext2DWorkerAgent); - connect(this, SIGNAL(painted()), d->agent, SIGNAL(painted())); - d->agent->setSize(size()); - return d->agent; - -} void QSGContext2D::processCommands(const QScriptValue& commands) { #ifdef QSGCANVASITEM_DEBUG @@ -3885,10 +3550,8 @@ void QSGContext2D::paint(QPainter* p) switch (cmd) { case UpdateMatrix: { -// qDebug() << "update matrix from " << d->state.matrix << " to " << d->matrixes[matrix_idx]; - //p->setWorldTransform(transform * QTransform(d->matrixes[matrix_idx++]), false); - //p->setMatrix(d->matrixes[matrix_idx++]); d->state.matrix = d->matrixes[matrix_idx++]; + p->setMatrix(d->state.matrix); break; } case ClearRect: @@ -3906,7 +3569,6 @@ void QSGContext2D::paint(QPainter* p) qreal y = d->reals[real_idx++]; qreal w = d->reals[real_idx++]; qreal h = d->reals[real_idx++]; -// qDebug() << "fillRect(" << x << y << w << h << ")"; if (d->hasShadow()) d->fillRectShadow(p, QRectF(x, y, w, h)); else @@ -3940,6 +3602,7 @@ void QSGContext2D::paint(QPainter* p) case Fill: { QPainterPath path = d->pathes[path_idx++]; + //qDebug() << "fill path:" << path.elementCount(); if (d->hasShadow()) d->fillShadowPath(p,path); else @@ -3948,8 +3611,10 @@ void QSGContext2D::paint(QPainter* p) } case Stroke: { - p->setMatrix(d->state.matrix); - QPainterPath path = d->state.matrix.inverted().map(d->pathes[path_idx++]); + //p->setMatrix(d->state.matrix); + //QPainterPath path = d->state.matrix.inverted().map(d->pathes[path_idx++]); + //qDebug() << "stroke path:" << path.elementCount(); + QPainterPath path = d->pathes[path_idx++]; if (d->hasShadow()) d->strokeShadowPath(p,path); else @@ -4173,9 +3838,6 @@ void QSGContext2D::setCachedImage(const QImage& image) d->waitingForPainting = false; } #endif - if (inWorkerThread()) { - d->agent->setCachedImage(image); - } } void QSGContext2D::clear() diff --git a/src/declarative/items/qsgcontext2d_p.h b/src/declarative/items/qsgcontext2d_p.h index 4de9fc1..6124f41 100644 --- a/src/declarative/items/qsgcontext2d_p.h +++ b/src/declarative/items/qsgcontext2d_p.h @@ -339,11 +339,6 @@ public: Sync() : QEvent(QEvent::User) {} QSGContext2DWorkerAgent *data; }; - inline bool inWorkerThread() const; - QSGContext2D *agent(); - const QString& agentScript() const; - - struct State { QMatrix matrix; QPainterPath clipPath; -- 2.7.4