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