1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/xml/SkJSDisplayable.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,452 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2006 The Android Open Source Project 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 + 1.13 +#include <jsapi.h> 1.14 +#include "SkJS.h" 1.15 +#include "SkDisplayType.h" 1.16 +//#include "SkAnimateColor.h" 1.17 +#include "SkAnimateMaker.h" 1.18 +#include "SkAnimateSet.h" 1.19 +//#include "SkAnimateTransform.h" 1.20 +#include "SkCanvas.h" 1.21 +//#include "SkDimensions.h" 1.22 +#include "SkDisplayAdd.h" 1.23 +#include "SkDisplayApply.h" 1.24 +//#include "SkDisplayBefore.h" 1.25 +#include "SkDisplayEvent.h" 1.26 +//#include "SkDisplayFocus.h" 1.27 +#include "SkDisplayInclude.h" 1.28 +#include "SkDisplayPost.h" 1.29 +#include "SkDisplayRandom.h" 1.30 +#include "SkDraw3D.h" 1.31 +#include "SkDrawBitmap.h" 1.32 +#include "SkDrawClip.h" 1.33 +#include "SkDrawDash.h" 1.34 +#include "SkDrawDiscrete.h" 1.35 +#include "SkDrawEmboss.h" 1.36 +//#include "SkDrawFont.h" 1.37 +#include "SkDrawFull.h" 1.38 +#include "SkDrawGradient.h" 1.39 +#include "SkDrawLine.h" 1.40 +//#include "SkDrawMaskFilter.h" 1.41 +#include "SkDrawMatrix.h" 1.42 +#include "SkDrawOval.h" 1.43 +#include "SkDrawPaint.h" 1.44 +#include "SkDrawPath.h" 1.45 +#include "SkDrawPoint.h" 1.46 +// #include "SkDrawStroke.h" 1.47 +#include "SkDrawText.h" 1.48 +#include "SkDrawTo.h" 1.49 +//#include "SkDrawTransferMode.h" 1.50 +#include "SkDrawTransparentShader.h" 1.51 +//#include "SkDrawUse.h" 1.52 +#include "SkMatrixParts.h" 1.53 +#include "SkPathParts.h" 1.54 +#include "SkPostParts.h" 1.55 +#include "SkScript.h" 1.56 +#include "SkSnapshot.h" 1.57 +#include "SkTextOnPath.h" 1.58 +#include "SkTextToPath.h" 1.59 + 1.60 + 1.61 +class SkJSDisplayable { 1.62 +public: 1.63 + SkJSDisplayable() : fDisplayable(NULL) {} 1.64 + ~SkJSDisplayable() { delete fDisplayable; } 1.65 + static void Destructor(JSContext *cx, JSObject *obj); 1.66 + static JSBool GetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp); 1.67 + static JSBool SetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp); 1.68 + static SkCanvas* gCanvas; 1.69 + static SkPaint* gPaint; 1.70 + static JSBool Draw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); 1.71 + SkDisplayable* fDisplayable; 1.72 +}; 1.73 + 1.74 +SkCanvas* SkJSDisplayable::gCanvas; 1.75 +SkPaint* SkJSDisplayable::gPaint; 1.76 + 1.77 +JSBool SkJSDisplayable::Draw(JSContext *cx, JSObject *obj, uintN argc, 1.78 + jsval *argv, jsval *rval) 1.79 +{ 1.80 + SkJSDisplayable *p = (SkJSDisplayable*) JS_GetPrivate(cx, obj); 1.81 + SkASSERT(p->fDisplayable->isDrawable()); 1.82 + SkDrawable* drawable = (SkDrawable*) p->fDisplayable; 1.83 + SkAnimateMaker maker(NULL, gCanvas, gPaint); 1.84 + drawable->draw(maker); 1.85 + return JS_TRUE; 1.86 +} 1.87 + 1.88 + 1.89 +JSFunctionSpec SkJSDisplayable_methods[] = 1.90 +{ 1.91 + { "draw", SkJSDisplayable::Draw, 1, 0, 0 }, 1.92 + { 0 } 1.93 +}; 1.94 + 1.95 +static JSPropertySpec* gDisplayableProperties[kNumberOfTypes]; 1.96 +static JSClass gDisplayableClasses[kNumberOfTypes]; 1.97 + 1.98 +#define JS_INIT(_prefix, _class) \ 1.99 +static JSBool _class##Constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { \ 1.100 + SkJSDisplayable* jsDisplayable = new SkJSDisplayable(); \ 1.101 + jsDisplayable->fDisplayable = new _prefix##_class(); \ 1.102 + JS_SetPrivate(cx, obj, (void*) jsDisplayable); \ 1.103 + return JS_TRUE; \ 1.104 +} \ 1.105 + \ 1.106 +static JSObject* _class##Init(JSContext *cx, JSObject *obj, JSObject *proto) { \ 1.107 + JSObject *newProtoObj = JS_InitClass(cx, obj, proto, &gDisplayableClasses[SkType_##_class], \ 1.108 + _class##Constructor, 0, \ 1.109 + NULL, SkJSDisplayable_methods , \ 1.110 + NULL, NULL); \ 1.111 + JS_DefineProperties(cx, newProtoObj, gDisplayableProperties[SkType_##_class]); \ 1.112 + return newProtoObj; \ 1.113 +} 1.114 + 1.115 +JS_INIT(Sk, Add) 1.116 +JS_INIT(Sk, AddCircle) 1.117 +JS_INIT(Sk, AddOval) 1.118 +JS_INIT(Sk, AddPath) 1.119 +JS_INIT(Sk, AddRectangle) 1.120 +JS_INIT(Sk, AddRoundRect) 1.121 +//JS_INIT(Sk, After) 1.122 +JS_INIT(Sk, Apply) 1.123 +// JS_INIT(Sk, Animate) 1.124 +//JS_INIT(Sk, AnimateColor) 1.125 +JS_INIT(Sk, AnimateField) 1.126 +//JS_INIT(Sk, AnimateRotate) 1.127 +//JS_INIT(Sk, AnimateScale) 1.128 +//JS_INIT(Sk, AnimateTranslate) 1.129 +JS_INIT(SkDraw, Bitmap) 1.130 +JS_INIT(Sk, BaseBitmap) 1.131 +//JS_INIT(Sk, Before) 1.132 +JS_INIT(SkDraw, BitmapShader) 1.133 +JS_INIT(SkDraw, Blur) 1.134 +JS_INIT(SkDraw, Clip) 1.135 +JS_INIT(SkDraw, Color) 1.136 +JS_INIT(Sk, CubicTo) 1.137 +JS_INIT(Sk, Dash) 1.138 +JS_INIT(Sk, Data) 1.139 +//JS_INIT(Sk, Dimensions) 1.140 +JS_INIT(Sk, Discrete) 1.141 +JS_INIT(Sk, DrawTo) 1.142 +JS_INIT(SkDraw, Emboss) 1.143 +JS_INIT(SkDisplay, Event) 1.144 +// JS_INIT(SkDraw, Font) 1.145 +// JS_INIT(Sk, Focus) 1.146 +JS_INIT(Sk, Image) 1.147 +JS_INIT(Sk, Include) 1.148 +// JS_INIT(Sk, Input) 1.149 +JS_INIT(Sk, Line) 1.150 +JS_INIT(Sk, LinearGradient) 1.151 +JS_INIT(Sk, LineTo) 1.152 +JS_INIT(SkDraw, Matrix) 1.153 +JS_INIT(Sk, Move) 1.154 +JS_INIT(Sk, MoveTo) 1.155 +JS_INIT(Sk, Oval) 1.156 +JS_INIT(SkDraw, Path) 1.157 +JS_INIT(SkDraw, Paint) 1.158 +JS_INIT(Sk, DrawPoint) 1.159 +JS_INIT(Sk, PolyToPoly) 1.160 +JS_INIT(Sk, Polygon) 1.161 +JS_INIT(Sk, Polyline) 1.162 +JS_INIT(Sk, Post) 1.163 +JS_INIT(Sk, QuadTo) 1.164 +JS_INIT(Sk, RadialGradient) 1.165 +JS_INIT(SkDisplay, Random) 1.166 +JS_INIT(Sk, RectToRect) 1.167 +JS_INIT(Sk, Rectangle) 1.168 +JS_INIT(Sk, Remove) 1.169 +JS_INIT(Sk, Replace) 1.170 +JS_INIT(Sk, Rotate) 1.171 +JS_INIT(Sk, RoundRect) 1.172 +JS_INIT(Sk, Scale) 1.173 +JS_INIT(Sk, Set) 1.174 +JS_INIT(Sk, Skew) 1.175 +// JS_INIT(Sk, 3D_Camera) 1.176 +// JS_INIT(Sk, 3D_Patch) 1.177 +JS_INIT(Sk, Snapshot) 1.178 +// JS_INIT(SkDraw, Stroke) 1.179 +JS_INIT(Sk, Text) 1.180 +JS_INIT(Sk, TextOnPath) 1.181 +JS_INIT(Sk, TextToPath) 1.182 +JS_INIT(Sk, Translate) 1.183 +//JS_INIT(Sk, Use) 1.184 + 1.185 +#if SK_USE_CONDENSED_INFO == 0 1.186 +static void GenerateTables() { 1.187 + for (int index = 0; index < kTypeNamesSize; index++) { 1.188 + int infoCount; 1.189 + SkDisplayTypes type = gTypeNames[index].fType; 1.190 + const SkMemberInfo* info = SkDisplayType::GetMembers(NULL /* fMaker */, type, &infoCount); 1.191 + if (info == NULL) 1.192 + continue; 1.193 + gDisplayableProperties[type] = new JSPropertySpec[infoCount + 1]; 1.194 + JSPropertySpec* propertySpec = gDisplayableProperties[type]; 1.195 + memset(propertySpec, 0, sizeof (JSPropertySpec) * (infoCount + 1)); 1.196 + for (int inner = 0; inner < infoCount; inner++) { 1.197 + if (info[inner].fType == SkType_BaseClassInfo) 1.198 + continue; 1.199 + propertySpec[inner].name = info[inner].fName; 1.200 + propertySpec[inner].tinyid = inner; 1.201 + propertySpec[inner].flags = JSPROP_ENUMERATE; 1.202 + } 1.203 + gDisplayableClasses[type].name = gTypeNames[index].fName; 1.204 + gDisplayableClasses[type].flags = JSCLASS_HAS_PRIVATE; 1.205 + gDisplayableClasses[type].addProperty = JS_PropertyStub; 1.206 + gDisplayableClasses[type].delProperty = JS_PropertyStub; 1.207 + gDisplayableClasses[type].getProperty = SkJSDisplayable::GetProperty; 1.208 + gDisplayableClasses[type].setProperty = SkJSDisplayable::SetProperty; 1.209 + gDisplayableClasses[type].enumerate = JS_EnumerateStub; 1.210 + gDisplayableClasses[type].resolve = JS_ResolveStub; 1.211 + gDisplayableClasses[type].convert = JS_ConvertStub; 1.212 + gDisplayableClasses[type].finalize = SkJSDisplayable::Destructor; 1.213 + } 1.214 +} 1.215 +#endif 1.216 + 1.217 +void SkJSDisplayable::Destructor(JSContext *cx, JSObject *obj) { 1.218 + delete (SkJSDisplayable*) JS_GetPrivate(cx, obj); 1.219 +} 1.220 + 1.221 +JSBool SkJSDisplayable::GetProperty(JSContext *cx, JSObject *obj, jsval id, 1.222 + jsval *vp) 1.223 +{ 1.224 + if (JSVAL_IS_INT(id) == 0) 1.225 + return JS_TRUE; 1.226 + SkJSDisplayable *p = (SkJSDisplayable *) JS_GetPrivate(cx, obj); 1.227 + SkDisplayable* displayable = p->fDisplayable; 1.228 + SkDisplayTypes displayableType = displayable->getType(); 1.229 + int members; 1.230 + const SkMemberInfo* info = SkDisplayType::GetMembers(NULL /* fMaker */, displayableType, &members); 1.231 + int idIndex = JSVAL_TO_INT(id); 1.232 + SkASSERT(idIndex >= 0 && idIndex < members); 1.233 + info = &info[idIndex]; 1.234 + SkDisplayTypes infoType = (SkDisplayTypes) info->fType; 1.235 + SkScalar scalar = 0; 1.236 + S32 s32 = 0; 1.237 + SkString* string= NULL; 1.238 + JSString *str; 1.239 + if (infoType == SkType_MemberProperty) { 1.240 + infoType = info->propertyType(); 1.241 + switch (infoType) { 1.242 + case SkType_Scalar: { 1.243 + SkScriptValue scriptValue; 1.244 + bool success = displayable->getProperty(info->propertyIndex(), &scriptValue); 1.245 + SkASSERT(scriptValue.fType == SkType_Scalar); 1.246 + scalar = scriptValue.fOperand.fScalar; 1.247 + } break; 1.248 + default: 1.249 + SkASSERT(0); // !!! unimplemented 1.250 + } 1.251 + } else { 1.252 + SkASSERT(info->fCount == 1); 1.253 + switch (infoType) { 1.254 + case SkType_Boolean: 1.255 + case SkType_Color: 1.256 + case SkType_S32: 1.257 + s32 = *(S32*) info->memberData(displayable); 1.258 + break; 1.259 + case SkType_String: 1.260 + info->getString(displayable, &string); 1.261 + break; 1.262 + case SkType_Scalar: 1.263 + SkOperand operand; 1.264 + info->getValue(displayable, &operand, 1); 1.265 + scalar = operand.fScalar; 1.266 + break; 1.267 + default: 1.268 + SkASSERT(0); // !!! unimplemented 1.269 + } 1.270 + } 1.271 + switch (infoType) { 1.272 + case SkType_Boolean: 1.273 + *vp = BOOLEAN_TO_JSVAL(s32); 1.274 + break; 1.275 + case SkType_Color: 1.276 + case SkType_S32: 1.277 + *vp = INT_TO_JSVAL(s32); 1.278 + break; 1.279 + case SkType_Scalar: 1.280 + if (SkScalarFraction(scalar) == 0) 1.281 + *vp = INT_TO_JSVAL(SkScalarFloor(scalar)); 1.282 + else 1.283 + *vp = DOUBLE_TO_JSVAL(scalar); 1.284 + break; 1.285 + case SkType_String: 1.286 + str = JS_NewStringCopyN(cx, string->c_str(), string->size()); 1.287 + *vp = STRING_TO_JSVAL(str); 1.288 + break; 1.289 + default: 1.290 + SkASSERT(0); // !!! unimplemented 1.291 + } 1.292 + return JS_TRUE; 1.293 +} 1.294 + 1.295 +JSBool SkJSDisplayable::SetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) { 1.296 + if (JSVAL_IS_INT(id) == 0) 1.297 + return JS_TRUE; 1.298 + SkJSDisplayable *p = (SkJSDisplayable *) JS_GetPrivate(cx, obj); 1.299 + SkDisplayable* displayable = p->fDisplayable; 1.300 + SkDisplayTypes displayableType = displayable->getType(); 1.301 + int members; 1.302 + const SkMemberInfo* info = SkDisplayType::GetMembers(NULL /* fMaker */, displayableType, &members); 1.303 + int idIndex = JSVAL_TO_INT(id); 1.304 + SkASSERT(idIndex >= 0 && idIndex < members); 1.305 + info = &info[idIndex]; 1.306 + SkDisplayTypes infoType = info->getType(); 1.307 + SkScalar scalar = 0; 1.308 + S32 s32 = 0; 1.309 + SkString string; 1.310 + JSString* str; 1.311 + jsval value = *vp; 1.312 + switch (infoType) { 1.313 + case SkType_Boolean: 1.314 + s32 = JSVAL_TO_BOOLEAN(value); 1.315 + break; 1.316 + case SkType_Color: 1.317 + case SkType_S32: 1.318 + s32 = JSVAL_TO_INT(value); 1.319 + break; 1.320 + case SkType_Scalar: 1.321 + if (JSVAL_IS_INT(value)) 1.322 + scalar = SkIntToScalar(JSVAL_TO_INT(value)); 1.323 + else { 1.324 + SkASSERT(JSVAL_IS_DOUBLE(value)); 1.325 + scalar = (float) *(double*) JSVAL_TO_DOUBLE(value); 1.326 + } 1.327 + break; 1.328 + case SkType_String: 1.329 + str = JS_ValueToString(cx, value); 1.330 + string.set(JS_GetStringBytes(str)); 1.331 + break; 1.332 + default: 1.333 + SkASSERT(0); // !!! unimplemented 1.334 + } 1.335 + if (info->fType == SkType_MemberProperty) { 1.336 + switch (infoType) { 1.337 + case SkType_Scalar: { 1.338 + SkScriptValue scriptValue; 1.339 + scriptValue.fType = SkType_Scalar; 1.340 + scriptValue.fOperand.fScalar = scalar; 1.341 + displayable->setProperty(-1 - (int) info->fOffset, scriptValue); 1.342 + } break; 1.343 + default: 1.344 + SkASSERT(0); // !!! unimplemented 1.345 + } 1.346 + } else { 1.347 + SkASSERT(info->fCount == 1); 1.348 + switch (infoType) { 1.349 + case SkType_Boolean: 1.350 + case SkType_Color: 1.351 + case SkType_S32: 1.352 + s32 = *(S32*) ((const char*) displayable + info->fOffset); 1.353 + break; 1.354 + case SkType_String: 1.355 + info->setString(displayable, &string); 1.356 + break; 1.357 + case SkType_Scalar: 1.358 + SkOperand operand; 1.359 + operand.fScalar = scalar; 1.360 + info->setValue(displayable, &operand, 1); 1.361 + break; 1.362 + default: 1.363 + SkASSERT(0); // !!! unimplemented 1.364 + } 1.365 + } 1.366 + return JS_TRUE; 1.367 +} 1.368 + 1.369 +void SkJS::InitializeDisplayables(const SkBitmap& bitmap, JSContext *cx, JSObject *obj, JSObject *proto) { 1.370 + SkJSDisplayable::gCanvas = new SkCanvas(bitmap); 1.371 + SkJSDisplayable::gPaint = new SkPaint(); 1.372 +#if SK_USE_CONDENSED_INFO == 0 1.373 + GenerateTables(); 1.374 +#else 1.375 + SkASSERT(0); // !!! compressed version hasn't been implemented 1.376 +#endif 1.377 + AddInit(cx, obj, proto); 1.378 + AddCircleInit(cx, obj, proto); 1.379 + AddOvalInit(cx, obj, proto); 1.380 + AddPathInit(cx, obj, proto); 1.381 + AddRectangleInit(cx, obj, proto); 1.382 + AddRoundRectInit(cx, obj, proto); 1.383 +// AfterInit(cx, obj, proto); 1.384 + ApplyInit(cx, obj, proto); 1.385 + // AnimateInit(cx, obj, proto); 1.386 +// AnimateColorInit(cx, obj, proto); 1.387 + AnimateFieldInit(cx, obj, proto); 1.388 +// AnimateRotateInit(cx, obj, proto); 1.389 +// AnimateScaleInit(cx, obj, proto); 1.390 +// AnimateTranslateInit(cx, obj, proto); 1.391 + BitmapInit(cx, obj, proto); 1.392 +// BaseBitmapInit(cx, obj, proto); 1.393 +// BeforeInit(cx, obj, proto); 1.394 + BitmapShaderInit(cx, obj, proto); 1.395 + BlurInit(cx, obj, proto); 1.396 + ClipInit(cx, obj, proto); 1.397 + ColorInit(cx, obj, proto); 1.398 + CubicToInit(cx, obj, proto); 1.399 + DashInit(cx, obj, proto); 1.400 + DataInit(cx, obj, proto); 1.401 +// DimensionsInit(cx, obj, proto); 1.402 + DiscreteInit(cx, obj, proto); 1.403 + DrawToInit(cx, obj, proto); 1.404 + EmbossInit(cx, obj, proto); 1.405 + EventInit(cx, obj, proto); 1.406 +// FontInit(cx, obj, proto); 1.407 +// FocusInit(cx, obj, proto); 1.408 + ImageInit(cx, obj, proto); 1.409 + IncludeInit(cx, obj, proto); 1.410 +// InputInit(cx, obj, proto); 1.411 + LineInit(cx, obj, proto); 1.412 + LinearGradientInit(cx, obj, proto); 1.413 + LineToInit(cx, obj, proto); 1.414 + MatrixInit(cx, obj, proto); 1.415 + MoveInit(cx, obj, proto); 1.416 + MoveToInit(cx, obj, proto); 1.417 + OvalInit(cx, obj, proto); 1.418 + PathInit(cx, obj, proto); 1.419 + PaintInit(cx, obj, proto); 1.420 + DrawPointInit(cx, obj, proto); 1.421 + PolyToPolyInit(cx, obj, proto); 1.422 + PolygonInit(cx, obj, proto); 1.423 + PolylineInit(cx, obj, proto); 1.424 + PostInit(cx, obj, proto); 1.425 + QuadToInit(cx, obj, proto); 1.426 + RadialGradientInit(cx, obj, proto); 1.427 + RandomInit(cx, obj, proto); 1.428 + RectToRectInit(cx, obj, proto); 1.429 + RectangleInit(cx, obj, proto); 1.430 + RemoveInit(cx, obj, proto); 1.431 + ReplaceInit(cx, obj, proto); 1.432 + RotateInit(cx, obj, proto); 1.433 + RoundRectInit(cx, obj, proto); 1.434 + ScaleInit(cx, obj, proto); 1.435 + SetInit(cx, obj, proto); 1.436 + SkewInit(cx, obj, proto); 1.437 + // 3D_CameraInit(cx, obj, proto); 1.438 + // 3D_PatchInit(cx, obj, proto); 1.439 + SnapshotInit(cx, obj, proto); 1.440 +// StrokeInit(cx, obj, proto); 1.441 + TextInit(cx, obj, proto); 1.442 + TextOnPathInit(cx, obj, proto); 1.443 + TextToPathInit(cx, obj, proto); 1.444 + TranslateInit(cx, obj, proto); 1.445 +// UseInit(cx, obj, proto); 1.446 +} 1.447 + 1.448 +void SkJS::DisposeDisplayables() { 1.449 + delete SkJSDisplayable::gPaint; 1.450 + delete SkJSDisplayable::gCanvas; 1.451 + for (int index = 0; index < kTypeNamesSize; index++) { 1.452 + SkDisplayTypes type = gTypeNames[index].fType; 1.453 + delete[] gDisplayableProperties[type]; 1.454 + } 1.455 +}