summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsubhransu mohanty <sub.mohanty@samsung.com>2017-12-14 20:22:45 +0900
committersubhransu mohanty <sub.mohanty@samsung.com>2018-04-12 13:51:52 +0900
commit4e78e7b4f2ac88ff04de5fd05abf0210e63ef853 (patch)
tree4cf8d6da14333506acabb48547afd531e13c5ac2
parent721f5f1a5f655d4854ebd9c776221322a15c14b1 (diff)
lottie: Fixed the parsing logic
-rw-r--r--ssg/src/lottie/jsontest.cpp404
-rw-r--r--ssg/src/lottie/lottiecomposition.h62
-rw-r--r--ssg/src/lottie/lottiemodel.h63
-rw-r--r--ssg/src/lottie/meson.build3
4 files changed, 314 insertions, 218 deletions
diff --git a/ssg/src/lottie/jsontest.cpp b/ssg/src/lottie/jsontest.cpp
index c49a630cfa..02f2fb0e18 100644
--- a/ssg/src/lottie/jsontest.cpp
+++ b/ssg/src/lottie/jsontest.cpp
@@ -103,34 +103,6 @@ void LookaheadParserHandler::ParseNext() {
103 } 103 }
104} 104}
105 105
106template <typename T>
107struct LottiePropertyHelper
108{
109 LottiePropertyHelper(const T &value):mAnimation(false), mStatic(value){}
110 bool mAnimation;
111 LottieProperty<T, false> mStatic;
112 LottieProperty<T,true> mDyanmic;
113};
114
115struct LottieFloatPropertyHelper
116{
117 LottieFloatPropertyHelper(float initialValue):
118 mAnimation(false), mStatic(initialValue){}
119 bool mAnimation;
120 LottieFloatProperty<false> mStatic;
121 LottieFloatProperty<true> mDyanmic;
122};
123
124struct LottiePointFPropertyHelper
125{
126 LottiePointFPropertyHelper(const SGPointF &initialValue):
127 mAnimation(false), mStatic(initialValue){}
128 bool mAnimation;
129 LottiePointFProperty<false> mStatic;
130 LottiePointFProperty<true> mDyanmic;
131};
132
133
134class LottieParser : protected LookaheadParserHandler { 106class LottieParser : protected LookaheadParserHandler {
135public: 107public:
136 LottieParser(char* str) : LookaheadParserHandler(str) {} 108 LottieParser(char* str) : LookaheadParserHandler(str) {}
@@ -154,14 +126,21 @@ public:
154 bool IsValid() { return st_ != kError; } 126 bool IsValid() { return st_ != kError; }
155 127
156 void Skip(const char *key); 128 void Skip(const char *key);
157 FIDocNode * parseDoc(); 129 SGRect getRect();
158 FINode * parseLayers(); 130 LottieBlendMode getBlendMode();
159 FINode * parseLayer(); 131
160 void parseItems(FINode *layer);
161 void parseItems1(FINode *layer);
162 void parseGroupItem(FINode *group); 132 void parseGroupItem(FINode *group);
163 void parseEllipse(FINode *parent); 133 void parseEllipse(FINode *parent);
164 void parseRectObject(); 134 LottieComposition *parseComposition();
135 void parseLayers(LottieComposition *comp);
136 LottieLayer *parseLayer();
137 void parseShapesAttr(LottieLayer *layer);
138 void parseObject(LottieGroupObj *parent);
139 LottieObject* parseObjectTypeAttr();
140 LottieObject *parseGroupObject();
141 LottieObject *parseRectObject();
142 LottieObject *parseEllipseObject();
143
165 void parseArrayValue(SGPointF &pt); 144 void parseArrayValue(SGPointF &pt);
166 void parseArrayValue(float &val); 145 void parseArrayValue(float &val);
167 template<typename T> 146 template<typename T>
@@ -176,6 +155,7 @@ protected:
176bool LottieParser::EnterObject() { 155bool LottieParser::EnterObject() {
177 if (st_ != kEnteringObject) { 156 if (st_ != kEnteringObject) {
178 st_ = kError; 157 st_ = kError;
158 RAPIDJSON_ASSERT(false);
179 return false; 159 return false;
180 } 160 }
181 161
@@ -186,6 +166,7 @@ bool LottieParser::EnterObject() {
186bool LottieParser::EnterArray() { 166bool LottieParser::EnterArray() {
187 if (st_ != kEnteringArray) { 167 if (st_ != kEnteringArray) {
188 st_ = kError; 168 st_ = kError;
169 RAPIDJSON_ASSERT(false);
189 return false; 170 return false;
190 } 171 }
191 172
@@ -200,7 +181,19 @@ const char* LottieParser::NextObjectKey() {
200 return result; 181 return result;
201 } 182 }
202 183
184 /* SPECIAL CASE
185 * The parser works with a prdefined rule that it will be only
186 * while (NextObjectKey()) for each object but in case of our nested group
187 * object we can call multiple time NextObjectKey() while exiting the object
188 * so ignore those and don't put parser in the error state.
189 * */
190 if (st_ == kExitingArray || st_ == kEnteringObject ) {
191 sgDebug<<"O: Exiting nested loop";
192 return 0;
193 }
194
203 if (st_ != kExitingObject) { 195 if (st_ != kExitingObject) {
196 RAPIDJSON_ASSERT(false);
204 st_ = kError; 197 st_ = kError;
205 return 0; 198 return 0;
206 } 199 }
@@ -215,7 +208,16 @@ bool LottieParser::NextArrayValue() {
215 return false; 208 return false;
216 } 209 }
217 210
218 if (st_ == kError || st_ == kExitingObject || st_ == kHasKey) { 211 /* SPECIAL CASE
212 * same as NextObjectKey()
213 */
214 if (st_ == kExitingObject || st_ == kEnteringArray) {
215 sgDebug<<"A: Exiting nested loop";
216 return 0;
217 }
218
219 if (st_ == kError || st_ == kHasKey) {
220 RAPIDJSON_ASSERT(false);
219 st_ = kError; 221 st_ = kError;
220 return false; 222 return false;
221 } 223 }
@@ -226,6 +228,7 @@ bool LottieParser::NextArrayValue() {
226int LottieParser::GetInt() { 228int LottieParser::GetInt() {
227 if (st_ != kHasNumber || !v_.IsInt()) { 229 if (st_ != kHasNumber || !v_.IsInt()) {
228 st_ = kError; 230 st_ = kError;
231 RAPIDJSON_ASSERT(false);
229 return 0; 232 return 0;
230 } 233 }
231 234
@@ -237,6 +240,7 @@ int LottieParser::GetInt() {
237double LottieParser::GetDouble() { 240double LottieParser::GetDouble() {
238 if (st_ != kHasNumber) { 241 if (st_ != kHasNumber) {
239 st_ = kError; 242 st_ = kError;
243 RAPIDJSON_ASSERT(false);
240 return 0.; 244 return 0.;
241 } 245 }
242 246
@@ -248,6 +252,7 @@ double LottieParser::GetDouble() {
248bool LottieParser::GetBool() { 252bool LottieParser::GetBool() {
249 if (st_ != kHasBool) { 253 if (st_ != kHasBool) {
250 st_ = kError; 254 st_ = kError;
255 RAPIDJSON_ASSERT(false);
251 return false; 256 return false;
252 } 257 }
253 258
@@ -268,6 +273,7 @@ void LottieParser::GetNull() {
268const char* LottieParser::GetString() { 273const char* LottieParser::GetString() {
269 if (st_ != kHasString) { 274 if (st_ != kHasString) {
270 st_ = kError; 275 st_ = kError;
276 RAPIDJSON_ASSERT(false);
271 return 0; 277 return 0;
272 } 278 }
273 279
@@ -285,6 +291,7 @@ void LottieParser::SkipOut(int depth) {
285 --depth; 291 --depth;
286 } 292 }
287 else if (st_ == kError) { 293 else if (st_ == kError) {
294 RAPIDJSON_ASSERT(false);
288 return; 295 return;
289 } 296 }
290 297
@@ -329,103 +336,110 @@ int LottieParser::PeekType() {
329 return -1; 336 return -1;
330} 337}
331 338
332using namespace std;
333
334void LottieParser::Skip(const char *key) 339void LottieParser::Skip(const char *key)
335{ 340{
336 if (PeekType() == kArrayType) { 341 if (PeekType() == kArrayType) {
337 if(key) 342// if(key)
338 sgWarning<<"Lottie ARRAY attribute not supported : "<<key; 343// sgWarning<<"Lottie ARRAY attribute not supported : "<<key;
339 EnterArray(); 344 EnterArray();
340 SkipArray(); 345 SkipArray();
341 } else if (PeekType() == kObjectType) { 346 } else if (PeekType() == kObjectType) {
342 if(key) 347// if(key)
343 sgWarning<<"Lottie OBJECT attribute not supported : "<<key; 348// sgWarning<<"Lottie OBJECT attribute not supported : "<<key;
344 EnterObject(); 349 EnterObject();
345 SkipObject(); 350 SkipObject();
346 } else { 351 } else {
347 SkipValue(); 352 SkipValue();
348 if(key) 353// if(key)
349 sgWarning<<"Lottie VALUE attribute not supported : "<<key; 354// sgWarning<<"Lottie VALUE attribute not supported : "<<key;
350 } 355 }
351 /* 356}
352 if (PeekType() == kArrayType) {
353 cout<<"\ntry skipping array : ";
354 if (key)
355 cout<<key;
356 EnterArray();
357 while (NextArrayValue())
358 Skip(nullptr);
359 357
360 } else if (PeekType() == kObjectType) { 358LottieBlendMode
361 cout<<"\ntry skipping Object : "; 359LottieParser::getBlendMode()
362 EnterObject(); 360{
363 while (const char* objkey = NextObjectKey()) 361 RAPIDJSON_ASSERT(PeekType() == kNumberType);
364 Skip(objkey); 362 LottieBlendMode mode = LottieBlendMode::Normal;
365 } else { 363
366 cout<<"\ntry skipping Value : "; 364 switch (GetInt()) {
367 if (key) 365 case 1:
368 cout<<key; 366 mode = LottieBlendMode::Multiply;
369 if (PeekType() == kNumberType) { 367 break;
370 cout << ": skipped number"; 368 case 2:
371 GetDouble(); 369 mode = LottieBlendMode::Screen;
372 } else if (PeekType() == kStringType) { 370 break;
373 cout << ": skipped string"; 371 case 3:
374 GetString(); 372 mode = LottieBlendMode::OverLay;
375 } else if(PeekType() == kTrueType || PeekType() == kFalseType) { 373 break;
376 cout << ": skipped boolean"; 374 default:
377 GetBool(); 375 break;
378 } else if (PeekType() == kNullType) { 376 }
379 cout << ": skipped null"; 377 return mode;
380 GetNull(); 378}
379SGRect LottieParser::getRect()
380{
381 SGRect r;
382 RAPIDJSON_ASSERT(PeekType() == kObjectType);
383 EnterObject();
384 while (const char* key = NextObjectKey()) {
385 if (0 == strcmp(key, "l")) {
386 RAPIDJSON_ASSERT(PeekType() == kNumberType);
387 r.setLeft(GetInt());
388 } else if (0 == strcmp(key, "r")) {
389 RAPIDJSON_ASSERT(PeekType() == kNumberType);
390 r.setRight(GetInt());
391 } else if (0 == strcmp(key, "t")) {
392 RAPIDJSON_ASSERT(PeekType() == kNumberType);
393 r.setTop(GetInt());
394 } else if (0 == strcmp(key, "b")) {
395 RAPIDJSON_ASSERT(PeekType() == kNumberType);
396 r.setBottom(GetInt());
397 } else {
398 RAPIDJSON_ASSERT(false);
381 } 399 }
382 } */ 400 }
401 return r;
383} 402}
384 403
385FIDocNode * LottieParser::parseDoc() 404LottieComposition *LottieParser::parseComposition()
386{ 405{
387 RAPIDJSON_ASSERT(PeekType() == kObjectType); 406 RAPIDJSON_ASSERT(PeekType() == kObjectType);
388 EnterObject(); 407 EnterObject();
389 FIDocNode *doc = new FIDocNode(); 408 LottieComposition *comp = new LottieComposition();
390 while (const char* key = NextObjectKey()) { 409 while (const char* key = NextObjectKey()) {
391 if (0 == strcmp(key, "w")) { 410 if (0 == strcmp(key, "w")) {
392 RAPIDJSON_ASSERT(PeekType() == kNumberType); 411 RAPIDJSON_ASSERT(PeekType() == kNumberType);
393 doc->mBound.setWidth(GetInt()); 412 comp->mBound.setWidth(GetInt());
394 } else if (0 == strcmp(key, "h")) { 413 } else if (0 == strcmp(key, "h")) {
395 RAPIDJSON_ASSERT(PeekType() == kNumberType); 414 RAPIDJSON_ASSERT(PeekType() == kNumberType);
396 doc->mBound.setHeight(GetInt()); 415 comp->mBound.setHeight(GetInt());
397 } else if (0 == strcmp(key, "ip")) { 416 } else if (0 == strcmp(key, "ip")) {
398 RAPIDJSON_ASSERT(PeekType() == kNumberType); 417 RAPIDJSON_ASSERT(PeekType() == kNumberType);
399 doc->mStartTime = GetDouble(); 418 comp->mStartFrame = GetDouble();
400 } else if (0 == strcmp(key, "op")) { 419 } else if (0 == strcmp(key, "op")) {
401 RAPIDJSON_ASSERT(PeekType() == kNumberType); 420 RAPIDJSON_ASSERT(PeekType() == kNumberType);
402 doc->mEndTime = GetDouble(); 421 comp->mEndFrame = GetDouble();
403 } else if (0 == strcmp(key, "fr")) { 422 } else if (0 == strcmp(key, "fr")) {
404 RAPIDJSON_ASSERT(PeekType() == kNumberType); 423 RAPIDJSON_ASSERT(PeekType() == kNumberType);
405 doc->mFrameRate = GetDouble(); 424 comp->mFrameRate = GetDouble();
406 } else if (0 == strcmp(key, "layers")) { 425 } else if (0 == strcmp(key, "layers")) {
407 RAPIDJSON_ASSERT(PeekType() == kArrayType); 426 parseLayers(comp);
408 FIGroupNode *composition = new FIGroupNode();
409 parseLayers();
410 } 427 }
411 else { 428 else {
429 sgWarning<<"Composition Attribute Skipped : "<<key;
412 Skip(key); 430 Skip(key);
413 } 431 }
414 } 432 }
415 return nullptr; 433 return comp;
416} 434}
417 435
418FINode * LottieParser::parseLayers() 436void LottieParser::parseLayers(LottieComposition *composition)
419{ 437{
420 FIGroupNode *composition = new FIGroupNode(); 438 RAPIDJSON_ASSERT(PeekType() == kArrayType);
421 EnterArray(); 439 EnterArray();
422 int i = 1;
423 while (NextArrayValue()) { 440 while (NextArrayValue()) {
424 RAPIDJSON_ASSERT(PeekType() == kObjectType); 441 auto layer = parseLayer();
425 sgDebug<<"ENTER LAYER: "<<i; 442 composition->mChildren.push_back(layer);
426 parseLayer();
427 sgDebug<<"EXIT LAYER: "<<i;
428 i++;
429 } 443 }
430} 444}
431 445
@@ -433,9 +447,11 @@ FINode * LottieParser::parseLayers()
433 * https://github.com/airbnb/lottie-web/blob/master/docs/json/layers/shape.json 447 * https://github.com/airbnb/lottie-web/blob/master/docs/json/layers/shape.json
434 * 448 *
435 */ 449 */
436FINode * LottieParser::parseLayer() 450LottieLayer * LottieParser::parseLayer()
437{ 451{
438 FIGroupNode *layer = new FIGroupNode(); 452 RAPIDJSON_ASSERT(PeekType() == kObjectType);
453 sgDebug<<"parse LAYER: S";
454 LottieLayer *layer = new LottieLayer();
439 EnterObject(); 455 EnterObject();
440 while (const char* key = NextObjectKey()) { 456 while (const char* key = NextObjectKey()) {
441 if (0 == strcmp(key, "ty")) { /* Type of layer: Shape. Value 4.*/ 457 if (0 == strcmp(key, "ty")) { /* Type of layer: Shape. Value 4.*/
@@ -449,69 +465,103 @@ FINode * LottieParser::parseLayer()
449 layer->mParentId = GetInt(); 465 layer->mParentId = GetInt();
450 }else if (0 == strcmp(key, "sr")) { // "Layer Time Stretching" 466 }else if (0 == strcmp(key, "sr")) { // "Layer Time Stretching"
451 RAPIDJSON_ASSERT(PeekType() == kNumberType); 467 RAPIDJSON_ASSERT(PeekType() == kNumberType);
452 Skip(key); 468 layer->mTimeStreatch = GetDouble();
453 } else if (0 == strcmp(key, "nm")) { /*After Effects Layer Name. Used for expressions.*/ 469 } else if (0 == strcmp(key, "ip")) {
454 RAPIDJSON_ASSERT(PeekType() == kStringType); 470 RAPIDJSON_ASSERT(PeekType() == kNumberType);
455 layer->name = GetString(); 471 layer->mStartFrame = GetDouble();
472 } else if (0 == strcmp(key, "op")) {
473 RAPIDJSON_ASSERT(PeekType() == kNumberType);
474 layer->mEndFrame = GetDouble();
475 } else if (0 == strcmp(key, "st")) {
476 RAPIDJSON_ASSERT(PeekType() == kNumberType);
477 layer->mStartTime = GetDouble();
478 } else if (0 == strcmp(key, "bounds")) {
479 layer->mBound = getRect();
480 } else if (0 == strcmp(key, "bm")) {
481 layer->mBlendMode = getBlendMode();
456 } else if (0 == strcmp(key, "shapes")) { /* Shape list of items */ 482 } else if (0 == strcmp(key, "shapes")) { /* Shape list of items */
457 sgDebug<<"ENTER SHAPE"; 483 parseShapesAttr(layer);
458 RAPIDJSON_ASSERT(PeekType() == kArrayType);
459 EnterArray();
460 while (NextArrayValue()) {
461 if (PeekType() == kObjectType) {
462 parseItems(layer);
463 } else {
464 Skip(nullptr);
465 }
466 }
467 sgDebug<<"EXIT SHAPE";
468 } else { 484 } else {
485 sgWarning<<"Layer Attribute Skipped : "<<key;
469 Skip(key); 486 Skip(key);
470 } 487 }
471 } 488 }
489 sgDebug<<"parse LAYER: E";
490 return layer;
472} 491}
473 492
474void LottieParser::parseItems(FINode *parent) 493void LottieParser::parseShapesAttr(LottieLayer *layer)
475{ 494{
476 FINode::Type nodeType = FINode::Type::Doc; 495 sgDebug<<"ENTER SHAPE ATTR";
496 RAPIDJSON_ASSERT(PeekType() == kArrayType);
497 EnterArray();
498 while (NextArrayValue()) {
499 parseObject(layer);
500 }
501 sgDebug<<"EXIT SHAPE ATTR";
502}
503
504LottieObject*
505LottieParser::parseObjectTypeAttr()
506{
507 RAPIDJSON_ASSERT(PeekType() == kStringType);
508 const char *type = GetString();
509 if (0 == strcmp(type, "gr")) {
510 return parseGroupObject();
511 } else if (0 == strcmp(type, "rc")) {
512 return parseRectObject();
513 } else if (0 == strcmp(type, "el")) {
514 return parseEllipseObject();
515 } else {
516 sgDebug<<"The Object Type not yet handled = "<< type;
517 return nullptr;
518 }
519}
520
521void
522LottieParser::parseObject(LottieGroupObj *parent)
523{
524 RAPIDJSON_ASSERT(PeekType() == kObjectType);
477 EnterObject(); 525 EnterObject();
478 //FINode *item;
479 sgDebug<<"ENTER Parse item";
480 while (const char* key = NextObjectKey()) { 526 while (const char* key = NextObjectKey()) {
481 if (0 == strcmp(key, "ty")) { 527 if (0 == strcmp(key, "ty")) {
482 const char *type = GetString(); 528 auto child = parseObjectTypeAttr();
483 sgDebug<<"Shape type :"<<type; 529 if (child)
484 if (0 == strcmp(type, "gr")) { 530 parent->mChildren.push_back(child);
485 nodeType = FINode::Type::Group; 531 } else {
486 } else if (0 == strcmp(type, "rc")) { 532 Skip(key);
487 parseRectObject(); 533 }
488 } else if (0 == strcmp(type, "el")) { 534 }
489 parseEllipse(parent); 535}
490 } else if (0 == strcmp(type, "sh")) { 536
491 nodeType = FINode::Type::Path; 537LottieObject *
492 } else { 538LottieParser::parseGroupObject()
493 } 539{
494 } else if (0 == strcmp(key, "it")) { /*After Effects Layer Name. Used for expressions.*/ 540 LottieGroupObj *group = new LottieGroupObj();
495 sgDebug<<"ENTER GROUP item"; 541 sgDebug<<"ENTER GROUP item";
542 while (const char* key = NextObjectKey()) {
543 if (0 == strcmp(key, "it")) {
544 sgDebug<<"ENTER IT attribute";
496 RAPIDJSON_ASSERT(PeekType() == kArrayType); 545 RAPIDJSON_ASSERT(PeekType() == kArrayType);
497 if (nodeType == FINode::Type::Group) 546 EnterArray();
498 parseGroupItem(parent); 547 while (NextArrayValue()) {
499 else { 548 RAPIDJSON_ASSERT(PeekType() == kObjectType);
500 assert(0); 549 parseObject(group);
501 } 550 }
502 sgDebug<<"EXIT GROUP item"; 551 sgDebug<<"EXIT IT attribute";
503 } else { 552 } else {
504 Skip(key); 553 Skip(key);
505 } 554 }
506
507 } 555 }
508 sgDebug<<"EXIT Parse item"; 556 sgDebug<<"EXIT GROUP item";
557 return group;
509} 558}
510 559
511/* 560/*
512 * https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/rect.json 561 * https://github.com/airbnb/lottie-web/blob/master/docs/json/shapes/rect.json
513 */ 562 */
514void LottieParser::parseRectObject() 563LottieObject *
564LottieParser::parseRectObject()
515{ 565{
516 LottiePropertyHelper<float> roundness(0); 566 LottiePropertyHelper<float> roundness(0);
517 while (const char* key = NextObjectKey()) { 567 while (const char* key = NextObjectKey()) {
@@ -527,8 +577,41 @@ void LottieParser::parseRectObject()
527 Skip(key); 577 Skip(key);
528 } 578 }
529 } 579 }
580 return nullptr;
581}
582
583LottieObject *
584LottieParser::parseEllipseObject()
585{
586 sgDebug<<"parse EL item START:";
587 LottiePropertyHelper<SGPointF> pos = LottiePropertyHelper<SGPointF>(SGPointF());
588 LottiePropertyHelper<SGPointF> size = LottiePropertyHelper<SGPointF>(SGPointF());
589 while (const char* key = NextObjectKey()) {
590 if (0 == strcmp(key, "p")) {
591 parseProperty(pos);
592 } else if (0 == strcmp(key, "s")) {
593 parseProperty(size);
594 } else {
595 Skip(key);
596 }
597 }
598
599 if (!pos.mAnimation && !size.mAnimation) {
600 auto obj = new LottieEllipseObject<false, false>();
601 obj->mPos = std::move(pos.mProperty.mValue);
602 obj->mSize = std::move(size.mProperty.mValue);
603 return obj;
604 } else {
605 auto obj = new LottieEllipseObject<true, true>();
606 obj->mPos = std::move(pos.mProperty);
607 obj->mSize = std::move(size.mProperty);
608 return obj;
609 }
610 sgDebug<<"parse EL item END:";
611 return nullptr;
530} 612}
531 613
614
532void LottieParser::parseArrayValue(SGPointF &pt) 615void LottieParser::parseArrayValue(SGPointF &pt)
533{ 616{
534 float val[10]; 617 float val[10];
@@ -539,7 +622,7 @@ void LottieParser::parseArrayValue(SGPointF &pt)
539 sgDebug<<"Value parsed as point / size"<<i; 622 sgDebug<<"Value parsed as point / size"<<i;
540 623
541 pt.setX(val[0]); 624 pt.setX(val[0]);
542 pt.setX(val[1]); 625 pt.setY(val[1]);
543} 626}
544 627
545void LottieParser::parseArrayValue(float &val) 628void LottieParser::parseArrayValue(float &val)
@@ -557,29 +640,31 @@ void LottieParser::parseKeyFrame(LottieProperty<T,true> &obj)
557 if (0 == strcmp(key, "i")) { 640 if (0 == strcmp(key, "i")) {
558 sgDebug<<"i"; 641 sgDebug<<"i";
559 Skip(key); 642 Skip(key);
560 } else if (0 == strcmp(key, "i")) { 643 } else if (0 == strcmp(key, "o")) {
561 sgDebug<<"o"; 644 sgDebug<<"o";
562 Skip(key); 645 Skip(key);
563 } else if (0 == strcmp(key, "n")) { 646 } else if (0 == strcmp(key, "n")) {
564 sgDebug<<"n"; 647 sgDebug<<"n";
565 Skip(key); 648 Skip(key);
566 } else if (0 == strcmp(key, "t")) { 649 } else if (0 == strcmp(key, "t")) {
567 sgDebug<<"t"; 650 keyframe.mStartFrame = GetDouble();
568 Skip(key);
569 } else if (0 == strcmp(key, "s")) { 651 } else if (0 == strcmp(key, "s")) {
570 if (PeekType() == kArrayType) 652 if (PeekType() == kArrayType)
571 EnterArray(); 653 EnterArray();
572 parseArrayValue(keyframe.mStartValue); 654 parseArrayValue(keyframe.mStartValue);
573 sgDebug<<" S consumed";
574 } else if (0 == strcmp(key, "e")) { 655 } else if (0 == strcmp(key, "e")) {
575 if (PeekType() == kArrayType) 656 if (PeekType() == kArrayType)
576 EnterArray(); 657 EnterArray();
577 parseArrayValue(keyframe.mEndValue); 658 parseArrayValue(keyframe.mEndValue);
578 sgDebug<<"E consumed";
579 } else { 659 } else {
580 Skip(key); 660 Skip(key);
581 } 661 }
582 } 662 }
663
664 if (!obj.mKeyFrames.empty()) {
665 // update the endFrame value of current keyframe
666 obj.mKeyFrames.back().mEndFrame = keyframe.mStartFrame;
667 }
583 obj.mKeyFrames.push_back(keyframe); 668 obj.mKeyFrames.push_back(keyframe);
584} 669}
585 670
@@ -598,54 +683,25 @@ void LottieParser::parseProperty(LottiePropertyHelper<T> &obj)
598 // for key frame 683 // for key frame
599 if (PeekType() == kObjectType) { 684 if (PeekType() == kObjectType) {
600 obj.mAnimation = true; 685 obj.mAnimation = true;
601 parseKeyFrame(obj.mDyanmic); 686 parseKeyFrame(obj.mProperty);
602 } else if (PeekType() == kNumberType) { 687 } else if (PeekType() == kNumberType) {
603 parseArrayValue(obj.mStatic.mValue); 688 parseArrayValue(obj.mProperty.mValue);
604 } else { 689 } else {
605 sgDebug<<"Something is really wrong here ++++++++"; 690 sgDebug<<"Something is really wrong here ++++++++";
606 Skip(nullptr); 691 Skip(nullptr);
607 } 692 }
608 } 693 }
609 } else { 694 } else {
610 sgDebug<<"PointFProperty ignored :"; 695 sgDebug<<"Property ignored :";
611 Skip(key); 696 Skip(key);
612 } 697 }
613 } 698 }
614} 699}
615 700
616void LottieParser::parseGroupItem(FINode *parent)
617{
618 FINode *group = new FIGroupNode(parent);
619 EnterArray();
620 while (NextArrayValue()) {
621 RAPIDJSON_ASSERT(PeekType() == kObjectType);
622 parseItems(group);
623 }
624}
625
626void LottieParser::parseEllipse(FINode *parent)
627{
628 sgDebug<<"parse el item :";
629 LottiePropertyHelper<SGPointF> pos = LottiePropertyHelper<SGPointF>(SGPointF());
630 LottiePropertyHelper<SGPointF> size = LottiePropertyHelper<SGPointF>(SGPointF());
631 while (const char* key = NextObjectKey()) {
632 if (0 == strcmp(key, "p")) {
633 parseProperty(pos);
634 } else if (0 == strcmp(key, "s")) {
635 parseProperty(size);
636 } else {
637 Skip(key);
638 }
639 }
640}
641
642
643SGJson::SGJson(const char *data) 701SGJson::SGJson(const char *data)
644{ 702{
645 using namespace std;
646
647 LottieParser r(const_cast<char *>(data)); 703 LottieParser r(const_cast<char *>(data));
648 r.parseDoc(); 704 r.parseComposition();
649} 705}
650 706
651RAPIDJSON_DIAG_POP 707RAPIDJSON_DIAG_POP
diff --git a/ssg/src/lottie/lottiecomposition.h b/ssg/src/lottie/lottiecomposition.h
index 870625946a..8c6c2cc43c 100644
--- a/ssg/src/lottie/lottiecomposition.h
+++ b/ssg/src/lottie/lottiecomposition.h
@@ -224,40 +224,40 @@ struct FIRadialGradinet : FIGradinet
224}; 224};
225 225
226 226
227using namespace rapidjson; 227//using namespace rapidjson;
228 228
229class LottieCompositionData; 229//class LottieCompositionData;
230class LottieComposition 230//class LottieComposition
231{ 231//{
232public: 232//public:
233 static LottieComposition fromJsonSync(JsonDoc &json); 233// static LottieComposition fromJsonSync(JsonDoc &json);
234 ~LottieComposition(); 234// ~LottieComposition();
235 LottieComposition(const LottieComposition &path); 235// LottieComposition(const LottieComposition &path);
236 LottieComposition(LottieComposition &&other); 236// LottieComposition(LottieComposition &&other);
237 LottieComposition &operator=(const LottieComposition &); 237// LottieComposition &operator=(const LottieComposition &);
238 LottieComposition &operator=(LottieComposition &&other); 238// LottieComposition &operator=(LottieComposition &&other);
239 239
240 long getStartFrame() const; 240// long getStartFrame() const;
241 long getEndFrame() const; 241// long getEndFrame() const;
242 SGRect getBounds() const; 242// SGRect getBounds() const;
243 float getDpScale() const; 243// float getDpScale() const;
244 int getMajorVersion() const; 244// int getMajorVersion() const;
245 int getMinorVersion() const; 245// int getMinorVersion() const;
246 int getPatchVersion() const; 246// int getPatchVersion() const;
247 long getDuration() const; 247// long getDuration() const;
248 248
249 friend SGDebug& operator<<(SGDebug& os, const LottieComposition& o); 249// friend SGDebug& operator<<(SGDebug& os, const LottieComposition& o);
250private: 250//private:
251 void cleanUp(LottieCompositionData *x); 251// void cleanUp(LottieCompositionData *x);
252 LottieComposition(); 252// LottieComposition();
253 friend class LottieCompositionData; 253// friend class LottieCompositionData;
254 LottieCompositionData *d; 254// LottieCompositionData *d;
255}; 255//};
256 256
257inline SGDebug& operator<<(SGDebug& os, const LottieComposition& o) 257//inline SGDebug& operator<<(SGDebug& os, const LottieComposition& o)
258{ 258//{
259 os<<"{startFrame:"<<o.getStartFrame()<<", endFrame: "<<o.getEndFrame()<<", Bound :"<<o.getBounds()<<", Duration:"<<o.getDuration()<<"}"; 259// os<<"{startFrame:"<<o.getStartFrame()<<", endFrame: "<<o.getEndFrame()<<", Bound :"<<o.getBounds()<<", Duration:"<<o.getDuration()<<"}";
260 return os; 260// return os;
261} 261//}
262 262
263#endif // LOTTIECOMPOSITION_H 263#endif // LOTTIECOMPOSITION_H
diff --git a/ssg/src/lottie/lottiemodel.h b/ssg/src/lottie/lottiemodel.h
index 0825b7cbd7..0e8c396e15 100644
--- a/ssg/src/lottie/lottiemodel.h
+++ b/ssg/src/lottie/lottiemodel.h
@@ -3,6 +3,7 @@
3 3
4#include<vector> 4#include<vector>
5#include"sgpoint.h" 5#include"sgpoint.h"
6#include"sgrect.h"
6 7
7template<typename T> 8template<typename T>
8class LottieKeyFrame 9class LottieKeyFrame
@@ -19,8 +20,10 @@ class LottieProperty
19{ 20{
20public: 21public:
21 LottieProperty(){} 22 LottieProperty(){}
22 constexpr bool isStatic() const {return false;} 23 constexpr bool staticType() const {return false;}
24 constexpr bool isStatic() const {return mKeyFrames.empty();}
23public: 25public:
26 T mValue;
24 std::vector<LottieKeyFrame<T>> mKeyFrames; 27 std::vector<LottieKeyFrame<T>> mKeyFrames;
25}; 28};
26 29
@@ -30,6 +33,7 @@ class LottieProperty<T, false>
30public: 33public:
31 LottieProperty(){} 34 LottieProperty(){}
32 LottieProperty<T,false>(T initialvalue): mValue(initialvalue){} 35 LottieProperty<T,false>(T initialvalue): mValue(initialvalue){}
36 constexpr bool staticType() const {return true;}
33 constexpr bool isStatic() const {return true;} 37 constexpr bool isStatic() const {return true;}
34public: 38public:
35 T mValue; 39 T mValue;
@@ -42,9 +46,24 @@ using LottieIntProperty = LottieProperty<int, animation>;
42template<bool animation> 46template<bool animation>
43using LottieFloatProperty = LottieProperty<float, animation>; 47using LottieFloatProperty = LottieProperty<float, animation>;
44 48
49template <typename T>
50struct LottiePropertyHelper
51{
52 LottiePropertyHelper(const T &value):mAnimation(false){ mProperty.mValue = value;}
53 bool mAnimation;
54 LottieProperty<T,true> mProperty;
55};
56
45template<bool animation> 57template<bool animation>
46using LottiePointFProperty = LottieProperty<SGPointF, animation>; 58using LottiePointFProperty = LottieProperty<SGPointF, animation>;
47 59
60enum class LottieBlendMode
61{
62 Normal = 0,
63 Multiply = 1,
64 Screen = 2,
65 OverLay = 3
66};
48class LottieObject 67class LottieObject
49{ 68{
50public: 69public:
@@ -67,7 +86,7 @@ public:
67 LottieObject::Type mType; 86 LottieObject::Type mType;
68}; 87};
69 88
70class LottieGroup : public LottieObject 89class LottieGroupObj : public LottieObject
71{ 90{
72public: 91public:
73 std::vector<LottieObject *> mChildren; 92 std::vector<LottieObject *> mChildren;
@@ -75,19 +94,33 @@ public:
75 int mId; // Lottie the group id used for parenting. 94 int mId; // Lottie the group id used for parenting.
76}; 95};
77 96
78//class LottieComposition : public LottieGroupObject 97class LottieComposition : public LottieGroupObj
79//{ 98{
80//public: 99public:
81 100 SGRect mBound;
82//}; 101 bool mpreserveAspect = false;
102 bool mAnimation = false;
103 long mStartFrame = 0;
104 long mEndFrame = 0;
105 float mFrameRate;
106};
83 107
84class LottieLayer : public LottieGroup 108class LottieLayer : public LottieGroupObj
85{ 109{
86public: 110public:
87 int mlayerType; //lottie layer type (solid/shape/precomp) 111 SGRect mBound;
112 int mlayerType; //lottie layer type (solid/shape/precomp)
113 int mParentId; // Lottie the id of the parent in the composition
114 int mId; // Lottie the group id used for parenting.
115 int mGroupType; //lottie layer type (solid/shape/precomp)
116 long mStartFrame = 0;
117 long mEndFrame = 0;
118 long mStartTime;
119 LottieBlendMode mBlendMode;
120 float mTimeStreatch;
88}; 121};
89 122
90class LottieMatrix : public LottieGroup 123class LottieMatrix : public LottieGroupObj
91{ 124{
92public: 125public:
93 LottieFloatProperty<true> mRotation; /* "r" */ 126 LottieFloatProperty<true> mRotation; /* "r" */
@@ -100,7 +133,7 @@ public:
100}; 133};
101 134
102template<bool pos, bool size, bool roundness> 135template<bool pos, bool size, bool roundness>
103class LottieRect : public LottieObject 136class LottieRectObject : public LottieObject
104{ 137{
105public: 138public:
106 LottiePointFProperty<pos> mPos; 139 LottiePointFProperty<pos> mPos;
@@ -108,6 +141,14 @@ public:
108 LottieFloatProperty<roundness> mRound; 141 LottieFloatProperty<roundness> mRound;
109}; 142};
110 143
144template<bool pos, bool size>
145class LottieEllipseObject : public LottieObject
146{
147public:
148 LottiePointFProperty<pos> mPos;
149 LottiePointFProperty<size> mSize;
150};
151
111 152
112 153
113#endif // LOTTIEMODEL_H 154#endif // LOTTIEMODEL_H
diff --git a/ssg/src/lottie/meson.build b/ssg/src/lottie/meson.build
index 022e54d15d..fa20573562 100644
--- a/ssg/src/lottie/meson.build
+++ b/ssg/src/lottie/meson.build
@@ -1,7 +1,6 @@
1ssg_sources_lottie = [] 1ssg_sources_lottie = []
2 2
3ssg_lottie_file = ['lottiecomposition.cpp', 3ssg_lottie_file = ['lottiedrawable.cpp',
4 'lottiedrawable.cpp',
5 'jsontest.cpp' 4 'jsontest.cpp'
6 ] 5 ]
7 6