• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef SkAnimator_DEFINED
18 #define SkAnimator_DEFINED
19 
20 #include "SkScalar.h"
21 #include "SkKey.h"
22 #include "SkEventSink.h"
23 
24 class SkAnimateMaker;
25 class SkCanvas;
26 class SkDisplayable;
27 class SkEvent;
28 class SkExtras;
29 struct SkMemberInfo;
30 class SkPaint;
31 struct SkRect;
32 class SkStream;
33 class SkTypedArray;
34 class SkXMLParserError;
35 class SkDOM;
36 struct SkDOMNode;
37 
38 /** SkElementType is the type of element: a rectangle, a color, an animator, and so on.
39     This enum is incomplete and will be fleshed out in a future release */
40 enum SkElementType {
41     kElementDummyType
42 };
43 /** SkFieldType is the type of field: a scalar, a string, an integer, a boolean, and so on.
44     This enum is incomplete and will be fleshed out in a future release */
45 enum SkFieldType {
46     kFieldDummyType
47 };
48 
49 /** \class SkAnimator
50 
51     The SkAnimator class decodes an XML stream into a display list. The
52     display list can be drawn statically as a picture, or can drawn
53     different elements at different times to form a moving animation.
54 
55     SkAnimator does not read the system time on its own; it relies on the
56     caller to pass the current time. The caller can pause, speed up, or
57     reverse the animation by varying the time passed in.
58 
59     The XML describing the display list must conform to the schema
60     described by SkAnimateSchema.xsd.
61 
62     The XML must contain an <event> element to draw. Usually, it contains
63     an <event kind="onload" /> block to add some drawing elements to the
64     display list when the document is first decoded.
65 
66     Here's an "Hello World" XML sample:
67 
68     <screenplay>
69         <event kind="onload" >
70             <text text="Hello World" y="20" />
71         </event>
72     </screenplay>
73 
74     To read and draw this sample:
75 
76         // choose one of these two
77         SkAnimator animator; // declare an animator instance on the stack
78     //  SkAnimator* animator = new SkAnimator() // or one could instantiate the class
79 
80         // choose one of these three
81         animator.decodeMemory(buffer, size); // to read from RAM
82         animator.decodeStream(stream); // to read from a user-defined stream (e.g., a zip file)
83         animator.decodeURI(filename); // to read from a web location, or from a local text file
84 
85         // to draw to the current window:
86         SkCanvas canvas(getBitmap()); // create a canvas
87         animator.draw(canvas, &paint, 0); // draw the scene
88 */
89 class SkAnimator : public SkEventSink {
90 public:
91     SkAnimator();
92     virtual ~SkAnimator();
93 
94     /** Add a drawable extension to the graphics engine. Experimental.
95         @param extras A derived class that implements methods that identify and instantiate the class
96     */
97     void addExtras(SkExtras* extras);
98 
99     /** Read in XML from a stream, and append it to the current
100         animator. Returns false if an error was encountered.
101         Error diagnostics are stored in fErrorCode and fLineNumber.
102         @param stream  The stream to append.
103         @return true if the XML was parsed successfully.
104     */
105     bool appendStream(SkStream* stream);
106 
107     /** Read in XML from memory. Returns true if the file can be
108         read without error. Returns false if an error was encountered.
109         Error diagnostics are stored in fErrorCode and fLineNumber.
110         @param buffer  The XML text as UTF-8 characters.
111         @param size  The XML text length in bytes.
112         @return true if the XML was parsed successfully.
113     */
114     bool decodeMemory(const void* buffer, size_t size);
115 
116     /** Read in XML from a stream. Returns true if the file can be
117         read without error. Returns false if an error was encountered.
118         Error diagnostics are stored in fErrorCode and fLineNumber.
119         @param stream  The stream containg the XML text as UTF-8 characters.
120         @return true if the XML was parsed successfully.
121     */
122     virtual bool decodeStream(SkStream* stream);
123 
124     /** Parse the DOM tree starting at the specified node. Returns true if it can be
125         parsed without error. Returns false if an error was encountered.
126         Error diagnostics are stored in fErrorCode and fLineNumber.
127         @return true if the DOM was parsed successfully.
128     */
129     virtual bool decodeDOM(const SkDOM&, const SkDOMNode*);
130 
131     /** Read in XML from a URI. Returns true if the file can be
132         read without error. Returns false if an error was encountered.
133         Error diagnostics are stored in fErrorCode and fLineNumber.
134         @param uri The complete url path to be read (either ftp, http or https).
135         @return true if the XML was parsed successfully.
136     */
137     bool decodeURI(const char uri[]);
138 
139     /** Pass a char event, usually a keyboard symbol, to the animator.
140         This triggers events of the form <event kind="keyChar" key="... />
141         @param ch  The character to match against <event> element "key"
142             attributes.
143         @return true if the event was dispatched successfully.
144     */
145     bool doCharEvent(SkUnichar ch);
146 
147     /** Experimental:
148         Pass a mouse click event along with the mouse coordinates to
149         the animator. This triggers events of the form <event kind="mouseDown" ... />
150         and other mouse events.
151         @param state The mouse state, described by SkView::Click::State : values are
152         down == 0, moved == 1, up == 2
153         @param x    The x-position of the mouse
154         @param y The y-position of the mouse
155         @return true if the event was dispatched successfully.
156     */
157     bool doClickEvent(int state, SkScalar x, SkScalar y);
158 
159     /** Pass a meta-key event, such as an arrow , to the animator.
160         This triggers events of the form <event kind="keyPress" code="... />
161         @param code  The key to match against <event> element "code"
162             attributes.
163         @return true if the event was dispatched successfully.
164     */
165     bool doKeyEvent(SkKey code);
166     bool doKeyUpEvent(SkKey code);
167 
168     /** Send an event to the animator. The animator's clock is set
169         relative to the current time.
170         @return true if the event was dispatched successfully.
171     */
172     bool doUserEvent(const SkEvent& evt);
173 
174     /** The possible results from the draw function.
175     */
176     enum DifferenceType {
177         kNotDifferent,
178         kDifferent,
179         kPartiallyDifferent
180     };
181     /** Draws one frame of the animation. The first call to draw always
182         draws the initial frame of the animation. Subsequent calls draw
183         the offset into the animation by
184         subtracting the initial time from the current time.
185         @param canvas  The canvas to draw into.
186         @param paint     The paint to draw with.
187         @param time  The offset into the current animation.
188         @return kNotDifferent if there are no active animations; kDifferent if there are active animations; and
189         kPartiallyDifferent if the document contains an active <bounds> element that specifies a minimal
190         redraw area.
191     */
192     DifferenceType draw(SkCanvas* canvas, SkPaint* paint, SkMSec time);
193 
194     /** Draws one frame of the animation, using a new Paint each time.
195         The first call to draw always
196         draws the initial frame of the animation. Subsequent calls draw
197         the offset into the animation by
198         subtracting the initial time from the current time.
199         @param canvas  The canvas to draw into.
200         @param time  The offset into the current animation.
201         @return kNotDifferent if there are no active animations; kDifferent if there are active animations; and
202         kPartiallyDifferent if the document contains an active <bounds> element that specifies a minimal
203         redraw area.
204     */
205     DifferenceType draw(SkCanvas* canvas, SkMSec time);
206 
207     /** Experimental:
208         Helper to choose whether to return a SkView::Click handler.
209         @param x ignored
210         @param y ignored
211         @return true if a mouseDown event handler is enabled.
212     */
213     bool findClickEvent(SkScalar x, SkScalar y);
214 
215 
216     /** Get the nested animator associated with this element, if any.
217         Use this to access a movie's event sink, to send events to movies.
218         @param element the value returned by getElement
219         @return the internal animator.
220     */
221     const SkAnimator* getAnimator(const SkDisplayable* element) const;
222 
223     /** Returns the scalar value of the specified element's attribute[index]
224         @param element the value returned by getElement
225         @param field the value returned by getField
226         @param index the array entry
227         @return the integer value to retrieve, or SK_NaN32 if unsuccessful
228     */
229     int32_t getArrayInt(const SkDisplayable* element, const SkMemberInfo* field, int index);
230 
231     /** Returns the scalar value of the specified element's attribute[index]
232         @param elementID is the value of the id attribute in the XML of this element
233         @param fieldName specifies the name of the attribute
234         @param index the array entry
235         @return the integer value to retrieve, or SK_NaN32 if unsuccessful
236     */
237     int32_t getArrayInt(const char* elementID, const char* fieldName, int index);
238 
239     /** Returns the scalar value of the specified element's attribute[index]
240         @param element the value returned by getElement
241         @param field the value returned by getField
242         @param index the array entry
243         @return the scalar value to retrieve, or SK_ScalarNaN if unsuccessful
244     */
245     SkScalar getArrayScalar(const SkDisplayable* element, const SkMemberInfo* field, int index);
246 
247     /** Returns the scalar value of the specified element's attribute[index]
248         @param elementID is the value of the id attribute in the XML of this element
249         @param fieldName specifies the name of the attribute
250         @param index the array entry
251         @return the scalar value to retrieve, or SK_ScalarNaN if unsuccessful
252     */
253     SkScalar getArrayScalar(const char* elementID, const char* fieldName, int index);
254 
255     /** Returns the string value of the specified element's attribute[index]
256         @param element is a value returned by getElement
257         @param field is a value returned by getField
258         @param index the array entry
259         @return the string value to retrieve, or null if unsuccessful
260     */
261     const char* getArrayString(const SkDisplayable* element, const SkMemberInfo* field, int index);
262 
263     /** Returns the string value of the specified element's attribute[index]
264         @param elementID is the value of the id attribute in the XML of this element
265         @param fieldName specifies the name of the attribute
266         @param index the array entry
267         @return the string value to retrieve, or null if unsuccessful
268     */
269     const char* getArrayString(const char* elementID, const char* fieldName, int index);
270 
271     /** Returns the XML element corresponding to the given ID.
272         @param elementID is the value of the id attribute in the XML of this element
273         @return the element matching the ID, or null if the element can't be found
274     */
275     const SkDisplayable* getElement(const char* elementID);
276 
277     /** Returns the element type corresponding to the XML element.
278         The element type matches the element name; for instance, <line> returns kElement_LineType
279         @param element is a value returned by getElement
280         @return element type, or 0 if the element can't be found
281     */
282     SkElementType getElementType(const SkDisplayable* element);
283 
284     /** Returns the element type corresponding to the given ID.
285         @param elementID is the value of the id attribute in the XML of this element
286         @return element type, or 0 if the element can't be found
287     */
288     SkElementType getElementType(const char* elementID);
289 
290     /** Returns the XML field of the named attribute in the XML element.
291         @param element is a value returned by getElement
292         @param fieldName is the attribute to return
293         @return the attribute matching the fieldName, or null if the element can't be found
294     */
295     const SkMemberInfo* getField(const SkDisplayable* element, const char* fieldName);
296 
297     /** Returns the XML field of the named attribute in the XML element matching the elementID.
298         @param elementID is the value of the id attribute in the XML of this element
299         @param fieldName is the attribute to return
300         @return the attribute matching the fieldName, or null if the element can't be found
301     */
302     const SkMemberInfo* getField(const char* elementID, const char* fieldName);
303 
304     /** Returns the value type coresponding to the element's attribute.
305         The value type matches the XML schema: and may be kField_BooleanType, kField_ScalarType, etc.
306         @param field is a value returned by getField
307         @return the attribute type, or 0 if the element can't be found
308     */
309     SkFieldType getFieldType(const SkMemberInfo* field);
310 
311     /** Returns the value type coresponding to the element's attribute.
312         @param elementID is the value of the id attribute in the XML of this element
313         @param fieldName specifies the name of the attribute
314         @return the attribute type, or 0 if the element can't be found
315     */
316     SkFieldType getFieldType(const char* elementID, const char* fieldName);
317 
318     /** Returns the recommended animation interval. Returns zero if no
319         interval is specified.
320     */
321     SkMSec getInterval();
322 
323     /** Returns the partial rectangle to invalidate after drawing. Call after draw() returns
324     kIsPartiallyDifferent to do a mimimal inval(). */
325     void getInvalBounds(SkRect* inval);
326 
327     /** Returns the details of any error encountered while parsing the XML.
328     */
329     const SkXMLParserError* getParserError();
330 
331     /** Returns the details of any error encountered while parsing the XML as string.
332     */
333     const char* getParserErrorString();
334 
335     /** Returns the scalar value of the specified element's attribute
336         @param element is a value returned by getElement
337         @param field is a value returned by getField
338         @return the integer value to retrieve, or SK_NaN32 if not found
339     */
340     int32_t getInt(const SkDisplayable* element, const SkMemberInfo* field);
341 
342     /** Returns the scalar value of the specified element's attribute
343         @param elementID is the value of the id attribute in the XML of this element
344         @param fieldName specifies the name of the attribute
345         @return the integer value to retrieve, or SK_NaN32 if not found
346     */
347     int32_t getInt(const char* elementID, const char* fieldName);
348 
349     /** Returns the scalar value of the specified element's attribute
350         @param element is a value returned by getElement
351         @param field is a value returned by getField
352         @return the scalar value to retrieve, or SK_ScalarNaN if not found
353     */
354     SkScalar getScalar(const SkDisplayable* element, const SkMemberInfo* field);
355 
356     /** Returns the scalar value of the specified element's attribute
357         @param elementID is the value of the id attribute in the XML of this element
358         @param fieldName specifies the name of the attribute
359         @return the scalar value to retrieve, or SK_ScalarNaN if not found
360     */
361     SkScalar getScalar(const char* elementID, const char* fieldName);
362 
363     /** Returns the string value of the specified element's attribute
364         @param element is a value returned by getElement
365         @param field is a value returned by getField
366         @return the string value to retrieve, or null if not found
367     */
368     const char* getString(const SkDisplayable* element, const SkMemberInfo* field);
369 
370     /** Returns the string value of the specified element's attribute
371         @param elementID is the value of the id attribute in the XML of this element
372         @param fieldName specifies the name of the attribute
373         @return the string value to retrieve, or null if not found
374     */
375     const char* getString(const char* elementID, const char* fieldName);
376 
377     /** Gets the file default directory of the URL base path set explicitly or by reading the last URL. */
378     const char* getURIBase();
379 
380     /** Resets the animator to a newly created state with no animation data. */
381     void initialize();
382 
383     /** Experimental. Resets any active animations so that the next time passed is treated as
384         time zero. */
385     void reset();
386 
387     /** Sets the scalar value of the specified element's attribute
388         @param elementID is the value of the id attribute in the XML of this element
389         @param fieldName specifies the name of the attribute
390         @param array is the c-style array of integers
391         @param count is the length of the array
392         @return true if the value was set successfully
393     */
394     bool setArrayInt(const char* elementID, const char* fieldName, const int* array, int count);
395 
396     /** Sets the scalar value of the specified element's attribute
397         @param elementID is the value of the id attribute in the XML of this element
398         @param fieldName specifies the name of the attribute
399         @param array is the c-style array of strings
400         @param count is the length of the array
401         @return true if the value was set successfully
402     */
403     bool setArrayString(const char* elementID, const char* fieldName, const char** array, int count);
404 
405     /** Sets the scalar value of the specified element's attribute
406         @param elementID is the value of the id attribute in the XML of this element
407         @param fieldName specifies the name of the attribute
408         @param data the integer value to set
409         @return true if the value was set successfully
410     */
411     bool setInt(const char* elementID, const char* fieldName, int32_t data);
412 
413     /** Sets the scalar value of the specified element's attribute
414         @param elementID is the value of the id attribute in the XML of this element
415         @param fieldName specifies the name of the attribute
416         @param data the scalar value to set
417         @return true if the value was set successfully
418     */
419     bool setScalar(const char* elementID, const char* fieldName, SkScalar data);
420 
421     /** Sets the string value of the specified element's attribute
422         @param elementID is the value of the id attribute in the XML of this element
423         @param fieldName specifies the name of the attribute
424         @param data the string value to set
425         @return true if the value was set successfully
426     */
427     bool setString(const char* elementID, const char* fieldName, const char* data);
428 
429     /** Sets the file default directory of the URL base path
430         @param path the directory path
431     */
432     void setURIBase(const char* path);
433 
434     typedef void* Handler;
435     // This guy needs to be exported to java, so don't make it virtual
setHostHandler(Handler handler)436     void setHostHandler(Handler handler) {
437         this->onSetHostHandler(handler);
438     }
439 
440     /** \class Timeline
441     Returns current time to animator. To return a custom timeline, create a child
442     class and override the getMSecs method.
443     */
444     class Timeline {
445     public:
~Timeline()446         virtual ~Timeline() {}
447 
448         /** Returns the current time in milliseconds */
449         virtual SkMSec getMSecs() const = 0;
450     };
451 
452     /** Sets a user class to return the current time to the animator.
453         Optional; if not called, the system clock will be used by calling SkTime::GetMSecs instead.
454         @param callBack the time function
455     */
456     void setTimeline(const Timeline& );
457 
458     static void Init(bool runUnitTests);
459     static void Term();
460 
461     /** The event sink events generated by the animation are posted to.
462         Screenplay also posts an inval event to this event sink after processing an
463         event to force a redraw.
464         @param target the event sink id
465     */
466     void setHostEventSinkID(SkEventSinkID hostID);
467     SkEventSinkID getHostEventSinkID() const;
468 
469     // helper
setHostEventSink(SkEventSink * sink)470     void setHostEventSink(SkEventSink* sink) {
471         this->setHostEventSinkID(sink ? sink->getSinkID() : 0);
472     }
473 
474     virtual void setJavaOwner(Handler owner);
475 
476 #ifdef SK_DEBUG
477     virtual void eventDone(const SkEvent& evt);
478     virtual bool isTrackingEvents();
479     static bool NoLeaks();
480 #endif
481 
482 protected:
483     virtual void onSetHostHandler(Handler handler);
484     virtual void onEventPost(SkEvent*, SkEventSinkID);
485     virtual void onEventPostTime(SkEvent*, SkEventSinkID, SkMSec time);
486 
487 private:
488 // helper functions for setters
489     bool setArray(SkDisplayable* element, const SkMemberInfo* field, SkTypedArray array);
490     bool setArray(const char* elementID, const char* fieldName, SkTypedArray array);
491     bool setInt(SkDisplayable* element, const SkMemberInfo* field, int32_t data);
492     bool setScalar(SkDisplayable* element, const SkMemberInfo* field, SkScalar data);
493     bool setString(SkDisplayable* element, const SkMemberInfo* field, const char* data);
494 
495     virtual bool onEvent(const SkEvent&);
496     SkAnimateMaker* fMaker;
497     friend class SkAnimateMaker;
498     friend class SkAnimatorScript;
499     friend class SkAnimatorScript2;
500     friend class SkApply;
501     friend class SkDisplayMovie;
502     friend class SkDisplayType;
503     friend class SkPost;
504     friend class SkXMLAnimatorWriter;
505 };
506 
507 #endif
508 
509