tvg_saver: save the missing scene reserve count. (#771)
authorHermet Park <hermetpark@gmail.com>
Mon, 6 Sep 2021 06:38:18 +0000 (15:38 +0900)
committerJunsuChoi <jsuya.choi@samsung.com>
Tue, 7 Sep 2021 00:45:14 +0000 (09:45 +0900)
This reserved count was just missed,
Aside from it, tvg_loader logic is not well organized (hard to expect)
We can refine it by recovering the data tree structure in the reverse order.

@Issues: https://github.com/Samsung/thorvg/issues/768

src/examples/images/test.tvg
src/lib/tvgBinaryDesc.h
src/loaders/tvg/tvgTvgBinInterpreter.cpp
src/savers/tvg/tvgTvgSaver.cpp
src/savers/tvg/tvgTvgSaver.h

index 9c42fae..4c628e3 100644 (file)
Binary files a/src/examples/images/test.tvg and b/src/examples/images/test.tvg differ
index 8760ffc..4ef59af 100644 (file)
@@ -63,7 +63,7 @@ using TvgBinFlag = TvgBinByte;
 
 
 //Scene
-#define TVG_FLAG_SCENE_RESERVEDCNT                  (TvgBinTag)0x30
+#define TVG_TAG_SCENE_RESERVEDCNT                   (TvgBinTag)0x30
 
 
 //Shape
index 1950eb2..b688eaf 100644 (file)
@@ -109,14 +109,12 @@ static bool _parseScene(TvgBinBlock block, Paint *paint)
 {
     auto scene = static_cast<Scene*>(paint);
 
-    switch (block.type) {
-        case TVG_FLAG_SCENE_RESERVEDCNT: {
-            if (block.length != SIZE(uint32_t)) return false;
-            uint32_t reservedCnt;
-            READ_UI32(&reservedCnt, block.data);
-            scene->reserve(reservedCnt);
-            return true;
-        }
+    if (block.type == TVG_TAG_SCENE_RESERVEDCNT) {
+        if (block.length != SIZE(uint32_t)) return false;
+        uint32_t reservedCnt;
+        READ_UI32(&reservedCnt, block.data);
+        scene->reserve(reservedCnt);
+        return true;
     }
 
     if (_paintProperty(block)) return _parsePaintProperty(block, scene);
index 4e07651..26a2e9d 100644 (file)
@@ -380,14 +380,14 @@ TvgBinCounter TvgSaver::serializeScene(const Scene* scene, const Matrix* pTransf
 
     //Case - Delegator Scene: This scene is just a delegator, we can skip this:
     if (scene->composite(nullptr) == CompositeMethod::None && scene->opacity() == 255) {
-        return serializeChildren(it, &transform);
+        return serializeChildren(it, &transform, false);
     }
 
     //Case - Serialize Scene & its children
     writeTag(TVG_TAG_CLASS_SCENE);
     reserveCount();
 
-    auto cnt = serializeChildren(it, &transform) + serializePaint(scene, pTransform);
+    auto cnt = serializeChildren(it, &transform, true) + serializePaint(scene, pTransform);
 
     delete(it);
 
@@ -592,7 +592,7 @@ TvgBinCounter TvgSaver::serializePicture(const Picture* picture, const Matrix* p
         } else {
             writeTag(TVG_TAG_CLASS_SCENE);
             reserveCount();
-            auto cnt = serializeChildren(it, &transform) + serializePaint(picture, pTransform);
+            auto cnt = serializeChildren(it, &transform, true) + serializePaint(picture, pTransform);
             writeReservedCount(cnt);
         }
         delete(it);
@@ -647,7 +647,7 @@ TvgBinCounter TvgSaver::serializeComposite(const Paint* cmpTarget, CompositeMeth
 }
 
 
-TvgBinCounter TvgSaver::serializeChildren(Iterator* it, const Matrix* pTransform)
+TvgBinCounter TvgSaver::serializeChildren(Iterator* it, const Matrix* pTransform, bool reserved)
 {
     TvgBinCounter cnt = 0;
 
@@ -669,6 +669,11 @@ TvgBinCounter TvgSaver::serializeChildren(Iterator* it, const Matrix* pTransform
         children.push(child);
     }
 
+    //The children of a reserved scene
+    if (reserved && children.count > 1) {
+        cnt += writeTagProperty(TVG_TAG_SCENE_RESERVEDCNT, SIZE(children.count), &children.count);
+    }
+
     //Serialize merged children.
     auto child = children.data;
     for (uint32_t i = 0; i < children.count; ++i, ++child) {
index 727c18f..155f350 100644 (file)
@@ -61,7 +61,7 @@ private:
     TvgBinCounter serializeStroke(const Shape* shape, const Matrix* pTransform);
     TvgBinCounter serializePath(const Shape* shape, const Matrix* pTransform);
     TvgBinCounter serializeComposite(const Paint* cmpTarget, CompositeMethod cmpMethod, const Matrix* pTransform);
-    TvgBinCounter serializeChildren(Iterator* it, const Matrix* transform);
+    TvgBinCounter serializeChildren(Iterator* it, const Matrix* transform, bool reserved);
     TvgBinCounter serializeChild(const Paint* parent, const Paint* child, const Matrix* pTransform);
 
 public: