aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/items/qsgcontext2d.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/items/qsgcontext2d.cpp')
-rw-r--r--src/declarative/items/qsgcontext2d.cpp427
1 files changed, 276 insertions, 151 deletions
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: