aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/items
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2011-07-08 15:56:48 +1000
committerAaron Kennedy <aaron.kennedy@nokia.com>2011-07-08 15:56:48 +1000
commit26590325b5e9209df4495841b9013d04bbb35515 (patch)
tree2a4e44ca1e1d4389caf999ee8801a312166bf39c /src/declarative/items
parent5a705d8951a0b23c725d99a5a3fce7902ec41374 (diff)
parent438d50d63c48bbbfd185bd7e1a0d6e6174c1791e (diff)
Merge branch 'v8'
Conflicts: src/declarative/qml/qdeclarativescarceresourcescriptclass.cpp src/declarative/qml/qdeclarativescarceresourcescriptclass_p.h Change-Id: I54e579307cbeafbbad21884218c5e797ba245c8b
Diffstat (limited to 'src/declarative/items')
-rw-r--r--src/declarative/items/qsgcanvasitem.cpp27
-rw-r--r--src/declarative/items/qsgcanvasitem_p.h9
-rw-r--r--src/declarative/items/qsgcontext2d.cpp2180
-rw-r--r--src/declarative/items/qsgcontext2d_p.h15
-rw-r--r--src/declarative/items/qsgcontext2d_p_p.h13
-rw-r--r--src/declarative/items/qsgitem.cpp74
-rw-r--r--src/declarative/items/qsgitem.h4
7 files changed, 1489 insertions, 833 deletions
diff --git a/src/declarative/items/qsgcanvasitem.cpp b/src/declarative/items/qsgcanvasitem.cpp
index 9f6e9db56b..f346db4c66 100644
--- a/src/declarative/items/qsgcanvasitem.cpp
+++ b/src/declarative/items/qsgcanvasitem.cpp
@@ -94,25 +94,40 @@ 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();
}
}
-QScriptValue QSGCanvasItem::getContext(const QString &contextId)
+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);
- QScriptEngine* e = QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(this));
+
if (contextId == QLatin1String("2d")) {
if (!d->context) {
+ QV8Engine *e = QDeclarativeEnginePrivate::getV8Engine(qmlEngine(this));
d->context = new QSGContext2D(this);
- d->context->setScriptEngine(e);
+ d->context->setV8Engine(e);
connect(d->context, SIGNAL(changed()), this, SLOT(requestPaint()));
}
- return d->context->scriptValue();
+ return QDeclarativeV8Handle::fromHandle(d->context->v8value());
}
- qDebug("Canvas:requesting unsupported context");
- return e->undefinedValue();
+ return QDeclarativeV8Handle::fromHandle(v8::Undefined());
}
void QSGCanvasItem::requestPaint()
diff --git a/src/declarative/items/qsgcanvasitem_p.h b/src/declarative/items/qsgcanvasitem_p.h
index 8f3130c340..71358c4d9e 100644
--- a/src/declarative/items/qsgcanvasitem_p.h
+++ b/src/declarative/items/qsgcanvasitem_p.h
@@ -43,6 +43,7 @@
#define QSGCANVASITEM_P_H
#include "qsgpainteditem.h"
+#include <private/qv8engine_p.h>
#define QSGCANVASITEM_DEBUG //enable this for just DEBUG purpose!
@@ -55,7 +56,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
-class QScriptValue;
class QSGContext2D;
class QSGCanvasItemPrivate;
class QSGCanvasItem : public QSGPaintedItem
@@ -65,11 +65,13 @@ public:
QSGCanvasItem(QSGItem *parent = 0);
~QSGCanvasItem();
-signals:
+Q_SIGNALS:
void canvasUpdated();
+ void drawRegion(QDeclarativeV8Handle context, const QRect &region);
+
public Q_SLOTS:
QString toDataURL(const QString& type = QLatin1String("image/png")) const;
- QScriptValue getContext(const QString & = QLatin1String("2d"));
+ QDeclarativeV8Handle getContext(const QString & = QLatin1String("2d"));
void requestPaint();
// Save current canvas to disk
@@ -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 db23e5bc7b..f3371ed982 100644
--- a/src/declarative/items/qsgcontext2d.cpp
+++ b/src/declarative/items/qsgcontext2d.cpp
@@ -53,7 +53,9 @@
#include <qdeclarativeinfo.h>
#include <QtCore/qmath.h>
#include "qdeclarativepixmapcache_p.h"
-#include <QtScript/QScriptEngine>
+
+#include <private/qv8engine_p.h>
+#include "qvarlengtharray.h"
QT_BEGIN_NAMESPACE
@@ -366,547 +368,882 @@ static QString compositeOperatorToString(QPainter::CompositionMode op)
return QString();
}
+class QV8Context2DResource : public QV8ObjectResource
+{
+ V8_RESOURCE_TYPE(Context2DType)
+public:
+ QV8Context2DResource(QV8Engine *e) : QV8ObjectResource(e) {}
+ QDeclarativeGuard<QSGContext2D> context;
+};
- #include <QScriptEngine>
-
-//static QtScript functions
-static QScriptValue ctx2d_sync(QScriptContext *c, QScriptEngine* e)
+//static script functions
+static v8::Handle<v8::Value> ctx2d_sync(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- ctx2d->sync();
- return e->nullValue();
-}
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ r->context->sync();
+ return v8::Undefined();
+}
// back-reference to the canvas, getter
-static QScriptValue ctx2d_canvas(QScriptContext *c, QScriptEngine* e)
+static v8::Handle<v8::Value> ctx2d_canvas(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- return e->newQObject(ctx2d->canvas());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+ return engine->newQObject(r->context->canvas());
}
// state
-static QScriptValue ctx2d_restore(QScriptContext *c, QScriptEngine *e)
+static v8::Handle<v8::Value> ctx2d_restore(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- ctx2d->restore();
- return e->nullValue();
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ r->context->restore();
+
+ return v8::Undefined();
}
-static QScriptValue ctx2d_save(QScriptContext *c, QScriptEngine *e)
+static v8::Handle<v8::Value> ctx2d_reset(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- ctx2d->save();
- return e->nullValue();
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ r->context->reset();
+
+ return v8::Undefined();
+}
+
+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");
+
+ r->context->save();
+
+ return v8::Undefined();
}
// transformations
-static QScriptValue ctx2d_rotate(QScriptContext *c, QScriptEngine *e)
+static v8::Handle<v8::Value> ctx2d_rotate(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 1) {
- ctx2d->rotate(c->argument(0).toNumber());
- }
- return e->nullValue();
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ if (args.Length() == 1)
+ r->context->rotate(args[0]->NumberValue());
+
+ return v8::Undefined();
}
-static QScriptValue ctx2d_scale(QScriptContext *c, QScriptEngine *e)
+
+static v8::Handle<v8::Value> ctx2d_scale(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 2) {
- ctx2d->scale(c->argument(0).toNumber(), c->argument(1).toNumber());
- }
- return e->nullValue();
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ if (args.Length() == 2)
+ r->context->scale(args[0]->NumberValue(), args[1]->NumberValue());
+
+ return v8::Undefined();
}
-static QScriptValue ctx2d_setTransform(QScriptContext *c, QScriptEngine *e)
+
+static v8::Handle<v8::Value> ctx2d_setTransform(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 6) {
- ctx2d->setTransform(c->argument(0).toNumber()
- , c->argument(1).toNumber()
- , c->argument(2).toNumber()
- , c->argument(3).toNumber()
- , c->argument(4).toNumber()
- , c->argument(5).toNumber());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ if (args.Length() == 6) {
+ r->context->setTransform(args[0]->NumberValue(),
+ args[1]->NumberValue(),
+ args[2]->NumberValue(),
+ args[3]->NumberValue(),
+ args[4]->NumberValue(),
+ args[5]->NumberValue());
}
- return e->nullValue();
+
+ return v8::Undefined();
}
-static QScriptValue ctx2d_transform(QScriptContext *c, QScriptEngine *e)
+
+static v8::Handle<v8::Value> ctx2d_transform(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 6) {
- ctx2d->transform(c->argument(0).toNumber()
- , c->argument(1).toNumber()
- , c->argument(2).toNumber()
- , c->argument(3).toNumber()
- , c->argument(4).toNumber()
- , c->argument(5).toNumber());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ if (args.Length() == 6) {
+ r->context->transform(args[0]->NumberValue(),
+ args[1]->NumberValue(),
+ args[2]->NumberValue(),
+ args[3]->NumberValue(),
+ args[4]->NumberValue(),
+ args[5]->NumberValue());
}
- return e->nullValue();
+
+ return v8::Undefined();
}
-static QScriptValue ctx2d_translate(QScriptContext *c, QScriptEngine *e)
+
+static v8::Handle<v8::Value> ctx2d_translate(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 2) {
- ctx2d->translate(c->argument(0).toNumber()
- , c->argument(1).toNumber());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ if (args.Length() == 2) {
+ r->context->translate(args[0]->NumberValue(),
+ args[1]->NumberValue());
}
- return e->nullValue();
+
+ return v8::Undefined();
}
// compositing
// float getter/setter default 1.0
-static QScriptValue ctx2d_globalAlpha(QScriptContext *c, QScriptEngine *e)
+static v8::Handle<v8::Value> ctx2d_globalAlpha(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 1) {//setter
- ctx2d->setGlobalAlpha(c->argument(0).toNumber());
- }
- return e->toScriptValue(ctx2d->globalAlpha());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ return v8::Number::New(r->context->globalAlpha());
+}
+
+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");
+
+ r->context->setGlobalAlpha(value->NumberValue());
}
// string getter/setter default "source-over"
-static QScriptValue ctx2d_globalCompositeOperation(QScriptContext *c, QScriptEngine *e)
+static v8::Handle<v8::Value> ctx2d_globalCompositeOperation(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (ctx2d) {
- if (c->argumentCount() == 1) {//setter
- ctx2d->setGlobalCompositeOperation(c->argument(0).toString());
- }
- return e->toScriptValue(ctx2d->globalCompositeOperation());
- }
- return e->nullValue();
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+ return engine->toString(r->context->globalCompositeOperation());
+}
+
+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");
+
+ QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+ r->context->setGlobalCompositeOperation(engine->toString(value));
}
// colors and styles
// getter/setter
-static QScriptValue ctx2d_fillStyle(QScriptContext *c, QScriptEngine *e)
+static v8::Handle<v8::Value> ctx2d_fillStyle(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 1) {//setter
- ctx2d->setFillStyle(c->argument(0).toVariant());
- }
- return e->toScriptValue(ctx2d->fillStyle());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+ return engine->fromVariant(r->context->fillStyle());
+}
+
+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");
+
+ QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+ r->context->setFillStyle(engine->toVariant(value, -1));
}
// colors and styles
// getter/setter
-static QScriptValue ctx2d_fillColor(QScriptContext *c, QScriptEngine *e)
+static v8::Handle<v8::Value> ctx2d_fillColor(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 1) {//setter
- ctx2d->setFillColor(c->argument(0).toVariant().value<QColor>());
- }
- return e->toScriptValue(ctx2d->fillColor());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+ return engine->fromVariant(r->context->fillColor());
}
+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");
+
+ QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+ r->context->setFillColor(engine->toVariant(value, -1).value<QColor>());
+}
//getter/setter
-static QScriptValue ctx2d_strokeStyle(QScriptContext *c, QScriptEngine *e)
+v8::Handle<v8::Value> ctx2d_strokeStyle(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 1) {//setter
- ctx2d->setStrokeStyle(c->argument(0).toVariant());
- }
- return e->toScriptValue(ctx2d->strokeStyle());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+ return engine->fromVariant(r->context->strokeStyle());
+}
+
+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");
+
+ QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+ r->context->setStrokeStyle(engine->toVariant(value, -1));
}
// colors and styles
// getter/setter
-static QScriptValue ctx2d_strokeColor(QScriptContext *c, QScriptEngine *e)
+v8::Handle<v8::Value> ctx2d_strokeColor(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 1) {//setter
- ctx2d->setStrokeColor(c->argument(0).toVariant().value<QColor>());
- }
- return e->toScriptValue(ctx2d->strokeColor());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+ return engine->fromVariant(r->context->strokeColor());
+}
+
+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");
+
+ QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+ r->context->setStrokeColor(engine->toVariant(value, -1).value<QColor>());
}
-static QScriptValue ctx2d_createLinearGradient(QScriptContext *c, QScriptEngine *e)
+static v8::Handle<v8::Value> ctx2d_createLinearGradient(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 4) {
- QObject* gradient = ctx2d->createLinearGradient( c->argument(0).toNumber()
- ,c->argument(1).toNumber()
- ,c->argument(2).toNumber()
- ,c->argument(3).toNumber());
- return e->toScriptValue(gradient);
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ QV8Engine *engine = V8ENGINE();
+
+ if (args.Length() == 4) {
+ QObject* gradient = r->context->createLinearGradient(args[0]->NumberValue(),
+ args[1]->NumberValue(),
+ args[2]->NumberValue(),
+ args[3]->NumberValue());
+ return engine->newQObject(gradient);
}
- return e->nullValue();
+
+ return v8::Null();
}
-static QScriptValue ctx2d_createRadialGradient(QScriptContext *c, QScriptEngine *e)
+
+static v8::Handle<v8::Value> ctx2d_createRadialGradient(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 6) {
- QObject* gradient = ctx2d->createRadialGradient( c->argument(0).toNumber()
- ,c->argument(1).toNumber()
- ,c->argument(2).toNumber()
- ,c->argument(3).toNumber()
- ,c->argument(4).toNumber()
- ,c->argument(5).toNumber());
- return e->toScriptValue(gradient);
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ QV8Engine *engine = V8ENGINE();
+
+ if (args.Length() == 6) {
+ QObject* gradient = r->context->createRadialGradient(args[0]->NumberValue(),
+ args[1]->NumberValue(),
+ args[2]->NumberValue(),
+ args[3]->NumberValue(),
+ args[4]->NumberValue(),
+ args[5]->NumberValue());
+ return engine->newQObject(gradient);
}
- return e->nullValue();
+
+ return v8::Null();
}
-static QScriptValue ctx2d_createPattern(QScriptContext *c, QScriptEngine *e)
+
+static v8::Handle<v8::Value> ctx2d_createPattern(const v8::Arguments &args)
{
//TODO
- return e->nullValue();
+ return v8::Null();
}
// line styles
// string getter/setter
-static QScriptValue ctx2d_lineCap(QScriptContext *c, QScriptEngine *e)
+v8::Handle<v8::Value> ctx2d_lineCap(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 1) {//setter
- ctx2d->setLineCap(c->argument(0).toString());
- }
- return e->toScriptValue(ctx2d->lineCap());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+ return engine->toString(r->context->lineCap());
+}
+
+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");
+
+ QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+ r->context->setLineCap(engine->toString(value));
}
// string getter/setter
-static QScriptValue ctx2d_lineJoin(QScriptContext *c, QScriptEngine *e)
+v8::Handle<v8::Value> ctx2d_lineJoin(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 1) {//setter
- ctx2d->setLineJoin(c->argument(0).toString());
- }
- return e->toScriptValue(ctx2d->lineJoin());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+ return engine->toString(r->context->lineJoin());
}
+
+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");
+
+ QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+ r->context->setLineJoin(engine->toString(value));
+}
+
// float getter/setter
-static QScriptValue ctx2d_lineWidth(QScriptContext *c, QScriptEngine *e)
+v8::Handle<v8::Value> ctx2d_lineWidth(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 1) {//setter
- ctx2d->setLineWidth(c->argument(0).toNumber());
- }
- return e->toScriptValue(ctx2d->lineWidth());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ return v8::Number::New(r->context->lineWidth());
}
+
+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");
+
+ r->context->setLineWidth(value->NumberValue());
+}
+
// float getter/setter
-static QScriptValue ctx2d_miterLimit(QScriptContext *c, QScriptEngine *e)
+v8::Handle<v8::Value> ctx2d_miterLimit(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 1) {//setter
- ctx2d->setMiterLimit(c->argument(0).toNumber());
- }
- return e->toScriptValue(ctx2d->miterLimit());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ return v8::Number::New(r->context->miterLimit());
+}
+
+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");
+
+ r->context->setMiterLimit(value->NumberValue());
}
// shadows
// float getter/setter
-static QScriptValue ctx2d_shadowBlur(QScriptContext *c, QScriptEngine *e)
+v8::Handle<v8::Value> ctx2d_shadowBlur(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 1) {//setter
- ctx2d->setShadowBlur(c->argument(0).toNumber());
- }
- return e->toScriptValue(ctx2d->shadowBlur());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ return v8::Number::New(r->context->shadowBlur());
}
-static QScriptValue ctx2d_shadowColor(QScriptContext *c, QScriptEngine *e)
+
+static void ctx2d_shadowBlur_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 1) {//setter
- ctx2d->setShadowColor(c->argument(0).toString());
- }
- return e->toScriptValue(ctx2d->shadowColor());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+ if (!r || !r->context)
+ V8THROW_ERROR_SETTER("Not a Context2D object");
+
+ r->context->setShadowBlur(value->NumberValue());
+}
+
+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");
+
+ QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+ return engine->toString(r->context->shadowColor());
}
-static QScriptValue ctx2d_shadowOffsetX(QScriptContext *c, QScriptEngine *e)
+
+static void ctx2d_shadowColor_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 1) {//setter
- ctx2d->setShadowOffsetX(c->argument(0).toNumber());
- }
- return e->toScriptValue(ctx2d->shadowOffsetX());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+ if (!r || !r->context)
+ V8THROW_ERROR_SETTER("Not a Context2D object");
+
+ QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+ r->context->setShadowColor(engine->toString(value));
}
-static QScriptValue ctx2d_shadowOffsetY(QScriptContext *c, QScriptEngine *e)
+v8::Handle<v8::Value> ctx2d_shadowOffsetX(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 1) {//setter
- ctx2d->setShadowOffsetY(c->argument(0).toNumber());
- }
- return e->toScriptValue(ctx2d->shadowOffsetY());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ return v8::Number::New(r->context->shadowOffsetX());
+}
+
+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");
+
+ r->context->setShadowOffsetX(value->NumberValue());
+}
+
+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");
+
+ return v8::Number::New(r->context->shadowOffsetY());
+}
+
+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");
+
+ r->context->setShadowOffsetY(value->NumberValue());
}
//rects
-static QScriptValue ctx2d_clearRect(QScriptContext *c, QScriptEngine *e)
+static v8::Handle<v8::Value> ctx2d_clearRect(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 4) {
- ctx2d->clearRect(c->argument(0).toNumber()
- ,c->argument(1).toNumber()
- ,c->argument(2).toNumber()
- ,c->argument(3).toNumber());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ if (args.Length() == 4) {
+ r->context->clearRect(args[0]->NumberValue(),
+ args[1]->NumberValue(),
+ args[2]->NumberValue(),
+ args[3]->NumberValue());
}
- return e->nullValue();
+
+ return v8::Undefined();
}
-static QScriptValue ctx2d_fillRect(QScriptContext *c, QScriptEngine *e)
+
+static v8::Handle<v8::Value> ctx2d_fillRect(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 4) {
- ctx2d->fillRect(c->argument(0).toNumber()
- ,c->argument(1).toNumber()
- ,c->argument(2).toNumber()
- ,c->argument(3).toNumber());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ if (args.Length() == 4) {
+ r->context->fillRect(args[0]->NumberValue(),
+ args[1]->NumberValue(),
+ args[2]->NumberValue(),
+ args[3]->NumberValue());
}
- return e->nullValue();
+
+ return v8::Undefined();
}
-static QScriptValue ctx2d_strokeRect(QScriptContext *c, QScriptEngine *e)
+
+static v8::Handle<v8::Value> ctx2d_strokeRect(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 4) {
- ctx2d->strokeRect(c->argument(0).toNumber()
- ,c->argument(1).toNumber()
- ,c->argument(2).toNumber()
- ,c->argument(3).toNumber());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ if (args.Length() == 4) {
+ r->context->strokeRect(args[0]->NumberValue(),
+ args[1]->NumberValue(),
+ args[2]->NumberValue(),
+ args[3]->NumberValue());
}
- return e->nullValue();
+
+ return v8::Undefined();
}
// Complex shapes (paths) API
-static QScriptValue ctx2d_arc(QScriptContext *c, QScriptEngine *e)
+static v8::Handle<v8::Value> ctx2d_arc(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 6) {
- ctx2d->arc(c->argument(0).toNumber()
- ,c->argument(1).toNumber()
- ,c->argument(2).toNumber()
- ,c->argument(3).toNumber()
- ,c->argument(4).toNumber()
- ,c->argument(5).toNumber());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ if (args.Length() == 6) {
+ r->context->arc(args[0]->NumberValue(),
+ args[1]->NumberValue(),
+ args[2]->NumberValue(),
+ args[3]->NumberValue(),
+ args[4]->NumberValue(),
+ args[5]->NumberValue());
}
- return e->nullValue();
+
+ return v8::Undefined();
}
-static QScriptValue ctx2d_arcTo(QScriptContext *c, QScriptEngine *e)
+
+static v8::Handle<v8::Value> ctx2d_arcTo(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 5) {
- ctx2d->arcTo(c->argument(0).toNumber()
- ,c->argument(1).toNumber()
- ,c->argument(2).toNumber()
- ,c->argument(3).toNumber()
- ,c->argument(4).toNumber());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ if (args.Length() == 5) {
+ r->context->arcTo(args[0]->NumberValue(),
+ args[1]->NumberValue(),
+ args[2]->NumberValue(),
+ args[3]->NumberValue(),
+ args[4]->NumberValue());
}
- return e->nullValue();
+
+ return v8::Undefined();
}
-static QScriptValue ctx2d_beginPath(QScriptContext *c, QScriptEngine *e)
+
+static v8::Handle<v8::Value> ctx2d_beginPath(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- ctx2d->beginPath();
- return e->nullValue();
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ r->context->beginPath();
+
+ return v8::Undefined();
}
-static QScriptValue ctx2d_bezierCurveTo(QScriptContext *c, QScriptEngine *e)
+
+static v8::Handle<v8::Value> ctx2d_bezierCurveTo(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 5) {
- ctx2d->bezierCurveTo(c->argument(0).toNumber()
- ,c->argument(1).toNumber()
- ,c->argument(2).toNumber()
- ,c->argument(3).toNumber()
- ,c->argument(4).toNumber()
- ,c->argument(5).toNumber());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ if (args.Length() == 5) {
+ r->context->bezierCurveTo(args[0]->NumberValue(),
+ args[1]->NumberValue(),
+ args[2]->NumberValue(),
+ args[3]->NumberValue(),
+ args[4]->NumberValue(),
+ args[5]->NumberValue());
}
- return e->nullValue();
+
+ return v8::Undefined();
}
-static QScriptValue ctx2d_clip(QScriptContext *c, QScriptEngine *e)
+
+static v8::Handle<v8::Value> ctx2d_clip(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- ctx2d->clip();
- return e->nullValue();
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ r->context->clip();
+
+ return v8::Undefined();
}
-static QScriptValue ctx2d_closePath(QScriptContext *c, QScriptEngine *e)
+
+static v8::Handle<v8::Value> ctx2d_closePath(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- ctx2d->closePath();
- return e->nullValue();
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ r->context->closePath();
+
+ return v8::Undefined();
}
-static QScriptValue ctx2d_fill(QScriptContext *c, QScriptEngine *e)
+
+static v8::Handle<v8::Value> ctx2d_fill(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- ctx2d->fill();
- return e->nullValue();
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ r->context->fill();
+
+ return v8::Undefined();
}
-static QScriptValue ctx2d_lineTo(QScriptContext *c, QScriptEngine *e)
+
+static v8::Handle<v8::Value> ctx2d_lineTo(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 2) {
- ctx2d->lineTo(c->argument(0).toNumber()
- ,c->argument(1).toNumber());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ if (args.Length() == 2) {
+ r->context->lineTo(args[0]->NumberValue(),
+ args[1]->NumberValue());
}
- return e->nullValue();
+
+ return v8::Undefined();
}
-static QScriptValue ctx2d_moveTo(QScriptContext *c, QScriptEngine *e)
+
+static v8::Handle<v8::Value> ctx2d_moveTo(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 2) {
- ctx2d->moveTo(c->argument(0).toNumber()
- ,c->argument(1).toNumber());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ if (args.Length() == 2) {
+ r->context->moveTo(args[0]->NumberValue(),
+ args[1]->NumberValue());
}
- return e->nullValue();
+
+ return v8::Undefined();
}
-static QScriptValue ctx2d_quadraticCurveTo(QScriptContext *c, QScriptEngine *e)
+
+static v8::Handle<v8::Value> ctx2d_quadraticCurveTo(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 4) {
- ctx2d->quadraticCurveTo(c->argument(0).toNumber()
- ,c->argument(1).toNumber()
- ,c->argument(2).toNumber()
- ,c->argument(3).toNumber());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ if (args.Length() == 4) {
+ r->context->quadraticCurveTo(args[0]->NumberValue(),
+ args[1]->NumberValue(),
+ args[2]->NumberValue(),
+ args[3]->NumberValue());
}
- return e->nullValue();
+
+ return v8::Undefined();
}
-static QScriptValue ctx2d_rect(QScriptContext *c, QScriptEngine *e)
+
+static v8::Handle<v8::Value> ctx2d_rect(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 4) {
- ctx2d->rect(c->argument(0).toNumber()
- ,c->argument(1).toNumber()
- ,c->argument(2).toNumber()
- ,c->argument(3).toNumber());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ if (args.Length() == 4) {
+ r->context->rect(args[0]->NumberValue(),
+ args[1]->NumberValue(),
+ args[2]->NumberValue(),
+ args[3]->NumberValue());
}
- return e->nullValue();
+
+ return v8::Undefined();
}
-static QScriptValue ctx2d_stroke(QScriptContext *c, QScriptEngine *e)
+
+static v8::Handle<v8::Value> ctx2d_stroke(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- ctx2d->stroke();
- return e->nullValue();
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ r->context->stroke();
+
+ return v8::Undefined();
}
-static QScriptValue ctx2d_isPointInPath(QScriptContext *c, QScriptEngine *e)
+
+static v8::Handle<v8::Value> ctx2d_isPointInPath(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
bool pointInPath = false;
- if (c->argumentCount() == 2) {
- pointInPath = ctx2d->isPointInPath(c->argument(0).toNumber()
- ,c->argument(1).toNumber());
+ if (args.Length() == 2) {
+ pointInPath = r->context->isPointInPath(args[0]->NumberValue(),
+ args[1]->NumberValue());
}
- return e->toScriptValue(pointInPath);
-}
-// text
-static QScriptValue ctx2d_font(QScriptContext *c, QScriptEngine *e)
-{
- return QScriptValue();
-}
-static QScriptValue ctx2d_textAlign(QScriptContext *c, QScriptEngine *e)
-{
- return QScriptValue();
+ return v8::Boolean::New(pointInPath);
}
-static QScriptValue ctx2d_textBaseline(QScriptContext *c, QScriptEngine *e)
-{
- return QScriptValue();
-}
-static QScriptValue ctx2d_fillText(QScriptContext *c, QScriptEngine *e)
+
+static v8::Handle<v8::Value> ctx2d_setPathString(const v8::Arguments &args)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 3) {
- ctx2d->fillText(c->argument(0).toString()
- ,c->argument(1).toNumber()
- ,c->argument(2).toNumber());
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ QV8Engine *engine = V8ENGINE();
+ if (args.Length() == 1) {
+ r->context->setPathString(engine->toString(args[0]));
}
- return e->nullValue();
+ return v8::Undefined();
}
-static QScriptValue ctx2d_strokeText(QScriptContext *c, QScriptEngine *e)
+
+// text
+v8::Handle<v8::Value> ctx2d_font(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 3) {
- ctx2d->strokeText(c->argument(0).toString()
- ,c->argument(1).toNumber()
- ,c->argument(2).toNumber());
- }
- return e->nullValue();
-}
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
-// drawing images
-static QScriptValue ctx2d_drawImage(QScriptContext *c, QScriptEngine *e)
-{
- QSGContext2D* ctx2d = qscriptvalue_cast<QSGContext2D*>(c->thisObject().data());
- if (c->argumentCount() == 3) {
- ctx2d->drawImage(c->argument(0).toString()
- ,c->argument(1).toNumber()
- ,c->argument(2).toNumber());
- } else if (c->argumentCount() == 5) {
- ctx2d->drawImage(c->argument(0).toString()
- ,c->argument(1).toNumber()
- ,c->argument(2).toNumber()
- ,c->argument(3).toNumber()
- ,c->argument(4).toNumber());
- } else if (c->argumentCount() == 9) {
- ctx2d->drawImage(c->argument(0).toString()
- ,c->argument(1).toNumber()
- ,c->argument(2).toNumber()
- ,c->argument(3).toNumber()
- ,c->argument(4).toNumber()
- ,c->argument(5).toNumber()
- ,c->argument(6).toNumber()
- ,c->argument(7).toNumber()
- ,c->argument(8).toNumber());
- }
- return e->nullValue();
+ return v8::Undefined();
}
-// pixel manipulation
-static QScriptValue ctx2d_createImageData(QScriptContext *c, QScriptEngine *e)
+static void ctx2d_font_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
{
- //#TODO
- return QScriptValue();
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+ if (!r || !r->context)
+ V8THROW_ERROR_SETTER("Not a Context2D object");
+
+ Q_UNUSED(value);
}
-static QScriptValue ctx2d_getImageData(QScriptContext *c, QScriptEngine *e)
+
+v8::Handle<v8::Value> ctx2d_textAlign(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
- //#TODO
- return QScriptValue();
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ return v8::Undefined();
}
-static QScriptValue ctx2d_putImageData(QScriptContext *c, QScriptEngine *e)
+
+static void ctx2d_textAlign_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
{
- //#TODO
- return QScriptValue();
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+ if (!r || !r->context)
+ V8THROW_ERROR_SETTER("Not a Context2D object");
+
+ Q_UNUSED(value);
}
-//Image Data Interface
-static QScriptValue ctx2d_imageData_data(QScriptContext *c, QScriptEngine *e)
+v8::Handle<v8::Value> ctx2d_textBaseline(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
- //#TODO
- return QScriptValue();
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ return v8::Undefined();
}
-static QScriptValue ctx2d_imageData_height(QScriptContext *c, QScriptEngine *e)
+
+static void ctx2d_textBaseline_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
{
- //#TODO
- return QScriptValue();
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+ if (!r || !r->context)
+ V8THROW_ERROR_SETTER("Not a Context2D object");
+
+ Q_UNUSED(value);
}
-static QScriptValue ctx2d_imageData_width(QScriptContext *c, QScriptEngine *e)
+
+static v8::Handle<v8::Value> ctx2d_fillText(const v8::Arguments &args)
{
- //#TODO
- return QScriptValue();
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ QV8Engine *engine = V8ENGINE();
+
+ if (args.Length() == 3) {
+ r->context->fillText(engine->toString(args[0]),
+ args[1]->NumberValue(),
+ args[2]->NumberValue());
+ }
+
+ return v8::Undefined();
}
-//CanvasPixelArray interface
-static QScriptValue ctx2d_pixelArray_length(QScriptContext *c, QScriptEngine *e)
+static v8::Handle<v8::Value> ctx2d_strokeText(const v8::Arguments &args)
{
- //#TODO
- return QScriptValue();
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ if (!r || !r->context)
+ V8THROW_ERROR("Not a Context2D object");
+
+ QV8Engine *engine = V8ENGINE();
+
+ if (args.Length() == 3) {
+ r->context->strokeText(engine->toString(args[0]),
+ args[1]->NumberValue(),
+ args[2]->NumberValue());
+ }
+
+ return v8::Undefined();
}
-//getter/setter by index how to?
-static QScriptValue ctx2d_pixelArray(QScriptContext *c, QScriptEngine *e)
+
+// drawing images
+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");
+
+ QV8Engine *engine = V8ENGINE();
+
+ if (args.Length() == 3) {
+ r->context->drawImage(engine->toString(args[0]),
+ args[1]->NumberValue(),
+ args[2]->NumberValue());
+ } else if (args.Length() == 5) {
+ r->context->drawImage(engine->toString(args[0]),
+ args[1]->NumberValue(),
+ args[2]->NumberValue(),
+ args[3]->NumberValue(),
+ args[4]->NumberValue());
+ } else if (args.Length() == 9) {
+ r->context->drawImage(engine->toString(args[0]),
+ args[1]->NumberValue(),
+ args[2]->NumberValue(),
+ args[3]->NumberValue(),
+ args[4]->NumberValue(),
+ args[5]->NumberValue(),
+ args[6]->NumberValue(),
+ args[7]->NumberValue(),
+ args[8]->NumberValue());
+ }
+
+ return v8::Undefined();
+}
+
+// pixel manipulation
+static v8::Handle<v8::Value> ctx2d_createImageData(const v8::Arguments &args)
{
//#TODO
- return QScriptValue();
+ return v8::Undefined();
}
-//CanvasGradient interface
-static QScriptValue ctx2d_gradient_addColorStop(QScriptContext *c, QScriptEngine *e)
+static v8::Handle<v8::Value> ctx2d_getImageData(const v8::Arguments &args)
{
//#TODO
- return QScriptValue();
+ return v8::Undefined();
}
-//TextMetrics
-static QScriptValue ctx2d_textMetrics_width(QScriptContext *c, QScriptEngine *e)
+static v8::Handle<v8::Value> ctx2d_putImageData(const v8::Arguments &args)
{
//#TODO
- return QScriptValue();
+ return v8::Undefined();
}
-
bool QSGContext2DPrivate::hasShadow() const
{
return state.shadowColor.isValid()
@@ -2132,6 +2469,593 @@ bool QSGContext2D::isPointInPath(qreal x, qreal y) const
return d->path.contains(QPointF(x, y));
}
+//copied from QtSvg (qsvghandler.cpp).
+Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok);
+// '0' is 0x30 and '9' is 0x39
+static inline bool isDigit(ushort ch)
+{
+ static quint16 magic = 0x3ff;
+ return ((ch >> 4) == 3) && (magic >> (ch & 15));
+}
+
+static qreal toDouble(const QChar *&str)
+{
+ const int maxLen = 255;//technically doubles can go til 308+ but whatever
+ char temp[maxLen+1];
+ int pos = 0;
+
+ if (*str == QLatin1Char('-')) {
+ temp[pos++] = '-';
+ ++str;
+ } else if (*str == QLatin1Char('+')) {
+ ++str;
+ }
+ while (isDigit(str->unicode()) && pos < maxLen) {
+ temp[pos++] = str->toLatin1();
+ ++str;
+ }
+ if (*str == QLatin1Char('.') && pos < maxLen) {
+ temp[pos++] = '.';
+ ++str;
+ }
+ while (isDigit(str->unicode()) && pos < maxLen) {
+ temp[pos++] = str->toLatin1();
+ ++str;
+ }
+ bool exponent = false;
+ if ((*str == QLatin1Char('e') || *str == QLatin1Char('E')) && pos < maxLen) {
+ exponent = true;
+ temp[pos++] = 'e';
+ ++str;
+ if ((*str == QLatin1Char('-') || *str == QLatin1Char('+')) && pos < maxLen) {
+ temp[pos++] = str->toLatin1();
+ ++str;
+ }
+ while (isDigit(str->unicode()) && pos < maxLen) {
+ temp[pos++] = str->toLatin1();
+ ++str;
+ }
+ }
+
+ temp[pos] = '\0';
+
+ qreal val;
+ if (!exponent && pos < 10) {
+ int ival = 0;
+ const char *t = temp;
+ bool neg = false;
+ if(*t == '-') {
+ neg = true;
+ ++t;
+ }
+ while(*t && *t != '.') {
+ ival *= 10;
+ ival += (*t) - '0';
+ ++t;
+ }
+ if(*t == '.') {
+ ++t;
+ int div = 1;
+ while(*t) {
+ ival *= 10;
+ ival += (*t) - '0';
+ div *= 10;
+ ++t;
+ }
+ val = ((qreal)ival)/((qreal)div);
+ } else {
+ val = ival;
+ }
+ if (neg)
+ val = -val;
+ } else {
+#if defined(Q_WS_QWS) && !defined(Q_OS_VXWORKS)
+ if(sizeof(qreal) == sizeof(float))
+ val = strtof(temp, 0);
+ else
+#endif
+ {
+ bool ok = false;
+ val = qstrtod(temp, 0, &ok);
+ }
+ }
+ return val;
+
+}
+static qreal toDouble(const QString &str, bool *ok = NULL)
+{
+ const QChar *c = str.constData();
+ qreal res = toDouble(c);
+ if (ok) {
+ *ok = ((*c) == QLatin1Char('\0'));
+ }
+ return res;
+}
+
+static qreal toDouble(const QStringRef &str, bool *ok = NULL)
+{
+ const QChar *c = str.constData();
+ qreal res = toDouble(c);
+ if (ok) {
+ *ok = (c == (str.constData() + str.length()));
+ }
+ return res;
+}
+static inline void parseNumbersArray(const QChar *&str, QVarLengthArray<qreal, 8> &points)
+{
+ while (str->isSpace())
+ ++str;
+ while (isDigit(str->unicode()) ||
+ *str == QLatin1Char('-') || *str == QLatin1Char('+') ||
+ *str == QLatin1Char('.')) {
+
+ points.append(toDouble(str));
+
+ while (str->isSpace())
+ ++str;
+ if (*str == QLatin1Char(','))
+ ++str;
+
+ //eat the rest of space
+ while (str->isSpace())
+ ++str;
+ }
+}
+
+static void pathArcSegment(QPainterPath &path,
+ qreal xc, qreal yc,
+ qreal th0, qreal th1,
+ qreal rx, qreal ry, qreal xAxisRotation)
+{
+ qreal sinTh, cosTh;
+ qreal a00, a01, a10, a11;
+ qreal x1, y1, x2, y2, x3, y3;
+ qreal t;
+ qreal thHalf;
+
+ sinTh = qSin(xAxisRotation * (Q_PI / 180.0));
+ cosTh = qCos(xAxisRotation * (Q_PI / 180.0));
+
+ a00 = cosTh * rx;
+ a01 = -sinTh * ry;
+ a10 = sinTh * rx;
+ a11 = cosTh * ry;
+
+ thHalf = 0.5 * (th1 - th0);
+ t = (8.0 / 3.0) * qSin(thHalf * 0.5) * qSin(thHalf * 0.5) / qSin(thHalf);
+ x1 = xc + qCos(th0) - t * qSin(th0);
+ y1 = yc + qSin(th0) + t * qCos(th0);
+ x3 = xc + qCos(th1);
+ y3 = yc + qSin(th1);
+ x2 = x3 + t * qSin(th1);
+ y2 = y3 - t * qCos(th1);
+
+ path.cubicTo(a00 * x1 + a01 * y1, a10 * x1 + a11 * y1,
+ a00 * x2 + a01 * y2, a10 * x2 + a11 * y2,
+ a00 * x3 + a01 * y3, a10 * x3 + a11 * y3);
+}
+
+static void pathArc(QPainterPath &path,
+ qreal rx,
+ qreal ry,
+ qreal x_axis_rotation,
+ int large_arc_flag,
+ int sweep_flag,
+ qreal x,
+ qreal y,
+ qreal curx, qreal cury)
+{
+ qreal sin_th, cos_th;
+ qreal a00, a01, a10, a11;
+ qreal x0, y0, x1, y1, xc, yc;
+ qreal d, sfactor, sfactor_sq;
+ qreal th0, th1, th_arc;
+ int i, n_segs;
+ qreal dx, dy, dx1, dy1, Pr1, Pr2, Px, Py, check;
+
+ rx = qAbs(rx);
+ ry = qAbs(ry);
+
+ sin_th = qSin(x_axis_rotation * (Q_PI / 180.0));
+ cos_th = qCos(x_axis_rotation * (Q_PI / 180.0));
+
+ dx = (curx - x) / 2.0;
+ dy = (cury - y) / 2.0;
+ dx1 = cos_th * dx + sin_th * dy;
+ dy1 = -sin_th * dx + cos_th * dy;
+ Pr1 = rx * rx;
+ Pr2 = ry * ry;
+ Px = dx1 * dx1;
+ Py = dy1 * dy1;
+ /* Spec : check if radii are large enough */
+ check = Px / Pr1 + Py / Pr2;
+ if (check > 1) {
+ rx = rx * qSqrt(check);
+ ry = ry * qSqrt(check);
+ }
+
+ a00 = cos_th / rx;
+ a01 = sin_th / rx;
+ a10 = -sin_th / ry;
+ a11 = cos_th / ry;
+ x0 = a00 * curx + a01 * cury;
+ y0 = a10 * curx + a11 * cury;
+ x1 = a00 * x + a01 * y;
+ y1 = a10 * x + a11 * y;
+ /* (x0, y0) is current point in transformed coordinate space.
+ (x1, y1) is new point in transformed coordinate space.
+
+ The arc fits a unit-radius circle in this space.
+ */
+ d = (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0);
+ sfactor_sq = 1.0 / d - 0.25;
+ if (sfactor_sq < 0) sfactor_sq = 0;
+ sfactor = qSqrt(sfactor_sq);
+ if (sweep_flag == large_arc_flag) sfactor = -sfactor;
+ xc = 0.5 * (x0 + x1) - sfactor * (y1 - y0);
+ yc = 0.5 * (y0 + y1) + sfactor * (x1 - x0);
+ /* (xc, yc) is center of the circle. */
+
+ th0 = qAtan2(y0 - yc, x0 - xc);
+ th1 = qAtan2(y1 - yc, x1 - xc);
+
+ th_arc = th1 - th0;
+ if (th_arc < 0 && sweep_flag)
+ th_arc += 2 * Q_PI;
+ else if (th_arc > 0 && !sweep_flag)
+ th_arc -= 2 * Q_PI;
+
+ n_segs = qCeil(qAbs(th_arc / (Q_PI * 0.5 + 0.001)));
+
+ for (i = 0; i < n_segs; i++) {
+ pathArcSegment(path, xc, yc,
+ th0 + i * th_arc / n_segs,
+ th0 + (i + 1) * th_arc / n_segs,
+ rx, ry, x_axis_rotation);
+ }
+}
+
+
+static bool parsePathDataFast(const QString &dataStr, QPainterPath &path)
+{
+ qreal x0 = 0, y0 = 0; // starting point
+ qreal x = 0, y = 0; // current point
+ char lastMode = 0;
+ QPointF ctrlPt;
+ const QChar *str = dataStr.constData();
+ const QChar *end = str + dataStr.size();
+
+ while (str != end) {
+ while (str->isSpace())
+ ++str;
+ QChar pathElem = *str;
+ ++str;
+ QChar endc = *end;
+ *const_cast<QChar *>(end) = 0; // parseNumbersArray requires 0-termination that QStringRef cannot guarantee
+ QVarLengthArray<qreal, 8> arg;
+ parseNumbersArray(str, arg);
+ *const_cast<QChar *>(end) = endc;
+ if (pathElem == QLatin1Char('z') || pathElem == QLatin1Char('Z'))
+ arg.append(0);//dummy
+ const qreal *num = arg.constData();
+ int count = arg.count();
+ while (count > 0) {
+ qreal offsetX = x; // correction offsets
+ qreal offsetY = y; // for relative commands
+ switch (pathElem.unicode()) {
+ case 'm': {
+ if (count < 2) {
+ num++;
+ count--;
+ break;
+ }
+ x = x0 = num[0] + offsetX;
+ y = y0 = num[1] + offsetY;
+ num += 2;
+ count -= 2;
+ path.moveTo(x0, y0);
+
+ // As per 1.2 spec 8.3.2 The "moveto" commands
+ // If a 'moveto' is followed by multiple pairs of coordinates without explicit commands,
+ // the subsequent pairs shall be treated as implicit 'lineto' commands.
+ pathElem = QLatin1Char('l');
+ }
+ break;
+ case 'M': {
+ if (count < 2) {
+ num++;
+ count--;
+ break;
+ }
+ x = x0 = num[0];
+ y = y0 = num[1];
+ num += 2;
+ count -= 2;
+ path.moveTo(x0, y0);
+
+ // As per 1.2 spec 8.3.2 The "moveto" commands
+ // If a 'moveto' is followed by multiple pairs of coordinates without explicit commands,
+ // the subsequent pairs shall be treated as implicit 'lineto' commands.
+ pathElem = QLatin1Char('L');
+ }
+ break;
+ case 'z':
+ case 'Z': {
+ x = x0;
+ y = y0;
+ count--; // skip dummy
+ num++;
+ path.closeSubpath();
+ }
+ break;
+ case 'l': {
+ if (count < 2) {
+ num++;
+ count--;
+ break;
+ }
+ x = num[0] + offsetX;
+ y = num[1] + offsetY;
+ num += 2;
+ count -= 2;
+ path.lineTo(x, y);
+
+ }
+ break;
+ case 'L': {
+ if (count < 2) {
+ num++;
+ count--;
+ break;
+ }
+ x = num[0];
+ y = num[1];
+ num += 2;
+ count -= 2;
+ path.lineTo(x, y);
+ }
+ break;
+ case 'h': {
+ x = num[0] + offsetX;
+ num++;
+ count--;
+ path.lineTo(x, y);
+ }
+ break;
+ case 'H': {
+ x = num[0];
+ num++;
+ count--;
+ path.lineTo(x, y);
+ }
+ break;
+ case 'v': {
+ y = num[0] + offsetY;
+ num++;
+ count--;
+ path.lineTo(x, y);
+ }
+ break;
+ case 'V': {
+ y = num[0];
+ num++;
+ count--;
+ path.lineTo(x, y);
+ }
+ break;
+ case 'c': {
+ if (count < 6) {
+ num += count;
+ count = 0;
+ break;
+ }
+ QPointF c1(num[0] + offsetX, num[1] + offsetY);
+ QPointF c2(num[2] + offsetX, num[3] + offsetY);
+ QPointF e(num[4] + offsetX, num[5] + offsetY);
+ num += 6;
+ count -= 6;
+ path.cubicTo(c1, c2, e);
+ ctrlPt = c2;
+ x = e.x();
+ y = e.y();
+ break;
+ }
+ case 'C': {
+ if (count < 6) {
+ num += count;
+ count = 0;
+ break;
+ }
+ QPointF c1(num[0], num[1]);
+ QPointF c2(num[2], num[3]);
+ QPointF e(num[4], num[5]);
+ num += 6;
+ count -= 6;
+ path.cubicTo(c1, c2, e);
+ ctrlPt = c2;
+ x = e.x();
+ y = e.y();
+ break;
+ }
+ case 's': {
+ if (count < 4) {
+ num += count;
+ count = 0;
+ break;
+ }
+ QPointF c1;
+ if (lastMode == 'c' || lastMode == 'C' ||
+ lastMode == 's' || lastMode == 'S')
+ c1 = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y());
+ else
+ c1 = QPointF(x, y);
+ QPointF c2(num[0] + offsetX, num[1] + offsetY);
+ QPointF e(num[2] + offsetX, num[3] + offsetY);
+ num += 4;
+ count -= 4;
+ path.cubicTo(c1, c2, e);
+ ctrlPt = c2;
+ x = e.x();
+ y = e.y();
+ break;
+ }
+ case 'S': {
+ if (count < 4) {
+ num += count;
+ count = 0;
+ break;
+ }
+ QPointF c1;
+ if (lastMode == 'c' || lastMode == 'C' ||
+ lastMode == 's' || lastMode == 'S')
+ c1 = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y());
+ else
+ c1 = QPointF(x, y);
+ QPointF c2(num[0], num[1]);
+ QPointF e(num[2], num[3]);
+ num += 4;
+ count -= 4;
+ path.cubicTo(c1, c2, e);
+ ctrlPt = c2;
+ x = e.x();
+ y = e.y();
+ break;
+ }
+ case 'q': {
+ if (count < 4) {
+ num += count;
+ count = 0;
+ break;
+ }
+ QPointF c(num[0] + offsetX, num[1] + offsetY);
+ QPointF e(num[2] + offsetX, num[3] + offsetY);
+ num += 4;
+ count -= 4;
+ path.quadTo(c, e);
+ ctrlPt = c;
+ x = e.x();
+ y = e.y();
+ break;
+ }
+ case 'Q': {
+ if (count < 4) {
+ num += count;
+ count = 0;
+ break;
+ }
+ QPointF c(num[0], num[1]);
+ QPointF e(num[2], num[3]);
+ num += 4;
+ count -= 4;
+ path.quadTo(c, e);
+ ctrlPt = c;
+ x = e.x();
+ y = e.y();
+ break;
+ }
+ case 't': {
+ if (count < 2) {
+ num += count;
+ count = 0;
+ break;
+ }
+ QPointF e(num[0] + offsetX, num[1] + offsetY);
+ num += 2;
+ count -= 2;
+ QPointF c;
+ if (lastMode == 'q' || lastMode == 'Q' ||
+ lastMode == 't' || lastMode == 'T')
+ c = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y());
+ else
+ c = QPointF(x, y);
+ path.quadTo(c, e);
+ ctrlPt = c;
+ x = e.x();
+ y = e.y();
+ break;
+ }
+ case 'T': {
+ if (count < 2) {
+ num += count;
+ count = 0;
+ break;
+ }
+ QPointF e(num[0], num[1]);
+ num += 2;
+ count -= 2;
+ QPointF c;
+ if (lastMode == 'q' || lastMode == 'Q' ||
+ lastMode == 't' || lastMode == 'T')
+ c = QPointF(2*x-ctrlPt.x(), 2*y-ctrlPt.y());
+ else
+ c = QPointF(x, y);
+ path.quadTo(c, e);
+ ctrlPt = c;
+ x = e.x();
+ y = e.y();
+ break;
+ }
+ case 'a': {
+ if (count < 7) {
+ num += count;
+ count = 0;
+ break;
+ }
+ qreal rx = (*num++);
+ qreal ry = (*num++);
+ qreal xAxisRotation = (*num++);
+ qreal largeArcFlag = (*num++);
+ qreal sweepFlag = (*num++);
+ qreal ex = (*num++) + offsetX;
+ qreal ey = (*num++) + offsetY;
+ count -= 7;
+ qreal curx = x;
+ qreal cury = y;
+ pathArc(path, rx, ry, xAxisRotation, int(largeArcFlag),
+ int(sweepFlag), ex, ey, curx, cury);
+
+ x = ex;
+ y = ey;
+ }
+ break;
+ case 'A': {
+ if (count < 7) {
+ num += count;
+ count = 0;
+ break;
+ }
+ qreal rx = (*num++);
+ qreal ry = (*num++);
+ qreal xAxisRotation = (*num++);
+ qreal largeArcFlag = (*num++);
+ qreal sweepFlag = (*num++);
+ qreal ex = (*num++);
+ qreal ey = (*num++);
+ count -= 7;
+ qreal curx = x;
+ qreal cury = y;
+ pathArc(path, rx, ry, xAxisRotation, int(largeArcFlag),
+ int(sweepFlag), ex, ey, curx, cury);
+
+ x = ex;
+ y = ey;
+ }
+ break;
+ default:
+ return false;
+ }
+ lastMode = pathElem.toLatin1();
+ }
+ }
+ return true;
+}
+
+void QSGContext2D::setPathString(const QString& path)
+{
+ Q_D(QSGContext2D);
+ d->path = QPainterPath();
+ parsePathDataFast(path, d->path);
+}
QList<int> QSGContext2D::getImageData(qreal sx, qreal sy, qreal sw, qreal sh)
{
@@ -2184,78 +3108,110 @@ bool QSGContext2D::isDirty() const
return !d->commands.isEmpty();
}
-QScriptValue QSGContext2D::scriptValue() const
+v8::Handle<v8::Object> QSGContext2D::v8value() const
{
Q_D(const QSGContext2D);
- return d->scriptValue;
-}
-
-void QSGContext2D::setScriptEngine(QScriptEngine *eng)
+ return d->v8value;
+}
+
+class QSGContext2DEngineData : public QV8Engine::Deletable
+{
+public:
+ QSGContext2DEngineData(QV8Engine *engine);
+ ~QSGContext2DEngineData();
+
+ v8::Persistent<v8::Function> constructor;
+};
+
+QSGContext2DEngineData::QSGContext2DEngineData(QV8Engine *engine)
+{
+ v8::HandleScope handle_scope;
+ v8::Context::Scope scope(engine->context());
+
+ v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
+ ft->InstanceTemplate()->SetHasExternalResource(true);
+ 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));
+ 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("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));
+ ft->InstanceTemplate()->SetAccessor(v8::String::New("strokeStyle"), ctx2d_strokeStyle, ctx2d_strokeStyle_set, v8::External::Wrap(engine));
+ ft->InstanceTemplate()->SetAccessor(v8::String::New("fillColor"), ctx2d_fillColor, ctx2d_fillColor_set, v8::External::Wrap(engine));
+ ft->InstanceTemplate()->SetAccessor(v8::String::New("strokeColor"), ctx2d_strokeColor, ctx2d_strokeColor_set, v8::External::Wrap(engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("createLinearGradient"), V8FUNCTION(ctx2d_createLinearGradient, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("createRadialGradient"), V8FUNCTION(ctx2d_createRadialGradient, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("createPattern"), V8FUNCTION(ctx2d_createPattern, engine));
+ ft->InstanceTemplate()->SetAccessor(v8::String::New("lineCap"), ctx2d_lineCap, ctx2d_lineCap_set, v8::External::Wrap(engine));
+ ft->InstanceTemplate()->SetAccessor(v8::String::New("lineJoin"), ctx2d_lineJoin, ctx2d_lineJoin_set, v8::External::Wrap(engine));
+ ft->InstanceTemplate()->SetAccessor(v8::String::New("lineWidth"), ctx2d_lineWidth, ctx2d_lineWidth_set, v8::External::Wrap(engine));
+ ft->InstanceTemplate()->SetAccessor(v8::String::New("miterLimit"), ctx2d_miterLimit, ctx2d_miterLimit_set, v8::External::Wrap(engine));
+ ft->InstanceTemplate()->SetAccessor(v8::String::New("shadowBlur"), ctx2d_shadowBlur, ctx2d_shadowBlur_set, v8::External::Wrap(engine));
+ ft->InstanceTemplate()->SetAccessor(v8::String::New("shadowColor"), ctx2d_shadowColor, ctx2d_shadowColor_set, v8::External::Wrap(engine));
+ ft->InstanceTemplate()->SetAccessor(v8::String::New("shadowOffsetX"), ctx2d_shadowOffsetX, ctx2d_shadowOffsetX_set, v8::External::Wrap(engine));
+ ft->InstanceTemplate()->SetAccessor(v8::String::New("shadowOffsetY"), ctx2d_shadowOffsetY, ctx2d_shadowOffsetY_set, v8::External::Wrap(engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("clearRect"), V8FUNCTION(ctx2d_clearRect, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("fillRect"), V8FUNCTION(ctx2d_fillRect, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("strokeRect"), V8FUNCTION(ctx2d_strokeRect, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("arc"), V8FUNCTION(ctx2d_arc, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("arcTo"), V8FUNCTION(ctx2d_arcTo, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("beginPath"), V8FUNCTION(ctx2d_beginPath, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("bezierCurveTo"), V8FUNCTION(ctx2d_bezierCurveTo, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("clip"), V8FUNCTION(ctx2d_clip, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("closePath"), V8FUNCTION(ctx2d_closePath, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("fill"), V8FUNCTION(ctx2d_fill, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("lineTo"), V8FUNCTION(ctx2d_lineTo, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("moveTo"), V8FUNCTION(ctx2d_moveTo, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("quadraticCurveTo"), V8FUNCTION(ctx2d_quadraticCurveTo, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("rect"), V8FUNCTION(ctx2d_rect, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("stroke"), V8FUNCTION(ctx2d_stroke, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("isPointInPath"), V8FUNCTION(ctx2d_isPointInPath, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("setPathString"), V8FUNCTION(ctx2d_setPathString, engine));
+ ft->InstanceTemplate()->SetAccessor(v8::String::New("font"), ctx2d_font, ctx2d_font_set, v8::External::Wrap(engine));
+ ft->InstanceTemplate()->SetAccessor(v8::String::New("textAlign"), ctx2d_textAlign, ctx2d_textAlign_set, v8::External::Wrap(engine));
+ ft->InstanceTemplate()->SetAccessor(v8::String::New("textBaseline"), ctx2d_textBaseline, ctx2d_textBaseline_set, v8::External::Wrap(engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("fillText"), V8FUNCTION(ctx2d_fillText, engine));
+ // ft->PrototypeTemplate()->Set(v8::String::New("measureText"), V8FUNCTION(ctx2d_measureText, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("strokeText"), V8FUNCTION(ctx2d_strokeText, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("drawImage"), V8FUNCTION(ctx2d_drawImage, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("createImageData"), V8FUNCTION(ctx2d_createImageData, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("getImageData"), V8FUNCTION(ctx2d_getImageData, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("putImageData"), V8FUNCTION(ctx2d_putImageData, engine));
+
+ constructor = qPersistentNew(ft->GetFunction());
+}
+
+QSGContext2DEngineData::~QSGContext2DEngineData()
+{
+ qPersistentDispose(constructor);
+}
+
+V8_DEFINE_EXTENSION(QSGContext2DEngineData, engineData);
+
+void QSGContext2D::setV8Engine(QV8Engine *engine)
{
Q_D(QSGContext2D);
- if (d->scriptEngine != eng) {
- d->scriptEngine = eng;
- d->scriptValue = eng->newObject();
- d->scriptValue.setData(eng->toScriptValue(this));
- d->scriptValue.setProperty(QLatin1String("sync"), eng->newFunction(ctx2d_sync));
- d->scriptValue.setProperty(QLatin1String("canvas"), eng->newFunction(ctx2d_canvas),QScriptValue::PropertyGetter);
- d->scriptValue.setProperty(QLatin1String("restore"), eng->newFunction(ctx2d_restore));
- d->scriptValue.setProperty(QLatin1String("save"), eng->newFunction(ctx2d_save));
- d->scriptValue.setProperty(QLatin1String("rotate"), eng->newFunction(ctx2d_rotate, 1));
- d->scriptValue.setProperty(QLatin1String("scale"), eng->newFunction(ctx2d_scale, 2));
- d->scriptValue.setProperty(QLatin1String("setTransform"), eng->newFunction(ctx2d_setTransform, 6));
- d->scriptValue.setProperty(QLatin1String("transform"), eng->newFunction(ctx2d_transform, 6));
- d->scriptValue.setProperty(QLatin1String("translate"), eng->newFunction(ctx2d_translate, 2));
- d->scriptValue.setProperty(QLatin1String("globalAlpha"), eng->newFunction(ctx2d_globalAlpha), QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
- d->scriptValue.setProperty(QLatin1String("globalCompositeOperation"), eng->newFunction(ctx2d_globalCompositeOperation), QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
- d->scriptValue.setProperty(QLatin1String("fillStyle"), eng->newFunction(ctx2d_fillStyle), QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
- d->scriptValue.setProperty(QLatin1String("strokeStyle"), eng->newFunction(ctx2d_strokeStyle), QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
- d->scriptValue.setProperty(QLatin1String("fillColor"), eng->newFunction(ctx2d_fillColor), QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
- d->scriptValue.setProperty(QLatin1String("strokeColor"), eng->newFunction(ctx2d_strokeColor), QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
- d->scriptValue.setProperty(QLatin1String("createLinearGradient"), eng->newFunction(ctx2d_createLinearGradient, 4));
- d->scriptValue.setProperty(QLatin1String("createRadialGradient"), eng->newFunction(ctx2d_createRadialGradient, 6));
- d->scriptValue.setProperty(QLatin1String("createPattern"), eng->newFunction(ctx2d_createPattern, 2));
- d->scriptValue.setProperty(QLatin1String("lineCap"), eng->newFunction(ctx2d_lineCap), QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
- d->scriptValue.setProperty(QLatin1String("lineJoin"), eng->newFunction(ctx2d_lineJoin), QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
- d->scriptValue.setProperty(QLatin1String("lineWidth"), eng->newFunction(ctx2d_lineWidth), QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
- d->scriptValue.setProperty(QLatin1String("miterLimit"), eng->newFunction(ctx2d_miterLimit), QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
- d->scriptValue.setProperty(QLatin1String("shadowBlur"), eng->newFunction(ctx2d_shadowBlur), QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
- d->scriptValue.setProperty(QLatin1String("shadowColor"), eng->newFunction(ctx2d_shadowColor), QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
- d->scriptValue.setProperty(QLatin1String("shadowOffsetX"), eng->newFunction(ctx2d_shadowOffsetX), QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
- d->scriptValue.setProperty(QLatin1String("shadowOffsetY"), eng->newFunction(ctx2d_shadowOffsetY), QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
- d->scriptValue.setProperty(QLatin1String("clearRect"), eng->newFunction(ctx2d_clearRect, 4));
- d->scriptValue.setProperty(QLatin1String("fillRect"), eng->newFunction(ctx2d_fillRect, 4));
- d->scriptValue.setProperty(QLatin1String("strokeRect"), eng->newFunction(ctx2d_strokeRect, 4));
- d->scriptValue.setProperty(QLatin1String("arc"), eng->newFunction(ctx2d_arc, 6));
- d->scriptValue.setProperty(QLatin1String("arcTo"), eng->newFunction(ctx2d_arcTo, 5));
- d->scriptValue.setProperty(QLatin1String("beginPath"), eng->newFunction(ctx2d_beginPath));
- d->scriptValue.setProperty(QLatin1String("bezierCurveTo"), eng->newFunction(ctx2d_bezierCurveTo, 6));
- d->scriptValue.setProperty(QLatin1String("clip"), eng->newFunction(ctx2d_clip));
- d->scriptValue.setProperty(QLatin1String("closePath"), eng->newFunction(ctx2d_closePath));
- d->scriptValue.setProperty(QLatin1String("fill"), eng->newFunction(ctx2d_fill));
- d->scriptValue.setProperty(QLatin1String("lineTo"), eng->newFunction(ctx2d_lineTo, 2));
- d->scriptValue.setProperty(QLatin1String("moveTo"), eng->newFunction(ctx2d_moveTo, 2));
- d->scriptValue.setProperty(QLatin1String("quadraticCurveTo"), eng->newFunction(ctx2d_quadraticCurveTo, 4));
- d->scriptValue.setProperty(QLatin1String("rect"), eng->newFunction(ctx2d_rect, 4));
- d->scriptValue.setProperty(QLatin1String("stroke"), eng->newFunction(ctx2d_stroke));
- d->scriptValue.setProperty(QLatin1String("isPointInPath"), eng->newFunction(ctx2d_isPointInPath, 2));
- d->scriptValue.setProperty(QLatin1String("font"), eng->newFunction(ctx2d_font), QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
- d->scriptValue.setProperty(QLatin1String("textAlign"), eng->newFunction(ctx2d_textAlign), QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
- d->scriptValue.setProperty(QLatin1String("textBaseline"), eng->newFunction(ctx2d_textBaseline), QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
- d->scriptValue.setProperty(QLatin1String("fillText"), eng->newFunction(ctx2d_fillText, 4));
- //d->scriptValue.setProperty(QLatin1String("measureText"), eng->newFunction(ctx2d_measureText, 1));
- d->scriptValue.setProperty(QLatin1String("strokeText"), eng->newFunction(ctx2d_strokeText, 4));
- d->scriptValue.setProperty(QLatin1String("drawImage"), eng->newFunction(ctx2d_drawImage, 9));
- d->scriptValue.setProperty(QLatin1String("createImageData"), eng->newFunction(ctx2d_createImageData, 2));
- d->scriptValue.setProperty(QLatin1String("getImageData"), eng->newFunction(ctx2d_getImageData, 4));
- d->scriptValue.setProperty(QLatin1String("putImageData"), eng->newFunction(ctx2d_putImageData, 7));
- }
-}
-
-QScriptEngine *QSGContext2D::scriptEngine() const
-{
- Q_D(const QSGContext2D);
- return d->scriptEngine;
+ if (d->v8engine != engine) {
+ d->v8engine = engine;
+
+ qPersistentDispose(d->v8value);
+
+ if (d->v8engine == 0)
+ return;
+
+ QSGContext2DEngineData *ed = engineData(engine);
+ d->v8value = qPersistentNew(ed->constructor->NewInstance());
+ QV8Context2DResource *r = new QV8Context2DResource(engine);
+ r->context = this;
+ d->v8value->SetExternalResource(r);
+ }
}
void QSGContext2D::addref()
@@ -2274,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<d.data.length; i++)"
- " d.data[i] = 255;"
- " return d;"
- " };"
- " this.getImageData = function(sx, sy, sw, sh) {"
- " var imageData = new CanvasImageData(sw, sh, this._ctx.getImageData(sx, sy, sw, sh));"
- " return imageData;"
- " };"
- " this.sync = function() {"
- " this._ctx.processCommands(this._commands);"
- " this._commands.length = 0;"
- " };");
-
- script.append(QString::fromLatin1(
- "this.save = function() {"
- " this._commands.push([%1]);"
- "};").arg(Save));
-
- script.append(QString::fromLatin1(
- "this.restore = function() {"
- " this._commands.push([%1]);"
- "};").arg(Restore));
-
- script.append(QString::fromLatin1(
- "this.scale = function(x, y) {"
- " this._commands.push([%1, x, y]);"
- "};").arg(Scale));
-
- script.append(QString::fromLatin1(
- "this.createImage = function(url) {"
- " return this._ctx.createImage(url);"
- "};"));
-
- script.append(QString::fromLatin1(
- "this.rotate = function(x) {"
- " this._commands.push([%1, x]);"
- "};").arg(Rotate));
-
- script.append(QString::fromLatin1(
- "this.translate = function(x, y) {"
- " this._commands.push([%1, x, y]);"
- "};").arg(Translate));
-
- script.append(QString::fromLatin1(
- "this.transform = function(a1, a2, a3, a4, a5, a6) {"
- " this._commands.push([%1, a1, a2, a3, a4, a5, a6]);"
- "};").arg(Transform));
-
- script.append(QString::fromLatin1(
- "this.setTransform = function(a1, a2, a3, a4, a5, a6) {"
- " this._commands.push([%1, a1, a2, a3, a4, a5, a6]);"
- "};").arg(SetTransform));
-
- script.append(QString::fromLatin1(
- "this.clearRect = function(x, y, w, h) {"
- " this._commands.push([%1, x, y, w, h]);"
- "};").arg(ClearRect));
-
- script.append(QString::fromLatin1(
- "this.fillRect = function(x, y, w, h) {"
- " this._commands.push([%1, x, y, w, h]);"
- "};").arg(FillRect));
-
- script.append(QString::fromLatin1(
- "this.strokeRect = function(x, y, w, h) {"
- " this._commands.push([%1, x, y, w, h]);"
- "};").arg(StrokeRect));
-
- script.append(QString::fromLatin1(
- "this.beginPath = function() {"
- " this._commands.push([%1]);"
- "};").arg(BeginPath));
-
- script.append(QString::fromLatin1(
- "this.closePath = function() {"
- " this._commands.push([%1]);"
- "};").arg(ClosePath));
-
- script.append(QString::fromLatin1(
- "this.moveTo = function(x, y) {"
- " this._commands.push([%1, x, y]);"
- "};").arg(MoveTo));
-
- script.append(QString::fromLatin1(
- "this.lineTo = function(x, y) {"
- " this._commands.push([%1, x, y]);"
- "};").arg(LineTo));
-
- script.append(QString::fromLatin1(
- "this.quadraticCurveTo = function(a1, a2, a3, a4) {"
- " this._commands.push([%1, a1, a2, a3, a4]);"
- "};").arg(QuadraticCurveTo));
-
- script.append(QString::fromLatin1(
- "this.bezierCurveTo = function(a1, a2, a3, a4, a5, a6) {"
- " this._commands.push([%1, a1, a2, a3, a4, a5, a6]);"
- "};").arg(BezierCurveTo));
-
- script.append(QString::fromLatin1(
- "this.arcTo = function(x1, y1, x2, y2, radius) {"
- " this._commands.push([%1, x1, y1, x2, y2, radius]);"
- "};").arg(ArcTo));
-
- script.append(QString::fromLatin1(
- "this.rect = function(x, y, w, h) {"
- " this._commands.push([%1, x, y, w, h]);"
- "};").arg(Rect));
-
- script.append(QString::fromLatin1(
- "this.rect = function(x, y, radius, startAngle, endAngle, anticlockwise) {"
- " this._commands.push([%1, x, y, radius, startAngle, endAngle, anticlockwise]);"
- "};").arg(Arc));
-
- script.append(QString::fromLatin1(
- "this.fill = function() {"
- " this._commands.push([%1]);"
- "};").arg(Fill));
-
- script.append(QString::fromLatin1(
- "this.stroke = function() {"
- " this._commands.push([%1]);"
- "};").arg(Stroke));
-
- script.append(QString::fromLatin1(
- "this.clip = function() {"
- " this._commands.push([%1]);"
- "};").arg(Clip));
-
- script.append(QString::fromLatin1(
- " this.__defineGetter__(\"globalAlpha\", function() {"
- " return this._globalAlpha;"
- " });"
- " this.__defineSetter__(\"globalAlpha\", function(v) {"
- " this._globalAlpha = v;"
- " this._commands.push([%1, v]);"
- " });").arg(GlobalAlpha));
-
- script.append(QString::fromLatin1(
- " this.__defineGetter__(\"globalCompositeOperation\", function() {"
- " return this._globalCompositeOperation;"
- " });"
- " this.__defineSetter__(\"globalCompositeOperation\", function(v) {"
- " this._globalCompositeOperation = v;"
- " this._commands.push([%1, v]);"
- " });").arg(GlobalCompositeOperation));
-
- script.append(QString::fromLatin1(
- " this.__defineGetter__(\"strokeStyle\", function() {return this._strokeStyle; });"
- " this.__defineSetter__(\"strokeStyle\", function(v) {"
- " this._commands.push([%1, v]);"
- " this._strokeStyle = v;"
- " });").arg(StrokeStyle));
-
- script.append(QString::fromLatin1(
- " this.__defineGetter__(\"fillStyle\", function() {return this._fillStyle; });"
- " this.__defineSetter__(\"fillStyle\", function(v) {"
- " this._commands.push([%1, v]);"
- " this._fillStyle = v;"
- " });").arg(FillStyle));
-
- script.append(QString::fromLatin1(
- " this.__defineGetter__(\"strokeColor\", function() {return this._strokeColor; });"
- " this.__defineSetter__(\"strokeColor\", function(v) {"
- " this._commands.push([%1, v]);"
- " this._strokeColor = v;"
- " });").arg(StrokeColor));
-
- script.append(QString::fromLatin1(
- " this.__defineGetter__(\"fillColor\", function() {return this._fillColor; });"
- " this.__defineSetter__(\"fillColor\", function(v) {"
- " this._commands.push([%1, v]);"
- " this._fillColor = v;"
- " });").arg(FillColor));
-
- script.append(QString::fromLatin1(
- " this.__defineGetter__(\"lineWidth\", function() {return this._lineWidth; });"
- " this.__defineSetter__(\"lineWidth\", function(v) {"
- " this._commands.push([%1, v]);"
- " this._lineWidth = v;"
- " });").arg(LineWidth));
-
- script.append(QString::fromLatin1(
- " this.__defineGetter__(\"lineCap\", function() {return this._lineCap; });"
- " this.__defineSetter__(\"lineCap\", function(v) {"
- " this._commands.push([%1, v]);"
- " this._lineCap = v;"
- " });").arg(LineCap));
-
-
- script.append(QString::fromLatin1(
- " this.__defineGetter__(\"lineJoin\", function() {return this._lineJoin; });"
- " this.__defineSetter__(\"lineJoin\", function(v) {"
- " this._commands.push([%1, v]);"
- " this._lineJoin = v;"
- " });").arg(LineJoin));
-
- script.append(QString::fromLatin1(
- " this.__defineGetter__(\"miterLimit\", function() {return this._miterLimit; });"
- " this.__defineSetter__(\"miterLimit\", function(v) {"
- " this._commands.push([%1, v]);"
- " this._miterLimit = v;"
- " });").arg(MiterLimit));
-
-
- script.append(QString::fromLatin1(
- " this.__defineGetter__(\"shadowOffsetX\", function() {return this._shadowOffsetX; });"
- " this.__defineSetter__(\"shadowOffsetX\", function(v) {"
- " this._commands.push([%1, v]);"
- " this._shadowOffsetX = v;"
- " });").arg(ShadowOffsetX));
-
- script.append(QString::fromLatin1(
- " this.__defineGetter__(\"shadowOffsetY\", function() {return this._shadowOffsetY; });"
- " this.__defineSetter__(\"shadowOffsetY\", function(v) {"
- " this._commands.push([%1, v]);"
- " this._shadowOffsetY = v;"
- " });").arg(ShadowOffsetY));
-
- script.append(QString::fromLatin1(
- " this.__defineGetter__(\"shadowBlur\", function() {return this._shadowBlur; });"
- " this.__defineSetter__(\"shadowBlur\", function(v) {"
- " this._commands.push([%1, v]);"
- " this._shadowBlur = v;"
- " });").arg(ShadowBlur));
-
- script.append(QString::fromLatin1(
- " this.__defineGetter__(\"shadowColor\", function() {return this._shadowColor; });"
- " this.__defineSetter__(\"shadowColor\", function(v) {"
- " this._commands.push([%1, v]);"
- " this._shadowColor = v;"
- " });").arg(ShadowColor));
-
- script.append(QString::fromLatin1(
- " this.__defineGetter__(\"font\", function() {return this._font; });"
- " this.__defineSetter__(\"font\", function(v) {"
- " this._commands.push([%1, v]);"
- " this._font = v;"
- " });").arg(Font));
-
- script.append(QString::fromLatin1(
- " this.__defineGetter__(\"textBaseline\", function() {return this._textBaseline; });"
- " this.__defineSetter__(\"textBaseline\", function(v) {"
- " this._commands.push([%1, v]);"
- " this._textBaseline = v;"
- " });").arg(TextBaseline));
-
- script.append(QString::fromLatin1(
- " this.__defineGetter__(\"textAlign\", function() {return this._textAlign; });"
- " this.__defineSetter__(\"textAlign\", function(v) {"
- " this._commands.push([%1, v]);"
- " this._textAlign = v;"
- " });").arg(TextAlign));
-
- script.append(QString::fromLatin1(
- "this.fillText = function(text, x, y) {"
- " this._commands.push([%1, text, x, y]);"
- "};").arg(FillText));
-
- script.append(QString::fromLatin1(
- "this.strokeText = function(text, x, y) {"
- " this._commands.push([%1, text, x, y]);"
- "};").arg(StrokeText));
-
- script.append(QString::fromLatin1(
- "this.drawImage = function() {"
- " if (arguments.length == 3) {"
- " this._commands.push([%1, arguments[0], arguments[1], arguments[2]]);"
- " } else if (arguments.length == 5) {"
- " this._commands.push([%2, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]]);"
- " } else if (arguments.length == 9) {"
- " this._commands.push([%3, arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8]]);}"
- "};").arg(DrawImage1).arg(DrawImage2).arg(DrawImage3));
-
- script.append(QString::fromLatin1(
- "this.putImageData = function() {"
- " var dx = arguments[1];"
- " var dy = arguments[2];"
- " if (arguments.length == 3) {"
- " this._commands.push([%1, arguments[0].data, dx, dy, arguments[0].width, arguments[0].height]);"
- " } else if (arguments.length == 7) {"
- " var dirtyX = arguments[3];"
- " var dirtyY = arguments[4];"
- " var dirtyWidth = arguments[5];"
- " var dirtyHeight = arguments[6];"
- " var width = arguments[0].width;"
- " var height = arguments[0].heigh;"
- " var filteredData = arguments[0].data.filter(function(element, index, array){"
- " var x=index/width;"
- " var y=index%width-1;"
- " return x >= 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
@@ -2941,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:
@@ -2962,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
@@ -2996,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
@@ -3004,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
@@ -3229,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 30af1f1cd6..924c4bf780 100644
--- a/src/declarative/items/qsgcontext2d_p.h
+++ b/src/declarative/items/qsgcontext2d_p.h
@@ -56,6 +56,7 @@
#include <QtCore/qcoreevent.h>
#include <QtCore/qvariant.h>
#include <QtScript/qscriptvalue.h>
+#include <private/qv8engine_p.h>
#include <QMutex>
#include <QWaitCondition>
#include "qsgimage_p.h"
@@ -290,6 +291,10 @@ public slots:
void clip();
bool isPointInPath(qreal x, qreal y) const;
+ //path string parser
+ //implement the W3C SVG path spec:
+ //http://www.w3.org/TR/SVG/paths.html
+ void setPathString(const QString& path);
QSGImage *createImage(const QString &url);
@@ -309,9 +314,8 @@ signals:
void painted();
public:
bool isDirty() const;
- QScriptValue scriptValue() const;
- void setScriptEngine(QScriptEngine *eng);
- QScriptEngine *scriptEngine() const;
+ v8::Handle<v8::Object> v8value() const;
+ void setV8Engine(QV8Engine *eng);
void addref();
void release();
@@ -335,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;
diff --git a/src/declarative/items/qsgcontext2d_p_p.h b/src/declarative/items/qsgcontext2d_p_p.h
index a412e6638a..4fcf40406e 100644
--- a/src/declarative/items/qsgcontext2d_p_p.h
+++ b/src/declarative/items/qsgcontext2d_p_p.h
@@ -78,12 +78,17 @@ public:
QSGContext2DPrivate()
: agent(0)
, agentData(0)
- , scriptEngine(0)
+ , v8engine(0)
, cachedImage(1,1, QImage::Format_ARGB32)
, canvas(0)
, waitingForPainting(false)
{
}
+ ~QSGContext2DPrivate()
+ {
+ qPersistentDispose(v8value);
+ }
+
void updateMatrix(const QMatrix& m);
void setSize(const QSize &s)
@@ -215,8 +220,10 @@ public:
//workerscript agent
QSGContext2D* agent;
QSGContext2DWorkerAgent* agentData;
- QScriptEngine* scriptEngine;
- QScriptValue scriptValue;
+
+ QV8Engine *v8engine;
+ v8::Persistent<v8::Object> v8value;
+
QImage cachedImage;
QSGCanvasItem* canvas;
bool waitingForPainting;
diff --git a/src/declarative/items/qsgitem.cpp b/src/declarative/items/qsgitem.cpp
index 5926274dba..2b6f5573aa 100644
--- a/src/declarative/items/qsgitem.cpp
+++ b/src/declarative/items/qsgitem.cpp
@@ -1837,20 +1837,33 @@ void QSGItem::polish()
}
}
-QScriptValue QSGItem::mapFromItem(const QScriptValue &item, qreal x, qreal y) const
+void QSGItem::mapFromItem(QDeclarativeV8Function *args) const
{
- QScriptValue sv = QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(this))->newObject();
- QSGItem *itemObj = qobject_cast<QSGItem*>(item.toQObject());
- if (!itemObj && !item.isNull()) {
- qmlInfo(this) << "mapFromItem() given argument \"" << item.toString() << "\" which is neither null nor an Item";
- return 0;
- }
+ if (args->Length() != 0) {
+ v8::Local<v8::Value> item = (*args)[0];
+ QV8Engine *engine = args->engine();
+
+ QSGItem *itemObj = 0;
+ if (!item->IsNull())
+ itemObj = qobject_cast<QSGItem*>(engine->toQObject(item));
+
+ if (!itemObj && !item->IsNull()) {
+ qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
+ << "\" which is neither null nor an Item";
+ return;
+ }
+
+ v8::Local<v8::Object> rv = v8::Object::New();
+ args->returnValue(rv);
+
+ qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
+ qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
- // If QSGItem::mapFromItem() is called with 0, behaves the same as mapFromScene()
- QPointF p = mapFromItem(itemObj, QPointF(x, y));
- sv.setProperty(QLatin1String("x"), p.x());
- sv.setProperty(QLatin1String("y"), p.y());
- return sv;
+ QPointF p = mapFromItem(itemObj, QPointF(x, y));
+
+ rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
+ rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
+ }
}
QTransform QSGItem::itemTransform(QSGItem *other, bool *ok) const
@@ -1867,20 +1880,33 @@ QTransform QSGItem::itemTransform(QSGItem *other, bool *ok) const
return t;
}
-QScriptValue QSGItem::mapToItem(const QScriptValue &item, qreal x, qreal y) const
+void QSGItem::mapToItem(QDeclarativeV8Function *args) const
{
- QScriptValue sv = QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(this))->newObject();
- QSGItem *itemObj = qobject_cast<QSGItem*>(item.toQObject());
- if (!itemObj && !item.isNull()) {
- qmlInfo(this) << "mapToItem() given argument \"" << item.toString() << "\" which is neither null nor an Item";
- return 0;
- }
+ if (args->Length() != 0) {
+ v8::Local<v8::Value> item = (*args)[0];
+ QV8Engine *engine = args->engine();
+
+ QSGItem *itemObj = 0;
+ if (!item->IsNull())
+ itemObj = qobject_cast<QSGItem*>(engine->toQObject(item));
+
+ if (!itemObj && !item->IsNull()) {
+ qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
+ << "\" which is neither null nor an Item";
+ return;
+ }
+
+ v8::Local<v8::Object> rv = v8::Object::New();
+ args->returnValue(rv);
+
+ qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
+ qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
- // If QSGItem::mapToItem() is called with 0, behaves the same as mapToScene()
- QPointF p = mapToItem(itemObj, QPointF(x, y));
- sv.setProperty(QLatin1String("x"), p.x());
- sv.setProperty(QLatin1String("y"), p.y());
- return sv;
+ QPointF p = mapToItem(itemObj, QPointF(x, y));
+
+ rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
+ rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
+ }
}
void QSGItem::forceActiveFocus()
diff --git a/src/declarative/items/qsgitem.h b/src/declarative/items/qsgitem.h
index 425e5bc35c..e7d9d0aa0a 100644
--- a/src/declarative/items/qsgitem.h
+++ b/src/declarative/items/qsgitem.h
@@ -288,8 +288,8 @@ public:
void polish();
- Q_INVOKABLE QScriptValue mapFromItem(const QScriptValue &item, qreal x, qreal y) const;
- Q_INVOKABLE QScriptValue mapToItem(const QScriptValue &item, qreal x, qreal y) const;
+ Q_INVOKABLE void mapFromItem(QDeclarativeV8Function*) const;
+ Q_INVOKABLE void mapToItem(QDeclarativeV8Function*) const;
Q_INVOKABLE void forceActiveFocus();
Q_INVOKABLE QSGItem *childAt(qreal x, qreal y) const;