| OLD | NEW |
| (Empty) |
| 1 | |
| 2 /* | |
| 3 * Copyright 2006 The Android Open Source Project | |
| 4 * | |
| 5 * Use of this source code is governed by a BSD-style license that can be | |
| 6 * found in the LICENSE file. | |
| 7 */ | |
| 8 | |
| 9 | |
| 10 #include <jsapi.h> | |
| 11 #include "SkJS.h" | |
| 12 #include "SkDisplayType.h" | |
| 13 //#include "SkAnimateColor.h" | |
| 14 #include "SkAnimateMaker.h" | |
| 15 #include "SkAnimateSet.h" | |
| 16 //#include "SkAnimateTransform.h" | |
| 17 #include "SkCanvas.h" | |
| 18 //#include "SkDimensions.h" | |
| 19 #include "SkDisplayAdd.h" | |
| 20 #include "SkDisplayApply.h" | |
| 21 //#include "SkDisplayBefore.h" | |
| 22 #include "SkDisplayEvent.h" | |
| 23 //#include "SkDisplayFocus.h" | |
| 24 #include "SkDisplayInclude.h" | |
| 25 #include "SkDisplayPost.h" | |
| 26 #include "SkDisplayRandom.h" | |
| 27 #include "SkDraw3D.h" | |
| 28 #include "SkDrawBitmap.h" | |
| 29 #include "SkDrawClip.h" | |
| 30 #include "SkDrawDash.h" | |
| 31 #include "SkDrawDiscrete.h" | |
| 32 #include "SkDrawEmboss.h" | |
| 33 //#include "SkDrawFont.h" | |
| 34 #include "SkDrawFull.h" | |
| 35 #include "SkDrawGradient.h" | |
| 36 #include "SkDrawLine.h" | |
| 37 //#include "SkDrawMaskFilter.h" | |
| 38 #include "SkDrawMatrix.h" | |
| 39 #include "SkDrawOval.h" | |
| 40 #include "SkDrawPaint.h" | |
| 41 #include "SkDrawPath.h" | |
| 42 #include "SkDrawPoint.h" | |
| 43 // #include "SkDrawStroke.h" | |
| 44 #include "SkDrawText.h" | |
| 45 #include "SkDrawTo.h" | |
| 46 //#include "SkDrawTransferMode.h" | |
| 47 #include "SkDrawTransparentShader.h" | |
| 48 //#include "SkDrawUse.h" | |
| 49 #include "SkMatrixParts.h" | |
| 50 #include "SkPathParts.h" | |
| 51 #include "SkPostParts.h" | |
| 52 #include "SkScript.h" | |
| 53 #include "SkSnapshot.h" | |
| 54 #include "SkTextOnPath.h" | |
| 55 #include "SkTextToPath.h" | |
| 56 | |
| 57 | |
| 58 class SkJSDisplayable { | |
| 59 public: | |
| 60 SkJSDisplayable() : fDisplayable(NULL) {} | |
| 61 ~SkJSDisplayable() { delete fDisplayable; } | |
| 62 static void Destructor(JSContext *cx, JSObject *obj); | |
| 63 static JSBool GetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
; | |
| 64 static JSBool SetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
; | |
| 65 static SkCanvas* gCanvas; | |
| 66 static SkPaint* gPaint; | |
| 67 static JSBool Draw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, js
val *rval); | |
| 68 SkDisplayable* fDisplayable; | |
| 69 }; | |
| 70 | |
| 71 SkCanvas* SkJSDisplayable::gCanvas; | |
| 72 SkPaint* SkJSDisplayable::gPaint; | |
| 73 | |
| 74 JSBool SkJSDisplayable::Draw(JSContext *cx, JSObject *obj, uintN argc, | |
| 75 jsval *argv, jsval *rval) | |
| 76 { | |
| 77 SkJSDisplayable *p = (SkJSDisplayable*) JS_GetPrivate(cx, obj); | |
| 78 SkASSERT(p->fDisplayable->isDrawable()); | |
| 79 SkDrawable* drawable = (SkDrawable*) p->fDisplayable; | |
| 80 SkAnimateMaker maker(NULL, gCanvas, gPaint); | |
| 81 drawable->draw(maker); | |
| 82 return JS_TRUE; | |
| 83 } | |
| 84 | |
| 85 | |
| 86 JSFunctionSpec SkJSDisplayable_methods[] = | |
| 87 { | |
| 88 { "draw", SkJSDisplayable::Draw, 1, 0, 0 }, | |
| 89 { 0 } | |
| 90 }; | |
| 91 | |
| 92 static JSPropertySpec* gDisplayableProperties[kNumberOfTypes]; | |
| 93 static JSClass gDisplayableClasses[kNumberOfTypes]; | |
| 94 | |
| 95 #define JS_INIT(_prefix, _class) \ | |
| 96 static JSBool _class##Constructor(JSContext *cx, JSObject *obj, uintN argc, jsva
l *argv, jsval *rval) { \ | |
| 97 SkJSDisplayable* jsDisplayable = new SkJSDisplayable(); \ | |
| 98 jsDisplayable->fDisplayable = new _prefix##_class(); \ | |
| 99 JS_SetPrivate(cx, obj, (void*) jsDisplayable); \ | |
| 100 return JS_TRUE; \ | |
| 101 } \ | |
| 102 \ | |
| 103 static JSObject* _class##Init(JSContext *cx, JSObject *obj, JSObject *proto) { \ | |
| 104 JSObject *newProtoObj = JS_InitClass(cx, obj, proto, &gDisplayableClasses[Sk
Type_##_class], \ | |
| 105 _class##Constructor, 0, \ | |
| 106 NULL, SkJSDisplayable_methods , \ | |
| 107 NULL, NULL); \ | |
| 108 JS_DefineProperties(cx, newProtoObj, gDisplayableProperties[SkType_##_class]
); \ | |
| 109 return newProtoObj; \ | |
| 110 } | |
| 111 | |
| 112 JS_INIT(Sk, Add) | |
| 113 JS_INIT(Sk, AddCircle) | |
| 114 JS_INIT(Sk, AddOval) | |
| 115 JS_INIT(Sk, AddPath) | |
| 116 JS_INIT(Sk, AddRectangle) | |
| 117 JS_INIT(Sk, AddRoundRect) | |
| 118 //JS_INIT(Sk, After) | |
| 119 JS_INIT(Sk, Apply) | |
| 120 // JS_INIT(Sk, Animate) | |
| 121 //JS_INIT(Sk, AnimateColor) | |
| 122 JS_INIT(Sk, AnimateField) | |
| 123 //JS_INIT(Sk, AnimateRotate) | |
| 124 //JS_INIT(Sk, AnimateScale) | |
| 125 //JS_INIT(Sk, AnimateTranslate) | |
| 126 JS_INIT(SkDraw, Bitmap) | |
| 127 JS_INIT(Sk, BaseBitmap) | |
| 128 //JS_INIT(Sk, Before) | |
| 129 JS_INIT(SkDraw, BitmapShader) | |
| 130 JS_INIT(SkDraw, Blur) | |
| 131 JS_INIT(SkDraw, Clip) | |
| 132 JS_INIT(SkDraw, Color) | |
| 133 JS_INIT(Sk, CubicTo) | |
| 134 JS_INIT(Sk, Dash) | |
| 135 JS_INIT(Sk, Data) | |
| 136 //JS_INIT(Sk, Dimensions) | |
| 137 JS_INIT(Sk, Discrete) | |
| 138 JS_INIT(Sk, DrawTo) | |
| 139 JS_INIT(SkDraw, Emboss) | |
| 140 JS_INIT(SkDisplay, Event) | |
| 141 // JS_INIT(SkDraw, Font) | |
| 142 // JS_INIT(Sk, Focus) | |
| 143 JS_INIT(Sk, Image) | |
| 144 JS_INIT(Sk, Include) | |
| 145 // JS_INIT(Sk, Input) | |
| 146 JS_INIT(Sk, Line) | |
| 147 JS_INIT(Sk, LinearGradient) | |
| 148 JS_INIT(Sk, LineTo) | |
| 149 JS_INIT(SkDraw, Matrix) | |
| 150 JS_INIT(Sk, Move) | |
| 151 JS_INIT(Sk, MoveTo) | |
| 152 JS_INIT(Sk, Oval) | |
| 153 JS_INIT(SkDraw, Path) | |
| 154 JS_INIT(SkDraw, Paint) | |
| 155 JS_INIT(Sk, DrawPoint) | |
| 156 JS_INIT(Sk, PolyToPoly) | |
| 157 JS_INIT(Sk, Polygon) | |
| 158 JS_INIT(Sk, Polyline) | |
| 159 JS_INIT(Sk, Post) | |
| 160 JS_INIT(Sk, QuadTo) | |
| 161 JS_INIT(Sk, RadialGradient) | |
| 162 JS_INIT(SkDisplay, Random) | |
| 163 JS_INIT(Sk, RectToRect) | |
| 164 JS_INIT(Sk, Rectangle) | |
| 165 JS_INIT(Sk, Remove) | |
| 166 JS_INIT(Sk, Replace) | |
| 167 JS_INIT(Sk, Rotate) | |
| 168 JS_INIT(Sk, RoundRect) | |
| 169 JS_INIT(Sk, Scale) | |
| 170 JS_INIT(Sk, Set) | |
| 171 JS_INIT(Sk, Skew) | |
| 172 // JS_INIT(Sk, 3D_Camera) | |
| 173 // JS_INIT(Sk, 3D_Patch) | |
| 174 JS_INIT(Sk, Snapshot) | |
| 175 // JS_INIT(SkDraw, Stroke) | |
| 176 JS_INIT(Sk, Text) | |
| 177 JS_INIT(Sk, TextOnPath) | |
| 178 JS_INIT(Sk, TextToPath) | |
| 179 JS_INIT(Sk, Translate) | |
| 180 //JS_INIT(Sk, Use) | |
| 181 | |
| 182 #if SK_USE_CONDENSED_INFO == 0 | |
| 183 static void GenerateTables() { | |
| 184 for (int index = 0; index < kTypeNamesSize; index++) { | |
| 185 int infoCount; | |
| 186 SkDisplayTypes type = gTypeNames[index].fType; | |
| 187 const SkMemberInfo* info = SkDisplayType::GetMembers(NULL /* fMaker */,
type, &infoCount); | |
| 188 if (info == NULL) | |
| 189 continue; | |
| 190 gDisplayableProperties[type] = new JSPropertySpec[infoCount + 1]; | |
| 191 JSPropertySpec* propertySpec = gDisplayableProperties[type]; | |
| 192 memset(propertySpec, 0, sizeof (JSPropertySpec) * (infoCount + 1)); | |
| 193 for (int inner = 0; inner < infoCount; inner++) { | |
| 194 if (info[inner].fType == SkType_BaseClassInfo) | |
| 195 continue; | |
| 196 propertySpec[inner].name = info[inner].fName; | |
| 197 propertySpec[inner].tinyid = inner; | |
| 198 propertySpec[inner].flags = JSPROP_ENUMERATE; | |
| 199 } | |
| 200 gDisplayableClasses[type].name = gTypeNames[index].fName; | |
| 201 gDisplayableClasses[type].flags = JSCLASS_HAS_PRIVATE; | |
| 202 gDisplayableClasses[type].addProperty = JS_PropertyStub; | |
| 203 gDisplayableClasses[type].delProperty = JS_PropertyStub; | |
| 204 gDisplayableClasses[type].getProperty = SkJSDisplayable::GetProperty; | |
| 205 gDisplayableClasses[type].setProperty = SkJSDisplayable::SetProperty; | |
| 206 gDisplayableClasses[type].enumerate = JS_EnumerateStub; | |
| 207 gDisplayableClasses[type].resolve = JS_ResolveStub; | |
| 208 gDisplayableClasses[type].convert = JS_ConvertStub; | |
| 209 gDisplayableClasses[type].finalize = SkJSDisplayable::Destructor; | |
| 210 } | |
| 211 } | |
| 212 #endif | |
| 213 | |
| 214 void SkJSDisplayable::Destructor(JSContext *cx, JSObject *obj) { | |
| 215 delete (SkJSDisplayable*) JS_GetPrivate(cx, obj); | |
| 216 } | |
| 217 | |
| 218 JSBool SkJSDisplayable::GetProperty(JSContext *cx, JSObject *obj, jsval id, | |
| 219 jsval *vp) | |
| 220 { | |
| 221 if (JSVAL_IS_INT(id) == 0) | |
| 222 return JS_TRUE; | |
| 223 SkJSDisplayable *p = (SkJSDisplayable *) JS_GetPrivate(cx, obj); | |
| 224 SkDisplayable* displayable = p->fDisplayable; | |
| 225 SkDisplayTypes displayableType = displayable->getType(); | |
| 226 int members; | |
| 227 const SkMemberInfo* info = SkDisplayType::GetMembers(NULL /* fMaker */, disp
layableType, &members); | |
| 228 int idIndex = JSVAL_TO_INT(id); | |
| 229 SkASSERT(idIndex >= 0 && idIndex < members); | |
| 230 info = &info[idIndex]; | |
| 231 SkDisplayTypes infoType = (SkDisplayTypes) info->fType; | |
| 232 SkScalar scalar = 0; | |
| 233 S32 s32 = 0; | |
| 234 SkString* string= NULL; | |
| 235 JSString *str; | |
| 236 if (infoType == SkType_MemberProperty) { | |
| 237 infoType = info->propertyType(); | |
| 238 switch (infoType) { | |
| 239 case SkType_Scalar: { | |
| 240 SkScriptValue scriptValue; | |
| 241 bool success = displayable->getProperty(info->propertyIndex(), &
scriptValue); | |
| 242 SkASSERT(scriptValue.fType == SkType_Scalar); | |
| 243 scalar = scriptValue.fOperand.fScalar; | |
| 244 } break; | |
| 245 default: | |
| 246 SkASSERT(0); // !!! unimplemented | |
| 247 } | |
| 248 } else { | |
| 249 SkASSERT(info->fCount == 1); | |
| 250 switch (infoType) { | |
| 251 case SkType_Boolean: | |
| 252 case SkType_Color: | |
| 253 case SkType_S32: | |
| 254 s32 = *(S32*) info->memberData(displayable); | |
| 255 break; | |
| 256 case SkType_String: | |
| 257 info->getString(displayable, &string); | |
| 258 break; | |
| 259 case SkType_Scalar: | |
| 260 SkOperand operand; | |
| 261 info->getValue(displayable, &operand, 1); | |
| 262 scalar = operand.fScalar; | |
| 263 break; | |
| 264 default: | |
| 265 SkASSERT(0); // !!! unimplemented | |
| 266 } | |
| 267 } | |
| 268 switch (infoType) { | |
| 269 case SkType_Boolean: | |
| 270 *vp = BOOLEAN_TO_JSVAL(s32); | |
| 271 break; | |
| 272 case SkType_Color: | |
| 273 case SkType_S32: | |
| 274 *vp = INT_TO_JSVAL(s32); | |
| 275 break; | |
| 276 case SkType_Scalar: | |
| 277 if (SkScalarFraction(scalar) == 0) | |
| 278 *vp = INT_TO_JSVAL(SkScalarFloor(scalar)); | |
| 279 else | |
| 280 *vp = DOUBLE_TO_JSVAL(scalar); | |
| 281 break; | |
| 282 case SkType_String: | |
| 283 str = JS_NewStringCopyN(cx, string->c_str(), string->size()); | |
| 284 *vp = STRING_TO_JSVAL(str); | |
| 285 break; | |
| 286 default: | |
| 287 SkASSERT(0); // !!! unimplemented | |
| 288 } | |
| 289 return JS_TRUE; | |
| 290 } | |
| 291 | |
| 292 JSBool SkJSDisplayable::SetProperty(JSContext *cx, JSObject *obj, jsval id, jsva
l *vp) { | |
| 293 if (JSVAL_IS_INT(id) == 0) | |
| 294 return JS_TRUE; | |
| 295 SkJSDisplayable *p = (SkJSDisplayable *) JS_GetPrivate(cx, obj); | |
| 296 SkDisplayable* displayable = p->fDisplayable; | |
| 297 SkDisplayTypes displayableType = displayable->getType(); | |
| 298 int members; | |
| 299 const SkMemberInfo* info = SkDisplayType::GetMembers(NULL /* fMaker */, disp
layableType, &members); | |
| 300 int idIndex = JSVAL_TO_INT(id); | |
| 301 SkASSERT(idIndex >= 0 && idIndex < members); | |
| 302 info = &info[idIndex]; | |
| 303 SkDisplayTypes infoType = info->getType(); | |
| 304 SkScalar scalar = 0; | |
| 305 S32 s32 = 0; | |
| 306 SkString string; | |
| 307 JSString* str; | |
| 308 jsval value = *vp; | |
| 309 switch (infoType) { | |
| 310 case SkType_Boolean: | |
| 311 s32 = JSVAL_TO_BOOLEAN(value); | |
| 312 break; | |
| 313 case SkType_Color: | |
| 314 case SkType_S32: | |
| 315 s32 = JSVAL_TO_INT(value); | |
| 316 break; | |
| 317 case SkType_Scalar: | |
| 318 if (JSVAL_IS_INT(value)) | |
| 319 scalar = SkIntToScalar(JSVAL_TO_INT(value)); | |
| 320 else { | |
| 321 SkASSERT(JSVAL_IS_DOUBLE(value)); | |
| 322 scalar = (float) *(double*) JSVAL_TO_DOUBLE(value); | |
| 323 } | |
| 324 break; | |
| 325 case SkType_String: | |
| 326 str = JS_ValueToString(cx, value); | |
| 327 string.set(JS_GetStringBytes(str)); | |
| 328 break; | |
| 329 default: | |
| 330 SkASSERT(0); // !!! unimplemented | |
| 331 } | |
| 332 if (info->fType == SkType_MemberProperty) { | |
| 333 switch (infoType) { | |
| 334 case SkType_Scalar: { | |
| 335 SkScriptValue scriptValue; | |
| 336 scriptValue.fType = SkType_Scalar; | |
| 337 scriptValue.fOperand.fScalar = scalar; | |
| 338 displayable->setProperty(-1 - (int) info->fOffset, scriptValue); | |
| 339 } break; | |
| 340 default: | |
| 341 SkASSERT(0); // !!! unimplemented | |
| 342 } | |
| 343 } else { | |
| 344 SkASSERT(info->fCount == 1); | |
| 345 switch (infoType) { | |
| 346 case SkType_Boolean: | |
| 347 case SkType_Color: | |
| 348 case SkType_S32: | |
| 349 s32 = *(S32*) ((const char*) displayable + info->fOffset); | |
| 350 break; | |
| 351 case SkType_String: | |
| 352 info->setString(displayable, &string); | |
| 353 break; | |
| 354 case SkType_Scalar: | |
| 355 SkOperand operand; | |
| 356 operand.fScalar = scalar; | |
| 357 info->setValue(displayable, &operand, 1); | |
| 358 break; | |
| 359 default: | |
| 360 SkASSERT(0); // !!! unimplemented | |
| 361 } | |
| 362 } | |
| 363 return JS_TRUE; | |
| 364 } | |
| 365 | |
| 366 void SkJS::InitializeDisplayables(const SkBitmap& bitmap, JSContext *cx, JSObjec
t *obj, JSObject *proto) { | |
| 367 SkJSDisplayable::gCanvas = new SkCanvas(bitmap); | |
| 368 SkJSDisplayable::gPaint = new SkPaint(); | |
| 369 #if SK_USE_CONDENSED_INFO == 0 | |
| 370 GenerateTables(); | |
| 371 #else | |
| 372 SkASSERT(0); // !!! compressed version hasn't been implemented | |
| 373 #endif | |
| 374 AddInit(cx, obj, proto); | |
| 375 AddCircleInit(cx, obj, proto); | |
| 376 AddOvalInit(cx, obj, proto); | |
| 377 AddPathInit(cx, obj, proto); | |
| 378 AddRectangleInit(cx, obj, proto); | |
| 379 AddRoundRectInit(cx, obj, proto); | |
| 380 // AfterInit(cx, obj, proto); | |
| 381 ApplyInit(cx, obj, proto); | |
| 382 // AnimateInit(cx, obj, proto); | |
| 383 // AnimateColorInit(cx, obj, proto); | |
| 384 AnimateFieldInit(cx, obj, proto); | |
| 385 // AnimateRotateInit(cx, obj, proto); | |
| 386 // AnimateScaleInit(cx, obj, proto); | |
| 387 // AnimateTranslateInit(cx, obj, proto); | |
| 388 BitmapInit(cx, obj, proto); | |
| 389 // BaseBitmapInit(cx, obj, proto); | |
| 390 // BeforeInit(cx, obj, proto); | |
| 391 BitmapShaderInit(cx, obj, proto); | |
| 392 BlurInit(cx, obj, proto); | |
| 393 ClipInit(cx, obj, proto); | |
| 394 ColorInit(cx, obj, proto); | |
| 395 CubicToInit(cx, obj, proto); | |
| 396 DashInit(cx, obj, proto); | |
| 397 DataInit(cx, obj, proto); | |
| 398 // DimensionsInit(cx, obj, proto); | |
| 399 DiscreteInit(cx, obj, proto); | |
| 400 DrawToInit(cx, obj, proto); | |
| 401 EmbossInit(cx, obj, proto); | |
| 402 EventInit(cx, obj, proto); | |
| 403 // FontInit(cx, obj, proto); | |
| 404 // FocusInit(cx, obj, proto); | |
| 405 ImageInit(cx, obj, proto); | |
| 406 IncludeInit(cx, obj, proto); | |
| 407 // InputInit(cx, obj, proto); | |
| 408 LineInit(cx, obj, proto); | |
| 409 LinearGradientInit(cx, obj, proto); | |
| 410 LineToInit(cx, obj, proto); | |
| 411 MatrixInit(cx, obj, proto); | |
| 412 MoveInit(cx, obj, proto); | |
| 413 MoveToInit(cx, obj, proto); | |
| 414 OvalInit(cx, obj, proto); | |
| 415 PathInit(cx, obj, proto); | |
| 416 PaintInit(cx, obj, proto); | |
| 417 DrawPointInit(cx, obj, proto); | |
| 418 PolyToPolyInit(cx, obj, proto); | |
| 419 PolygonInit(cx, obj, proto); | |
| 420 PolylineInit(cx, obj, proto); | |
| 421 PostInit(cx, obj, proto); | |
| 422 QuadToInit(cx, obj, proto); | |
| 423 RadialGradientInit(cx, obj, proto); | |
| 424 RandomInit(cx, obj, proto); | |
| 425 RectToRectInit(cx, obj, proto); | |
| 426 RectangleInit(cx, obj, proto); | |
| 427 RemoveInit(cx, obj, proto); | |
| 428 ReplaceInit(cx, obj, proto); | |
| 429 RotateInit(cx, obj, proto); | |
| 430 RoundRectInit(cx, obj, proto); | |
| 431 ScaleInit(cx, obj, proto); | |
| 432 SetInit(cx, obj, proto); | |
| 433 SkewInit(cx, obj, proto); | |
| 434 // 3D_CameraInit(cx, obj, proto); | |
| 435 // 3D_PatchInit(cx, obj, proto); | |
| 436 SnapshotInit(cx, obj, proto); | |
| 437 // StrokeInit(cx, obj, proto); | |
| 438 TextInit(cx, obj, proto); | |
| 439 TextOnPathInit(cx, obj, proto); | |
| 440 TextToPathInit(cx, obj, proto); | |
| 441 TranslateInit(cx, obj, proto); | |
| 442 // UseInit(cx, obj, proto); | |
| 443 } | |
| 444 | |
| 445 void SkJS::DisposeDisplayables() { | |
| 446 delete SkJSDisplayable::gPaint; | |
| 447 delete SkJSDisplayable::gCanvas; | |
| 448 for (int index = 0; index < kTypeNamesSize; index++) { | |
| 449 SkDisplayTypes type = gTypeNames[index].fType; | |
| 450 delete[] gDisplayableProperties[type]; | |
| 451 } | |
| 452 } | |
| OLD | NEW |