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 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: 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 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