diff options
Diffstat (limited to 'skia/xml/SkJSDisplayable.cpp')
-rw-r--r-- | skia/xml/SkJSDisplayable.cpp | 472 |
1 files changed, 472 insertions, 0 deletions
diff --git a/skia/xml/SkJSDisplayable.cpp b/skia/xml/SkJSDisplayable.cpp new file mode 100644 index 0000000..87269f3 --- /dev/null +++ b/skia/xml/SkJSDisplayable.cpp @@ -0,0 +1,472 @@ +/* libs/graphics/xml/SkJSDisplayable.cpp +** +** Copyright 2006, Google Inc. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#include <jsapi.h> +#include "SkJS.h" +#include "SkDisplayType.h" +//#include "SkAnimateColor.h" +#include "SkAnimateMaker.h" +#include "SkAnimateSet.h" +//#include "SkAnimateTransform.h" +#include "SkCanvas.h" +//#include "SkDimensions.h" +#include "SkDisplayAdd.h" +#include "SkDisplayApply.h" +//#include "SkDisplayBefore.h" +#include "SkDisplayEvent.h" +//#include "SkDisplayFocus.h" +#include "SkDisplayInclude.h" +#include "SkDisplayPost.h" +#include "SkDisplayRandom.h" +#include "SkDraw3D.h" +#include "SkDrawBitmap.h" +#include "SkDrawClip.h" +#include "SkDrawDash.h" +#include "SkDrawDiscrete.h" +#include "SkDrawEmboss.h" +//#include "SkDrawFont.h" +#include "SkDrawFull.h" +#include "SkDrawGradient.h" +#include "SkDrawLine.h" +//#include "SkDrawMaskFilter.h" +#include "SkDrawMatrix.h" +#include "SkDrawOval.h" +#include "SkDrawPaint.h" +#include "SkDrawPath.h" +#include "SkDrawPoint.h" +// #include "SkDrawStroke.h" +#include "SkDrawText.h" +#include "SkDrawTo.h" +//#include "SkDrawTransferMode.h" +#include "SkDrawTransparentShader.h" +//#include "SkDrawUse.h" +#include "SkMatrixParts.h" +#include "SkPathParts.h" +#include "SkPostParts.h" +#include "SkScript.h" +#include "SkSnapshot.h" +#include "SkTextOnPath.h" +#include "SkTextToPath.h" + + +class SkJSDisplayable { +public: + SkJSDisplayable() : fDisplayable(NULL) {} + ~SkJSDisplayable() { delete fDisplayable; } + static void Destructor(JSContext *cx, JSObject *obj); + static JSBool GetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp); + static JSBool SetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp); + static SkCanvas* gCanvas; + static SkPaint* gPaint; + static JSBool Draw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); + SkDisplayable* fDisplayable; +}; + +SkCanvas* SkJSDisplayable::gCanvas; +SkPaint* SkJSDisplayable::gPaint; + +JSBool SkJSDisplayable::Draw(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval) +{ + SkJSDisplayable *p = (SkJSDisplayable*) JS_GetPrivate(cx, obj); + SkASSERT(p->fDisplayable->isDrawable()); + SkDrawable* drawable = (SkDrawable*) p->fDisplayable; + SkAnimateMaker maker(NULL, gCanvas, gPaint); + drawable->draw(maker); + return JS_TRUE; +} + + +JSFunctionSpec SkJSDisplayable_methods[] = +{ + { "draw", SkJSDisplayable::Draw, 1, 0, 0 }, + { 0 } +}; + +static JSPropertySpec* gDisplayableProperties[kNumberOfTypes]; +static JSClass gDisplayableClasses[kNumberOfTypes]; + +#define JS_INIT(_prefix, _class) \ +static JSBool _class##Constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { \ + SkJSDisplayable* jsDisplayable = new SkJSDisplayable(); \ + jsDisplayable->fDisplayable = new _prefix##_class(); \ + JS_SetPrivate(cx, obj, (void*) jsDisplayable); \ + return JS_TRUE; \ +} \ + \ +static JSObject* _class##Init(JSContext *cx, JSObject *obj, JSObject *proto) { \ + JSObject *newProtoObj = JS_InitClass(cx, obj, proto, &gDisplayableClasses[SkType_##_class], \ + _class##Constructor, 0, \ + NULL, SkJSDisplayable_methods , \ + NULL, NULL); \ + JS_DefineProperties(cx, newProtoObj, gDisplayableProperties[SkType_##_class]); \ + return newProtoObj; \ +} + +JS_INIT(Sk, Add) +JS_INIT(Sk, AddCircle) +JS_INIT(Sk, AddOval) +JS_INIT(Sk, AddPath) +JS_INIT(Sk, AddRectangle) +JS_INIT(Sk, AddRoundRect) +//JS_INIT(Sk, After) +JS_INIT(Sk, Apply) +// JS_INIT(Sk, Animate) +//JS_INIT(Sk, AnimateColor) +JS_INIT(Sk, AnimateField) +//JS_INIT(Sk, AnimateRotate) +//JS_INIT(Sk, AnimateScale) +//JS_INIT(Sk, AnimateTranslate) +JS_INIT(SkDraw, Bitmap) +JS_INIT(Sk, BaseBitmap) +//JS_INIT(Sk, Before) +JS_INIT(SkDraw, BitmapShader) +JS_INIT(SkDraw, Blur) +JS_INIT(SkDraw, Clip) +JS_INIT(SkDraw, Color) +JS_INIT(Sk, CubicTo) +JS_INIT(Sk, Dash) +JS_INIT(Sk, Data) +//JS_INIT(Sk, Dimensions) +JS_INIT(Sk, Discrete) +JS_INIT(Sk, DrawTo) +JS_INIT(SkDraw, Emboss) +JS_INIT(SkDisplay, Event) +// JS_INIT(SkDraw, Font) +// JS_INIT(Sk, Focus) +JS_INIT(Sk, Image) +JS_INIT(Sk, Include) +// JS_INIT(Sk, Input) +JS_INIT(Sk, Line) +JS_INIT(Sk, LinearGradient) +JS_INIT(Sk, LineTo) +JS_INIT(SkDraw, Matrix) +JS_INIT(Sk, Move) +JS_INIT(Sk, MoveTo) +JS_INIT(Sk, Oval) +JS_INIT(SkDraw, Path) +JS_INIT(SkDraw, Paint) +JS_INIT(Sk, DrawPoint) +JS_INIT(Sk, PolyToPoly) +JS_INIT(Sk, Polygon) +JS_INIT(Sk, Polyline) +JS_INIT(Sk, Post) +JS_INIT(Sk, QuadTo) +JS_INIT(Sk, RadialGradient) +JS_INIT(SkDisplay, Random) +JS_INIT(Sk, RectToRect) +JS_INIT(Sk, Rectangle) +JS_INIT(Sk, Remove) +JS_INIT(Sk, Replace) +JS_INIT(Sk, Rotate) +JS_INIT(Sk, RoundRect) +JS_INIT(Sk, Scale) +JS_INIT(Sk, Set) +JS_INIT(Sk, Skew) +// JS_INIT(Sk, 3D_Camera) +// JS_INIT(Sk, 3D_Patch) +#ifdef SK_SUPPORT_IMAGE_ENCODE +JS_INIT(Sk, Snapshot) +#endif +// JS_INIT(SkDraw, Stroke) +JS_INIT(Sk, Text) +JS_INIT(Sk, TextOnPath) +JS_INIT(Sk, TextToPath) +JS_INIT(Sk, Translate) +//JS_INIT(Sk, Use) + +#if SK_USE_CONDENSED_INFO == 0 +static void GenerateTables() { + for (int index = 0; index < kTypeNamesSize; index++) { + int infoCount; + SkDisplayTypes type = gTypeNames[index].fType; + const SkMemberInfo* info = SkDisplayType::GetMembers(NULL /* fMaker */, type, &infoCount); + if (info == NULL) + continue; + gDisplayableProperties[type] = new JSPropertySpec[infoCount + 1]; + JSPropertySpec* propertySpec = gDisplayableProperties[type]; + memset(propertySpec, 0, sizeof (JSPropertySpec) * (infoCount + 1)); + for (int inner = 0; inner < infoCount; inner++) { + if (info[inner].fType == SkType_BaseClassInfo) + continue; + propertySpec[inner].name = info[inner].fName; + propertySpec[inner].tinyid = inner; + propertySpec[inner].flags = JSPROP_ENUMERATE; + } + gDisplayableClasses[type].name = gTypeNames[index].fName; + gDisplayableClasses[type].flags = JSCLASS_HAS_PRIVATE; + gDisplayableClasses[type].addProperty = JS_PropertyStub; + gDisplayableClasses[type].delProperty = JS_PropertyStub; + gDisplayableClasses[type].getProperty = SkJSDisplayable::GetProperty; + gDisplayableClasses[type].setProperty = SkJSDisplayable::SetProperty; + gDisplayableClasses[type].enumerate = JS_EnumerateStub; + gDisplayableClasses[type].resolve = JS_ResolveStub; + gDisplayableClasses[type].convert = JS_ConvertStub; + gDisplayableClasses[type].finalize = SkJSDisplayable::Destructor; + } +} +#endif + +void SkJSDisplayable::Destructor(JSContext *cx, JSObject *obj) { + delete (SkJSDisplayable*) JS_GetPrivate(cx, obj); +} + +JSBool SkJSDisplayable::GetProperty(JSContext *cx, JSObject *obj, jsval id, + jsval *vp) +{ + if (JSVAL_IS_INT(id) == 0) + return JS_TRUE; + SkJSDisplayable *p = (SkJSDisplayable *) JS_GetPrivate(cx, obj); + SkDisplayable* displayable = p->fDisplayable; + SkDisplayTypes displayableType = displayable->getType(); + int members; + const SkMemberInfo* info = SkDisplayType::GetMembers(NULL /* fMaker */, displayableType, &members); + int idIndex = JSVAL_TO_INT(id); + SkASSERT(idIndex >= 0 && idIndex < members); + info = &info[idIndex]; + SkDisplayTypes infoType = (SkDisplayTypes) info->fType; + SkScalar scalar = 0; + S32 s32 = 0; + SkString* string= NULL; + JSString *str; + if (infoType == SkType_MemberProperty) { + infoType = info->propertyType(); + switch (infoType) { + case SkType_Scalar: { + SkScriptValue scriptValue; + bool success = displayable->getProperty(info->propertyIndex(), &scriptValue); + SkASSERT(scriptValue.fType == SkType_Scalar); + scalar = scriptValue.fOperand.fScalar; + } break; + default: + SkASSERT(0); // !!! unimplemented + } + } else { + SkASSERT(info->fCount == 1); + switch (infoType) { + case SkType_Boolean: + case SkType_Color: + case SkType_S32: + s32 = *(S32*) info->memberData(displayable); + break; + case SkType_String: + info->getString(displayable, &string); + break; + case SkType_Scalar: + SkOperand operand; + info->getValue(displayable, &operand, 1); + scalar = operand.fScalar; + break; + default: + SkASSERT(0); // !!! unimplemented + } + } + switch (infoType) { + case SkType_Boolean: + *vp = BOOLEAN_TO_JSVAL(s32); + break; + case SkType_Color: + case SkType_S32: + *vp = INT_TO_JSVAL(s32); + break; + case SkType_Scalar: + if (SkScalarFraction(scalar) == 0) + *vp = INT_TO_JSVAL(SkScalarFloor(scalar)); + else +#ifdef SK_SCALAR_IS_FLOAT + *vp = DOUBLE_TO_JSVAL(scalar); +#else + *vp = DOUBLE_TO_JSVAL(scalar / 65536.0f ); +#endif + break; + case SkType_String: + str = JS_NewStringCopyN(cx, string->c_str(), string->size()); + *vp = STRING_TO_JSVAL(str); + break; + default: + SkASSERT(0); // !!! unimplemented + } + return JS_TRUE; +} + +JSBool SkJSDisplayable::SetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) { + if (JSVAL_IS_INT(id) == 0) + return JS_TRUE; + SkJSDisplayable *p = (SkJSDisplayable *) JS_GetPrivate(cx, obj); + SkDisplayable* displayable = p->fDisplayable; + SkDisplayTypes displayableType = displayable->getType(); + int members; + const SkMemberInfo* info = SkDisplayType::GetMembers(NULL /* fMaker */, displayableType, &members); + int idIndex = JSVAL_TO_INT(id); + SkASSERT(idIndex >= 0 && idIndex < members); + info = &info[idIndex]; + SkDisplayTypes infoType = info->getType(); + SkScalar scalar = 0; + S32 s32 = 0; + SkString string; + JSString* str; + jsval value = *vp; + switch (infoType) { + case SkType_Boolean: + s32 = JSVAL_TO_BOOLEAN(value); + break; + case SkType_Color: + case SkType_S32: + s32 = JSVAL_TO_INT(value); + break; + case SkType_Scalar: + if (JSVAL_IS_INT(value)) + scalar = SkIntToScalar(JSVAL_TO_INT(value)); + else { + SkASSERT(JSVAL_IS_DOUBLE(value)); +#ifdef SK_SCALAR_IS_FLOAT + scalar = (float) *(double*) JSVAL_TO_DOUBLE(value); +#else + scalar = (SkFixed) (*(double*)JSVAL_TO_DOUBLE(value) * 65536.0); +#endif + } + break; + case SkType_String: + str = JS_ValueToString(cx, value); + string.set(JS_GetStringBytes(str)); + break; + default: + SkASSERT(0); // !!! unimplemented + } + if (info->fType == SkType_MemberProperty) { + switch (infoType) { + case SkType_Scalar: { + SkScriptValue scriptValue; + scriptValue.fType = SkType_Scalar; + scriptValue.fOperand.fScalar = scalar; + displayable->setProperty(-1 - (int) info->fOffset, scriptValue); + } break; + default: + SkASSERT(0); // !!! unimplemented + } + } else { + SkASSERT(info->fCount == 1); + switch (infoType) { + case SkType_Boolean: + case SkType_Color: + case SkType_S32: + s32 = *(S32*) ((const char*) displayable + info->fOffset); + break; + case SkType_String: + info->setString(displayable, &string); + break; + case SkType_Scalar: + SkOperand operand; + operand.fScalar = scalar; + info->setValue(displayable, &operand, 1); + break; + default: + SkASSERT(0); // !!! unimplemented + } + } + return JS_TRUE; +} + +void SkJS::InitializeDisplayables(const SkBitmap& bitmap, JSContext *cx, JSObject *obj, JSObject *proto) { + SkJSDisplayable::gCanvas = new SkCanvas(bitmap); + SkJSDisplayable::gPaint = new SkPaint(); +#if SK_USE_CONDENSED_INFO == 0 + GenerateTables(); +#else + SkASSERT(0); // !!! compressed version hasn't been implemented +#endif + AddInit(cx, obj, proto); + AddCircleInit(cx, obj, proto); + AddOvalInit(cx, obj, proto); + AddPathInit(cx, obj, proto); + AddRectangleInit(cx, obj, proto); + AddRoundRectInit(cx, obj, proto); +// AfterInit(cx, obj, proto); + ApplyInit(cx, obj, proto); + // AnimateInit(cx, obj, proto); +// AnimateColorInit(cx, obj, proto); + AnimateFieldInit(cx, obj, proto); +// AnimateRotateInit(cx, obj, proto); +// AnimateScaleInit(cx, obj, proto); +// AnimateTranslateInit(cx, obj, proto); + BitmapInit(cx, obj, proto); +// BaseBitmapInit(cx, obj, proto); +// BeforeInit(cx, obj, proto); + BitmapShaderInit(cx, obj, proto); + BlurInit(cx, obj, proto); + ClipInit(cx, obj, proto); + ColorInit(cx, obj, proto); + CubicToInit(cx, obj, proto); + DashInit(cx, obj, proto); + DataInit(cx, obj, proto); +// DimensionsInit(cx, obj, proto); + DiscreteInit(cx, obj, proto); + DrawToInit(cx, obj, proto); + EmbossInit(cx, obj, proto); + EventInit(cx, obj, proto); +// FontInit(cx, obj, proto); +// FocusInit(cx, obj, proto); + ImageInit(cx, obj, proto); + IncludeInit(cx, obj, proto); +// InputInit(cx, obj, proto); + LineInit(cx, obj, proto); + LinearGradientInit(cx, obj, proto); + LineToInit(cx, obj, proto); + MatrixInit(cx, obj, proto); + MoveInit(cx, obj, proto); + MoveToInit(cx, obj, proto); + OvalInit(cx, obj, proto); + PathInit(cx, obj, proto); + PaintInit(cx, obj, proto); + DrawPointInit(cx, obj, proto); + PolyToPolyInit(cx, obj, proto); + PolygonInit(cx, obj, proto); + PolylineInit(cx, obj, proto); + PostInit(cx, obj, proto); + QuadToInit(cx, obj, proto); + RadialGradientInit(cx, obj, proto); + RandomInit(cx, obj, proto); + RectToRectInit(cx, obj, proto); + RectangleInit(cx, obj, proto); + RemoveInit(cx, obj, proto); + ReplaceInit(cx, obj, proto); + RotateInit(cx, obj, proto); + RoundRectInit(cx, obj, proto); + ScaleInit(cx, obj, proto); + SetInit(cx, obj, proto); + SkewInit(cx, obj, proto); + // 3D_CameraInit(cx, obj, proto); + // 3D_PatchInit(cx, obj, proto); + #ifdef SK_SUPPORT_IMAGE_ENCODE + SnapshotInit(cx, obj, proto); + #endif +// StrokeInit(cx, obj, proto); + TextInit(cx, obj, proto); + TextOnPathInit(cx, obj, proto); + TextToPathInit(cx, obj, proto); + TranslateInit(cx, obj, proto); +// UseInit(cx, obj, proto); +} + +void SkJS::DisposeDisplayables() { + delete SkJSDisplayable::gPaint; + delete SkJSDisplayable::gCanvas; + for (int index = 0; index < kTypeNamesSize; index++) { + SkDisplayTypes type = gTypeNames[index].fType; + delete[] gDisplayableProperties[type]; + } +} |