aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/declarative/canvas/svgpath/tiger.js8
-rw-r--r--examples/declarative/canvas/svgpath/tiger.qml86
-rw-r--r--src/declarative/items/qsgcanvasitem.cpp119
-rw-r--r--src/declarative/items/qsgcanvasitem_p.h20
-rw-r--r--src/declarative/items/qsgcontext2d.cpp427
-rw-r--r--src/declarative/items/qsgcontext2d_p.h19
-rw-r--r--src/declarative/items/qsgcontext2d_p_p.h4
7 files changed, 490 insertions, 193 deletions
diff --git a/examples/declarative/canvas/svgpath/tiger.js b/examples/declarative/canvas/svgpath/tiger.js
index 2695cd52fe..d8657b5abe 100644
--- a/examples/declarative/canvas/svgpath/tiger.js
+++ b/examples/declarative/canvas/svgpath/tiger.js
@@ -724,6 +724,7 @@ var tiger = [
function draw(ctx, frame)
{
+ var startTime = new Date();
var totalPaths = tiger.length;
if (frame > totalPaths)
@@ -731,14 +732,12 @@ function draw(ctx, frame)
ctx.reset();
ctx.globalCompositeOperation = "source-over";
ctx.fillStyle = "rgba(0,0,0,0)";
- //ctx.fillRect(0, 0, 600, 600);
ctx.fillRect(0, 0, 1900, 1200);
ctx.strokeColor = Qt.rgba(133, 133, 133,1);
ctx.lineWidth = 1;
- //ctx.translate(200, 200);
ctx.translate(750, 350);
- ctx.scale(2,2);
+ ctx.scale(5,5);
for (var i = 0; i < frame; i++) {
if (tiger[i].width != undefined)
ctx.lineWidth = tiger[i].width;
@@ -756,6 +755,9 @@ function draw(ctx, frame)
ctx.stroke();
}
}
+ var endTime = new Date();
+ console.log("Javascript time:" + (endTime.valueOf() - startTime.valueOf()));
+
}
diff --git a/examples/declarative/canvas/svgpath/tiger.qml b/examples/declarative/canvas/svgpath/tiger.qml
index 96d19d3dba..77161e7c46 100644
--- a/examples/declarative/canvas/svgpath/tiger.qml
+++ b/examples/declarative/canvas/svgpath/tiger.qml
@@ -5,29 +5,81 @@ Canvas {
id:canvas
width:1900
height:1100
+ fillColor:"#000000"
+ focus:true
+ renderTarget:PaintedItem.FramebufferObject
property int frame:0
-
- Timer {
- repeat:true
- interval:100
- running:true
- onTriggered: {
+ property date paintingTime
+ Component.onCompleted: {
+ canvas.frame++;
+ canvas.requestPaint();
+ }
+ onPainted: {
+ var endPaintingTime = new Date;
+ console.log("painting time:" + (endPaintingTime.valueOf() - canvas.paintingTime.valueOf()));
canvas.frame++;
if (canvas.frame > Tiger.tiger.length) {
- canvas.frame = 0;
+// canvas.frame = 0;
+ canvas.frame = Tiger.tiger.length;
} else {
- Tiger.draw(canvas.getContext(), canvas.frame);
+ canvas.requestPaint();
}
- }
}
-/*
- onDrawRegion:{
+ onPaint:{
+ canvas.paintingTime = new Date();
Tiger.draw(context, canvas.frame);
}
-Text {
- anchors.top : parent.top
- font.pixelSize : 30
- text: "drawing path:" + canvas.frame + "/" + Tiger.tiger.length;
-}
-*/
+ Keys.onPressed : {
+ if (event.key == Qt.Key_Plus) {
+ canvas.contentsScale *= 1.5;
+ }
+ if (event.key == Qt.Key_Minus) {
+ canvas.contentsScale *= 0.7;
+ }
+ if (event.key == Qt.Key_Left) {
+ canvas.canvasX +=60;
+ }
+ if (event.key == Qt.Key_Right) {
+ canvas.canvasX -= 60;
+ }
+ if (event.key == Qt.Key_Up) {
+ canvas.canvasY += 40;
+ }
+ if (event.key == Qt.Key_Down) {
+ canvas.canvasY -= 40;
+ }
+
+ canvas.requestPaint();
+ }
+ Rectangle {
+ anchors.bottom : parent.bottom
+ color: "white"
+ opacity:0.7
+ height:50
+ width:canvas.width
+ radius:4
+ Text {
+ anchors.bottom : parent.bottom
+ font.pixelSize : 30
+ text: "drawing path:" + canvas.frame + "/" + Tiger.tiger.length
+ + " moving to:(" + canvas.canvasX + "," + canvas.canvasY + ")"
+ + " scale:" + canvas.contentsScale;
+ }
+ }
+
+ MouseArea {
+ id:mouseArea
+ anchors.fill:parent
+ property real pressedX;
+ property real pressedY;
+ onPressed: {
+ pressedX = mouseX;
+ pressedY = mouseY;
+ }
+ onPositionChanged : {
+ canvas.canvasX = mouseX - pressedX;
+ canvas.canvasY = mouseY - pressedY;
+ canvas.requestPaint();
+ }
+ }
}
diff --git a/src/declarative/items/qsgcanvasitem.cpp b/src/declarative/items/qsgcanvasitem.cpp
index f346db4c66..0bd9a47d8d 100644
--- a/src/declarative/items/qsgcanvasitem.cpp
+++ b/src/declarative/items/qsgcanvasitem.cpp
@@ -58,6 +58,10 @@ public:
QSGCanvasItemPrivate();
~QSGCanvasItemPrivate();
QSGContext2D* context;
+ QList<QRect> dirtyRegions;
+ QRect unitedDirtyRegion;
+ qreal canvasX;
+ qreal canvasY;
};
@@ -67,6 +71,9 @@ public:
QSGCanvasItemPrivate::QSGCanvasItemPrivate()
: QSGPaintedItemPrivate()
, context(0)
+ , unitedDirtyRegion()
+ , canvasX(0.)
+ , canvasY(0.)
{
}
@@ -74,6 +81,40 @@ QSGCanvasItemPrivate::~QSGCanvasItemPrivate()
{
}
+
+void QSGCanvasItem::setCanvasX(qreal x)
+{
+ Q_D(QSGCanvasItem);
+ if (d->canvasX != x) {
+ d->canvasX = x;
+ emit canvasXChanged();
+ }
+}
+void QSGCanvasItem::setCanvasY(qreal y)
+{
+ Q_D(QSGCanvasItem);
+ if (d->canvasY != y) {
+ d->canvasY = y;
+ emit canvasYChanged();
+ }
+}
+
+qreal QSGCanvasItem::canvasX() const
+{
+ Q_D(const QSGCanvasItem);
+ return d->canvasX;
+}
+qreal QSGCanvasItem::canvasY() const
+{
+ Q_D(const QSGCanvasItem);
+ return d->canvasY;
+}
+QPointF QSGCanvasItem::canvasPos() const
+{
+ Q_D(const QSGCanvasItem);
+ return QPointF(d->canvasX, d->canvasY);
+}
+
/*!
Constructs a QSGCanvasItem with the given \a parent item.
*/
@@ -92,11 +133,13 @@ QSGCanvasItem::~QSGCanvasItem()
void QSGCanvasItem::paint(QPainter *painter)
{
Q_D(QSGCanvasItem);
+ if (d->context && d->context->isDirty()) {
+ painter->setWindow(-d->canvasX, -d->canvasY, d->width, d->height);
+ painter->setViewport(0, 0, d->width, d->height);
+ painter->scale(d->contentsScale, d->contentsScale);
- if (d->context) {
- emit drawRegion(getContext(), QRect(0, 0, width(), height()));
d->context->paint(painter);
- emit canvasUpdated();
+ emit painted();
}
}
@@ -104,36 +147,59 @@ void QSGCanvasItem::componentComplete()
{
const QMetaObject *metaObject = this->metaObject();
int propertyCount = metaObject->propertyCount();
- int requestPaintMethod = metaObject->indexOfMethod("requestPaint()");
+ int requestPaintMethod = metaObject->indexOfMethod("requestPaint(const QRect&)");
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);
}
+
+ createContext();
+
QSGPaintedItem::componentComplete();
}
+void QSGCanvasItem::createContext()
+{
+ Q_D(QSGCanvasItem);
+
+ delete d->context;
+
+ d->context = new QSGContext2D(this);
+
+ QV8Engine *e = QDeclarativeEnginePrivate::getV8Engine(qmlEngine(this));
+ d->context->setV8Engine(e);
+}
QDeclarativeV8Handle QSGCanvasItem::getContext(const QString &contextId)
{
Q_D(QSGCanvasItem);
+ Q_UNUSED(contextId);
- if (contextId == QLatin1String("2d")) {
- if (!d->context) {
- QV8Engine *e = QDeclarativeEnginePrivate::getV8Engine(qmlEngine(this));
- d->context = new QSGContext2D(this);
- d->context->setV8Engine(e);
- connect(d->context, SIGNAL(changed()), this, SLOT(requestPaint()));
- }
- return QDeclarativeV8Handle::fromHandle(d->context->v8value());
- }
+ if (d->context)
+ return QDeclarativeV8Handle::fromHandle(d->context->v8value());
return QDeclarativeV8Handle::fromHandle(v8::Undefined());
}
-void QSGCanvasItem::requestPaint()
+void QSGCanvasItem::requestPaint(const QRect& r)
{
- //TODO:update(d->context->dirtyRect());
- update();
+ Q_D(QSGCanvasItem);
+
+ QRect region;
+ if (!r.isValid())
+ region = QRect(d->canvasX, d->canvasY, d->width, d->height);
+ else
+ region = r;
+
+ foreach (const QRect& rect, d->dirtyRegions) {
+ if (rect.contains(region))
+ return;
+ }
+
+ d->unitedDirtyRegion = d->unitedDirtyRegion.unite(region);
+ d->dirtyRegions.append(region);
+ polish();
+ update(d->unitedDirtyRegion);
}
bool QSGCanvasItem::save(const QString &filename) const
@@ -147,6 +213,26 @@ bool QSGCanvasItem::save(const QString &filename) const
return false;
}
+void QSGCanvasItem::updatePolish()
+{
+ Q_D(QSGCanvasItem);
+ QDeclarativeV8Handle context = QDeclarativeV8Handle::fromHandle(d->context->v8value());
+
+ d->context->setValid(true);
+
+ // d->context->setTileRect(QRectF(d->canvasX, d->canvasY, d->width, d->height).intersected(QRectF(0, 0, d->width, d->height)));
+ // d->context->setTileRect(QRectF(d->canvasX, d->canvasY, d->width, d->height));
+
+ foreach (const QRect& region, d->dirtyRegions) {
+ emit paint(context, region);
+ }
+ d->dirtyRegions.clear();
+
+ d->context->setValid(false);
+
+ QSGPaintedItem::updatePolish();
+}
+
QString QSGCanvasItem::toDataURL(const QString& mimeType) const
{
Q_D(const QSGCanvasItem);
@@ -182,5 +268,4 @@ QString QSGCanvasItem::toDataURL(const QString& mimeType) const
}
return QLatin1String("data:,");
}
-
QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgcanvasitem_p.h b/src/declarative/items/qsgcanvasitem_p.h
index 71358c4d9e..9a6ccc27ed 100644
--- a/src/declarative/items/qsgcanvasitem_p.h
+++ b/src/declarative/items/qsgcanvasitem_p.h
@@ -61,26 +61,36 @@ class QSGCanvasItemPrivate;
class QSGCanvasItem : public QSGPaintedItem
{
Q_OBJECT
+ Q_PROPERTY(QPointF canvasPos READ canvasPos FINAL)
+ Q_PROPERTY(qreal canvasX READ canvasX WRITE setCanvasX NOTIFY canvasXChanged FINAL)
+ Q_PROPERTY(qreal canvasY READ canvasY WRITE setCanvasY NOTIFY canvasYChanged FINAL)
public:
QSGCanvasItem(QSGItem *parent = 0);
~QSGCanvasItem();
-
+ void setCanvasX(qreal x);
+ void setCanvasY(qreal y);
+ qreal canvasX() const;
+ qreal canvasY() const;
+ QPointF canvasPos() const;
Q_SIGNALS:
- void canvasUpdated();
- void drawRegion(QDeclarativeV8Handle context, const QRect &region);
-
+ void painted();
+ void paint(QDeclarativeV8Handle context, const QRect &region);
+ void canvasXChanged();
+ void canvasYChanged();
public Q_SLOTS:
QString toDataURL(const QString& type = QLatin1String("image/png")) const;
QDeclarativeV8Handle getContext(const QString & = QLatin1String("2d"));
- void requestPaint();
+ void requestPaint(const QRect& region = QRect());
// Save current canvas to disk
bool save(const QString& filename) const;
protected:
+ void updatePolish();
void paint(QPainter *painter);
virtual void componentComplete();
private:
+ void createContext();
Q_DECLARE_PRIVATE(QSGCanvasItem)
friend class QSGContext2D;
};
diff --git a/src/declarative/items/qsgcontext2d.cpp b/src/declarative/items/qsgcontext2d.cpp
index f3371ed982..6f3b117661 100644
--- a/src/declarative/items/qsgcontext2d.cpp
+++ b/src/declarative/items/qsgcontext2d.cpp
@@ -82,10 +82,20 @@ void copy_vector(QVector<T>* dst, const QVector<T>& src)
// But it really should be considered private API
void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0);
void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed = 0);
-
+static bool parsePathDataFast(const QString &dataStr, QPainterPath &path);
#define DEGREES(t) ((t) * 180.0 / Q_PI)
#define qClamp(val, min, max) qMin(qMax(val, min), max)
+#define CHECK_CONTEXT(r) if (!r || !r->context) \
+ V8THROW_ERROR("Not a Context2D object"); \
+ if (!r->context->valid()) \
+ V8THROW_ERROR("Context2D object is out of scope, please only access context2d APIs from onPaint method.");
+
+#define CHECK_CONTEXT_SETTER(r) if (!r || !r->context) \
+ V8THROW_ERROR_SETTER("Not a Context2D object"); \
+ if (!r->context->valid()) \
+ V8THROW_ERROR_SETTER("Context2D object is out of scope, please only access context2d APIs from onPaint method.");
+
static inline int extractInt(const char **name)
{
int result = 0;
@@ -380,8 +390,8 @@ public:
static v8::Handle<v8::Value> ctx2d_sync(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
r->context->sync();
@@ -392,8 +402,8 @@ static v8::Handle<v8::Value> ctx2d_sync(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_canvas(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
QV8Engine *engine = V8ENGINE_ACCESSOR();
@@ -404,8 +414,8 @@ static v8::Handle<v8::Value> ctx2d_canvas(v8::Local<v8::String>, const v8::Acces
static v8::Handle<v8::Value> ctx2d_restore(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
r->context->restore();
@@ -415,8 +425,8 @@ static v8::Handle<v8::Value> ctx2d_restore(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_reset(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
r->context->reset();
@@ -426,8 +436,8 @@ static v8::Handle<v8::Value> ctx2d_reset(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_save(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
r->context->save();
@@ -438,8 +448,8 @@ static v8::Handle<v8::Value> ctx2d_save(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_rotate(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
if (args.Length() == 1)
r->context->rotate(args[0]->NumberValue());
@@ -450,8 +460,8 @@ static v8::Handle<v8::Value> ctx2d_rotate(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_scale(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
if (args.Length() == 2)
r->context->scale(args[0]->NumberValue(), args[1]->NumberValue());
@@ -462,8 +472,8 @@ static v8::Handle<v8::Value> ctx2d_scale(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_setTransform(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
if (args.Length() == 6) {
r->context->setTransform(args[0]->NumberValue(),
@@ -480,8 +490,8 @@ static v8::Handle<v8::Value> ctx2d_setTransform(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_transform(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
if (args.Length() == 6) {
r->context->transform(args[0]->NumberValue(),
@@ -498,8 +508,8 @@ static v8::Handle<v8::Value> ctx2d_transform(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_translate(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
if (args.Length() == 2) {
r->context->translate(args[0]->NumberValue(),
@@ -514,8 +524,8 @@ static v8::Handle<v8::Value> ctx2d_translate(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_globalAlpha(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
return v8::Number::New(r->context->globalAlpha());
}
@@ -523,18 +533,30 @@ static v8::Handle<v8::Value> ctx2d_globalAlpha(v8::Local<v8::String>, const v8::
static void ctx2d_globalAlpha_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR_SETTER("Not a Context2D object");
+ CHECK_CONTEXT_SETTER(r)
r->context->setGlobalAlpha(value->NumberValue());
}
+// read only property to indicate the validation of the context object
+static v8::Handle<v8::Value> ctx2d_valid(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+ CHECK_CONTEXT(r)
+
+
+ QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+ return v8::Boolean::New(r->context->valid());
+}
+
+
// string getter/setter default "source-over"
static v8::Handle<v8::Value> ctx2d_globalCompositeOperation(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
QV8Engine *engine = V8ENGINE_ACCESSOR();
@@ -544,8 +566,7 @@ static v8::Handle<v8::Value> ctx2d_globalCompositeOperation(v8::Local<v8::String
static void ctx2d_globalCompositeOperation_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR_SETTER("Not a Context2D object");
+ CHECK_CONTEXT_SETTER(r)
QV8Engine *engine = V8ENGINE_ACCESSOR();
@@ -557,8 +578,8 @@ static void ctx2d_globalCompositeOperation_set(v8::Local<v8::String>, v8::Local<
static v8::Handle<v8::Value> ctx2d_fillStyle(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
QV8Engine *engine = V8ENGINE_ACCESSOR();
@@ -568,8 +589,7 @@ static v8::Handle<v8::Value> ctx2d_fillStyle(v8::Local<v8::String>, const v8::Ac
static void ctx2d_fillStyle_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR_SETTER("Not a Context2D object");
+ CHECK_CONTEXT_SETTER(r)
QV8Engine *engine = V8ENGINE_ACCESSOR();
@@ -581,8 +601,8 @@ static void ctx2d_fillStyle_set(v8::Local<v8::String>, v8::Local<v8::Value> valu
static v8::Handle<v8::Value> ctx2d_fillColor(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
QV8Engine *engine = V8ENGINE_ACCESSOR();
@@ -592,8 +612,7 @@ static v8::Handle<v8::Value> ctx2d_fillColor(v8::Local<v8::String>, const v8::Ac
static void ctx2d_fillColor_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR_SETTER("Not a Context2D object");
+ CHECK_CONTEXT_SETTER(r)
QV8Engine *engine = V8ENGINE_ACCESSOR();
@@ -604,8 +623,8 @@ static void ctx2d_fillColor_set(v8::Local<v8::String>, v8::Local<v8::Value> valu
v8::Handle<v8::Value> ctx2d_strokeStyle(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
QV8Engine *engine = V8ENGINE_ACCESSOR();
@@ -615,8 +634,7 @@ v8::Handle<v8::Value> ctx2d_strokeStyle(v8::Local<v8::String>, const v8::Accesso
static void ctx2d_strokeStyle_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR_SETTER("Not a Context2D object");
+ CHECK_CONTEXT_SETTER(r)
QV8Engine *engine = V8ENGINE_ACCESSOR();
@@ -628,8 +646,8 @@ static void ctx2d_strokeStyle_set(v8::Local<v8::String>, v8::Local<v8::Value> va
v8::Handle<v8::Value> ctx2d_strokeColor(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
QV8Engine *engine = V8ENGINE_ACCESSOR();
@@ -639,8 +657,7 @@ v8::Handle<v8::Value> ctx2d_strokeColor(v8::Local<v8::String>, const v8::Accesso
static void ctx2d_strokeColor_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR_SETTER("Not a Context2D object");
+ CHECK_CONTEXT_SETTER(r)
QV8Engine *engine = V8ENGINE_ACCESSOR();
@@ -650,8 +667,8 @@ static void ctx2d_strokeColor_set(v8::Local<v8::String>, v8::Local<v8::Value> va
static v8::Handle<v8::Value> ctx2d_createLinearGradient(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
QV8Engine *engine = V8ENGINE();
@@ -669,8 +686,8 @@ static v8::Handle<v8::Value> ctx2d_createLinearGradient(const v8::Arguments &arg
static v8::Handle<v8::Value> ctx2d_createRadialGradient(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
QV8Engine *engine = V8ENGINE();
@@ -698,8 +715,8 @@ static v8::Handle<v8::Value> ctx2d_createPattern(const v8::Arguments &args)
v8::Handle<v8::Value> ctx2d_lineCap(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
QV8Engine *engine = V8ENGINE_ACCESSOR();
@@ -709,8 +726,7 @@ v8::Handle<v8::Value> ctx2d_lineCap(v8::Local<v8::String>, const v8::AccessorInf
static void ctx2d_lineCap_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR_SETTER("Not a Context2D object");
+ CHECK_CONTEXT_SETTER(r)
QV8Engine *engine = V8ENGINE_ACCESSOR();
@@ -721,8 +737,8 @@ static void ctx2d_lineCap_set(v8::Local<v8::String>, v8::Local<v8::Value> value,
v8::Handle<v8::Value> ctx2d_lineJoin(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
QV8Engine *engine = V8ENGINE_ACCESSOR();
@@ -732,8 +748,7 @@ v8::Handle<v8::Value> ctx2d_lineJoin(v8::Local<v8::String>, const v8::AccessorIn
static void ctx2d_lineJoin_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR_SETTER("Not a Context2D object");
+ CHECK_CONTEXT_SETTER(r)
QV8Engine *engine = V8ENGINE_ACCESSOR();
@@ -744,8 +759,8 @@ static void ctx2d_lineJoin_set(v8::Local<v8::String>, v8::Local<v8::Value> value
v8::Handle<v8::Value> ctx2d_lineWidth(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
return v8::Number::New(r->context->lineWidth());
}
@@ -753,8 +768,7 @@ v8::Handle<v8::Value> ctx2d_lineWidth(v8::Local<v8::String>, const v8::AccessorI
static void ctx2d_lineWidth_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR_SETTER("Not a Context2D object");
+ CHECK_CONTEXT_SETTER(r)
r->context->setLineWidth(value->NumberValue());
}
@@ -763,8 +777,8 @@ static void ctx2d_lineWidth_set(v8::Local<v8::String>, v8::Local<v8::Value> valu
v8::Handle<v8::Value> ctx2d_miterLimit(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
return v8::Number::New(r->context->miterLimit());
}
@@ -772,8 +786,7 @@ v8::Handle<v8::Value> ctx2d_miterLimit(v8::Local<v8::String>, const v8::Accessor
static void ctx2d_miterLimit_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR_SETTER("Not a Context2D object");
+ CHECK_CONTEXT_SETTER(r)
r->context->setMiterLimit(value->NumberValue());
}
@@ -783,8 +796,8 @@ static void ctx2d_miterLimit_set(v8::Local<v8::String>, v8::Local<v8::Value> val
v8::Handle<v8::Value> ctx2d_shadowBlur(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
return v8::Number::New(r->context->shadowBlur());
}
@@ -792,8 +805,7 @@ v8::Handle<v8::Value> ctx2d_shadowBlur(v8::Local<v8::String>, const v8::Accessor
static void ctx2d_shadowBlur_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR_SETTER("Not a Context2D object");
+ CHECK_CONTEXT_SETTER(r)
r->context->setShadowBlur(value->NumberValue());
}
@@ -801,8 +813,8 @@ static void ctx2d_shadowBlur_set(v8::Local<v8::String>, v8::Local<v8::Value> val
v8::Handle<v8::Value> ctx2d_shadowColor(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
QV8Engine *engine = V8ENGINE_ACCESSOR();
@@ -812,8 +824,7 @@ v8::Handle<v8::Value> ctx2d_shadowColor(v8::Local<v8::String>, const v8::Accesso
static void ctx2d_shadowColor_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR_SETTER("Not a Context2D object");
+ CHECK_CONTEXT_SETTER(r)
QV8Engine *engine = V8ENGINE_ACCESSOR();
@@ -823,8 +834,8 @@ static void ctx2d_shadowColor_set(v8::Local<v8::String>, v8::Local<v8::Value> va
v8::Handle<v8::Value> ctx2d_shadowOffsetX(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
return v8::Number::New(r->context->shadowOffsetX());
}
@@ -832,8 +843,7 @@ v8::Handle<v8::Value> ctx2d_shadowOffsetX(v8::Local<v8::String>, const v8::Acces
static void ctx2d_shadowOffsetX_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR_SETTER("Not a Context2D object");
+ CHECK_CONTEXT_SETTER(r)
r->context->setShadowOffsetX(value->NumberValue());
}
@@ -841,8 +851,8 @@ static void ctx2d_shadowOffsetX_set(v8::Local<v8::String>, v8::Local<v8::Value>
v8::Handle<v8::Value> ctx2d_shadowOffsetY(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
return v8::Number::New(r->context->shadowOffsetY());
}
@@ -850,8 +860,7 @@ v8::Handle<v8::Value> ctx2d_shadowOffsetY(v8::Local<v8::String>, const v8::Acces
static void ctx2d_shadowOffsetY_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR_SETTER("Not a Context2D object");
+ CHECK_CONTEXT_SETTER(r)
r->context->setShadowOffsetY(value->NumberValue());
}
@@ -860,8 +869,8 @@ static void ctx2d_shadowOffsetY_set(v8::Local<v8::String>, v8::Local<v8::Value>
static v8::Handle<v8::Value> ctx2d_clearRect(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
if (args.Length() == 4) {
r->context->clearRect(args[0]->NumberValue(),
@@ -876,8 +885,8 @@ static v8::Handle<v8::Value> ctx2d_clearRect(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_fillRect(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
if (args.Length() == 4) {
r->context->fillRect(args[0]->NumberValue(),
@@ -892,8 +901,8 @@ static v8::Handle<v8::Value> ctx2d_fillRect(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_strokeRect(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
if (args.Length() == 4) {
r->context->strokeRect(args[0]->NumberValue(),
@@ -909,8 +918,8 @@ static v8::Handle<v8::Value> ctx2d_strokeRect(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_arc(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
if (args.Length() == 6) {
r->context->arc(args[0]->NumberValue(),
@@ -927,8 +936,8 @@ static v8::Handle<v8::Value> ctx2d_arc(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_arcTo(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
if (args.Length() == 5) {
r->context->arcTo(args[0]->NumberValue(),
@@ -944,8 +953,8 @@ static v8::Handle<v8::Value> ctx2d_arcTo(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_beginPath(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
r->context->beginPath();
@@ -955,8 +964,8 @@ static v8::Handle<v8::Value> ctx2d_beginPath(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_bezierCurveTo(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
if (args.Length() == 5) {
r->context->bezierCurveTo(args[0]->NumberValue(),
@@ -973,8 +982,8 @@ static v8::Handle<v8::Value> ctx2d_bezierCurveTo(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_clip(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
r->context->clip();
@@ -984,8 +993,8 @@ static v8::Handle<v8::Value> ctx2d_clip(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_closePath(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
r->context->closePath();
@@ -995,8 +1004,8 @@ static v8::Handle<v8::Value> ctx2d_closePath(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_fill(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
r->context->fill();
@@ -1006,8 +1015,8 @@ static v8::Handle<v8::Value> ctx2d_fill(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_lineTo(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
if (args.Length() == 2) {
r->context->lineTo(args[0]->NumberValue(),
@@ -1020,8 +1029,8 @@ static v8::Handle<v8::Value> ctx2d_lineTo(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_moveTo(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
if (args.Length() == 2) {
r->context->moveTo(args[0]->NumberValue(),
@@ -1034,8 +1043,8 @@ static v8::Handle<v8::Value> ctx2d_moveTo(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_quadraticCurveTo(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
if (args.Length() == 4) {
r->context->quadraticCurveTo(args[0]->NumberValue(),
@@ -1050,8 +1059,8 @@ static v8::Handle<v8::Value> ctx2d_quadraticCurveTo(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_rect(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
if (args.Length() == 4) {
r->context->rect(args[0]->NumberValue(),
@@ -1066,8 +1075,8 @@ static v8::Handle<v8::Value> ctx2d_rect(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_stroke(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
r->context->stroke();
@@ -1077,8 +1086,8 @@ static v8::Handle<v8::Value> ctx2d_stroke(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_isPointInPath(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
bool pointInPath = false;
if (args.Length() == 2) {
@@ -1092,8 +1101,8 @@ static v8::Handle<v8::Value> ctx2d_isPointInPath(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_setPathString(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
QV8Engine *engine = V8ENGINE();
if (args.Length() == 1) {
@@ -1102,12 +1111,48 @@ static v8::Handle<v8::Value> ctx2d_setPathString(const v8::Arguments &args)
return v8::Undefined();
}
+static v8::Handle<v8::Value> ctx2d_path(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+// QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+// CHECK_CONTEXT(r)
+
+// QV8Engine *engine = V8ENGINE();
+
+ return v8::Undefined();
+}
+
+static v8::Handle<v8::Value> ctx2d_path_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
+{
+// QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+// CHECK_CONTEXT(r)
+
+
+// QV8Engine *engine = V8ENGINE();
+// if (args.Length() == 1) {
+// r->context->setPathString(engine->toString(args[0]));
+// }
+ return v8::Undefined();
+}
+
+static v8::Handle<v8::Value> ctx2d_createPath(const v8::Arguments &args)
+{
+// QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+// CHECK_CONTEXT(r)
+
+
+// QV8Engine *engine = V8ENGINE();
+// if (args.Length() == 1) {
+// r->context->setPathString(engine->toString(args[0]));
+// }
+ return v8::Undefined();
+}
+
// text
v8::Handle<v8::Value> ctx2d_font(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
return v8::Undefined();
}
@@ -1115,8 +1160,7 @@ v8::Handle<v8::Value> ctx2d_font(v8::Local<v8::String>, const v8::AccessorInfo &
static void ctx2d_font_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR_SETTER("Not a Context2D object");
+ CHECK_CONTEXT_SETTER(r)
Q_UNUSED(value);
}
@@ -1124,8 +1168,8 @@ static void ctx2d_font_set(v8::Local<v8::String>, v8::Local<v8::Value> value, co
v8::Handle<v8::Value> ctx2d_textAlign(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
return v8::Undefined();
}
@@ -1133,8 +1177,7 @@ v8::Handle<v8::Value> ctx2d_textAlign(v8::Local<v8::String>, const v8::AccessorI
static void ctx2d_textAlign_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR_SETTER("Not a Context2D object");
+ CHECK_CONTEXT_SETTER(r)
Q_UNUSED(value);
}
@@ -1142,8 +1185,8 @@ static void ctx2d_textAlign_set(v8::Local<v8::String>, v8::Local<v8::Value> valu
v8::Handle<v8::Value> ctx2d_textBaseline(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
return v8::Undefined();
}
@@ -1151,8 +1194,7 @@ v8::Handle<v8::Value> ctx2d_textBaseline(v8::Local<v8::String>, const v8::Access
static void ctx2d_textBaseline_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
- if (!r || !r->context)
- V8THROW_ERROR_SETTER("Not a Context2D object");
+ CHECK_CONTEXT_SETTER(r)
Q_UNUSED(value);
}
@@ -1160,8 +1202,8 @@ static void ctx2d_textBaseline_set(v8::Local<v8::String>, v8::Local<v8::Value> v
static v8::Handle<v8::Value> ctx2d_fillText(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
QV8Engine *engine = V8ENGINE();
@@ -1177,8 +1219,8 @@ static v8::Handle<v8::Value> ctx2d_fillText(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_strokeText(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
QV8Engine *engine = V8ENGINE();
@@ -1195,8 +1237,8 @@ static v8::Handle<v8::Value> ctx2d_strokeText(const v8::Arguments &args)
static v8::Handle<v8::Value> ctx2d_drawImage(const v8::Arguments &args)
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
- if (!r || !r->context)
- V8THROW_ERROR("Not a Context2D object");
+ CHECK_CONTEXT(r)
+
QV8Engine *engine = V8ENGINE();
@@ -1509,20 +1551,38 @@ void QSGContext2DPrivate::clearRect(qreal x, qreal y,
void QSGContext2DPrivate::fillRect(qreal x, qreal y,
qreal w, qreal h)
{
- commands.push_back(QSGContext2D::FillRect);
- reals.push_back(x);
- reals.push_back(y);
- reals.push_back(w);
- reals.push_back(h);
+ QRectF rect;
+ if (tileRect.isValid()) {
+ rect = tileRect.intersect(QRect(x, y, w, h));
+ } else {
+ rect = QRectF(x, y, w, h);
+ }
+
+ if (rect.isValid()) {
+ commands.push_back(QSGContext2D::FillRect);
+ reals.push_back(rect.x());
+ reals.push_back(rect.y());
+ reals.push_back(rect.width());
+ reals.push_back(rect.height());
+ }
}
void QSGContext2DPrivate::strokeRect(qreal x, qreal y,
qreal w, qreal h)
{
- QPainterPath path;
- path.addRect(x, y, w, h);
- commands.push_back(QSGContext2D::Stroke);
- pathes.push_back(path);
+ QPainterPath p;
+ p.addRect(x, y, w, h);
+
+ if (tileRect.isValid()) {
+ QPainterPath tr;
+ tr.addRect(tileRect);
+ p = p.intersected(tr);
+ }
+
+ if (!p.isEmpty()) {
+ commands.push_back(QSGContext2D::Stroke);
+ pathes.push_back(p);
+ }
}
void QSGContext2DPrivate::beginPath()
@@ -1633,21 +1693,39 @@ void QSGContext2DPrivate::arc(qreal xc,
void QSGContext2DPrivate::fill()
{
- commands.push_back(QSGContext2D::Fill);
- pathes.push_back(path);
+ QPainterPath tr;
+ if (tileRect.isValid()) {
+ tr.addRect(tileRect);
+ tr = tr.intersected(path);
+ } else {
+ tr = path;
+ }
+
+ if (!tr.isEmpty()) {
+ commands.push_back(QSGContext2D::Fill);
+ pathes.push_back(tr);
+ }
}
void QSGContext2DPrivate::stroke()
{
- commands.push_back(QSGContext2D::Stroke);
- pathes.push_back(path);
-// painter->setMatrix(state.matrix, false);
-// QPainterPath tmp = state.matrix.inverted().map(path); //why?
-// painter->strokePath(tmp, painter->pen());
+ QPainterPath tr;
+ if (tileRect.isValid()) {
+ tr.addRect(tileRect);
+ tr = tr.intersected(path);
+ } else {
+ tr = path;
+ }
+
+ if (!tr.isEmpty()) {
+ commands.push_back(QSGContext2D::Stroke);
+ pathes.push_back(tr);
+ }
}
void QSGContext2DPrivate::clip()
{
+ //TODO:XXX
state.clipPath = path;
pathes.push_back(state.clipPath);
commands.push_back(QSGContext2D::Clip);
@@ -2214,6 +2292,26 @@ void QSGContext2D::setShadowColor(const QString &str)
d->setShadowColor(str);
}
+QSGCanvasPath* QSGContext2D::path()
+{
+ Q_D(const QSGContext2D);
+ return new QSGCanvasPath(d->path, this);
+}
+void QSGContext2D::setPath(QSGCanvasPath* path)
+{
+ Q_D(QSGContext2D);
+ d->path = path->m_path;
+}
+
+QSGCanvasPath* QSGContext2D::createPath(const QString& pathString)
+{
+ QPainterPath path;
+ if (parsePathDataFast(pathString, path)) {
+ return new QSGCanvasPath(path, this);
+ }
+ return 0;
+}
+
QString QSGContext2D::textBaseline() const
{
Q_D(const QSGContext2D);
@@ -3140,6 +3238,7 @@ QSGContext2DEngineData::QSGContext2DEngineData(QV8Engine *engine)
ft->PrototypeTemplate()->Set(v8::String::New("setTransform"), V8FUNCTION(ctx2d_setTransform, engine));
ft->PrototypeTemplate()->Set(v8::String::New("transform"), V8FUNCTION(ctx2d_transform, engine));
ft->PrototypeTemplate()->Set(v8::String::New("translate"), V8FUNCTION(ctx2d_translate, engine));
+ ft->InstanceTemplate()->SetAccessor(v8::String::New("valid"), ctx2d_valid, 0, v8::External::Wrap(engine));
ft->InstanceTemplate()->SetAccessor(v8::String::New("globalAlpha"), ctx2d_globalAlpha, ctx2d_globalAlpha_set, v8::External::Wrap(engine));
ft->InstanceTemplate()->SetAccessor(v8::String::New("globalCompositeOperation"), ctx2d_globalCompositeOperation, ctx2d_globalCompositeOperation_set, v8::External::Wrap(engine));
ft->InstanceTemplate()->SetAccessor(v8::String::New("fillStyle"), ctx2d_fillStyle, ctx2d_fillStyle_set, v8::External::Wrap(engine));
@@ -3195,8 +3294,17 @@ QSGContext2DEngineData::~QSGContext2DEngineData()
V8_DEFINE_EXTENSION(QSGContext2DEngineData, engineData);
+QV8Engine* QSGContext2D::v8Engine() const
+{
+ Q_D(const QSGContext2D);
+ return d->v8engine;
+}
+
void QSGContext2D::setV8Engine(QV8Engine *engine)
{
+ v8::HandleScope handle_scope;
+ v8::Context::Scope scope(engine->context());
+
Q_D(QSGContext2D);
if (d->v8engine != engine) {
d->v8engine = engine;
@@ -3214,6 +3322,23 @@ void QSGContext2D::setV8Engine(QV8Engine *engine)
}
}
+bool QSGContext2D::valid() const
+{
+ Q_D(const QSGContext2D);
+ return d->valid;
+}
+
+void QSGContext2D::setValid(bool valid)
+{
+ Q_D(QSGContext2D);
+ d->valid = valid;
+}
+void QSGContext2D::setTileRect(const QRectF& rect)
+{
+ Q_D(QSGContext2D);
+ if (d->tileRect != rect)
+ d->tileRect = rect;
+}
void QSGContext2D::addref()
{
Q_D(QSGContext2D);
@@ -3538,7 +3663,7 @@ void QSGContext2D::paint(QPainter* p)
{
Q_D(QSGContext2D);
- QTransform transform = p->worldTransform();
+ QMatrix originMatrix = p->matrix();
if (!d->commands.isEmpty()) {
int matrix_idx, real_idx, int_idx, variant_idx, string_idx,color_idx,cmd_idx,
pen_idx, brush_idx, font_idx, path_idx, image_idx, size_idx;
@@ -3551,7 +3676,7 @@ void QSGContext2D::paint(QPainter* p)
case UpdateMatrix:
{
d->state.matrix = d->matrixes[matrix_idx++];
- p->setMatrix(d->state.matrix);
+ p->setMatrix(d->state.matrix * originMatrix);
break;
}
case ClearRect:
diff --git a/src/declarative/items/qsgcontext2d_p.h b/src/declarative/items/qsgcontext2d_p.h
index 924c4bf780..335d954fc1 100644
--- a/src/declarative/items/qsgcontext2d_p.h
+++ b/src/declarative/items/qsgcontext2d_p.h
@@ -86,6 +86,16 @@ public:
Q_DECLARE_METATYPE(QSGCanvasGradient*)
+class QSGCanvasPath : QObject
+{
+ Q_OBJECT
+public:
+ QSGCanvasPath(const QPainterPath& path, QObject* parent = 0) : QObject(parent), m_path(path) {}
+
+ QPainterPath m_path;
+};
+Q_DECLARE_METATYPE(QSGCanvasPath*)
+
class QSGContext2DWorkerAgent;
class QSGContext2DPrivate;
class QSGCanvasItem;
@@ -113,6 +123,8 @@ class QSGContext2D : public QObject
Q_PROPERTY(QString font READ font WRITE setFont)
Q_PROPERTY(QString textBaseline READ textBaseline WRITE setTextBaseline)
Q_PROPERTY(QString textAlign READ textAlign WRITE setTextAlign)
+
+ Q_PROPERTY(QSGCanvasPath* path READ path WRITE setPath)
Q_ENUMS(PaintCommand)
public:
enum TextBaseLineType { Alphabetic=0, Top, Middle, Bottom, Hanging};
@@ -245,6 +257,8 @@ public:
void setShadowBlur(qreal b);
void setShadowColor(const QString &str);
+ QSGCanvasPath* path();
+ void setPath(QSGCanvasPath* path);
public slots:
void save(); // push state on state stack
void restore(); // pop state stack and restore state
@@ -295,6 +309,7 @@ public slots:
//implement the W3C SVG path spec:
//http://www.w3.org/TR/SVG/paths.html
void setPathString(const QString& path);
+ QSGCanvasPath* createPath(const QString& pathString);
QSGImage *createImage(const QString &url);
@@ -315,8 +330,12 @@ signals:
public:
bool isDirty() const;
v8::Handle<v8::Object> v8value() const;
+ QV8Engine* v8Engine() const;
void setV8Engine(QV8Engine *eng);
+ bool valid() const;
+ void setValid(bool valid);
+ void setTileRect(const QRectF& region);
void addref();
void release();
diff --git a/src/declarative/items/qsgcontext2d_p_p.h b/src/declarative/items/qsgcontext2d_p_p.h
index 4fcf40406e..ed73b2fbd2 100644
--- a/src/declarative/items/qsgcontext2d_p_p.h
+++ b/src/declarative/items/qsgcontext2d_p_p.h
@@ -82,6 +82,7 @@ public:
, cachedImage(1,1, QImage::Format_ARGB32)
, canvas(0)
, waitingForPainting(false)
+ , valid(false)
{
}
~QSGContext2DPrivate()
@@ -180,6 +181,7 @@ public:
void clearCommands()
{
+ qDebug() << "painting commands:" << commands.size();
commands.remove(0, commands.size());
variants.remove(0, variants.size());
pens.remove(0, pens.size());
@@ -227,6 +229,8 @@ public:
QImage cachedImage;
QSGCanvasItem* canvas;
bool waitingForPainting;
+ bool valid;
+ QRectF tileRect;
};
QT_END_NAMESPACE