Implements ThorVG Renderer Skeletone Code for Rive
[platform/core/uifw/rive-tizen.git] / example / rive_viewer.cpp
1 #include <thread>
2 #include <Evas_GL.h>
3 #include <Elementary.h>
4 #include <rive_tizen.hpp>
5 #include "animation/linear_animation_instance.hpp"
6 #include "artboard.hpp"
7 #include "file.hpp"
8 #include "thorvg_renderer.hpp"
9
10 using namespace std;
11
12
13 #define WIDTH 700
14 #define HEIGHT 700
15
16 static uint32_t buffer[WIDTH * HEIGHT];
17 static unique_ptr<tvg::SwCanvas> swCanvas;
18 Eo *gView;
19 rive::File* currentFile = nullptr;
20 rive::Artboard* artboard = nullptr;
21 rive::LinearAnimationInstance* animationInstance = nullptr;
22
23 void win_del(void *data, Evas_Object *o, void *ev)
24 {
25    elm_exit();
26 }
27
28 void drawSwView(void* data, Eo* obj)
29 {
30     if (swCanvas && swCanvas->draw() == tvg::Result::Success) {
31         swCanvas->sync();
32     }
33 }
34
35 void tvgSwTest(uint32_t* buffer)
36 {
37     //Create a Canvas
38     swCanvas = tvg::SwCanvas::gen();
39     swCanvas->target(buffer, WIDTH, WIDTH, HEIGHT, tvg::SwCanvas::ARGB8888);
40
41     // Load Rive File
42     char *filename = "../../example/shapes.riv";
43     FILE* fp = fopen(filename, "r");
44
45     fseek(fp, 0, SEEK_END);
46     auto length = ftell(fp);
47     fseek(fp, 0, SEEK_SET);
48     uint8_t* bytes = new uint8_t[length];
49     if (fread(bytes, 1, length, fp) != length)
50     {
51        delete[] bytes;
52        fprintf(stderr, "failed to read all of %s\n", filename);
53        return;
54     }
55     auto reader = rive::BinaryReader(bytes, length);
56     rive::File* file = nullptr;
57     auto result = rive::File::import(reader, &file);
58     if (result != rive::ImportResult::success)
59     {
60        delete[] bytes;
61        fprintf(stderr, "failed to import %s\n", filename);
62        return;
63     }
64
65     artboard = file->artboard();
66     artboard->advance(0.0f);
67
68     delete animationInstance;
69     delete currentFile;
70
71     auto animation = artboard->firstAnimation<rive::LinearAnimation>();
72     if (animation != nullptr)
73     {
74        animationInstance = new rive::LinearAnimationInstance(animation);
75     }
76     else
77     {
78        animationInstance = nullptr;
79     }
80
81     currentFile = file;
82     delete[] bytes;
83
84     if (animationInstance != nullptr)
85     {
86        animationInstance->advance(0);
87        animationInstance->apply(artboard);
88     }
89     artboard->advance(0);
90
91     rive::ThorvgRenderer renderer(swCanvas.get());
92     renderer.save();
93     artboard->draw(&renderer);
94     renderer.restore();
95 }
96
97 static Eo* createSwView()
98 {
99     Eo* win = elm_win_util_standard_add(NULL, "Rive Viewer");
100     evas_object_smart_callback_add(win, "delete,request", win_del, 0);
101
102     Eo* view = evas_object_image_filled_add(evas_object_evas_get(win));
103     evas_object_image_size_set(view, WIDTH, HEIGHT);
104     evas_object_image_data_set(view, buffer);
105     evas_object_image_pixels_get_callback_set(view, drawSwView, nullptr);
106     evas_object_image_pixels_dirty_set(view, EINA_TRUE);
107     evas_object_image_data_update_add(view, 0, 0, WIDTH, HEIGHT);
108     evas_object_size_hint_weight_set(view, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
109     evas_object_show(view);
110
111     elm_win_resize_object_add(win, view);
112     evas_object_resize(win, WIDTH, HEIGHT);
113     evas_object_show(win);
114
115     tvgSwTest(buffer);
116
117     return view;
118 }
119
120 int main(int argc, char **argv)
121 {
122     rive_tizen_print();
123     rive::ThorvgRenderPath *path = new rive::ThorvgRenderPath();
124
125     tvg::CanvasEngine tvgEngine = tvg::CanvasEngine::Sw;
126
127     auto threads = std::thread::hardware_concurrency();
128
129     if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success)
130     {
131         elm_init(argc, argv);
132
133         gView = createSwView();
134
135         elm_run();
136         elm_shutdown();
137
138         tvg::Initializer::term(tvgEngine);
139
140     }
141     else
142     {
143         cout << "engine is not supported" << endl;
144     }
145
146     return 0;
147 }