middleware文件夹下services文件夹下gui文件夹合并提交
authorluozheng <1732036298@qq.com>
Wed, 23 Jul 2025 06:49:29 +0000 (14:49 +0800)
committerluozheng <1732036298@qq.com>
Wed, 23 Jul 2025 06:49:29 +0000 (14:49 +0800)
84 files changed:
code/sdk/middleware/services/gui/hal/common/include/graphic_hardware_config.h
code/sdk/middleware/services/gui/hal/display/brandy-auto-ota-cli/libdisplay_gfx.a
code/sdk/middleware/services/gui/hal/display/brandy-auto-ota-ser/libdisplay_gfx.a
code/sdk/middleware/services/gui/hal/display/brandy-native-js/libdisplay_gfx.a
code/sdk/middleware/services/gui/hal/display/brandy-target1/libdisplay_gfx.a
code/sdk/middleware/services/gui/hal/display/brandy-target3/libdisplay_gfx.a
code/sdk/middleware/services/gui/hal/display/brandy-target5/libdisplay_gfx.a
code/sdk/middleware/services/gui/hal/display/brandy-xts/libdisplay_gfx.a
code/sdk/middleware/services/gui/hal/display/src/display_gralloc.c
code/sdk/middleware/services/gui/lvgl/brandy-target1/liblvgl_proprietary_mini.a
code/sdk/middleware/services/gui/lvgl/brandy-target5/liblvgl_proprietary.a
code/sdk/middleware/services/gui/uikit/CMakeLists.txt
code/sdk/middleware/services/gui/uikit/brandy-auto-ota-cli/libuikit_ext.a
code/sdk/middleware/services/gui/uikit/brandy-auto-ota-ser/libuikit_ext.a
code/sdk/middleware/services/gui/uikit/brandy-native-js/libuikit_ext.a
code/sdk/middleware/services/gui/uikit/brandy-target3/libuikit_ext.a
code/sdk/middleware/services/gui/uikit/brandy-xts/libuikit_ext.a
code/sdk/middleware/services/gui/uikit/proprietary/include/common/image_cache_manager.h
code/sdk/middleware/services/gui/uikit/proprietary/include/components/ui_canvas_ext.h
code/sdk/middleware/services/gui/uikit/proprietary/include/components/ui_card_page.h
code/sdk/middleware/services/gui/uikit/proprietary/include/components/ui_fragment.h [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/proprietary/include/dfx/dfx_frame_trace.h
code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_comp.h [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_ellipse.h [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_flatbuffer.h [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_image_layer.h [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_interpolator.h [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_layer.h [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_math.h [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_null_layer.h [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_paint.h [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_parser.h [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_path.h [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_precomp_layer.h [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_property.h [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_rect.h [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_shape.h [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_shape_group.h [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_shape_layer.h [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_solid_layer.h [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_transform.h [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/ui_lott_view.h [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/proprietary/src/service/src/graphic_service.cpp
code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/common/lite_surface.cpp
code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/components/ui_fragment.cpp [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/components/ui_list_nested.cpp
code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/components/ui_lite_surface_view.cpp
code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/components/ui_scroll_view_nested.cpp
code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/components/ui_swipe_view_nested.cpp
code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/dfx/dfx_cmd.cpp
code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/dfx/dfx_frame_trace.cpp
code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/draw/clip_img.cpp
code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/draw/hw_draw_utils.cpp
code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/draw/hw_draw_utils.h
code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/engines/gfx/lite_m_gfx_engine.h
code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/imgdecode/hw_jpeg_decoder.cpp
code/sdk/middleware/services/gui/uikit/proprietary/src/utils/frameworks/hals/display_dev.cpp
code/sdk/middleware/services/gui/uikit/proprietary/src/utils/frameworks/hals/gralloc_engines.cpp
code/sdk/middleware/services/gui/uikit/proprietary/src/utils/frameworks/hals/lite_input_distributer.cpp
code/sdk/middleware/services/gui/uikit/proprietary/src/utils/frameworks/mem_custom.cpp
code/sdk/middleware/services/gui/uikit/proprietary/src/utils/innerkits/hals/display_dev.h
code/sdk/middleware/services/gui/uikit/proprietary/src/utils/innerkits/hals/gralloc_engines.h
code/sdk/middleware/services/gui/uikit/sample/uitest/components/ui_test_cross/ui_test_cross.cpp
code/sdk/middleware/services/gui/uikit/sample/uitest/components/ui_test_draw/ui_test_canvas_ext.cpp
code/sdk/middleware/services/gui/uikit/sample/uitest/components/ui_test_draw/ui_test_canvas_ext.h
code/sdk/middleware/services/gui/uikit/sample/uitest/components/ui_test_lottie/ui_test_lottie.cpp [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/sample/uitest/components/ui_test_lottie/ui_test_lottie.h [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/sample/uitest/components/ui_test_video_play/ui_test_video_play.cpp
code/sdk/middleware/services/gui/uikit/sample/uitest/framework/src/ui_test_group.cpp
code/sdk/middleware/services/gui/uikit/ui/frameworks/common/text.cpp
code/sdk/middleware/services/gui/uikit/ui/frameworks/components/text_adapter.cpp
code/sdk/middleware/services/gui/uikit/ui/frameworks/components/ui_box_progress.cpp
code/sdk/middleware/services/gui/uikit/ui/frameworks/components/ui_circle_progress.cpp
code/sdk/middleware/services/gui/uikit/ui/frameworks/components/ui_picker.cpp
code/sdk/middleware/services/gui/uikit/ui/frameworks/components/ui_view_group.cpp
code/sdk/middleware/services/gui/uikit/ui/frameworks/font/ui_font_vector.cpp
code/sdk/middleware/services/gui/uikit/ui/interfaces/innerkits/font/ui_font_vector.h
code/sdk/middleware/services/gui/uikit/ui/interfaces/kits/components/ui_circle_progress.h
code/sdk/middleware/services/gui/uikit/ui/interfaces/kits/components/ui_picker.h
code/sdk/middleware/services/gui/uikit/ui/interfaces/kits/components/ui_view_group.h
code/sdk/middleware/services/gui/uikit/utils/frameworks/mem_api.cpp
code/sdk/middleware/services/gui/uikit/utils/interfaces/innerkits/graphic_config.h
code/sdk/middleware/services/gui/uikit/utils/interfaces/innerkits/graphic_mutex.h
code/sdk/middleware/services/gui/uikit/utils/interfaces/kits/gfx_utils/mem_api.h

index f834f49..a84928b 100644 (file)
 #define DOUBLE_BUFFER                     1
 #endif
 
+#ifndef HW_ROTATE_ANGLE
+#define HW_ROTATE_ANGLE 0
+#endif
+
 #if !defined(RESOLUTION_WIDTH) || !defined(RESOLUTION_HEIGHT)
 #define RESOLUTION_WIDTH                  454
 #define RESOLUTION_HEIGHT                 454
 #define MEM_POOL_UI_OTHER      (MEM_POOL_UI_FONT + MEM_POOL_UI_FONT_SIZE)
 #define MEM_POOL_UI_OTHER_SIZE (MEM_POOL_UI_POOL_SIZE - MEM_POOL_UI_FONT_SIZE)
 #else // FB(psram) is physical addr, GUI dynamic allocation
-#define MEM_POOL_UI_FB         (MEM_POOL_UI_FONT + MEM_POOL_UI_FONT_SIZE)
-#define MEM_POOL_UI_FB_SIZE    ((ALIGN_UP(RESOLUTION_WIDTH, 16) * RESOLUTION_HEIGHT * LAYER_BPP / 8) * 2)
-#define MEM_POOL_UI_OTHER      (MEM_POOL_UI_FB + MEM_POOL_UI_FB_SIZE)
-#define MEM_POOL_UI_OTHER_SIZE (MEM_POOL_UI_POOL_SIZE - MEM_POOL_UI_FONT_SIZE - MEM_POOL_UI_FB_SIZE)
+#define MEM_POOL_UI_FB         0x60240000
+#define MEM_POOL_UI_FB_SIZE    0x151800 // max:480*3*480*2
+#define MEM_POOL_UI_OTHER      (MEM_POOL_UI_FONT + MEM_POOL_UI_FONT_SIZE)
+#define MEM_POOL_UI_OTHER_SIZE (MEM_POOL_UI_POOL_SIZE - MEM_POOL_UI_FONT_SIZE)
 #endif
 #endif
 
index 1c555ab..846db31 100644 (file)
Binary files a/code/sdk/middleware/services/gui/hal/display/brandy-auto-ota-cli/libdisplay_gfx.a and b/code/sdk/middleware/services/gui/hal/display/brandy-auto-ota-cli/libdisplay_gfx.a differ
index 55d1530..366791e 100644 (file)
Binary files a/code/sdk/middleware/services/gui/hal/display/brandy-auto-ota-ser/libdisplay_gfx.a and b/code/sdk/middleware/services/gui/hal/display/brandy-auto-ota-ser/libdisplay_gfx.a differ
index 5b7a503..8864f8e 100644 (file)
Binary files a/code/sdk/middleware/services/gui/hal/display/brandy-native-js/libdisplay_gfx.a and b/code/sdk/middleware/services/gui/hal/display/brandy-native-js/libdisplay_gfx.a differ
index 3325fc9..6c0dcec 100644 (file)
Binary files a/code/sdk/middleware/services/gui/hal/display/brandy-target1/libdisplay_gfx.a and b/code/sdk/middleware/services/gui/hal/display/brandy-target1/libdisplay_gfx.a differ
index 2df6c10..53a5e2d 100644 (file)
Binary files a/code/sdk/middleware/services/gui/hal/display/brandy-target3/libdisplay_gfx.a and b/code/sdk/middleware/services/gui/hal/display/brandy-target3/libdisplay_gfx.a differ
index 9e3a976..2066cb7 100644 (file)
Binary files a/code/sdk/middleware/services/gui/hal/display/brandy-target5/libdisplay_gfx.a and b/code/sdk/middleware/services/gui/hal/display/brandy-target5/libdisplay_gfx.a differ
index 93d2d8d..17aa14c 100644 (file)
Binary files a/code/sdk/middleware/services/gui/hal/display/brandy-xts/libdisplay_gfx.a and b/code/sdk/middleware/services/gui/hal/display/brandy-xts/libdisplay_gfx.a differ
index 11a0af6..ac1fe2f 100644 (file)
@@ -92,8 +92,7 @@ static bool InitMemPool(void)
     }
 
 #if CAPABILITY_HWDRAW_LETTER_VECTOR || CAPABILITY_HWDRAW_ALPHA_BITMAP
-    // 400: same minimum font cache size with ui_font_allocator, 20 x 20
-    g_fontPoolId = LosRegisterMemPool((uint8_t *)MEM_POOL_UI_FONT, MEM_POOL_UI_FONT_SIZE, 0, 400);
+    g_fontPoolId = LosRegisterMemPool((uint8_t *)MEM_POOL_UI_FONT, MEM_POOL_UI_FONT_SIZE, 0, 0);
     if (g_fontPoolId == MEMORY_POOL_ID_INVALID) {
         return false;
     }
index c065a9f..6001780 100644 (file)
Binary files a/code/sdk/middleware/services/gui/lvgl/brandy-target1/liblvgl_proprietary_mini.a and b/code/sdk/middleware/services/gui/lvgl/brandy-target1/liblvgl_proprietary_mini.a differ
index 597c388..800c51c 100644 (file)
Binary files a/code/sdk/middleware/services/gui/lvgl/brandy-target5/liblvgl_proprietary.a and b/code/sdk/middleware/services/gui/lvgl/brandy-target5/liblvgl_proprietary.a differ
index 4cd76ec..62fb078 100644 (file)
@@ -148,6 +148,8 @@ set(PRIVATE_HEADER
     ${ROOTDIR}/open_source/openharmony/third_party/libjpeg\r
     ${ROOTDIR}/open_source/openharmony/third_party/libpng\r
     ${ROOTDIR}/open_source/openharmony/foundation/graphic/ui/frameworks/imgdecode\r
+    ${ROOTDIR}/application/wearable/service/dial_market\r
+    ${ROOTDIR}/open_source/openharmony/drivers/peripheral/format/interfaces/include\r
 )\r
 \r
 set(PRIVATE_DEFINES\r
@@ -179,6 +181,7 @@ build_component()
 # build uikit ext\r
 set(COMPONENT_NAME "uikit_ext")\r
 set(PROP_UI_SRC ${UIKIT_ROOT_DIR}/proprietary/src/ui/frameworks)\r
+file(GLOB_RECURSE lottie ${PROP_UI_SRC}/lottie/*.cpp)\r
 set(COMPONENT_SRC\r
     ${PROP_UI_SRC}/engines/gfx/lite_m_gfx_engine.cpp\r
     ${PROP_UI_SRC}/font/ui_font_hw_cache.cpp\r
@@ -209,6 +212,7 @@ set(COMPONENT_SRC
     ${PROP_UI_SRC}/components_ext/ui_sphere_view.cpp\r
     ${PROP_UI_SRC}/components_ext/particle_cell.cpp\r
     ${PROP_UI_SRC}/components_ext/ui_particle_view.cpp\r
+    ${lottie}\r
 )\r
 \r
 set(SOURCES\r
@@ -224,6 +228,7 @@ set(PRIVATE_HEADER
     ${ROOTDIR}/open_source/openharmony/third_party/freetype/include\r
     ${ROOTDIR}/open_source/openharmony/third_party/icu/icu4c/source/common\r
     ${ROOTDIR}/open_source/openharmony/third_party/harfbuzz/src\r
+    ${ROOTDIR}/open_source/flatbuffers/include\r
 )\r
 \r
 set(PRIVATE_DEFINES\r
index 0938482..7b71cd5 100644 (file)
Binary files a/code/sdk/middleware/services/gui/uikit/brandy-auto-ota-cli/libuikit_ext.a and b/code/sdk/middleware/services/gui/uikit/brandy-auto-ota-cli/libuikit_ext.a differ
index 2856f3d..f8be69a 100644 (file)
Binary files a/code/sdk/middleware/services/gui/uikit/brandy-auto-ota-ser/libuikit_ext.a and b/code/sdk/middleware/services/gui/uikit/brandy-auto-ota-ser/libuikit_ext.a differ
index aa77c68..9d278be 100644 (file)
Binary files a/code/sdk/middleware/services/gui/uikit/brandy-native-js/libuikit_ext.a and b/code/sdk/middleware/services/gui/uikit/brandy-native-js/libuikit_ext.a differ
index fbaddb6..aa4d13d 100644 (file)
Binary files a/code/sdk/middleware/services/gui/uikit/brandy-target3/libuikit_ext.a and b/code/sdk/middleware/services/gui/uikit/brandy-target3/libuikit_ext.a differ
index 13ebf2c..2cef996 100644 (file)
Binary files a/code/sdk/middleware/services/gui/uikit/brandy-xts/libuikit_ext.a and b/code/sdk/middleware/services/gui/uikit/brandy-xts/libuikit_ext.a differ
index a7e8fa6..72085c0 100644 (file)
@@ -63,7 +63,7 @@ public:
      * @param file: the path of the image binary.
      *        userFP: file pointer(witch opend outside), if userFP is not nullptr, we will use it firstly.
      *        isLongTerm: whether the image should be kept in long term.
-     *        offset: the offset of the multi image start point, mainly used with input userFP(not nullptr).
+     *        offset: the offset of the multi image start point.
      */
     bool LoadAllInMultiRes(const std::string& file, FILE* userFP = nullptr, bool isLongTerm = false, int offset = 0);
 
index 105b471..0b20002 100644 (file)
@@ -272,7 +272,7 @@ public:
      * @brief Begin a path.
      *        This method would init a new path in the context.
      * @param paint Indicates the path style of the newly-created path in the context.
-     * @return Returns index value that relates to a path object. Returns -1 when any error occurs.
+     * @return Returns index value that relates to an object. Returns -1 when any error occurs.
      */
     int16_t BeginPath(const PaintExt &paint);
 
@@ -321,7 +321,7 @@ public:
      * @param startPoint Indicates the coordinates of the start point.
      * @param endPoint   Indicates the coordinates of the end point.
      * @param paint      Indicates the straight line style. For details, see {@link PaintExt}.
-     * @return Returns index value that relates to a path object. Returns -1 when any error occurs.
+     * @return Returns index value that relates to an object. Returns -1 when any error occurs.
      */
     int16_t DrawLine(const Point& startPoint, const Point& endPoint, const PaintExt& paint);
 
@@ -333,7 +333,7 @@ public:
      * @param control2   Indicates the coordinates of the second control point of the cubic Bezier curve.
      * @param endPoint   Indicates the coordinates of the end point of the cubic Bezier curve.
      * @param paint      Indicates the curve style. For details, see {@link PaintExt}.
-     * @return Returns index value that relates to a path object. Returns -1 when any error occurs.
+     * @return Returns index value that relates to an object. Returns -1 when any error occurs.
      */
     int16_t DrawCurve(const Point& startPoint, const Point& control1, const Point& control2,
         const Point& endPoint, const PaintExt& paint);
@@ -345,9 +345,10 @@ public:
      * @param height     Indicates the height of the rectangle.
      * @param width      Indicates the width of the rectangle.
      * @param paint      Indicates the rectangle style. For details, see {@link PaintExt}.
-     * @return Returns index value that relates to a path object. Returns -1 when any error occurs.
+     * @return Returns index value that relates to an object. Returns -1 when any error occurs.
      */
-    int16_t DrawRect(const Point& startPoint, int16_t height, int16_t width, const PaintExt& paint);
+    int16_t DrawRect(const Point& startPoint, int16_t height, int16_t width, const PaintExt& paint,
+        uint16_t radius = 0);
 
    /**
      * @brief Draws a circle.
@@ -355,7 +356,7 @@ public:
      * @param center Indicates the coordinates of the circle center.
      * @param radius Indicates the radius of the circle.
      * @param paint  Indicates the circle style. For details, see {@link PaintExt}.
-     * @return Returns index value that relates to a path object. Returns -1 when any error occurs.
+     * @return Returns index value that relates to an object. Returns -1 when any error occurs.
      */
     int16_t DrawCircle(const Point& center, uint16_t radius, const PaintExt& paint);
 
@@ -372,7 +373,7 @@ public:
      * @param endAngle   Indicates the end angle of the sector. Value <b>0</b> indicates the 12-o'clock direction,
      *                   and <b>90</b> indicates the 3-o'clock direction.
      * @param paint      Indicates the sector style. For details, see {@link PaintExt}.
-     * @return Returns index value that relates to a path object. Returns -1 when any error occurs.
+     * @return Returns index value that relates to an object. Returns -1 when any error occurs.
      */
     int16_t DrawSector(const Point& center, uint16_t radius,
         float startAngle, float endAngle, const PaintExt& paint);
@@ -380,7 +381,6 @@ public:
     /**
      * @brief Draws an arc.
      *
-     * Only stroke is supported.
      * When the start angle is smaller than the end angle, the sector is drawn clockwise.
      * Otherwise, the sector is drawn counterclockwise.
      *
@@ -391,11 +391,51 @@ public:
      * @param endAngle   Indicates the end angle of the arc. Value <b>0</b> indicates the 12-o'clock direction,
      *                   and <b>90</b> indicates the 3-o'clock direction.
      * @param paint      Indicates the arc style. For details, see {@link PaintExt}.
-     * @return Returns index value that relates to a path object. Returns -1 when any error occurs.
+     * @return Returns index value that relates to an object. Returns -1 when any error occurs.
      */
     int16_t DrawArc(const Point& center, uint16_t radius,
         float startAngle, float endAngle, const PaintExt& paint);
 
+    /**
+     * @brief Draws an image.
+     *
+     * @param startPoint   Indicates the coordinates of the point at the upper left corner of the image.
+     * @param image        Indicates the image bin path.
+     * @param paint        Indicates the image style. For details, see {@link PaintExt}.
+     * @return Returns index value that relates to an object. Returns -1 when any error occurs.
+     */
+    int16_t DrawImage(const Point& startPoint, const char* image, const PaintExt& paint);
+
+    /**
+     * @brief Defines the font style.
+     */
+    struct FontStyle {
+        /** Text direction. For details, see {@link UITextLanguageDirect}. */
+        UITextLanguageDirect direct;
+        /** Text alignment mode. For details, see {@link UITextLanguageAlignment}. */
+        UITextLanguageAlignment align;
+        /** Font size */
+        uint8_t fontSize;
+        /** Letter-spacing */
+        int16_t letterSpace;
+        /** Font name */
+        const char* fontName;
+    };
+
+    /**
+     * @brief Draws text.
+     *
+     * @param startPoint Indicates the coordinates of the start point.
+     * @param text       Indicates the pointer to the text content.
+     * @param maxWidth   Indicates the maximum width of the text that can be displayed. If the maximum width is
+     *                   exceeded, the text is truncated.
+     * @param fontStyle  Indicates the text layout and font style. For details, see {@link FontStyle}.
+     * @param paint      Indicates the text style. For details, see {@link Paint}.
+     * @return Returns index value that relates to an object. Returns -1 when any error occurs.
+     */
+    int16_t DrawLabel(const Point& startPoint, const char* text, uint16_t maxWidth, const FontStyle& fontStyle,
+        const PaintExt& paint);
+
     /**
      * @brief Callback for root view to draw the current content.
      *
@@ -405,20 +445,35 @@ public:
     void OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea) override;
 
 private:
-    List<Path*> paths_;
-    List<PaintExt*> paints_;
+    struct DrawCmd : public HeapBase {
+        PaintExt* paint;
+        void* param;
+        uint16_t index;
+        void(UICanvasExt::*DrawGraphics)(BufferInfo&, void*, PaintExt*, const Rect&, const Rect&, Matrix3<float>&);
+        void(UICanvasExt::*DeleteParam)(void *);
+    };
+
+    List<DrawCmd> drawCmdList_;
+    Path* curPath_;
     Graphic::Vector<SvgData*> svgObjList_;
     Graphic::Vector<SvgPath> svgPaths_;
     Graphic::Vector<Matrix3<float>> matrices_;
     bool isPathDrawable_;
 
-    void ClearInnerPaths();
-    void ClearInnerPaints();
     void ClearSvgData();
     int16_t InitGraphicPathInner(Path* path, const PaintExt& paint);
-    void PushPaintToList(const PaintExt& paint);
-    void DoDrawPath(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea,
+    void AddPaintToCmd(const PaintExt& paint, DrawCmd& cmd);
+    void DrawPathInner(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea,
         Path* path, PaintExt* paint, Matrix3<float>* matrix);
+    void DoDrawPath(BufferInfo& gfxDstBuffer, void* param, PaintExt* paint, const Rect& rect,
+        const Rect& invalidatedArea, Matrix3<float>& matrix);
+    void DoDrawImage(BufferInfo& gfxDstBuffer, void* param, PaintExt* paint, const Rect& rect,
+        const Rect& invalidatedArea, Matrix3<float>& matrix);
+    void DoDrawLabel(BufferInfo& gfxDstBuffer, void* param, PaintExt* paint, const Rect& rect,
+        const Rect& invalidatedArea, Matrix3<float>& matrix);
+    void DeletePath(void* param);
+    void DeleteImageView(void* param);
+    void DeleteLabel(void* param);
 
     SvgData* GetSvgData(const char* path);
     void PaintSetGradient(SvgData* svg, int16_t gradientIndex, PaintExt& paint, uint16_t index);
index 34a0a76..6ae88e7 100644 (file)
@@ -74,7 +74,8 @@ public:
     virtual void PreLoad(void) {}
 
     /* *
-     * @brief Unload resource callback function, it will be called at the end of swipe animator.
+     * @brief Unload resource callback function, it will be called at the end of swipe animator or the function
+     *        SetHorCurrentPage is called.
      * @since 1.0
      * @version 1.0
      */
diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/include/components/ui_fragment.h b/code/sdk/middleware/services/gui/uikit/proprietary/include/components/ui_fragment.h
new file mode 100644 (file)
index 0000000..d9a5c4a
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved.
+ * Description: UI fragment
+ * Author: Hisi Graphic Team
+ * Created: 2025-5
+ */
+#ifndef UI_FRAGMENT_H
+#define UI_FRAGMENT_H
+
+#include <unordered_map>
+#include "components/ui_view_group.h"
+
+namespace OHOS {
+// UIFragment represents a reusable fragment of UI content, it has its own life cycle, and can handle its own event
+enum class FragmentState : uint8_t {
+    INITIALIZED,
+    CREATED,
+    RESUMED
+};
+
+class UIFragment : public HeapBase {
+public:
+    /**
+     * @brief Constructor of UIFragment without parameter, it will not be added into UIFragmentManager
+     */
+    UIFragment() : id_(), state_(FragmentState::INITIALIZED) {}
+
+    /**
+     * @brief Constructor of UIFragment with parameter, it will be added into UIFragmentManager if strlen(id) > 0
+     * @param id Used to distinguish and get different UIFragment Instance from UIFragmentManager
+     */
+    UIFragment(const std::string& id);
+
+    virtual ~UIFragment();
+
+    /**
+     * @brief Invoked to call OnCreateView if state is INITIALIZED.
+     */
+    UIView* CreateView(void *data = nullptr);
+
+    /**
+     * @brief Invoked to call OnResumeView if state is CREATED
+     */
+    void ResumeView();
+
+    /**
+     * @brief Invoked to call OnPauseView if state is RESUMED
+     */
+    void PauseView();
+
+    /**
+     * @brief Invoked to call OnDestroyView if state is RESUMED or CREATED.
+     */
+    void DestroyView();
+
+    UIView* GetFragmentView()
+    {
+        return &fragmentView_;
+    }
+
+    FragmentState GetState()
+    {
+        return state_;
+    }
+
+    UIFragment(const UIFragment&) = delete;
+    UIFragment& operator=(const UIFragment&) = delete;
+    UIFragment(UIFragment&&) = delete;
+    UIFragment& operator=(UIFragment&&) = delete;
+
+protected:
+    /**
+     * @brief Recommended for creating views and add them into UIViewGroup fragmentView_.
+     */
+    virtual void OnCreateView(void* data) = 0;
+
+    /**
+     * @brief Recommended for setting input event listener, requesting focus, or starting animator here.
+     */
+    virtual void OnResumeView() {}
+
+    /**
+     * @brief Recommended for clearing input event listener, clearing focus, or stopping animator here.
+     */
+    virtual void OnPauseView() {}
+
+    /**
+     * @brief Recommended for destroying UIView or UIViewGroup which belong to UIFragment.
+     */
+    virtual void OnDestroyView() = 0;
+    UIViewGroup fragmentView_;
+
+private:
+    std::string id_;
+    FragmentState state_;
+};
+
+// UIFragmentManager can be used to fetch fragment by id
+class UIFragmentManager : public HeapBase {
+public:
+    static UIFragmentManager& GetInstance();
+    void AddFragment(const std::string& id, UIFragment* fragment);
+    void RemoveFragment(const std::string& id);
+    UIFragment* GetFragmentById(const std::string& id);
+    uint32_t GetFragmentsCount()
+    {
+        return fragments_.size();
+    }
+private:
+    UIFragmentManager() = default;
+    std::unordered_map<std::string, UIFragment*> fragments_;
+};
+}
+#endif
\ No newline at end of file
index bd9f056..e1e1edb 100644 (file)
@@ -40,6 +40,7 @@
 #define EVENT_TRACE_END() DfxFrameTrace::GetInstance().EventTraceEnd()
 #define TASK_TRACE_START() DfxFrameTrace::GetInstance().TaskTraceStart()
 #define TASK_TRACE_END() DfxFrameTrace::GetInstance().TaskTraceEnd()
+#define SET_TRACE_PATH_TYPE(type) DfxFrameTrace::GetInstance().SetPathType(type)
 #else
 #define FRAME_TRACE_START(type)
 #define FRAME_TRACE_END(type, prect)
@@ -52,6 +53,7 @@
 #define EVENT_TRACE_END()
 #define TASK_TRACE_START()
 #define TASK_TRACE_END()
+#define SET_TRACE_PATH_TYPE(type)
 #endif
 
 namespace OHOS {
@@ -75,6 +77,7 @@ enum class FrameTraceType {
     HW_DRAW_LINE,
     HW_DRAW_ARC,
     HW_DRAW_CUBICBEZIER,
+    HW_DRAW_ELLIPSE,
     DRAW_MAX
 };
 
@@ -111,6 +114,7 @@ public:
         }
     }
 
+    void SetPathType(FrameTraceType type);
     void FrameTraceStart(FrameTraceType type);
     void FrameTraceEnd(FrameTraceType type, const Rect *rect = nullptr);
     void ShowFrameTrace();
@@ -234,6 +238,7 @@ private:
     EventRecord *tailEvt_ = nullptr;
     bool eventRecording_ = false;
     bool taskRecording_ = false;
+    FrameTraceType pathType_ = FrameTraceType::HW_DRAW_PATH;
 };
 } // OHOS
 #endif // GRAPHIC_LITE_DFX_FRAME_TRACE_H
diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_comp.h b/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_comp.h
new file mode 100644 (file)
index 0000000..1b1472f
--- /dev/null
@@ -0,0 +1,35 @@
+/*\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025. All rights reserved.\r
+ * Description: Lottie\r
+ * Author: Hisi Graphic Team\r
+ * Created: 2025-6\r
+ */\r
+\r
+#ifndef LOTT_COMP_H\r
+#define LOTT_COMP_H\r
+\r
+#include <string>\r
+#include "gfx_utils/vector.h"\r
+#include "gfx_utils/graphic_buffer.h"\r
+#include "lottie/lott_layer.h"\r
+\r
+namespace OHOS {\r
+class LottComp : public HeapBase {\r
+public:\r
+    LottComp();\r
+    virtual ~LottComp();\r
+    void UpdateLottComp(float frameNo);\r
+    void DrawLottComp(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea, const Matrix3<float>& mat, uint8_t opa);\r
+    float GetFrameCnt();\r
+\r
+    float width_ = 0.0f;\r
+    float height_ = 0.0f;\r
+    float frameRate_ = 0.0f;\r
+    float inFrame_ = 0.0f;\r
+    float outFrame_ = 0.0f;\r
+    std::string version_;\r
+    std::string name_;\r
+    Graphic::Vector<LottLayer*> layers_;\r
+};\r
+}\r
+#endif // LOTT_COMP_H
\ No newline at end of file
diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_ellipse.h b/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_ellipse.h
new file mode 100644 (file)
index 0000000..4350cca
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025. All rights reserved.
+ * Description: Lottie
+ * Author: Hisi Graphic Team
+ * Created: 2025-6
+ */
+
+#ifndef LOTT_ELLIPSE
+#define LOTT_ELLIPSE
+
+#include "lottie/lott_shape.h"
+#include "lottie/lott_property.h"
+
+namespace OHOS {
+
+class LottEllipse : public LottShape {
+public:
+    LottEllipse();
+    virtual ~LottEllipse();
+
+    void Update(LottShape* parent, float frameNo) override;
+    bool GetPathData(Path& path) override;
+
+    LottPositionProp position_;
+    LottVectorProp size_;
+};
+}
+#endif // LOTT_ELLIPSE
\ No newline at end of file
diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_flatbuffer.h b/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_flatbuffer.h
new file mode 100644 (file)
index 0000000..e2a21c4
--- /dev/null
@@ -0,0 +1,5945 @@
+/*
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025. All rights reserved.
+ * Description: Lottie
+ * Author: Hisi Graphic Team
+ * Created: 2025-6
+ */
+
+#ifndef LOTT_FLATBUFFER_H
+#define LOTT_FLATBUFFER_H
+
+#include "flatbuffers/flatbuffers.h"
+
+// Ensure the included flatbuffers.h is the same version as when this file was
+// generated, otherwise it may not be compatible.
+static_assert(FLATBUFFERS_VERSION_MAJOR == 24 && FLATBUFFERS_VERSION_MINOR == 3 && FLATBUFFERS_VERSION_REVISION == 25,
+              "Non-compatible flatbuffers version included");
+
+namespace LottieFlatBuffer {
+
+struct Point;
+
+struct Color32;
+
+struct Color24;
+
+struct ColorStop;
+
+struct Gradient;
+struct GradientBuilder;
+
+struct FloatFrame;
+struct FloatFrameBuilder;
+
+struct FloatFrameArray;
+struct FloatFrameArrayBuilder;
+
+struct FloatScalar;
+struct FloatScalarBuilder;
+
+struct IntegerFrame;
+struct IntegerFrameBuilder;
+
+struct IntegerFrameArray;
+struct IntegerFrameArrayBuilder;
+
+struct IntegerScalar;
+struct IntegerScalarBuilder;
+
+struct BezierData;
+struct BezierDataBuilder;
+
+struct VectorFrame;
+struct VectorFrameBuilder;
+
+struct VectorFrameArray;
+struct VectorFrameArrayBuilder;
+
+struct ColorFrame;
+struct ColorFrameBuilder;
+
+struct ColorFrameArray;
+struct ColorFrameArrayBuilder;
+
+struct Color24Scalar;
+struct Color24ScalarBuilder;
+
+struct GradientFrame;
+struct GradientFrameBuilder;
+
+struct GradientFrameArray;
+struct GradientFrameArrayBuilder;
+
+struct BezierDataFrame;
+struct BezierDataFrameBuilder;
+
+struct BezierDataFrameArray;
+struct BezierDataFrameArrayBuilder;
+
+struct PositionFrame;
+struct PositionFrameBuilder;
+
+struct PositionFrameArray;
+struct PositionFrameArrayBuilder;
+
+struct SplitProp;
+struct SplitPropBuilder;
+
+struct Transform;
+struct TransformBuilder;
+
+struct EllipseShape;
+struct EllipseShapeBuilder;
+
+struct RectShape;
+struct RectShapeBuilder;
+
+struct PathShape;
+struct PathShapeBuilder;
+
+struct FillStyle;
+struct FillStyleBuilder;
+
+struct StrokeStyle;
+struct StrokeStyleBuilder;
+
+struct GradientFillStyle;
+struct GradientFillStyleBuilder;
+
+struct GradientStrokeStyle;
+struct GradientStrokeStyleBuilder;
+
+struct TrimPath;
+struct TrimPathBuilder;
+
+struct TransformShape;
+struct TransformShapeBuilder;
+
+struct GroupShape;
+struct GroupShapeBuilder;
+
+struct BaseLayer;
+struct BaseLayerBuilder;
+
+struct ShapeLayer;
+struct ShapeLayerBuilder;
+
+struct PrecompositionLayer;
+struct PrecompositionLayerBuilder;
+
+struct NullLayer;
+struct NullLayerBuilder;
+
+struct Rect;
+
+struct TextDocument;
+struct TextDocumentBuilder;
+
+struct TextDocumentFrame;
+struct TextDocumentFrameBuilder;
+
+struct TextData;
+struct TextDataBuilder;
+
+struct TextLayer;
+struct TextLayerBuilder;
+
+struct ImageLayer;
+struct ImageLayerBuilder;
+
+struct SolidLayer;
+struct SolidLayerBuilder;
+
+struct Asset;
+struct AssetBuilder;
+
+struct Animations;
+struct AnimationsBuilder;
+
+enum FloatProp : uint8_t {
+    FloatProp_NONE = 0,
+    FloatProp_frames = 1,
+    FloatProp_value = 2,
+    FloatProp_MIN = FloatProp_NONE,
+    FloatProp_MAX = FloatProp_value
+};
+
+inline const FloatProp (&EnumValuesFloatProp())[3]
+{
+    static const FloatProp values[] = {FloatProp_NONE, FloatProp_frames, FloatProp_value};
+    return values;
+}
+
+inline const char *const *EnumNamesFloatProp()
+{
+    static const char *const names[4] = {"NONE", "frames", "value", nullptr};
+    return names;
+}
+
+inline const char *EnumNameFloatProp(FloatProp e)
+{
+    if (::flatbuffers::IsOutRange(e, FloatProp_NONE, FloatProp_value))
+        return "";
+    const size_t index = static_cast<size_t>(e);
+    return EnumNamesFloatProp()[index];
+}
+
+template <typename T>
+struct FloatPropTraits {
+    static const FloatProp enum_value = FloatProp_NONE;
+};
+
+template <>
+struct FloatPropTraits<LottieFlatBuffer::FloatFrameArray> {
+    static const FloatProp enum_value = FloatProp_frames;
+};
+
+template <>
+struct FloatPropTraits<LottieFlatBuffer::FloatScalar> {
+    static const FloatProp enum_value = FloatProp_value;
+};
+
+bool VerifyFloatProp(::flatbuffers::Verifier &verifier, const void *obj, FloatProp type);
+bool VerifyFloatPropVector(::flatbuffers::Verifier &verifier,
+                           const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
+                           const ::flatbuffers::Vector<uint8_t> *types);
+
+enum IntegerProp : uint8_t {
+    IntegerProp_NONE = 0,
+    IntegerProp_frames = 1,
+    IntegerProp_value = 2,
+    IntegerProp_MIN = IntegerProp_NONE,
+    IntegerProp_MAX = IntegerProp_value
+};
+
+inline const IntegerProp (&EnumValuesIntegerProp())[3]
+{
+    static const IntegerProp values[] = {IntegerProp_NONE, IntegerProp_frames, IntegerProp_value};
+    return values;
+}
+
+inline const char *const *EnumNamesIntegerProp()
+{
+    static const char *const names[4] = {"NONE", "frames", "value", nullptr};
+    return names;
+}
+
+inline const char *EnumNameIntegerProp(IntegerProp e)
+{
+    if (::flatbuffers::IsOutRange(e, IntegerProp_NONE, IntegerProp_value))
+        return "";
+    const size_t index = static_cast<size_t>(e);
+    return EnumNamesIntegerProp()[index];
+}
+
+template <typename T>
+struct IntegerPropTraits {
+    static const IntegerProp enum_value = IntegerProp_NONE;
+};
+
+template <>
+struct IntegerPropTraits<LottieFlatBuffer::IntegerFrameArray> {
+    static const IntegerProp enum_value = IntegerProp_frames;
+};
+
+template <>
+struct IntegerPropTraits<LottieFlatBuffer::IntegerScalar> {
+    static const IntegerProp enum_value = IntegerProp_value;
+};
+
+bool VerifyIntegerProp(::flatbuffers::Verifier &verifier, const void *obj, IntegerProp type);
+bool VerifyIntegerPropVector(::flatbuffers::Verifier &verifier,
+                             const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
+                             const ::flatbuffers::Vector<uint8_t> *types);
+
+enum VectorProp : uint8_t {
+    VectorProp_NONE = 0,
+    VectorProp_frames = 1,
+    VectorProp_value = 2,
+    VectorProp_MIN = VectorProp_NONE,
+    VectorProp_MAX = VectorProp_value
+};
+
+inline const VectorProp (&EnumValuesVectorProp())[3]
+{
+    static const VectorProp values[] = {VectorProp_NONE, VectorProp_frames, VectorProp_value};
+    return values;
+}
+
+inline const char *const *EnumNamesVectorProp()
+{
+    static const char *const names[4] = {"NONE", "frames", "value", nullptr};
+    return names;
+}
+
+inline const char *EnumNameVectorProp(VectorProp e)
+{
+    if (::flatbuffers::IsOutRange(e, VectorProp_NONE, VectorProp_value))
+        return "";
+    const size_t index = static_cast<size_t>(e);
+    return EnumNamesVectorProp()[index];
+}
+
+template <typename T>
+struct VectorPropTraits {
+    static const VectorProp enum_value = VectorProp_NONE;
+};
+
+template <>
+struct VectorPropTraits<LottieFlatBuffer::VectorFrameArray> {
+    static const VectorProp enum_value = VectorProp_frames;
+};
+
+template <>
+struct VectorPropTraits<LottieFlatBuffer::Point> {
+    static const VectorProp enum_value = VectorProp_value;
+};
+
+bool VerifyVectorProp(::flatbuffers::Verifier &verifier, const void *obj, VectorProp type);
+bool VerifyVectorPropVector(::flatbuffers::Verifier &verifier,
+                            const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
+                            const ::flatbuffers::Vector<uint8_t> *types);
+
+enum ColorProp : uint8_t {
+    ColorProp_NONE = 0,
+    ColorProp_frames = 1,
+    ColorProp_color = 2,
+    ColorProp_MIN = ColorProp_NONE,
+    ColorProp_MAX = ColorProp_color
+};
+
+inline const ColorProp (&EnumValuesColorProp())[3]
+{
+    static const ColorProp values[] = {ColorProp_NONE, ColorProp_frames, ColorProp_color};
+    return values;
+}
+
+inline const char *const *EnumNamesColorProp()
+{
+    static const char *const names[4] = {"NONE", "frames", "color", nullptr};
+    return names;
+}
+
+inline const char *EnumNameColorProp(ColorProp e)
+{
+    if (::flatbuffers::IsOutRange(e, ColorProp_NONE, ColorProp_color))
+        return "";
+    const size_t index = static_cast<size_t>(e);
+    return EnumNamesColorProp()[index];
+}
+
+template <typename T>
+struct ColorPropTraits {
+    static const ColorProp enum_value = ColorProp_NONE;
+};
+
+template <>
+struct ColorPropTraits<LottieFlatBuffer::ColorFrameArray> {
+    static const ColorProp enum_value = ColorProp_frames;
+};
+
+template <>
+struct ColorPropTraits<LottieFlatBuffer::Color24Scalar> {
+    static const ColorProp enum_value = ColorProp_color;
+};
+
+bool VerifyColorProp(::flatbuffers::Verifier &verifier, const void *obj, ColorProp type);
+bool VerifyColorPropVector(::flatbuffers::Verifier &verifier,
+                           const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
+                           const ::flatbuffers::Vector<uint8_t> *types);
+
+enum GradientProp : uint8_t {
+    GradientProp_NONE = 0,
+    GradientProp_frames = 1,
+    GradientProp_value = 2,
+    GradientProp_MIN = GradientProp_NONE,
+    GradientProp_MAX = GradientProp_value
+};
+
+inline const GradientProp (&EnumValuesGradientProp())[3]
+{
+    static const GradientProp values[] = {GradientProp_NONE, GradientProp_frames, GradientProp_value};
+    return values;
+}
+
+inline const char *const *EnumNamesGradientProp()
+{
+    static const char *const names[4] = {"NONE", "frames", "value", nullptr};
+    return names;
+}
+
+inline const char *EnumNameGradientProp(GradientProp e)
+{
+    if (::flatbuffers::IsOutRange(e, GradientProp_NONE, GradientProp_value))
+        return "";
+    const size_t index = static_cast<size_t>(e);
+    return EnumNamesGradientProp()[index];
+}
+
+template <typename T>
+struct GradientPropTraits {
+    static const GradientProp enum_value = GradientProp_NONE;
+};
+
+template <>
+struct GradientPropTraits<LottieFlatBuffer::GradientFrameArray> {
+    static const GradientProp enum_value = GradientProp_frames;
+};
+
+template <>
+struct GradientPropTraits<LottieFlatBuffer::Gradient> {
+    static const GradientProp enum_value = GradientProp_value;
+};
+
+bool VerifyGradientProp(::flatbuffers::Verifier &verifier, const void *obj, GradientProp type);
+bool VerifyGradientPropVector(::flatbuffers::Verifier &verifier,
+                              const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
+                              const ::flatbuffers::Vector<uint8_t> *types);
+
+enum BezierDataProp : uint8_t {
+    BezierDataProp_NONE = 0,
+    BezierDataProp_frames = 1,
+    BezierDataProp_value = 2,
+    BezierDataProp_MIN = BezierDataProp_NONE,
+    BezierDataProp_MAX = BezierDataProp_value
+};
+
+inline const BezierDataProp (&EnumValuesBezierDataProp())[3]
+{
+    static const BezierDataProp values[] = {BezierDataProp_NONE, BezierDataProp_frames, BezierDataProp_value};
+    return values;
+}
+
+inline const char *const *EnumNamesBezierDataProp()
+{
+    static const char *const names[4] = {"NONE", "frames", "value", nullptr};
+    return names;
+}
+
+inline const char *EnumNameBezierDataProp(BezierDataProp e)
+{
+    if (::flatbuffers::IsOutRange(e, BezierDataProp_NONE, BezierDataProp_value))
+        return "";
+    const size_t index = static_cast<size_t>(e);
+    return EnumNamesBezierDataProp()[index];
+}
+
+template <typename T>
+struct BezierDataPropTraits {
+    static const BezierDataProp enum_value = BezierDataProp_NONE;
+};
+
+template <>
+struct BezierDataPropTraits<LottieFlatBuffer::BezierDataFrameArray> {
+    static const BezierDataProp enum_value = BezierDataProp_frames;
+};
+
+template <>
+struct BezierDataPropTraits<LottieFlatBuffer::BezierData> {
+    static const BezierDataProp enum_value = BezierDataProp_value;
+};
+
+bool VerifyBezierDataProp(::flatbuffers::Verifier &verifier, const void *obj, BezierDataProp type);
+bool VerifyBezierDataPropVector(::flatbuffers::Verifier &verifier,
+                                const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
+                                const ::flatbuffers::Vector<uint8_t> *types);
+
+enum PositionProp : uint8_t {
+    PositionProp_NONE = 0,
+    PositionProp_frames = 1,
+    PositionProp_value = 2,
+    PositionProp_MIN = PositionProp_NONE,
+    PositionProp_MAX = PositionProp_value
+};
+
+inline const PositionProp (&EnumValuesPositionProp())[3]
+{
+    static const PositionProp values[] = {PositionProp_NONE, PositionProp_frames, PositionProp_value};
+    return values;
+}
+
+inline const char *const *EnumNamesPositionProp()
+{
+    static const char *const names[4] = {"NONE", "frames", "value", nullptr};
+    return names;
+}
+
+inline const char *EnumNamePositionProp(PositionProp e)
+{
+    if (::flatbuffers::IsOutRange(e, PositionProp_NONE, PositionProp_value))
+        return "";
+    const size_t index = static_cast<size_t>(e);
+    return EnumNamesPositionProp()[index];
+}
+
+template <typename T>
+struct PositionPropTraits {
+    static const PositionProp enum_value = PositionProp_NONE;
+};
+
+template <>
+struct PositionPropTraits<LottieFlatBuffer::PositionFrameArray> {
+    static const PositionProp enum_value = PositionProp_frames;
+};
+
+template <>
+struct PositionPropTraits<LottieFlatBuffer::Point> {
+    static const PositionProp enum_value = PositionProp_value;
+};
+
+bool VerifyPositionProp(::flatbuffers::Verifier &verifier, const void *obj, PositionProp type);
+bool VerifyPositionPropVector(::flatbuffers::Verifier &verifier,
+                              const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
+                              const ::flatbuffers::Vector<uint8_t> *types);
+
+enum FillRule : int8_t {
+    FillRule_NON_ZERO = 0,
+    FillRule_EVEN_ODD = 1,
+    FillRule_MIN = FillRule_NON_ZERO,
+    FillRule_MAX = FillRule_EVEN_ODD
+};
+
+inline const FillRule (&EnumValuesFillRule())[2]
+{
+    static const FillRule values[] = {FillRule_NON_ZERO, FillRule_EVEN_ODD};
+    return values;
+}
+
+inline const char *const *EnumNamesFillRule()
+{
+    static const char *const names[3] = {"NON_ZERO", "EVEN_ODD", nullptr};
+    return names;
+}
+
+inline const char *EnumNameFillRule(FillRule e)
+{
+    if (::flatbuffers::IsOutRange(e, FillRule_NON_ZERO, FillRule_EVEN_ODD))
+        return "";
+    const size_t index = static_cast<size_t>(e);
+    return EnumNamesFillRule()[index];
+}
+
+enum LineCap : int8_t {
+    LineCap_CAP_BUTT = 0,
+    LineCap_CAP_ROUND = 1,
+    LineCap_CAP_SQUARE = 2,
+    LineCap_MIN = LineCap_CAP_BUTT,
+    LineCap_MAX = LineCap_CAP_SQUARE
+};
+
+inline const LineCap (&EnumValuesLineCap())[3]
+{
+    static const LineCap values[] = {LineCap_CAP_BUTT, LineCap_CAP_ROUND, LineCap_CAP_SQUARE};
+    return values;
+}
+
+inline const char *const *EnumNamesLineCap()
+{
+    static const char *const names[4] = {"CAP_BUTT", "CAP_ROUND", "CAP_SQUARE", nullptr};
+    return names;
+}
+
+inline const char *EnumNameLineCap(LineCap e)
+{
+    if (::flatbuffers::IsOutRange(e, LineCap_CAP_BUTT, LineCap_CAP_SQUARE))
+        return "";
+    const size_t index = static_cast<size_t>(e);
+    return EnumNamesLineCap()[index];
+}
+
+enum LineJoin : int8_t {
+    LineJoin_JOIN_MITER = 0,
+    LineJoin_JOIN_ROUND = 1,
+    LineJoin_JOIN_BEVEL = 2,
+    LineJoin_MIN = LineJoin_JOIN_MITER,
+    LineJoin_MAX = LineJoin_JOIN_BEVEL
+};
+
+inline const LineJoin (&EnumValuesLineJoin())[3]
+{
+    static const LineJoin values[] = {LineJoin_JOIN_MITER, LineJoin_JOIN_ROUND, LineJoin_JOIN_BEVEL};
+    return values;
+}
+
+inline const char *const *EnumNamesLineJoin()
+{
+    static const char *const names[4] = {"JOIN_MITER", "JOIN_ROUND", "JOIN_BEVEL", nullptr};
+    return names;
+}
+
+inline const char *EnumNameLineJoin(LineJoin e)
+{
+    if (::flatbuffers::IsOutRange(e, LineJoin_JOIN_MITER, LineJoin_JOIN_BEVEL))
+        return "";
+    const size_t index = static_cast<size_t>(e);
+    return EnumNamesLineJoin()[index];
+}
+
+enum GradientType : int8_t {
+    GradientType_GRADIENT_LINEAR = 0,
+    GradientType_GRADIENT_RADIAL = 1,
+    GradientType_MIN = GradientType_GRADIENT_LINEAR,
+    GradientType_MAX = GradientType_GRADIENT_RADIAL
+};
+
+inline const GradientType (&EnumValuesGradientType())[2]
+{
+    static const GradientType values[] = {GradientType_GRADIENT_LINEAR, GradientType_GRADIENT_RADIAL};
+    return values;
+}
+
+inline const char *const *EnumNamesGradientType()
+{
+    static const char *const names[3] = {"GRADIENT_LINEAR", "GRADIENT_RADIAL", nullptr};
+    return names;
+}
+
+inline const char *EnumNameGradientType(GradientType e)
+{
+    if (::flatbuffers::IsOutRange(e, GradientType_GRADIENT_LINEAR, GradientType_GRADIENT_RADIAL))
+        return "";
+    const size_t index = static_cast<size_t>(e);
+    return EnumNamesGradientType()[index];
+}
+
+enum TrimType : int8_t {
+    TrimType_Simultaneous = 0,
+    TrimType_Individual = 1,
+    TrimType_MIN = TrimType_Simultaneous,
+    TrimType_MAX = TrimType_Individual
+};
+
+inline const TrimType (&EnumValuesTrimType())[2]
+{
+    static const TrimType values[] = {TrimType_Simultaneous, TrimType_Individual};
+    return values;
+}
+
+inline const char *const *EnumNamesTrimType()
+{
+    static const char *const names[3] = {"Simultaneous", "Individual", nullptr};
+    return names;
+}
+
+inline const char *EnumNameTrimType(TrimType e)
+{
+    if (::flatbuffers::IsOutRange(e, TrimType_Simultaneous, TrimType_Individual))
+        return "";
+    const size_t index = static_cast<size_t>(e);
+    return EnumNamesTrimType()[index];
+}
+
+enum GraphicElement : uint8_t {
+    GraphicElement_NONE = 0,
+    GraphicElement_EllipseShape = 1,
+    GraphicElement_RectShape = 2,
+    GraphicElement_PathShape = 3,
+    GraphicElement_FillStyle = 4,
+    GraphicElement_StrokeStyle = 5,
+    GraphicElement_GradientFillStyle = 6,
+    GraphicElement_GradientStrokeStyle = 7,
+    GraphicElement_TransformShape = 8,
+    GraphicElement_TrimPath = 9,
+    GraphicElement_GroupShape = 10,
+    GraphicElement_MIN = GraphicElement_NONE,
+    GraphicElement_MAX = GraphicElement_GroupShape
+};
+
+inline const GraphicElement (&EnumValuesGraphicElement())[11]
+{
+    static const GraphicElement values[] = {GraphicElement_NONE,
+                                            GraphicElement_EllipseShape,
+                                            GraphicElement_RectShape,
+                                            GraphicElement_PathShape,
+                                            GraphicElement_FillStyle,
+                                            GraphicElement_StrokeStyle,
+                                            GraphicElement_GradientFillStyle,
+                                            GraphicElement_GradientStrokeStyle,
+                                            GraphicElement_TransformShape,
+                                            GraphicElement_TrimPath,
+                                            GraphicElement_GroupShape};
+    return values;
+}
+
+inline const char *const *EnumNamesGraphicElement()
+{
+    static const char *const names[12] = {"NONE",           "EllipseShape", "RectShape",         "PathShape",
+                                          "FillStyle",      "StrokeStyle",  "GradientFillStyle", "GradientStrokeStyle",
+                                          "TransformShape", "TrimPath",     "GroupShape",        nullptr};
+    return names;
+}
+
+inline const char *EnumNameGraphicElement(GraphicElement e)
+{
+    if (::flatbuffers::IsOutRange(e, GraphicElement_NONE, GraphicElement_GroupShape))
+        return "";
+    const size_t index = static_cast<size_t>(e);
+    return EnumNamesGraphicElement()[index];
+}
+
+template <typename T>
+struct GraphicElementTraits {
+    static const GraphicElement enum_value = GraphicElement_NONE;
+};
+
+template <>
+struct GraphicElementTraits<LottieFlatBuffer::EllipseShape> {
+    static const GraphicElement enum_value = GraphicElement_EllipseShape;
+};
+
+template <>
+struct GraphicElementTraits<LottieFlatBuffer::RectShape> {
+    static const GraphicElement enum_value = GraphicElement_RectShape;
+};
+
+template <>
+struct GraphicElementTraits<LottieFlatBuffer::PathShape> {
+    static const GraphicElement enum_value = GraphicElement_PathShape;
+};
+
+template <>
+struct GraphicElementTraits<LottieFlatBuffer::FillStyle> {
+    static const GraphicElement enum_value = GraphicElement_FillStyle;
+};
+
+template <>
+struct GraphicElementTraits<LottieFlatBuffer::StrokeStyle> {
+    static const GraphicElement enum_value = GraphicElement_StrokeStyle;
+};
+
+template <>
+struct GraphicElementTraits<LottieFlatBuffer::GradientFillStyle> {
+    static const GraphicElement enum_value = GraphicElement_GradientFillStyle;
+};
+
+template <>
+struct GraphicElementTraits<LottieFlatBuffer::GradientStrokeStyle> {
+    static const GraphicElement enum_value = GraphicElement_GradientStrokeStyle;
+};
+
+template <>
+struct GraphicElementTraits<LottieFlatBuffer::TransformShape> {
+    static const GraphicElement enum_value = GraphicElement_TransformShape;
+};
+
+template <>
+struct GraphicElementTraits<LottieFlatBuffer::TrimPath> {
+    static const GraphicElement enum_value = GraphicElement_TrimPath;
+};
+
+template <>
+struct GraphicElementTraits<LottieFlatBuffer::GroupShape> {
+    static const GraphicElement enum_value = GraphicElement_GroupShape;
+};
+
+bool VerifyGraphicElement(::flatbuffers::Verifier &verifier, const void *obj, GraphicElement type);
+bool VerifyGraphicElementVector(::flatbuffers::Verifier &verifier,
+                                const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
+                                const ::flatbuffers::Vector<uint8_t> *types);
+
+enum BlendMode : int8_t {
+    BlendMode_Normal = 0,
+    BlendMode_Overlay = 1,
+    BlendMode_Multiply = 2,
+    BlendMode_Add = 3,
+    BlendMode_MIN = BlendMode_Normal,
+    BlendMode_MAX = BlendMode_Add
+};
+
+inline const BlendMode (&EnumValuesBlendMode())[4]
+{
+    static const BlendMode values[] = {BlendMode_Normal, BlendMode_Overlay, BlendMode_Multiply, BlendMode_Add};
+    return values;
+}
+
+inline const char *const *EnumNamesBlendMode()
+{
+    static const char *const names[5] = {"Normal", "Overlay", "Multiply", "Add", nullptr};
+    return names;
+}
+
+inline const char *EnumNameBlendMode(BlendMode e)
+{
+    if (::flatbuffers::IsOutRange(e, BlendMode_Normal, BlendMode_Add))
+        return "";
+    const size_t index = static_cast<size_t>(e);
+    return EnumNamesBlendMode()[index];
+}
+
+enum TextAlign : int8_t {
+    TextAlign_AlignLeft = 1,
+    TextAlign_AlignRight = 2,
+    TextAlign_AlignCenter = 3,
+    TextAlign_MIN = TextAlign_AlignLeft,
+    TextAlign_MAX = TextAlign_AlignCenter
+};
+
+inline const TextAlign (&EnumValuesTextAlign())[3]
+{
+    static const TextAlign values[] = {TextAlign_AlignLeft, TextAlign_AlignRight, TextAlign_AlignCenter};
+    return values;
+}
+
+inline const char *const *EnumNamesTextAlign()
+{
+    static const char *const names[4] = {"AlignLeft", "AlignRight", "AlignCenter", nullptr};
+    return names;
+}
+
+inline const char *EnumNameTextAlign(TextAlign e)
+{
+    if (::flatbuffers::IsOutRange(e, TextAlign_AlignLeft, TextAlign_AlignCenter))
+        return "";
+    const size_t index = static_cast<size_t>(e) - static_cast<size_t>(TextAlign_AlignLeft);
+    return EnumNamesTextAlign()[index];
+}
+
+enum Layer : uint8_t {
+    Layer_NONE = 0,
+    Layer_PrecompositionLayer = 1,
+    Layer_SolidLayer = 2,
+    Layer_ImageLayer = 3,
+    Layer_NullLayer = 4,
+    Layer_ShapeLayer = 5,
+    Layer_TextLayer = 6,
+    Layer_MIN = Layer_NONE,
+    Layer_MAX = Layer_TextLayer
+};
+
+inline const Layer (&EnumValuesLayer())[7]
+{
+    static const Layer values[] = {Layer_NONE,      Layer_PrecompositionLayer, Layer_SolidLayer, Layer_ImageLayer,
+                                   Layer_NullLayer, Layer_ShapeLayer,          Layer_TextLayer};
+    return values;
+}
+
+inline const char *const *EnumNamesLayer()
+{
+    static const char *const names[8] = {"NONE",      "PrecompositionLayer", "SolidLayer", "ImageLayer",
+                                         "NullLayer", "ShapeLayer",          "TextLayer",  nullptr};
+    return names;
+}
+
+inline const char *EnumNameLayer(Layer e)
+{
+    if (::flatbuffers::IsOutRange(e, Layer_NONE, Layer_TextLayer))
+        return "";
+    const size_t index = static_cast<size_t>(e);
+    return EnumNamesLayer()[index];
+}
+
+template <typename T>
+struct LayerTraits {
+    static const Layer enum_value = Layer_NONE;
+};
+
+template <>
+struct LayerTraits<LottieFlatBuffer::PrecompositionLayer> {
+    static const Layer enum_value = Layer_PrecompositionLayer;
+};
+
+template <>
+struct LayerTraits<LottieFlatBuffer::SolidLayer> {
+    static const Layer enum_value = Layer_SolidLayer;
+};
+
+template <>
+struct LayerTraits<LottieFlatBuffer::ImageLayer> {
+    static const Layer enum_value = Layer_ImageLayer;
+};
+
+template <>
+struct LayerTraits<LottieFlatBuffer::NullLayer> {
+    static const Layer enum_value = Layer_NullLayer;
+};
+
+template <>
+struct LayerTraits<LottieFlatBuffer::ShapeLayer> {
+    static const Layer enum_value = Layer_ShapeLayer;
+};
+
+template <>
+struct LayerTraits<LottieFlatBuffer::TextLayer> {
+    static const Layer enum_value = Layer_TextLayer;
+};
+
+bool VerifyLayer(::flatbuffers::Verifier &verifier, const void *obj, Layer type);
+bool VerifyLayerVector(::flatbuffers::Verifier &verifier,
+                       const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
+                       const ::flatbuffers::Vector<uint8_t> *types);
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Point FLATBUFFERS_FINAL_CLASS
+{
+private:
+    float x_;
+    float y_;
+
+public:
+    Point() : x_(0), y_(0) {}
+    Point(float _x, float _y) : x_(::flatbuffers::EndianScalar(_x)), y_(::flatbuffers::EndianScalar(_y)) {}
+    float x() const
+    {
+        return ::flatbuffers::EndianScalar(x_);
+    }
+    float y() const
+    {
+        return ::flatbuffers::EndianScalar(y_);
+    }
+};
+FLATBUFFERS_STRUCT_END(Point, 8);
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(1) Color32 FLATBUFFERS_FINAL_CLASS
+{
+private:
+    uint8_t r_;
+    uint8_t g_;
+    uint8_t b_;
+    uint8_t a_;
+
+public:
+    Color32() : r_(0), g_(0), b_(0), a_(0) {}
+    Color32(uint8_t _r, uint8_t _g, uint8_t _b, uint8_t _a)
+        : r_(::flatbuffers::EndianScalar(_r)),
+          g_(::flatbuffers::EndianScalar(_g)),
+          b_(::flatbuffers::EndianScalar(_b)),
+          a_(::flatbuffers::EndianScalar(_a))
+    {
+    }
+    uint8_t r() const
+    {
+        return ::flatbuffers::EndianScalar(r_);
+    }
+    uint8_t g() const
+    {
+        return ::flatbuffers::EndianScalar(g_);
+    }
+    uint8_t b() const
+    {
+        return ::flatbuffers::EndianScalar(b_);
+    }
+    uint8_t a() const
+    {
+        return ::flatbuffers::EndianScalar(a_);
+    }
+};
+FLATBUFFERS_STRUCT_END(Color32, 4);
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(1) Color24 FLATBUFFERS_FINAL_CLASS
+{
+private:
+    uint8_t r_;
+    uint8_t g_;
+    uint8_t b_;
+
+public:
+    Color24() : r_(0), g_(0), b_(0) {}
+    Color24(uint8_t _r, uint8_t _g, uint8_t _b)
+        : r_(::flatbuffers::EndianScalar(_r)),
+          g_(::flatbuffers::EndianScalar(_g)),
+          b_(::flatbuffers::EndianScalar(_b))
+    {
+    }
+    uint8_t r() const
+    {
+        return ::flatbuffers::EndianScalar(r_);
+    }
+    uint8_t g() const
+    {
+        return ::flatbuffers::EndianScalar(g_);
+    }
+    uint8_t b() const
+    {
+        return ::flatbuffers::EndianScalar(b_);
+    }
+};
+FLATBUFFERS_STRUCT_END(Color24, 3);
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) ColorStop FLATBUFFERS_FINAL_CLASS
+{
+private:
+    float stop_;
+    LottieFlatBuffer::Color32 color_;
+
+public:
+    ColorStop() : stop_(0), color_() {}
+    ColorStop(float _stop, const LottieFlatBuffer::Color32 &_color)
+        : stop_(::flatbuffers::EndianScalar(_stop)),
+          color_(_color)
+    {
+    }
+    float stop() const
+    {
+        return ::flatbuffers::EndianScalar(stop_);
+    }
+    const LottieFlatBuffer::Color32 &color() const
+    {
+        return color_;
+    }
+};
+FLATBUFFERS_STRUCT_END(ColorStop, 8);
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Rect FLATBUFFERS_FINAL_CLASS
+{
+private:
+    LottieFlatBuffer::Point pos_;
+    LottieFlatBuffer::Point size_;
+
+public:
+    Rect() : pos_(), size_() {}
+    Rect(const LottieFlatBuffer::Point &_pos, const LottieFlatBuffer::Point &_size) : pos_(_pos), size_(_size) {}
+    const LottieFlatBuffer::Point &pos() const
+    {
+        return pos_;
+    }
+    const LottieFlatBuffer::Point &size() const
+    {
+        return size_;
+    }
+};
+FLATBUFFERS_STRUCT_END(Rect, 16);
+
+struct Gradient FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef GradientBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_STOPS = 4 };
+    const ::flatbuffers::Vector<const LottieFlatBuffer::ColorStop *> *stops() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<const LottieFlatBuffer::ColorStop *> *>(VT_STOPS);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyOffsetRequired(verifier, VT_STOPS) &&
+               verifier.VerifyVector(stops()) && verifier.EndTable();
+    }
+};
+
+struct GradientBuilder {
+    typedef Gradient Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_stops(::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::ColorStop *>> stops)
+    {
+        fbb_.AddOffset(Gradient::VT_STOPS, stops);
+    }
+    explicit GradientBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<Gradient> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<Gradient>(end);
+        fbb_.Required(o, Gradient::VT_STOPS);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<Gradient> CreateGradient(
+    ::flatbuffers::FlatBufferBuilder &_fbb,
+    ::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::ColorStop *>> stops = 0)
+{
+    GradientBuilder builder_(_fbb);
+    builder_.add_stops(stops);
+    return builder_.Finish();
+}
+
+inline ::flatbuffers::Offset<Gradient> CreateGradientDirect(
+    ::flatbuffers::FlatBufferBuilder &_fbb, const std::vector<LottieFlatBuffer::ColorStop> *stops = nullptr)
+{
+    auto stops__ = stops ? _fbb.CreateVectorOfStructs<LottieFlatBuffer::ColorStop>(*stops) : 0;
+    return LottieFlatBuffer::CreateGradient(_fbb, stops__);
+}
+
+struct FloatFrame FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef FloatFrameBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+        VT_TIME = 4,
+        VT_START = 6,
+        VT_HOLD = 8,
+        VT_TIME_EASING = 10,
+        VT_VALUE_EASING = 12
+    };
+    float time() const
+    {
+        return GetField<float>(VT_TIME, 0.0f);
+    }
+    float start() const
+    {
+        return GetField<float>(VT_START, 0.0f);
+    }
+    bool hold() const
+    {
+        return GetField<uint8_t>(VT_HOLD, 0) != 0;
+    }
+    const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *time_easing() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *>(VT_TIME_EASING);
+    }
+    const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *value_easing() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *>(VT_VALUE_EASING);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyField<float>(verifier, VT_TIME, 4) &&
+               VerifyField<float>(verifier, VT_START, 4) && VerifyField<uint8_t>(verifier, VT_HOLD, 1) &&
+               VerifyOffset(verifier, VT_TIME_EASING) && verifier.VerifyVector(time_easing()) &&
+               VerifyOffset(verifier, VT_VALUE_EASING) && verifier.VerifyVector(value_easing()) && verifier.EndTable();
+    }
+};
+
+struct FloatFrameBuilder {
+    typedef FloatFrame Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_time(float time)
+    {
+        fbb_.AddElement<float>(FloatFrame::VT_TIME, time, 0.0f);
+    }
+    void add_start(float start)
+    {
+        fbb_.AddElement<float>(FloatFrame::VT_START, start, 0.0f);
+    }
+    void add_hold(bool hold)
+    {
+        fbb_.AddElement<uint8_t>(FloatFrame::VT_HOLD, static_cast<uint8_t>(hold), 0);
+    }
+    void add_time_easing(::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> time_easing)
+    {
+        fbb_.AddOffset(FloatFrame::VT_TIME_EASING, time_easing);
+    }
+    void add_value_easing(::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> value_easing)
+    {
+        fbb_.AddOffset(FloatFrame::VT_VALUE_EASING, value_easing);
+    }
+    explicit FloatFrameBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<FloatFrame> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<FloatFrame>(end);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<FloatFrame> CreateFloatFrame(
+    ::flatbuffers::FlatBufferBuilder &_fbb, float time = 0.0f, float start = 0.0f, bool hold = false,
+    ::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> time_easing = 0,
+    ::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> value_easing = 0)
+{
+    FloatFrameBuilder builder_(_fbb);
+    builder_.add_value_easing(value_easing);
+    builder_.add_time_easing(time_easing);
+    builder_.add_start(start);
+    builder_.add_time(time);
+    builder_.add_hold(hold);
+    return builder_.Finish();
+}
+
+inline ::flatbuffers::Offset<FloatFrame> CreateFloatFrameDirect(
+    ::flatbuffers::FlatBufferBuilder &_fbb, float time = 0.0f, float start = 0.0f, bool hold = false,
+    const std::vector<LottieFlatBuffer::Point> *time_easing = nullptr,
+    const std::vector<LottieFlatBuffer::Point> *value_easing = nullptr)
+{
+    auto time_easing__ = time_easing ? _fbb.CreateVectorOfStructs<LottieFlatBuffer::Point>(*time_easing) : 0;
+    auto value_easing__ = value_easing ? _fbb.CreateVectorOfStructs<LottieFlatBuffer::Point>(*value_easing) : 0;
+    return LottieFlatBuffer::CreateFloatFrame(_fbb, time, start, hold, time_easing__, value_easing__);
+}
+
+struct FloatFrameArray FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef FloatFrameArrayBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_FRAMES = 4 };
+    const ::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::FloatFrame>> *frames() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::FloatFrame>> *>(
+            VT_FRAMES);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_FRAMES) && verifier.VerifyVector(frames()) &&
+               verifier.VerifyVectorOfTables(frames()) && verifier.EndTable();
+    }
+};
+
+struct FloatFrameArrayBuilder {
+    typedef FloatFrameArray Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_frames(
+        ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::FloatFrame>>> frames)
+    {
+        fbb_.AddOffset(FloatFrameArray::VT_FRAMES, frames);
+    }
+    explicit FloatFrameArrayBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<FloatFrameArray> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<FloatFrameArray>(end);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<FloatFrameArray> CreateFloatFrameArray(
+    ::flatbuffers::FlatBufferBuilder &_fbb,
+    ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::FloatFrame>>> frames = 0)
+{
+    FloatFrameArrayBuilder builder_(_fbb);
+    builder_.add_frames(frames);
+    return builder_.Finish();
+}
+
+inline ::flatbuffers::Offset<FloatFrameArray> CreateFloatFrameArrayDirect(
+    ::flatbuffers::FlatBufferBuilder &_fbb,
+    const std::vector<::flatbuffers::Offset<LottieFlatBuffer::FloatFrame>> *frames = nullptr)
+{
+    auto frames__ = frames ? _fbb.CreateVector<::flatbuffers::Offset<LottieFlatBuffer::FloatFrame>>(*frames) : 0;
+    return LottieFlatBuffer::CreateFloatFrameArray(_fbb, frames__);
+}
+
+struct FloatScalar FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef FloatScalarBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_VALUE = 4 };
+    float value() const
+    {
+        return GetField<float>(VT_VALUE, 0.0f);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyField<float>(verifier, VT_VALUE, 4) && verifier.EndTable();
+    }
+};
+
+struct FloatScalarBuilder {
+    typedef FloatScalar Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_value(float value)
+    {
+        fbb_.AddElement<float>(FloatScalar::VT_VALUE, value, 0.0f);
+    }
+    explicit FloatScalarBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<FloatScalar> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<FloatScalar>(end);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<FloatScalar> CreateFloatScalar(::flatbuffers::FlatBufferBuilder &_fbb, float value = 0.0f)
+{
+    FloatScalarBuilder builder_(_fbb);
+    builder_.add_value(value);
+    return builder_.Finish();
+}
+
+struct IntegerFrame FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef IntegerFrameBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+        VT_TIME = 4,
+        VT_START = 6,
+        VT_HOLD = 8,
+        VT_TIME_EASING = 10,
+        VT_VALUE_EASING = 12
+    };
+    float time() const
+    {
+        return GetField<float>(VT_TIME, 0.0f);
+    }
+    uint32_t start() const
+    {
+        return GetField<uint32_t>(VT_START, 0);
+    }
+    bool hold() const
+    {
+        return GetField<uint8_t>(VT_HOLD, 0) != 0;
+    }
+    const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *time_easing() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *>(VT_TIME_EASING);
+    }
+    const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *value_easing() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *>(VT_VALUE_EASING);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyField<float>(verifier, VT_TIME, 4) &&
+               VerifyField<uint32_t>(verifier, VT_START, 4) && VerifyField<uint8_t>(verifier, VT_HOLD, 1) &&
+               VerifyOffset(verifier, VT_TIME_EASING) && verifier.VerifyVector(time_easing()) &&
+               VerifyOffset(verifier, VT_VALUE_EASING) && verifier.VerifyVector(value_easing()) && verifier.EndTable();
+    }
+};
+
+struct IntegerFrameBuilder {
+    typedef IntegerFrame Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_time(float time)
+    {
+        fbb_.AddElement<float>(IntegerFrame::VT_TIME, time, 0.0f);
+    }
+    void add_start(uint32_t start)
+    {
+        fbb_.AddElement<uint32_t>(IntegerFrame::VT_START, start, 0);
+    }
+    void add_hold(bool hold)
+    {
+        fbb_.AddElement<uint8_t>(IntegerFrame::VT_HOLD, static_cast<uint8_t>(hold), 0);
+    }
+    void add_time_easing(::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> time_easing)
+    {
+        fbb_.AddOffset(IntegerFrame::VT_TIME_EASING, time_easing);
+    }
+    void add_value_easing(::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> value_easing)
+    {
+        fbb_.AddOffset(IntegerFrame::VT_VALUE_EASING, value_easing);
+    }
+    explicit IntegerFrameBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<IntegerFrame> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<IntegerFrame>(end);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<IntegerFrame> CreateIntegerFrame(
+    ::flatbuffers::FlatBufferBuilder &_fbb, float time = 0.0f, uint32_t start = 0, bool hold = false,
+    ::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> time_easing = 0,
+    ::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> value_easing = 0)
+{
+    IntegerFrameBuilder builder_(_fbb);
+    builder_.add_value_easing(value_easing);
+    builder_.add_time_easing(time_easing);
+    builder_.add_start(start);
+    builder_.add_time(time);
+    builder_.add_hold(hold);
+    return builder_.Finish();
+}
+
+inline ::flatbuffers::Offset<IntegerFrame> CreateIntegerFrameDirect(
+    ::flatbuffers::FlatBufferBuilder &_fbb, float time = 0.0f, uint32_t start = 0, bool hold = false,
+    const std::vector<LottieFlatBuffer::Point> *time_easing = nullptr,
+    const std::vector<LottieFlatBuffer::Point> *value_easing = nullptr)
+{
+    auto time_easing__ = time_easing ? _fbb.CreateVectorOfStructs<LottieFlatBuffer::Point>(*time_easing) : 0;
+    auto value_easing__ = value_easing ? _fbb.CreateVectorOfStructs<LottieFlatBuffer::Point>(*value_easing) : 0;
+    return LottieFlatBuffer::CreateIntegerFrame(_fbb, time, start, hold, time_easing__, value_easing__);
+}
+
+struct IntegerFrameArray FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef IntegerFrameArrayBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_FRAMES = 4 };
+    const ::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::IntegerFrame>> *frames() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::IntegerFrame>> *>(
+            VT_FRAMES);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_FRAMES) && verifier.VerifyVector(frames()) &&
+               verifier.VerifyVectorOfTables(frames()) && verifier.EndTable();
+    }
+};
+
+struct IntegerFrameArrayBuilder {
+    typedef IntegerFrameArray Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_frames(
+        ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::IntegerFrame>>> frames)
+    {
+        fbb_.AddOffset(IntegerFrameArray::VT_FRAMES, frames);
+    }
+    explicit IntegerFrameArrayBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<IntegerFrameArray> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<IntegerFrameArray>(end);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<IntegerFrameArray> CreateIntegerFrameArray(
+    ::flatbuffers::FlatBufferBuilder &_fbb,
+    ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::IntegerFrame>>> frames = 0)
+{
+    IntegerFrameArrayBuilder builder_(_fbb);
+    builder_.add_frames(frames);
+    return builder_.Finish();
+}
+
+inline ::flatbuffers::Offset<IntegerFrameArray> CreateIntegerFrameArrayDirect(
+    ::flatbuffers::FlatBufferBuilder &_fbb,
+    const std::vector<::flatbuffers::Offset<LottieFlatBuffer::IntegerFrame>> *frames = nullptr)
+{
+    auto frames__ = frames ? _fbb.CreateVector<::flatbuffers::Offset<LottieFlatBuffer::IntegerFrame>>(*frames) : 0;
+    return LottieFlatBuffer::CreateIntegerFrameArray(_fbb, frames__);
+}
+
+struct IntegerScalar FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef IntegerScalarBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_VALUE = 4 };
+    uint32_t value() const
+    {
+        return GetField<uint32_t>(VT_VALUE, 0);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyField<uint32_t>(verifier, VT_VALUE, 4) && verifier.EndTable();
+    }
+};
+
+struct IntegerScalarBuilder {
+    typedef IntegerScalar Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_value(uint32_t value)
+    {
+        fbb_.AddElement<uint32_t>(IntegerScalar::VT_VALUE, value, 0);
+    }
+    explicit IntegerScalarBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<IntegerScalar> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<IntegerScalar>(end);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<IntegerScalar> CreateIntegerScalar(::flatbuffers::FlatBufferBuilder &_fbb,
+                                                                uint32_t value = 0)
+{
+    IntegerScalarBuilder builder_(_fbb);
+    builder_.add_value(value);
+    return builder_.Finish();
+}
+
+struct BezierData FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef BezierDataBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_CMD = 4, VT_DATA = 6 };
+    const ::flatbuffers::Vector<uint8_t> *cmd() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<uint8_t> *>(VT_CMD);
+    }
+    const ::flatbuffers::Vector<float> *data() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<float> *>(VT_DATA);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyOffsetRequired(verifier, VT_CMD) && verifier.VerifyVector(cmd()) &&
+               VerifyOffsetRequired(verifier, VT_DATA) && verifier.VerifyVector(data()) && verifier.EndTable();
+    }
+};
+
+struct BezierDataBuilder {
+    typedef BezierData Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_cmd(::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> cmd)
+    {
+        fbb_.AddOffset(BezierData::VT_CMD, cmd);
+    }
+    void add_data(::flatbuffers::Offset<::flatbuffers::Vector<float>> data)
+    {
+        fbb_.AddOffset(BezierData::VT_DATA, data);
+    }
+    explicit BezierDataBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<BezierData> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<BezierData>(end);
+        fbb_.Required(o, BezierData::VT_CMD);
+        fbb_.Required(o, BezierData::VT_DATA);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<BezierData> CreateBezierData(::flatbuffers::FlatBufferBuilder &_fbb,
+                                                          ::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> cmd = 0,
+                                                          ::flatbuffers::Offset<::flatbuffers::Vector<float>> data = 0)
+{
+    BezierDataBuilder builder_(_fbb);
+    builder_.add_data(data);
+    builder_.add_cmd(cmd);
+    return builder_.Finish();
+}
+
+inline ::flatbuffers::Offset<BezierData> CreateBezierDataDirect(::flatbuffers::FlatBufferBuilder &_fbb,
+                                                                const std::vector<uint8_t> *cmd = nullptr,
+                                                                const std::vector<float> *data = nullptr)
+{
+    auto cmd__ = cmd ? _fbb.CreateVector<uint8_t>(*cmd) : 0;
+    auto data__ = data ? _fbb.CreateVector<float>(*data) : 0;
+    return LottieFlatBuffer::CreateBezierData(_fbb, cmd__, data__);
+}
+
+struct VectorFrame FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef VectorFrameBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+        VT_TIME = 4,
+        VT_START = 6,
+        VT_HOLD = 8,
+        VT_TIME_EASING = 10,
+        VT_VALUE_EASING = 12
+    };
+    float time() const
+    {
+        return GetField<float>(VT_TIME, 0.0f);
+    }
+    const LottieFlatBuffer::Point *start() const
+    {
+        return GetStruct<const LottieFlatBuffer::Point *>(VT_START);
+    }
+    bool hold() const
+    {
+        return GetField<uint8_t>(VT_HOLD, 0) != 0;
+    }
+    const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *time_easing() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *>(VT_TIME_EASING);
+    }
+    const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *value_easing() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *>(VT_VALUE_EASING);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyField<float>(verifier, VT_TIME, 4) &&
+               VerifyField<LottieFlatBuffer::Point>(verifier, VT_START, 4) &&
+               VerifyField<uint8_t>(verifier, VT_HOLD, 1) && VerifyOffset(verifier, VT_TIME_EASING) &&
+               verifier.VerifyVector(time_easing()) && VerifyOffset(verifier, VT_VALUE_EASING) &&
+               verifier.VerifyVector(value_easing()) && verifier.EndTable();
+    }
+};
+
+struct VectorFrameBuilder {
+    typedef VectorFrame Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_time(float time)
+    {
+        fbb_.AddElement<float>(VectorFrame::VT_TIME, time, 0.0f);
+    }
+    void add_start(const LottieFlatBuffer::Point *start)
+    {
+        fbb_.AddStruct(VectorFrame::VT_START, start);
+    }
+    void add_hold(bool hold)
+    {
+        fbb_.AddElement<uint8_t>(VectorFrame::VT_HOLD, static_cast<uint8_t>(hold), 0);
+    }
+    void add_time_easing(::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> time_easing)
+    {
+        fbb_.AddOffset(VectorFrame::VT_TIME_EASING, time_easing);
+    }
+    void add_value_easing(::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> value_easing)
+    {
+        fbb_.AddOffset(VectorFrame::VT_VALUE_EASING, value_easing);
+    }
+    explicit VectorFrameBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<VectorFrame> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<VectorFrame>(end);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<VectorFrame> CreateVectorFrame(
+    ::flatbuffers::FlatBufferBuilder &_fbb, float time = 0.0f, const LottieFlatBuffer::Point *start = nullptr,
+    bool hold = false, ::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> time_easing = 0,
+    ::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> value_easing = 0)
+{
+    VectorFrameBuilder builder_(_fbb);
+    builder_.add_value_easing(value_easing);
+    builder_.add_time_easing(time_easing);
+    builder_.add_start(start);
+    builder_.add_time(time);
+    builder_.add_hold(hold);
+    return builder_.Finish();
+}
+
+inline ::flatbuffers::Offset<VectorFrame> CreateVectorFrameDirect(
+    ::flatbuffers::FlatBufferBuilder &_fbb, float time = 0.0f, const LottieFlatBuffer::Point *start = nullptr,
+    bool hold = false, const std::vector<LottieFlatBuffer::Point> *time_easing = nullptr,
+    const std::vector<LottieFlatBuffer::Point> *value_easing = nullptr)
+{
+    auto time_easing__ = time_easing ? _fbb.CreateVectorOfStructs<LottieFlatBuffer::Point>(*time_easing) : 0;
+    auto value_easing__ = value_easing ? _fbb.CreateVectorOfStructs<LottieFlatBuffer::Point>(*value_easing) : 0;
+    return LottieFlatBuffer::CreateVectorFrame(_fbb, time, start, hold, time_easing__, value_easing__);
+}
+
+struct VectorFrameArray FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef VectorFrameArrayBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_FRAMES = 4 };
+    const ::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::VectorFrame>> *frames() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::VectorFrame>> *>(
+            VT_FRAMES);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyOffsetRequired(verifier, VT_FRAMES) &&
+               verifier.VerifyVector(frames()) && verifier.VerifyVectorOfTables(frames()) && verifier.EndTable();
+    }
+};
+
+struct VectorFrameArrayBuilder {
+    typedef VectorFrameArray Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_frames(
+        ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::VectorFrame>>> frames)
+    {
+        fbb_.AddOffset(VectorFrameArray::VT_FRAMES, frames);
+    }
+    explicit VectorFrameArrayBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<VectorFrameArray> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<VectorFrameArray>(end);
+        fbb_.Required(o, VectorFrameArray::VT_FRAMES);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<VectorFrameArray> CreateVectorFrameArray(
+    ::flatbuffers::FlatBufferBuilder &_fbb,
+    ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::VectorFrame>>> frames = 0)
+{
+    VectorFrameArrayBuilder builder_(_fbb);
+    builder_.add_frames(frames);
+    return builder_.Finish();
+}
+
+inline ::flatbuffers::Offset<VectorFrameArray> CreateVectorFrameArrayDirect(
+    ::flatbuffers::FlatBufferBuilder &_fbb,
+    const std::vector<::flatbuffers::Offset<LottieFlatBuffer::VectorFrame>> *frames = nullptr)
+{
+    auto frames__ = frames ? _fbb.CreateVector<::flatbuffers::Offset<LottieFlatBuffer::VectorFrame>>(*frames) : 0;
+    return LottieFlatBuffer::CreateVectorFrameArray(_fbb, frames__);
+}
+
+struct ColorFrame FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef ColorFrameBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+        VT_TIME = 4,
+        VT_START = 6,
+        VT_HOLD = 8,
+        VT_TIME_EASING = 10,
+        VT_VALUE_EASING = 12
+    };
+    float time() const
+    {
+        return GetField<float>(VT_TIME, 0.0f);
+    }
+    const LottieFlatBuffer::Color24 *start() const
+    {
+        return GetStruct<const LottieFlatBuffer::Color24 *>(VT_START);
+    }
+    bool hold() const
+    {
+        return GetField<uint8_t>(VT_HOLD, 0) != 0;
+    }
+    const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *time_easing() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *>(VT_TIME_EASING);
+    }
+    const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *value_easing() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *>(VT_VALUE_EASING);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyField<float>(verifier, VT_TIME, 4) &&
+               VerifyField<LottieFlatBuffer::Color24>(verifier, VT_START, 1) &&
+               VerifyField<uint8_t>(verifier, VT_HOLD, 1) && VerifyOffset(verifier, VT_TIME_EASING) &&
+               verifier.VerifyVector(time_easing()) && VerifyOffset(verifier, VT_VALUE_EASING) &&
+               verifier.VerifyVector(value_easing()) && verifier.EndTable();
+    }
+};
+
+struct ColorFrameBuilder {
+    typedef ColorFrame Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_time(float time)
+    {
+        fbb_.AddElement<float>(ColorFrame::VT_TIME, time, 0.0f);
+    }
+    void add_start(const LottieFlatBuffer::Color24 *start)
+    {
+        fbb_.AddStruct(ColorFrame::VT_START, start);
+    }
+    void add_hold(bool hold)
+    {
+        fbb_.AddElement<uint8_t>(ColorFrame::VT_HOLD, static_cast<uint8_t>(hold), 0);
+    }
+    void add_time_easing(::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> time_easing)
+    {
+        fbb_.AddOffset(ColorFrame::VT_TIME_EASING, time_easing);
+    }
+    void add_value_easing(::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> value_easing)
+    {
+        fbb_.AddOffset(ColorFrame::VT_VALUE_EASING, value_easing);
+    }
+    explicit ColorFrameBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<ColorFrame> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<ColorFrame>(end);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<ColorFrame> CreateColorFrame(
+    ::flatbuffers::FlatBufferBuilder &_fbb, float time = 0.0f, const LottieFlatBuffer::Color24 *start = nullptr,
+    bool hold = false, ::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> time_easing = 0,
+    ::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> value_easing = 0)
+{
+    ColorFrameBuilder builder_(_fbb);
+    builder_.add_value_easing(value_easing);
+    builder_.add_time_easing(time_easing);
+    builder_.add_start(start);
+    builder_.add_time(time);
+    builder_.add_hold(hold);
+    return builder_.Finish();
+}
+
+inline ::flatbuffers::Offset<ColorFrame> CreateColorFrameDirect(
+    ::flatbuffers::FlatBufferBuilder &_fbb, float time = 0.0f, const LottieFlatBuffer::Color24 *start = nullptr,
+    bool hold = false, const std::vector<LottieFlatBuffer::Point> *time_easing = nullptr,
+    const std::vector<LottieFlatBuffer::Point> *value_easing = nullptr)
+{
+    auto time_easing__ = time_easing ? _fbb.CreateVectorOfStructs<LottieFlatBuffer::Point>(*time_easing) : 0;
+    auto value_easing__ = value_easing ? _fbb.CreateVectorOfStructs<LottieFlatBuffer::Point>(*value_easing) : 0;
+    return LottieFlatBuffer::CreateColorFrame(_fbb, time, start, hold, time_easing__, value_easing__);
+}
+
+struct ColorFrameArray FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef ColorFrameArrayBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_FRAMES = 4 };
+    const ::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::ColorFrame>> *frames() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::ColorFrame>> *>(
+            VT_FRAMES);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyOffsetRequired(verifier, VT_FRAMES) &&
+               verifier.VerifyVector(frames()) && verifier.VerifyVectorOfTables(frames()) && verifier.EndTable();
+    }
+};
+
+struct ColorFrameArrayBuilder {
+    typedef ColorFrameArray Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_frames(
+        ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::ColorFrame>>> frames)
+    {
+        fbb_.AddOffset(ColorFrameArray::VT_FRAMES, frames);
+    }
+    explicit ColorFrameArrayBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<ColorFrameArray> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<ColorFrameArray>(end);
+        fbb_.Required(o, ColorFrameArray::VT_FRAMES);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<ColorFrameArray> CreateColorFrameArray(
+    ::flatbuffers::FlatBufferBuilder &_fbb,
+    ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::ColorFrame>>> frames = 0)
+{
+    ColorFrameArrayBuilder builder_(_fbb);
+    builder_.add_frames(frames);
+    return builder_.Finish();
+}
+
+inline ::flatbuffers::Offset<ColorFrameArray> CreateColorFrameArrayDirect(
+    ::flatbuffers::FlatBufferBuilder &_fbb,
+    const std::vector<::flatbuffers::Offset<LottieFlatBuffer::ColorFrame>> *frames = nullptr)
+{
+    auto frames__ = frames ? _fbb.CreateVector<::flatbuffers::Offset<LottieFlatBuffer::ColorFrame>>(*frames) : 0;
+    return LottieFlatBuffer::CreateColorFrameArray(_fbb, frames__);
+}
+
+struct Color24Scalar FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef Color24ScalarBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_VALUE = 4 };
+    const LottieFlatBuffer::Color24 *value() const
+    {
+        return GetStruct<const LottieFlatBuffer::Color24 *>(VT_VALUE);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyField<LottieFlatBuffer::Color24>(verifier, VT_VALUE, 1) &&
+               verifier.EndTable();
+    }
+};
+
+struct Color24ScalarBuilder {
+    typedef Color24Scalar Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_value(const LottieFlatBuffer::Color24 *value)
+    {
+        fbb_.AddStruct(Color24Scalar::VT_VALUE, value);
+    }
+    explicit Color24ScalarBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<Color24Scalar> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<Color24Scalar>(end);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<Color24Scalar> CreateColor24Scalar(::flatbuffers::FlatBufferBuilder &_fbb,
+                                                                const LottieFlatBuffer::Color24 *value = nullptr)
+{
+    Color24ScalarBuilder builder_(_fbb);
+    builder_.add_value(value);
+    return builder_.Finish();
+}
+
+struct GradientFrame FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef GradientFrameBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+        VT_TIME = 4,
+        VT_START = 6,
+        VT_HOLD = 8,
+        VT_TIME_EASING = 10,
+        VT_VALUE_EASING = 12
+    };
+    float time() const
+    {
+        return GetField<float>(VT_TIME, 0.0f);
+    }
+    const LottieFlatBuffer::Gradient *start() const
+    {
+        return GetPointer<const LottieFlatBuffer::Gradient *>(VT_START);
+    }
+    bool hold() const
+    {
+        return GetField<uint8_t>(VT_HOLD, 0) != 0;
+    }
+    const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *time_easing() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *>(VT_TIME_EASING);
+    }
+    const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *value_easing() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *>(VT_VALUE_EASING);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyField<float>(verifier, VT_TIME, 4) &&
+               VerifyOffsetRequired(verifier, VT_START) && verifier.VerifyTable(start()) &&
+               VerifyField<uint8_t>(verifier, VT_HOLD, 1) && VerifyOffset(verifier, VT_TIME_EASING) &&
+               verifier.VerifyVector(time_easing()) && VerifyOffset(verifier, VT_VALUE_EASING) &&
+               verifier.VerifyVector(value_easing()) && verifier.EndTable();
+    }
+};
+
+struct GradientFrameBuilder {
+    typedef GradientFrame Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_time(float time)
+    {
+        fbb_.AddElement<float>(GradientFrame::VT_TIME, time, 0.0f);
+    }
+    void add_start(::flatbuffers::Offset<LottieFlatBuffer::Gradient> start)
+    {
+        fbb_.AddOffset(GradientFrame::VT_START, start);
+    }
+    void add_hold(bool hold)
+    {
+        fbb_.AddElement<uint8_t>(GradientFrame::VT_HOLD, static_cast<uint8_t>(hold), 0);
+    }
+    void add_time_easing(::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> time_easing)
+    {
+        fbb_.AddOffset(GradientFrame::VT_TIME_EASING, time_easing);
+    }
+    void add_value_easing(::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> value_easing)
+    {
+        fbb_.AddOffset(GradientFrame::VT_VALUE_EASING, value_easing);
+    }
+    explicit GradientFrameBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<GradientFrame> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<GradientFrame>(end);
+        fbb_.Required(o, GradientFrame::VT_START);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<GradientFrame> CreateGradientFrame(
+    ::flatbuffers::FlatBufferBuilder &_fbb, float time = 0.0f,
+    ::flatbuffers::Offset<LottieFlatBuffer::Gradient> start = 0, bool hold = false,
+    ::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> time_easing = 0,
+    ::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> value_easing = 0)
+{
+    GradientFrameBuilder builder_(_fbb);
+    builder_.add_value_easing(value_easing);
+    builder_.add_time_easing(time_easing);
+    builder_.add_start(start);
+    builder_.add_time(time);
+    builder_.add_hold(hold);
+    return builder_.Finish();
+}
+
+inline ::flatbuffers::Offset<GradientFrame> CreateGradientFrameDirect(
+    ::flatbuffers::FlatBufferBuilder &_fbb, float time = 0.0f,
+    ::flatbuffers::Offset<LottieFlatBuffer::Gradient> start = 0, bool hold = false,
+    const std::vector<LottieFlatBuffer::Point> *time_easing = nullptr,
+    const std::vector<LottieFlatBuffer::Point> *value_easing = nullptr)
+{
+    auto time_easing__ = time_easing ? _fbb.CreateVectorOfStructs<LottieFlatBuffer::Point>(*time_easing) : 0;
+    auto value_easing__ = value_easing ? _fbb.CreateVectorOfStructs<LottieFlatBuffer::Point>(*value_easing) : 0;
+    return LottieFlatBuffer::CreateGradientFrame(_fbb, time, start, hold, time_easing__, value_easing__);
+}
+
+struct GradientFrameArray FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef GradientFrameArrayBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_FRAMES = 4 };
+    const ::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::GradientFrame>> *frames() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::GradientFrame>> *>(
+            VT_FRAMES);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyOffsetRequired(verifier, VT_FRAMES) &&
+               verifier.VerifyVector(frames()) && verifier.VerifyVectorOfTables(frames()) && verifier.EndTable();
+    }
+};
+
+struct GradientFrameArrayBuilder {
+    typedef GradientFrameArray Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_frames(
+        ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::GradientFrame>>> frames)
+    {
+        fbb_.AddOffset(GradientFrameArray::VT_FRAMES, frames);
+    }
+    explicit GradientFrameArrayBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<GradientFrameArray> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<GradientFrameArray>(end);
+        fbb_.Required(o, GradientFrameArray::VT_FRAMES);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<GradientFrameArray> CreateGradientFrameArray(
+    ::flatbuffers::FlatBufferBuilder &_fbb,
+    ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::GradientFrame>>> frames = 0)
+{
+    GradientFrameArrayBuilder builder_(_fbb);
+    builder_.add_frames(frames);
+    return builder_.Finish();
+}
+
+inline ::flatbuffers::Offset<GradientFrameArray> CreateGradientFrameArrayDirect(
+    ::flatbuffers::FlatBufferBuilder &_fbb,
+    const std::vector<::flatbuffers::Offset<LottieFlatBuffer::GradientFrame>> *frames = nullptr)
+{
+    auto frames__ = frames ? _fbb.CreateVector<::flatbuffers::Offset<LottieFlatBuffer::GradientFrame>>(*frames) : 0;
+    return LottieFlatBuffer::CreateGradientFrameArray(_fbb, frames__);
+}
+
+struct BezierDataFrame FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef BezierDataFrameBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+        VT_TIME = 4,
+        VT_START = 6,
+        VT_HOLD = 8,
+        VT_TIME_EASING = 10,
+        VT_VALUE_EASING = 12
+    };
+    float time() const
+    {
+        return GetField<float>(VT_TIME, 0.0f);
+    }
+    const LottieFlatBuffer::BezierData *start() const
+    {
+        return GetPointer<const LottieFlatBuffer::BezierData *>(VT_START);
+    }
+    bool hold() const
+    {
+        return GetField<uint8_t>(VT_HOLD, 0) != 0;
+    }
+    const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *time_easing() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *>(VT_TIME_EASING);
+    }
+    const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *value_easing() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *>(VT_VALUE_EASING);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyField<float>(verifier, VT_TIME, 4) &&
+               VerifyOffsetRequired(verifier, VT_START) && verifier.VerifyTable(start()) &&
+               VerifyField<uint8_t>(verifier, VT_HOLD, 1) && VerifyOffset(verifier, VT_TIME_EASING) &&
+               verifier.VerifyVector(time_easing()) && VerifyOffset(verifier, VT_VALUE_EASING) &&
+               verifier.VerifyVector(value_easing()) && verifier.EndTable();
+    }
+};
+
+struct BezierDataFrameBuilder {
+    typedef BezierDataFrame Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_time(float time)
+    {
+        fbb_.AddElement<float>(BezierDataFrame::VT_TIME, time, 0.0f);
+    }
+    void add_start(::flatbuffers::Offset<LottieFlatBuffer::BezierData> start)
+    {
+        fbb_.AddOffset(BezierDataFrame::VT_START, start);
+    }
+    void add_hold(bool hold)
+    {
+        fbb_.AddElement<uint8_t>(BezierDataFrame::VT_HOLD, static_cast<uint8_t>(hold), 0);
+    }
+    void add_time_easing(::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> time_easing)
+    {
+        fbb_.AddOffset(BezierDataFrame::VT_TIME_EASING, time_easing);
+    }
+    void add_value_easing(::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> value_easing)
+    {
+        fbb_.AddOffset(BezierDataFrame::VT_VALUE_EASING, value_easing);
+    }
+    explicit BezierDataFrameBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<BezierDataFrame> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<BezierDataFrame>(end);
+        fbb_.Required(o, BezierDataFrame::VT_START);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<BezierDataFrame> CreateBezierDataFrame(
+    ::flatbuffers::FlatBufferBuilder &_fbb, float time = 0.0f,
+    ::flatbuffers::Offset<LottieFlatBuffer::BezierData> start = 0, bool hold = false,
+    ::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> time_easing = 0,
+    ::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> value_easing = 0)
+{
+    BezierDataFrameBuilder builder_(_fbb);
+    builder_.add_value_easing(value_easing);
+    builder_.add_time_easing(time_easing);
+    builder_.add_start(start);
+    builder_.add_time(time);
+    builder_.add_hold(hold);
+    return builder_.Finish();
+}
+
+inline ::flatbuffers::Offset<BezierDataFrame> CreateBezierDataFrameDirect(
+    ::flatbuffers::FlatBufferBuilder &_fbb, float time = 0.0f,
+    ::flatbuffers::Offset<LottieFlatBuffer::BezierData> start = 0, bool hold = false,
+    const std::vector<LottieFlatBuffer::Point> *time_easing = nullptr,
+    const std::vector<LottieFlatBuffer::Point> *value_easing = nullptr)
+{
+    auto time_easing__ = time_easing ? _fbb.CreateVectorOfStructs<LottieFlatBuffer::Point>(*time_easing) : 0;
+    auto value_easing__ = value_easing ? _fbb.CreateVectorOfStructs<LottieFlatBuffer::Point>(*value_easing) : 0;
+    return LottieFlatBuffer::CreateBezierDataFrame(_fbb, time, start, hold, time_easing__, value_easing__);
+}
+
+struct BezierDataFrameArray FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef BezierDataFrameArrayBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_FRAMES = 4 };
+    const ::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::BezierDataFrame>> *frames() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::BezierDataFrame>> *>(
+            VT_FRAMES);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyOffsetRequired(verifier, VT_FRAMES) &&
+               verifier.VerifyVector(frames()) && verifier.VerifyVectorOfTables(frames()) && verifier.EndTable();
+    }
+};
+
+struct BezierDataFrameArrayBuilder {
+    typedef BezierDataFrameArray Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_frames(
+        ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::BezierDataFrame>>> frames)
+    {
+        fbb_.AddOffset(BezierDataFrameArray::VT_FRAMES, frames);
+    }
+    explicit BezierDataFrameArrayBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<BezierDataFrameArray> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<BezierDataFrameArray>(end);
+        fbb_.Required(o, BezierDataFrameArray::VT_FRAMES);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<BezierDataFrameArray> CreateBezierDataFrameArray(
+    ::flatbuffers::FlatBufferBuilder &_fbb,
+    ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::BezierDataFrame>>> frames = 0)
+{
+    BezierDataFrameArrayBuilder builder_(_fbb);
+    builder_.add_frames(frames);
+    return builder_.Finish();
+}
+
+inline ::flatbuffers::Offset<BezierDataFrameArray> CreateBezierDataFrameArrayDirect(
+    ::flatbuffers::FlatBufferBuilder &_fbb,
+    const std::vector<::flatbuffers::Offset<LottieFlatBuffer::BezierDataFrame>> *frames = nullptr)
+{
+    auto frames__ = frames ? _fbb.CreateVector<::flatbuffers::Offset<LottieFlatBuffer::BezierDataFrame>>(*frames) : 0;
+    return LottieFlatBuffer::CreateBezierDataFrameArray(_fbb, frames__);
+}
+
+struct PositionFrame FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef PositionFrameBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+        VT_TIME = 4,
+        VT_START = 6,
+        VT_HOLD = 8,
+        VT_TIME_EASING = 10,
+        VT_VALUE_EASING = 12,
+        VT_IN_TAN = 14,
+        VT_OUT_TAN = 16
+    };
+    uint16_t time() const
+    {
+        return GetField<uint16_t>(VT_TIME, 0);
+    }
+    const LottieFlatBuffer::Point *start() const
+    {
+        return GetStruct<const LottieFlatBuffer::Point *>(VT_START);
+    }
+    bool hold() const
+    {
+        return GetField<uint8_t>(VT_HOLD, 0) != 0;
+    }
+    const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *time_easing() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *>(VT_TIME_EASING);
+    }
+    const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *value_easing() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *>(VT_VALUE_EASING);
+    }
+    const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *in_tan() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *>(VT_IN_TAN);
+    }
+    const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *out_tan() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *>(VT_OUT_TAN);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyField<uint16_t>(verifier, VT_TIME, 2) &&
+               VerifyField<LottieFlatBuffer::Point>(verifier, VT_START, 4) &&
+               VerifyField<uint8_t>(verifier, VT_HOLD, 1) && VerifyOffset(verifier, VT_TIME_EASING) &&
+               verifier.VerifyVector(time_easing()) && VerifyOffset(verifier, VT_VALUE_EASING) &&
+               verifier.VerifyVector(value_easing()) && VerifyOffset(verifier, VT_IN_TAN) &&
+               verifier.VerifyVector(in_tan()) && VerifyOffset(verifier, VT_OUT_TAN) &&
+               verifier.VerifyVector(out_tan()) && verifier.EndTable();
+    }
+};
+
+struct PositionFrameBuilder {
+    typedef PositionFrame Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_time(uint16_t time)
+    {
+        fbb_.AddElement<uint16_t>(PositionFrame::VT_TIME, time, 0);
+    }
+    void add_start(const LottieFlatBuffer::Point *start)
+    {
+        fbb_.AddStruct(PositionFrame::VT_START, start);
+    }
+    void add_hold(bool hold)
+    {
+        fbb_.AddElement<uint8_t>(PositionFrame::VT_HOLD, static_cast<uint8_t>(hold), 0);
+    }
+    void add_time_easing(::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> time_easing)
+    {
+        fbb_.AddOffset(PositionFrame::VT_TIME_EASING, time_easing);
+    }
+    void add_value_easing(::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> value_easing)
+    {
+        fbb_.AddOffset(PositionFrame::VT_VALUE_EASING, value_easing);
+    }
+    void add_in_tan(::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> in_tan)
+    {
+        fbb_.AddOffset(PositionFrame::VT_IN_TAN, in_tan);
+    }
+    void add_out_tan(::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> out_tan)
+    {
+        fbb_.AddOffset(PositionFrame::VT_OUT_TAN, out_tan);
+    }
+    explicit PositionFrameBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<PositionFrame> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<PositionFrame>(end);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<PositionFrame> CreatePositionFrame(
+    ::flatbuffers::FlatBufferBuilder &_fbb, uint16_t time = 0, const LottieFlatBuffer::Point *start = nullptr,
+    bool hold = false, ::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> time_easing = 0,
+    ::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> value_easing = 0,
+    ::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> in_tan = 0,
+    ::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> out_tan = 0)
+{
+    PositionFrameBuilder builder_(_fbb);
+    builder_.add_out_tan(out_tan);
+    builder_.add_in_tan(in_tan);
+    builder_.add_value_easing(value_easing);
+    builder_.add_time_easing(time_easing);
+    builder_.add_start(start);
+    builder_.add_time(time);
+    builder_.add_hold(hold);
+    return builder_.Finish();
+}
+
+inline ::flatbuffers::Offset<PositionFrame> CreatePositionFrameDirect(
+    ::flatbuffers::FlatBufferBuilder &_fbb, uint16_t time = 0, const LottieFlatBuffer::Point *start = nullptr,
+    bool hold = false, const std::vector<LottieFlatBuffer::Point> *time_easing = nullptr,
+    const std::vector<LottieFlatBuffer::Point> *value_easing = nullptr,
+    const std::vector<LottieFlatBuffer::Point> *in_tan = nullptr,
+    const std::vector<LottieFlatBuffer::Point> *out_tan = nullptr)
+{
+    auto time_easing__ = time_easing ? _fbb.CreateVectorOfStructs<LottieFlatBuffer::Point>(*time_easing) : 0;
+    auto value_easing__ = value_easing ? _fbb.CreateVectorOfStructs<LottieFlatBuffer::Point>(*value_easing) : 0;
+    auto in_tan__ = in_tan ? _fbb.CreateVectorOfStructs<LottieFlatBuffer::Point>(*in_tan) : 0;
+    auto out_tan__ = out_tan ? _fbb.CreateVectorOfStructs<LottieFlatBuffer::Point>(*out_tan) : 0;
+    return LottieFlatBuffer::CreatePositionFrame(_fbb, time, start, hold, time_easing__, value_easing__, in_tan__,
+                                                 out_tan__);
+}
+
+struct PositionFrameArray FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef PositionFrameArrayBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_FRAMES = 4 };
+    const ::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::PositionFrame>> *frames() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::PositionFrame>> *>(
+            VT_FRAMES);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyOffsetRequired(verifier, VT_FRAMES) &&
+               verifier.VerifyVector(frames()) && verifier.VerifyVectorOfTables(frames()) && verifier.EndTable();
+    }
+};
+
+struct PositionFrameArrayBuilder {
+    typedef PositionFrameArray Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_frames(
+        ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::PositionFrame>>> frames)
+    {
+        fbb_.AddOffset(PositionFrameArray::VT_FRAMES, frames);
+    }
+    explicit PositionFrameArrayBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<PositionFrameArray> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<PositionFrameArray>(end);
+        fbb_.Required(o, PositionFrameArray::VT_FRAMES);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<PositionFrameArray> CreatePositionFrameArray(
+    ::flatbuffers::FlatBufferBuilder &_fbb,
+    ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::PositionFrame>>> frames = 0)
+{
+    PositionFrameArrayBuilder builder_(_fbb);
+    builder_.add_frames(frames);
+    return builder_.Finish();
+}
+
+inline ::flatbuffers::Offset<PositionFrameArray> CreatePositionFrameArrayDirect(
+    ::flatbuffers::FlatBufferBuilder &_fbb,
+    const std::vector<::flatbuffers::Offset<LottieFlatBuffer::PositionFrame>> *frames = nullptr)
+{
+    auto frames__ = frames ? _fbb.CreateVector<::flatbuffers::Offset<LottieFlatBuffer::PositionFrame>>(*frames) : 0;
+    return LottieFlatBuffer::CreatePositionFrameArray(_fbb, frames__);
+}
+
+struct SplitProp FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef SplitPropBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+        VT_X_TYPE = 4,
+        VT_X = 6,
+        VT_Y_TYPE = 8,
+        VT_Y = 10
+    };
+    LottieFlatBuffer::FloatProp x_type() const
+    {
+        return static_cast<LottieFlatBuffer::FloatProp>(GetField<uint8_t>(VT_X_TYPE, 0));
+    }
+    const void *x() const
+    {
+        return GetPointer<const void *>(VT_X);
+    }
+    template <typename T>
+    const T *x_as() const;
+    const LottieFlatBuffer::FloatFrameArray *x_as_frames() const
+    {
+        return x_type() == LottieFlatBuffer::FloatProp_frames ?
+                   static_cast<const LottieFlatBuffer::FloatFrameArray *>(x()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::FloatScalar *x_as_value() const
+    {
+        return x_type() == LottieFlatBuffer::FloatProp_value ? static_cast<const LottieFlatBuffer::FloatScalar *>(x()) :
+                                                               nullptr;
+    }
+    LottieFlatBuffer::FloatProp y_type() const
+    {
+        return static_cast<LottieFlatBuffer::FloatProp>(GetField<uint8_t>(VT_Y_TYPE, 0));
+    }
+    const void *y() const
+    {
+        return GetPointer<const void *>(VT_Y);
+    }
+    template <typename T>
+    const T *y_as() const;
+    const LottieFlatBuffer::FloatFrameArray *y_as_frames() const
+    {
+        return y_type() == LottieFlatBuffer::FloatProp_frames ?
+                   static_cast<const LottieFlatBuffer::FloatFrameArray *>(y()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::FloatScalar *y_as_value() const
+    {
+        return y_type() == LottieFlatBuffer::FloatProp_value ? static_cast<const LottieFlatBuffer::FloatScalar *>(y()) :
+                                                               nullptr;
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyField<uint8_t>(verifier, VT_X_TYPE, 1) &&
+               VerifyOffsetRequired(verifier, VT_X) && VerifyFloatProp(verifier, x(), x_type()) &&
+               VerifyField<uint8_t>(verifier, VT_Y_TYPE, 1) && VerifyOffsetRequired(verifier, VT_Y) &&
+               VerifyFloatProp(verifier, y(), y_type()) && verifier.EndTable();
+    }
+};
+
+template <>
+inline const LottieFlatBuffer::FloatFrameArray *SplitProp::x_as<LottieFlatBuffer::FloatFrameArray>() const
+{
+    return x_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::FloatScalar *SplitProp::x_as<LottieFlatBuffer::FloatScalar>() const
+{
+    return x_as_value();
+}
+
+template <>
+inline const LottieFlatBuffer::FloatFrameArray *SplitProp::y_as<LottieFlatBuffer::FloatFrameArray>() const
+{
+    return y_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::FloatScalar *SplitProp::y_as<LottieFlatBuffer::FloatScalar>() const
+{
+    return y_as_value();
+}
+
+struct SplitPropBuilder {
+    typedef SplitProp Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_x_type(LottieFlatBuffer::FloatProp x_type)
+    {
+        fbb_.AddElement<uint8_t>(SplitProp::VT_X_TYPE, static_cast<uint8_t>(x_type), 0);
+    }
+    void add_x(::flatbuffers::Offset<void> x)
+    {
+        fbb_.AddOffset(SplitProp::VT_X, x);
+    }
+    void add_y_type(LottieFlatBuffer::FloatProp y_type)
+    {
+        fbb_.AddElement<uint8_t>(SplitProp::VT_Y_TYPE, static_cast<uint8_t>(y_type), 0);
+    }
+    void add_y(::flatbuffers::Offset<void> y)
+    {
+        fbb_.AddOffset(SplitProp::VT_Y, y);
+    }
+    explicit SplitPropBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<SplitProp> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<SplitProp>(end);
+        fbb_.Required(o, SplitProp::VT_X);
+        fbb_.Required(o, SplitProp::VT_Y);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<SplitProp> CreateSplitProp(
+    ::flatbuffers::FlatBufferBuilder &_fbb, LottieFlatBuffer::FloatProp x_type = LottieFlatBuffer::FloatProp_NONE,
+    ::flatbuffers::Offset<void> x = 0, LottieFlatBuffer::FloatProp y_type = LottieFlatBuffer::FloatProp_NONE,
+    ::flatbuffers::Offset<void> y = 0)
+{
+    SplitPropBuilder builder_(_fbb);
+    builder_.add_y(y);
+    builder_.add_x(x);
+    builder_.add_y_type(y_type);
+    builder_.add_x_type(x_type);
+    return builder_.Finish();
+}
+
+struct Transform FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef TransformBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+        VT_ANCHOR_TYPE = 4,
+        VT_ANCHOR = 6,
+        VT_POSITION_TYPE = 8,
+        VT_POSITION = 10,
+        VT_SPLIT_POSITION = 12,
+        VT_SCALE_TYPE = 14,
+        VT_SCALE = 16,
+        VT_ROTATION_TYPE = 18,
+        VT_ROTATION = 20,
+        VT_OPACITY_TYPE = 22,
+        VT_OPACITY = 24,
+        VT_SKEW_ANGLE_TYPE = 26,
+        VT_SKEW_ANGLE = 28,
+        VT_SKEW_AXIS_TYPE = 30,
+        VT_SKEW_AXIS = 32
+    };
+    LottieFlatBuffer::VectorProp anchor_type() const
+    {
+        return static_cast<LottieFlatBuffer::VectorProp>(GetField<uint8_t>(VT_ANCHOR_TYPE, 0));
+    }
+    const void *anchor() const
+    {
+        return GetPointer<const void *>(VT_ANCHOR);
+    }
+    template <typename T>
+    const T *anchor_as() const;
+    const LottieFlatBuffer::VectorFrameArray *anchor_as_frames() const
+    {
+        return anchor_type() == LottieFlatBuffer::VectorProp_frames ?
+                   static_cast<const LottieFlatBuffer::VectorFrameArray *>(anchor()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::Point *anchor_as_value() const
+    {
+        return anchor_type() == LottieFlatBuffer::VectorProp_value ?
+                   static_cast<const LottieFlatBuffer::Point *>(anchor()) :
+                   nullptr;
+    }
+    LottieFlatBuffer::PositionProp position_type() const
+    {
+        return static_cast<LottieFlatBuffer::PositionProp>(GetField<uint8_t>(VT_POSITION_TYPE, 0));
+    }
+    const void *position() const
+    {
+        return GetPointer<const void *>(VT_POSITION);
+    }
+    template <typename T>
+    const T *position_as() const;
+    const LottieFlatBuffer::PositionFrameArray *position_as_frames() const
+    {
+        return position_type() == LottieFlatBuffer::PositionProp_frames ?
+                   static_cast<const LottieFlatBuffer::PositionFrameArray *>(position()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::Point *position_as_value() const
+    {
+        return position_type() == LottieFlatBuffer::PositionProp_value ?
+                   static_cast<const LottieFlatBuffer::Point *>(position()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::SplitProp *split_position() const
+    {
+        return GetPointer<const LottieFlatBuffer::SplitProp *>(VT_SPLIT_POSITION);
+    }
+    LottieFlatBuffer::VectorProp scale_type() const
+    {
+        return static_cast<LottieFlatBuffer::VectorProp>(GetField<uint8_t>(VT_SCALE_TYPE, 0));
+    }
+    const void *scale() const
+    {
+        return GetPointer<const void *>(VT_SCALE);
+    }
+    template <typename T>
+    const T *scale_as() const;
+    const LottieFlatBuffer::VectorFrameArray *scale_as_frames() const
+    {
+        return scale_type() == LottieFlatBuffer::VectorProp_frames ?
+                   static_cast<const LottieFlatBuffer::VectorFrameArray *>(scale()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::Point *scale_as_value() const
+    {
+        return scale_type() == LottieFlatBuffer::VectorProp_value ?
+                   static_cast<const LottieFlatBuffer::Point *>(scale()) :
+                   nullptr;
+    }
+    LottieFlatBuffer::FloatProp rotation_type() const
+    {
+        return static_cast<LottieFlatBuffer::FloatProp>(GetField<uint8_t>(VT_ROTATION_TYPE, 0));
+    }
+    const void *rotation() const
+    {
+        return GetPointer<const void *>(VT_ROTATION);
+    }
+    template <typename T>
+    const T *rotation_as() const;
+    const LottieFlatBuffer::FloatFrameArray *rotation_as_frames() const
+    {
+        return rotation_type() == LottieFlatBuffer::FloatProp_frames ?
+                   static_cast<const LottieFlatBuffer::FloatFrameArray *>(rotation()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::FloatScalar *rotation_as_value() const
+    {
+        return rotation_type() == LottieFlatBuffer::FloatProp_value ?
+                   static_cast<const LottieFlatBuffer::FloatScalar *>(rotation()) :
+                   nullptr;
+    }
+    LottieFlatBuffer::IntegerProp opacity_type() const
+    {
+        return static_cast<LottieFlatBuffer::IntegerProp>(GetField<uint8_t>(VT_OPACITY_TYPE, 0));
+    }
+    const void *opacity() const
+    {
+        return GetPointer<const void *>(VT_OPACITY);
+    }
+    template <typename T>
+    const T *opacity_as() const;
+    const LottieFlatBuffer::IntegerFrameArray *opacity_as_frames() const
+    {
+        return opacity_type() == LottieFlatBuffer::IntegerProp_frames ?
+                   static_cast<const LottieFlatBuffer::IntegerFrameArray *>(opacity()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::IntegerScalar *opacity_as_value() const
+    {
+        return opacity_type() == LottieFlatBuffer::IntegerProp_value ?
+                   static_cast<const LottieFlatBuffer::IntegerScalar *>(opacity()) :
+                   nullptr;
+    }
+    LottieFlatBuffer::FloatProp skew_angle_type() const
+    {
+        return static_cast<LottieFlatBuffer::FloatProp>(GetField<uint8_t>(VT_SKEW_ANGLE_TYPE, 0));
+    }
+    const void *skew_angle() const
+    {
+        return GetPointer<const void *>(VT_SKEW_ANGLE);
+    }
+    template <typename T>
+    const T *skew_angle_as() const;
+    const LottieFlatBuffer::FloatFrameArray *skew_angle_as_frames() const
+    {
+        return skew_angle_type() == LottieFlatBuffer::FloatProp_frames ?
+                   static_cast<const LottieFlatBuffer::FloatFrameArray *>(skew_angle()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::FloatScalar *skew_angle_as_value() const
+    {
+        return skew_angle_type() == LottieFlatBuffer::FloatProp_value ?
+                   static_cast<const LottieFlatBuffer::FloatScalar *>(skew_angle()) :
+                   nullptr;
+    }
+    LottieFlatBuffer::FloatProp skew_axis_type() const
+    {
+        return static_cast<LottieFlatBuffer::FloatProp>(GetField<uint8_t>(VT_SKEW_AXIS_TYPE, 0));
+    }
+    const void *skew_axis() const
+    {
+        return GetPointer<const void *>(VT_SKEW_AXIS);
+    }
+    template <typename T>
+    const T *skew_axis_as() const;
+    const LottieFlatBuffer::FloatFrameArray *skew_axis_as_frames() const
+    {
+        return skew_axis_type() == LottieFlatBuffer::FloatProp_frames ?
+                   static_cast<const LottieFlatBuffer::FloatFrameArray *>(skew_axis()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::FloatScalar *skew_axis_as_value() const
+    {
+        return skew_axis_type() == LottieFlatBuffer::FloatProp_value ?
+                   static_cast<const LottieFlatBuffer::FloatScalar *>(skew_axis()) :
+                   nullptr;
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyField<uint8_t>(verifier, VT_ANCHOR_TYPE, 1) &&
+               VerifyOffset(verifier, VT_ANCHOR) && VerifyVectorProp(verifier, anchor(), anchor_type()) &&
+               VerifyField<uint8_t>(verifier, VT_POSITION_TYPE, 1) && VerifyOffset(verifier, VT_POSITION) &&
+               VerifyPositionProp(verifier, position(), position_type()) && VerifyOffset(verifier, VT_SPLIT_POSITION) &&
+               verifier.VerifyTable(split_position()) && VerifyField<uint8_t>(verifier, VT_SCALE_TYPE, 1) &&
+               VerifyOffset(verifier, VT_SCALE) && VerifyVectorProp(verifier, scale(), scale_type()) &&
+               VerifyField<uint8_t>(verifier, VT_ROTATION_TYPE, 1) && VerifyOffset(verifier, VT_ROTATION) &&
+               VerifyFloatProp(verifier, rotation(), rotation_type()) &&
+               VerifyField<uint8_t>(verifier, VT_OPACITY_TYPE, 1) && VerifyOffset(verifier, VT_OPACITY) &&
+               VerifyIntegerProp(verifier, opacity(), opacity_type()) &&
+               VerifyField<uint8_t>(verifier, VT_SKEW_ANGLE_TYPE, 1) && VerifyOffset(verifier, VT_SKEW_ANGLE) &&
+               VerifyFloatProp(verifier, skew_angle(), skew_angle_type()) &&
+               VerifyField<uint8_t>(verifier, VT_SKEW_AXIS_TYPE, 1) && VerifyOffset(verifier, VT_SKEW_AXIS) &&
+               VerifyFloatProp(verifier, skew_axis(), skew_axis_type()) && verifier.EndTable();
+    }
+};
+
+template <>
+inline const LottieFlatBuffer::VectorFrameArray *Transform::anchor_as<LottieFlatBuffer::VectorFrameArray>() const
+{
+    return anchor_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::Point *Transform::anchor_as<LottieFlatBuffer::Point>() const
+{
+    return anchor_as_value();
+}
+
+template <>
+inline const LottieFlatBuffer::PositionFrameArray *Transform::position_as<LottieFlatBuffer::PositionFrameArray>() const
+{
+    return position_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::Point *Transform::position_as<LottieFlatBuffer::Point>() const
+{
+    return position_as_value();
+}
+
+template <>
+inline const LottieFlatBuffer::VectorFrameArray *Transform::scale_as<LottieFlatBuffer::VectorFrameArray>() const
+{
+    return scale_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::Point *Transform::scale_as<LottieFlatBuffer::Point>() const
+{
+    return scale_as_value();
+}
+
+template <>
+inline const LottieFlatBuffer::FloatFrameArray *Transform::rotation_as<LottieFlatBuffer::FloatFrameArray>() const
+{
+    return rotation_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::FloatScalar *Transform::rotation_as<LottieFlatBuffer::FloatScalar>() const
+{
+    return rotation_as_value();
+}
+
+template <>
+inline const LottieFlatBuffer::IntegerFrameArray *Transform::opacity_as<LottieFlatBuffer::IntegerFrameArray>() const
+{
+    return opacity_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::IntegerScalar *Transform::opacity_as<LottieFlatBuffer::IntegerScalar>() const
+{
+    return opacity_as_value();
+}
+
+template <>
+inline const LottieFlatBuffer::FloatFrameArray *Transform::skew_angle_as<LottieFlatBuffer::FloatFrameArray>() const
+{
+    return skew_angle_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::FloatScalar *Transform::skew_angle_as<LottieFlatBuffer::FloatScalar>() const
+{
+    return skew_angle_as_value();
+}
+
+template <>
+inline const LottieFlatBuffer::FloatFrameArray *Transform::skew_axis_as<LottieFlatBuffer::FloatFrameArray>() const
+{
+    return skew_axis_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::FloatScalar *Transform::skew_axis_as<LottieFlatBuffer::FloatScalar>() const
+{
+    return skew_axis_as_value();
+}
+
+struct TransformBuilder {
+    typedef Transform Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_anchor_type(LottieFlatBuffer::VectorProp anchor_type)
+    {
+        fbb_.AddElement<uint8_t>(Transform::VT_ANCHOR_TYPE, static_cast<uint8_t>(anchor_type), 0);
+    }
+    void add_anchor(::flatbuffers::Offset<void> anchor)
+    {
+        fbb_.AddOffset(Transform::VT_ANCHOR, anchor);
+    }
+    void add_position_type(LottieFlatBuffer::PositionProp position_type)
+    {
+        fbb_.AddElement<uint8_t>(Transform::VT_POSITION_TYPE, static_cast<uint8_t>(position_type), 0);
+    }
+    void add_position(::flatbuffers::Offset<void> position)
+    {
+        fbb_.AddOffset(Transform::VT_POSITION, position);
+    }
+    void add_split_position(::flatbuffers::Offset<LottieFlatBuffer::SplitProp> split_position)
+    {
+        fbb_.AddOffset(Transform::VT_SPLIT_POSITION, split_position);
+    }
+    void add_scale_type(LottieFlatBuffer::VectorProp scale_type)
+    {
+        fbb_.AddElement<uint8_t>(Transform::VT_SCALE_TYPE, static_cast<uint8_t>(scale_type), 0);
+    }
+    void add_scale(::flatbuffers::Offset<void> scale)
+    {
+        fbb_.AddOffset(Transform::VT_SCALE, scale);
+    }
+    void add_rotation_type(LottieFlatBuffer::FloatProp rotation_type)
+    {
+        fbb_.AddElement<uint8_t>(Transform::VT_ROTATION_TYPE, static_cast<uint8_t>(rotation_type), 0);
+    }
+    void add_rotation(::flatbuffers::Offset<void> rotation)
+    {
+        fbb_.AddOffset(Transform::VT_ROTATION, rotation);
+    }
+    void add_opacity_type(LottieFlatBuffer::IntegerProp opacity_type)
+    {
+        fbb_.AddElement<uint8_t>(Transform::VT_OPACITY_TYPE, static_cast<uint8_t>(opacity_type), 0);
+    }
+    void add_opacity(::flatbuffers::Offset<void> opacity)
+    {
+        fbb_.AddOffset(Transform::VT_OPACITY, opacity);
+    }
+    void add_skew_angle_type(LottieFlatBuffer::FloatProp skew_angle_type)
+    {
+        fbb_.AddElement<uint8_t>(Transform::VT_SKEW_ANGLE_TYPE, static_cast<uint8_t>(skew_angle_type), 0);
+    }
+    void add_skew_angle(::flatbuffers::Offset<void> skew_angle)
+    {
+        fbb_.AddOffset(Transform::VT_SKEW_ANGLE, skew_angle);
+    }
+    void add_skew_axis_type(LottieFlatBuffer::FloatProp skew_axis_type)
+    {
+        fbb_.AddElement<uint8_t>(Transform::VT_SKEW_AXIS_TYPE, static_cast<uint8_t>(skew_axis_type), 0);
+    }
+    void add_skew_axis(::flatbuffers::Offset<void> skew_axis)
+    {
+        fbb_.AddOffset(Transform::VT_SKEW_AXIS, skew_axis);
+    }
+    explicit TransformBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<Transform> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<Transform>(end);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<Transform> CreateTransform(
+    ::flatbuffers::FlatBufferBuilder &_fbb,
+    LottieFlatBuffer::VectorProp anchor_type = LottieFlatBuffer::VectorProp_NONE,
+    ::flatbuffers::Offset<void> anchor = 0,
+    LottieFlatBuffer::PositionProp position_type = LottieFlatBuffer::PositionProp_NONE,
+    ::flatbuffers::Offset<void> position = 0, ::flatbuffers::Offset<LottieFlatBuffer::SplitProp> split_position = 0,
+    LottieFlatBuffer::VectorProp scale_type = LottieFlatBuffer::VectorProp_NONE, ::flatbuffers::Offset<void> scale = 0,
+    LottieFlatBuffer::FloatProp rotation_type = LottieFlatBuffer::FloatProp_NONE,
+    ::flatbuffers::Offset<void> rotation = 0,
+    LottieFlatBuffer::IntegerProp opacity_type = LottieFlatBuffer::IntegerProp_NONE,
+    ::flatbuffers::Offset<void> opacity = 0,
+    LottieFlatBuffer::FloatProp skew_angle_type = LottieFlatBuffer::FloatProp_NONE,
+    ::flatbuffers::Offset<void> skew_angle = 0,
+    LottieFlatBuffer::FloatProp skew_axis_type = LottieFlatBuffer::FloatProp_NONE,
+    ::flatbuffers::Offset<void> skew_axis = 0)
+{
+    TransformBuilder builder_(_fbb);
+    builder_.add_skew_axis(skew_axis);
+    builder_.add_skew_angle(skew_angle);
+    builder_.add_opacity(opacity);
+    builder_.add_rotation(rotation);
+    builder_.add_scale(scale);
+    builder_.add_split_position(split_position);
+    builder_.add_position(position);
+    builder_.add_anchor(anchor);
+    builder_.add_skew_axis_type(skew_axis_type);
+    builder_.add_skew_angle_type(skew_angle_type);
+    builder_.add_opacity_type(opacity_type);
+    builder_.add_rotation_type(rotation_type);
+    builder_.add_scale_type(scale_type);
+    builder_.add_position_type(position_type);
+    builder_.add_anchor_type(anchor_type);
+    return builder_.Finish();
+}
+
+struct EllipseShape FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef EllipseShapeBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+        VT_CLOCKWISE = 4,
+        VT_POS_TYPE = 6,
+        VT_POS = 8,
+        VT_SIZE_TYPE = 10,
+        VT_SIZE = 12
+    };
+    bool clockwise() const
+    {
+        return GetField<uint8_t>(VT_CLOCKWISE, 1) != 0;
+    }
+    LottieFlatBuffer::PositionProp pos_type() const
+    {
+        return static_cast<LottieFlatBuffer::PositionProp>(GetField<uint8_t>(VT_POS_TYPE, 0));
+    }
+    const void *pos() const
+    {
+        return GetPointer<const void *>(VT_POS);
+    }
+    template <typename T>
+    const T *pos_as() const;
+    const LottieFlatBuffer::PositionFrameArray *pos_as_frames() const
+    {
+        return pos_type() == LottieFlatBuffer::PositionProp_frames ?
+                   static_cast<const LottieFlatBuffer::PositionFrameArray *>(pos()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::Point *pos_as_value() const
+    {
+        return pos_type() == LottieFlatBuffer::PositionProp_value ?
+                   static_cast<const LottieFlatBuffer::Point *>(pos()) :
+                   nullptr;
+    }
+    LottieFlatBuffer::VectorProp size_type() const
+    {
+        return static_cast<LottieFlatBuffer::VectorProp>(GetField<uint8_t>(VT_SIZE_TYPE, 0));
+    }
+    const void *size() const
+    {
+        return GetPointer<const void *>(VT_SIZE);
+    }
+    template <typename T>
+    const T *size_as() const;
+    const LottieFlatBuffer::VectorFrameArray *size_as_frames() const
+    {
+        return size_type() == LottieFlatBuffer::VectorProp_frames ?
+                   static_cast<const LottieFlatBuffer::VectorFrameArray *>(size()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::Point *size_as_value() const
+    {
+        return size_type() == LottieFlatBuffer::VectorProp_value ?
+                   static_cast<const LottieFlatBuffer::Point *>(size()) :
+                   nullptr;
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyField<uint8_t>(verifier, VT_CLOCKWISE, 1) &&
+               VerifyField<uint8_t>(verifier, VT_POS_TYPE, 1) && VerifyOffsetRequired(verifier, VT_POS) &&
+               VerifyPositionProp(verifier, pos(), pos_type()) && VerifyField<uint8_t>(verifier, VT_SIZE_TYPE, 1) &&
+               VerifyOffsetRequired(verifier, VT_SIZE) && VerifyVectorProp(verifier, size(), size_type()) &&
+               verifier.EndTable();
+    }
+};
+
+template <>
+inline const LottieFlatBuffer::PositionFrameArray *EllipseShape::pos_as<LottieFlatBuffer::PositionFrameArray>() const
+{
+    return pos_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::Point *EllipseShape::pos_as<LottieFlatBuffer::Point>() const
+{
+    return pos_as_value();
+}
+
+template <>
+inline const LottieFlatBuffer::VectorFrameArray *EllipseShape::size_as<LottieFlatBuffer::VectorFrameArray>() const
+{
+    return size_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::Point *EllipseShape::size_as<LottieFlatBuffer::Point>() const
+{
+    return size_as_value();
+}
+
+struct EllipseShapeBuilder {
+    typedef EllipseShape Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_clockwise(bool clockwise)
+    {
+        fbb_.AddElement<uint8_t>(EllipseShape::VT_CLOCKWISE, static_cast<uint8_t>(clockwise), 1);
+    }
+    void add_pos_type(LottieFlatBuffer::PositionProp pos_type)
+    {
+        fbb_.AddElement<uint8_t>(EllipseShape::VT_POS_TYPE, static_cast<uint8_t>(pos_type), 0);
+    }
+    void add_pos(::flatbuffers::Offset<void> pos)
+    {
+        fbb_.AddOffset(EllipseShape::VT_POS, pos);
+    }
+    void add_size_type(LottieFlatBuffer::VectorProp size_type)
+    {
+        fbb_.AddElement<uint8_t>(EllipseShape::VT_SIZE_TYPE, static_cast<uint8_t>(size_type), 0);
+    }
+    void add_size(::flatbuffers::Offset<void> size)
+    {
+        fbb_.AddOffset(EllipseShape::VT_SIZE, size);
+    }
+    explicit EllipseShapeBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<EllipseShape> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<EllipseShape>(end);
+        fbb_.Required(o, EllipseShape::VT_POS);
+        fbb_.Required(o, EllipseShape::VT_SIZE);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<EllipseShape> CreateEllipseShape(
+    ::flatbuffers::FlatBufferBuilder &_fbb, bool clockwise = true,
+    LottieFlatBuffer::PositionProp pos_type = LottieFlatBuffer::PositionProp_NONE, ::flatbuffers::Offset<void> pos = 0,
+    LottieFlatBuffer::VectorProp size_type = LottieFlatBuffer::VectorProp_NONE, ::flatbuffers::Offset<void> size = 0)
+{
+    EllipseShapeBuilder builder_(_fbb);
+    builder_.add_size(size);
+    builder_.add_pos(pos);
+    builder_.add_size_type(size_type);
+    builder_.add_pos_type(pos_type);
+    builder_.add_clockwise(clockwise);
+    return builder_.Finish();
+}
+
+struct RectShape FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef RectShapeBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+        VT_CLOCKWISE = 4,
+        VT_POS_TYPE = 6,
+        VT_POS = 8,
+        VT_SIZE_TYPE = 10,
+        VT_SIZE = 12,
+        VT_RADIUS_TYPE = 14,
+        VT_RADIUS = 16
+    };
+    bool clockwise() const
+    {
+        return GetField<uint8_t>(VT_CLOCKWISE, 1) != 0;
+    }
+    LottieFlatBuffer::PositionProp pos_type() const
+    {
+        return static_cast<LottieFlatBuffer::PositionProp>(GetField<uint8_t>(VT_POS_TYPE, 0));
+    }
+    const void *pos() const
+    {
+        return GetPointer<const void *>(VT_POS);
+    }
+    template <typename T>
+    const T *pos_as() const;
+    const LottieFlatBuffer::PositionFrameArray *pos_as_frames() const
+    {
+        return pos_type() == LottieFlatBuffer::PositionProp_frames ?
+                   static_cast<const LottieFlatBuffer::PositionFrameArray *>(pos()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::Point *pos_as_value() const
+    {
+        return pos_type() == LottieFlatBuffer::PositionProp_value ?
+                   static_cast<const LottieFlatBuffer::Point *>(pos()) :
+                   nullptr;
+    }
+    LottieFlatBuffer::VectorProp size_type() const
+    {
+        return static_cast<LottieFlatBuffer::VectorProp>(GetField<uint8_t>(VT_SIZE_TYPE, 0));
+    }
+    const void *size() const
+    {
+        return GetPointer<const void *>(VT_SIZE);
+    }
+    template <typename T>
+    const T *size_as() const;
+    const LottieFlatBuffer::VectorFrameArray *size_as_frames() const
+    {
+        return size_type() == LottieFlatBuffer::VectorProp_frames ?
+                   static_cast<const LottieFlatBuffer::VectorFrameArray *>(size()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::Point *size_as_value() const
+    {
+        return size_type() == LottieFlatBuffer::VectorProp_value ?
+                   static_cast<const LottieFlatBuffer::Point *>(size()) :
+                   nullptr;
+    }
+    LottieFlatBuffer::FloatProp radius_type() const
+    {
+        return static_cast<LottieFlatBuffer::FloatProp>(GetField<uint8_t>(VT_RADIUS_TYPE, 0));
+    }
+    const void *radius() const
+    {
+        return GetPointer<const void *>(VT_RADIUS);
+    }
+    template <typename T>
+    const T *radius_as() const;
+    const LottieFlatBuffer::FloatFrameArray *radius_as_frames() const
+    {
+        return radius_type() == LottieFlatBuffer::FloatProp_frames ?
+                   static_cast<const LottieFlatBuffer::FloatFrameArray *>(radius()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::FloatScalar *radius_as_value() const
+    {
+        return radius_type() == LottieFlatBuffer::FloatProp_value ?
+                   static_cast<const LottieFlatBuffer::FloatScalar *>(radius()) :
+                   nullptr;
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyField<uint8_t>(verifier, VT_CLOCKWISE, 1) &&
+               VerifyField<uint8_t>(verifier, VT_POS_TYPE, 1) && VerifyOffsetRequired(verifier, VT_POS) &&
+               VerifyPositionProp(verifier, pos(), pos_type()) && VerifyField<uint8_t>(verifier, VT_SIZE_TYPE, 1) &&
+               VerifyOffsetRequired(verifier, VT_SIZE) && VerifyVectorProp(verifier, size(), size_type()) &&
+               VerifyField<uint8_t>(verifier, VT_RADIUS_TYPE, 1) && VerifyOffsetRequired(verifier, VT_RADIUS) &&
+               VerifyFloatProp(verifier, radius(), radius_type()) && verifier.EndTable();
+    }
+};
+
+template <>
+inline const LottieFlatBuffer::PositionFrameArray *RectShape::pos_as<LottieFlatBuffer::PositionFrameArray>() const
+{
+    return pos_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::Point *RectShape::pos_as<LottieFlatBuffer::Point>() const
+{
+    return pos_as_value();
+}
+
+template <>
+inline const LottieFlatBuffer::VectorFrameArray *RectShape::size_as<LottieFlatBuffer::VectorFrameArray>() const
+{
+    return size_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::Point *RectShape::size_as<LottieFlatBuffer::Point>() const
+{
+    return size_as_value();
+}
+
+template <>
+inline const LottieFlatBuffer::FloatFrameArray *RectShape::radius_as<LottieFlatBuffer::FloatFrameArray>() const
+{
+    return radius_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::FloatScalar *RectShape::radius_as<LottieFlatBuffer::FloatScalar>() const
+{
+    return radius_as_value();
+}
+
+struct RectShapeBuilder {
+    typedef RectShape Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_clockwise(bool clockwise)
+    {
+        fbb_.AddElement<uint8_t>(RectShape::VT_CLOCKWISE, static_cast<uint8_t>(clockwise), 1);
+    }
+    void add_pos_type(LottieFlatBuffer::PositionProp pos_type)
+    {
+        fbb_.AddElement<uint8_t>(RectShape::VT_POS_TYPE, static_cast<uint8_t>(pos_type), 0);
+    }
+    void add_pos(::flatbuffers::Offset<void> pos)
+    {
+        fbb_.AddOffset(RectShape::VT_POS, pos);
+    }
+    void add_size_type(LottieFlatBuffer::VectorProp size_type)
+    {
+        fbb_.AddElement<uint8_t>(RectShape::VT_SIZE_TYPE, static_cast<uint8_t>(size_type), 0);
+    }
+    void add_size(::flatbuffers::Offset<void> size)
+    {
+        fbb_.AddOffset(RectShape::VT_SIZE, size);
+    }
+    void add_radius_type(LottieFlatBuffer::FloatProp radius_type)
+    {
+        fbb_.AddElement<uint8_t>(RectShape::VT_RADIUS_TYPE, static_cast<uint8_t>(radius_type), 0);
+    }
+    void add_radius(::flatbuffers::Offset<void> radius)
+    {
+        fbb_.AddOffset(RectShape::VT_RADIUS, radius);
+    }
+    explicit RectShapeBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<RectShape> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<RectShape>(end);
+        fbb_.Required(o, RectShape::VT_POS);
+        fbb_.Required(o, RectShape::VT_SIZE);
+        fbb_.Required(o, RectShape::VT_RADIUS);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<RectShape> CreateRectShape(
+    ::flatbuffers::FlatBufferBuilder &_fbb, bool clockwise = true,
+    LottieFlatBuffer::PositionProp pos_type = LottieFlatBuffer::PositionProp_NONE, ::flatbuffers::Offset<void> pos = 0,
+    LottieFlatBuffer::VectorProp size_type = LottieFlatBuffer::VectorProp_NONE, ::flatbuffers::Offset<void> size = 0,
+    LottieFlatBuffer::FloatProp radius_type = LottieFlatBuffer::FloatProp_NONE, ::flatbuffers::Offset<void> radius = 0)
+{
+    RectShapeBuilder builder_(_fbb);
+    builder_.add_radius(radius);
+    builder_.add_size(size);
+    builder_.add_pos(pos);
+    builder_.add_radius_type(radius_type);
+    builder_.add_size_type(size_type);
+    builder_.add_pos_type(pos_type);
+    builder_.add_clockwise(clockwise);
+    return builder_.Finish();
+}
+
+struct PathShape FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef PathShapeBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+        VT_CLOCKWISE = 4,
+        VT_BEZIER_TYPE = 6,
+        VT_BEZIER = 8
+    };
+    bool clockwise() const
+    {
+        return GetField<uint8_t>(VT_CLOCKWISE, 1) != 0;
+    }
+    LottieFlatBuffer::BezierDataProp bezier_type() const
+    {
+        return static_cast<LottieFlatBuffer::BezierDataProp>(GetField<uint8_t>(VT_BEZIER_TYPE, 0));
+    }
+    const void *bezier() const
+    {
+        return GetPointer<const void *>(VT_BEZIER);
+    }
+    template <typename T>
+    const T *bezier_as() const;
+    const LottieFlatBuffer::BezierDataFrameArray *bezier_as_frames() const
+    {
+        return bezier_type() == LottieFlatBuffer::BezierDataProp_frames ?
+                   static_cast<const LottieFlatBuffer::BezierDataFrameArray *>(bezier()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::BezierData *bezier_as_value() const
+    {
+        return bezier_type() == LottieFlatBuffer::BezierDataProp_value ?
+                   static_cast<const LottieFlatBuffer::BezierData *>(bezier()) :
+                   nullptr;
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyField<uint8_t>(verifier, VT_CLOCKWISE, 1) &&
+               VerifyField<uint8_t>(verifier, VT_BEZIER_TYPE, 1) && VerifyOffsetRequired(verifier, VT_BEZIER) &&
+               VerifyBezierDataProp(verifier, bezier(), bezier_type()) && verifier.EndTable();
+    }
+};
+
+template <>
+inline const LottieFlatBuffer::BezierDataFrameArray *
+PathShape::bezier_as<LottieFlatBuffer::BezierDataFrameArray>() const
+{
+    return bezier_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::BezierData *PathShape::bezier_as<LottieFlatBuffer::BezierData>() const
+{
+    return bezier_as_value();
+}
+
+struct PathShapeBuilder {
+    typedef PathShape Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_clockwise(bool clockwise)
+    {
+        fbb_.AddElement<uint8_t>(PathShape::VT_CLOCKWISE, static_cast<uint8_t>(clockwise), 1);
+    }
+    void add_bezier_type(LottieFlatBuffer::BezierDataProp bezier_type)
+    {
+        fbb_.AddElement<uint8_t>(PathShape::VT_BEZIER_TYPE, static_cast<uint8_t>(bezier_type), 0);
+    }
+    void add_bezier(::flatbuffers::Offset<void> bezier)
+    {
+        fbb_.AddOffset(PathShape::VT_BEZIER, bezier);
+    }
+    explicit PathShapeBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<PathShape> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<PathShape>(end);
+        fbb_.Required(o, PathShape::VT_BEZIER);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<PathShape> CreatePathShape(
+    ::flatbuffers::FlatBufferBuilder &_fbb, bool clockwise = true,
+    LottieFlatBuffer::BezierDataProp bezier_type = LottieFlatBuffer::BezierDataProp_NONE,
+    ::flatbuffers::Offset<void> bezier = 0)
+{
+    PathShapeBuilder builder_(_fbb);
+    builder_.add_bezier(bezier);
+    builder_.add_bezier_type(bezier_type);
+    builder_.add_clockwise(clockwise);
+    return builder_.Finish();
+}
+
+struct FillStyle FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef FillStyleBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+        VT_OPACITY_TYPE = 4,
+        VT_OPACITY = 6,
+        VT_COLOR_TYPE = 8,
+        VT_COLOR = 10,
+        VT_RULE = 12
+    };
+    LottieFlatBuffer::IntegerProp opacity_type() const
+    {
+        return static_cast<LottieFlatBuffer::IntegerProp>(GetField<uint8_t>(VT_OPACITY_TYPE, 0));
+    }
+    const void *opacity() const
+    {
+        return GetPointer<const void *>(VT_OPACITY);
+    }
+    template <typename T>
+    const T *opacity_as() const;
+    const LottieFlatBuffer::IntegerFrameArray *opacity_as_frames() const
+    {
+        return opacity_type() == LottieFlatBuffer::IntegerProp_frames ?
+                   static_cast<const LottieFlatBuffer::IntegerFrameArray *>(opacity()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::IntegerScalar *opacity_as_value() const
+    {
+        return opacity_type() == LottieFlatBuffer::IntegerProp_value ?
+                   static_cast<const LottieFlatBuffer::IntegerScalar *>(opacity()) :
+                   nullptr;
+    }
+    LottieFlatBuffer::ColorProp color_type() const
+    {
+        return static_cast<LottieFlatBuffer::ColorProp>(GetField<uint8_t>(VT_COLOR_TYPE, 0));
+    }
+    const void *color() const
+    {
+        return GetPointer<const void *>(VT_COLOR);
+    }
+    template <typename T>
+    const T *color_as() const;
+    const LottieFlatBuffer::ColorFrameArray *color_as_frames() const
+    {
+        return color_type() == LottieFlatBuffer::ColorProp_frames ?
+                   static_cast<const LottieFlatBuffer::ColorFrameArray *>(color()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::Color24Scalar *color_as_color() const
+    {
+        return color_type() == LottieFlatBuffer::ColorProp_color ?
+                   static_cast<const LottieFlatBuffer::Color24Scalar *>(color()) :
+                   nullptr;
+    }
+    LottieFlatBuffer::FillRule rule() const
+    {
+        return static_cast<LottieFlatBuffer::FillRule>(GetField<int8_t>(VT_RULE, 0));
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyField<uint8_t>(verifier, VT_OPACITY_TYPE, 1) &&
+               VerifyOffsetRequired(verifier, VT_OPACITY) && VerifyIntegerProp(verifier, opacity(), opacity_type()) &&
+               VerifyField<uint8_t>(verifier, VT_COLOR_TYPE, 1) && VerifyOffsetRequired(verifier, VT_COLOR) &&
+               VerifyColorProp(verifier, color(), color_type()) && VerifyField<int8_t>(verifier, VT_RULE, 1) &&
+               verifier.EndTable();
+    }
+};
+
+template <>
+inline const LottieFlatBuffer::IntegerFrameArray *FillStyle::opacity_as<LottieFlatBuffer::IntegerFrameArray>() const
+{
+    return opacity_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::IntegerScalar *FillStyle::opacity_as<LottieFlatBuffer::IntegerScalar>() const
+{
+    return opacity_as_value();
+}
+
+template <>
+inline const LottieFlatBuffer::ColorFrameArray *FillStyle::color_as<LottieFlatBuffer::ColorFrameArray>() const
+{
+    return color_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::Color24Scalar *FillStyle::color_as<LottieFlatBuffer::Color24Scalar>() const
+{
+    return color_as_color();
+}
+
+struct FillStyleBuilder {
+    typedef FillStyle Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_opacity_type(LottieFlatBuffer::IntegerProp opacity_type)
+    {
+        fbb_.AddElement<uint8_t>(FillStyle::VT_OPACITY_TYPE, static_cast<uint8_t>(opacity_type), 0);
+    }
+    void add_opacity(::flatbuffers::Offset<void> opacity)
+    {
+        fbb_.AddOffset(FillStyle::VT_OPACITY, opacity);
+    }
+    void add_color_type(LottieFlatBuffer::ColorProp color_type)
+    {
+        fbb_.AddElement<uint8_t>(FillStyle::VT_COLOR_TYPE, static_cast<uint8_t>(color_type), 0);
+    }
+    void add_color(::flatbuffers::Offset<void> color)
+    {
+        fbb_.AddOffset(FillStyle::VT_COLOR, color);
+    }
+    void add_rule(LottieFlatBuffer::FillRule rule)
+    {
+        fbb_.AddElement<int8_t>(FillStyle::VT_RULE, static_cast<int8_t>(rule), 0);
+    }
+    explicit FillStyleBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<FillStyle> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<FillStyle>(end);
+        fbb_.Required(o, FillStyle::VT_OPACITY);
+        fbb_.Required(o, FillStyle::VT_COLOR);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<FillStyle> CreateFillStyle(
+    ::flatbuffers::FlatBufferBuilder &_fbb,
+    LottieFlatBuffer::IntegerProp opacity_type = LottieFlatBuffer::IntegerProp_NONE,
+    ::flatbuffers::Offset<void> opacity = 0, LottieFlatBuffer::ColorProp color_type = LottieFlatBuffer::ColorProp_NONE,
+    ::flatbuffers::Offset<void> color = 0, LottieFlatBuffer::FillRule rule = LottieFlatBuffer::FillRule_NON_ZERO)
+{
+    FillStyleBuilder builder_(_fbb);
+    builder_.add_color(color);
+    builder_.add_opacity(opacity);
+    builder_.add_rule(rule);
+    builder_.add_color_type(color_type);
+    builder_.add_opacity_type(opacity_type);
+    return builder_.Finish();
+}
+
+struct StrokeStyle FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef StrokeStyleBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+        VT_OPACITY_TYPE = 4,
+        VT_OPACITY = 6,
+        VT_COLOR_TYPE = 8,
+        VT_COLOR = 10,
+        VT_WIDTH_TYPE = 12,
+        VT_WIDTH = 14,
+        VT_CAP = 16,
+        VT_JOIN = 18,
+        VT_MITER_LIMIT = 20
+    };
+    LottieFlatBuffer::IntegerProp opacity_type() const
+    {
+        return static_cast<LottieFlatBuffer::IntegerProp>(GetField<uint8_t>(VT_OPACITY_TYPE, 0));
+    }
+    const void *opacity() const
+    {
+        return GetPointer<const void *>(VT_OPACITY);
+    }
+    template <typename T>
+    const T *opacity_as() const;
+    const LottieFlatBuffer::IntegerFrameArray *opacity_as_frames() const
+    {
+        return opacity_type() == LottieFlatBuffer::IntegerProp_frames ?
+                   static_cast<const LottieFlatBuffer::IntegerFrameArray *>(opacity()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::IntegerScalar *opacity_as_value() const
+    {
+        return opacity_type() == LottieFlatBuffer::IntegerProp_value ?
+                   static_cast<const LottieFlatBuffer::IntegerScalar *>(opacity()) :
+                   nullptr;
+    }
+    LottieFlatBuffer::ColorProp color_type() const
+    {
+        return static_cast<LottieFlatBuffer::ColorProp>(GetField<uint8_t>(VT_COLOR_TYPE, 0));
+    }
+    const void *color() const
+    {
+        return GetPointer<const void *>(VT_COLOR);
+    }
+    template <typename T>
+    const T *color_as() const;
+    const LottieFlatBuffer::ColorFrameArray *color_as_frames() const
+    {
+        return color_type() == LottieFlatBuffer::ColorProp_frames ?
+                   static_cast<const LottieFlatBuffer::ColorFrameArray *>(color()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::Color24Scalar *color_as_color() const
+    {
+        return color_type() == LottieFlatBuffer::ColorProp_color ?
+                   static_cast<const LottieFlatBuffer::Color24Scalar *>(color()) :
+                   nullptr;
+    }
+    LottieFlatBuffer::FloatProp width_type() const
+    {
+        return static_cast<LottieFlatBuffer::FloatProp>(GetField<uint8_t>(VT_WIDTH_TYPE, 0));
+    }
+    const void *width() const
+    {
+        return GetPointer<const void *>(VT_WIDTH);
+    }
+    template <typename T>
+    const T *width_as() const;
+    const LottieFlatBuffer::FloatFrameArray *width_as_frames() const
+    {
+        return width_type() == LottieFlatBuffer::FloatProp_frames ?
+                   static_cast<const LottieFlatBuffer::FloatFrameArray *>(width()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::FloatScalar *width_as_value() const
+    {
+        return width_type() == LottieFlatBuffer::FloatProp_value ?
+                   static_cast<const LottieFlatBuffer::FloatScalar *>(width()) :
+                   nullptr;
+    }
+    LottieFlatBuffer::LineCap cap() const
+    {
+        return static_cast<LottieFlatBuffer::LineCap>(GetField<int8_t>(VT_CAP, 1));
+    }
+    LottieFlatBuffer::LineJoin join() const
+    {
+        return static_cast<LottieFlatBuffer::LineJoin>(GetField<int8_t>(VT_JOIN, 1));
+    }
+    float miter_limit() const
+    {
+        return GetField<float>(VT_MITER_LIMIT, 0.0f);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyField<uint8_t>(verifier, VT_OPACITY_TYPE, 1) &&
+               VerifyOffsetRequired(verifier, VT_OPACITY) && VerifyIntegerProp(verifier, opacity(), opacity_type()) &&
+               VerifyField<uint8_t>(verifier, VT_COLOR_TYPE, 1) && VerifyOffsetRequired(verifier, VT_COLOR) &&
+               VerifyColorProp(verifier, color(), color_type()) && VerifyField<uint8_t>(verifier, VT_WIDTH_TYPE, 1) &&
+               VerifyOffsetRequired(verifier, VT_WIDTH) && VerifyFloatProp(verifier, width(), width_type()) &&
+               VerifyField<int8_t>(verifier, VT_CAP, 1) && VerifyField<int8_t>(verifier, VT_JOIN, 1) &&
+               VerifyField<float>(verifier, VT_MITER_LIMIT, 4) && verifier.EndTable();
+    }
+};
+
+template <>
+inline const LottieFlatBuffer::IntegerFrameArray *StrokeStyle::opacity_as<LottieFlatBuffer::IntegerFrameArray>() const
+{
+    return opacity_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::IntegerScalar *StrokeStyle::opacity_as<LottieFlatBuffer::IntegerScalar>() const
+{
+    return opacity_as_value();
+}
+
+template <>
+inline const LottieFlatBuffer::ColorFrameArray *StrokeStyle::color_as<LottieFlatBuffer::ColorFrameArray>() const
+{
+    return color_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::Color24Scalar *StrokeStyle::color_as<LottieFlatBuffer::Color24Scalar>() const
+{
+    return color_as_color();
+}
+
+template <>
+inline const LottieFlatBuffer::FloatFrameArray *StrokeStyle::width_as<LottieFlatBuffer::FloatFrameArray>() const
+{
+    return width_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::FloatScalar *StrokeStyle::width_as<LottieFlatBuffer::FloatScalar>() const
+{
+    return width_as_value();
+}
+
+struct StrokeStyleBuilder {
+    typedef StrokeStyle Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_opacity_type(LottieFlatBuffer::IntegerProp opacity_type)
+    {
+        fbb_.AddElement<uint8_t>(StrokeStyle::VT_OPACITY_TYPE, static_cast<uint8_t>(opacity_type), 0);
+    }
+    void add_opacity(::flatbuffers::Offset<void> opacity)
+    {
+        fbb_.AddOffset(StrokeStyle::VT_OPACITY, opacity);
+    }
+    void add_color_type(LottieFlatBuffer::ColorProp color_type)
+    {
+        fbb_.AddElement<uint8_t>(StrokeStyle::VT_COLOR_TYPE, static_cast<uint8_t>(color_type), 0);
+    }
+    void add_color(::flatbuffers::Offset<void> color)
+    {
+        fbb_.AddOffset(StrokeStyle::VT_COLOR, color);
+    }
+    void add_width_type(LottieFlatBuffer::FloatProp width_type)
+    {
+        fbb_.AddElement<uint8_t>(StrokeStyle::VT_WIDTH_TYPE, static_cast<uint8_t>(width_type), 0);
+    }
+    void add_width(::flatbuffers::Offset<void> width)
+    {
+        fbb_.AddOffset(StrokeStyle::VT_WIDTH, width);
+    }
+    void add_cap(LottieFlatBuffer::LineCap cap)
+    {
+        fbb_.AddElement<int8_t>(StrokeStyle::VT_CAP, static_cast<int8_t>(cap), 1);
+    }
+    void add_join(LottieFlatBuffer::LineJoin join)
+    {
+        fbb_.AddElement<int8_t>(StrokeStyle::VT_JOIN, static_cast<int8_t>(join), 1);
+    }
+    void add_miter_limit(float miter_limit)
+    {
+        fbb_.AddElement<float>(StrokeStyle::VT_MITER_LIMIT, miter_limit, 0.0f);
+    }
+    explicit StrokeStyleBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<StrokeStyle> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<StrokeStyle>(end);
+        fbb_.Required(o, StrokeStyle::VT_OPACITY);
+        fbb_.Required(o, StrokeStyle::VT_COLOR);
+        fbb_.Required(o, StrokeStyle::VT_WIDTH);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<StrokeStyle> CreateStrokeStyle(
+    ::flatbuffers::FlatBufferBuilder &_fbb,
+    LottieFlatBuffer::IntegerProp opacity_type = LottieFlatBuffer::IntegerProp_NONE,
+    ::flatbuffers::Offset<void> opacity = 0, LottieFlatBuffer::ColorProp color_type = LottieFlatBuffer::ColorProp_NONE,
+    ::flatbuffers::Offset<void> color = 0, LottieFlatBuffer::FloatProp width_type = LottieFlatBuffer::FloatProp_NONE,
+    ::flatbuffers::Offset<void> width = 0, LottieFlatBuffer::LineCap cap = LottieFlatBuffer::LineCap_CAP_ROUND,
+    LottieFlatBuffer::LineJoin join = LottieFlatBuffer::LineJoin_JOIN_ROUND, float miter_limit = 0.0f)
+{
+    StrokeStyleBuilder builder_(_fbb);
+    builder_.add_miter_limit(miter_limit);
+    builder_.add_width(width);
+    builder_.add_color(color);
+    builder_.add_opacity(opacity);
+    builder_.add_join(join);
+    builder_.add_cap(cap);
+    builder_.add_width_type(width_type);
+    builder_.add_color_type(color_type);
+    builder_.add_opacity_type(opacity_type);
+    return builder_.Finish();
+}
+
+struct GradientFillStyle FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef GradientFillStyleBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+        VT_OPACITY_TYPE = 4,
+        VT_OPACITY = 6,
+        VT_START_POS_TYPE = 8,
+        VT_START_POS = 10,
+        VT_END_POS_TYPE = 12,
+        VT_END_POS = 14,
+        VT_GRADIENT_TYPE = 16,
+        VT_GRADIENT = 18,
+        VT_TYPE = 20,
+        VT_RULE = 22
+    };
+    LottieFlatBuffer::IntegerProp opacity_type() const
+    {
+        return static_cast<LottieFlatBuffer::IntegerProp>(GetField<uint8_t>(VT_OPACITY_TYPE, 0));
+    }
+    const void *opacity() const
+    {
+        return GetPointer<const void *>(VT_OPACITY);
+    }
+    template <typename T>
+    const T *opacity_as() const;
+    const LottieFlatBuffer::IntegerFrameArray *opacity_as_frames() const
+    {
+        return opacity_type() == LottieFlatBuffer::IntegerProp_frames ?
+                   static_cast<const LottieFlatBuffer::IntegerFrameArray *>(opacity()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::IntegerScalar *opacity_as_value() const
+    {
+        return opacity_type() == LottieFlatBuffer::IntegerProp_value ?
+                   static_cast<const LottieFlatBuffer::IntegerScalar *>(opacity()) :
+                   nullptr;
+    }
+    LottieFlatBuffer::VectorProp start_pos_type() const
+    {
+        return static_cast<LottieFlatBuffer::VectorProp>(GetField<uint8_t>(VT_START_POS_TYPE, 0));
+    }
+    const void *start_pos() const
+    {
+        return GetPointer<const void *>(VT_START_POS);
+    }
+    template <typename T>
+    const T *start_pos_as() const;
+    const LottieFlatBuffer::VectorFrameArray *start_pos_as_frames() const
+    {
+        return start_pos_type() == LottieFlatBuffer::VectorProp_frames ?
+                   static_cast<const LottieFlatBuffer::VectorFrameArray *>(start_pos()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::Point *start_pos_as_value() const
+    {
+        return start_pos_type() == LottieFlatBuffer::VectorProp_value ?
+                   static_cast<const LottieFlatBuffer::Point *>(start_pos()) :
+                   nullptr;
+    }
+    LottieFlatBuffer::VectorProp end_pos_type() const
+    {
+        return static_cast<LottieFlatBuffer::VectorProp>(GetField<uint8_t>(VT_END_POS_TYPE, 0));
+    }
+    const void *end_pos() const
+    {
+        return GetPointer<const void *>(VT_END_POS);
+    }
+    template <typename T>
+    const T *end_pos_as() const;
+    const LottieFlatBuffer::VectorFrameArray *end_pos_as_frames() const
+    {
+        return end_pos_type() == LottieFlatBuffer::VectorProp_frames ?
+                   static_cast<const LottieFlatBuffer::VectorFrameArray *>(end_pos()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::Point *end_pos_as_value() const
+    {
+        return end_pos_type() == LottieFlatBuffer::VectorProp_value ?
+                   static_cast<const LottieFlatBuffer::Point *>(end_pos()) :
+                   nullptr;
+    }
+    LottieFlatBuffer::GradientProp gradient_type() const
+    {
+        return static_cast<LottieFlatBuffer::GradientProp>(GetField<uint8_t>(VT_GRADIENT_TYPE, 0));
+    }
+    const void *gradient() const
+    {
+        return GetPointer<const void *>(VT_GRADIENT);
+    }
+    template <typename T>
+    const T *gradient_as() const;
+    const LottieFlatBuffer::GradientFrameArray *gradient_as_frames() const
+    {
+        return gradient_type() == LottieFlatBuffer::GradientProp_frames ?
+                   static_cast<const LottieFlatBuffer::GradientFrameArray *>(gradient()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::Gradient *gradient_as_value() const
+    {
+        return gradient_type() == LottieFlatBuffer::GradientProp_value ?
+                   static_cast<const LottieFlatBuffer::Gradient *>(gradient()) :
+                   nullptr;
+    }
+    LottieFlatBuffer::GradientType type() const
+    {
+        return static_cast<LottieFlatBuffer::GradientType>(GetField<int8_t>(VT_TYPE, 0));
+    }
+    LottieFlatBuffer::FillRule rule() const
+    {
+        return static_cast<LottieFlatBuffer::FillRule>(GetField<int8_t>(VT_RULE, 0));
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyField<uint8_t>(verifier, VT_OPACITY_TYPE, 1) &&
+               VerifyOffsetRequired(verifier, VT_OPACITY) && VerifyIntegerProp(verifier, opacity(), opacity_type()) &&
+               VerifyField<uint8_t>(verifier, VT_START_POS_TYPE, 1) && VerifyOffsetRequired(verifier, VT_START_POS) &&
+               VerifyVectorProp(verifier, start_pos(), start_pos_type()) &&
+               VerifyField<uint8_t>(verifier, VT_END_POS_TYPE, 1) && VerifyOffsetRequired(verifier, VT_END_POS) &&
+               VerifyVectorProp(verifier, end_pos(), end_pos_type()) &&
+               VerifyField<uint8_t>(verifier, VT_GRADIENT_TYPE, 1) && VerifyOffsetRequired(verifier, VT_GRADIENT) &&
+               VerifyGradientProp(verifier, gradient(), gradient_type()) && VerifyField<int8_t>(verifier, VT_TYPE, 1) &&
+               VerifyField<int8_t>(verifier, VT_RULE, 1) && verifier.EndTable();
+    }
+};
+
+template <>
+inline const LottieFlatBuffer::IntegerFrameArray *
+GradientFillStyle::opacity_as<LottieFlatBuffer::IntegerFrameArray>() const
+{
+    return opacity_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::IntegerScalar *GradientFillStyle::opacity_as<LottieFlatBuffer::IntegerScalar>() const
+{
+    return opacity_as_value();
+}
+
+template <>
+inline const LottieFlatBuffer::VectorFrameArray *
+GradientFillStyle::start_pos_as<LottieFlatBuffer::VectorFrameArray>() const
+{
+    return start_pos_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::Point *GradientFillStyle::start_pos_as<LottieFlatBuffer::Point>() const
+{
+    return start_pos_as_value();
+}
+
+template <>
+inline const LottieFlatBuffer::VectorFrameArray *
+GradientFillStyle::end_pos_as<LottieFlatBuffer::VectorFrameArray>() const
+{
+    return end_pos_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::Point *GradientFillStyle::end_pos_as<LottieFlatBuffer::Point>() const
+{
+    return end_pos_as_value();
+}
+
+template <>
+inline const LottieFlatBuffer::GradientFrameArray *
+GradientFillStyle::gradient_as<LottieFlatBuffer::GradientFrameArray>() const
+{
+    return gradient_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::Gradient *GradientFillStyle::gradient_as<LottieFlatBuffer::Gradient>() const
+{
+    return gradient_as_value();
+}
+
+struct GradientFillStyleBuilder {
+    typedef GradientFillStyle Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_opacity_type(LottieFlatBuffer::IntegerProp opacity_type)
+    {
+        fbb_.AddElement<uint8_t>(GradientFillStyle::VT_OPACITY_TYPE, static_cast<uint8_t>(opacity_type), 0);
+    }
+    void add_opacity(::flatbuffers::Offset<void> opacity)
+    {
+        fbb_.AddOffset(GradientFillStyle::VT_OPACITY, opacity);
+    }
+    void add_start_pos_type(LottieFlatBuffer::VectorProp start_pos_type)
+    {
+        fbb_.AddElement<uint8_t>(GradientFillStyle::VT_START_POS_TYPE, static_cast<uint8_t>(start_pos_type), 0);
+    }
+    void add_start_pos(::flatbuffers::Offset<void> start_pos)
+    {
+        fbb_.AddOffset(GradientFillStyle::VT_START_POS, start_pos);
+    }
+    void add_end_pos_type(LottieFlatBuffer::VectorProp end_pos_type)
+    {
+        fbb_.AddElement<uint8_t>(GradientFillStyle::VT_END_POS_TYPE, static_cast<uint8_t>(end_pos_type), 0);
+    }
+    void add_end_pos(::flatbuffers::Offset<void> end_pos)
+    {
+        fbb_.AddOffset(GradientFillStyle::VT_END_POS, end_pos);
+    }
+    void add_gradient_type(LottieFlatBuffer::GradientProp gradient_type)
+    {
+        fbb_.AddElement<uint8_t>(GradientFillStyle::VT_GRADIENT_TYPE, static_cast<uint8_t>(gradient_type), 0);
+    }
+    void add_gradient(::flatbuffers::Offset<void> gradient)
+    {
+        fbb_.AddOffset(GradientFillStyle::VT_GRADIENT, gradient);
+    }
+    void add_type(LottieFlatBuffer::GradientType type)
+    {
+        fbb_.AddElement<int8_t>(GradientFillStyle::VT_TYPE, static_cast<int8_t>(type), 0);
+    }
+    void add_rule(LottieFlatBuffer::FillRule rule)
+    {
+        fbb_.AddElement<int8_t>(GradientFillStyle::VT_RULE, static_cast<int8_t>(rule), 0);
+    }
+    explicit GradientFillStyleBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<GradientFillStyle> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<GradientFillStyle>(end);
+        fbb_.Required(o, GradientFillStyle::VT_OPACITY);
+        fbb_.Required(o, GradientFillStyle::VT_START_POS);
+        fbb_.Required(o, GradientFillStyle::VT_END_POS);
+        fbb_.Required(o, GradientFillStyle::VT_GRADIENT);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<GradientFillStyle> CreateGradientFillStyle(
+    ::flatbuffers::FlatBufferBuilder &_fbb,
+    LottieFlatBuffer::IntegerProp opacity_type = LottieFlatBuffer::IntegerProp_NONE,
+    ::flatbuffers::Offset<void> opacity = 0,
+    LottieFlatBuffer::VectorProp start_pos_type = LottieFlatBuffer::VectorProp_NONE,
+    ::flatbuffers::Offset<void> start_pos = 0,
+    LottieFlatBuffer::VectorProp end_pos_type = LottieFlatBuffer::VectorProp_NONE,
+    ::flatbuffers::Offset<void> end_pos = 0,
+    LottieFlatBuffer::GradientProp gradient_type = LottieFlatBuffer::GradientProp_NONE,
+    ::flatbuffers::Offset<void> gradient = 0,
+    LottieFlatBuffer::GradientType type = LottieFlatBuffer::GradientType_GRADIENT_LINEAR,
+    LottieFlatBuffer::FillRule rule = LottieFlatBuffer::FillRule_NON_ZERO)
+{
+    GradientFillStyleBuilder builder_(_fbb);
+    builder_.add_gradient(gradient);
+    builder_.add_end_pos(end_pos);
+    builder_.add_start_pos(start_pos);
+    builder_.add_opacity(opacity);
+    builder_.add_rule(rule);
+    builder_.add_type(type);
+    builder_.add_gradient_type(gradient_type);
+    builder_.add_end_pos_type(end_pos_type);
+    builder_.add_start_pos_type(start_pos_type);
+    builder_.add_opacity_type(opacity_type);
+    return builder_.Finish();
+}
+
+struct GradientStrokeStyle FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef GradientStrokeStyleBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+        VT_WIDTH_TYPE = 4,
+        VT_WIDTH = 6,
+        VT_OPACITY_TYPE = 8,
+        VT_OPACITY = 10,
+        VT_START_POS_TYPE = 12,
+        VT_START_POS = 14,
+        VT_END_POS_TYPE = 16,
+        VT_END_POS = 18,
+        VT_GRADIENT_TYPE = 20,
+        VT_GRADIENT = 22,
+        VT_TYPE = 24,
+        VT_CAP = 26,
+        VT_JOIN = 28,
+        VT_MITER_LIMIT = 30
+    };
+    LottieFlatBuffer::FloatProp width_type() const
+    {
+        return static_cast<LottieFlatBuffer::FloatProp>(GetField<uint8_t>(VT_WIDTH_TYPE, 0));
+    }
+    const void *width() const
+    {
+        return GetPointer<const void *>(VT_WIDTH);
+    }
+    template <typename T>
+    const T *width_as() const;
+    const LottieFlatBuffer::FloatFrameArray *width_as_frames() const
+    {
+        return width_type() == LottieFlatBuffer::FloatProp_frames ?
+                   static_cast<const LottieFlatBuffer::FloatFrameArray *>(width()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::FloatScalar *width_as_value() const
+    {
+        return width_type() == LottieFlatBuffer::FloatProp_value ?
+                   static_cast<const LottieFlatBuffer::FloatScalar *>(width()) :
+                   nullptr;
+    }
+    LottieFlatBuffer::IntegerProp opacity_type() const
+    {
+        return static_cast<LottieFlatBuffer::IntegerProp>(GetField<uint8_t>(VT_OPACITY_TYPE, 0));
+    }
+    const void *opacity() const
+    {
+        return GetPointer<const void *>(VT_OPACITY);
+    }
+    template <typename T>
+    const T *opacity_as() const;
+    const LottieFlatBuffer::IntegerFrameArray *opacity_as_frames() const
+    {
+        return opacity_type() == LottieFlatBuffer::IntegerProp_frames ?
+                   static_cast<const LottieFlatBuffer::IntegerFrameArray *>(opacity()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::IntegerScalar *opacity_as_value() const
+    {
+        return opacity_type() == LottieFlatBuffer::IntegerProp_value ?
+                   static_cast<const LottieFlatBuffer::IntegerScalar *>(opacity()) :
+                   nullptr;
+    }
+    LottieFlatBuffer::VectorProp start_pos_type() const
+    {
+        return static_cast<LottieFlatBuffer::VectorProp>(GetField<uint8_t>(VT_START_POS_TYPE, 0));
+    }
+    const void *start_pos() const
+    {
+        return GetPointer<const void *>(VT_START_POS);
+    }
+    template <typename T>
+    const T *start_pos_as() const;
+    const LottieFlatBuffer::VectorFrameArray *start_pos_as_frames() const
+    {
+        return start_pos_type() == LottieFlatBuffer::VectorProp_frames ?
+                   static_cast<const LottieFlatBuffer::VectorFrameArray *>(start_pos()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::Point *start_pos_as_value() const
+    {
+        return start_pos_type() == LottieFlatBuffer::VectorProp_value ?
+                   static_cast<const LottieFlatBuffer::Point *>(start_pos()) :
+                   nullptr;
+    }
+    LottieFlatBuffer::VectorProp end_pos_type() const
+    {
+        return static_cast<LottieFlatBuffer::VectorProp>(GetField<uint8_t>(VT_END_POS_TYPE, 0));
+    }
+    const void *end_pos() const
+    {
+        return GetPointer<const void *>(VT_END_POS);
+    }
+    template <typename T>
+    const T *end_pos_as() const;
+    const LottieFlatBuffer::VectorFrameArray *end_pos_as_frames() const
+    {
+        return end_pos_type() == LottieFlatBuffer::VectorProp_frames ?
+                   static_cast<const LottieFlatBuffer::VectorFrameArray *>(end_pos()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::Point *end_pos_as_value() const
+    {
+        return end_pos_type() == LottieFlatBuffer::VectorProp_value ?
+                   static_cast<const LottieFlatBuffer::Point *>(end_pos()) :
+                   nullptr;
+    }
+    LottieFlatBuffer::GradientProp gradient_type() const
+    {
+        return static_cast<LottieFlatBuffer::GradientProp>(GetField<uint8_t>(VT_GRADIENT_TYPE, 0));
+    }
+    const void *gradient() const
+    {
+        return GetPointer<const void *>(VT_GRADIENT);
+    }
+    template <typename T>
+    const T *gradient_as() const;
+    const LottieFlatBuffer::GradientFrameArray *gradient_as_frames() const
+    {
+        return gradient_type() == LottieFlatBuffer::GradientProp_frames ?
+                   static_cast<const LottieFlatBuffer::GradientFrameArray *>(gradient()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::Gradient *gradient_as_value() const
+    {
+        return gradient_type() == LottieFlatBuffer::GradientProp_value ?
+                   static_cast<const LottieFlatBuffer::Gradient *>(gradient()) :
+                   nullptr;
+    }
+    LottieFlatBuffer::GradientType type() const
+    {
+        return static_cast<LottieFlatBuffer::GradientType>(GetField<int8_t>(VT_TYPE, 0));
+    }
+    LottieFlatBuffer::LineCap cap() const
+    {
+        return static_cast<LottieFlatBuffer::LineCap>(GetField<int8_t>(VT_CAP, 1));
+    }
+    LottieFlatBuffer::LineJoin join() const
+    {
+        return static_cast<LottieFlatBuffer::LineJoin>(GetField<int8_t>(VT_JOIN, 1));
+    }
+    float miter_limit() const
+    {
+        return GetField<float>(VT_MITER_LIMIT, 0.0f);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyField<uint8_t>(verifier, VT_WIDTH_TYPE, 1) &&
+               VerifyOffsetRequired(verifier, VT_WIDTH) && VerifyFloatProp(verifier, width(), width_type()) &&
+               VerifyField<uint8_t>(verifier, VT_OPACITY_TYPE, 1) && VerifyOffsetRequired(verifier, VT_OPACITY) &&
+               VerifyIntegerProp(verifier, opacity(), opacity_type()) &&
+               VerifyField<uint8_t>(verifier, VT_START_POS_TYPE, 1) && VerifyOffsetRequired(verifier, VT_START_POS) &&
+               VerifyVectorProp(verifier, start_pos(), start_pos_type()) &&
+               VerifyField<uint8_t>(verifier, VT_END_POS_TYPE, 1) && VerifyOffsetRequired(verifier, VT_END_POS) &&
+               VerifyVectorProp(verifier, end_pos(), end_pos_type()) &&
+               VerifyField<uint8_t>(verifier, VT_GRADIENT_TYPE, 1) && VerifyOffsetRequired(verifier, VT_GRADIENT) &&
+               VerifyGradientProp(verifier, gradient(), gradient_type()) && VerifyField<int8_t>(verifier, VT_TYPE, 1) &&
+               VerifyField<int8_t>(verifier, VT_CAP, 1) && VerifyField<int8_t>(verifier, VT_JOIN, 1) &&
+               VerifyField<float>(verifier, VT_MITER_LIMIT, 4) && verifier.EndTable();
+    }
+};
+
+template <>
+inline const LottieFlatBuffer::FloatFrameArray *GradientStrokeStyle::width_as<LottieFlatBuffer::FloatFrameArray>() const
+{
+    return width_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::FloatScalar *GradientStrokeStyle::width_as<LottieFlatBuffer::FloatScalar>() const
+{
+    return width_as_value();
+}
+
+template <>
+inline const LottieFlatBuffer::IntegerFrameArray *
+GradientStrokeStyle::opacity_as<LottieFlatBuffer::IntegerFrameArray>() const
+{
+    return opacity_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::IntegerScalar *GradientStrokeStyle::opacity_as<LottieFlatBuffer::IntegerScalar>() const
+{
+    return opacity_as_value();
+}
+
+template <>
+inline const LottieFlatBuffer::VectorFrameArray *
+GradientStrokeStyle::start_pos_as<LottieFlatBuffer::VectorFrameArray>() const
+{
+    return start_pos_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::Point *GradientStrokeStyle::start_pos_as<LottieFlatBuffer::Point>() const
+{
+    return start_pos_as_value();
+}
+
+template <>
+inline const LottieFlatBuffer::VectorFrameArray *
+GradientStrokeStyle::end_pos_as<LottieFlatBuffer::VectorFrameArray>() const
+{
+    return end_pos_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::Point *GradientStrokeStyle::end_pos_as<LottieFlatBuffer::Point>() const
+{
+    return end_pos_as_value();
+}
+
+template <>
+inline const LottieFlatBuffer::GradientFrameArray *
+GradientStrokeStyle::gradient_as<LottieFlatBuffer::GradientFrameArray>() const
+{
+    return gradient_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::Gradient *GradientStrokeStyle::gradient_as<LottieFlatBuffer::Gradient>() const
+{
+    return gradient_as_value();
+}
+
+struct GradientStrokeStyleBuilder {
+    typedef GradientStrokeStyle Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_width_type(LottieFlatBuffer::FloatProp width_type)
+    {
+        fbb_.AddElement<uint8_t>(GradientStrokeStyle::VT_WIDTH_TYPE, static_cast<uint8_t>(width_type), 0);
+    }
+    void add_width(::flatbuffers::Offset<void> width)
+    {
+        fbb_.AddOffset(GradientStrokeStyle::VT_WIDTH, width);
+    }
+    void add_opacity_type(LottieFlatBuffer::IntegerProp opacity_type)
+    {
+        fbb_.AddElement<uint8_t>(GradientStrokeStyle::VT_OPACITY_TYPE, static_cast<uint8_t>(opacity_type), 0);
+    }
+    void add_opacity(::flatbuffers::Offset<void> opacity)
+    {
+        fbb_.AddOffset(GradientStrokeStyle::VT_OPACITY, opacity);
+    }
+    void add_start_pos_type(LottieFlatBuffer::VectorProp start_pos_type)
+    {
+        fbb_.AddElement<uint8_t>(GradientStrokeStyle::VT_START_POS_TYPE, static_cast<uint8_t>(start_pos_type), 0);
+    }
+    void add_start_pos(::flatbuffers::Offset<void> start_pos)
+    {
+        fbb_.AddOffset(GradientStrokeStyle::VT_START_POS, start_pos);
+    }
+    void add_end_pos_type(LottieFlatBuffer::VectorProp end_pos_type)
+    {
+        fbb_.AddElement<uint8_t>(GradientStrokeStyle::VT_END_POS_TYPE, static_cast<uint8_t>(end_pos_type), 0);
+    }
+    void add_end_pos(::flatbuffers::Offset<void> end_pos)
+    {
+        fbb_.AddOffset(GradientStrokeStyle::VT_END_POS, end_pos);
+    }
+    void add_gradient_type(LottieFlatBuffer::GradientProp gradient_type)
+    {
+        fbb_.AddElement<uint8_t>(GradientStrokeStyle::VT_GRADIENT_TYPE, static_cast<uint8_t>(gradient_type), 0);
+    }
+    void add_gradient(::flatbuffers::Offset<void> gradient)
+    {
+        fbb_.AddOffset(GradientStrokeStyle::VT_GRADIENT, gradient);
+    }
+    void add_type(LottieFlatBuffer::GradientType type)
+    {
+        fbb_.AddElement<int8_t>(GradientStrokeStyle::VT_TYPE, static_cast<int8_t>(type), 0);
+    }
+    void add_cap(LottieFlatBuffer::LineCap cap)
+    {
+        fbb_.AddElement<int8_t>(GradientStrokeStyle::VT_CAP, static_cast<int8_t>(cap), 1);
+    }
+    void add_join(LottieFlatBuffer::LineJoin join)
+    {
+        fbb_.AddElement<int8_t>(GradientStrokeStyle::VT_JOIN, static_cast<int8_t>(join), 1);
+    }
+    void add_miter_limit(float miter_limit)
+    {
+        fbb_.AddElement<float>(GradientStrokeStyle::VT_MITER_LIMIT, miter_limit, 0.0f);
+    }
+    explicit GradientStrokeStyleBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<GradientStrokeStyle> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<GradientStrokeStyle>(end);
+        fbb_.Required(o, GradientStrokeStyle::VT_WIDTH);
+        fbb_.Required(o, GradientStrokeStyle::VT_OPACITY);
+        fbb_.Required(o, GradientStrokeStyle::VT_START_POS);
+        fbb_.Required(o, GradientStrokeStyle::VT_END_POS);
+        fbb_.Required(o, GradientStrokeStyle::VT_GRADIENT);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<GradientStrokeStyle> CreateGradientStrokeStyle(
+    ::flatbuffers::FlatBufferBuilder &_fbb, LottieFlatBuffer::FloatProp width_type = LottieFlatBuffer::FloatProp_NONE,
+    ::flatbuffers::Offset<void> width = 0,
+    LottieFlatBuffer::IntegerProp opacity_type = LottieFlatBuffer::IntegerProp_NONE,
+    ::flatbuffers::Offset<void> opacity = 0,
+    LottieFlatBuffer::VectorProp start_pos_type = LottieFlatBuffer::VectorProp_NONE,
+    ::flatbuffers::Offset<void> start_pos = 0,
+    LottieFlatBuffer::VectorProp end_pos_type = LottieFlatBuffer::VectorProp_NONE,
+    ::flatbuffers::Offset<void> end_pos = 0,
+    LottieFlatBuffer::GradientProp gradient_type = LottieFlatBuffer::GradientProp_NONE,
+    ::flatbuffers::Offset<void> gradient = 0,
+    LottieFlatBuffer::GradientType type = LottieFlatBuffer::GradientType_GRADIENT_LINEAR,
+    LottieFlatBuffer::LineCap cap = LottieFlatBuffer::LineCap_CAP_ROUND,
+    LottieFlatBuffer::LineJoin join = LottieFlatBuffer::LineJoin_JOIN_ROUND, float miter_limit = 0.0f)
+{
+    GradientStrokeStyleBuilder builder_(_fbb);
+    builder_.add_miter_limit(miter_limit);
+    builder_.add_gradient(gradient);
+    builder_.add_end_pos(end_pos);
+    builder_.add_start_pos(start_pos);
+    builder_.add_opacity(opacity);
+    builder_.add_width(width);
+    builder_.add_join(join);
+    builder_.add_cap(cap);
+    builder_.add_type(type);
+    builder_.add_gradient_type(gradient_type);
+    builder_.add_end_pos_type(end_pos_type);
+    builder_.add_start_pos_type(start_pos_type);
+    builder_.add_opacity_type(opacity_type);
+    builder_.add_width_type(width_type);
+    return builder_.Finish();
+}
+
+struct TrimPath FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef TrimPathBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+        VT_START_TYPE = 4,
+        VT_START = 6,
+        VT_END_TYPE = 8,
+        VT_END = 10,
+        VT_OFFSET_TYPE = 12,
+        VT_OFFSET = 14,
+        VT_TYPE = 16
+    };
+    LottieFlatBuffer::FloatProp start_type() const
+    {
+        return static_cast<LottieFlatBuffer::FloatProp>(GetField<uint8_t>(VT_START_TYPE, 0));
+    }
+    const void *start() const
+    {
+        return GetPointer<const void *>(VT_START);
+    }
+    template <typename T>
+    const T *start_as() const;
+    const LottieFlatBuffer::FloatFrameArray *start_as_frames() const
+    {
+        return start_type() == LottieFlatBuffer::FloatProp_frames ?
+                   static_cast<const LottieFlatBuffer::FloatFrameArray *>(start()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::FloatScalar *start_as_value() const
+    {
+        return start_type() == LottieFlatBuffer::FloatProp_value ?
+                   static_cast<const LottieFlatBuffer::FloatScalar *>(start()) :
+                   nullptr;
+    }
+    LottieFlatBuffer::FloatProp end_type() const
+    {
+        return static_cast<LottieFlatBuffer::FloatProp>(GetField<uint8_t>(VT_END_TYPE, 0));
+    }
+    const void *end() const
+    {
+        return GetPointer<const void *>(VT_END);
+    }
+    template <typename T>
+    const T *end_as() const;
+    const LottieFlatBuffer::FloatFrameArray *end_as_frames() const
+    {
+        return end_type() == LottieFlatBuffer::FloatProp_frames ?
+                   static_cast<const LottieFlatBuffer::FloatFrameArray *>(end()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::FloatScalar *end_as_value() const
+    {
+        return end_type() == LottieFlatBuffer::FloatProp_value ?
+                   static_cast<const LottieFlatBuffer::FloatScalar *>(end()) :
+                   nullptr;
+    }
+    LottieFlatBuffer::FloatProp offset_type() const
+    {
+        return static_cast<LottieFlatBuffer::FloatProp>(GetField<uint8_t>(VT_OFFSET_TYPE, 0));
+    }
+    const void *offset() const
+    {
+        return GetPointer<const void *>(VT_OFFSET);
+    }
+    template <typename T>
+    const T *offset_as() const;
+    const LottieFlatBuffer::FloatFrameArray *offset_as_frames() const
+    {
+        return offset_type() == LottieFlatBuffer::FloatProp_frames ?
+                   static_cast<const LottieFlatBuffer::FloatFrameArray *>(offset()) :
+                   nullptr;
+    }
+    const LottieFlatBuffer::FloatScalar *offset_as_value() const
+    {
+        return offset_type() == LottieFlatBuffer::FloatProp_value ?
+                   static_cast<const LottieFlatBuffer::FloatScalar *>(offset()) :
+                   nullptr;
+    }
+    LottieFlatBuffer::TrimType type() const
+    {
+        return static_cast<LottieFlatBuffer::TrimType>(GetField<int8_t>(VT_TYPE, 0));
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyField<uint8_t>(verifier, VT_START_TYPE, 1) &&
+               VerifyOffsetRequired(verifier, VT_START) && VerifyFloatProp(verifier, start(), start_type()) &&
+               VerifyField<uint8_t>(verifier, VT_END_TYPE, 1) && VerifyOffsetRequired(verifier, VT_END) &&
+               VerifyFloatProp(verifier, end(), end_type()) && VerifyField<uint8_t>(verifier, VT_OFFSET_TYPE, 1) &&
+               VerifyOffsetRequired(verifier, VT_OFFSET) && VerifyFloatProp(verifier, offset(), offset_type()) &&
+               VerifyField<int8_t>(verifier, VT_TYPE, 1) && verifier.EndTable();
+    }
+};
+
+template <>
+inline const LottieFlatBuffer::FloatFrameArray *TrimPath::start_as<LottieFlatBuffer::FloatFrameArray>() const
+{
+    return start_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::FloatScalar *TrimPath::start_as<LottieFlatBuffer::FloatScalar>() const
+{
+    return start_as_value();
+}
+
+template <>
+inline const LottieFlatBuffer::FloatFrameArray *TrimPath::end_as<LottieFlatBuffer::FloatFrameArray>() const
+{
+    return end_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::FloatScalar *TrimPath::end_as<LottieFlatBuffer::FloatScalar>() const
+{
+    return end_as_value();
+}
+
+template <>
+inline const LottieFlatBuffer::FloatFrameArray *TrimPath::offset_as<LottieFlatBuffer::FloatFrameArray>() const
+{
+    return offset_as_frames();
+}
+
+template <>
+inline const LottieFlatBuffer::FloatScalar *TrimPath::offset_as<LottieFlatBuffer::FloatScalar>() const
+{
+    return offset_as_value();
+}
+
+struct TrimPathBuilder {
+    typedef TrimPath Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_start_type(LottieFlatBuffer::FloatProp start_type)
+    {
+        fbb_.AddElement<uint8_t>(TrimPath::VT_START_TYPE, static_cast<uint8_t>(start_type), 0);
+    }
+    void add_start(::flatbuffers::Offset<void> start)
+    {
+        fbb_.AddOffset(TrimPath::VT_START, start);
+    }
+    void add_end_type(LottieFlatBuffer::FloatProp end_type)
+    {
+        fbb_.AddElement<uint8_t>(TrimPath::VT_END_TYPE, static_cast<uint8_t>(end_type), 0);
+    }
+    void add_end(::flatbuffers::Offset<void> end)
+    {
+        fbb_.AddOffset(TrimPath::VT_END, end);
+    }
+    void add_offset_type(LottieFlatBuffer::FloatProp offset_type)
+    {
+        fbb_.AddElement<uint8_t>(TrimPath::VT_OFFSET_TYPE, static_cast<uint8_t>(offset_type), 0);
+    }
+    void add_offset(::flatbuffers::Offset<void> offset)
+    {
+        fbb_.AddOffset(TrimPath::VT_OFFSET, offset);
+    }
+    void add_type(LottieFlatBuffer::TrimType type)
+    {
+        fbb_.AddElement<int8_t>(TrimPath::VT_TYPE, static_cast<int8_t>(type), 0);
+    }
+    explicit TrimPathBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<TrimPath> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<TrimPath>(end);
+        fbb_.Required(o, TrimPath::VT_START);
+        fbb_.Required(o, TrimPath::VT_END);
+        fbb_.Required(o, TrimPath::VT_OFFSET);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<TrimPath> CreateTrimPath(
+    ::flatbuffers::FlatBufferBuilder &_fbb, LottieFlatBuffer::FloatProp start_type = LottieFlatBuffer::FloatProp_NONE,
+    ::flatbuffers::Offset<void> start = 0, LottieFlatBuffer::FloatProp end_type = LottieFlatBuffer::FloatProp_NONE,
+    ::flatbuffers::Offset<void> end = 0, LottieFlatBuffer::FloatProp offset_type = LottieFlatBuffer::FloatProp_NONE,
+    ::flatbuffers::Offset<void> offset = 0, LottieFlatBuffer::TrimType type = LottieFlatBuffer::TrimType_Simultaneous)
+{
+    TrimPathBuilder builder_(_fbb);
+    builder_.add_offset(offset);
+    builder_.add_end(end);
+    builder_.add_start(start);
+    builder_.add_type(type);
+    builder_.add_offset_type(offset_type);
+    builder_.add_end_type(end_type);
+    builder_.add_start_type(start_type);
+    return builder_.Finish();
+}
+
+struct TransformShape FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef TransformShapeBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_TRANSFORM = 4 };
+    const LottieFlatBuffer::Transform *transform() const
+    {
+        return GetPointer<const LottieFlatBuffer::Transform *>(VT_TRANSFORM);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_TRANSFORM) &&
+               verifier.VerifyTable(transform()) && verifier.EndTable();
+    }
+};
+
+struct TransformShapeBuilder {
+    typedef TransformShape Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_transform(::flatbuffers::Offset<LottieFlatBuffer::Transform> transform)
+    {
+        fbb_.AddOffset(TransformShape::VT_TRANSFORM, transform);
+    }
+    explicit TransformShapeBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<TransformShape> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<TransformShape>(end);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<TransformShape> CreateTransformShape(
+    ::flatbuffers::FlatBufferBuilder &_fbb, ::flatbuffers::Offset<LottieFlatBuffer::Transform> transform = 0)
+{
+    TransformShapeBuilder builder_(_fbb);
+    builder_.add_transform(transform);
+    return builder_.Finish();
+}
+
+struct GroupShape FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef GroupShapeBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_SHAPES_TYPE = 4, VT_SHAPES = 6 };
+    const ::flatbuffers::Vector<uint8_t> *shapes_type() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<uint8_t> *>(VT_SHAPES_TYPE);
+    }
+    const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *shapes() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *>(VT_SHAPES);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_SHAPES_TYPE) &&
+               verifier.VerifyVector(shapes_type()) && VerifyOffset(verifier, VT_SHAPES) &&
+               verifier.VerifyVector(shapes()) && VerifyGraphicElementVector(verifier, shapes(), shapes_type()) &&
+               verifier.EndTable();
+    }
+};
+
+struct GroupShapeBuilder {
+    typedef GroupShape Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_shapes_type(::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> shapes_type)
+    {
+        fbb_.AddOffset(GroupShape::VT_SHAPES_TYPE, shapes_type);
+    }
+    void add_shapes(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<void>>> shapes)
+    {
+        fbb_.AddOffset(GroupShape::VT_SHAPES, shapes);
+    }
+    explicit GroupShapeBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<GroupShape> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<GroupShape>(end);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<GroupShape> CreateGroupShape(
+    ::flatbuffers::FlatBufferBuilder &_fbb, ::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> shapes_type = 0,
+    ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<void>>> shapes = 0)
+{
+    GroupShapeBuilder builder_(_fbb);
+    builder_.add_shapes(shapes);
+    builder_.add_shapes_type(shapes_type);
+    return builder_.Finish();
+}
+
+inline ::flatbuffers::Offset<GroupShape> CreateGroupShapeDirect(
+    ::flatbuffers::FlatBufferBuilder &_fbb, const std::vector<uint8_t> *shapes_type = nullptr,
+    const std::vector<::flatbuffers::Offset<void>> *shapes = nullptr)
+{
+    auto shapes_type__ = shapes_type ? _fbb.CreateVector<uint8_t>(*shapes_type) : 0;
+    auto shapes__ = shapes ? _fbb.CreateVector<::flatbuffers::Offset<void>>(*shapes) : 0;
+    return LottieFlatBuffer::CreateGroupShape(_fbb, shapes_type__, shapes__);
+}
+
+struct BaseLayer FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef BaseLayerBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+        VT_IN_FRAME = 4,
+        VT_OUT_FRAME = 6,
+        VT_START_FRAME = 8,
+        VT_INDEX = 10,
+        VT_PARENT = 12,
+        VT_NAME = 14,
+        VT_TRANSFORM = 16,
+        VT_BLEND_MODE = 18
+    };
+    float in_frame() const
+    {
+        return GetField<float>(VT_IN_FRAME, 0.0f);
+    }
+    float out_frame() const
+    {
+        return GetField<float>(VT_OUT_FRAME, 0.0f);
+    }
+    float start_frame() const
+    {
+        return GetField<float>(VT_START_FRAME, 0.0f);
+    }
+    int32_t index() const
+    {
+        return GetField<int32_t>(VT_INDEX, -1);
+    }
+    int32_t parent() const
+    {
+        return GetField<int32_t>(VT_PARENT, -1);
+    }
+    const ::flatbuffers::String *name() const
+    {
+        return GetPointer<const ::flatbuffers::String *>(VT_NAME);
+    }
+    const LottieFlatBuffer::Transform *transform() const
+    {
+        return GetPointer<const LottieFlatBuffer::Transform *>(VT_TRANSFORM);
+    }
+    LottieFlatBuffer::BlendMode blend_mode() const
+    {
+        return static_cast<LottieFlatBuffer::BlendMode>(GetField<int8_t>(VT_BLEND_MODE, 0));
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyField<float>(verifier, VT_IN_FRAME, 4) &&
+               VerifyField<float>(verifier, VT_OUT_FRAME, 4) && VerifyField<float>(verifier, VT_START_FRAME, 4) &&
+               VerifyField<int32_t>(verifier, VT_INDEX, 4) && VerifyField<int32_t>(verifier, VT_PARENT, 4) &&
+               VerifyOffset(verifier, VT_NAME) && verifier.VerifyString(name()) &&
+               VerifyOffset(verifier, VT_TRANSFORM) && verifier.VerifyTable(transform()) &&
+               VerifyField<int8_t>(verifier, VT_BLEND_MODE, 1) && verifier.EndTable();
+    }
+};
+
+struct BaseLayerBuilder {
+    typedef BaseLayer Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_in_frame(float in_frame)
+    {
+        fbb_.AddElement<float>(BaseLayer::VT_IN_FRAME, in_frame, 0.0f);
+    }
+    void add_out_frame(float out_frame)
+    {
+        fbb_.AddElement<float>(BaseLayer::VT_OUT_FRAME, out_frame, 0.0f);
+    }
+    void add_start_frame(float start_frame)
+    {
+        fbb_.AddElement<float>(BaseLayer::VT_START_FRAME, start_frame, 0.0f);
+    }
+    void add_index(int32_t index)
+    {
+        fbb_.AddElement<int32_t>(BaseLayer::VT_INDEX, index, -1);
+    }
+    void add_parent(int32_t parent)
+    {
+        fbb_.AddElement<int32_t>(BaseLayer::VT_PARENT, parent, -1);
+    }
+    void add_name(::flatbuffers::Offset<::flatbuffers::String> name)
+    {
+        fbb_.AddOffset(BaseLayer::VT_NAME, name);
+    }
+    void add_transform(::flatbuffers::Offset<LottieFlatBuffer::Transform> transform)
+    {
+        fbb_.AddOffset(BaseLayer::VT_TRANSFORM, transform);
+    }
+    void add_blend_mode(LottieFlatBuffer::BlendMode blend_mode)
+    {
+        fbb_.AddElement<int8_t>(BaseLayer::VT_BLEND_MODE, static_cast<int8_t>(blend_mode), 0);
+    }
+    explicit BaseLayerBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<BaseLayer> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<BaseLayer>(end);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<BaseLayer> CreateBaseLayer(
+    ::flatbuffers::FlatBufferBuilder &_fbb, float in_frame = 0.0f, float out_frame = 0.0f, float start_frame = 0.0f,
+    int32_t index = -1, int32_t parent = -1, ::flatbuffers::Offset<::flatbuffers::String> name = 0,
+    ::flatbuffers::Offset<LottieFlatBuffer::Transform> transform = 0,
+    LottieFlatBuffer::BlendMode blend_mode = LottieFlatBuffer::BlendMode_Normal)
+{
+    BaseLayerBuilder builder_(_fbb);
+    builder_.add_transform(transform);
+    builder_.add_name(name);
+    builder_.add_parent(parent);
+    builder_.add_index(index);
+    builder_.add_start_frame(start_frame);
+    builder_.add_out_frame(out_frame);
+    builder_.add_in_frame(in_frame);
+    builder_.add_blend_mode(blend_mode);
+    return builder_.Finish();
+}
+
+inline ::flatbuffers::Offset<BaseLayer> CreateBaseLayerDirect(
+    ::flatbuffers::FlatBufferBuilder &_fbb, float in_frame = 0.0f, float out_frame = 0.0f, float start_frame = 0.0f,
+    int32_t index = -1, int32_t parent = -1, const char *name = nullptr,
+    ::flatbuffers::Offset<LottieFlatBuffer::Transform> transform = 0,
+    LottieFlatBuffer::BlendMode blend_mode = LottieFlatBuffer::BlendMode_Normal)
+{
+    auto name__ = name ? _fbb.CreateString(name) : 0;
+    return LottieFlatBuffer::CreateBaseLayer(_fbb, in_frame, out_frame, start_frame, index, parent, name__, transform,
+                                             blend_mode);
+}
+
+struct ShapeLayer FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef ShapeLayerBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_BASE = 4, VT_SHAPES_TYPE = 6, VT_SHAPES = 8 };
+    const LottieFlatBuffer::BaseLayer *base() const
+    {
+        return GetPointer<const LottieFlatBuffer::BaseLayer *>(VT_BASE);
+    }
+    const ::flatbuffers::Vector<uint8_t> *shapes_type() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<uint8_t> *>(VT_SHAPES_TYPE);
+    }
+    const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *shapes() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *>(VT_SHAPES);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_BASE) && verifier.VerifyTable(base()) &&
+               VerifyOffsetRequired(verifier, VT_SHAPES_TYPE) && verifier.VerifyVector(shapes_type()) &&
+               VerifyOffsetRequired(verifier, VT_SHAPES) && verifier.VerifyVector(shapes()) &&
+               VerifyGraphicElementVector(verifier, shapes(), shapes_type()) && verifier.EndTable();
+    }
+};
+
+struct ShapeLayerBuilder {
+    typedef ShapeLayer Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_base(::flatbuffers::Offset<LottieFlatBuffer::BaseLayer> base)
+    {
+        fbb_.AddOffset(ShapeLayer::VT_BASE, base);
+    }
+    void add_shapes_type(::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> shapes_type)
+    {
+        fbb_.AddOffset(ShapeLayer::VT_SHAPES_TYPE, shapes_type);
+    }
+    void add_shapes(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<void>>> shapes)
+    {
+        fbb_.AddOffset(ShapeLayer::VT_SHAPES, shapes);
+    }
+    explicit ShapeLayerBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<ShapeLayer> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<ShapeLayer>(end);
+        fbb_.Required(o, ShapeLayer::VT_SHAPES_TYPE);
+        fbb_.Required(o, ShapeLayer::VT_SHAPES);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<ShapeLayer> CreateShapeLayer(
+    ::flatbuffers::FlatBufferBuilder &_fbb, ::flatbuffers::Offset<LottieFlatBuffer::BaseLayer> base = 0,
+    ::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> shapes_type = 0,
+    ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<void>>> shapes = 0)
+{
+    ShapeLayerBuilder builder_(_fbb);
+    builder_.add_shapes(shapes);
+    builder_.add_shapes_type(shapes_type);
+    builder_.add_base(base);
+    return builder_.Finish();
+}
+
+inline ::flatbuffers::Offset<ShapeLayer> CreateShapeLayerDirect(
+    ::flatbuffers::FlatBufferBuilder &_fbb, ::flatbuffers::Offset<LottieFlatBuffer::BaseLayer> base = 0,
+    const std::vector<uint8_t> *shapes_type = nullptr, const std::vector<::flatbuffers::Offset<void>> *shapes = nullptr)
+{
+    auto shapes_type__ = shapes_type ? _fbb.CreateVector<uint8_t>(*shapes_type) : 0;
+    auto shapes__ = shapes ? _fbb.CreateVector<::flatbuffers::Offset<void>>(*shapes) : 0;
+    return LottieFlatBuffer::CreateShapeLayer(_fbb, base, shapes_type__, shapes__);
+}
+
+struct PrecompositionLayer FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef PrecompositionLayerBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+        VT_BASE = 4,
+        VT_REF_ID = 6,
+        VT_WIDTH = 8,
+        VT_HEIGHT = 10
+    };
+    const LottieFlatBuffer::BaseLayer *base() const
+    {
+        return GetPointer<const LottieFlatBuffer::BaseLayer *>(VT_BASE);
+    }
+    const ::flatbuffers::String *ref_id() const
+    {
+        return GetPointer<const ::flatbuffers::String *>(VT_REF_ID);
+    }
+    uint16_t width() const
+    {
+        return GetField<uint16_t>(VT_WIDTH, 0);
+    }
+    uint16_t height() const
+    {
+        return GetField<uint16_t>(VT_HEIGHT, 0);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_BASE) && verifier.VerifyTable(base()) &&
+               VerifyOffset(verifier, VT_REF_ID) && verifier.VerifyString(ref_id()) &&
+               VerifyField<uint16_t>(verifier, VT_WIDTH, 2) && VerifyField<uint16_t>(verifier, VT_HEIGHT, 2) &&
+               verifier.EndTable();
+    }
+};
+
+struct PrecompositionLayerBuilder {
+    typedef PrecompositionLayer Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_base(::flatbuffers::Offset<LottieFlatBuffer::BaseLayer> base)
+    {
+        fbb_.AddOffset(PrecompositionLayer::VT_BASE, base);
+    }
+    void add_ref_id(::flatbuffers::Offset<::flatbuffers::String> ref_id)
+    {
+        fbb_.AddOffset(PrecompositionLayer::VT_REF_ID, ref_id);
+    }
+    void add_width(uint16_t width)
+    {
+        fbb_.AddElement<uint16_t>(PrecompositionLayer::VT_WIDTH, width, 0);
+    }
+    void add_height(uint16_t height)
+    {
+        fbb_.AddElement<uint16_t>(PrecompositionLayer::VT_HEIGHT, height, 0);
+    }
+    explicit PrecompositionLayerBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<PrecompositionLayer> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<PrecompositionLayer>(end);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<PrecompositionLayer> CreatePrecompositionLayer(
+    ::flatbuffers::FlatBufferBuilder &_fbb, ::flatbuffers::Offset<LottieFlatBuffer::BaseLayer> base = 0,
+    ::flatbuffers::Offset<::flatbuffers::String> ref_id = 0, uint16_t width = 0, uint16_t height = 0)
+{
+    PrecompositionLayerBuilder builder_(_fbb);
+    builder_.add_ref_id(ref_id);
+    builder_.add_base(base);
+    builder_.add_height(height);
+    builder_.add_width(width);
+    return builder_.Finish();
+}
+
+inline ::flatbuffers::Offset<PrecompositionLayer> CreatePrecompositionLayerDirect(
+    ::flatbuffers::FlatBufferBuilder &_fbb, ::flatbuffers::Offset<LottieFlatBuffer::BaseLayer> base = 0,
+    const char *ref_id = nullptr, uint16_t width = 0, uint16_t height = 0)
+{
+    auto ref_id__ = ref_id ? _fbb.CreateString(ref_id) : 0;
+    return LottieFlatBuffer::CreatePrecompositionLayer(_fbb, base, ref_id__, width, height);
+}
+
+struct NullLayer FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef NullLayerBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_BASE = 4 };
+    const LottieFlatBuffer::BaseLayer *base() const
+    {
+        return GetPointer<const LottieFlatBuffer::BaseLayer *>(VT_BASE);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_BASE) && verifier.VerifyTable(base()) &&
+               verifier.EndTable();
+    }
+};
+
+struct NullLayerBuilder {
+    typedef NullLayer Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_base(::flatbuffers::Offset<LottieFlatBuffer::BaseLayer> base)
+    {
+        fbb_.AddOffset(NullLayer::VT_BASE, base);
+    }
+    explicit NullLayerBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<NullLayer> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<NullLayer>(end);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<NullLayer> CreateNullLayer(::flatbuffers::FlatBufferBuilder &_fbb,
+                                                        ::flatbuffers::Offset<LottieFlatBuffer::BaseLayer> base = 0)
+{
+    NullLayerBuilder builder_(_fbb);
+    builder_.add_base(base);
+    return builder_.Finish();
+}
+
+struct TextDocument FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef TextDocumentBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+        VT_TEXT = 4,
+        VT_COLOR = 6,
+        VT_SIZE = 8,
+        VT_HEIGHT = 10,
+        VT_B_BOX = 12,
+        VT_ALIGN = 14
+    };
+    const ::flatbuffers::String *text() const
+    {
+        return GetPointer<const ::flatbuffers::String *>(VT_TEXT);
+    }
+    const LottieFlatBuffer::Color24 *color() const
+    {
+        return GetStruct<const LottieFlatBuffer::Color24 *>(VT_COLOR);
+    }
+    uint16_t size() const
+    {
+        return GetField<uint16_t>(VT_SIZE, 0);
+    }
+    uint16_t height() const
+    {
+        return GetField<uint16_t>(VT_HEIGHT, 0);
+    }
+    const LottieFlatBuffer::Rect *b_box() const
+    {
+        return GetStruct<const LottieFlatBuffer::Rect *>(VT_B_BOX);
+    }
+    LottieFlatBuffer::TextAlign align() const
+    {
+        return static_cast<LottieFlatBuffer::TextAlign>(GetField<int8_t>(VT_ALIGN, 1));
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_TEXT) && verifier.VerifyString(text()) &&
+               VerifyField<LottieFlatBuffer::Color24>(verifier, VT_COLOR, 1) &&
+               VerifyField<uint16_t>(verifier, VT_SIZE, 2) && VerifyField<uint16_t>(verifier, VT_HEIGHT, 2) &&
+               VerifyField<LottieFlatBuffer::Rect>(verifier, VT_B_BOX, 4) &&
+               VerifyField<int8_t>(verifier, VT_ALIGN, 1) && verifier.EndTable();
+    }
+};
+
+struct TextDocumentBuilder {
+    typedef TextDocument Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_text(::flatbuffers::Offset<::flatbuffers::String> text)
+    {
+        fbb_.AddOffset(TextDocument::VT_TEXT, text);
+    }
+    void add_color(const LottieFlatBuffer::Color24 *color)
+    {
+        fbb_.AddStruct(TextDocument::VT_COLOR, color);
+    }
+    void add_size(uint16_t size)
+    {
+        fbb_.AddElement<uint16_t>(TextDocument::VT_SIZE, size, 0);
+    }
+    void add_height(uint16_t height)
+    {
+        fbb_.AddElement<uint16_t>(TextDocument::VT_HEIGHT, height, 0);
+    }
+    void add_b_box(const LottieFlatBuffer::Rect *b_box)
+    {
+        fbb_.AddStruct(TextDocument::VT_B_BOX, b_box);
+    }
+    void add_align(LottieFlatBuffer::TextAlign align)
+    {
+        fbb_.AddElement<int8_t>(TextDocument::VT_ALIGN, static_cast<int8_t>(align), 1);
+    }
+    explicit TextDocumentBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<TextDocument> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<TextDocument>(end);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<TextDocument> CreateTextDocument(
+    ::flatbuffers::FlatBufferBuilder &_fbb, ::flatbuffers::Offset<::flatbuffers::String> text = 0,
+    const LottieFlatBuffer::Color24 *color = nullptr, uint16_t size = 0, uint16_t height = 0,
+    const LottieFlatBuffer::Rect *b_box = nullptr,
+    LottieFlatBuffer::TextAlign align = LottieFlatBuffer::TextAlign_AlignLeft)
+{
+    TextDocumentBuilder builder_(_fbb);
+    builder_.add_b_box(b_box);
+    builder_.add_color(color);
+    builder_.add_text(text);
+    builder_.add_height(height);
+    builder_.add_size(size);
+    builder_.add_align(align);
+    return builder_.Finish();
+}
+
+inline ::flatbuffers::Offset<TextDocument> CreateTextDocumentDirect(
+    ::flatbuffers::FlatBufferBuilder &_fbb, const char *text = nullptr,
+    const LottieFlatBuffer::Color24 *color = nullptr, uint16_t size = 0, uint16_t height = 0,
+    const LottieFlatBuffer::Rect *b_box = nullptr,
+    LottieFlatBuffer::TextAlign align = LottieFlatBuffer::TextAlign_AlignLeft)
+{
+    auto text__ = text ? _fbb.CreateString(text) : 0;
+    return LottieFlatBuffer::CreateTextDocument(_fbb, text__, color, size, height, b_box, align);
+}
+
+struct TextDocumentFrame FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef TextDocumentFrameBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+        VT_TIME = 4,
+        VT_START = 6,
+        VT_HOLD = 8,
+        VT_TIME_EASING = 10,
+        VT_VALUE_EASING = 12
+    };
+    float time() const
+    {
+        return GetField<float>(VT_TIME, 0.0f);
+    }
+    const LottieFlatBuffer::TextDocument *start() const
+    {
+        return GetPointer<const LottieFlatBuffer::TextDocument *>(VT_START);
+    }
+    bool hold() const
+    {
+        return GetField<uint8_t>(VT_HOLD, 0) != 0;
+    }
+    const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *time_easing() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *>(VT_TIME_EASING);
+    }
+    const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *value_easing() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<const LottieFlatBuffer::Point *> *>(VT_VALUE_EASING);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyField<float>(verifier, VT_TIME, 4) &&
+               VerifyOffsetRequired(verifier, VT_START) && verifier.VerifyTable(start()) &&
+               VerifyField<uint8_t>(verifier, VT_HOLD, 1) && VerifyOffset(verifier, VT_TIME_EASING) &&
+               verifier.VerifyVector(time_easing()) && VerifyOffset(verifier, VT_VALUE_EASING) &&
+               verifier.VerifyVector(value_easing()) && verifier.EndTable();
+    }
+};
+
+struct TextDocumentFrameBuilder {
+    typedef TextDocumentFrame Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_time(float time)
+    {
+        fbb_.AddElement<float>(TextDocumentFrame::VT_TIME, time, 0.0f);
+    }
+    void add_start(::flatbuffers::Offset<LottieFlatBuffer::TextDocument> start)
+    {
+        fbb_.AddOffset(TextDocumentFrame::VT_START, start);
+    }
+    void add_hold(bool hold)
+    {
+        fbb_.AddElement<uint8_t>(TextDocumentFrame::VT_HOLD, static_cast<uint8_t>(hold), 0);
+    }
+    void add_time_easing(::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> time_easing)
+    {
+        fbb_.AddOffset(TextDocumentFrame::VT_TIME_EASING, time_easing);
+    }
+    void add_value_easing(::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> value_easing)
+    {
+        fbb_.AddOffset(TextDocumentFrame::VT_VALUE_EASING, value_easing);
+    }
+    explicit TextDocumentFrameBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<TextDocumentFrame> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<TextDocumentFrame>(end);
+        fbb_.Required(o, TextDocumentFrame::VT_START);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<TextDocumentFrame> CreateTextDocumentFrame(
+    ::flatbuffers::FlatBufferBuilder &_fbb, float time = 0.0f,
+    ::flatbuffers::Offset<LottieFlatBuffer::TextDocument> start = 0, bool hold = false,
+    ::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> time_easing = 0,
+    ::flatbuffers::Offset<::flatbuffers::Vector<const LottieFlatBuffer::Point *>> value_easing = 0)
+{
+    TextDocumentFrameBuilder builder_(_fbb);
+    builder_.add_value_easing(value_easing);
+    builder_.add_time_easing(time_easing);
+    builder_.add_start(start);
+    builder_.add_time(time);
+    builder_.add_hold(hold);
+    return builder_.Finish();
+}
+
+inline ::flatbuffers::Offset<TextDocumentFrame> CreateTextDocumentFrameDirect(
+    ::flatbuffers::FlatBufferBuilder &_fbb, float time = 0.0f,
+    ::flatbuffers::Offset<LottieFlatBuffer::TextDocument> start = 0, bool hold = false,
+    const std::vector<LottieFlatBuffer::Point> *time_easing = nullptr,
+    const std::vector<LottieFlatBuffer::Point> *value_easing = nullptr)
+{
+    auto time_easing__ = time_easing ? _fbb.CreateVectorOfStructs<LottieFlatBuffer::Point>(*time_easing) : 0;
+    auto value_easing__ = value_easing ? _fbb.CreateVectorOfStructs<LottieFlatBuffer::Point>(*value_easing) : 0;
+    return LottieFlatBuffer::CreateTextDocumentFrame(_fbb, time, start, hold, time_easing__, value_easing__);
+}
+
+struct TextData FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef TextDataBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_FRAMES = 4 };
+    const ::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::TextDocumentFrame>> *frames() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::TextDocumentFrame>> *>(
+            VT_FRAMES);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyOffsetRequired(verifier, VT_FRAMES) &&
+               verifier.VerifyVector(frames()) && verifier.VerifyVectorOfTables(frames()) && verifier.EndTable();
+    }
+};
+
+struct TextDataBuilder {
+    typedef TextData Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_frames(
+        ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::TextDocumentFrame>>> frames)
+    {
+        fbb_.AddOffset(TextData::VT_FRAMES, frames);
+    }
+    explicit TextDataBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<TextData> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<TextData>(end);
+        fbb_.Required(o, TextData::VT_FRAMES);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<TextData> CreateTextData(
+    ::flatbuffers::FlatBufferBuilder &_fbb,
+    ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::TextDocumentFrame>>> frames = 0)
+{
+    TextDataBuilder builder_(_fbb);
+    builder_.add_frames(frames);
+    return builder_.Finish();
+}
+
+inline ::flatbuffers::Offset<TextData> CreateTextDataDirect(
+    ::flatbuffers::FlatBufferBuilder &_fbb,
+    const std::vector<::flatbuffers::Offset<LottieFlatBuffer::TextDocumentFrame>> *frames = nullptr)
+{
+    auto frames__ = frames ? _fbb.CreateVector<::flatbuffers::Offset<LottieFlatBuffer::TextDocumentFrame>>(*frames) : 0;
+    return LottieFlatBuffer::CreateTextData(_fbb, frames__);
+}
+
+struct TextLayer FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef TextLayerBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_BASE = 4, VT_DATA = 6 };
+    const LottieFlatBuffer::BaseLayer *base() const
+    {
+        return GetPointer<const LottieFlatBuffer::BaseLayer *>(VT_BASE);
+    }
+    const LottieFlatBuffer::TextData *data() const
+    {
+        return GetPointer<const LottieFlatBuffer::TextData *>(VT_DATA);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_BASE) && verifier.VerifyTable(base()) &&
+               VerifyOffset(verifier, VT_DATA) && verifier.VerifyTable(data()) && verifier.EndTable();
+    }
+};
+
+struct TextLayerBuilder {
+    typedef TextLayer Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_base(::flatbuffers::Offset<LottieFlatBuffer::BaseLayer> base)
+    {
+        fbb_.AddOffset(TextLayer::VT_BASE, base);
+    }
+    void add_data(::flatbuffers::Offset<LottieFlatBuffer::TextData> data)
+    {
+        fbb_.AddOffset(TextLayer::VT_DATA, data);
+    }
+    explicit TextLayerBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<TextLayer> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<TextLayer>(end);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<TextLayer> CreateTextLayer(::flatbuffers::FlatBufferBuilder &_fbb,
+                                                        ::flatbuffers::Offset<LottieFlatBuffer::BaseLayer> base = 0,
+                                                        ::flatbuffers::Offset<LottieFlatBuffer::TextData> data = 0)
+{
+    TextLayerBuilder builder_(_fbb);
+    builder_.add_data(data);
+    builder_.add_base(base);
+    return builder_.Finish();
+}
+
+struct ImageLayer FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef ImageLayerBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_BASE = 4, VT_INDEX = 6 };
+    const LottieFlatBuffer::BaseLayer *base() const
+    {
+        return GetPointer<const LottieFlatBuffer::BaseLayer *>(VT_BASE);
+    }
+    int32_t index() const
+    {
+        return GetField<int32_t>(VT_INDEX, 0);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_BASE) && verifier.VerifyTable(base()) &&
+               VerifyField<int32_t>(verifier, VT_INDEX, 4) && verifier.EndTable();
+    }
+};
+
+struct ImageLayerBuilder {
+    typedef ImageLayer Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_base(::flatbuffers::Offset<LottieFlatBuffer::BaseLayer> base)
+    {
+        fbb_.AddOffset(ImageLayer::VT_BASE, base);
+    }
+    void add_index(int32_t index)
+    {
+        fbb_.AddElement<int32_t>(ImageLayer::VT_INDEX, index, 0);
+    }
+    explicit ImageLayerBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<ImageLayer> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<ImageLayer>(end);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<ImageLayer> CreateImageLayer(::flatbuffers::FlatBufferBuilder &_fbb,
+                                                          ::flatbuffers::Offset<LottieFlatBuffer::BaseLayer> base = 0,
+                                                          int32_t index = 0)
+{
+    ImageLayerBuilder builder_(_fbb);
+    builder_.add_index(index);
+    builder_.add_base(base);
+    return builder_.Finish();
+}
+
+struct SolidLayer FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef SolidLayerBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+        VT_BASE = 4,
+        VT_WIDTH = 6,
+        VT_HEIGHT = 8,
+        VT_COLOR = 10
+    };
+    const LottieFlatBuffer::BaseLayer *base() const
+    {
+        return GetPointer<const LottieFlatBuffer::BaseLayer *>(VT_BASE);
+    }
+    uint16_t width() const
+    {
+        return GetField<uint16_t>(VT_WIDTH, 0);
+    }
+    uint16_t height() const
+    {
+        return GetField<uint16_t>(VT_HEIGHT, 0);
+    }
+    const LottieFlatBuffer::Color24 *color() const
+    {
+        return GetStruct<const LottieFlatBuffer::Color24 *>(VT_COLOR);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_BASE) && verifier.VerifyTable(base()) &&
+               VerifyField<uint16_t>(verifier, VT_WIDTH, 2) && VerifyField<uint16_t>(verifier, VT_HEIGHT, 2) &&
+               VerifyField<LottieFlatBuffer::Color24>(verifier, VT_COLOR, 1) && verifier.EndTable();
+    }
+};
+
+struct SolidLayerBuilder {
+    typedef SolidLayer Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_base(::flatbuffers::Offset<LottieFlatBuffer::BaseLayer> base)
+    {
+        fbb_.AddOffset(SolidLayer::VT_BASE, base);
+    }
+    void add_width(uint16_t width)
+    {
+        fbb_.AddElement<uint16_t>(SolidLayer::VT_WIDTH, width, 0);
+    }
+    void add_height(uint16_t height)
+    {
+        fbb_.AddElement<uint16_t>(SolidLayer::VT_HEIGHT, height, 0);
+    }
+    void add_color(const LottieFlatBuffer::Color24 *color)
+    {
+        fbb_.AddStruct(SolidLayer::VT_COLOR, color);
+    }
+    explicit SolidLayerBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<SolidLayer> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<SolidLayer>(end);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<SolidLayer> CreateSolidLayer(::flatbuffers::FlatBufferBuilder &_fbb,
+                                                          ::flatbuffers::Offset<LottieFlatBuffer::BaseLayer> base = 0,
+                                                          uint16_t width = 0, uint16_t height = 0,
+                                                          const LottieFlatBuffer::Color24 *color = nullptr)
+{
+    SolidLayerBuilder builder_(_fbb);
+    builder_.add_color(color);
+    builder_.add_base(base);
+    builder_.add_height(height);
+    builder_.add_width(width);
+    return builder_.Finish();
+}
+
+struct Asset FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef AssetBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_ID = 4, VT_LAYERS_TYPE = 6, VT_LAYERS = 8 };
+    const ::flatbuffers::String *id() const
+    {
+        return GetPointer<const ::flatbuffers::String *>(VT_ID);
+    }
+    const ::flatbuffers::Vector<uint8_t> *layers_type() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<uint8_t> *>(VT_LAYERS_TYPE);
+    }
+    const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *layers() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *>(VT_LAYERS);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_ID) && verifier.VerifyString(id()) &&
+               VerifyOffset(verifier, VT_LAYERS_TYPE) && verifier.VerifyVector(layers_type()) &&
+               VerifyOffset(verifier, VT_LAYERS) && verifier.VerifyVector(layers()) &&
+               VerifyLayerVector(verifier, layers(), layers_type()) && verifier.EndTable();
+    }
+};
+
+struct AssetBuilder {
+    typedef Asset Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_id(::flatbuffers::Offset<::flatbuffers::String> id)
+    {
+        fbb_.AddOffset(Asset::VT_ID, id);
+    }
+    void add_layers_type(::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> layers_type)
+    {
+        fbb_.AddOffset(Asset::VT_LAYERS_TYPE, layers_type);
+    }
+    void add_layers(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<void>>> layers)
+    {
+        fbb_.AddOffset(Asset::VT_LAYERS, layers);
+    }
+    explicit AssetBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<Asset> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<Asset>(end);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<Asset> CreateAsset(
+    ::flatbuffers::FlatBufferBuilder &_fbb, ::flatbuffers::Offset<::flatbuffers::String> id = 0,
+    ::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> layers_type = 0,
+    ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<void>>> layers = 0)
+{
+    AssetBuilder builder_(_fbb);
+    builder_.add_layers(layers);
+    builder_.add_layers_type(layers_type);
+    builder_.add_id(id);
+    return builder_.Finish();
+}
+
+inline ::flatbuffers::Offset<Asset> CreateAssetDirect(::flatbuffers::FlatBufferBuilder &_fbb, const char *id = nullptr,
+                                                      const std::vector<uint8_t> *layers_type = nullptr,
+                                                      const std::vector<::flatbuffers::Offset<void>> *layers = nullptr)
+{
+    auto id__ = id ? _fbb.CreateString(id) : 0;
+    auto layers_type__ = layers_type ? _fbb.CreateVector<uint8_t>(*layers_type) : 0;
+    auto layers__ = layers ? _fbb.CreateVector<::flatbuffers::Offset<void>>(*layers) : 0;
+    return LottieFlatBuffer::CreateAsset(_fbb, id__, layers_type__, layers__);
+}
+
+struct Animations FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+    typedef AnimationsBuilder Builder;
+    enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+        VT_VERSION = 4,
+        VT_LAYERS_TYPE = 6,
+        VT_LAYERS = 8,
+        VT_FRAME_RATE = 10,
+        VT_START_FRAME = 12,
+        VT_END_FRAME = 14,
+        VT_WIDTH = 16,
+        VT_HEIGHT = 18,
+        VT_ASSETS = 20
+    };
+    const ::flatbuffers::String *version() const
+    {
+        return GetPointer<const ::flatbuffers::String *>(VT_VERSION);
+    }
+    const ::flatbuffers::Vector<uint8_t> *layers_type() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<uint8_t> *>(VT_LAYERS_TYPE);
+    }
+    const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *layers() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *>(VT_LAYERS);
+    }
+    float frame_rate() const
+    {
+        return GetField<float>(VT_FRAME_RATE, 0.0f);
+    }
+    float start_frame() const
+    {
+        return GetField<float>(VT_START_FRAME, 0.0f);
+    }
+    float end_frame() const
+    {
+        return GetField<float>(VT_END_FRAME, 0.0f);
+    }
+    float width() const
+    {
+        return GetField<float>(VT_WIDTH, 0.0f);
+    }
+    float height() const
+    {
+        return GetField<float>(VT_HEIGHT, 0.0f);
+    }
+    const ::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::Asset>> *assets() const
+    {
+        return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::Asset>> *>(VT_ASSETS);
+    }
+    bool Verify(::flatbuffers::Verifier &verifier) const
+    {
+        return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_VERSION) && verifier.VerifyString(version()) &&
+               VerifyOffsetRequired(verifier, VT_LAYERS_TYPE) && verifier.VerifyVector(layers_type()) &&
+               VerifyOffsetRequired(verifier, VT_LAYERS) && verifier.VerifyVector(layers()) &&
+               VerifyLayerVector(verifier, layers(), layers_type()) && VerifyField<float>(verifier, VT_FRAME_RATE, 4) &&
+               VerifyField<float>(verifier, VT_START_FRAME, 4) && VerifyField<float>(verifier, VT_END_FRAME, 4) &&
+               VerifyField<float>(verifier, VT_WIDTH, 4) && VerifyField<float>(verifier, VT_HEIGHT, 4) &&
+               VerifyOffset(verifier, VT_ASSETS) && verifier.VerifyVector(assets()) &&
+               verifier.VerifyVectorOfTables(assets()) && verifier.EndTable();
+    }
+};
+
+struct AnimationsBuilder {
+    typedef Animations Table;
+    ::flatbuffers::FlatBufferBuilder &fbb_;
+    ::flatbuffers::uoffset_t start_;
+    void add_version(::flatbuffers::Offset<::flatbuffers::String> version)
+    {
+        fbb_.AddOffset(Animations::VT_VERSION, version);
+    }
+    void add_layers_type(::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> layers_type)
+    {
+        fbb_.AddOffset(Animations::VT_LAYERS_TYPE, layers_type);
+    }
+    void add_layers(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<void>>> layers)
+    {
+        fbb_.AddOffset(Animations::VT_LAYERS, layers);
+    }
+    void add_frame_rate(float frame_rate)
+    {
+        fbb_.AddElement<float>(Animations::VT_FRAME_RATE, frame_rate, 0.0f);
+    }
+    void add_start_frame(float start_frame)
+    {
+        fbb_.AddElement<float>(Animations::VT_START_FRAME, start_frame, 0.0f);
+    }
+    void add_end_frame(float end_frame)
+    {
+        fbb_.AddElement<float>(Animations::VT_END_FRAME, end_frame, 0.0f);
+    }
+    void add_width(float width)
+    {
+        fbb_.AddElement<float>(Animations::VT_WIDTH, width, 0.0f);
+    }
+    void add_height(float height)
+    {
+        fbb_.AddElement<float>(Animations::VT_HEIGHT, height, 0.0f);
+    }
+    void add_assets(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::Asset>>> assets)
+    {
+        fbb_.AddOffset(Animations::VT_ASSETS, assets);
+    }
+    explicit AnimationsBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb)
+    {
+        start_ = fbb_.StartTable();
+    }
+    ::flatbuffers::Offset<Animations> Finish()
+    {
+        const auto end = fbb_.EndTable(start_);
+        auto o = ::flatbuffers::Offset<Animations>(end);
+        fbb_.Required(o, Animations::VT_LAYERS_TYPE);
+        fbb_.Required(o, Animations::VT_LAYERS);
+        return o;
+    }
+};
+
+inline ::flatbuffers::Offset<Animations> CreateAnimations(
+    ::flatbuffers::FlatBufferBuilder &_fbb, ::flatbuffers::Offset<::flatbuffers::String> version = 0,
+    ::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> layers_type = 0,
+    ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<void>>> layers = 0, float frame_rate = 0.0f,
+    float start_frame = 0.0f, float end_frame = 0.0f, float width = 0.0f, float height = 0.0f,
+    ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<LottieFlatBuffer::Asset>>> assets = 0)
+{
+    AnimationsBuilder builder_(_fbb);
+    builder_.add_assets(assets);
+    builder_.add_height(height);
+    builder_.add_width(width);
+    builder_.add_end_frame(end_frame);
+    builder_.add_start_frame(start_frame);
+    builder_.add_frame_rate(frame_rate);
+    builder_.add_layers(layers);
+    builder_.add_layers_type(layers_type);
+    builder_.add_version(version);
+    return builder_.Finish();
+}
+
+inline ::flatbuffers::Offset<Animations> CreateAnimationsDirect(
+    ::flatbuffers::FlatBufferBuilder &_fbb, const char *version = nullptr,
+    const std::vector<uint8_t> *layers_type = nullptr, const std::vector<::flatbuffers::Offset<void>> *layers = nullptr,
+    float frame_rate = 0.0f, float start_frame = 0.0f, float end_frame = 0.0f, float width = 0.0f, float height = 0.0f,
+    const std::vector<::flatbuffers::Offset<LottieFlatBuffer::Asset>> *assets = nullptr)
+{
+    auto version__ = version ? _fbb.CreateString(version) : 0;
+    auto layers_type__ = layers_type ? _fbb.CreateVector<uint8_t>(*layers_type) : 0;
+    auto layers__ = layers ? _fbb.CreateVector<::flatbuffers::Offset<void>>(*layers) : 0;
+    auto assets__ = assets ? _fbb.CreateVector<::flatbuffers::Offset<LottieFlatBuffer::Asset>>(*assets) : 0;
+    return LottieFlatBuffer::CreateAnimations(_fbb, version__, layers_type__, layers__, frame_rate, start_frame,
+                                              end_frame, width, height, assets__);
+}
+
+inline bool VerifyFloatProp(::flatbuffers::Verifier &verifier, const void *obj, FloatProp type)
+{
+    switch (type) {
+        case FloatProp_NONE: {
+            return true;
+        }
+        case FloatProp_frames: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::FloatFrameArray *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        case FloatProp_value: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::FloatScalar *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        default:
+            return true;
+    }
+}
+
+inline bool VerifyFloatPropVector(::flatbuffers::Verifier &verifier,
+                                  const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
+                                  const ::flatbuffers::Vector<uint8_t> *types)
+{
+    if (!values || !types)
+        return !values && !types;
+    if (values->size() != types->size())
+        return false;
+    for (::flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+        if (!VerifyFloatProp(verifier, values->Get(i), types->GetEnum<FloatProp>(i))) {
+            return false;
+        }
+    }
+    return true;
+}
+
+inline bool VerifyIntegerProp(::flatbuffers::Verifier &verifier, const void *obj, IntegerProp type)
+{
+    switch (type) {
+        case IntegerProp_NONE: {
+            return true;
+        }
+        case IntegerProp_frames: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::IntegerFrameArray *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        case IntegerProp_value: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::IntegerScalar *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        default:
+            return true;
+    }
+}
+
+inline bool VerifyIntegerPropVector(::flatbuffers::Verifier &verifier,
+                                    const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
+                                    const ::flatbuffers::Vector<uint8_t> *types)
+{
+    if (!values || !types)
+        return !values && !types;
+    if (values->size() != types->size())
+        return false;
+    for (::flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+        if (!VerifyIntegerProp(verifier, values->Get(i), types->GetEnum<IntegerProp>(i))) {
+            return false;
+        }
+    }
+    return true;
+}
+
+inline bool VerifyVectorProp(::flatbuffers::Verifier &verifier, const void *obj, VectorProp type)
+{
+    switch (type) {
+        case VectorProp_NONE: {
+            return true;
+        }
+        case VectorProp_frames: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::VectorFrameArray *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        case VectorProp_value: {
+            return verifier.VerifyField<LottieFlatBuffer::Point>(static_cast<const uint8_t *>(obj), 0, 4);
+        }
+        default:
+            return true;
+    }
+}
+
+inline bool VerifyVectorPropVector(::flatbuffers::Verifier &verifier,
+                                   const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
+                                   const ::flatbuffers::Vector<uint8_t> *types)
+{
+    if (!values || !types)
+        return !values && !types;
+    if (values->size() != types->size())
+        return false;
+    for (::flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+        if (!VerifyVectorProp(verifier, values->Get(i), types->GetEnum<VectorProp>(i))) {
+            return false;
+        }
+    }
+    return true;
+}
+
+inline bool VerifyColorProp(::flatbuffers::Verifier &verifier, const void *obj, ColorProp type)
+{
+    switch (type) {
+        case ColorProp_NONE: {
+            return true;
+        }
+        case ColorProp_frames: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::ColorFrameArray *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        case ColorProp_color: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::Color24Scalar *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        default:
+            return true;
+    }
+}
+
+inline bool VerifyColorPropVector(::flatbuffers::Verifier &verifier,
+                                  const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
+                                  const ::flatbuffers::Vector<uint8_t> *types)
+{
+    if (!values || !types)
+        return !values && !types;
+    if (values->size() != types->size())
+        return false;
+    for (::flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+        if (!VerifyColorProp(verifier, values->Get(i), types->GetEnum<ColorProp>(i))) {
+            return false;
+        }
+    }
+    return true;
+}
+
+inline bool VerifyGradientProp(::flatbuffers::Verifier &verifier, const void *obj, GradientProp type)
+{
+    switch (type) {
+        case GradientProp_NONE: {
+            return true;
+        }
+        case GradientProp_frames: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::GradientFrameArray *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        case GradientProp_value: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::Gradient *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        default:
+            return true;
+    }
+}
+
+inline bool VerifyGradientPropVector(::flatbuffers::Verifier &verifier,
+                                     const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
+                                     const ::flatbuffers::Vector<uint8_t> *types)
+{
+    if (!values || !types)
+        return !values && !types;
+    if (values->size() != types->size())
+        return false;
+    for (::flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+        if (!VerifyGradientProp(verifier, values->Get(i), types->GetEnum<GradientProp>(i))) {
+            return false;
+        }
+    }
+    return true;
+}
+
+inline bool VerifyBezierDataProp(::flatbuffers::Verifier &verifier, const void *obj, BezierDataProp type)
+{
+    switch (type) {
+        case BezierDataProp_NONE: {
+            return true;
+        }
+        case BezierDataProp_frames: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::BezierDataFrameArray *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        case BezierDataProp_value: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::BezierData *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        default:
+            return true;
+    }
+}
+
+inline bool VerifyBezierDataPropVector(::flatbuffers::Verifier &verifier,
+                                       const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
+                                       const ::flatbuffers::Vector<uint8_t> *types)
+{
+    if (!values || !types)
+        return !values && !types;
+    if (values->size() != types->size())
+        return false;
+    for (::flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+        if (!VerifyBezierDataProp(verifier, values->Get(i), types->GetEnum<BezierDataProp>(i))) {
+            return false;
+        }
+    }
+    return true;
+}
+
+inline bool VerifyPositionProp(::flatbuffers::Verifier &verifier, const void *obj, PositionProp type)
+{
+    switch (type) {
+        case PositionProp_NONE: {
+            return true;
+        }
+        case PositionProp_frames: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::PositionFrameArray *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        case PositionProp_value: {
+            return verifier.VerifyField<LottieFlatBuffer::Point>(static_cast<const uint8_t *>(obj), 0, 4);
+        }
+        default:
+            return true;
+    }
+}
+
+inline bool VerifyPositionPropVector(::flatbuffers::Verifier &verifier,
+                                     const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
+                                     const ::flatbuffers::Vector<uint8_t> *types)
+{
+    if (!values || !types)
+        return !values && !types;
+    if (values->size() != types->size())
+        return false;
+    for (::flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+        if (!VerifyPositionProp(verifier, values->Get(i), types->GetEnum<PositionProp>(i))) {
+            return false;
+        }
+    }
+    return true;
+}
+
+inline bool VerifyGraphicElement(::flatbuffers::Verifier &verifier, const void *obj, GraphicElement type)
+{
+    switch (type) {
+        case GraphicElement_NONE: {
+            return true;
+        }
+        case GraphicElement_EllipseShape: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::EllipseShape *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        case GraphicElement_RectShape: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::RectShape *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        case GraphicElement_PathShape: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::PathShape *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        case GraphicElement_FillStyle: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::FillStyle *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        case GraphicElement_StrokeStyle: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::StrokeStyle *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        case GraphicElement_GradientFillStyle: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::GradientFillStyle *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        case GraphicElement_GradientStrokeStyle: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::GradientStrokeStyle *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        case GraphicElement_TransformShape: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::TransformShape *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        case GraphicElement_TrimPath: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::TrimPath *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        case GraphicElement_GroupShape: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::GroupShape *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        default:
+            return true;
+    }
+}
+
+inline bool VerifyGraphicElementVector(::flatbuffers::Verifier &verifier,
+                                       const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
+                                       const ::flatbuffers::Vector<uint8_t> *types)
+{
+    if (!values || !types)
+        return !values && !types;
+    if (values->size() != types->size())
+        return false;
+    for (::flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+        if (!VerifyGraphicElement(verifier, values->Get(i), types->GetEnum<GraphicElement>(i))) {
+            return false;
+        }
+    }
+    return true;
+}
+
+inline bool VerifyLayer(::flatbuffers::Verifier &verifier, const void *obj, Layer type)
+{
+    switch (type) {
+        case Layer_NONE: {
+            return true;
+        }
+        case Layer_PrecompositionLayer: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::PrecompositionLayer *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        case Layer_SolidLayer: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::SolidLayer *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        case Layer_ImageLayer: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::ImageLayer *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        case Layer_NullLayer: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::NullLayer *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        case Layer_ShapeLayer: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::ShapeLayer *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        case Layer_TextLayer: {
+            auto ptr = reinterpret_cast<const LottieFlatBuffer::TextLayer *>(obj);
+            return verifier.VerifyTable(ptr);
+        }
+        default:
+            return true;
+    }
+}
+
+inline bool VerifyLayerVector(::flatbuffers::Verifier &verifier,
+                              const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
+                              const ::flatbuffers::Vector<uint8_t> *types)
+{
+    if (!values || !types)
+        return !values && !types;
+    if (values->size() != types->size())
+        return false;
+    for (::flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+        if (!VerifyLayer(verifier, values->Get(i), types->GetEnum<Layer>(i))) {
+            return false;
+        }
+    }
+    return true;
+}
+
+inline const LottieFlatBuffer::Animations *GetAnimations(const void *buf)
+{
+    return ::flatbuffers::GetRoot<LottieFlatBuffer::Animations>(buf);
+}
+
+inline const LottieFlatBuffer::Animations *GetSizePrefixedAnimations(const void *buf)
+{
+    return ::flatbuffers::GetSizePrefixedRoot<LottieFlatBuffer::Animations>(buf);
+}
+
+inline bool VerifyAnimationsBuffer(::flatbuffers::Verifier &verifier)
+{
+    return verifier.VerifyBuffer<LottieFlatBuffer::Animations>(nullptr);
+}
+
+inline bool VerifySizePrefixedAnimationsBuffer(::flatbuffers::Verifier &verifier)
+{
+    return verifier.VerifySizePrefixedBuffer<LottieFlatBuffer::Animations>(nullptr);
+}
+
+inline void FinishAnimationsBuffer(::flatbuffers::FlatBufferBuilder &fbb,
+                                   ::flatbuffers::Offset<LottieFlatBuffer::Animations> root)
+{
+    fbb.Finish(root);
+}
+
+inline void FinishSizePrefixedAnimationsBuffer(::flatbuffers::FlatBufferBuilder &fbb,
+                                               ::flatbuffers::Offset<LottieFlatBuffer::Animations> root)
+{
+    fbb.FinishSizePrefixed(root);
+}
+
+}  // namespace LottieFlatBuffer
+
+#endif  // LOTT_FLATBUFFER_H
diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_image_layer.h b/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_image_layer.h
new file mode 100644 (file)
index 0000000..8d9f585
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025. All rights reserved.
+ * Description: Lottie
+ * Author: Hisi Graphic Team
+ * Created: 2025-6
+ */
+
+#ifndef LOTT_IMAGE_LAYER_H
+#define LOTT_IMAGE_LAYER_H
+
+#include "lottie/lott_layer.h"
+#include "gfx_utils/image_info.h"
+
+namespace OHOS {
+
+class LottImageLayer : public LottLayer {
+public:
+    LottImageLayer();
+    virtual ~LottImageLayer();
+
+    bool UpdateLottLayer(float frameNo) override;
+    void DrawLottLayer(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea,
+        const Matrix3<float>& matrix, uint8_t opa) override;
+
+    uint32_t resId_ = 0;
+    uint32_t offset_ = 0;
+    std::string filePath_;
+    ImageInfo* imgInfo_ = nullptr;
+};
+}
+#endif // LOTT_IMAGE_LAYER_H
\ No newline at end of file
diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_interpolator.h b/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_interpolator.h
new file mode 100644 (file)
index 0000000..8efd4b9
--- /dev/null
@@ -0,0 +1,56 @@
+/*\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved.\r
+ * Description: LottInterpolator\r
+ * Author: Hisi Graphic Team\r
+ * Created: 2025-5\r
+ */\r
+\r
+#ifndef LOTT_INTERPOLATOR_H\r
+#define LOTT_INTERPOLATOR_H\r
+\r
+#include <math.h>\r
+#include "gfx_utils/graphic_math.h"\r
+#include "gfx_utils/heap_base.h"\r
+#include "gfx_utils/vector.h"\r
+#include "lottie/lott_math.h"\r
+\r
+namespace OHOS {\r
+\r
+static constexpr int32_t SPLINE_TABLE_SIZE =  11;\r
+static constexpr float NEWTON_MIN_SLOPE =  0.02f;\r
+static constexpr int32_t NEWTON_ITERATIONS =  4;\r
+static constexpr float SUBDIVISION_PRECISION =  0.0000001f;\r
+static constexpr int32_t SUBDIVISION_MAX_ITERATIONS =  10;\r
+\r
+class LottInterpolator : public HeapBase {\r
+public:\r
+    LottInterpolator() {}\r
+    float Progress(float time);\r
+    void SetTangent(Vector2<float>& inTangent, Vector2<float>& outTangent);\r
+\r
+    Vector2<float> inTangent;\r
+    Vector2<float> outTangent;\r
+\r
+private:\r
+    static constexpr float SAMPLE_STEP_SIZE = 1.0f / float(SPLINE_TABLE_SIZE - 1);\r
+    float samples[SPLINE_TABLE_SIZE];\r
+\r
+    float GetTForX(float aX);\r
+    float BinarySubdivide(float aX, float aA, float aB);\r
+    float NewtonRaphsonIterate(float aX, float aGuessT);\r
+};\r
+\r
+class LottInterpolatorFactory : public HeapBase {\r
+public:\r
+    LottInterpolatorFactory() {}\r
+    static LottInterpolatorFactory& GetInstance(void);\r
+    LottInterpolator* GetInterpolator(Vector2<float>& in, Vector2<float>& out);\r
+    void ClearAll();\r
+\r
+    Graphic::Vector<LottInterpolator*> interpolators_;\r
+};\r
+\r
+}\r
+\r
+#endif  // LOTT_INTERPOLATOR_H\r
+\r
diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_layer.h b/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_layer.h
new file mode 100644 (file)
index 0000000..f1e98ff
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025. All rights reserved.
+ * Description: Lottie
+ * Author: Hisi Graphic Team
+ * Created: 2025-6
+ */
+
+#ifndef LOTT_LAYER_H
+#define LOTT_LAYER_H
+
+#include <string>
+#include "lottie/lott_paint.h"
+#include "lottie/lott_property.h"
+#include "lottie/lott_transform.h"
+#include "engines/gfx/gfx_engine_manager.h"
+#include "gfx_utils/rect.h"
+#include "gfx_utils/graphic_buffer.h"
+
+namespace OHOS {
+enum class LottLayerType {
+    PRECOMP_LAYER = 0,
+    SOLID_LAYER,
+    IMAGE_LAYER,
+    NULL_LAYER,
+    SHAPE_LAYER,
+    TEXT_LAYER,
+};
+
+class LottLayer : public HeapBase {
+public:
+    LottLayer();
+    virtual ~LottLayer();
+
+    virtual bool UpdateLottLayer(float frameNo);
+    virtual void DrawLottLayer(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea,
+        const Matrix3<float>& matrix, uint8_t opa) {};
+    LottLayerType GetType();
+
+    float width_ = 0.0f;
+    float height_ = 0.0f;
+    float inFrame_ = 0.0f;
+    float outFrame_ = 0.0f;
+    float startFrame_ = 0.0f;
+    int16_t id_ = -1;
+    int16_t pId_ = -1;
+    LottLayer* parent_ = nullptr;
+
+    uint8_t opa_ = LOTT_OPA_MAX;
+    Matrix3<float> matrix_;
+
+    std::string name_;
+    BlendMode blendMode_ = BlendMode::BLEND_MODE;
+    LottTransform* transform_ = nullptr;
+
+protected:
+    void ResetUpdateState();
+    bool isUpdated_ = false;
+    bool isValidFrame_ = false;
+    LottLayerType type_ = LottLayerType::NULL_LAYER;
+};
+}
+#endif // LOTT_LAYER_H
\ No newline at end of file
diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_math.h b/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_math.h
new file mode 100644 (file)
index 0000000..fea0746
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved.
+ * Description: Graphic Math Ext
+ * Author: Hisi Graphic Team
+ * Created: 2025-5
+ */
+
+#ifndef GRAPHIC_MATH_EXT_H
+#define GRAPHIC_MATH_EXT_H
+
+#include <algorithm>
+#include <cmath>
+#include "gfx_utils/heap_base.h"
+#include "gfx_utils/graphic_math.h"
+
+namespace OHOS {
+
+static constexpr float MATH_PI = 3.14159265358979323846f;
+static constexpr float BEZIER_EPSILON = 1e-2f;
+static constexpr float ANT2_COEFF1 = -0.0464964749f;
+static constexpr float ANT2_COEFF2 = 0.15931422f;
+static constexpr float ANT2_COEFF3 = 0.327622764f;
+static constexpr float ANT2_COEFF4 = 1.57079637f;
+static constexpr float ANT2_COEFF5 = 3.14159274f;
+static constexpr float CONST_COEFF_1 = 1.0f;
+static constexpr float CONST_COEFF_2 = 2.0f;
+static constexpr float CONST_COEFF_3 = 3.0f;
+static constexpr float CONST_COEFF_6 = 6.0f;
+static constexpr float RED2DEG_COEFF = 180.0f;
+
+class Bezier : public HeapBase {
+public:
+    Bezier() {}
+    Bezier(Vector2<float> start, Vector2<float> ctrl1, Vector2<float> ctrl2, Vector2<float> end);
+    void Split(float t, Bezier& left);
+    void Split(Bezier& left, Bezier& right) const;
+    void Split(float at, Bezier& left, Bezier& right) const;
+    float Length() const;
+    float LengthApprox() const;
+    float At(float at, float length) const;
+    float AtApprox(float at, float length) const;
+    Vector2<float> At(float t) const;
+    float Angle(float t) const;
+
+    Vector2<float> start_;
+    Vector2<float> ctrl1_;
+    Vector2<float> ctrl2_;
+    Vector2<float> end_;
+};
+
+template <typename T>
+inline T Lerp(const T &start, const T &end, float t)
+{
+    return static_cast<T>(start + (end - start) * t);
+}
+
+template<typename T>
+uint32_t Bsearch(T* frames, float frameNo)
+{
+    int32_t low = 0;
+    int32_t high = int32_t(frames->Size()) - 1;
+
+    while (low <= high) {
+        auto mid = low + (high - low) / 2;
+        auto frame = frames->Begin()[mid];
+        if (frameNo < frame->time) high = mid - 1;
+        else low = mid + 1;
+    }
+    if (high < low) low = high;
+    if (low < 0) low = 0;
+    return low;
+}
+
+inline float ConstA(float aA1, float aA2)
+{
+    return CONST_COEFF_1 - CONST_COEFF_3 * aA2 + CONST_COEFF_3 * aA1;
+}
+inline float ConstB(float aA1, float aA2)
+{
+    return CONST_COEFF_3 * aA2 - CONST_COEFF_6 * aA1;
+}
+inline float ConstC(float aA1)
+{
+    return CONST_COEFF_3 * aA1;
+}
+
+inline float GetSlope(float t, float aA1, float aA2)
+{
+    return CONST_COEFF_3 * ConstA(aA1, aA2) * t * t + CONST_COEFF_2 * ConstB(aA1, aA2) * t + ConstC(aA1);
+}
+
+inline float CalcBezier(float t, float aA1, float aA2)
+{
+    return ((ConstA(aA1, aA2) * t + ConstB(aA1, aA2)) * t + ConstC(aA1)) * t;
+}
+
+inline float Rad2deg(float radian)
+{
+    return radian * (RED2DEG_COEFF / MATH_PI);
+}
+
+inline float Atan2(float y, float x)
+{
+    if (y == 0.0f && x == 0.0f) return 0.0f;
+    auto a = std::min(fabsf(x), fabsf(y)) / std::max(fabsf(x), fabsf(y));
+    auto s = a * a;
+    auto r = ((ANT2_COEFF1 * s + ANT2_COEFF2) * s - ANT2_COEFF3) * s * a + a;
+    if (fabsf(y) > fabsf(x)) r = ANT2_COEFF4 - r;
+    if (x < 0) r = ANT2_COEFF5 - r;
+    if (y < 0) return -r;
+    return r;
+}
+
+} // namespace OHOS
+#endif // GRAPHIC_MATH_EXT_H
+/**
+ * @}
+ */
diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_null_layer.h b/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_null_layer.h
new file mode 100644 (file)
index 0000000..2c1af51
--- /dev/null
@@ -0,0 +1,23 @@
+/*\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025. All rights reserved.\r
+ * Description: Lottie\r
+ * Author: Hisi Graphic Team\r
+ * Created: 2025-6\r
+ */\r
+\r
+#ifndef LOTT_NULL_LAYER_H\r
+#define LOTT_NULL_LAYER_H\r
+\r
+#include "lottie/lott_layer.h"\r
+\r
+namespace OHOS {\r
+\r
+class LottNullLayer : public LottLayer {\r
+public:\r
+    LottNullLayer()\r
+    {\r
+        type_ = LottLayerType::NULL_LAYER;\r
+    }\r
+};\r
+}\r
+#endif // LOTT_NULL_LAYER_H
\ No newline at end of file
diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_paint.h b/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_paint.h
new file mode 100644 (file)
index 0000000..f552c09
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025. All rights reserved.
+ * Description: Lottie
+ * Author: Hisi Graphic Team
+ * Created: 2025-6
+ */
+
+#ifndef LOTT_PAINT_H
+#define LOTT_PAINT_H
+
+#include "components/ui_view.h"
+#include "common/graphic_hardware_types.h"
+#include "gfx_utils/style.h"
+#include "gfx_utils/heap_base.h"
+#include "lottie/lott_property.h"
+#include "hals/gralloc_engines.h"
+
+namespace OHOS {
+const uint8_t LOTT_OPA_MAX = 100; // lott opa range is [0, 100]
+const float LOTT_OPA_PCT_MULTIPLIER = 0.01f;
+
+class LottGradient : public HeapBase {
+public:
+    GradientSpread spread_;
+    LottVectorProp start_;
+    LottVectorProp end_;
+    LottFloatProp height_;
+    LottFloatProp angle_;
+    LottIntegerProp opa_;
+    LottColorStopsProp stops_;
+    GradientType type_; // only support linear and radial
+
+    void Update(float frameNo);
+};
+
+class LottFill : public HeapBase {
+public:
+    LottFill();
+    virtual ~LottFill();
+
+    LottIntegerProp opa_;
+    LottColorProp color_;
+    FillRule fillRule_;
+    LottGradient* gradient_ = nullptr;
+
+    void Update(float frameNo);
+};
+
+class LottStroke : public HeapBase {
+public:
+    LottStroke();
+    virtual ~LottStroke();
+
+    LottIntegerProp opa_;
+    LottColorProp color_;
+    LottFloatProp width_;
+    float miterLimit_;
+    JoinType join_;
+    CapType cap_;
+    LottGradient* gradient_ = nullptr;
+
+    void Update(float frameNo);
+};
+
+class LottPaint : public HeapBase {
+public:
+    LottPaint();
+    virtual ~LottPaint();
+    void Update(float frameNo);
+
+    LottFill* fill_ = nullptr;
+    LottStroke* stroke_ = nullptr;
+};
+
+struct LottGradientValue {
+    float startX;
+    float startY;
+    float endX;
+    float endY;
+    float height;
+    float angle;
+    ColorStop* stops = nullptr;
+    uint16_t stopNum;
+    GradientType type;
+
+    ~LottGradientValue()
+    {
+        if (stops != nullptr) {
+            UIFree(stops);
+        }
+    }
+};
+
+struct LottFillValue {
+    uint32_t color;
+    FillRule fillRule;
+    LottGradientValue* gradient = nullptr;
+
+    ~LottFillValue()
+    {
+        if (gradient != nullptr) {
+            delete gradient;
+        }
+    }
+};
+
+struct LottStrokeValue {
+    uint32_t color;
+    float width;
+    float miterLimit;
+    JoinType join;
+    CapType cap;
+    LottGradientValue* gradient = nullptr;
+
+    ~LottStrokeValue()
+    {
+        if (gradient != nullptr) {
+            delete gradient;
+        }
+    }
+};
+
+struct LottPaintValue {
+    LottFillValue* fill = nullptr;
+    LottStrokeValue* stroke = nullptr;
+
+    ~LottPaintValue()
+    {
+        if (fill != nullptr) {
+            delete fill;
+        }
+
+        if (stroke != nullptr) {
+            delete stroke;
+        }
+    }
+
+    uint32_t GetMixedColor(uint32_t color, uint8_t opa)
+    {
+        const uint8_t alphaShift = 24; // 24: alpha shift
+        uint8_t alpha = (color >> alphaShift) * (opa * LOTT_OPA_PCT_MULTIPLIER);
+        uint32_t mixedColor = (alpha << alphaShift) | (color & 0x00FFFFFF);
+        return mixedColor;
+    }
+
+    void ConvertGradient(LottGradientValue* value, LottGradient* gradient, uint8_t opa)
+    {
+        value->startX = gradient->start_.value_.x_;
+        value->startY = gradient->start_.value_.y_;
+        value->endX = gradient->end_.value_.x_;
+        value->endY = gradient->end_.value_.y_;
+        value->height = gradient->height_.value_;
+        value->angle = gradient->angle_.value_;
+
+        if (gradient->stops_.value_.Size() == 0) {
+            return;
+        }
+
+        Graphic::Vector<ColorStop>* colorStops = &gradient->stops_.value_;
+
+        if (value->stops != nullptr && value->stopNum != colorStops->Size()) {
+            UIFree(value->stops);
+            value->stops = nullptr;
+            value->stopNum = 0;
+        }
+
+        uint32_t size = sizeof(ColorStop) * colorStops->Size();
+        if (value->stops == nullptr) {
+            value->stops = static_cast<ColorStop*>(UIMalloc(size));
+            if (value->stops == nullptr) {
+                return;
+            }
+        }
+
+        memcpy_s(value->stops, size, colorStops->Begin(), size);
+        value->stopNum = colorStops->Size();
+
+        for (uint32_t i = 0; i < value->stopNum; i++) {
+            value->stops[i].color = GetMixedColor(value->stops[i].color, opa);
+        }
+        value->type = gradient->type_;
+    }
+
+    bool FillValue(LottFill* lottFill, uint8_t opa)
+    {
+        if (lottFill == nullptr) {
+            return false;
+        }
+
+        if (fill == nullptr) {
+            fill = new LottFillValue;
+            if (fill == nullptr) {
+                return false;
+            }
+            fill->gradient = nullptr;
+        }
+
+        uint8_t lottOpa = lottFill->opa_.value_ * opa * LOTT_OPA_PCT_MULTIPLIER;
+        fill->color = GetMixedColor(lottFill->color_.value_.full, lottOpa);
+        fill->fillRule = lottFill->fillRule_;
+
+        if (lottFill->gradient_ != nullptr) {
+            if (fill->gradient == nullptr) {
+                fill->gradient = new LottGradientValue;
+                if (fill->gradient == nullptr) {
+                    delete fill;
+                    fill = nullptr;
+                    return false;
+                }
+                fill->gradient->stops = nullptr;
+                fill->gradient->stopNum = 0;
+            }
+            ConvertGradient(fill->gradient, lottFill->gradient_, opa);
+        }
+        return true;
+    }
+
+    bool StrokeValue(LottStroke* lottStroke, uint8_t opa)
+    {
+        if (lottStroke == nullptr) {
+            return false;
+        }
+
+        if (stroke == nullptr) {
+            stroke = new LottStrokeValue;
+            if (stroke == nullptr) {
+                return false;
+            }
+            stroke->gradient = nullptr;
+        }
+
+        uint8_t lottOpa = lottStroke->opa_.value_ * opa * LOTT_OPA_PCT_MULTIPLIER;
+        stroke->color = GetMixedColor(lottStroke->color_.value_.full, lottOpa);
+        stroke->width = lottStroke->width_.value_;
+        stroke->miterLimit = lottStroke->miterLimit_;
+        stroke->join = lottStroke->join_;
+        stroke->cap = lottStroke->cap_;
+
+        if (lottStroke->gradient_ != nullptr) {
+            if (stroke->gradient == nullptr) {
+                stroke->gradient = new LottGradientValue;
+                if (stroke->gradient == nullptr) {
+                    delete stroke;
+                    stroke = nullptr;
+                    return false;
+                }
+                stroke->gradient->stops = nullptr;
+                stroke->gradient->stopNum = 0;
+            }
+            ConvertGradient(stroke->gradient, lottStroke->gradient_, opa);
+        }
+        return true;
+    }
+
+    bool UpdatePaint(LottPaint* paint, uint8_t opa)
+    {
+        if (paint == nullptr) {
+            return false;
+        }
+        FillValue(paint->fill_, opa);
+        StrokeValue(paint->stroke_, opa);
+        return true;
+    }
+
+    bool DeepCopyGradient(const LottGradientValue* src, LottGradientValue*& dst)
+    {
+        if (src->stops == nullptr) {
+            return false;
+        }
+        if (dst == nullptr) {
+            dst = new LottGradientValue;
+            if (dst == nullptr) {
+                return false;
+            }
+            dst->stops = nullptr;
+            dst->stopNum = 0;
+        }
+
+        dst->startX = src->startX;
+        dst->startY = src->startY;
+        dst->endX = src->endX;
+        dst->endY = src->endY;
+        dst->height = src->height;
+        dst->angle = src->angle;
+        dst->type = src->type;
+
+        if ((dst->stops != nullptr) && (dst->stopNum != src->stopNum)) {
+            UIFree(dst->stops);
+            dst->stops = nullptr;
+            dst->stopNum = 0;
+        }
+
+        uint32_t size = sizeof(ColorStop) * src->stopNum;
+        if (dst->stops == nullptr) {
+            dst->stops = static_cast<ColorStop*>(UIMalloc(size));
+            if (dst->stops == nullptr) {
+                return false;
+            }
+        }
+        memcpy_s(dst->stops, size, src->stops, size);
+        dst->stopNum = src->stopNum;
+        return true;
+    }
+
+    bool DeepCopy(LottPaintValue& value)
+    {
+        if (value.fill != nullptr) {
+            if (fill == nullptr) {
+                fill = new LottFillValue;
+                if (fill == nullptr) {
+                    return false;
+                }
+                fill->gradient = nullptr;
+            }
+
+            fill->color = value.fill->color;
+            fill->fillRule = value.fill->fillRule;
+
+            if (value.fill->gradient != nullptr) {
+                DeepCopyGradient(value.fill->gradient, fill->gradient);
+            }
+        }
+
+        if (value.stroke != nullptr) {
+            if (stroke == nullptr) {
+                stroke = new LottStrokeValue;
+                if (stroke == nullptr) {
+                    return false;
+                }
+                stroke->gradient = nullptr;
+            }
+
+            stroke->color = value.stroke->color;
+            stroke->width = value.stroke->width;
+            stroke->miterLimit = value.stroke->miterLimit;
+            stroke->join = value.stroke->join;
+            stroke->cap = value.stroke->cap;
+
+            if (value.stroke->gradient != nullptr) {
+                DeepCopyGradient(value.stroke->gradient, stroke->gradient);
+            }
+        }
+        return true;
+    }
+};
+
+}
+#endif // LOTT_PAINT_H
\ No newline at end of file
diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_parser.h b/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_parser.h
new file mode 100644 (file)
index 0000000..ecc095c
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025. All rights reserved.
+ * Description: Lottie
+ * Author: Hisi Graphic Team
+ * Created: 2025-6
+ */
+
+#ifndef LOTT_PARSER_H
+#define LOTT_PARSER_H
+#include "gfx_utils/heap_base.h"
+#include "lott_comp.h"
+#include "lott_flatbuffer.h"
+#include "lott_shape_group.h"
+
+namespace OHOS {
+
+class LottParser : public HeapBase {
+public:
+    LottParser() : buffer_(nullptr), offset_(0), fp_(nullptr), comp_(nullptr), hasError_(false) {}
+    ~LottParser() {}
+
+    LottComp* Parse(std::string file);
+
+private:
+    struct LottHeader {
+        uint32_t startFlag;
+        uint32_t version;
+        uint32_t bufferSize;
+    };
+
+    struct shapeGroup {
+        uint32_t fillIndex = 0;
+        uint32_t strokeindex = 0;
+        uint32_t transIndex = 0;
+        Graphic::Vector<uint32_t> shapes;
+    };
+
+    void* buffer_;
+    uint32_t offset_;
+    std::string file_;
+    FILE* fp_;
+    LottComp* comp_;
+    bool hasError_;
+    const ::flatbuffers::Vector< ::flatbuffers::Offset<LottieFlatBuffer::Asset>>* assets_;
+
+    void LoadFile();
+    void ParseLayers(const flatbuffers::Vector<::flatbuffers::Offset<void>>* layers,
+        const flatbuffers::Vector<uint8_t>* layers_type, Graphic::Vector<LottLayer*>& parent);
+    void ParseBaseLayer(const void* layer, LottLayer* lottLayer);
+    LottLayer* ParsePreComLayer(const void* layer);
+    LottLayer* ParseImageLayer(const void* layer);
+    LottLayer* ParseShapeLayer(const void* layer);
+    LottLayer* ParseNullLayer(const void* layer);
+    LottLayer* ParseSolidLayer(const void* layer);
+    LottLayer* ParseTextLayer(const void* layer);
+    LottTransform* ParseTransform(const LottieFlatBuffer::Transform* trans);
+
+    Graphic::Vector<shapeGroup>* BuildGroups(
+        const flatbuffers::Vector<::flatbuffers::Offset<void>>* shapes,
+        const flatbuffers::Vector<uint8_t>* shapes_type);
+
+    LottShapeGroup* BuildGroup(shapeGroup* group, const flatbuffers::Vector<::flatbuffers::Offset<void>>* shapes,
+        const flatbuffers::Vector<uint8_t>* shapes_type);
+    LottShape* ParseShape(const void* shape, uint8_t type);
+    LottShape* ParseGroup(const void* shape);
+    LottShape* ParseEllipse(const void* shape);
+    LottShape* ParseRect(const void* shape);
+    LottShape* ParsePath(const void* shape);
+    LottFill* ParseFill(const void* shape, uint8_t type);
+    LottStroke* ParseStroke(const void* shape, uint8_t type);
+    LottTransform* ParseTransShape(const void* shape);
+
+    void ParseSplitProp(const void* split, LottTransform::LottSplitPosition& lottSplit);
+    void ParsePositionProp(const void* value,  LottieFlatBuffer::PositionProp type, LottPositionProp& lottPosition);
+    void ParseFloatProp(const void* value, LottieFlatBuffer::FloatProp type, LottFloatProp& lottFloat);
+    void ParseIntegerProp(const void* value, LottieFlatBuffer::IntegerProp type, LottIntegerProp& lottInt);
+    void ParseBezierProp(const void* value, LottieFlatBuffer::BezierDataProp type, LottPathDataProp& lottBez);
+    void ParseVectorProp(const void* value, LottieFlatBuffer::VectorProp type, LottVectorProp& lottVec);
+    void ParseColorProp(const void* value, LottieFlatBuffer::ColorProp type, LottColorProp& lottColor);
+    void ParseGradientProp(const void* value, LottieFlatBuffer::GradientProp type, LottColorStopsProp& lottGradient);
+    void ParseBezierData(const LottieFlatBuffer::BezierData* bezData, Path& path);
+    void ParseColorStops(const LottieFlatBuffer::Gradient* gradient, Graphic::Vector<ColorStop>& colorStops);
+
+    void BuildHierarchy(Graphic::Vector<LottLayer*>& parent);
+};
+}
+#endif // LOTT_PARSER_H
+
diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_path.h b/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_path.h
new file mode 100644 (file)
index 0000000..cce29b0
--- /dev/null
@@ -0,0 +1,27 @@
+/*\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025. All rights reserved.\r
+ * Description: Lottie\r
+ * Author: Hisi Graphic Team\r
+ * Created: 2025-6\r
+ */\r
+\r
+#ifndef LOTT_PATH_H\r
+#define LOTT_PATH_H\r
+\r
+#include "lottie/lott_shape.h"\r
+#include "lottie/lott_property.h"\r
+\r
+namespace OHOS {\r
+\r
+class LottPath : public LottShape {\r
+public:\r
+    LottPath();\r
+    virtual ~LottPath();\r
+\r
+    void Update(LottShape* parent, float frameNo) override;\r
+    bool GetPathData(Path& path) override;\r
+\r
+    LottPathDataProp pathData_;\r
+};\r
+}\r
+#endif // LOTT_PATH_H
\ No newline at end of file
diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_precomp_layer.h b/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_precomp_layer.h
new file mode 100644 (file)
index 0000000..493e0c8
--- /dev/null
@@ -0,0 +1,26 @@
+/*\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025. All rights reserved.\r
+ * Description: Lottie\r
+ * Author: Hisi Graphic Team\r
+ * Created: 2025-6\r
+ */\r
+\r
+#ifndef LOTT_PRECOMP_LAYER_H\r
+#define LOTT_PRECOMP_LAYER_H\r
+\r
+#include "lottie/lott_layer.h"\r
+namespace OHOS {\r
+\r
+class LottPrecompLayer : public LottLayer {\r
+public:\r
+    LottPrecompLayer();\r
+    virtual ~LottPrecompLayer();\r
+\r
+    bool UpdateLottLayer(float frameNo) override;\r
+    void DrawLottLayer(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea,\r
+        const Matrix3<float>& matrix, uint8_t opa) override;\r
+\r
+    Graphic::Vector<LottLayer*> layers_;\r
+};\r
+}\r
+#endif // LOTT_PRECOMP_LAYER_H
\ No newline at end of file
diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_property.h b/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_property.h
new file mode 100644 (file)
index 0000000..68c509d
--- /dev/null
@@ -0,0 +1,190 @@
+/*\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved.\r
+ * Description: LottProperty\r
+ * Author: Hisi Graphic Team\r
+ * Created: 2025-5\r
+ */\r
+\r
+#ifndef LOTT_PROPERTY_H\r
+#define LOTT_PROPERTY_H\r
+\r
+#include "common/graphic_hardware_types.h"\r
+#include "gfx_utils/color.h"\r
+#include "gfx_utils/graphic_log.h"\r
+#include "gfx_utils/graphic_math.h"\r
+#include "gfx_utils/heap_base.h"\r
+#include "gfx_utils/vector.h"\r
+#include "lottie/lott_math.h"\r
+#include "lottie/lott_interpolator.h"\r
+\r
+namespace OHOS {\r
+\r
+struct LottFloatFrame {\r
+    float start; // keyframe value\r
+    float time; // frame number\r
+    LottInterpolator* interpolator;\r
+    bool hold = false; //  do not interpolate\r
+};\r
+\r
+class LottFloatProp : public HeapBase {\r
+public:\r
+    LottFloatProp(float v) : value_(v), frames_(nullptr) {}\r
+    LottFloatProp() : value_(0.0f), frames_(nullptr) {}\r
+    ~LottFloatProp();\r
+    LottFloatFrame* CreateFrame();\r
+    void UpdateValue(float frameNo);\r
+\r
+    float value_;\r
+\r
+private:\r
+    Graphic::Vector<LottFloatFrame*>* frames_;\r
+\r
+    float Interpolate(LottFloatFrame* frame, LottFloatFrame* nextFrame, float frameNo);\r
+};\r
+\r
+struct LottIntegerFrame {\r
+    int start; // keyframe value\r
+    float time; // frame number\r
+    LottInterpolator* interpolator;\r
+    bool hold = false; //  do not interpolate\r
+};\r
+\r
+class LottIntegerProp : public HeapBase {\r
+public:\r
+    LottIntegerProp(int v) : value_(v), frames_(nullptr) {}\r
+    LottIntegerProp() : value_(0), frames_(nullptr) {}\r
+    ~LottIntegerProp();\r
+    LottIntegerFrame* CreateFrame();\r
+    void UpdateValue(float frameNo);\r
+\r
+    int value_;\r
+\r
+private:\r
+    Graphic::Vector<LottIntegerFrame*>* frames_;\r
+\r
+    int Interpolate(LottIntegerFrame* frame, LottIntegerFrame* nextFrame, float frameNo);\r
+};\r
+\r
+struct LottColorFrame {\r
+    Color32 start; // keyframe value\r
+    float time; // frame number\r
+    LottInterpolator* interpolator;\r
+    bool hold = false; //  do not interpolate\r
+};\r
+\r
+class LottColorProp : public HeapBase {\r
+public:\r
+    LottColorProp(Color32 v) : value_(v), frames_(nullptr) {}\r
+    LottColorProp() : value_(Color::Black()), frames_(nullptr) {}\r
+    ~LottColorProp();\r
+    LottColorFrame* CreateFrame();\r
+    void UpdateValue(float frameNo);\r
+\r
+    Color32 value_;\r
+\r
+private:\r
+    Graphic::Vector<LottColorFrame*>* frames_;\r
+\r
+    Color32 Interpolate(LottColorFrame* frame, LottColorFrame* nextFrame, float frameNo);\r
+};\r
+\r
+struct LottVectorFrame {\r
+    Vector2<float> start; // keyframe value\r
+    float time; // frame number\r
+    LottInterpolator* interpolator;\r
+    bool hold = false; //  do not interpolate\r
+};\r
+\r
+class LottVectorProp : public HeapBase {\r
+public:\r
+    LottVectorProp(Vector2<float> v) : value_(v), frames_(nullptr) {}\r
+    LottVectorProp() : value_(Vector2<float>(0.0f, 0.0f)), frames_(nullptr) {}\r
+    ~LottVectorProp();\r
+    LottVectorFrame* CreateFrame();\r
+    void UpdateValue(float frameNo);\r
+\r
+    Vector2<float> value_;\r
+\r
+private:\r
+    Graphic::Vector<LottVectorFrame*>* frames_;\r
+\r
+    Vector2<float> Interpolate(LottVectorFrame* frame, LottVectorFrame* nextFrame, float frameNo);\r
+};\r
+\r
+struct LottColorStopsFrame {\r
+    Graphic::Vector<ColorStop> start; // keyframe value\r
+    float time; // frame number\r
+    LottInterpolator* interpolator;\r
+    bool hold = false; //  do not interpolate\r
+};\r
+\r
+class LottColorStopsProp : public HeapBase {\r
+public:\r
+    LottColorStopsProp(Graphic::Vector<ColorStop> v) : value_(v), frames_(nullptr) {}\r
+    LottColorStopsProp() : frames_(nullptr) {}\r
+    ~LottColorStopsProp();\r
+    LottColorStopsFrame* CreateFrame();\r
+    void UpdateValue(float frameNo);\r
+\r
+    Graphic::Vector<ColorStop> value_;\r
+\r
+private:\r
+    Graphic::Vector<LottColorStopsFrame*>* frames_;\r
+};\r
+\r
+struct LottPositionFrame {\r
+    Vector2<float> start; // keyframe value\r
+    float time; // frame number\r
+    LottInterpolator* interpolator;\r
+    float length;\r
+    bool hasTangent = false;\r
+    Vector2<float> outTangent, inTangent;\r
+    bool hold = false; //  do not interpolate\r
+};\r
+\r
+class LottPositionProp : public HeapBase {\r
+public:\r
+    LottPositionProp(Vector2<float> v) : value_(v), frames_(nullptr) {}\r
+    LottPositionProp() : value_(Vector2<float>(0.0f, 0.0f)), frames_(nullptr) {}\r
+    ~LottPositionProp();\r
+    LottPositionFrame* CreateFrame();\r
+    float GetAngle(float frameNo);\r
+    void UpdateValue(float frameNo);\r
+    void PrepareLength();\r
+\r
+    Vector2<float> value_;\r
+\r
+private:\r
+    Graphic::Vector<LottPositionFrame*>* frames_;\r
+\r
+    Vector2<float> Interpolate(LottPositionFrame* frame, LottPositionFrame* nextFrame, float frameNo);\r
+    float Angle(LottPositionFrame* frame, LottPositionFrame* nextFrame, float frameNo);\r
+};\r
+\r
+struct LottPathDataFrame {\r
+    Path start; // keyframe value\r
+    float time; // frame number\r
+    LottInterpolator* interpolator;\r
+    bool hold = false; //  do not interpolate\r
+};\r
+\r
+class LottPathDataProp : public HeapBase {\r
+public:\r
+    LottPathDataProp(Path v) : value_(v), innerPath_(Path{0, nullptr, 0, nullptr}), frames_(nullptr) {}\r
+    LottPathDataProp() : value_(Path{0, nullptr, 0, nullptr}),\r
+        innerPath_(Path{0, nullptr, 0, nullptr}), frames_(nullptr) {}\r
+    ~LottPathDataProp();\r
+    LottPathDataFrame* CreateFrame();\r
+    void UpdateValue(float frameNo);\r
+\r
+    Path value_;\r
+\r
+private:\r
+    Path innerPath_; // Store temporary path data to avoid allocate memory frequently\r
+    Graphic::Vector<LottPathDataFrame*>* frames_;\r
+\r
+    bool UpdatePath(LottPathDataFrame* curFrame, LottPathDataFrame* nextFrame, float time);\r
+};\r
+\r
+}\r
+#endif // LOTT_PROPERTY_H\r
diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_rect.h b/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_rect.h
new file mode 100644 (file)
index 0000000..5714588
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025. All rights reserved.
+ * Description: Lottie
+ * Author: Hisi Graphic Team
+ * Created: 2025-6
+ */
+
+#ifndef LOTT_RECT_H
+#define LOTT_RECT_H
+
+#include "lottie/lott_shape.h"
+#include "lottie/lott_property.h"
+#include "lottie/lott_shape_group.h"
+
+namespace OHOS {
+class LottRect : public LottShape {
+public:
+    LottRect();
+    virtual ~LottRect();
+
+    void Update(LottShape* parent, float frameNo) override;
+    bool GetPathData(Path& path) override;
+
+    LottPositionProp position_;
+    LottVectorProp size_;
+    LottFloatProp radius_;
+
+private:
+    bool GetRectPathWithoutRadius(float x, float y, float width, float height);
+};
+}
+#endif // LOTT_RECT_H
\ No newline at end of file
diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_shape.h b/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_shape.h
new file mode 100644 (file)
index 0000000..ea80e2e
--- /dev/null
@@ -0,0 +1,39 @@
+/*\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025. All rights reserved.\r
+ * Description: Lottie\r
+ * Author: Hisi Graphic Team\r
+ * Created: 2025-6\r
+ */\r
+\r
+#ifndef LOTT_SHAPE_H\r
+#define LOTT_SHAPE_H\r
+\r
+#include "common/graphic_hardware_types.h"\r
+#include "hals/gralloc_engines.h"\r
+\r
+namespace OHOS {\r
+enum class LottShapeType {\r
+    INVALID,\r
+    RECT,\r
+    ELLIPSE,\r
+    PATH,\r
+    SHAPE_GROUP,\r
+};\r
+\r
+class LottShape : public HeapBase {\r
+public:\r
+    LottShape();\r
+    virtual ~LottShape();\r
+\r
+    virtual void Update(LottShape* parent, float frameNo) {};\r
+    virtual bool GetPathData(Path& path);\r
+    LottShapeType GetType();\r
+\r
+protected:\r
+    void ClearPathInner();\r
+\r
+    Path path_ = {0};\r
+    LottShapeType type_ = LottShapeType::INVALID;\r
+};\r
+}\r
+#endif // LOTT_SHAPE_H
\ No newline at end of file
diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_shape_group.h b/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_shape_group.h
new file mode 100644 (file)
index 0000000..219de0b
--- /dev/null
@@ -0,0 +1,56 @@
+/*\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025. All rights reserved.\r
+ * Description: Lottie\r
+ * Author: Hisi Graphic Team\r
+ * Created: 2025-6\r
+ */\r
+\r
+#ifndef LOTT_SHAPE_GROUP_H\r
+#define LOTT_SHAPE_GROUP_H\r
+\r
+#include "lottie/lott_shape.h"\r
+#include "lottie/lott_paint.h"\r
+#include "lottie/lott_transform.h"\r
+#include "common/graphic_hardware_types.h"\r
+#include "gfx_utils/graphic_types.h"\r
+#include "display_vgu.h"\r
+\r
+namespace OHOS {\r
+\r
+struct LottRenderContext {\r
+    uint8_t opa;\r
+    Matrix3<float> matrix;\r
+    LottPaintValue paint;\r
+\r
+    void DeepCopy(LottRenderContext& ctx)\r
+    {\r
+        matrix = ctx.matrix;\r
+        paint.DeepCopy(ctx.paint);\r
+        opa = ctx.opa;\r
+    }\r
+};\r
+\r
+class LottShapeGroup : public LottShape {\r
+public:\r
+    LottShapeGroup();\r
+    virtual ~LottShapeGroup();\r
+\r
+    void Update(LottShape* parent, float frameNo) override;\r
+    void DrawLottShape(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea, LottRenderContext& ctx);\r
+    void Prepare();\r
+\r
+    Graphic::Vector<LottShape*> shapes_;\r
+    LottTransform* transform_ = nullptr;\r
+    Matrix3<float> matrix_;\r
+    bool mergeable_ = false;\r
+    LottPaint* paint_ = nullptr;\r
+\r
+private:\r
+    void DrawMerged(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea, VGUStrokeAttr& strokeAttr,\r
+        VGUFillAttr& fillAttr, VGUMatrix3& vguMat, bool strokeEnabled, bool fillEnabled);\r
+    bool UpdatePathInner();\r
+    Graphic::Vector<float> datas_;\r
+    Graphic::Vector<uint8_t> cmds_;\r
+};\r
+}\r
+#endif // LOTT_SHAPE_GROUP_H
\ No newline at end of file
diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_shape_layer.h b/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_shape_layer.h
new file mode 100644 (file)
index 0000000..65b32b9
--- /dev/null
@@ -0,0 +1,28 @@
+/*\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025. All rights reserved.\r
+ * Description: Lottie\r
+ * Author: Hisi Graphic Team\r
+ * Created: 2025-6\r
+ */\r
+\r
+#ifndef LOTT_SHAPE_LAYER_H\r
+#define LOTT_SHAPE_LAYER_H\r
+\r
+#include "lottie/lott_layer.h"\r
+#include "lottie/lott_shape_group.h"\r
+\r
+namespace OHOS {\r
+\r
+class LottShapeLayer : public LottLayer {\r
+public:\r
+    LottShapeLayer();\r
+    virtual ~LottShapeLayer();\r
+\r
+    bool UpdateLottLayer(float frameNo) override;\r
+    void DrawLottLayer(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea,\r
+        const Matrix3<float>& matrix, uint8_t opa) override;\r
+\r
+    Graphic::Vector<LottShapeGroup*> shapeGroups_;\r
+};\r
+}\r
+#endif // LOTT_SHAPE_LAYER_H
\ No newline at end of file
diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_solid_layer.h b/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_solid_layer.h
new file mode 100644 (file)
index 0000000..356891d
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025. All rights reserved.
+ * Description: Lottie
+ * Author: Hisi Graphic Team
+ * Created: 2025-6
+ */
+
+#ifndef LOTT_SOLID_LAYER_H
+#define LOTT_SOLID_LAYER_H
+
+#include "lottie/lott_layer.h"
+#include "common/graphic_hardware_types.h"
+
+namespace OHOS {
+
+class LottSolidLayer : public LottLayer {
+public:
+    LottSolidLayer();
+    virtual ~LottSolidLayer();
+
+    void DrawLottLayer(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea,
+        const Matrix3<float>& matrix, uint8_t opa) override;
+
+    uint32_t color_ = 0;
+    Path path_ = {0};
+};
+}
+#endif // LOTT_SOLID_LAYER_H
\ No newline at end of file
diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_transform.h b/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/lott_transform.h
new file mode 100644 (file)
index 0000000..540d409
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025. All rights reserved.
+ * Description: Lottie
+ * Author: Hisi Graphic Team
+ * Created: 2025-6
+ */
+
+#ifndef LOTT_TRANSFORM_H
+#define LOTT_TRANSFORM_H
+
+#include "lottie/lott_property.h"
+#include "display_vgu.h"
+#include "gfx_utils/graphic_math.h"
+#include "gfx_utils/heap_base.h"
+
+namespace OHOS {
+class LottTransform : public HeapBase {
+public:
+    LottTransform();
+    ~LottTransform();
+
+    struct LottSplitPosition {
+        LottFloatProp x;
+        LottFloatProp y;
+    };
+
+    LottSplitPosition* splitPosition_ = nullptr;
+    LottPositionProp position_;
+    LottFloatProp rotation_;
+    LottFloatProp skewAngle_;
+    LottFloatProp skewAxis_;
+    LottVectorProp scale_;
+    LottVectorProp anchor_;
+    LottIntegerProp opa_;
+
+    void Update(float frameNo, uint8_t& opa, Matrix3<float>& mat);
+    Matrix3<float> GetTransformMatrix();
+};
+}
+#endif // LOTT_TRANSFORM_H
\ No newline at end of file
diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/ui_lott_view.h b/code/sdk/middleware/services/gui/uikit/proprietary/include/lottie/ui_lott_view.h
new file mode 100644 (file)
index 0000000..476c8b8
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025. All rights reserved.
+ * Description: Lottie
+ * Author: Hisi Graphic Team
+ * Created: 2025-6
+ */
+
+#ifndef UI_LOTT_VIEW_H
+#define UI_LOTT_VIEW_H
+
+#include <string>
+#include "lottie/lott_comp.h"
+#include "animator/animator.h"
+#include "gfx_utils/vector.h"
+#include "gfx_utils/rect.h"
+#include "gfx_utils/graphic_buffer.h"
+
+namespace OHOS {
+
+class UILottView : public UIView {
+public:
+    UILottView();
+    virtual ~UILottView();
+    void OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea) override;
+
+    /**
+     * @brief Set lottie source file.
+     * @param file lottie source file.
+     * @return Returns <b>true</b> if set file successfully; returns <b> false</b> otherwise.
+     */
+    bool SetSrc(std::string file);
+
+    /**
+     * @brief  Start lottie animation.
+     */
+    void Start();
+
+    /**
+     * @brief  Pause lottie animation.
+     */
+    void Pause();
+
+    /**
+     * @brief  Resume lottie animation.
+     */
+    void Resume();
+
+    /**
+     * @brief  Stop lottie animation.
+     */
+    void Stop();
+
+private:
+
+    class LottAnimCb : public AnimatorCallback {
+    public:
+        LottAnimCb() {}
+        virtual ~LottAnimCb() {}
+        void Callback(UIView* view) override;
+
+        void SetEndValue(float value)
+        {
+            endValue_ = value;
+        }
+
+        void BindAnimator(Animator* anim)
+        {
+            anim_ = anim;
+        }
+
+        void Reset()
+        {
+            endValue_ = 0;
+            anim_ = nullptr;
+        }
+
+    private:
+        float endValue_ = 0;
+        Animator* anim_ = nullptr;
+    };
+
+    friend class LottAnimCb;
+
+    LottAnimCb lottAnimCb_;
+    Animator animator_;
+    LottComp* lottComp_ = nullptr;
+    std::string filePath_;
+};
+}
+#endif
index 2d79d54..f358979 100644 (file)
@@ -33,7 +33,7 @@
 #include "common/screen.h"\r
 #include "components/root_view.h"\r
 #ifdef SUPPORT_OHOSFWK\r
-#include "ui_screennotify.h"\r
+#include "screennotify/ui_screennotify.h"\r
 #endif\r
 #ifdef SUPPORT_GPU_JPEG\r
 #include "drv_jpeg_intf.h"\r
@@ -102,7 +102,6 @@ void GraphicService::SetNativeUIRunning(bool isRunning)
         osal_atomic_set(&isNativeRunning_, 1);\r
     } else {\r
         osal_atomic_set(&isNativeRunning_, 0);\r
-        OHOS::GraphicEventHandler::GetInstance()->ClearGraphicEvent();\r
         osal_atomic_set(&graphicTaskTriggeredCount_, 0);\r
     }\r
     switchMutex_.Unlock();\r
index 332ffe5..3fb1585 100644 (file)
@@ -76,11 +76,9 @@ void LiteSurface::AddBuffer()
         return;
     }
 
-    AllocInfo info;
-    info.expectedSize = size_;
-    info.usage = HBM_USE_ASSIGN_SIZE | HBM_USE_MEM_YUV;
-    GrallocBuffer buffer;
-    if (!GrallocEngines::GetInstance()->AllocBuffer(info, buffer)) {
+    uint8_t* addr = GrallocEngines::GetInstance()->AllocBufferBySize(size_,
+        HBM_USE_ASSIGN_SIZE | HBM_USE_MEM_YUV);
+    if (addr == nullptr) {
         GRAPHIC_LOGE("Alloc memory for buffer failed.\n");
         delete bufferItem;
         return;
@@ -89,13 +87,14 @@ void LiteSurface::AddBuffer()
     SurfaceBuffer* surfaceBuffer = new SurfaceBuffer();
     if (surfaceBuffer == nullptr) {
         GRAPHIC_LOGE("new surfaceBuffer failed.");
+        GrallocEngines::GetInstance()->FreeBuffer(addr);
         delete bufferItem;
         return;
     }
 
     bufferItem->buffer = surfaceBuffer;
 
-    surfaceBuffer->addr = reinterpret_cast<uint32_t>(buffer.virAddr);
+    surfaceBuffer->addr = reinterpret_cast<uint32_t>(addr);
     surfaceBuffer->width = width_;
     surfaceBuffer->height = height_;
     surfaceBuffer->stride = GetStride();
diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/components/ui_fragment.cpp b/code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/components/ui_fragment.cpp
new file mode 100644 (file)
index 0000000..ecc2316
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025-2025. All rights reserved.
+ * Description: UI fragment
+ * Author: Hisi Graphic Team
+ * Created: 2025-5
+ */
+#include "components/ui_fragment.h"
+#include "gfx_utils/graphic_log.h"
+
+namespace OHOS {
+
+UIFragment::UIFragment(const std::string& id) : id_(id), state_(FragmentState::INITIALIZED)
+{
+    if (!id_.empty()) {
+        UIFragmentManager::GetInstance().AddFragment(id_, this);
+    }
+}
+
+UIFragment::~UIFragment()
+{
+    if (!id_.empty()) {
+        UIFragmentManager::GetInstance().RemoveFragment(id_);
+    }
+}
+
+UIView* UIFragment::CreateView(void* data)
+{
+    if (state_ == FragmentState::INITIALIZED) {
+        OnCreateView(data);
+    }
+    
+    state_ = FragmentState::CREATED;
+    return &fragmentView_;
+}
+
+void UIFragment::ResumeView()
+{
+    if (state_ == FragmentState::CREATED) {
+        OnResumeView();
+    }
+    state_ = FragmentState::RESUMED;
+}
+
+void UIFragment::PauseView()
+{
+    if (state_ == FragmentState::RESUMED) {
+        OnPauseView();
+    }
+    state_ = FragmentState::CREATED;
+}
+
+void UIFragment::DestroyView()
+{
+    if ((state_ == FragmentState::CREATED || state_ == FragmentState::RESUMED)) {
+        OnDestroyView();
+    }
+    state_ = FragmentState::INITIALIZED;
+}
+
+UIFragmentManager& UIFragmentManager::GetInstance()
+{
+    static UIFragmentManager instance;
+    return instance;
+}
+
+void UIFragmentManager::AddFragment(const std::string& id, UIFragment* fragment)
+{
+    auto it = fragments_.find(id);
+    if (it == fragments_.end()) {
+        fragments_[id] = fragment;
+    } else {
+        GRAPHIC_LOGE("fragment %s already exist", id.c_str());
+    }
+}
+
+void UIFragmentManager::RemoveFragment(const std::string& id)
+{
+    auto it = fragments_.find(id);
+    if (it != fragments_.end()) {
+        fragments_.erase(it);
+    } else {
+        GRAPHIC_LOGE("fragment %s does not exist", id.c_str());
+    }
+}
+
+UIFragment* UIFragmentManager::GetFragmentById(const std::string& id)
+{
+    auto it = fragments_.find(id);
+    if (it != fragments_.end()) {
+        return it->second;
+    } else {
+        GRAPHIC_LOGE("fragment %s does not exist", id.c_str());
+        return nullptr;
+    }
+}
+}
\ No newline at end of file
index 5bbd1cc..d830487 100644 (file)
@@ -34,7 +34,7 @@ bool UIListNested::OnDragStartEvent(const DragEvent& event)
     } else {
         dragDirection = VERTICAL;
     }
-    isConsumed_ = (direction_ == dragDirection);
+    isConsumed_ = (direction_ == dragDirection) && (childrenHead_ != nullptr);
 
     UIView::OnDragStartEvent(event);
     return isConsumed_;
@@ -47,8 +47,8 @@ bool UIListNested::OnDragEvent(const DragEvent& event)
         return false;
     }
     UIList::OnDragEvent(event);
-    if (GetLoopState() || childrenHead_ == nullptr) {
-        return false;
+    if (GetLoopState()) {
+        return true;
     }
     bool outOfBounds[4] = {false, false, false, false}; // 4: the number of direction
     int16_t listHeight = GetHeight();
index ec777b1..b3406e8 100644 (file)
@@ -360,6 +360,9 @@ void UILiteSurfaceView::OnBufferAvailable()
 \r
 void UILiteSurfaceView::SetPreview(ImageInfo* info)\r
 {\r
+    if (info == nullptr) {\r
+        return;\r
+    }\r
     if (preView_ == nullptr) {\r
         preView_ = new Image();\r
     }\r
index 6687ff0..33f50dd 100644 (file)
@@ -34,7 +34,7 @@ bool UIScrollViewNested::OnDragStartEvent(const DragEvent& event)
     } else {
         dragDirection = VERTICAL;
     }
-    isConsumed_ = (direction_ == dragDirection);
+    isConsumed_ = (direction_ == dragDirection) && (childrenHead_ != nullptr);
 
     UIView::OnDragStartEvent(event);
     return isConsumed_;
index 58219d3..27a3610 100644 (file)
@@ -26,7 +26,7 @@ bool UISwipeViewNested::OnDragStartEvent(const DragEvent& event)
     } else {
         dragDirection = VERTICAL;
     }
-    isConsumed_ = (direction_ == dragDirection);
+    isConsumed_ = (direction_ == dragDirection) && (childrenHead_ != nullptr);
 
     UIView::OnDragStartEvent(event);
     return isConsumed_;
@@ -40,8 +40,8 @@ bool UISwipeViewNested::OnDragEvent(const DragEvent& event)
     }
 
     UISwipeView::OnDragEvent(event);
-    if (loop_ || childrenHead_ == nullptr) {
-        return false;
+    if (loop_) {
+        return true;
     }
     bool outOfBounds[4] = {false, false, false, false}; // 4: the number of direction
     int16_t height = GetHeight();
index d2f908e..16155d8 100644 (file)
@@ -43,6 +43,9 @@
 #include "dock/input_device.h"
 #include "events/key_event.h"
 #endif
+#if defined (SUPPORT_DIAL_DEBUG)
+#include "main/dial/WatchInterface.h"
+#endif // defined (SUPPORT_DIAL_DEBUG)
 
 namespace OHOS {
 constexpr int DEFAULT_FILE_PERMISSION = 0666;
@@ -427,6 +430,143 @@ void PrintFPS(int argc, char *argv[])
     }
 }
 
+#if defined (SUPPORT_DIAL_DEBUG)
+void PrintWatchDialInfo(const watch_dial_info &info)
+{
+    printf("uuid %u, install state %u, is current %u, pro ver %s, internal ver %s\n",
+        info.uuid,
+        info.install_state,
+        info.is_current_watch,
+        info.watch_protocol_version,
+        info.watch_version);
+}
+
+void DebugGetAllWatchFaceInfo(int argc, char *argv[])
+{
+    GraphicService::GetInstance()->PostGraphicEvent([]() {
+        watch_dial_info *info = nullptr;
+        uint8_t num = 0;
+        bool ret = GetAllWatchFaceInfo(&info, &num);
+        if (!ret) {
+            printf("error in get allwatch info\n");
+            return;
+        }
+        for (uint8_t i = 0; i < num; ++i) {
+            PrintWatchDialInfo(info[i]);
+        }
+        free(info);
+    });
+}
+
+void DebugGetWatchFaceInfo(int argc, char *argv[])
+{
+    uint32_t uuid[] = {1, 2, 3};       // 1, 2, 3: uuid
+    for (uint8_t i = 0; i < 3; ++i) {  // 3: num
+        watch_dial_info info;
+        bool ret = GetWatchFaceInfo(uuid[i], &info);
+        if (!ret) {
+            printf("error in DebugGetWatchFaceInfo uuid %u\n", uuid[i]);
+            continue;
+        }
+        PrintWatchDialInfo(info);
+    }
+}
+
+void DebugGetWatchCapability(int argc, char *argv[])
+{
+    watch_dev_cap_info dev;
+    bool ret = GetWatchCapability(&dev);
+    if (!ret) {
+        printf("error in DebugGetWatchCapability\n");
+        return;
+    }
+    printf("kaleidoscope %u, 3d %u, interaction %u, video %u, fmt %u\n",
+        dev.kaleidoscope,
+        dev.effect_3D,
+        dev.interaction,
+        dev.video,
+        dev.video_format);
+}
+
+void DebugGetWatchSystemInfo(int argc, char *argv[])
+{
+    watch_sys_info sys;
+    bool ret = GetWatchSystemInfo(&sys);
+    if (!ret) {
+        printf("error in DebugGetWatchSystemInfo\n");
+        return;
+    }
+    printf("resolution %s watch_proto_support_cnt %u\n", sys.resolution, sys.watch_proto_support_cnt);
+    for (uint8_t i = 0; i < sys.watch_proto_support_cnt; ++i) {
+        printf("version %s\n", sys.watch_protocol_verion[i]);
+    }
+}
+
+void DebugGetCurrentWatchFaceInfo(int argc, char *argv[])
+{
+    watch_dial_info cur;
+    if (!GetCurrentWatchFaceInfo(&cur)) {
+        printf("current is not 3.0 dial\n");
+        return;
+    }
+    PrintWatchDialInfo(cur);
+}
+
+void DebugSetCurrentWatchFace(int argc, char *argv[])
+{
+    uint16_t i = 0;
+    if (argc != 1) {
+        printf("fmt: AT^UIKIT_DFX=debug_set_cur <num>\n");
+        return;
+    }
+    ConvertToInt(argv[0], i);
+    printf("function %s, line %d, uuid %u\n", __PRETTY_FUNCTION__, __LINE__, i);
+    if (!SetCurrentWatchFace(i)) {
+        printf("set uuid %u error\n", i);
+    }
+}
+
+void DebugUninstallWatch(int argc, char *argv[])
+{
+    if (argc != 1) {
+        printf("fmt: AT^UIKIT_DFX=debug_uninstall <num>\n");
+        return;
+    }
+    uint16_t i = 3;
+    ConvertToInt(argv[0], i);
+
+    if (!UninstallWatch(i)) {
+        printf("uninstall uuid %u error\n", i);
+        return;
+    }
+    printf("uninstall %u successfully\n", i);
+}
+
+void DebugGetUuidByPath(int argc, char *argv[])
+{
+    if (argc != 1) {
+        printf("fmt: AT^UIKIT_DFX=debug_get_uuid <num>\n");
+        return;
+    }
+    uint16_t i = 0;
+    ConvertToInt(argv[0], i);
+    if (i < 1 || i > 4) {  // 4: max uuid
+        printf("wrong id %u\n", i);
+        return;
+    }
+    std::string dir = "/user/dial/";
+    std::string files[] = {
+        "test_interface_1.bin", "test_interface_2.bin", "test_interface_3.bin", "test_interface_4.bin"};
+    std::string path = dir + files[i - 1];
+    uint32_t uuid = 0;
+    if (!GetUuidByPath(path.c_str(), &uuid)) {
+        printf("get uuid %s error\n", path.c_str());
+        return;
+    }
+    printf("Succuss to get file %s, uuid %u\n", path.c_str(), uuid);
+}
+#endif // defined (SUPPORT_DIAL_DEBUG)
+
 #if ENABLE_DEBUG
 void InjectRotateEvent(int argc, char *argv[])
 {
@@ -561,8 +701,7 @@ struct DfxCmd {
     void (*func)(int argc, char *argv[]);
 };
 
-struct DfxCmd g_dfxCmdList[] = {
-    {"screencap", OHOS::ScreencapCmd},
+struct DfxCmd g_dfxCmdList[] = {{"screencap", OHOS::ScreencapCmd},
     {"dump_view_id", OHOS::DumpViewIdCmd},
     {"dump_root_view", OHOS::DumpRootView},
     {"printfps", OHOS::PrintFPS},
@@ -570,6 +709,16 @@ struct DfxCmd g_dfxCmdList[] = {
     {"showfps", OHOS::ShowFPS},
     {"showtime", OHOS::ShowTime},
     {"refresh", OHOS::ForceRefresh},
+#if defined (SUPPORT_DIAL_DEBUG)
+    {"debug_get_all", OHOS::DebugGetAllWatchFaceInfo},
+    {"debug_get_watch", OHOS::DebugGetWatchFaceInfo},
+    {"debug_get_ability", OHOS::DebugGetWatchCapability},
+    {"debug_get_sys", OHOS::DebugGetWatchSystemInfo},
+    {"debug_get_cur", OHOS::DebugGetCurrentWatchFaceInfo},
+    {"debug_set_cur", OHOS::DebugSetCurrentWatchFace},
+    {"debug_uninstall", OHOS::DebugUninstallWatch},
+    {"debug_get_uuid", OHOS::DebugGetUuidByPath},
+#endif // defined (SUPPORT_DIAL_DEBUG)
 #if ENABLE_MEMORY_CHECK
     {"dumpstate", OHOS::DumpState},
     {"dumpmem", OHOS::DumpMemoryCmd},
index 2201b6b..3565fc5 100644 (file)
@@ -40,6 +40,7 @@ static struct {
     {FrameTraceType::HW_DRAW_LINE, "hw_line"},
     {FrameTraceType::HW_DRAW_ARC, "hw_arc"},
     {FrameTraceType::HW_DRAW_CUBICBEZIER, "hw_bezier"},
+    {FrameTraceType::HW_DRAW_ELLIPSE, "hw_ellipse"},
 };
 
 int DfxFrameTrace::evtCnt_ = 0;
@@ -58,12 +59,20 @@ DfxFrameTrace& DfxFrameTrace::GetInstance()
     return dfx;
 }
 
+void DfxFrameTrace::SetPathType(FrameTraceType type)
+{
+    pathType_ = type;
+}
+
 void DfxFrameTrace::FrameTraceStart(FrameTraceType type)
 {
     if (!CanTrace()) {
         return;
     }
     if (drawStack_ == 0) {
+        if (type == FrameTraceType::HW_DRAW_PATH) {
+            type = pathType_;
+        }
         RecordStart(type);
     }
     ++drawStack_;
@@ -79,6 +88,10 @@ void DfxFrameTrace::FrameTraceEnd(FrameTraceType type, const Rect *rect)
         return;
     }
 
+    if (type == FrameTraceType::HW_DRAW_PATH) {
+        type = pathType_;
+        pathType_ = FrameTraceType::HW_DRAW_PATH;
+    }
     RecordEnd(type, rect);
 }
 
@@ -241,20 +254,26 @@ void DfxFrameTrace::ShowEventRecord() const
     int evtIndex = 0;
     int taskIndex = 0;
     printf("Total: E %d, T %d, F %d\n", evtCnt_, tskCnt_, frmCnt_);
+    EventRecord *preE = events_;
     for (EventRecord *it = events_; it != nullptr; it = it->next) {
         EventRecord &evt = *it;
-        printf("\nE %d: %llu, (%llu, %llu)\n", evtIndex, GetDuration(evt.startTime, evt.endTime),
-            evt.startTime, evt.endTime);
+        uint64_t preEvtTime = evtIndex == 0 ? preE->startTime : preE->endTime;
+        printf("\nE %d: %llu, %llu\n",
+            evtIndex, GetDuration(preEvtTime, evt.startTime), GetDuration(evt.startTime, evt.endTime));
         taskIndex = 0;
+        TaskRecord *preT = evt.tasks;
         for (TaskRecord *it1 = evt.tasks; it1 != nullptr; it1 = it1->next) {
             TaskRecord &tsk = *it1;
-            printf(" T %d: %llu, (%llu, %llu)\n", taskIndex, GetDuration(tsk.startTime, tsk.endTime),
-                tsk.startTime, tsk.endTime);
+            uint64_t preTskTime = taskIndex == 0 ? evt.startTime : preT->endTime;
+            printf(" T %d: %llu, %llu\n",
+                taskIndex, GetDuration(preTskTime, tsk.startTime), GetDuration(tsk.startTime, tsk.endTime));
             if (tsk.frameInfo != nullptr) {
                 ShowFrameRecord(tsk.frameInfo);
             }
+            preT = it1;
             taskIndex++;
         }
+        preE = it;
         evtIndex++;
     }
 }
index 13e4801..485dd31 100644 (file)
 #include "clip_img.h"
 
 namespace OHOS {
-static void ClearPath(Path* path)
-{
-    GrallocEngines::GetInstance()->FreeBuffer(reinterpret_cast<uint8_t*>(path->cmds));
-    GrallocEngines::GetInstance()->FreeBuffer(reinterpret_cast<uint8_t*>(path->data));
-    path->cmds = nullptr;
-    path->data = nullptr;
-}
-
 static bool AllocImageInfo(ImageInfo& info, uint16_t width, uint16_t height, ColorMode mod)
 {
     info.header.width = width;
@@ -61,7 +53,7 @@ ImageInfo ClipImg::ClipImgByCircle(ImageInfo& srcInfo, Point center, int16_t rad
     }
 
     if (!AllocImageInfo(dstInfo, 2 * radius, 2 * radius, mode)) { // 2: the diameter of the circle
-        ClearPath(&path);
+        HWDrawUtils::GetInstance()->FreeBufferForPath(&path);
         return dstInfo;
     }
 
@@ -69,7 +61,7 @@ ImageInfo ClipImg::ClipImgByCircle(ImageInfo& srcInfo, Point center, int16_t rad
     if (immediatelySync) {
         LiteMGfxEngine::GetInstance()->SyncHwDraw();
     }
-    ClearPath(&path);
+    HWDrawUtils::GetInstance()->FreeBufferForPath(&path);
     return dstInfo;
 }
 
@@ -77,26 +69,17 @@ ImageInfo ClipImg::ClipImgByRect(ImageInfo& srcInfo, Rect* srcImgArea, Rect clip
 {
     ImageInfo dstInfo = {{0}};
     Path path = {0};
-    path.dataNum = 5; // 5: data num
-    if (!HWDrawUtils::GetInstance()->AllocBufferForData(path.dataNum, path.data)) {
-        return dstInfo;
-    }
 
-    path.cmdNum = 5; // 5: cmd num
-    AllocInfo cmdInfo;
-    cmdInfo.expectedSize = sizeof(uint8_t) * path.cmdNum;
-    cmdInfo.usage = HBM_USE_ASSIGN_SIZE | HBM_USE_MEM_PATH;
-    GrallocBuffer cmdBuffer;
-    if (!GrallocEngines::GetInstance()->AllocBuffer(cmdInfo, cmdBuffer)) {
-        GrallocEngines::GetInstance()->FreeBuffer(reinterpret_cast<uint8_t*>(path.data));
+    if (!HWDrawUtils::GetInstance()->AllocBufferForPath(&path, 5, 5)) { // 5: cmd and data num
         return dstInfo;
     }
+
     path.data[0] = clipArea.GetX();
     path.data[1] = clipArea.GetY();
     path.data[2] = clipArea.GetRight();  // 2: index
     path.data[3] = clipArea.GetBottom(); // 3: index
     path.data[4] = clipArea.GetX();      // 4: index
-    path.cmds = (uint8_t *)cmdBuffer.virAddr;
+
     path.cmds[0] = CMD_MOVE_TO;
     path.cmds[1] = CMD_HLINE_TO;
     path.cmds[2] = CMD_VLINE_TO; // 2: index
@@ -104,12 +87,12 @@ ImageInfo ClipImg::ClipImgByRect(ImageInfo& srcInfo, Rect* srcImgArea, Rect clip
     path.cmds[4] = CMD_CLOSE;    // 4: index
 
     if (!AllocImageInfo(dstInfo, clipArea.GetWidth(), clipArea.GetHeight(), mode)) {
-        ClearPath(&path);
+        HWDrawUtils::GetInstance()->FreeBufferForPath(&path);
         return dstInfo;
     }
 
     ClipImgByPath(dstInfo, srcInfo, &path, nullptr, nullptr, nullptr);
-    ClearPath(&path);
+    HWDrawUtils::GetInstance()->FreeBufferForPath(&path);
     return dstInfo;
 }
 }
index d7feafb..d44c2fd 100644 (file)
@@ -20,7 +20,7 @@
 #include "gfx_utils/graphic_log.h"
 #include "hals/gralloc_engines.h"
 
-#if ENABLE_VGU_ENGINE && CAPABILITY_HWDRAW_PATH
+#if ENABLE_VGU_ENGINE
 namespace OHOS {
 constexpr float ARC_TO_BEZIER_90_DEG = 0.551915024494f;
 constexpr int16_t DATA_NUM_PER_BEZ = 6;
@@ -28,32 +28,64 @@ constexpr float PRECISION_ANGLE = 0.01f;
 
 bool HWDrawUtils::AllocBufferForCmd(uint16_t cmdNum, uint8_t*& addr)
 {
-    AllocInfo dataInfo;
-    dataInfo.expectedSize = sizeof(uint8_t) * cmdNum;
-    dataInfo.usage = HBM_USE_ASSIGN_SIZE | HBM_USE_MEM_PATH;
-    GrallocBuffer dataBuffer;
-    if (!GrallocEngines::GetInstance()->AllocBuffer(dataInfo, dataBuffer)) {
-        GRAPHIC_LOGE("Alloc buffer for data failed.");
+    uint8_t* cmdAddr = GrallocEngines::GetInstance()->AllocBufferBySize(sizeof(uint8_t) * cmdNum,
+        HBM_USE_ASSIGN_SIZE | HBM_USE_MEM_PATH);
+    if (cmdAddr == nullptr) {
+        GRAPHIC_LOGE("Alloc buffer for cmd failed.");
+        addr = nullptr;
         return false;
     }
-    addr = reinterpret_cast<uint8_t*>(dataBuffer.virAddr);
+    addr = cmdAddr;
     return true;
 }
 
 bool HWDrawUtils::AllocBufferForData(uint16_t dataNum, float*& addr)
 {
-    AllocInfo dataInfo;
-    dataInfo.expectedSize = sizeof(float) * dataNum;
-    dataInfo.usage = HBM_USE_ASSIGN_SIZE | HBM_USE_MEM_PATH;
-    GrallocBuffer dataBuffer;
-    if (!GrallocEngines::GetInstance()->AllocBuffer(dataInfo, dataBuffer)) {
+    uint8_t* dataAddr = GrallocEngines::GetInstance()->AllocBufferBySize(sizeof(float) * dataNum,
+        HBM_USE_ASSIGN_SIZE | HBM_USE_MEM_PATH);
+    if (dataAddr == nullptr) {
         GRAPHIC_LOGE("Alloc buffer for data failed.");
+        addr = nullptr;
         return false;
     }
-    addr = reinterpret_cast<float*>(dataBuffer.virAddr);
+    addr = reinterpret_cast<float*>(dataAddr);
     return true;
 }
 
+bool HWDrawUtils::AllocBufferForPath(Path* path, uint16_t cmdNum, uint16_t dataNum)
+{
+    if (path == nullptr) {
+        return false;
+    }
+
+    if (!AllocBufferForCmd(cmdNum, path->cmds)) {
+        return false;
+    }
+
+    if (!AllocBufferForData(dataNum, path->data)) {
+        GrallocEngines::GetInstance()->FreeBuffer(path->cmds);
+        path->cmds = nullptr;
+        return false;
+    }
+
+    path->cmdNum = cmdNum;
+    path->dataNum = dataNum;
+    return true;
+}
+
+void HWDrawUtils::FreeBufferForPath(Path* path)
+{
+    if (path == nullptr) {
+        return;
+    }
+    GrallocEngines::GetInstance()->FreeBuffer(path->cmds);
+    GrallocEngines::GetInstance()->FreeBuffer(reinterpret_cast<uint8_t*>(path->data));
+    path->cmds = nullptr;
+    path->data = nullptr;
+    path->cmdNum = 0;
+    path->dataNum = 0;
+}
+
 void HWDrawUtils::GetArcControlPoint(float* arcData, float centerX, float centerY, float mangicNum, int8_t neg)
 {
     arcData[2] = arcData[0] - (neg * mangicNum * (arcData[1] - centerY)); // 2: index
@@ -244,10 +276,16 @@ bool HWDrawUtils::ObtainCirclePath(const ArcInfo& arc, uint32_t& cmdNum,
 
 bool HWDrawUtils::ObtainRectPathWithRadius(const Rect& rect, Path& path, int16_t radius)
 {
-    path.cmdNum = 10; // 10: Circle path command number is 10
-    if (!AllocBufferForCmd(path.cmdNum, path.cmds)) {
-        return false;
+    uint32_t cmdNum = 10; // 10: Circle path command number is 10
+    if (path.cmdNum < cmdNum) {
+        GrallocEngines::GetInstance()->FreeBuffer(path.cmds);
+        path.cmds = nullptr;
+        if (!AllocBufferForCmd(cmdNum, path.cmds)) {
+            return false;
+        }
     }
+    path.cmdNum = cmdNum;
+
     path.cmds[0] = CMD_MOVE_TO;
     path.cmds[1] = CMD_LINE_TO;
     path.cmds[2] = CMD_CUBIC_TO;  // 2: cmd index
@@ -259,12 +297,18 @@ bool HWDrawUtils::ObtainRectPathWithRadius(const Rect& rect, Path& path, int16_t
     path.cmds[8] = CMD_CUBIC_TO;    // 8: cmd index
     path.cmds[9] = CMD_CLOSE;    // 9: cmd index
 
-    path.dataNum = 34; // Circle path data number is 34
-    if (!AllocBufferForData(path.dataNum, path.data)) {
-        GrallocEngines::GetInstance()->FreeBuffer(path.cmds);
-        path.cmds = nullptr;
-        return false;
+    uint32_t dataNum = 34; // Circle path data number is 34
+    if (path.dataNum < dataNum) {
+        GrallocEngines::GetInstance()->FreeBuffer(reinterpret_cast<uint8_t*>(path.data));
+        path.data = nullptr;
+        if (!AllocBufferForData(dataNum, path.data)) {
+            GrallocEngines::GetInstance()->FreeBuffer(path.cmds);
+            path.cmds = nullptr;
+            return false;
+        }
     }
+    path.dataNum = dataNum;
+
     GetFilledRoundRectData(path.data, radius, rect);
     return true;
 }
@@ -312,5 +356,117 @@ void HWDrawUtils::GetFilledRoundRectData(float* data, uint16_t radius, const Rec
 
     GetArcControlPoint(&data[26], x1 + r, y1 + r, ARC_TO_BEZIER_90_DEG, -1); // 26: index
 }
+
+static void GetEllipsePathData(const Point& center, uint16_t rx, uint16_t ry, Path& path)
+{
+    path.cmds[0] = CMD_MOVE_TO;
+    path.cmds[1] = CMD_CUBIC_TO;
+    path.cmds[2] = CMD_CUBIC_TO;  // 2: cmd index
+    path.cmds[3] = CMD_CUBIC_TO;  // 3: cmd index
+    path.cmds[4] = CMD_CUBIC_TO;  // 4: cmd index
+    path.cmds[5] = CMD_CLOSE;     // 5: cmd index
+
+    float magicX = rx * ARC_TO_BEZIER_90_DEG;
+    float magicY = ry * ARC_TO_BEZIER_90_DEG;
+
+    // start point
+    path.data[0] = center.x;
+    path.data[1] = center.y - ry;
+
+    // right top control point
+    path.data[2] = center.x + magicX;  // 2: index
+    path.data[3] = center.y - ry;      // 3: index
+    path.data[4] = center.x + rx;      // 4: index
+    path.data[5] = center.y - magicY;  // 5: index
+    path.data[6] = center.x + rx;      // 6: index
+    path.data[7] = center.y;           // 7: index
+
+    // right bottom control point
+    path.data[8] = center.x + rx;       // 8: index
+    path.data[9] = center.y + magicY;   // 9: index
+    path.data[10] = center.x + magicX;  // 10: index
+    path.data[11] = center.y + ry;      // 11: index
+    path.data[12] = center.x;           // 12: index
+    path.data[13] = center.y + ry;      // 13: index
+
+    // left bottom control point
+    path.data[14] = center.x - magicX;  // 14: index
+    path.data[15] = center.y + ry;      // 15: index
+    path.data[16] = center.x - rx;      // 16: index
+    path.data[17] = center.y + magicY;  // 17: index
+    path.data[18] = center.x - rx;      // 18: index
+    path.data[19] = center.y;           // 19: index
+
+    // left top control point
+    path.data[20] = center.x - rx;       // 20: index
+    path.data[21] = center.y - magicY;   // 21: index
+    path.data[22] = center.x - magicX;   // 22: index
+    path.data[23] = center.y - ry;       // 23: index
+    path.data[24] = center.x;            // 24: index
+    path.data[25] = center.y - ry;       // 25: index
+}
+
+bool HWDrawUtils::ObtainEllipsePath(const Point& center, uint16_t rx, uint16_t ry, Path& path)
+{
+    uint32_t cmdNum = 6; // 6: Ellipse path command number is 6
+    if (path.cmdNum < cmdNum) {
+        if (path.cmds != nullptr) {
+            GrallocEngines::GetInstance()->FreeBuffer(path.cmds);
+            path.cmds = nullptr;
+            path.cmdNum = 0;
+        }
+        if (!AllocBufferForCmd(cmdNum, path.cmds)) {
+            return false;
+        }
+    }
+    path.cmdNum = cmdNum;
+
+    uint32_t dataNum = 26; // 26: Ellipse path data number is 26
+    if (path.dataNum < dataNum) {
+        if (path.data != nullptr) {
+            GrallocEngines::GetInstance()->FreeBuffer(reinterpret_cast<uint8_t*>(path.data));
+            path.data = nullptr;
+            path.dataNum = 0;
+        }
+        if (!AllocBufferForData(dataNum, path.data)) {
+            GrallocEngines::GetInstance()->FreeBuffer(path.cmds);
+            path.cmds = nullptr;
+            path.cmdNum = 0;
+            return false;
+        }
+    }
+    path.dataNum = dataNum;
+
+    GetEllipsePathData(center, rx, ry, path);
+    return true;
+}
+
+void HWDrawUtils::Matrix3ToVguMatrix3(const Matrix3<float>& matrix, VGUMatrix3& vguMat)
+{
+    const float* data = matrix.GetData();
+    vguMat.m[0][0] = data[0]; // 0, 0: index
+    vguMat.m[0][1] = data[3]; // 0, 3: index
+    vguMat.m[0][2] = data[6]; // 0, 2, 6: index
+    vguMat.m[1][0] = data[1]; // 1, 0: index
+    vguMat.m[1][1] = data[4]; // 1, 4: index
+    vguMat.m[1][2] = data[7]; // 1, 2, 7: index
+    vguMat.m[2][0] = data[2]; // 2, 0: index
+    vguMat.m[2][1] = data[5]; // 2, 1, 5: index
+    vguMat.m[2][2] = data[8]; // 2, 8: index
+}
+
+void HWDrawUtils::Matrix4ToVguMatrix3(const Matrix4<float>& matrix, VGUMatrix3& vguMat)
+{
+    const float* data = matrix.GetData();
+    vguMat.m[0][0] = data[0];
+    vguMat.m[1][0] = data[1];
+    vguMat.m[2][0] = data[3];  // 2, 3: index
+    vguMat.m[0][1] = data[4];  // 4: index
+    vguMat.m[1][1] = data[5];  // 5: index
+    vguMat.m[2][1] = data[7];  // 2, 7: index
+    vguMat.m[0][2] = data[12]; // 2, 12: index
+    vguMat.m[1][2] = data[13]; // 2, 13: index
+    vguMat.m[2][2] = data[15]; // 2, 15: index
+}
 }
 #endif
index 86d3b04..2280c0d 100644 (file)
 #define GRAPHIC_LITE_HW_DRAW_H
 
 #include "graphic_config.h"
-#if ENABLE_VGU_ENGINE && CAPABILITY_HWDRAW_PATH
+#if ENABLE_VGU_ENGINE
 #include "engines/gfx/gfx_engine_manager.h"
 #include "common/graphic_hardware_types.h"
+#include "display_vgu.h"
 
 namespace OHOS {
 class HWDrawUtils : public HeapBase {
@@ -34,8 +35,14 @@ public:
     bool ObtainCirclePath(const ArcInfo& arc, uint32_t& cmdNum, uint8_t*& cmds, uint32_t& dataNum, float*& data);
     bool AllocBufferForCmd(uint16_t cmdNum, uint8_t*& addr);
     bool AllocBufferForData(uint16_t dataNum, float*& addr);
+    bool AllocBufferForPath(Path* path, uint16_t cmdNum, uint16_t dataNum);
+    void FreeBufferForPath(Path* path);
     void Obtain30DegSectorPath(const ArcInfo& arc, float x, float y, uint8_t* cmd, float* data);
     bool ObtainRectPathWithRadius(const Rect& rect, Path& path, int16_t radius);
+    bool ObtainEllipsePath(const Point& center, uint16_t rx, uint16_t ry, Path& path);
+    void Matrix3ToVguMatrix3(const Matrix3<float>& matrix, VGUMatrix3& vguMat);
+    void Matrix4ToVguMatrix3(const Matrix4<float>& matrix, VGUMatrix3& vguMat);
+
 private:
     HWDrawUtils() {}
     virtual ~HWDrawUtils() {}
index 4f42d20..3d066c5 100644 (file)
@@ -28,6 +28,7 @@
 #include "gfx_utils/heap_base.h"
 #include "gfx_utils/style.h"
 #include "gfx_utils/transform.h"
+#include "gfx_utils/vector.h"
 #include "common/ihardware_view.h"
 #include "common/graphic_hardware_types.h"
 
@@ -44,6 +45,8 @@ struct AsyncSubmitInfo {
     bool needSwapToPendingFrame;
 };
 
+static constexpr uint16_t INIT_PATH_NUM = 20;
+
 class LiteMGfxEngine : public BaseGfxEngine {
 public:
     using BaseGfxEngine::Flush;
@@ -109,6 +112,15 @@ public:
         const ColorType color,
         const OpacityType opacity) override;
 
+    void DrawEllipse(BufferInfo& dst,
+        const Rect& mask,
+        const Point& center,
+        uint16_t rx,
+        uint16_t ry,
+        VGUStrokeAttr* strokeAttr,
+        VGUFillAttr* fillAttr,
+        VGUMatrix3* matrix);
+
 #if CAPABILITY_HWDRAW_PATH
     uintptr_t InitPath(bool enAlias);
     void DeinitPath(uintptr_t path) const;
@@ -170,15 +182,22 @@ private:
         ReleasePath();
     }
 
+#if defined(HW_ROTATE_ANGLE)
+    bool RotateBufferIfNecessary();
+#endif
     void DrawRectWithRound(BufferInfo& dst, const Rect& rect, const Style& style, const Rect& dirtyRect,
         OpacityType opacity);
     void DrawRectWithoutRound(BufferInfo& dst, const Rect& rect, const Style& style, const Rect& dirtyRect,
         OpacityType opacity);
-    List<Path*> pathList_ = {};
+    bool HandleImageSrc(const Image* imgSrc, VGUImage& image, const Style& style);
     void ReleasePath();
+    void DrawArcInner(BufferInfo& dst, const ArcInfo& arcInfo, const Rect& mask,
+        const Style& style, OpacityType opacity, uint8_t cap, VGUImage& image);
 
     BufferInfo* bufferInfo_ = nullptr;
     BufferInfo* nextBufferInfo_ = nullptr;
+    Graphic::Vector<Path> pathSubmit_{INIT_PATH_NUM};
+    Graphic::Vector<Path> pathRender_{INIT_PATH_NUM};
 
     AsyncSubmitInfo lastAsyncInfo_ = {{0, 0, 1, 1}, false, false};
     bool enableAsyncSubmit_ = true;
@@ -194,10 +213,12 @@ private:
     IHardwareView* hardwareView_ {nullptr};
 
     bool Convert2VGUBuffer(const BufferInfo& bufferInfo, VGUBuffer& buffer) const;
-    void BlitImages();
-    void AddHwDraw(uint16_t cnt);
+    void BlitImages(bool calledBySync = false);
+    void CheckHwDrawLimit(uint16_t nodeCnt, uint16_t strokeCnt = 0);
+    void AddHwDraw(uint16_t nodeCnt, uint16_t strokeCnt = 0);
     void AsyncFlush();
+    void RenderSubmitInner(bool isNeedWait = true);
 #endif
 };
 }
-#endif // GRAPHIC_LITE_LITE_M_GFX_ENGINE_H
+#endif // GRAPHIC_LITE_LITE_M_GFX_ENGINE_H
\ No newline at end of file
index 3a2af9a..108e4da 100644 (file)
@@ -43,17 +43,13 @@ RetCode HWJpegDecoder::Open(ImgResDsc& dsc)
 
     fseek(fp, 0, SEEK_END);
     g_fileLen = static_cast<uint32_t>(ftell(fp));
-
-    AllocInfo dataInfo;
-    dataInfo.expectedSize = g_fileLen;
-    dataInfo.usage = HBM_USE_ASSIGN_SIZE | HBM_USE_MEM_JPEG_DATA;
-    GrallocBuffer dataBuffer;
-    if (!GrallocEngines::GetInstance()->AllocBuffer(dataInfo, dataBuffer)) {
+    filedata_ = GrallocEngines::GetInstance()->AllocBufferBySize(g_fileLen,
+        HBM_USE_ASSIGN_SIZE | HBM_USE_MEM_JPEG_DATA);
+    if (filedata_ == nullptr) {
         fclose(fp);
         GRAPHIC_LOGE("Alloc buffer for data failed.");
         return RetCode::FAIL;
     }
-    filedata_ = reinterpret_cast<uint8_t*>(dataBuffer.virAddr);
 
     fseek(fp, 0, SEEK_SET);
     if (fread(filedata_, 1, g_fileLen, fp) != g_fileLen) {
index c401887..4f06c90 100644 (file)
@@ -22,6 +22,8 @@
 #include "graphic_config.h"
 #include "hals/gralloc_engines.h"
 #include "dfx/dfx_frame_trace.h"
+#include "imgdecode/image_load.h"
+#include "engines/gfx/lite_m_gfx_engine.h"
 
 #ifndef _WIN32
 #include "tcxo.h"
@@ -43,6 +45,8 @@ DisplayDev::DisplayDev() : isDisplayDevInited_(false), devId_(0), layerFuncs_(nu
         (void)memset_s(&layer_[i].layerInfo, sizeof(LayerInfo), 0, sizeof(LayerInfo));
         layer_[i].bufferCount = 0;
         layer_[i].buffer = nullptr;
+        (void)memset_s(&layer_[i].rotateInfo, sizeof(LayerInfo), 0, sizeof(LayerInfo));
+        layer_[i].rotate = nullptr;
         layer_[i].rotateType = LayerRotateType::LAYER_ROTATE_NONE;
     }
 }
@@ -63,7 +67,13 @@ void DisplayDev::LcdFlush(uint8_t layerId)
             return;
         }
         uint8_t currentBufferIndex = currentBufferId_[layerId];
-        if (layerFuncs_->Flush(devId_, layer_[layerId].layerHdl, &layer_[layerId].buffer[currentBufferIndex]) !=
+        LayerBuffer *buffer = nullptr;
+        if (layer_[layerId].rotate != nullptr) {
+            buffer = &layer_[layerId].rotate[currentBufferIndex];
+        } else {
+            buffer = &layer_[layerId].buffer[currentBufferIndex];
+        }
+        if (layerFuncs_->Flush(devId_, layer_[layerId].layerHdl, buffer) !=
             DISPLAY_SUCCESS) {
             GRAPHIC_LOGE("flush failed.");
             return;
@@ -123,6 +133,85 @@ LayerBuffer* DisplayDev::GetNextBuffer(uint8_t layerId)
     return &layer_[layerId].buffer[nextBufferId];
 }
 
+LayerBuffer* DisplayDev::GetCurrentRotateBuffer(uint8_t layerId)
+{
+    if (layerId < LAYER_0 || layerId >= LAYER_MAX) {
+        GRAPHIC_LOGE("Invalid layerId[%u].", layerId);
+        return nullptr;
+    }
+    if (layer_[layerId].bufferCount == 0) {
+        GRAPHIC_LOGE("layer[%u] is not opened.", layerId);
+        return nullptr;
+    }
+    if (layer_[layerId].rotate == nullptr) {
+        GRAPHIC_LOGE("rotateBuffer is nullptr!");
+        return nullptr;
+    }
+    return &layer_[layerId].rotate[currentBufferId_[layerId]];
+}
+
+void DisplayDev::GetRotatePosition(int32_t width, int32_t height, int32_t &x, int32_t &y, LayerRotateType type) const
+{
+    int32_t outX = x;
+    int32_t outY = y;
+    switch (type) {
+        case LayerRotateType::LAYER_ROTATE_90: {
+            outX = height - y;
+            outY = x;
+            break;
+        }
+        case LayerRotateType::LAYER_ROTATE_180: {
+            outX = width - x;
+            outY = height - y;
+            break;
+        }
+        case LayerRotateType::LAYER_ROTATE_270: {
+            outX = y;
+            outY = width - x;
+            break;
+        }
+        default:
+            return;
+    }
+    x = outX;
+    y = outY;
+}
+
+void DisplayDev::GetRotateRect(int32_t width, int32_t height, Rect &rect, LayerRotateType type) const
+{
+    Rect outRect = rect;
+    int32_t x = rect.GetLeft();
+    int32_t y = rect.GetTop();
+    switch (type) {
+        case LayerRotateType::LAYER_ROTATE_90: {
+            x = rect.GetLeft();
+            y = rect.GetBottom();
+            outRect.SetWidth(rect.GetHeight());
+            outRect.SetHeight(rect.GetWidth());
+            GetRotatePosition(width, height, x, y, type);
+            break;
+        }
+        case LayerRotateType::LAYER_ROTATE_180: {
+            x = rect.GetRight();
+            y = rect.GetBottom();
+            GetRotatePosition(width, height, x, y, type);
+            break;
+        }
+        case LayerRotateType::LAYER_ROTATE_270: {
+            x = rect.GetRight();
+            y = rect.GetTop();
+            outRect.SetWidth(rect.GetHeight());
+            outRect.SetHeight(rect.GetWidth());
+            GetRotatePosition(width, height, x, y, type);
+            break;
+        }
+        default:
+            return;
+    }
+    outRect.SetPosition(x, y);
+    rect = outRect;
+}
+
 bool DisplayDev::SwapBuffer(uint8_t layerId)
 {
     if (layerId < LAYER_0 || layerId >= LAYER_MAX) {
@@ -142,29 +231,103 @@ bool DisplayDev::SwapBuffer(uint8_t layerId)
     return true;
 }
 
-uint32_t DisplayDev::CalcStride(uint32_t width, PixelFormat fmt)
+static uint32_t GetAlignedStride(uint32_t width, PixelFormat fmt, uint8_t cmpMode)
 {
-    uint32_t bytePerPixel;
+    uint32_t bpp;
     uint32_t stride;
     switch (fmt) {
         case PIXEL_FMT_RGBA_8888:
-            bytePerPixel = 4; // 4: byte per pixel
+            if (cmpMode == COMPRESS_MODE_HFBC) {
+                bpp = 12; /* 12 bits */
+            } else if (cmpMode == COMPRESS_MODE_HFBC_ABYPASS) {
+                bpp = 16; /* 16 bits */
+            } else {
+                bpp = 32; /* 32 bits */
+            }
+            break;
+        case PIXEL_FMT_RGBA_5551:
+        case PIXEL_FMT_RGB_565:
+            bpp = 16; /* 16 bits */
+            break;
+        case PIXEL_FMT_RGB_888:
+            bpp = (cmpMode != COMPRESS_MODE_NONE) ? 8 : 24; /* 8,24 bits */
+            break;
+        case PIXEL_FMT_A1:
+            stride = width >> SHIFT_3;
+            if (width & 0x7) {
+                stride++;
+            }
+            stride = ALIGN_BYTE(stride, BYTE_ALIGNMENT);
+            return stride;
+        default:
+            bpp = 32; /* 32 bits */
+            break;
+    }
+    stride = ALIGN_BYTE(width, BYTE_ALIGNMENT) * bpp / STRIDE_DIVIDER;
+    if (cmpMode != COMPRESS_MODE_NONE) {
+        stride = stride * 4; /* 4: compress coef */
+    }
+    return stride;
+}
+
+uint32_t DisplayDev::CalcStride(uint32_t width, PixelFormat fmt, uint8_t cmpMode)
+{
+    uint32_t bitPerPixel;
+    uint32_t stride;
+    switch (fmt) {
+        case PIXEL_FMT_RGBA_8888:
+            bitPerPixel = 32; // 32: bit per pixel
             break;
         case PIXEL_FMT_RGBA_5551:
         case PIXEL_FMT_RGB_565:
-            bytePerPixel = 2; // 2: byte per pixel
+            bitPerPixel = 16; // 16: bit per pixel
             break;
         case PIXEL_FMT_RGB_888:
-            bytePerPixel = 3; // 3: byte per pixel
+            bitPerPixel = 24; // 24: bit per pixel
+            break;
+        case PIXEL_FMT_A1:
+        case PIXEL_FMT_A2:
+        case PIXEL_FMT_A4:
+        case PIXEL_FMT_A8:
+            bitPerPixel = 8; /* 8 bits */
             break;
         default:
             GRAPHIC_LOGE("unsupported PixelFormat: %d, just return 0.", fmt);
             return 0;
     }
-    stride = ALIGN_BYTE(width, BYTE_ALIGNMENT) * bytePerPixel;
+
+    switch (cmpMode) {
+        case COMPRESS_MODE_NONE:
+            stride = ALIGN_BYTE(width, 16) * bitPerPixel / 8; /** 16-byte aligned  8 bits per byte */
+            break;
+        case COMPRESS_MODE_HFBC:
+        case COMPRESS_MODE_HFBC_ABYPASS:
+            stride = GetAlignedStride(width, fmt, cmpMode);
+            break;
+        default:
+            GRAPHIC_LOGE("unsupported compress mode: %d, just return 0.", cmpMode);
+            return 0;
+    }
+
     return stride;
 }
 
+uint32_t DisplayDev::CalcSize(uint32_t stride, uint32_t height, uint8_t cmpMode)
+{
+    uint32_t size;
+    switch (cmpMode) {
+        case COMPRESS_MODE_NONE:
+            size = stride * height;
+            break;
+        default:
+            GRAPHIC_LOGE("unsupported compress mode: %d, just return 0.", cmpMode);
+            return 0;
+            break;
+    }
+
+    return size;
+}
+
 bool DisplayDev::OpenLayer(uint8_t layerId, const LayerInfo& info, uint8_t bufferCount, LayerRotateType rotateType)
 {
     if (layerId < LAYER_0 || layerId >= LAYER_MAX || bufferCount == 0 || bufferCount > BUFFER_MAX) {
@@ -190,18 +353,36 @@ bool DisplayDev::OpenLayer(uint8_t layerId, const LayerInfo& info, uint8_t buffe
         return false;
     }
 
-    layer_[layerId].layerInfo.width = info.width;
-    layer_[layerId].layerInfo.height = info.height;
-    layer_[layerId].layerInfo.type = info.type;
-    layer_[layerId].layerInfo.bpp = info.bpp;
-    layer_[layerId].layerInfo.pixFormat = info.pixFormat;
+    LayerInfo outInfo = info;
+    layer_[layerId].layerInfo = outInfo;
     layer_[layerId].bufferCount = bufferCount;
     layer_[layerId].rotateType = rotateType;
     layer_[layerId].pos.x = 0;
     layer_[layerId].pos.y = 0;
-    if (layerFuncs_->CreateLayer(devId_, &layer_[layerId].layerInfo, &layer_[layerId].layerHdl) != DISPLAY_SUCCESS) {
+    if (rotateType != LayerRotateType::LAYER_ROTATE_NONE) {
+        layer_[layerId].rotate = (LayerBuffer*)UIMalloc(size);
+        if (layer_[layerId].rotate == nullptr) {
+            UIFree(layer_[layerId].buffer);
+            GRAPHIC_LOGE("new rotate layerBuffer failed.");
+            layer_[layerId].buffer = nullptr;
+            return false;
+        }
+        if (rotateType == LayerRotateType::LAYER_ROTATE_90 || rotateType == LayerRotateType::LAYER_ROTATE_270) {
+            outInfo.height = info.width;
+            outInfo.width = info.height;
+            layer_[layerId].rotateInfo = outInfo;
+        } else {
+            layer_[layerId].rotateInfo = outInfo;
+        }
+    }
+
+    if (layerFuncs_->CreateLayer(devId_, &outInfo, &layer_[layerId].layerHdl) != DISPLAY_SUCCESS) {
         UIFree(layer_[layerId].buffer);
         layer_[layerId].buffer = nullptr;
+        if (layer_[layerId].rotate != nullptr) {
+            UIFree(layer_[layerId].rotate);
+            layer_[layerId].rotate = nullptr;
+        }
         layer_[layerId].layerHdl = 0;
         layer_[layerId].bufferCount = 0;
         layer_[layerId].rotateType = LayerRotateType::LAYER_ROTATE_NONE;
@@ -236,6 +417,10 @@ void DisplayDev::CloseLayer(uint8_t layerId)
 
     UIFree(layer_[layerId].buffer);
     layer_[layerId].buffer = nullptr;
+    if (layer_[layerId].rotate) {
+        UIFree(layer_[layerId].rotate);
+        layer_[layerId].rotate = nullptr;
+    }
 
     layer_[layerId].layerHdl = 0;
     layer_[layerId].bufferCount = 0;
@@ -289,59 +474,97 @@ bool DisplayDev::IsDoubleBuffer(void)
 #endif
 }
 
-bool DisplayDev::AllocLayerBuffer(uint8_t layerId)
+bool DisplayDev::AllocBuffer(LayerBuffer *layerBuffer, const LayerInfo &layerInfo, uint8_t count, bool isFb)
 {
-    if (layerId < LAYER_0 || layerId >= LAYER_MAX || layer_[layerId].bufferCount == 0) {
-        GRAPHIC_LOGE("Invalid layerId[%u] or layer is not opened.", layerId);
+    if (layerBuffer == nullptr || count == 0) {
         return false;
     }
 
-    if (layer_[layerId].buffer[0].data.virAddr != nullptr) {
-        GRAPHIC_LOGE("layer[%u] : Memory of buffers is already allocated.", layerId);
-        return false;
-    }
-
-#if !ENABLE_GMMU
-    uint32_t stride = CalcStride(layer_[layerId].layerInfo.width, layer_[layerId].layerInfo.pixFormat);
+    uint32_t stride = CalcStride(layerInfo.width, layerInfo.pixFormat);
     if (stride == 0) {
         return false;
     }
-#endif
 
     uint8_t index = 0;
-    while (index < layer_[layerId].bufferCount) {
+    while (index < count) {
         AllocInfo info;
+        if (isFb) {
 #if ENABLE_GMMU
-        info.usage = HBM_USE_MEM_FB;
+            info.usage = HBM_USE_MEM_FB;
 #else
-        info.expectedSize = stride * (uint16_t)layer_[layerId].layerInfo.height;
-        info.usage = HBM_USE_ASSIGN_SIZE | HBM_USE_MEM_FB;
+            info.expectedSize = stride * (uint16_t)layerInfo.height;
+            info.usage = HBM_USE_ASSIGN_SIZE | HBM_USE_MEM_FB;
 #endif
+        } else {
+            info.usage = HBM_USE_ASSIGN_SIZE;
+            info.expectedSize = stride * (uint16_t)layerInfo.height;
+        }
+
         GrallocBuffer buffer;
         if (!GrallocEngines::GetInstance()->AllocBuffer(info, buffer)) {
             GRAPHIC_LOGE("AllocMem failed.");
-            goto ERROR;
+            FreeBuffer(layerBuffer, index);
+            return false;
         }
 
-        layer_[layerId].buffer[index].data.virAddr = buffer.virAddr;
-        layer_[layerId].buffer[index].data.phyAddr = reinterpret_cast<uint64_t>(buffer.virAddr);
-        layer_[layerId].buffer[index].width = layer_[layerId].layerInfo.width;
-        layer_[layerId].buffer[index].height = layer_[layerId].layerInfo.height;
+        layerBuffer[index].data.virAddr = buffer.virAddr;
+        layerBuffer[index].data.phyAddr = reinterpret_cast<uint64_t>(buffer.virAddr);
+        layerBuffer[index].width = layerInfo.width;
+        layerBuffer[index].height = layerInfo.height;
+        if (isFb) {
 #if ENABLE_GMMU
-        layer_[layerId].buffer[index].pitch = static_cast<int32_t>(buffer.stride);
+            layerBuffer[index].pitch = static_cast<int32_t>(buffer.stride);
 #else
-        layer_[layerId].buffer[index].pitch = (int32_t)stride;
+            layerBuffer[index].pitch = (int32_t)stride;
 #endif
-        layer_[layerId].buffer[index].pixFormat = layer_[layerId].layerInfo.pixFormat;
+        } else {
+            layerBuffer[index].pitch = (int32_t)stride;
+        }
+        layerBuffer[index].pixFormat = layerInfo.pixFormat;
         ++index;
     }
+
     return true;
-ERROR:
-    for (uint8_t i = 0; i < index; i++) {
-        GrallocEngines::GetInstance()->FreeBuffer((uint8_t*)layer_[layerId].buffer[i].data.virAddr);
-        ClearLayerBuffer(layer_[layerId].buffer[i]);
+}
+
+void DisplayDev::FreeBuffer(LayerBuffer *buffer, uint8_t count)
+{
+    if (buffer == nullptr || count == 0) {
+        return;
+    }
+
+    for (uint8_t i = 0; i < count; i++) {
+        GrallocEngines::GetInstance()->FreeBuffer(reinterpret_cast<uint8_t*>(buffer[i].data.virAddr));
+        ClearLayerBuffer(buffer[i]);
     }
-    return false;
+}
+
+bool DisplayDev::AllocLayerBuffer(uint8_t layerId)
+{
+    if (layerId < LAYER_0 || layerId >= LAYER_MAX || layer_[layerId].bufferCount == 0) {
+        GRAPHIC_LOGE("Invalid layerId[%u] or layer is not opened.", layerId);
+        return false;
+    }
+
+    if (layer_[layerId].buffer[0].data.virAddr != nullptr) {
+        GRAPHIC_LOGE("layer[%u] : Memory of buffers is already allocated.", layerId);
+        return false;
+    }
+
+    if (layer_[layerId].rotate != nullptr) {
+        if (!AllocBuffer(layer_[layerId].buffer, layer_[layerId].layerInfo, layer_[layerId].bufferCount)) {
+            return false;
+        }
+        if (!AllocBuffer(layer_[layerId].rotate, layer_[layerId].rotateInfo, layer_[layerId].bufferCount, false)) {
+            FreeBuffer(layer_[layerId].buffer, layer_[layerId].bufferCount);
+            return false;
+        }
+    } else {
+        if (!AllocBuffer(layer_[layerId].buffer, layer_[layerId].layerInfo, layer_[layerId].bufferCount)) {
+            return false;
+        }
+    }
+    return true;
 }
 
 void DisplayDev::FreeLayerBuffer(uint8_t layerId)
@@ -356,9 +579,9 @@ void DisplayDev::FreeLayerBuffer(uint8_t layerId)
         return;
     }
 
-    for (uint8_t i = 0; i < layer_[layerId].bufferCount; i++) {
-        GrallocEngines::GetInstance()->FreeBuffer((uint8_t*)layer_[layerId].buffer[i].data.virAddr);
-        ClearLayerBuffer(layer_[layerId].buffer[i]);
+    FreeBuffer(layer_[layerId].buffer, layer_[layerId].bufferCount);
+    if (layer_[layerId].rotate != nullptr) {
+        FreeBuffer(layer_[layerId].rotate, layer_[layerId].bufferCount);
     }
 }
 
@@ -386,7 +609,10 @@ void DisplayDev::SetLayerDirtyRegion(uint8_t layerId, const Rect& rect)
 
     if (layerFuncs_->SetLayerDirtyRegion != nullptr) {
         FRAME_TRACE_SET_RECT(rect);
-        IRect iRect = {rect.GetX(), rect.GetY(), rect.GetWidth(), rect.GetHeight()};
+        Rect outRect = rect;
+        GetRotateRect(
+            layer_[layerId].layerInfo.width, layer_[layerId].layerInfo.height, outRect, layer_[layerId].rotateType);
+        IRect iRect = {outRect.GetX(), outRect.GetY(), outRect.GetWidth(), outRect.GetHeight()};
         if (layerFuncs_->SetLayerDirtyRegion(devId_, layer_[layerId].layerHdl, &iRect) !=
             DISPLAY_SUCCESS) {
             GRAPHIC_LOGE("SetLayerDirtyRegion failed. LayerId: %u.", layerId);
@@ -478,6 +704,7 @@ void DisplayDev::DisplayDevInit()
     }
 
     LayerInfo layerInfo;
+    LayerRotateType type = static_cast<LayerRotateType>(HW_ROTATE_ANGLE);
     layerInfo.width = HORIZONTAL_RESOLUTION;
     layerInfo.height = VERTICAL_RESOLUTION;
     layerInfo.pixFormat = layerPixFmt_;
@@ -485,7 +712,7 @@ void DisplayDev::DisplayDevInit()
     layerInfo.type = LAYER_TYPE_GRAPHIC;
 
     uint8_t bufferCount = IsDoubleBuffer() ? 2 : 1;
-    if (!OpenLayer(LAYER_0, layerInfo, bufferCount)) {
+    if (!OpenLayer(LAYER_0, layerInfo, bufferCount, type)) {
         GRAPHIC_LOGE("OpenLayer failed.");
         return;
     }
@@ -520,4 +747,93 @@ void DisplayDev::DisplayDevClose()
     }
     isDisplayDevInited_ = false;
 }
+
+#if defined(HW_ROTATE_ANGLE)
+static void ConvertPixelFormat2ColorMode(ColorMode& mode, PixelFormat fmt)
+{
+    switch (fmt) {
+        case PIXEL_FMT_RGBA_8888:
+            mode = ARGB8888;
+            break;
+        case PIXEL_FMT_RGB_888:
+            mode = RGB888;
+            break;
+        default:
+            mode = UNKNOW;
+            break;
+    }
+}
+
+bool LiteMGfxEngine::RotateBufferIfNecessary()
+{
+    LayerRotateType rotateType = DisplayDev::GetInstance()->GetLayerRotateType(LAYER_0);
+    if (rotateType == LayerRotateType::LAYER_ROTATE_NONE) {
+        return true;
+    }
+    LayerBuffer* rotateBuffer = DisplayDev::GetInstance()->GetCurrentBuffer(LAYER_0);
+    LayerBuffer* buffer = DisplayDev::GetInstance()->GetCurrentRotateBuffer(LAYER_0);
+    if (rotateBuffer == nullptr || rotateBuffer->data.virAddr == nullptr ||
+        buffer == nullptr || buffer->data.virAddr == nullptr) {
+        return false;
+    }
+
+    int32_t rotateBufferWidth = rotateBuffer->width;
+    int32_t rotateBufferHeight = rotateBuffer->height;
+
+    BufferInfo src;
+    src.rect = {0, 0, static_cast<int16_t>(rotateBuffer->width - 1), static_cast<int16_t>(rotateBuffer->height - 1)};
+    src.virAddr = rotateBuffer->data.virAddr;
+    src.phyAddr = src.virAddr;
+    src.stride = rotateBuffer->pitch;
+    ConvertPixelFormat2ColorMode(src.mode, rotateBuffer->pixFormat);
+    src.color = 0;
+    src.width = rotateBuffer->width;
+    src.height = rotateBuffer->height;
+    src.compressMode = COMPRESS_MODE_NONE;
+
+    BufferInfo dst;
+    dst.rect = {0, 0, static_cast<int16_t>(buffer->width - 1), static_cast<int16_t>(buffer->height - 1)};
+    dst.virAddr = buffer->data.virAddr;
+    dst.phyAddr = dst.virAddr;
+    dst.stride = buffer->pitch;
+    ConvertPixelFormat2ColorMode(dst.mode, buffer->pixFormat);
+    dst.color = 0;
+    dst.width = buffer->width;
+    dst.height = buffer->height;
+    dst.compressMode = COMPRESS_MODE_NONE;
+
+    BlendOption blendOption;
+
+    switch (rotateType) {
+        case LayerRotateType::LAYER_ROTATE_90: {
+            float rotAngle = 90;
+            blendOption.transMap.Rotate(rotAngle, Vector2<float>{0, 0});
+            blendOption.transMap.Translate(Vector2<int16_t>{static_cast<int16_t>(src.height), 0});
+            break;
+        }
+        case LayerRotateType::LAYER_ROTATE_180: {
+            float rotAngle = 180;
+            blendOption.transMap.Rotate(rotAngle, Vector2<float>{0, 0});
+            blendOption.transMap.Translate(
+                Vector2<int16_t>{static_cast<int16_t>(src.width), static_cast<int16_t>(src.height)});
+            break;
+        }
+        case LayerRotateType::LAYER_ROTATE_270: {
+            float rotAngle = 270;
+            blendOption.transMap.Rotate(rotAngle, Vector2<float>{0, 0});
+            blendOption.transMap.Translate(Vector2<int16_t>{0, static_cast<int16_t>(src.width)});
+            break;
+        }
+        default:
+            GRAPHIC_LOGE("error rotate type %d", rotateType);
+            return false;
+    }
+
+    blendOption.opacity = OPA_OPAQUE;
+    blendOption.mode = BLEND_SRC_OVER;
+    BaseGfxEngine::GetInstance()->Blit(dst, {0, 0}, src, dst.rect, blendOption);
+
+    return true;
+}
+#endif
 } // namespace OHOS
index e07764d..645bfe9 100644 (file)
@@ -126,6 +126,18 @@ void GrallocEngines::FreeBuffer(uint8_t* virAddr)
     }
 }
 
+uint8_t* GrallocEngines::AllocBufferBySize(uint32_t size, uint64_t usage)
+{
+    AllocInfo info;
+    info.expectedSize = size;
+    info.usage = usage;
+    GrallocBuffer buffer;
+    if (!AllocBuffer(info, buffer)) {
+        return nullptr;
+    }
+    return reinterpret_cast<uint8_t*>(buffer.virAddr);
+}
+
 #if ENABLE_MEMORY_CHECK
 void GrallocEngines::DumpMem(bool dumpDetails)
 {
index 2ed0314..413505b 100644 (file)
@@ -36,16 +36,22 @@ void LiteInputDistributer::SendRawEvent(const RawEvent& rawEvent)
 #if !defined(_WIN32)
     RawEvent event = rawEvent;
     DisplayDev* displayDev = DisplayDev::GetInstance();
-    if ((event.type == InputDevType::INDEV_TYPE_TOUCH) &&
-        (displayDev->GetLayerRotateType(LAYER_0) == LayerRotateType::LAYER_ROTATE_90)) {
-        LayerBuffer* buffer = displayDev->GetCurrentBuffer(LAYER_0);
+    if (event.type == InputDevType::INDEV_TYPE_TOUCH) {
+        LayerBuffer *buffer = displayDev->GetCurrentBuffer(LAYER_0);
         if (buffer == nullptr) {
             return;
         }
-
-        int16_t tmp = buffer->height - event.x;
-        event.x = event.y;
-        event.y = tmp;
+        if (displayDev->GetLayerRotateType(LAYER_0) == LayerRotateType::LAYER_ROTATE_90) {
+            int16_t tmp = buffer->height - event.x;
+            event.x = event.y;
+            event.y = tmp;
+        } else if (displayDev->GetLayerRotateType(LAYER_0) == LayerRotateType::LAYER_ROTATE_180) {
+            event.x = buffer->width - event.x;
+            event.y = buffer->height - event.y;
+        } else if (displayDev->GetLayerRotateType(LAYER_0) == LayerRotateType::LAYER_ROTATE_270) {
+            event.x = buffer->width - rawEvent.y;
+            event.y = rawEvent.x;
+        }
     }
 #ifdef CONFIG_SUPPORTED_POWERMGR
     SendEventToPM(event);
index 664c3c9..7773497 100644 (file)
 namespace OHOS {
 void* ImageCacheMalloc(ImageInfo& info)
 {
-    AllocInfo allocInfo;
-    allocInfo.expectedSize = info.dataSize;
-    allocInfo.usage = HBM_USE_ASSIGN_SIZE;
-    GrallocBuffer buffer;
-    if (!GrallocEngines::GetInstance()->AllocBuffer(allocInfo, buffer)) {
+    uint8_t* addr = GrallocEngines::GetInstance()->AllocBufferBySize(info.dataSize);
+    if (addr == nullptr) {
         GRAPHIC_LOGE("ImageCacheMalloc failed! size = %u", info.dataSize);
         return nullptr;
     }
-    info.phyAddr = reinterpret_cast<uint8_t*>(buffer.phyAddr);
-    info.data = reinterpret_cast<uint8_t*>(buffer.virAddr);
+    info.phyAddr = addr;
+    info.data = addr;
     info.fileLen = 0;
     info.resId = 0;
-    return buffer.virAddr;
+    return reinterpret_cast<void*>(addr);
 }
 
-void ImageCacheFree(ImageInfo& info)
+void ImageCacheFree(ImageInfo& info, bool syncHwDraw)
 {
     if (info.data == nullptr) {
         return;
     }
 
-    LiteMGfxEngine::GetInstance()->SyncHwDraw();
+    if (syncHwDraw) {
+        LiteMGfxEngine::GetInstance()->SyncHwDraw();
+    }
     GrallocEngines::GetInstance()->FreeBuffer(const_cast<uint8_t*>(info.data));
     info.phyAddr = nullptr;
     info.data = nullptr;
index 24707c0..26518b3 100644 (file)
@@ -141,7 +141,13 @@ public:
 
     LayerBuffer* GetNextBuffer(uint8_t layerId);
 
-    uint32_t CalcStride(uint32_t width, PixelFormat fmt);
+    LayerBuffer* GetCurrentRotateBuffer(uint8_t layerId);
+
+    void GetRotatePosition(int32_t width, int32_t height, int32_t &x, int32_t &y, LayerRotateType type) const;
+    void GetRotateRect(int32_t width, int32_t height, Rect &rect, LayerRotateType type) const;
+
+    uint32_t CalcStride(uint32_t width, PixelFormat fmt, uint8_t cmpMode = 0);
+    uint32_t CalcSize(uint32_t stride, uint32_t height, uint8_t cmpMode);
     bool IsUlpsEnabled(void);
     bool TryExitUlps(bool isFlushing);
     bool IsDoubleBuffer(void);
@@ -155,8 +161,10 @@ public:
     struct Layer {
         uint32_t layerHdl;
         LayerInfo layerInfo;
+        LayerInfo rotateInfo;
         uint8_t bufferCount;
         LayerBuffer* buffer;
+        LayerBuffer* rotate;
         LayerRotateType rotateType;
         Point pos;
     };
@@ -165,6 +173,8 @@ public:
 private:
     DisplayDev();
     virtual ~DisplayDev() {}
+    bool AllocBuffer(LayerBuffer *layerBuffer, const LayerInfo &layerInfo, uint8_t count, bool isFb = true);
+    void FreeBuffer(LayerBuffer *buffer, uint8_t count);
 
     bool isDisplayDevInited_ : 1;
     uint32_t devId_;
index e83c506..38a5af8 100644 (file)
@@ -39,8 +39,8 @@ public:
     bool Init();
 
     bool AllocBuffer(const AllocInfo& info, GrallocBuffer& buffer);
-    bool AllocBufferOnce(const AllocInfo& info, GrallocBuffer& buffer);
     void FreeBuffer(uint8_t* virAddr);
+    uint8_t* AllocBufferBySize(uint32_t size, uint64_t usage = HBM_USE_ASSIGN_SIZE);
 #if ENABLE_MEMORY_CHECK
     void DumpMem(bool dumpDetails = false);
     void SetMemMonitor(bool enable);
index 83db466..1249ec6 100644 (file)
@@ -71,7 +71,7 @@ void UITestCanvasExt::SetUp()
     SetUpBtn(addSquareBtn_, "Add Square", X_300, 0); // 0: Y coordinate
     SetUpBtn(addSectorBtn_, "Add Sector", X_300, 60); // 60: Y coordinate
     SetUpBtn(clearBtn_, "Clear", X_300, 120); // 120: Y coordinate
-    SetUpBtn(transBtn_, "Y: +150", X_300, 180); // 180: Y coordinate
+    SetUpBtn(transBtn_, "Y: +100", X_300, 180); // 180: Y coordinate
     SetUpBtn(scaleBtn_, "Scale 0.5", X_300, 240); // 240: Y coordinate
     SetUpBtn(rotateBtn_, "Rotate 90", X_300, 300); // 300: Y coordinate
     SetUpBtn(matrixBtn_, "Matrix", X_300, 360); // 360: Y coordinate
@@ -191,10 +191,13 @@ const UIView* UITestCanvasExt::GetTestView()
 {
     DrawArc(canvas_);
     DrawRect(canvas_);
+    DrawRoundRect(canvas_);
     DrawLine(canvas_);
     DrawCurve(canvas_);
     Draw123(canvas_);
     DrawPattern(canvas_);
+    DrawImage(canvas_);
+    DrawLabel(canvas_);
     return container_;
 }
 
@@ -304,6 +307,22 @@ void UITestCanvasExt::DrawRect(UICanvasExt* canvas)
     }
 }
 
+void UITestCanvasExt::DrawRoundRect(UICanvasExt* canvas)
+{
+    PaintExt paint;
+    paint.SetStyle(Paint::PaintStyle::STROKE_FILL_STYLE);
+    paint.SetStrokeWidth(10); // 10: stroke width
+    paint.SetStrokeColor(Color::Purple());
+    paint.SetOpacity(125); // 125: opa
+    paint.SetFillColor(Color::Navy());
+    paint.SetFillRule(FillRule::EVEN_ODD);
+    paint.SetAntialiased(true);
+    int16_t index = canvas->DrawRect({240, 220}, 50, 50, paint, 10); // 240, 220, 50, 10 : coordinate, radius
+    if (matrixIndex_ == -1) {
+        matrixIndex_ = index;
+    }
+}
+
 void UITestCanvasExt::DrawArc(UICanvasExt* canvas)
 {
     PaintExt paint;
@@ -340,6 +359,15 @@ void UITestCanvasExt::DrawArc(UICanvasExt* canvas)
     canvas->DrawArc({cx, cy}, 30, 10, 390, paint); // 30, 10, 390: radius, startAngle, endAngle
     canvas->DrawArc({cx, cy}, 35, 380, 270, paint); // 35, 380, 270: radius, startAngle, endAngle
     canvas->DrawArc({cx, cy}, 40, 540, 630, paint); // 40, 540, 630: radius, startAngle, endAngle
+
+    cx += 100; // 100: offset
+    paint.SetStyle(Paint::PaintStyle::FILL_STYLE);
+    paint.SetFillColor(Color::Red());
+    paint.SetOpacity(OPA_OPAQUE);
+    canvas->DrawArc({cx, cy}, 40, 270, 360, paint); // 40, 270, 360: radius, startAngle, endAngle
+    canvas->DrawArc({cx, cy}, 40, 0, 90, paint); // 40, 0, 90: radius, startAngle, endAngle
+    canvas->DrawArc({cx, cy}, 40, 90, 180, paint); // 40, 90, 180: radius, startAngle, endAngle
+    canvas->DrawArc({cx, cy}, 40, 180, 270, paint); // 40, 180, 270: radius, startAngle, endAngle
 }
 
 void UITestCanvasExt::DrawSector(UICanvasExt* canvas)
@@ -369,6 +397,44 @@ void UITestCanvasExt::DrawPattern(UICanvasExt* canvas)
     canvas->DrawRect({0, 0}, 160, 160, paint); // 160, 160: left, top, width, height
     Matrix3<float> mat2(1, 0, 0, 0, 1, 0, 250, 370, 1); // 250, 370: x/y axis translate
     canvas->SetMatrix(mat2);
+
+    paint.SetStyle(Paint::PaintStyle::STROKE_STYLE);
+    paint.SetStrokeWidth(10); // 10: stroke width
+    Matrix3<float> patternMat3(1, 0, 0, 0, 1, 0, 0, 0, 1);
+    paint.SetWrapPattern(PatternType::PATTERN_FILL, Color::Yellow().full, patternMat3, *img_);
+    canvas->DrawArc({0, 0}, 40, 0, 360, paint); // 40, 0, 360: radius, startAngle, endAngle
+    Matrix3<float> mat3(1, 0, 0, 0, 1, 0, 100, 500, 1); // 100, 500: x/y axis translate
+    canvas->SetMatrix(mat3);
+}
+
+void UITestCanvasExt::DrawImage(UICanvasExt* canvas)
+{
+    PaintExt paint;
+    canvas->DrawImage({200, 400}, RES_PATH"PROGRESS_BAR_TMAGE.bin", paint); // 200, 400: startPoint
+    Matrix3<float> mat(1, 0, 0, 0, 1, 0, 50, 0, 1); // 50: x axis translate
+    canvas->SetMatrix(mat);
+
+    paint.Scale(0.5, 0.5); // 0.5: scale factor
+    paint.Rotate(30, 200, 400); // 30: rotate angle, 200, 400: coordinates
+    paint.Translate(0, 50); // 50: y axis translate
+    canvas->DrawImage({200, 400}, RES_PATH"haha.bin", paint); // 200, 400: startPoint
+}
+
+void UITestCanvasExt::DrawLabel(UICanvasExt* canvas)
+{
+    PaintExt paint;
+    paint.SetFillColor(Color::Blue());
+    UICanvasExt::FontStyle fontStyle;
+    fontStyle.align = TEXT_ALIGNMENT_LEFT;
+    fontStyle.direct = TEXT_DIRECT_LTR;
+    fontStyle.fontName = DEFAULT_VECTOR_FONT_FILENAME;
+    fontStyle.fontSize = 10;    // 10: font size
+    fontStyle.letterSpace = 5; // 5 letter space
+    // {180, 30}: start point coordinates, 100: max width
+    canvas->DrawLabel({180, 30}, "canvasext label绘制", 100, fontStyle, paint);
+    Matrix3<float> rotate =  Matrix3<float>::Rotate(45, {180.0f, 30.0f}); // 180.0f, 30.0f: coordinates, 45: angle
+    canvas->SetMatrix(rotate);
 }
+
 #endif
 }
index ffe4ca4..85cf839 100644 (file)
@@ -53,11 +53,14 @@ private:
     void Add3(UICanvasExt* canvas);
     void DrawCurve(UICanvasExt* canvas);
     void DrawRect(UICanvasExt* canvas);
+    void DrawRoundRect(UICanvasExt* canvas);
     void DrawLine(UICanvasExt* canvas);
     void DrawArc(UICanvasExt* canvas);
     void DrawSector(UICanvasExt* canvas);
     void SetUpBtn(UILabelButton*& btn, const char* text, int16_t x, int16_t y);
     void DrawPattern(UICanvasExt* canvas);
+    void DrawImage(UICanvasExt* canvas);
+    void DrawLabel(UICanvasExt* canvas);
     int16_t matrixIndex_ = -1;
     UICanvasExt* canvas_ = nullptr;
     UILabelButton* addSquareBtn_ = nullptr;
diff --git a/code/sdk/middleware/services/gui/uikit/sample/uitest/components/ui_test_lottie/ui_test_lottie.cpp b/code/sdk/middleware/services/gui/uikit/sample/uitest/components/ui_test_lottie/ui_test_lottie.cpp
new file mode 100644 (file)
index 0000000..6d0d7f1
--- /dev/null
@@ -0,0 +1,92 @@
+/*\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025. All rights reserved.\r
+ * Description: Lottie Test\r
+ * Author: Hisi Graphic Team\r
+ * Created: 2025-6\r
+ */\r
+\r
+#include "ui_test_lottie.h"\r
+#include "common/image_cache_manager.h"\r
+\r
+namespace OHOS {\r
+constexpr uint8_t FILE_MAX = 8;\r
+static char* g_filePath[FILE_MAX] = {\r
+    RES_PATH"2016_lottie.bin",\r
+    RES_PATH"singing-contract.bin",\r
+    RES_PATH"girl-cycling-in-autumn.bin",\r
+    RES_PATH"loading.bin",\r
+    RES_PATH"ripple_loading_animation.bin",\r
+    RES_PATH"starts_transparent.bin",\r
+    RES_PATH"fingerprint_success.bin",\r
+    RES_PATH"intelia_logo_animation.bin",\r
+};\r
+\r
+void UITestLottie::SetUp()\r
+{\r
+    fileIndex_ = 0;\r
+    if (container_ == nullptr) {\r
+        container_ = new UIViewGroup();\r
+    }\r
+    container_->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight());\r
+    container_->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE);\r
+    container_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full);\r
+\r
+    if (lottieView_ == nullptr) {\r
+        lottieView_ = new UILottView();\r
+        lottieView_->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight());\r
+        lottieView_->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE);\r
+        lottieView_->SetStyle(STYLE_BACKGROUND_COLOR, Color::White().full);\r
+        if (lottieView_->SetSrc(g_filePath[fileIndex_])) {\r
+            lottieView_->Start();\r
+        }\r
+        fileIndex_++;\r
+    }\r
+    container_->Add(lottieView_);\r
+\r
+    startBtn_ = new UILabelButton();\r
+    startBtn_->SetPosition(167, 400, 60, 50); // 167, 400, 60, 50: coordinate\r
+    startBtn_->SetOnClickListener(this);\r
+    startBtn_->SetText("Start");\r
+    container_->Add(startBtn_);\r
+\r
+    switchBtn_ = new UILabelButton();\r
+    switchBtn_->SetPosition(237, 400, 60, 50); // 237, 400, 60, 50: coordinate\r
+    switchBtn_->SetOnClickListener(this);\r
+    switchBtn_->SetText("Switch");\r
+    container_->Add(switchBtn_);\r
+}\r
+\r
+void UITestLottie::TearDown()\r
+{\r
+    DeleteChildren(container_);\r
+    lottieView_ = nullptr;\r
+    startBtn_ = nullptr;\r
+    switchBtn_ = nullptr;\r
+    container_ = nullptr;\r
+}\r
+\r
+bool UITestLottie::OnClick(UIView& view, const ClickEvent& event)\r
+{\r
+    if (&view == startBtn_) {\r
+        if (lottieView_ != nullptr) {\r
+            lottieView_->Start();\r
+        }\r
+    }\r
+    if (&view == switchBtn_) {\r
+        if (lottieView_ != nullptr) {\r
+            lottieView_->SetSrc(g_filePath[fileIndex_]);\r
+            fileIndex_++;\r
+            if (fileIndex_ == FILE_MAX) {\r
+                fileIndex_ = 0;\r
+            }\r
+            lottieView_->Start();\r
+        }\r
+    }\r
+    return true;\r
+}\r
+\r
+const UIView* UITestLottie::GetTestView()\r
+{\r
+    return container_;\r
+}\r
+}
\ No newline at end of file
diff --git a/code/sdk/middleware/services/gui/uikit/sample/uitest/components/ui_test_lottie/ui_test_lottie.h b/code/sdk/middleware/services/gui/uikit/sample/uitest/components/ui_test_lottie/ui_test_lottie.h
new file mode 100644 (file)
index 0000000..97b1aa2
--- /dev/null
@@ -0,0 +1,33 @@
+/*\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2025. All rights reserved.\r
+ * Description: Lottie Test\r
+ * Author: Hisi Graphic Team\r
+ * Created: 2025-6\r
+ */\r
+\r
+#ifndef UI_TEST_LOTTIE_H\r
+#define UI_TEST_LOTTIE_H\r
+\r
+#include "ui_test.h"\r
+#include "lottie/ui_lott_view.h"\r
+#include "components/ui_label_button.h"\r
+\r
+namespace OHOS {\r
+class UITestLottie : public UITest, public UIView::OnClickListener {\r
+public:\r
+    UITestLottie() {}\r
+    ~UITestLottie() override {}\r
+    void SetUp() override;\r
+    void TearDown() override;\r
+    const UIView* GetTestView() override;\r
+    bool OnClick(UIView& view, const ClickEvent& event) override;\r
+\r
+private:\r
+    UIViewGroup* container_ = nullptr;\r
+    UILottView* lottieView_ = nullptr;\r
+    UILabelButton* startBtn_ = nullptr;\r
+    UILabelButton* switchBtn_ = nullptr;\r
+    uint8_t fileIndex_ = 0;\r
+};\r
+}\r
+#endif
\ No newline at end of file
index 2913115..bfd6638 100644 (file)
@@ -87,6 +87,7 @@
 #include "ui_test_transform_list/ui_test_scale_list.h"
 #include "ui_test_emoji/ui_test_emoji.h"
 #include "ui_test_particle/ui_test_particle.h"
+#include "ui_test_lottie/ui_test_lottie.h"
 
 namespace OHOS {
 void UITestGroup::AddTestCase(TestCaseInfo testCaseInfo)
@@ -104,6 +105,7 @@ void UITestGroup::SetUpTestCase()
         return;
     }
     testCaseList_->Clear();
+    testCaseList_->PushBack(TestCaseInfo{"Lottie", new UITestLottie()});
     testCaseList_->PushBack(TestCaseInfo{"粒子效果", new UITestParticle()});
     testCaseList_->PushBack(TestCaseInfo{"瀑布列表", new UITestWaterfallList()});
     testCaseList_->PushBack(TestCaseInfo{"老虎头", new UITestTiger()});
index 19d9375..24fb435 100644 (file)
@@ -239,12 +239,16 @@ void Text::Draw(BufferInfo& gfxDstBuffer,
         pos.y = TextPositionY(coords, (lineCount * lineHeight - style.lineSpace_));
     }
     OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.textOpa_);
+    bool isTransValid = false;
+    if (transMap_ != nullptr && !transMap_->IsInvalid())  {
+        isTransValid = true;
+    }
     for (int i = 0; i < lineCount; i++) {
-        if (pos.y > mask.GetBottom() || pos.y > coords.GetBottom()) {
+        if (!isTransValid && pos.y > mask.GetBottom()) {
             return;
         }
         int16_t nextLine = pos.y + lineHeight;
-        if (nextLine >= mask.GetTop() && nextLine >= coords.GetTop()) {
+         if (isTransValid || nextLine >= mask.GetTop()) {
             pos.x = LineStartPos(coords, textLine_[i].linePixelWidth);
             LabelLineInfo labelLine{pos, offset, mask, lineHeight, textLine_[i].lineBytes,
                                     0, opa, style, &text_[lineBegin], textLine_[i].lineBytes,
index 1f9c9ae..cc01aa0 100644 (file)
@@ -79,6 +79,12 @@ UIView* TextAdapter::GetView(UIView* inView, int16_t index)
     }
 
     if (label != nullptr) {
+        label->UIView::SetStyle(style_);
+        if (fontName_ == nullptr) {
+            label->SetFontId(fontId_);
+        } else {
+            label->SetFont(fontName_, fontSize_);
+        }
         if (dataMode_ == DYNAMIC_TEXT_MODE) {
             ListNode<const char*>* node = dynamicText_.Begin();
             for (int16_t i = 0; i < index; i++) {
@@ -135,16 +141,10 @@ UILabel* TextAdapter::CreateUILabel()
         newView->SetHeight(height_);
     }
 
-    newView->UIView::SetStyle(style_);
     if (clickListener_) {
         newView->SetOnClickListener(clickListener_);
         newView->SetTouchable(true);
     }
-    if (fontName_ == nullptr) {
-        newView->SetFontId(fontId_);
-    } else {
-        newView->SetFont(fontName_, fontSize_);
-    }
     newView->SetDirect(direct_);
     return newView;
 }
index 711cfe6..8ba6674 100644 (file)
@@ -95,6 +95,12 @@ void UIBoxProgress::DrawRoundCap(BufferInfo& gfxDstBuffer,
             rightTop.y = leftTop.y;
             rightBottom.x = rightTop.x;
             rightBottom.y = leftBottom.y;
+#if CAPABILITY_HWDRAW_ARC
+            leftTop.x += 1;
+            leftTop.y = leftBottom.y;
+            rightTop.y = leftTop.y;
+            leftBottom.x = leftTop.x;
+#endif
             break;
         }
 
@@ -108,6 +114,12 @@ void UIBoxProgress::DrawRoundCap(BufferInfo& gfxDstBuffer,
             leftBottom.y = rect.GetBottom() + 1;
             rightBottom.x = rightTop.x;
             rightBottom.y = leftBottom.y;
+#if CAPABILITY_HWDRAW_ARC
+            leftTop.x = rightTop.x;
+            leftTop.y += 1;
+            rightTop.y = leftTop.y;
+            leftBottom.x = leftTop.x;
+#endif
             break;
         }
         default:
index eab2bb8..6edd9b5 100644 (file)
@@ -61,10 +61,29 @@ void UICircleProgress::GetStartEndAngle(int16_t& start, int16_t& end) const
     }
 }
 
+#if ENABLE_VGU_ENGINE && CAPABILITY_HWDRAW_PATH
+static void HwGetAngleRange(int16_t &start, int16_t &end)
+{
+    int16_t range = end - start;
+    int16_t absRange = (range < 0 ? -range : range);
+    if (absRange >= CIRCLE_IN_DEGREE) {
+        start = 0;
+        end = CIRCLE_IN_DEGREE;
+        return;
+    }
+    start = (start < 0 ? (start % CIRCLE_IN_DEGREE + CIRCLE_IN_DEGREE) : (start % CIRCLE_IN_DEGREE));
+    end = start + range;
+}
+#endif
+
 void UICircleProgress::GetAngleRange(int16_t& start, int16_t& end) const
 {
     GetStartEndAngle(start, end);
+#if ENABLE_VGU_ENGINE && CAPABILITY_HWDRAW_PATH
+    HwGetAngleRange(start, end);
+#else
     DrawArc::GetInstance()->GetDrawRange(start, end);
+#endif
 }
 
 void UICircleProgress::GetRedrawAngle(int16_t& start, int16_t& end) const
@@ -84,9 +103,13 @@ void UICircleProgress::GetRedrawAngle(int16_t& start, int16_t& end) const
     } else {
         end = angle + start;
     }
+#if ENABLE_VGU_ENGINE && CAPABILITY_HWDRAW_PATH
+    HwGetAngleRange(start, end);
+#else
     DrawArc::GetInstance()->GetDrawRange(start, end);
+#endif
 }
-
+#if ENABLE_VGU_ENGINE && CAPABILITY_HWDRAW_PATH
 void UICircleProgress::DrawForegroundGradient(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea,
         const Point& point, const uint16_t& radius, const Vector2<float>& angle)
 {
@@ -112,7 +135,7 @@ void UICircleProgress::DrawForegroundGradient(BufferInfo& gfxDstBuffer, const Re
     int16_t strokeWidth = foregroundStyle_->lineWidth_;
     RenderGradientStroke(gfxDstBuffer, invalidatedArea, strokeWidth);
 }
-
+#endif
 void UICircleProgress::DrawCommonCircle(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea)
 {
     ArcInfo arcinfo = {{0}};
@@ -144,11 +167,13 @@ void UICircleProgress::DrawCommonCircle(BufferInfo& gfxDstBuffer, const Rect& in
         arcinfo.startAngle = startAngle;
         arcinfo.endAngle = endAngle;
         arcinfo.imgSrc = foregroundImage_;
+#if ENABLE_VGU_ENGINE && CAPABILITY_HWDRAW_PATH
         if (foregroundStopCount_ != 0) {
             DrawForegroundGradient(gfxDstBuffer, invalidatedArea, arcinfo.center,
                 arcinfo.radius, Vector2<float>{arcinfo.startAngle, arcinfo.endAngle});
             return;
         }
+#endif
         BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcinfo, invalidatedArea, *foregroundStyle_, opaScale_,
                                               foregroundStyle_->lineCap_);
     }
index 8e364e7..0bd240e 100644 (file)
@@ -297,7 +297,7 @@ void UIPicker::RefreshList()
     itemsWidth_ = GetWidth();
     textAdapter_->SetWidth(itemsWidth_);
     textAdapter_->SetHeight(itemsHeight_);
-    textAdapter_->SetLineBreakMode(UILabel::LINE_BREAK_CLIP);
+    textAdapter_->SetLineBreakMode(lineBreakMode_);
     if (backgroundFontName_ == nullptr) {
         textAdapter_->SetFontId(backgroundFontId_);
     } else {
@@ -459,6 +459,13 @@ void UIPicker::SetItemHeight(int16_t height)
     }
 }
 
+void UIPicker::SetTextLineBreakMode(const uint8_t lineBreakMode)
+{
+    InitTextAdapter();
+    lineBreakMode_ = lineBreakMode;
+    Refresh();
+}
+
 void UIPicker::SetWidth(int16_t width)
 {
     if (width > 0) {
index 43ed8fc..d14718d 100644 (file)
@@ -170,7 +170,7 @@ void UIViewGroup::RemoveAndDeleteAllRecursively(UIViewGroup*& group)
 
     UIViewType type = group->GetViewType();
     if ((type == UI_DIGITAL_CLOCK) || (type == UI_PICKER) || (type == UI_TIME_PICKER) || (type == UI_MENU_ITEM) ||
-        (type == UI_IMAGE_PICKER) || (type == UI_ROLLER_VIEW) || (type == UI_COVER_FLOW)) {
+        (type == UI_IMAGE_PICKER) || (type == UI_ROLLER_VIEW) || (type == UI_COVER_FLOW) || (type == UI_LIST)) {
         delete group;
         group = nullptr;
         return;
@@ -195,6 +195,8 @@ void UIViewGroup::RemoveAndDeleteAllRecursively(UIViewGroup*& group)
             UIViewGroup* tmpGroup = dynamic_cast<UIViewGroup*>(tmp);
             RemoveAndDeleteAllRecursively(tmpGroup);
         } else {
+            tmp->SetParent(nullptr);
+            tmp->SetNextSibling(nullptr);
             delete tmp;
         }
     }
index 4c36db7..ecf5bbd 100644 (file)
@@ -200,7 +200,7 @@ int16_t UIFontVector::GetEmojiHeight()
     return GetHeight();
 }
 
-uint16_t UIFontVector::GetEmojiWidth(uint32_t unicode, uint8_t fontId)
+int16_t UIFontVector::GetEmojiWidth(uint32_t unicode, uint8_t fontId)
 {
     ImageInfo info;
     if (!GetEmoji(unicode, info)) {
index e777127..c920bbc 100644 (file)
@@ -50,7 +50,7 @@ public:
     int32_t OpenVectorFont(uint8_t ttfId) override;
     bool GetEmoji(uint32_t unicode, ImageInfo &unicodeInfo);
     int16_t GetEmojiHeight();
-    uint16_t GetEmojiWidth(uint32_t unicode, uint8_t fontId);
+    int16_t GetEmojiWidth(uint32_t unicode, uint8_t fontId);
 
 protected:
     bool freeTypeInited_;
index e07b636..7fc5f84 100644 (file)
@@ -249,9 +249,10 @@ private:
     void GetAngleRange(int16_t& start, int16_t& end) const;
     void GetRedrawAngle(int16_t& start, int16_t& end) const;
     void DrawCommonCircle(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea);
+#if ENABLE_VGU_ENGINE && CAPABILITY_HWDRAW_PATH
     void DrawForegroundGradient(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea,
         const Point& point, const uint16_t& radius, const Vector2<float>& angle);
-
+#endif
     Point center_;
     Point backgroundImagePos_;
     Point progressImagePos_;
index ee74f29..8a45210 100644 (file)
@@ -134,6 +134,15 @@ public:
      */
     void SetBackgroundFont(const char* name, uint8_t size);
 
+    /**
+     * @brief Sets the line break mode for text.
+     *
+     * @param lineBreakMode Indicates the line break mode numebr to set.
+     * @since 1.0
+     * @version 1.0
+     */
+    void SetTextLineBreakMode(const uint8_t lineBreakMode);
+
     /**
      * @brief Sets the font name and size for the highlighted text.
      *
index c05695b..10412f9 100644 (file)
@@ -115,12 +115,15 @@ public:
     virtual void RemoveAll();
 
     /**
-     * @brief Removes and delete all child views recursively. this method have some limitation:
-     *        1. Some UI group views delete children in their destructor function, don't delete them repeatly in this
-     *        function in this situation. some special treatment has already been done for below basic UI group views:
-     *            UIPicker UITimePicker UIImagePicker UIDigitalClock UIRollerView UICoverFlow UIMenuItem
-     *        However, the custom UI group views was ignored in this function, so be carefully when using this method.
-     *        2. Not all children in UICrossView are deleted in this method, you should remove UICardPages in addtion.
+     * @brief Removes and delete all children views recursively. The following points should be noted:
+     *        1. If the group and its child views don't delete their child views in their destructior function,
+     *           you can use this mehod safely.
+     *        2. If the group or its child views delete (all/some of) their child views in their destructor function,
+     *           don't delete it using this method unless it have been specially handled. for example:
+     *           2.1 if delete all, You can delete it using this method:
+     *               - UIPicker UITimePicker UIImagePicker UIDigitalClock UIRollerView UICoverFlow UIMenuItem UIList
+     *           2.2 if delete some, You can delete it using this method, and need to delete other children mannually:
+     *               - UICrossView
      * @since 1.0
      * @version 1.0
      */
index ebb78c2..d9464bc 100644 (file)
@@ -33,7 +33,7 @@ void* ImageCacheMalloc(ImageInfo& info)
 #endif
 }
 
-void ImageCacheFree(ImageInfo& info)
+void ImageCacheFree(ImageInfo& info, bool syncHwDraw)
 {
     uint8_t* buf = const_cast<uint8_t*>(info.data);
 #if ENABLE_MEMORY_CHECK
index 18e4bb2..606fd90 100644 (file)
@@ -573,10 +573,17 @@ static constexpr uint8_t DEFAULT_VECTOR_FONT_SIZE = 18;
 #define DEFAULT_LINE_BREAK_RULE_FILENAME   "line_cj.brk"
 /* Defines some configurations and their default values on LiteOS and other system platforms. */
 #ifdef VERSION_IOT
+#if HW_ROTATE_ANGLE == 0 || HW_ROTATE_ANGLE == 2
 /* Resolution width of a graphics display screen. The default value is <b>454</b>. */
 static constexpr int16_t HORIZONTAL_RESOLUTION = RESOLUTION_WIDTH;
 /* Resolution height of a graphics display screen. The default value is <b>454</b>. */
 static constexpr int16_t VERTICAL_RESOLUTION = RESOLUTION_HEIGHT;
+#else
+/* Resolution width of a graphics display screen. The default value is <b>454</b>. */
+static constexpr int16_t HORIZONTAL_RESOLUTION = RESOLUTION_HEIGHT;
+/* Resolution height of a graphics display screen. The default value is <b>454</b>. */
+static constexpr int16_t VERTICAL_RESOLUTION = RESOLUTION_WIDTH;
+#endif
 #elif defined _LITEOS
 /* Resolution width of a graphics display screen. The default value is <b>454</b>. */
 static constexpr int16_t HORIZONTAL_RESOLUTION = RESOLUTION_WIDTH;
index a16c1c3..f85e4be 100644 (file)
@@ -184,5 +184,40 @@ private:
     pthread_cond_t cond_;
 #endif
 };
+
+// do not support multi-thread
+class GraphicLockGuard {
+public:
+    explicit GraphicLockGuard(GraphicMutex& mutex) : mutex_(mutex)
+    {
+        Lock();
+    }
+    ~GraphicLockGuard()
+    {
+        Unlock();
+    }
+    void Lock()
+    {
+        mutex_.Lock();
+        lockCnt_++;
+    }
+    void Unlock()
+    {
+        if (lockCnt_ > 0) {
+            mutex_.Unlock();
+            lockCnt_--;
+        }
+    }
+
+    GraphicLockGuard() = delete;
+    GraphicLockGuard(const GraphicLockGuard&) = delete;
+    GraphicLockGuard(const GraphicLockGuard&&) = delete;
+    GraphicLockGuard& operator=(const GraphicLockGuard&) = delete;
+    GraphicLockGuard& operator=(const GraphicLockGuard&&) = delete;
+
+private:
+    GraphicMutex& mutex_;
+    int8_t lockCnt_ = 0;
+};
 } // namespace OHOS
 #endif // GRAPHIC_LITE_GRAPHIC_MUTEX_H
\ No newline at end of file
index 0b53989..1040f0e 100644 (file)
@@ -58,7 +58,7 @@ void* ImageCacheMalloc(ImageInfo& info);
  * @since 1.0
  * @version 1.0
  */
-void ImageCacheFree(ImageInfo& info);
+void ImageCacheFree(ImageInfo& info, bool syncHwDraw = true);
 
 /**
  * @brief Applies for memory for the graphics module. You can implement this function to override the <b>malloc</b> and