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 |