[Adaptation Layer] Added rive-tizen adaptation layer class. 82/279782/2 accepted/tizen/unified/20220824.135622 submit/tizen/20220823.073856
authorMichal Szczecinski <mihashco89@gmail.com>
Sat, 13 Aug 2022 08:15:19 +0000 (10:15 +0200)
committerMichal Szczecinski <mihashco89@gmail.com>
Thu, 18 Aug 2022 10:38:48 +0000 (12:38 +0200)
RiveTizen class is an adapter between two versions of rive-cpp. This
allows us to seamlessly update the rive-cpp version, which in some cases
provides a new API without breaking the entire dependency system.

Update process will be performed in 3 or 4 steps:
1. Merge this commit
2. Use introduced class in the dali extension code.
3. Update rive-cpp
4. Remove or left adapter for future changes.

Change-Id: I9cb26a7c4b875bdbb20830d5a286150bdbb46ced

inc/rive_tizen.hpp
meson.build
packaging/rive-tizen.spec
src/renderer/meson.build
src/rive_tizen.cpp

index be92d0e..7bbf0aa 100644 (file)
@@ -1,5 +1,41 @@
+#ifndef _RIVE_TIZEN_HPP_
+#define _RIVE_TIZEN_HPP_
+
 #include <iostream>
 
+#include <artboard.hpp>
+#include <file.hpp>
+#include <animation/linear_animation_instance.hpp>
+
 #define RIVE_EXPORT __attribute__ ((visibility ("default")))
 
 RIVE_EXPORT void rive_tizen_print();
+
+#include <vector>
+
+class RiveTizen {
+    private:
+        rive::Artboard *mArtboard; ///< Loaded artboard
+
+    public:
+        RiveTizen();
+        ~RiveTizen();
+
+        rive::Artboard* getArtboard();
+        rive::LinearAnimationInstance* createLinearAnimationInstance(size_t index);
+        void animationAdvanceApply(rive::LinearAnimationInstance* animation, double elapsed);
+        void animationApply(rive::LinearAnimationInstance* animation, double elapsed);
+
+        bool loadRiveResource(uint8_t* bytes, size_t size);
+        bool createCanvas(unsigned char* buffer, unsigned width, unsigned height, unsigned stride);
+        bool render(double elapsed, unsigned width, unsigned height);
+
+        bool setShapeFillColor(const std::string &name, int a, int r, int g, int b);
+        bool setShapeStrokeColor(const std::string &name, int a, int r, int g, int b);
+        bool setNodeOpacity(const std::string &name, float opacity);
+        bool setNodeScale(const std::string &name, float scale_x, float scale_y);
+        bool setNodeRotation(const std::string &name, float degree);
+        bool setNodePosition(const std::string &name, float position_x, float position_y);
+};
+
+#endif
\ No newline at end of file
index f4c53dd..596d831 100644 (file)
@@ -8,6 +8,7 @@ run_command('script/install.sh')
 add_project_arguments('-DRIVE_FILE_DIR="@0@/example/resources/"'.format(meson.current_source_dir()), language : 'cpp')
 
 thorvg_dep = dependency('thorvg', required : true)
+dlog_dep = dependency('dlog', required: true)
 
 install_headers([
    'submodule/include/artboard.hpp',
@@ -375,12 +376,14 @@ rive_cpp_src = [
    'submodule/src/generated/shapes/paint/trim_path_base.cpp',
 ]
 
+rive_cpp_inc = include_directories('submodule/include')
+
 rive_cpp_dep = declare_dependency(
-   include_directories : include_directories('submodule/include'),
+   include_directories : rive_cpp_inc,
    sources : rive_cpp_src,
 )
 
-headers = [include_directories('inc'), include_directories('submodule/include'), include_directories('src/renderer')]
+headers = [include_directories('inc'), include_directories('submodule/include'), include_directories('src/renderer'), include_directories('src')]
 
 subdir('inc')
 subdir('src')
@@ -389,8 +392,3 @@ if get_option('example') == true
        message('Enable Examples')
        subdir('example')
 endif
-
-if get_option('test') == true
-   subdir('test')
-endif
-
index 382da7f..0ac9a18 100644 (file)
@@ -9,6 +9,7 @@ Source0:    %{name}-%{version}.tar.gz
 
 BuildRequires:  pkgconfig
 BuildRequires:  pkgconfig(thorvg)
+BuildRequires:  pkgconfig(dlog)
 
 BuildRequires:  meson
 BuildRequires:  ninja
index 401fc38..11c54b8 100644 (file)
@@ -7,5 +7,5 @@ source_files = [
 rive_tizen_renderer_dep = declare_dependency(
    include_directories : include_directories('.'),
    sources : source_files,
-   dependencies : thorvg_dep
+   dependencies : [thorvg_dep, dlog_dep]
 )
index 1c4f3ed..80975f9 100644 (file)
 #include "rive_tizen.hpp"
-#include "math/aabb.hpp"
 
-void rive_tizen_print()
+#include <dlog.h>
+#include <vector>
+
+#include <shapes/paint/fill.hpp>
+#include <shapes/paint/stroke.hpp>
+#include <shapes/paint/solid_color.hpp>
+#include <shapes/paint/color.hpp>
+#include <node.hpp>
+
+#include "tvg_renderer.hpp"
+
+//Remove compilation warning
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "RIVE_TIZEN"
+
+//TODO: maybe we have to introduce another class -> Adapter implementation
+//and encapsulate header there. We don't want to put implementation related
+//code in the class header file.
+std::unique_ptr<tvg::SwCanvas> mSwCanvas; ///< ThorVG SW canvas handle
+
+RiveTizen::RiveTizen()
+{
+   tvg::Initializer::init(tvg::CanvasEngine::Sw, 0);
+   mArtboard = nullptr;
+}
+
+RiveTizen::~RiveTizen()
 {
-   // This line to check calling Rive APIs
-   rive::AABB aabb(0, 0, 100, 100);
-   // This line to check rive_tizen API calls
-   std::cout << "hello rive-tizen" << std::endl;
+   tvg::Initializer::term(tvg::CanvasEngine::Sw);
+}
+
+void RiveTizen::animationAdvanceApply(rive::LinearAnimationInstance *animation, double elapsed)
+{
+   if (!animation)
+   {
+      return;
+   }
+   animation->advance(elapsed);
+   animation->apply(mArtboard);
+}
+
+void RiveTizen::animationApply(rive::LinearAnimationInstance *animation, double elapsed)
+{
+   if (!animation)
+   {
+      return;
+   }
+   animation->time(elapsed);
+   animation->apply(mArtboard);
+}
+
+rive::LinearAnimationInstance *RiveTizen::createLinearAnimationInstance(size_t index)
+{
+   auto animation = mArtboard->animation(index);
+   if (!animation)
+   {
+      return nullptr;
+   }
+
+   rive::LinearAnimationInstance *instance = new rive::LinearAnimationInstance(animation);
+   return instance;
+}
+
+rive::Artboard *RiveTizen::getArtboard()
+{
+   return mArtboard;
+}
+
+bool RiveTizen::loadRiveResource(uint8_t *bytes, size_t size)
+{
+
+   if (!bytes)
+   {
+      dlog_print(DLOG_ERROR, LOG_TAG, "Invalid function parameters: bytes == nullptr");
+      return false;
+   }
+
+   auto reader = rive::BinaryReader(bytes, size);
+
+   if (mArtboard)
+   {
+      delete mArtboard;
+      mArtboard = nullptr;
+   }
+
+   rive::File *file = nullptr;
+
+   auto result = rive::File::import(reader, &file);
+   if (result != rive::ImportResult::success)
+   {
+      dlog_print(DLOG_ERROR, LOG_TAG, "rive::File::import() failed.");
+      return false;
+   }
+
+   mArtboard = file->artboard();
+
+   return true;
+}
+
+bool RiveTizen::createCanvas(unsigned char *buffer, unsigned int width, unsigned int height, unsigned int stride)
+{
+   if (!mSwCanvas)
+   {
+      mSwCanvas = tvg::SwCanvas::gen();
+      mSwCanvas->mempool(tvg::SwCanvas::MempoolPolicy::Individual);
+   }
+   mSwCanvas->clear();
+   mSwCanvas->target((uint32_t *)buffer, stride, width, height, tvg::SwCanvas::ARGB8888);
+   return true;
+}
+
+bool RiveTizen::render(double elapsed, unsigned int width, unsigned int height)
+{
+   mArtboard->advance(elapsed);
+   rive::TvgRenderer renderer(mSwCanvas.get());
+
+   renderer.save();
+   renderer.align(rive::Fit::contain,
+                  rive::Alignment::center,
+                  rive::AABB(0, 0, width, height),
+                  mArtboard->bounds());
+   mArtboard->draw(&renderer);
+   renderer.restore();
+
+   auto result = mSwCanvas->draw();
+   if (result == tvg::Result::Success)
+   {
+      mSwCanvas->sync();
+   }
+   else
+   {
+      return false;
+   }
+
+   return true;
+}
+
+bool RiveTizen::setShapeFillColor(const std::string &name, int a, int r, int g, int b)
+{
+   auto instance = mArtboard->find<rive::Fill>(name.c_str());
+   if (!instance || !instance->paint()->is<rive::SolidColor>())
+      return false;
+   instance->paint()->as<rive::SolidColor>()->colorValue(rive::colorARGB(a, r, g, b));
+   return true;
+}
+
+bool RiveTizen::setShapeStrokeColor(const std::string &name, int a, int r, int g, int b)
+{
+   auto instance = mArtboard->find<rive::Stroke>(name.c_str());
+   if (!instance || !instance->paint()->is<rive::SolidColor>())
+      return false;
+   instance->paint()->as<rive::SolidColor>()->colorValue(rive::colorARGB(a, r, g, b));
+   return true;
+}
+
+bool RiveTizen::setNodeOpacity(const std::string &name, float opacity)
+{
+   auto node = mArtboard->find(name.c_str());
+   if (!node)
+      return false;
+   node->as<rive::Node>()->opacity(opacity);
+   return true;
+}
+
+bool RiveTizen::setNodeScale(const std::string &name, float scale_x, float scale_y)
+{
+   auto node = mArtboard->find(name.c_str());
+   if (!node)
+      return false;
+
+   auto nodeInstance = node->as<rive::Node>();
+   nodeInstance->scaleX(scale_x);
+   nodeInstance->scaleY(scale_y);
+   return true;
+}
+
+bool RiveTizen::setNodeRotation(const std::string &name, float degree)
+{
+   auto node = mArtboard->find(name.c_str());
+   if (!node)
+      return false;
+
+   node->as<rive::Node>()->rotation(degree);
+   return true;
+}
+
+bool RiveTizen::setNodePosition(const std::string &name, float position_x, float position_y)
+{
+   auto node = mArtboard->find(name.c_str());
+   if (!node)
+      return false;
+
+   auto nodeInstance = node->as<rive::Node>();
+   nodeInstance->x(position_x);
+   nodeInstance->y(position_y);
+   return true;
 }