From 9876d685cfbaefc1ba1e3b2f565f655b62326d93 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Mon, 13 Jul 2020 20:19:23 +0900 Subject: [PATCH 01/16] capi: support c interfaces this capi is under the beta, we quickly provide this working prototype for collaboration. Change-Id: Ie246abc306feb9a1305d1b593c4f3ef7f40ab5a9 --- .gitignore | 1 + inc/meson.build | 10 +- inc/thorvg_capi.h | 111 ++++++++++++++++++++++ meson.build | 4 + meson_options.txt | 6 ++ src/bindings/capi/meson.build | 8 ++ src/bindings/capi/tvgCapi.cpp | 214 ++++++++++++++++++++++++++++++++++++++++++ src/bindings/meson.build | 11 +++ src/meson.build | 3 +- test/makefile | 1 + test/testCapi.c | 73 ++++++++++++++ 11 files changed, 438 insertions(+), 4 deletions(-) create mode 100644 inc/thorvg_capi.h create mode 100644 src/bindings/capi/meson.build create mode 100644 src/bindings/capi/tvgCapi.cpp create mode 100644 src/bindings/meson.build create mode 100644 test/testCapi.c diff --git a/.gitignore b/.gitignore index 9a64520..b796b5e 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ testRadialGradient testGradientTransform testSvg testAsync +testCapi diff --git a/inc/meson.build b/inc/meson.build index c598ee5..90e3fc4 100644 --- a/inc/meson.build +++ b/inc/meson.build @@ -1,3 +1,7 @@ -install_headers([ - 'thorvg.h', - ]) +header_files = ['thorvg.h'] + +if get_option('bindings').contains('capi') == true + header_files += ['thorvg_capi.h'] +endif + +install_headers(header_files) diff --git a/inc/thorvg_capi.h b/inc/thorvg_capi.h new file mode 100644 index 0000000..d2f7f85 --- /dev/null +++ b/inc/thorvg_capi.h @@ -0,0 +1,111 @@ +#ifndef __THORVG_CAPI_H__ +#define __THORVG_CAPI_H__ + +#ifdef TVG_EXPORT + #undef TVG_EXPORT +#endif + +#ifdef TVG_BUILD + #define TVG_EXPORT __attribute__ ((visibility ("default"))) +#else + #define TVG_EXPORT +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _Tvg_Canvas Tvg_Canvas; +typedef struct _Tvg_Paint Tvg_Paint; + +#define TVG_ENGINE_SW (1 << 1) +#define TVG_ENGINE_GL (1 << 2) + +typedef enum { + TVG_RESULT_SUCCESS = 0, + TVG_RESULT_INVALID_ARGUMENT, + TVG_RESULT_INSUFFICIENT_CONDITION, + TVG_RESULT_FAILED_ALLOCATION, + TVG_RESULT_MEMORY_CORRUPTION, + TVG_RESULT_NOT_SUPPORTED, + TVG_RESULT_UNKNOWN +} Tvg_Result; + +typedef enum { + TVG_PATH_COMMAND_CLOSE = 0, + TVG_PATH_COMMAND_MOVE_TO, + TVG_PATH_COMMAND_LINE_TO, + TVG_PATH_COMMAND_CUBIC_TO +} Tvg_Path_Command; + +typedef enum { + TVG_STROKE_CAP_SQUARE = 0, + TVG_STROKE_CAP_ROUND, + TVG_STROKE_CAP_BUTT +} Tvg_Stroke_Cap; + +typedef enum { + TVG_STROKE_JOIN_BEVEL = 0, + TVG_STROKE_JOIN_ROUND, + TVG_STROKE_JOIN_MITER +} Tvg_Stroke_Join; + +typedef enum { + TVG_STROKE_FILL_PAD = 0, + TVG_STROKE_FILL_REFLECT, + TVG_STROKE_FILL_REPEAT +} Tvg_Stroke_Fill; + + +typedef struct +{ + float x, y; +} Tvg_Point; + +typedef struct +{ + float e11, e12, e13; + float e21, e22, e23; + float e31, e32, e33; +} Tvg_Matrix; + + + +TVG_EXPORT Tvg_Result tvg_engine_init(unsigned engine_method); +TVG_EXPORT Tvg_Result tvg_engine_term(unsigned engine_method); + +TVG_EXPORT Tvg_Canvas* tvg_swcanvas_create(); +TVG_EXPORT Tvg_Result tvg_swcanvas_set_target(Tvg_Canvas* canvas, uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h); + +TVG_EXPORT Tvg_Result tvg_canvas_destroy(Tvg_Canvas* canvas); +TVG_EXPORT Tvg_Result tvg_canvas_push(Tvg_Canvas* canvas, Tvg_Paint* paint); +TVG_EXPORT Tvg_Result tvg_canvas_reserve(Tvg_Canvas* canvas, uint32_t n); +TVG_EXPORT Tvg_Result tvg_canvas_clear(Tvg_Canvas* canvas); +TVG_EXPORT Tvg_Result tvg_canvas_update(Tvg_Canvas* canvas); +TVG_EXPORT Tvg_Result tvg_canvas_update_paint(Tvg_Canvas* canvas, Tvg_Paint* paint); +TVG_EXPORT Tvg_Result tvg_canvas_draw(Tvg_Canvas* canvas, unsigned char async); +TVG_EXPORT Tvg_Result tvg_canvas_sync(Tvg_Canvas* canvas); + +TVG_EXPORT Tvg_Paint* tvg_shape_new(); +TVG_EXPORT Tvg_Result tvg_shape_del(Tvg_Paint* paint); +TVG_EXPORT Tvg_Result tvg_shape_reset(Tvg_Paint* paint); +TVG_EXPORT Tvg_Result tvg_shape_move_to(Tvg_Paint* paint, float x, float y); +TVG_EXPORT Tvg_Result tvg_shape_line_to(Tvg_Paint* paint, float x, float y); +TVG_EXPORT Tvg_Result tvg_shape_cubic_to(Tvg_Paint* paint, float cx1, float cy1, float cx2, float cy2, float x, float y); +TVG_EXPORT Tvg_Result tvg_shape_close(Tvg_Paint* paint); +TVG_EXPORT Tvg_Result tvg_shape_append_rect(Tvg_Paint* paint, float x, float y, float w, float h, float rx, float ry); +TVG_EXPORT Tvg_Result tvg_shape_append_circle(Tvg_Paint* paint, float cx, float cy, float rx, float ry); +TVG_EXPORT Tvg_Result tvg_shape_append_path(Tvg_Paint* paint, const Tvg_Path_Command* cmds, uint32_t cmdCnt, const Tvg_Point* pts, uint32_t ptsCnt); +TVG_EXPORT Tvg_Result tvg_shape_set_stroke_width(Tvg_Paint* paint, float width); +TVG_EXPORT Tvg_Result tvg_shape_set_stroke_color(Tvg_Paint* paint, uint8_t r, uint8_t g, uint8_t b, uint8_t a); +TVG_EXPORT Tvg_Result tvg_shape_set_stroke_dash(Tvg_Paint* paint, const float* dashPattern, uint32_t cnt); +TVG_EXPORT Tvg_Result tvg_shape_set_stroke_cap(Tvg_Paint* paint, Tvg_Stroke_Cap cap); +TVG_EXPORT Tvg_Result tvg_shape_set_stroke_join(Tvg_Paint* paint, Tvg_Stroke_Join join); +TVG_EXPORT Tvg_Result tvg_shape_fill_color(Tvg_Paint* paint, uint8_t r, uint8_t g, uint8_t b, uint8_t a); + +#ifdef __cplusplus +} +#endif + +#endif //_THORVG_CAPI_H_ diff --git a/meson.build b/meson.build index d1803a3..6da6d26 100644 --- a/meson.build +++ b/meson.build @@ -22,6 +22,10 @@ if get_option('vectors').contains('avx') == true config_h.set10('THORVG_AVX_VECTOR_SUPPORT', true) endif +if get_option('bindings').contains('capi') == true + config_h.set10('THORVG_CAPI_BINDING_SUPPORT', true) +endif + configure_file( output: 'config.h', configuration: config_h diff --git a/meson_options.txt b/meson_options.txt index 5a440fa..59d0130 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -15,3 +15,9 @@ option('vectors', choices: ['', 'avx'], value: [''], description: 'Enable CPU Vectorization(SIMD) in thorvg') + +option('bindings', + type: 'array', + choices: ['', 'capi'], + value: ['capi'], + description: 'Enable C API binding') diff --git a/src/bindings/capi/meson.build b/src/bindings/capi/meson.build new file mode 100644 index 0000000..919442a --- /dev/null +++ b/src/bindings/capi/meson.build @@ -0,0 +1,8 @@ +source_file = [ + 'tvgCapi.cpp', +] + +subbinding_dep += [declare_dependency( + include_directories : include_directories('.'), + sources : source_file +)] diff --git a/src/bindings/capi/tvgCapi.cpp b/src/bindings/capi/tvgCapi.cpp new file mode 100644 index 0000000..37e01af --- /dev/null +++ b/src/bindings/capi/tvgCapi.cpp @@ -0,0 +1,214 @@ +#include +#include "thorvg_capi.h" + +using namespace std; +using namespace tvg; + +#ifdef __cplusplus +extern "C" { +#endif + +struct _Tvg_Canvas +{ + //Dummy for Direct Casting +}; + +struct _Tvg_Paint +{ + //Dummy for Direct Casting +}; + + +/************************************************************************/ +/* Engine API */ +/************************************************************************/ + +TVG_EXPORT Tvg_Result tvg_engine_init(unsigned engine_method) { + Result ret = Result::Success; + + if (engine_method & TVG_ENGINE_SW) ret = tvg::Initializer::init(tvg::CanvasEngine::Sw); + if (ret != Result::Success) return (Tvg_Result) ret; + + if (engine_method & TVG_ENGINE_GL) ret = tvg::Initializer::init(tvg::CanvasEngine::Gl); + return (Tvg_Result) ret; +} + + +TVG_EXPORT Tvg_Result tvg_engine_term(unsigned engine_method) { + Result ret = Result::Success; + + if (engine_method & TVG_ENGINE_SW) ret = tvg::Initializer::init(tvg::CanvasEngine::Sw); + if (ret != Result::Success) return (Tvg_Result) ret; + + if (engine_method & TVG_ENGINE_GL) ret = tvg::Initializer::init(tvg::CanvasEngine::Gl); + return (Tvg_Result) ret; +} + +/************************************************************************/ +/* Canvas API */ +/************************************************************************/ + +TVG_EXPORT Tvg_Canvas* tvg_swcanvas_create() +{ + return (Tvg_Canvas*) SwCanvas::gen().release(); +} + + +TVG_EXPORT Tvg_Result tvg_canvas_destroy(Tvg_Canvas* canvas) +{ + delete(canvas); + return TVG_RESULT_SUCCESS; +} + + +TVG_EXPORT Tvg_Result tvg_swcanvas_set_target(Tvg_Canvas* canvas, uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h) +{ + return (Tvg_Result) reinterpret_cast(canvas)->target(buffer, stride, w, h); +} + + +TVG_EXPORT Tvg_Result tvg_canvas_push(Tvg_Canvas* canvas, Tvg_Paint* paint) +{ + return (Tvg_Result) reinterpret_cast(canvas)->push(unique_ptr((Paint*)paint)); +} + + +TVG_EXPORT Tvg_Result tvg_canvas_reserve(Tvg_Canvas* canvas, uint32_t n) +{ + return (Tvg_Result) reinterpret_cast(canvas)->reserve(n); +} + + +TVG_EXPORT Tvg_Result tvg_canvas_clear(Tvg_Canvas* canvas) +{ + return (Tvg_Result) reinterpret_cast(canvas)->clear(); +} + + +TVG_EXPORT Tvg_Result tvg_canvas_update(Tvg_Canvas* canvas) +{ + return (Tvg_Result) reinterpret_cast(canvas)->update(); +} + + +TVG_EXPORT Tvg_Result tvg_canvas_update_paint(Tvg_Canvas* canvas, Tvg_Paint* paint) +{ + return (Tvg_Result) reinterpret_cast(canvas)->update((Paint*) paint); +} + + +TVG_EXPORT Tvg_Result tvg_canvas_draw(Tvg_Canvas* canvas, unsigned char async) +{ + return (Tvg_Result) reinterpret_cast(canvas)->draw(async); +} + + +TVG_EXPORT Tvg_Result tvg_canvas_sync(Tvg_Canvas* canvas) +{ + return (Tvg_Result) reinterpret_cast(canvas)->sync(); +} + + +/************************************************************************/ +/* Shape API */ +/************************************************************************/ + +TVG_EXPORT Tvg_Paint* tvg_shape_new() +{ + return (Tvg_Paint*) Shape::gen().release(); +} + + +TVG_EXPORT Tvg_Result tvg_shape_del(Tvg_Paint* paint) +{ + delete(paint); + return TVG_RESULT_SUCCESS; +} + + +TVG_EXPORT Tvg_Result tvg_shape_reset(Tvg_Paint* paint) +{ + return (Tvg_Result) reinterpret_cast(paint)->reset(); +} + + +TVG_EXPORT Tvg_Result tvg_shape_move_to(Tvg_Paint* paint, float x, float y) +{ + return (Tvg_Result) reinterpret_cast(paint)->moveTo(x, y); +} + + +TVG_EXPORT Tvg_Result tvg_shape_line_to(Tvg_Paint* paint, float x, float y) +{ + return (Tvg_Result) reinterpret_cast(paint)->lineTo(x, y); +} + + +TVG_EXPORT Tvg_Result tvg_shape_cubic_to(Tvg_Paint* paint, float cx1, float cy1, float cx2, float cy2, float x, float y) +{ + return (Tvg_Result) reinterpret_cast(paint)->cubicTo(cx1, cy1, cx2, cy2, x, y); +} + + +TVG_EXPORT Tvg_Result tvg_shape_close(Tvg_Paint* paint) +{ + return (Tvg_Result) reinterpret_cast(paint)->close(); +} + + +TVG_EXPORT Tvg_Result tvg_shape_append_rect(Tvg_Paint* paint, float x, float y, float w, float h, float rx, float ry) +{ + return (Tvg_Result) reinterpret_cast(paint)->appendRect(x, y, w, h, rx, ry); +} + + +TVG_EXPORT Tvg_Result tvg_shape_append_circle(Tvg_Paint* paint, float cx, float cy, float rx, float ry) +{ + return (Tvg_Result) reinterpret_cast(paint)->appendCircle(cx, cy, rx, ry); +} + + +TVG_EXPORT Tvg_Result tvg_shape_append_path(Tvg_Paint* paint, const Tvg_Path_Command* cmds, uint32_t cmdCnt, const Tvg_Point* pts, uint32_t ptsCnt) +{ + return (Tvg_Result) reinterpret_cast(paint)->appendPath((PathCommand*)cmds, cmdCnt, (Point*)pts, ptsCnt); +} + + +TVG_EXPORT Tvg_Result tvg_shape_set_stroke_width(Tvg_Paint* paint, float width) +{ + return (Tvg_Result) reinterpret_cast(paint)->stroke(width); +} + + +TVG_EXPORT Tvg_Result tvg_shape_set_stroke_color(Tvg_Paint* paint, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + return (Tvg_Result) reinterpret_cast(paint)->stroke(r, g, b, a); +} + + +TVG_EXPORT Tvg_Result tvg_shape_set_stroke_dash(Tvg_Paint* paint, const float* dashPattern, uint32_t cnt) +{ + return (Tvg_Result) reinterpret_cast(paint)->stroke(dashPattern, cnt); +} + + +TVG_EXPORT Tvg_Result tvg_shape_set_stroke_cap(Tvg_Paint* paint, Tvg_Stroke_Cap cap) +{ + return (Tvg_Result) reinterpret_cast(paint)->stroke((StrokeCap)cap); +} + + +TVG_EXPORT Tvg_Result tvg_shape_set_stroke_join(Tvg_Paint* paint, Tvg_Stroke_Join join) +{ + return (Tvg_Result) reinterpret_cast(paint)->stroke((StrokeJoin)join); +} + + +TVG_EXPORT Tvg_Result tvg_shape_fill_color(Tvg_Paint* paint, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + return (Tvg_Result) reinterpret_cast(paint)->fill(r, g, b, a); +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/src/bindings/meson.build b/src/bindings/meson.build new file mode 100644 index 0000000..2b3a150 --- /dev/null +++ b/src/bindings/meson.build @@ -0,0 +1,11 @@ +subbinding_dep = [] + +if get_option('bindings').contains('capi') == true + subdir('capi') + message('Enable CAPI Bindings') +endif + +binding_dep = declare_dependency( + dependencies: subbinding_dep, + include_directories : include_directories('.'), +) diff --git a/src/meson.build b/src/meson.build index 6873870..ced59a5 100644 --- a/src/meson.build +++ b/src/meson.build @@ -11,10 +11,11 @@ endif subdir('lib') subdir('loaders') +subdir('bindings') subdir('examples') thread_dep = meson.get_compiler('cpp').find_library('pthread') -thorvg_lib_dep = [common_dep, loader_dep, thread_dep] +thorvg_lib_dep = [common_dep, loader_dep, binding_dep, thread_dep] thorvg_lib = library( 'thorvg', diff --git a/test/makefile b/test/makefile index 6455a0a..ef9e28a 100644 --- a/test/makefile +++ b/test/makefile @@ -18,3 +18,4 @@ all: gcc -o testGradientTransform testGradientTransform.cpp -g -lstdc++ `pkg-config --cflags --libs elementary thorvg` gcc -o testSvg testSvg.cpp -g -lstdc++ `pkg-config --cflags --libs elementary thorvg` gcc -o testAsync testAsync.cpp -g -lstdc++ `pkg-config --cflags --libs elementary thorvg` + gcc -o testCapi testCapi.c -g 'pkg-config --cflags --libs elementary thorvg` diff --git a/test/testCapi.c b/test/testCapi.c new file mode 100644 index 0000000..5b8b91b --- /dev/null +++ b/test/testCapi.c @@ -0,0 +1,73 @@ +#include +#include + +#define WIDTH 800 +#define HEIGHT 800 + + +/************************************************************************/ +/* Capi Test Code */ +/************************************************************************/ + +static uint32_t buffer[WIDTH * HEIGHT]; + +void testCapi() +{ + tvg_engine_init(TVG_ENGINE_SW | TVG_ENGINE_GL); + + Tvg_Canvas* canvas = tvg_swcanvas_create(); + tvg_swcanvas_set_target(canvas, buffer, WIDTH, WIDTH, HEIGHT); + + Tvg_Paint* shape = tvg_shape_new(); + tvg_shape_append_rect(shape, 0, 0, 200, 200, 0, 0); + tvg_shape_append_rect(shape, 100, 100, 300, 300, 100, 100); + tvg_shape_append_circle(shape, 400, 400, 100, 100); + tvg_shape_append_circle(shape, 400, 500, 170, 100); + tvg_shape_fill_color(shape, 255, 255, 0, 255); + tvg_canvas_push(canvas, shape); + + tvg_canvas_draw(canvas, 1); + tvg_canvas_sync(canvas); + + tvg_canvas_destroy(canvas); + + tvg_engine_term(TVG_ENGINE_SW | TVG_ENGINE_GL); +} + + +/************************************************************************/ +/* Main Code */ +/************************************************************************/ + +void win_del(void *data, Evas_Object *o, void *ev) +{ + elm_exit(); +} + + +int main(int argc, char **argv) +{ + elm_init(argc, argv); + + Eo* win = elm_win_util_standard_add(NULL, "ThorVG Test"); + evas_object_smart_callback_add(win, "delete,request", win_del, 0); + + Eo* view = evas_object_image_filled_add(evas_object_evas_get(win)); + evas_object_image_size_set(view, WIDTH, HEIGHT); + evas_object_image_data_set(view, buffer); + evas_object_image_pixels_dirty_set(view, EINA_TRUE); + evas_object_image_data_update_add(view, 0, 0, WIDTH, HEIGHT); + evas_object_size_hint_weight_set(view, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_show(view); + + elm_win_resize_object_add(win, view); + evas_object_geometry_set(win, 0, 0, WIDTH, HEIGHT); + evas_object_show(win); + + testCapi(); + + elm_run(); + elm_shutdown(); + + return 0; +} -- 2.7.4 From 2501c50506da04fccf7dda3949b8313dc164c723 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Wed, 15 Jul 2020 16:18:55 +0900 Subject: [PATCH 02/16] capi: improve code template. Change-Id: Ia48a21fbd93103b371b41a13adf46d82b76803b1 --- inc/thorvg_capi.h | 39 ++++++++++++++++++++++++++++++++++++++- src/bindings/capi/tvgCapi.cpp | 17 +++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/inc/thorvg_capi.h b/inc/thorvg_capi.h index d2f7f85..7c92184 100644 --- a/inc/thorvg_capi.h +++ b/inc/thorvg_capi.h @@ -1,3 +1,20 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + #ifndef __THORVG_CAPI_H__ #define __THORVG_CAPI_H__ @@ -22,6 +39,7 @@ typedef struct _Tvg_Paint Tvg_Paint; #define TVG_ENGINE_SW (1 << 1) #define TVG_ENGINE_GL (1 << 2) + typedef enum { TVG_RESULT_SUCCESS = 0, TVG_RESULT_INVALID_ARGUMENT, @@ -32,6 +50,7 @@ typedef enum { TVG_RESULT_UNKNOWN } Tvg_Result; + typedef enum { TVG_PATH_COMMAND_CLOSE = 0, TVG_PATH_COMMAND_MOVE_TO, @@ -39,18 +58,21 @@ typedef enum { TVG_PATH_COMMAND_CUBIC_TO } Tvg_Path_Command; + typedef enum { TVG_STROKE_CAP_SQUARE = 0, TVG_STROKE_CAP_ROUND, TVG_STROKE_CAP_BUTT } Tvg_Stroke_Cap; + typedef enum { TVG_STROKE_JOIN_BEVEL = 0, TVG_STROKE_JOIN_ROUND, TVG_STROKE_JOIN_MITER } Tvg_Stroke_Join; + typedef enum { TVG_STROKE_FILL_PAD = 0, TVG_STROKE_FILL_REFLECT, @@ -63,6 +85,7 @@ typedef struct float x, y; } Tvg_Point; + typedef struct { float e11, e12, e13; @@ -71,13 +94,23 @@ typedef struct } Tvg_Matrix; - +/************************************************************************/ +/* Engine API */ +/************************************************************************/ TVG_EXPORT Tvg_Result tvg_engine_init(unsigned engine_method); TVG_EXPORT Tvg_Result tvg_engine_term(unsigned engine_method); + +/************************************************************************/ +/* SwCanvas API */ +/************************************************************************/ TVG_EXPORT Tvg_Canvas* tvg_swcanvas_create(); TVG_EXPORT Tvg_Result tvg_swcanvas_set_target(Tvg_Canvas* canvas, uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h); + +/************************************************************************/ +/* Common Canvas API */ +/************************************************************************/ TVG_EXPORT Tvg_Result tvg_canvas_destroy(Tvg_Canvas* canvas); TVG_EXPORT Tvg_Result tvg_canvas_push(Tvg_Canvas* canvas, Tvg_Paint* paint); TVG_EXPORT Tvg_Result tvg_canvas_reserve(Tvg_Canvas* canvas, uint32_t n); @@ -87,6 +120,10 @@ TVG_EXPORT Tvg_Result tvg_canvas_update_paint(Tvg_Canvas* canvas, Tvg_Paint* pai TVG_EXPORT Tvg_Result tvg_canvas_draw(Tvg_Canvas* canvas, unsigned char async); TVG_EXPORT Tvg_Result tvg_canvas_sync(Tvg_Canvas* canvas); + +/************************************************************************/ +/* Shape API */ +/************************************************************************/ TVG_EXPORT Tvg_Paint* tvg_shape_new(); TVG_EXPORT Tvg_Result tvg_shape_del(Tvg_Paint* paint); TVG_EXPORT Tvg_Result tvg_shape_reset(Tvg_Paint* paint); diff --git a/src/bindings/capi/tvgCapi.cpp b/src/bindings/capi/tvgCapi.cpp index 37e01af..6ba0e6d 100644 --- a/src/bindings/capi/tvgCapi.cpp +++ b/src/bindings/capi/tvgCapi.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + #include #include "thorvg_capi.h" -- 2.7.4 From 1b48bf10fe01e2026296c3eef6fe82e471889e56 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Thu, 9 Jul 2020 20:12:48 +0900 Subject: [PATCH 03/16] SvgLoader: Verify SVG resource Only tag is parsed first before data get in file open function. If the tag is found, the loaded file is valid and stores viewbox information. After that, the remaining content data is parsed in order with async. Change-Id: Idb934fbd5e190c7c523abe601a80745ccc767af1 --- src/loaders/svg_loader/tvgSvgLoader.cpp | 87 +++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 9 deletions(-) diff --git a/src/loaders/svg_loader/tvgSvgLoader.cpp b/src/loaders/svg_loader/tvgSvgLoader.cpp index 130a60c..9d58792 100644 --- a/src/loaders/svg_loader/tvgSvgLoader.cpp +++ b/src/loaders/svg_loader/tvgSvgLoader.cpp @@ -1982,6 +1982,7 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content, node = method(loader, nullptr, attrs, attrsLength); loader->doc = node; } else { + if (!strcmp(tagName, "svg")) return; //Already loadded (SvgNodeType::Doc) tag if (loader->stack.size() > 0) parent = loader->stack.at(loader->stack.size() - 1); node = method(loader, parent, attrs, attrsLength); } @@ -2223,6 +2224,64 @@ static void _freeSvgNode(SvgNode* node) } +static bool _svgLoaderParserForValidCheckXmlOpen(SvgLoaderData* loader, const char* content, unsigned int length) +{ + const char* attrs = nullptr; + int sz = length; + char tagName[20] = ""; + FactoryMethod method; + SvgNode *node = nullptr; + int attrsLength = 0; + loader->level++; + attrs = simpleXmlFindAttributesTag(content, length); + + if (!attrs) { + //Parse the empty tag + attrs = content; + while ((attrs != nullptr) && *attrs != '>') attrs++; + } + + if (attrs) { + sz = attrs - content; + attrsLength = length - sz; + while ((sz > 0) && (isspace(content[sz - 1]))) sz--; + strncpy(tagName, content, sz); + tagName[sz] = '\0'; + } + + if ((method = _findGroupFactory(tagName))) { + if (!loader->doc) { + if (strcmp(tagName, "svg")) return true; //Not a valid svg document + node = method(loader, nullptr, attrs, attrsLength); + loader->doc = node; + loader->stack.push_back(node); + return false; + } + } + return true; +} + + +static bool _svgLoaderParserForValidCheck(void* data, SimpleXMLType type, const char* content, unsigned int offset, unsigned int length) +{ + SvgLoaderData* loader = (SvgLoaderData*)data; + bool res = true;; + + switch (type) { + case SimpleXMLType::Open: + case SimpleXMLType::OpenEmpty: { + //If 'res' is false, it means tag is found. + res = _svgLoaderParserForValidCheckXmlOpen(loader, content, length); + break; + } + default: { + break; + } + } + + return res; +} + /************************************************************************/ /* External Class Implementation */ /************************************************************************/ @@ -2254,12 +2313,25 @@ bool SvgLoader::open(const char* path) if (content.empty()) return false; } - //FIXME: Verify this resource is normal SVG, otherwise return false - //Also, return the brief resource info such as viewbox: - //this->vx = ? - //this->vy = ? - //this->vw = ? - //this->vh = ? + //For valid check, only tag is parsed first. + //If the tag is found, the loaded file is valid and stores viewbox information. + //After that, the remaining content data is parsed in order with async. + loaderData.svgParse = (SvgParser*)malloc(sizeof(SvgParser)); + if (!loaderData.svgParse) return false; + + simpleXmlParse(content.c_str(), content.size(), true, _svgLoaderParserForValidCheck, &(loaderData)); + + if (loaderData.doc && loaderData.doc->type == SvgNodeType::Doc) { + //Return the brief resource info such as viewbox: + this->vx = loaderData.doc->node.doc.vx; + this->vy = loaderData.doc->node.doc.vy; + this->vw = loaderData.doc->node.doc.vw; + this->vh = loaderData.doc->node.doc.vh; + + } else { + cout << "ERROR : No SVG File. There is no " <loaderData.svgParse = (SvgParser*)malloc(sizeof(SvgParser)); - bool res = simpleXmlParse(loader->content.c_str(), loader->content.size(), true, _svgLoaderParser, &(loader->loaderData)); if (!res) return unique_ptr(nullptr); -- 2.7.4 From a6344daa66ef53a74d1a72876aaead934e629c3a Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 16 Jul 2020 13:45:27 +0900 Subject: [PATCH 04/16] sw_engine: fix wrong gradient fill transform. it missed the offset when transformed gradient positions. now it's fixed. Change-Id: I916bd88b40bc29ca57d31411b92e10fe357d720e --- src/lib/sw_engine/tvgSwFill.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib/sw_engine/tvgSwFill.cpp b/src/lib/sw_engine/tvgSwFill.cpp index 1f72ee9..fd857f9 100644 --- a/src/lib/sw_engine/tvgSwFill.cpp +++ b/src/lib/sw_engine/tvgSwFill.cpp @@ -100,12 +100,12 @@ bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix* tr auto cy = (y2 - y1) * 0.5f + y1; auto dx = x1 - cx; auto dy = y1 - cy; - x1 = dx * transform->e11 + dy * transform->e12 + transform->e31; - y1 = dx * transform->e21 + dy * transform->e22 + transform->e32; + x1 = dx * transform->e11 + dy * transform->e12 + transform->e31 + cx; + y1 = dx * transform->e21 + dy * transform->e22 + transform->e32 + cy; dx = x2 - cx; dy = y2 - cy; - x2 = dx * transform->e11 + dy * transform->e12 + transform->e31; - y2 = dx * transform->e21 + dy * transform->e22 + transform->e32; + x2 = dx * transform->e11 + dy * transform->e12 + transform->e31 + cx; + y2 = dx * transform->e21 + dy * transform->e22 + transform->e32 + cy; } fill->linear.dx = x2 - x1; -- 2.7.4 From e3218a8a9aeac1123a9fcfcefe9df1083ec1fa28 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Thu, 16 Jul 2020 14:58:35 +0900 Subject: [PATCH 05/16] test: Fix typo in makefile ' -> ` Change-Id: Iafacfb78d8f788ef302e5ad7f1a1d9cfbd380ffb --- test/makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/makefile b/test/makefile index ef9e28a..e1a8afb 100644 --- a/test/makefile +++ b/test/makefile @@ -18,4 +18,4 @@ all: gcc -o testGradientTransform testGradientTransform.cpp -g -lstdc++ `pkg-config --cflags --libs elementary thorvg` gcc -o testSvg testSvg.cpp -g -lstdc++ `pkg-config --cflags --libs elementary thorvg` gcc -o testAsync testAsync.cpp -g -lstdc++ `pkg-config --cflags --libs elementary thorvg` - gcc -o testCapi testCapi.c -g 'pkg-config --cflags --libs elementary thorvg` + gcc -o testCapi testCapi.c -g `pkg-config --cflags --libs elementary thorvg` -- 2.7.4 From 33b067eb0ad75366d5869d77162be975739b6425 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 16 Jul 2020 17:03:44 +0900 Subject: [PATCH 06/16] svg_loader: optimize data delivery. We know how this shape is passed, so don't use unique_ptr to save data size. Change-Id: I02410692199b9cee701c206246ceea5988d06726 --- src/loaders/svg_loader/tvgSvgSceneBuilder.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp b/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp index 4daf7d8..1e6ea32 100644 --- a/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp +++ b/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp @@ -221,7 +221,7 @@ unique_ptr _applyRadialGradientProperty(SvgStyleGradient* g, Sha } -unique_ptr _applyProperty(SvgNode* node, unique_ptr vg, float vx, float vy, float vw, float vh) +void _applyProperty(SvgNode* node, Shape* vg, float vx, float vy, float vw, float vh) { SvgStyleProperty* style = node->style; @@ -234,7 +234,7 @@ unique_ptr _applyProperty(SvgNode* node, unique_ptr vg, float vx, if (!(fabsf(tx) <= FLT_EPSILON) && !(fabsf(ty) <= FLT_EPSILON)) vg->translate(tx, ty); } - if (node->type == SvgNodeType::Doc) return vg; + if (node->type == SvgNodeType::Doc) return; //If fill property is nullptr then do nothing if (style->fill.paint.none) { @@ -243,10 +243,10 @@ unique_ptr _applyProperty(SvgNode* node, unique_ptr vg, float vx, if (!style->fill.paint.gradient->userSpace) vg->bounds(&vx, &vy, &vw, &vh); if (style->fill.paint.gradient->type == SvgGradientType::Linear) { - auto linear = _applyLinearGradientProperty(style->fill.paint.gradient, vg.get(), vx, vy, vw, vh); + auto linear = _applyLinearGradientProperty(style->fill.paint.gradient, vg, vx, vy, vw, vh); vg->fill(move(linear)); } else if (style->fill.paint.gradient->type == SvgGradientType::Radial) { - auto radial = _applyRadialGradientProperty(style->fill.paint.gradient, vg.get(), vx, vy, vw, vh); + auto radial = _applyRadialGradientProperty(style->fill.paint.gradient, vg, vx, vy, vw, vh); vg->fill(move(radial)); } } else if (style->fill.paint.curColor) { @@ -267,7 +267,7 @@ unique_ptr _applyProperty(SvgNode* node, unique_ptr vg, float vx, vg->fill(((float)r) * fa, ((float)g) * fa, ((float)b) * fa, ((float)a) * fa); } - if (node->type == SvgNodeType::G) return vg; + if (node->type == SvgNodeType::G) return; //Apply the stroke style property vg->stroke(style->stroke.width); @@ -298,7 +298,6 @@ unique_ptr _applyProperty(SvgNode* node, unique_ptr vg, float vx, float fa = ((float)style->opacity / 255.0); vg->stroke(((float)r) * fa, ((float)g) * fa, ((float)b) * fa, ((float)a) * fa); } - return vg; } @@ -351,7 +350,7 @@ unique_ptr _shapeBuildHelper(SvgNode* node, float vx, float vy, float vw, break; } } - shape = move(_applyProperty(node, move(shape), vx, vy, vw, vh)); + _applyProperty(node, shape.get(), vx, vy, vw, vh); return shape; } -- 2.7.4 From 231b3779b1bd75bed86ab88c000bb45928913d23 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 16 Jul 2020 17:09:48 +0900 Subject: [PATCH 07/16] svg_loader: code refactoring keep clean & neat code. Change-Id: Ia17139a291fc9934fe2f8d5e51417c44ec50f2ed --- src/loaders/svg_loader/tvgSvgSceneBuilder.cpp | 39 +++++++++++++-------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp b/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp index 1e6ea32..64d34b9 100644 --- a/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp +++ b/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp @@ -118,14 +118,14 @@ unique_ptr _applyLinearGradientProperty(SvgStyleGradient* g, Sha float fopacity = fillOpacity / 255.0f; //fill opacity if any exists. int i = 0; stops = (Fill::ColorStop*)calloc(stopCount, sizeof(Fill::ColorStop)); - for (vector::iterator itrStop = g->stops.begin(); itrStop != g->stops.end(); itrStop++) { + for (auto colorStop : g->stops) { //Use premultiplied color - opacity = ((float)(*itrStop)->a / 255) * fopacity; - stops[i].r = ((*itrStop)->r * opacity); - stops[i].g = ((*itrStop)->g * opacity); - stops[i].b = ((*itrStop)->b * opacity); - stops[i].a = ((*itrStop)->a * fopacity); - stops[i].offset = (*itrStop)->offset; + opacity = ((float)colorStop->a / 255.0f) * fopacity; + stops[i].r = colorStop->r * opacity; + stops[i].g = colorStop->g * opacity; + stops[i].b = colorStop->b * opacity; + stops[i].a = colorStop->a * fopacity; + stops[i].offset = colorStop->offset; i++; } fillGrad->colorStops(stops, stopCount); @@ -204,14 +204,14 @@ unique_ptr _applyRadialGradientProperty(SvgStyleGradient* g, Sha float fopacity = fillOpacity / 255.0f; //fill opacity if any exists. int i = 0; stops = (Fill::ColorStop*)calloc(stopCount, sizeof(Fill::ColorStop)); - for (vector::iterator itrStop = g->stops.begin(); itrStop != g->stops.end(); itrStop++) { + for (auto colorStop : g->stops) { //Use premultiplied color - opacity = ((float)(*itrStop)->a / 255) * fopacity; - stops[i].r = ((*itrStop)->r * opacity); - stops[i].g = ((*itrStop)->g * opacity); - stops[i].b = ((*itrStop)->b * opacity); - stops[i].a = ((*itrStop)->a * fopacity); - stops[i].offset = (*itrStop)->offset; + opacity = ((float)colorStop->a / 255.0f) * fopacity; + stops[i].r = colorStop->r * opacity; + stops[i].g = colorStop->g * opacity; + stops[i].b = colorStop->b * opacity; + stops[i].a = colorStop->a * fopacity; + stops[i].offset = colorStop->offset; i++; } fillGrad->colorStops(stops, stopCount); @@ -366,12 +366,11 @@ unique_ptr _sceneBuildHelper(SvgNode* node, float vx, float vy, float vw, if (!(fmod(fabsf(z), 360.0) <= FLT_EPSILON)) scene->rotate(fmod(z, 360.0)); if (!(fabsf(tx) <= FLT_EPSILON) && !(fabsf(ty) <= FLT_EPSILON)) scene->translate(tx, ty); } - node->style->opacity = (node->style->opacity * parentOpacity) / 255; - for (vector::iterator itrChild = node->child.begin(); itrChild != node->child.end(); itrChild++) { - SvgNode* child = *itrChild; - child->style->opacity = (child->style->opacity * node->style->opacity) / 255; - if (child->type == SvgNodeType::Doc || child->type == SvgNodeType::G) scene->push(_sceneBuildHelper(*itrChild, vx, vy, vw, vh, node->style->opacity)); - else scene->push(_shapeBuildHelper(*itrChild, vx, vy, vw, vh)); + node->style->opacity = (node->style->opacity * parentOpacity) / 255.0f; + for (auto child : node->child) { + child->style->opacity = (child->style->opacity * node->style->opacity) / 255.0f; + if (child->type == SvgNodeType::Doc || child->type == SvgNodeType::G) scene->push(_sceneBuildHelper(child, vx, vy, vw, vh, node->style->opacity)); + else scene->push(_shapeBuildHelper(child, vx, vy, vw, vh)); } return move(scene); } -- 2.7.4 From ca6417ec8d848b67d75a3242c4a00501284ef6a3 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 16 Jul 2020 17:17:16 +0900 Subject: [PATCH 08/16] svg_loader: code refactoring. leave to shape to handle non-effective values. Change-Id: I4193653710498e0ea31b0ff88fd8f0f8f0238e0e --- src/loaders/svg_loader/tvgSvgSceneBuilder.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp b/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp index 64d34b9..c651368 100644 --- a/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp +++ b/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp @@ -229,9 +229,9 @@ void _applyProperty(SvgNode* node, Shape* vg, float vx, float vy, float vw, floa if (node->transform) { float tx = 0, ty = 0, s = 0, z = 0; _getTransformationData(node->transform, &tx, &ty, &s, &z); - if (!(fabsf(s - 1) <= FLT_EPSILON)) vg->scale(s); - if (!(fmod(fabsf(z), 360.0) <= FLT_EPSILON)) vg->rotate(fmod(z, 360.0)); - if (!(fabsf(tx) <= FLT_EPSILON) && !(fabsf(ty) <= FLT_EPSILON)) vg->translate(tx, ty); + vg->scale(s); + vg->rotate(z); + vg->translate(tx, ty); } if (node->type == SvgNodeType::Doc) return; @@ -362,9 +362,9 @@ unique_ptr _sceneBuildHelper(SvgNode* node, float vx, float vy, float vw, if (node->transform) { float tx = 0, ty = 0, s = 0, z = 0; _getTransformationData(node->transform, &tx, &ty, &s, &z); - if (!(fabsf(s - 1) <= FLT_EPSILON)) scene->scale(s); - if (!(fmod(fabsf(z), 360.0) <= FLT_EPSILON)) scene->rotate(fmod(z, 360.0)); - if (!(fabsf(tx) <= FLT_EPSILON) && !(fabsf(ty) <= FLT_EPSILON)) scene->translate(tx, ty); + scene->scale(s); + scene->rotate(z); + scene->translate(tx, ty); } node->style->opacity = (node->style->opacity * parentOpacity) / 255.0f; for (auto child : node->child) { -- 2.7.4 From 3b385d1d5496d27217582c11a34c659e5ac601de Mon Sep 17 00:00:00 2001 From: Pranay Kumar Samanta Date: Wed, 15 Jul 2020 19:02:27 +0530 Subject: [PATCH 09/16] gl_engine: Fix crash in animation callback. Refactor test samples draw function. Fix open shape drawing. Change-Id: I9ca2cb3951f2229f36292b69221451e0eaf5b6a1 --- src/lib/gl_engine/tvgGlGeometry.cpp | 8 ++++---- src/lib/gl_engine/tvgGlRenderer.cpp | 5 +++-- test/testAsync.cpp | 6 ------ test/testBlending.cpp | 6 ------ test/testBoundary.cpp | 6 ------ test/testCustomTransform.cpp | 6 ------ test/testDirectUpdate.cpp | 6 ------ test/testGradientTransform.cpp | 6 ------ test/testLinearGradient.cpp | 6 ------ test/testMultiShapes.cpp | 6 ------ test/testPath.cpp | 6 ------ test/testPathCopy.cpp | 6 ------ test/testRadialGradient.cpp | 6 ------ test/testScene.cpp | 6 ------ test/testSceneTransform.cpp | 6 ------ test/testShape.cpp | 6 ------ test/testStroke.cpp | 6 ------ test/testStrokeLine.cpp | 6 ------ test/testSvg.cpp | 6 ------ test/testTransform.cpp | 6 ------ test/testUpdate.cpp | 6 ------ 21 files changed, 7 insertions(+), 120 deletions(-) mode change 100644 => 100755 src/lib/gl_engine/tvgGlGeometry.cpp mode change 100644 => 100755 src/lib/gl_engine/tvgGlRenderer.cpp mode change 100644 => 100755 test/testAsync.cpp mode change 100644 => 100755 test/testBlending.cpp mode change 100644 => 100755 test/testBoundary.cpp mode change 100644 => 100755 test/testCustomTransform.cpp mode change 100644 => 100755 test/testDirectUpdate.cpp mode change 100644 => 100755 test/testGradientTransform.cpp mode change 100644 => 100755 test/testLinearGradient.cpp mode change 100644 => 100755 test/testMultiShapes.cpp mode change 100644 => 100755 test/testPath.cpp mode change 100644 => 100755 test/testPathCopy.cpp mode change 100644 => 100755 test/testRadialGradient.cpp mode change 100644 => 100755 test/testScene.cpp mode change 100644 => 100755 test/testSceneTransform.cpp mode change 100644 => 100755 test/testShape.cpp mode change 100644 => 100755 test/testStroke.cpp mode change 100644 => 100755 test/testStrokeLine.cpp mode change 100644 => 100755 test/testSvg.cpp mode change 100644 => 100755 test/testTransform.cpp mode change 100644 => 100755 test/testUpdate.cpp diff --git a/src/lib/gl_engine/tvgGlGeometry.cpp b/src/lib/gl_engine/tvgGlGeometry.cpp old mode 100644 new mode 100755 index 59b730b..eba6fbf --- a/src/lib/gl_engine/tvgGlGeometry.cpp +++ b/src/lib/gl_engine/tvgGlGeometry.cpp @@ -84,11 +84,11 @@ bool GlGeometry::generateAAPoints(const Shape &shape, float strokeWd, RenderUpda size_t fPoint = 0; size_t sPoint = 1; - for (size_t i = 0; i < nPoints - 1; ++i) + for (size_t i = 0; i < nPoints; ++i) { fPoint = i; sPoint = i + 1; - if (sPoint == nPoints - 1) + if (fPoint == nPoints - 1) sPoint = 0; GlPoint normal = getNormal(aaPts[fPoint].orgPt, aaPts[sPoint].orgPt); @@ -96,8 +96,8 @@ bool GlGeometry::generateAAPoints(const Shape &shape, float strokeWd, RenderUpda normalInfo[fPoint].normal1 = normal; normalInfo[sPoint].normal2 = normal; } - normalInfo[nPoints - 1].normal1 = normalInfo[0].normal1; - normalInfo[nPoints - 1].normal2 = normalInfo[0].normal2; + normalInfo[0].normal2 = normalInfo[0].normal1; + normalInfo[nPoints - 1].normal1 = normalInfo[nPoints - 1].normal2; for (uint32_t i = 0; i < nPoints; ++i) { diff --git a/src/lib/gl_engine/tvgGlRenderer.cpp b/src/lib/gl_engine/tvgGlRenderer.cpp old mode 100644 new mode 100755 index bef3871..d9acf61 --- a/src/lib/gl_engine/tvgGlRenderer.cpp +++ b/src/lib/gl_engine/tvgGlRenderer.cpp @@ -64,8 +64,9 @@ bool GlRenderer::flush() bool GlRenderer::preRender() { - //TODO: called just before render() - + // Blend function for pre multiplied alpha + GL_CHECK(glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); + GL_CHECK(glEnable(GL_BLEND)); return true; } diff --git a/test/testAsync.cpp b/test/testAsync.cpp old mode 100644 new mode 100755 index df81020..4530f1d --- a/test/testAsync.cpp +++ b/test/testAsync.cpp @@ -113,14 +113,8 @@ void initGLview(Evas_Object *obj) void drawGLview(Evas_Object *obj) { auto gl = elm_glview_gl_api_get(obj); - int w, h; - elm_glview_size_get(obj, &w, &h); - gl->glViewport(0, 0, w, h); gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl->glClear(GL_COLOR_BUFFER_BIT); - gl->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - gl->glEnable(GL_BLEND); glCanvas->sync(); } diff --git a/test/testBlending.cpp b/test/testBlending.cpp old mode 100644 new mode 100755 index 6765cb6..7db8201 --- a/test/testBlending.cpp +++ b/test/testBlending.cpp @@ -101,14 +101,8 @@ void initGLview(Evas_Object *obj) void drawGLview(Evas_Object *obj) { auto gl = elm_glview_gl_api_get(obj); - int w, h; - elm_glview_size_get(obj, &w, &h); - gl->glViewport(0, 0, w, h); gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl->glClear(GL_COLOR_BUFFER_BIT); - gl->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - gl->glEnable(GL_BLEND); if (glCanvas->draw() == tvg::Result::Success) { glCanvas->sync(); diff --git a/test/testBoundary.cpp b/test/testBoundary.cpp old mode 100644 new mode 100755 index 71dd6a0..a2bb1d8 --- a/test/testBoundary.cpp +++ b/test/testBoundary.cpp @@ -90,14 +90,8 @@ void initGLview(Evas_Object *obj) void drawGLview(Evas_Object *obj) { auto gl = elm_glview_gl_api_get(obj); - int w, h; - elm_glview_size_get(obj, &w, &h); - gl->glViewport(0, 0, w, h); gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl->glClear(GL_COLOR_BUFFER_BIT); - gl->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - gl->glEnable(GL_BLEND); if (glCanvas->draw() == tvg::Result::Success) { glCanvas->sync(); diff --git a/test/testCustomTransform.cpp b/test/testCustomTransform.cpp old mode 100644 new mode 100755 index 5945490..00a3bc3 --- a/test/testCustomTransform.cpp +++ b/test/testCustomTransform.cpp @@ -139,14 +139,8 @@ void initGLview(Evas_Object *obj) void drawGLview(Evas_Object *obj) { auto gl = elm_glview_gl_api_get(obj); - int w, h; - elm_glview_size_get(obj, &w, &h); - gl->glViewport(0, 0, w, h); gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl->glClear(GL_COLOR_BUFFER_BIT); - gl->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - gl->glEnable(GL_BLEND); if (glCanvas->draw() == tvg::Result::Success) { glCanvas->sync(); diff --git a/test/testDirectUpdate.cpp b/test/testDirectUpdate.cpp old mode 100644 new mode 100755 index 67d0240..164ff61 --- a/test/testDirectUpdate.cpp +++ b/test/testDirectUpdate.cpp @@ -102,14 +102,8 @@ void initGLview(Evas_Object *obj) void drawGLview(Evas_Object *obj) { auto gl = elm_glview_gl_api_get(obj); - int w, h; - elm_glview_size_get(obj, &w, &h); - gl->glViewport(0, 0, w, h); gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl->glClear(GL_COLOR_BUFFER_BIT); - gl->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - gl->glEnable(GL_BLEND); if (glCanvas->draw() == tvg::Result::Success) { glCanvas->sync(); diff --git a/test/testGradientTransform.cpp b/test/testGradientTransform.cpp old mode 100644 new mode 100755 index 1c1b820..a97ec70 --- a/test/testGradientTransform.cpp +++ b/test/testGradientTransform.cpp @@ -167,14 +167,8 @@ void initGLview(Evas_Object *obj) void drawGLview(Evas_Object *obj) { auto gl = elm_glview_gl_api_get(obj); - int w, h; - elm_glview_size_get(obj, &w, &h); - gl->glViewport(0, 0, w, h); gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl->glClear(GL_COLOR_BUFFER_BIT); - gl->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - gl->glEnable(GL_BLEND); if (glCanvas->draw() == tvg::Result::Success) { glCanvas->sync(); diff --git a/test/testLinearGradient.cpp b/test/testLinearGradient.cpp old mode 100644 new mode 100755 index 826287b..90656fc --- a/test/testLinearGradient.cpp +++ b/test/testLinearGradient.cpp @@ -119,14 +119,8 @@ void initGLview(Evas_Object *obj) void drawGLview(Evas_Object *obj) { auto gl = elm_glview_gl_api_get(obj); - int w, h; - elm_glview_size_get(obj, &w, &h); - gl->glViewport(0, 0, w, h); gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl->glClear(GL_COLOR_BUFFER_BIT); - gl->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - gl->glEnable(GL_BLEND); if (glCanvas->draw() == tvg::Result::Success) { glCanvas->sync(); diff --git a/test/testMultiShapes.cpp b/test/testMultiShapes.cpp old mode 100644 new mode 100755 index 8860135..d81f709 --- a/test/testMultiShapes.cpp +++ b/test/testMultiShapes.cpp @@ -79,14 +79,8 @@ void initGLview(Evas_Object *obj) void drawGLview(Evas_Object *obj) { auto gl = elm_glview_gl_api_get(obj); - int w, h; - elm_glview_size_get(obj, &w, &h); - gl->glViewport(0, 0, w, h); gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl->glClear(GL_COLOR_BUFFER_BIT); - gl->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - gl->glEnable(GL_BLEND); if (glCanvas->draw() == tvg::Result::Success) { glCanvas->sync(); diff --git a/test/testPath.cpp b/test/testPath.cpp old mode 100644 new mode 100755 index bcd5ab7..b3a265e --- a/test/testPath.cpp +++ b/test/testPath.cpp @@ -96,14 +96,8 @@ void initGLview(Evas_Object *obj) void drawGLview(Evas_Object *obj) { auto gl = elm_glview_gl_api_get(obj); - int w, h; - elm_glview_size_get(obj, &w, &h); - gl->glViewport(0, 0, w, h); gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl->glClear(GL_COLOR_BUFFER_BIT); - gl->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - gl->glEnable(GL_BLEND); if (glCanvas->draw() == tvg::Result::Success) { glCanvas->sync(); diff --git a/test/testPathCopy.cpp b/test/testPathCopy.cpp old mode 100644 new mode 100755 index dd00827..724b8b4 --- a/test/testPathCopy.cpp +++ b/test/testPathCopy.cpp @@ -133,14 +133,8 @@ void initGLview(Evas_Object *obj) void drawGLview(Evas_Object *obj) { auto gl = elm_glview_gl_api_get(obj); - int w, h; - elm_glview_size_get(obj, &w, &h); - gl->glViewport(0, 0, w, h); gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl->glClear(GL_COLOR_BUFFER_BIT); - gl->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - gl->glEnable(GL_BLEND); if (glCanvas->draw() == tvg::Result::Success) { glCanvas->sync(); diff --git a/test/testRadialGradient.cpp b/test/testRadialGradient.cpp old mode 100644 new mode 100755 index 054bf12..c80cb03 --- a/test/testRadialGradient.cpp +++ b/test/testRadialGradient.cpp @@ -119,14 +119,8 @@ void initGLview(Evas_Object *obj) void drawGLview(Evas_Object *obj) { auto gl = elm_glview_gl_api_get(obj); - int w, h; - elm_glview_size_get(obj, &w, &h); - gl->glViewport(0, 0, w, h); gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl->glClear(GL_COLOR_BUFFER_BIT); - gl->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - gl->glEnable(GL_BLEND); if (glCanvas->draw() == tvg::Result::Success) { glCanvas->sync(); diff --git a/test/testScene.cpp b/test/testScene.cpp old mode 100644 new mode 100755 index b796a5b..c835a92 --- a/test/testScene.cpp +++ b/test/testScene.cpp @@ -126,14 +126,8 @@ void initGLview(Evas_Object *obj) void drawGLview(Evas_Object *obj) { auto gl = elm_glview_gl_api_get(obj); - int w, h; - elm_glview_size_get(obj, &w, &h); - gl->glViewport(0, 0, w, h); gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl->glClear(GL_COLOR_BUFFER_BIT); - gl->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - gl->glEnable(GL_BLEND); if (glCanvas->draw() == tvg::Result::Success) { glCanvas->sync(); diff --git a/test/testSceneTransform.cpp b/test/testSceneTransform.cpp old mode 100644 new mode 100755 index aeaf11e..9597101 --- a/test/testSceneTransform.cpp +++ b/test/testSceneTransform.cpp @@ -163,14 +163,8 @@ void initGLview(Evas_Object *obj) void drawGLview(Evas_Object *obj) { auto gl = elm_glview_gl_api_get(obj); - int w, h; - elm_glview_size_get(obj, &w, &h); - gl->glViewport(0, 0, w, h); gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl->glClear(GL_COLOR_BUFFER_BIT); - gl->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - gl->glEnable(GL_BLEND); if (glCanvas->draw() == tvg::Result::Success) { glCanvas->sync(); diff --git a/test/testShape.cpp b/test/testShape.cpp old mode 100644 new mode 100755 index 391b55f..7788817 --- a/test/testShape.cpp +++ b/test/testShape.cpp @@ -69,14 +69,8 @@ void initGLview(Evas_Object *obj) void drawGLview(Evas_Object *obj) { auto gl = elm_glview_gl_api_get(obj); - int w, h; - elm_glview_size_get(obj, &w, &h); - gl->glViewport(0, 0, w, h); gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl->glClear(GL_COLOR_BUFFER_BIT); - gl->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - gl->glEnable(GL_BLEND); if (glCanvas->draw() == tvg::Result::Success) { glCanvas->sync(); diff --git a/test/testStroke.cpp b/test/testStroke.cpp old mode 100644 new mode 100755 index f7c1a88..36f2a94 --- a/test/testStroke.cpp +++ b/test/testStroke.cpp @@ -116,14 +116,8 @@ void initGLview(Evas_Object *obj) void drawGLview(Evas_Object *obj) { auto gl = elm_glview_gl_api_get(obj); - int w, h; - elm_glview_size_get(obj, &w, &h); - gl->glViewport(0, 0, w, h); gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl->glClear(GL_COLOR_BUFFER_BIT); - gl->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - gl->glEnable(GL_BLEND); if (glCanvas->draw() == tvg::Result::Success) { glCanvas->sync(); diff --git a/test/testStrokeLine.cpp b/test/testStrokeLine.cpp old mode 100644 new mode 100755 index bc3f960..894c695 --- a/test/testStrokeLine.cpp +++ b/test/testStrokeLine.cpp @@ -153,14 +153,8 @@ void initGLview(Evas_Object *obj) void drawGLview(Evas_Object *obj) { auto gl = elm_glview_gl_api_get(obj); - int w, h; - elm_glview_size_get(obj, &w, &h); - gl->glViewport(0, 0, w, h); gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl->glClear(GL_COLOR_BUFFER_BIT); - gl->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - gl->glEnable(GL_BLEND); if (glCanvas->draw() == tvg::Result::Success) { glCanvas->sync(); diff --git a/test/testSvg.cpp b/test/testSvg.cpp old mode 100644 new mode 100755 index edb987b..65fe9d7 --- a/test/testSvg.cpp +++ b/test/testSvg.cpp @@ -93,14 +93,8 @@ void initGLview(Evas_Object *obj) void drawGLview(Evas_Object *obj) { auto gl = elm_glview_gl_api_get(obj); - int w, h; - elm_glview_size_get(obj, &w, &h); - gl->glViewport(0, 0, w, h); gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl->glClear(GL_COLOR_BUFFER_BIT); - gl->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - gl->glEnable(GL_BLEND); if (glCanvas->draw() == tvg::Result::Success) { glCanvas->sync(); diff --git a/test/testTransform.cpp b/test/testTransform.cpp old mode 100644 new mode 100755 index da7c87c..6d0edbf --- a/test/testTransform.cpp +++ b/test/testTransform.cpp @@ -130,14 +130,8 @@ void initGLview(Evas_Object *obj) void drawGLview(Evas_Object *obj) { auto gl = elm_glview_gl_api_get(obj); - int w, h; - elm_glview_size_get(obj, &w, &h); - gl->glViewport(0, 0, w, h); gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl->glClear(GL_COLOR_BUFFER_BIT); - gl->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - gl->glEnable(GL_BLEND); if (glCanvas->draw() == tvg::Result::Success) { glCanvas->sync(); diff --git a/test/testUpdate.cpp b/test/testUpdate.cpp old mode 100644 new mode 100755 index c350435..0d00738 --- a/test/testUpdate.cpp +++ b/test/testUpdate.cpp @@ -91,14 +91,8 @@ void initGLview(Evas_Object *obj) void drawGLview(Evas_Object *obj) { auto gl = elm_glview_gl_api_get(obj); - int w, h; - elm_glview_size_get(obj, &w, &h); - gl->glViewport(0, 0, w, h); gl->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl->glClear(GL_COLOR_BUFFER_BIT); - gl->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - gl->glEnable(GL_BLEND); if (glCanvas->draw() == tvg::Result::Success) { glCanvas->sync(); -- 2.7.4 From dd1f7875f62178564817309d4bfb19ada835a946 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Fri, 17 Jul 2020 16:56:05 +0900 Subject: [PATCH 10/16] updated AUTHORS Change-Id: If9412e0598bdfa59dc142aacaec1cb5ae3f5401d --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 3e778fe..348597a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,3 +1,4 @@ Hermet Park Prudhvi Raj Vasireddi Junsu Choi +Pranay Samanta -- 2.7.4 From 56c0235dc5b43261f376d9164f93dcdca5af6f4d Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Fri, 17 Jul 2020 16:57:02 +0900 Subject: [PATCH 11/16] test: changed file permission. Change-Id: I8172152f700d10fa1d8c84473d45ff484c0b36d8 --- test/testAsync.cpp | 0 test/testBlending.cpp | 0 test/testBoundary.cpp | 0 test/testCustomTransform.cpp | 0 test/testDirectUpdate.cpp | 0 test/testGradientTransform.cpp | 0 test/testLinearGradient.cpp | 0 test/testMultiShapes.cpp | 0 test/testPath.cpp | 0 test/testPathCopy.cpp | 0 test/testRadialGradient.cpp | 0 test/testScene.cpp | 0 test/testSceneTransform.cpp | 0 test/testShape.cpp | 0 test/testStroke.cpp | 0 test/testStrokeLine.cpp | 0 test/testSvg.cpp | 0 test/testTransform.cpp | 0 test/testUpdate.cpp | 0 19 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 test/testAsync.cpp mode change 100755 => 100644 test/testBlending.cpp mode change 100755 => 100644 test/testBoundary.cpp mode change 100755 => 100644 test/testCustomTransform.cpp mode change 100755 => 100644 test/testDirectUpdate.cpp mode change 100755 => 100644 test/testGradientTransform.cpp mode change 100755 => 100644 test/testLinearGradient.cpp mode change 100755 => 100644 test/testMultiShapes.cpp mode change 100755 => 100644 test/testPath.cpp mode change 100755 => 100644 test/testPathCopy.cpp mode change 100755 => 100644 test/testRadialGradient.cpp mode change 100755 => 100644 test/testScene.cpp mode change 100755 => 100644 test/testSceneTransform.cpp mode change 100755 => 100644 test/testShape.cpp mode change 100755 => 100644 test/testStroke.cpp mode change 100755 => 100644 test/testStrokeLine.cpp mode change 100755 => 100644 test/testSvg.cpp mode change 100755 => 100644 test/testTransform.cpp mode change 100755 => 100644 test/testUpdate.cpp diff --git a/test/testAsync.cpp b/test/testAsync.cpp old mode 100755 new mode 100644 diff --git a/test/testBlending.cpp b/test/testBlending.cpp old mode 100755 new mode 100644 diff --git a/test/testBoundary.cpp b/test/testBoundary.cpp old mode 100755 new mode 100644 diff --git a/test/testCustomTransform.cpp b/test/testCustomTransform.cpp old mode 100755 new mode 100644 diff --git a/test/testDirectUpdate.cpp b/test/testDirectUpdate.cpp old mode 100755 new mode 100644 diff --git a/test/testGradientTransform.cpp b/test/testGradientTransform.cpp old mode 100755 new mode 100644 diff --git a/test/testLinearGradient.cpp b/test/testLinearGradient.cpp old mode 100755 new mode 100644 diff --git a/test/testMultiShapes.cpp b/test/testMultiShapes.cpp old mode 100755 new mode 100644 diff --git a/test/testPath.cpp b/test/testPath.cpp old mode 100755 new mode 100644 diff --git a/test/testPathCopy.cpp b/test/testPathCopy.cpp old mode 100755 new mode 100644 diff --git a/test/testRadialGradient.cpp b/test/testRadialGradient.cpp old mode 100755 new mode 100644 diff --git a/test/testScene.cpp b/test/testScene.cpp old mode 100755 new mode 100644 diff --git a/test/testSceneTransform.cpp b/test/testSceneTransform.cpp old mode 100755 new mode 100644 diff --git a/test/testShape.cpp b/test/testShape.cpp old mode 100755 new mode 100644 diff --git a/test/testStroke.cpp b/test/testStroke.cpp old mode 100755 new mode 100644 diff --git a/test/testStrokeLine.cpp b/test/testStrokeLine.cpp old mode 100755 new mode 100644 diff --git a/test/testSvg.cpp b/test/testSvg.cpp old mode 100755 new mode 100644 diff --git a/test/testTransform.cpp b/test/testTransform.cpp old mode 100755 new mode 100644 diff --git a/test/testUpdate.cpp b/test/testUpdate.cpp old mode 100755 new mode 100644 -- 2.7.4 From a5d1542e4478b19e6b5b44869bc677ec0ffa930a Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Fri, 17 Jul 2020 17:15:16 +0900 Subject: [PATCH 12/16] test: ++code safety added null check for exceptional case. Change-Id: I12a5e9724149f607188b67a84e46a033a16270f7 --- test/testAsync.cpp | 2 ++ test/testBlending.cpp | 2 ++ test/testBoundary.cpp | 2 ++ test/testCommon.h | 3 +-- test/testCustomTransform.cpp | 6 +++++- test/testDirectUpdate.cpp | 4 ++++ test/testGradientTransform.cpp | 6 +++++- test/testLinearGradient.cpp | 2 ++ test/testMultiShapes.cpp | 2 ++ test/testPath.cpp | 2 ++ test/testPathCopy.cpp | 4 +++- test/testRadialGradient.cpp | 4 +++- test/testScene.cpp | 4 +++- test/testSceneTransform.cpp | 6 +++++- test/testShape.cpp | 4 +++- test/testStroke.cpp | 4 +++- test/testStrokeLine.cpp | 4 +++- test/testSvg.cpp | 4 +++- test/testTransform.cpp | 6 +++++- test/testUpdate.cpp | 6 +++++- 20 files changed, 63 insertions(+), 14 deletions(-) diff --git a/test/testAsync.cpp b/test/testAsync.cpp index 4530f1d..edc6dde 100644 --- a/test/testAsync.cpp +++ b/test/testAsync.cpp @@ -10,6 +10,8 @@ static unsigned cnt = 0; bool tvgUpdateCmds(tvg::Canvas* canvas) { + if (!canvas) return false; + auto t = ecore_time_get(); //Explicitly clear all retained paint nodes. diff --git a/test/testBlending.cpp b/test/testBlending.cpp index 7db8201..5477b3b 100644 --- a/test/testBlending.cpp +++ b/test/testBlending.cpp @@ -6,6 +6,8 @@ void tvgDrawCmds(tvg::Canvas* canvas) { + if (!canvas) return; + canvas->reserve(5); //Prepare Round Rectangle diff --git a/test/testBoundary.cpp b/test/testBoundary.cpp index a2bb1d8..57a3d6c 100644 --- a/test/testBoundary.cpp +++ b/test/testBoundary.cpp @@ -6,6 +6,8 @@ void tvgDrawCmds(tvg::Canvas* canvas) { + if (!canvas) return; + canvas->reserve(5); //reserve 5 shape nodes (optional) //Prepare Shape1 diff --git a/test/testCommon.h b/test/testCommon.h index f176956..13ac86a 100644 --- a/test/testCommon.h +++ b/test/testCommon.h @@ -12,14 +12,13 @@ using namespace std; /************************************************************************/ void tvgSwTest(uint32_t* buffer); +void drawSwView(void* data, Eo* obj); void win_del(void *data, Evas_Object *o, void *ev) { elm_exit(); } -void drawSwView(void* data, Eo* obj); - static Eo* createSwView() { static uint32_t buffer[WIDTH * HEIGHT]; diff --git a/test/testCustomTransform.cpp b/test/testCustomTransform.cpp index 00a3bc3..f95e41e 100644 --- a/test/testCustomTransform.cpp +++ b/test/testCustomTransform.cpp @@ -7,6 +7,8 @@ tvg::Shape* pShape = nullptr; void tvgDrawCmds(tvg::Canvas* canvas) { + if (!canvas) return; + //Shape1 auto shape = tvg::Shape::gen(); @@ -33,6 +35,8 @@ void tvgDrawCmds(tvg::Canvas* canvas) void tvgUpdateCmds(tvg::Canvas* canvas, float progress) { + if (!canvas) return; + /* Update shape directly. You can update only necessary properties of this shape, while retaining other properties. */ @@ -202,4 +206,4 @@ int main(int argc, char **argv) cout << "engine is not supported" << endl; } return 0; -} \ No newline at end of file +} diff --git a/test/testDirectUpdate.cpp b/test/testDirectUpdate.cpp index 164ff61..3c275b6 100644 --- a/test/testDirectUpdate.cpp +++ b/test/testDirectUpdate.cpp @@ -7,6 +7,8 @@ tvg::Shape* pShape = nullptr; void tvgDrawCmds(tvg::Canvas* canvas) { + if (!canvas) return; + //Shape auto shape = tvg::Shape::gen(); @@ -26,6 +28,8 @@ void tvgDrawCmds(tvg::Canvas* canvas) void tvgUpdateCmds(tvg::Canvas* canvas, float progress) { + if (!canvas) return; + /* Update shape directly. You can update only necessary properties of this shape, while retaining other properties. */ diff --git a/test/testGradientTransform.cpp b/test/testGradientTransform.cpp index a97ec70..4fa426b 100644 --- a/test/testGradientTransform.cpp +++ b/test/testGradientTransform.cpp @@ -9,6 +9,8 @@ tvg::Shape* pShape3 = nullptr; void tvgDrawCmds(tvg::Canvas* canvas) { + if (!canvas) return; + //Shape1 auto shape = tvg::Shape::gen(); @@ -83,6 +85,8 @@ void tvgDrawCmds(tvg::Canvas* canvas) void tvgUpdateCmds(tvg::Canvas* canvas, float progress) { + if (!canvas) return; + /* Update shape directly. You can update only necessary properties of this shape, while retaining other properties. */ @@ -230,4 +234,4 @@ int main(int argc, char **argv) cout << "engine is not supported" << endl; } return 0; -} \ No newline at end of file +} diff --git a/test/testLinearGradient.cpp b/test/testLinearGradient.cpp index 90656fc..f98fc97 100644 --- a/test/testLinearGradient.cpp +++ b/test/testLinearGradient.cpp @@ -6,6 +6,8 @@ void tvgDrawCmds(tvg::Canvas* canvas) { + if (!canvas) return; + canvas->reserve(3); //reserve 3 shape nodes (optional) //Prepare Round Rectangle diff --git a/test/testMultiShapes.cpp b/test/testMultiShapes.cpp index d81f709..5a6d34f 100644 --- a/test/testMultiShapes.cpp +++ b/test/testMultiShapes.cpp @@ -6,6 +6,8 @@ void tvgDrawCmds(tvg::Canvas* canvas) { + if (!canvas) return; + canvas->reserve(3); //reserve 3 shape nodes (optional) //Prepare Round Rectangle diff --git a/test/testPath.cpp b/test/testPath.cpp index b3a265e..52c56ef 100644 --- a/test/testPath.cpp +++ b/test/testPath.cpp @@ -6,6 +6,8 @@ void tvgDrawCmds(tvg::Canvas* canvas) { + if (!canvas) return; + //Star auto shape1 = tvg::Shape::gen(); diff --git a/test/testPathCopy.cpp b/test/testPathCopy.cpp index 724b8b4..0ae364b 100644 --- a/test/testPathCopy.cpp +++ b/test/testPathCopy.cpp @@ -6,6 +6,8 @@ void tvgDrawCmds(tvg::Canvas* canvas) { + if (!canvas) return; + /* Star */ //Prepare Path Commands @@ -182,4 +184,4 @@ int main(int argc, char **argv) cout << "engine is not supported" << endl; } return 0; -} \ No newline at end of file +} diff --git a/test/testRadialGradient.cpp b/test/testRadialGradient.cpp index c80cb03..a6c10ba 100644 --- a/test/testRadialGradient.cpp +++ b/test/testRadialGradient.cpp @@ -6,6 +6,8 @@ void tvgDrawCmds(tvg::Canvas* canvas) { + if (!canvas) return; + canvas->reserve(3); //reserve 3 shape nodes (optional) //Prepare Round Rectangle @@ -168,4 +170,4 @@ int main(int argc, char **argv) cout << "engine is not supported" << endl; } return 0; -} \ No newline at end of file +} diff --git a/test/testScene.cpp b/test/testScene.cpp index c835a92..5b12020 100644 --- a/test/testScene.cpp +++ b/test/testScene.cpp @@ -6,6 +6,8 @@ void tvgDrawCmds(tvg::Canvas* canvas) { + if (!canvas) return; + //Create a Scene auto scene = tvg::Scene::gen(); scene->reserve(3); //reserve 3 shape nodes (optional) @@ -175,4 +177,4 @@ int main(int argc, char **argv) cout << "engine is not supported" << endl; } return 0; -} \ No newline at end of file +} diff --git a/test/testSceneTransform.cpp b/test/testSceneTransform.cpp index 9597101..0d0be8e 100644 --- a/test/testSceneTransform.cpp +++ b/test/testSceneTransform.cpp @@ -8,6 +8,8 @@ tvg::Scene* pScene2 = nullptr; void tvgDrawCmds(tvg::Canvas* canvas) { + if (!canvas) return; + //Create a Scene1 auto scene = tvg::Scene::gen(); pScene1 = scene.get(); @@ -90,6 +92,8 @@ void tvgDrawCmds(tvg::Canvas* canvas) void tvgUpdateCmds(tvg::Canvas* canvas, float progress) { + if (!canvas) return; + /* Update scene directly. You can update only necessary properties of this scene, while retaining other properties. */ @@ -226,4 +230,4 @@ int main(int argc, char **argv) cout << "engine is not supported" << endl; } return 0; -} \ No newline at end of file +} diff --git a/test/testShape.cpp b/test/testShape.cpp index 7788817..88519d0 100644 --- a/test/testShape.cpp +++ b/test/testShape.cpp @@ -6,6 +6,8 @@ void tvgDrawCmds(tvg::Canvas* canvas) { + if (!canvas) return; + //Prepare a Shape (Rectangle + Rectangle + Circle + Circle) auto shape1 = tvg::Shape::gen(); shape1->appendRect(0, 0, 200, 200, 0, 0); //x, y, w, h, rx, ry @@ -118,4 +120,4 @@ int main(int argc, char **argv) cout << "engine is not supported" << endl; } return 0; -} \ No newline at end of file +} diff --git a/test/testStroke.cpp b/test/testStroke.cpp index 36f2a94..9174872 100644 --- a/test/testStroke.cpp +++ b/test/testStroke.cpp @@ -6,6 +6,8 @@ void tvgDrawCmds(tvg::Canvas* canvas) { + if (!canvas) return; + //Shape 1 auto shape1 = tvg::Shape::gen(); shape1->appendRect(50, 50, 200, 200, 0, 0); @@ -165,4 +167,4 @@ int main(int argc, char **argv) cout << "engine is not supported" << endl; } return 0; -} \ No newline at end of file +} diff --git a/test/testStrokeLine.cpp b/test/testStrokeLine.cpp index 894c695..445f840 100644 --- a/test/testStrokeLine.cpp +++ b/test/testStrokeLine.cpp @@ -6,6 +6,8 @@ void tvgDrawCmds(tvg::Canvas* canvas) { + if (!canvas) return; + //Test for Stroke Width for (int i = 0; i < 10; ++i) { auto shape = tvg::Shape::gen(); @@ -202,4 +204,4 @@ int main(int argc, char **argv) cout << "engine is not supported" << endl; } return 0; -} \ No newline at end of file +} diff --git a/test/testSvg.cpp b/test/testSvg.cpp index 65fe9d7..b8eb2ba 100644 --- a/test/testSvg.cpp +++ b/test/testSvg.cpp @@ -31,6 +31,8 @@ void svgDirCallback(const char* name, const char* path, void* data) void tvgDrawCmds(tvg::Canvas* canvas) { + if (!canvas) return; + //Background auto shape = tvg::Shape::gen(); shape->appendRect(0, 0, WIDTH, HEIGHT, 0, 0); //x, y, w, h, rx, ry @@ -142,4 +144,4 @@ int main(int argc, char **argv) cout << "engine is not supported" << endl; } return 0; -} \ No newline at end of file +} diff --git a/test/testTransform.cpp b/test/testTransform.cpp index 6d0edbf..7529d14 100644 --- a/test/testTransform.cpp +++ b/test/testTransform.cpp @@ -9,6 +9,8 @@ tvg::Shape* pShape3 = nullptr; void tvgDrawCmds(tvg::Canvas* canvas) { + if (!canvas) return; + //Shape1 auto shape = tvg::Shape::gen(); @@ -46,6 +48,8 @@ void tvgDrawCmds(tvg::Canvas* canvas) void tvgUpdateCmds(tvg::Canvas* canvas, float progress) { + if (!canvas) return; + /* Update shape directly. You can update only necessary properties of this shape, while retaining other properties. */ @@ -193,4 +197,4 @@ int main(int argc, char **argv) cout << "engine is not supported" << endl; } return 0; -} \ No newline at end of file +} diff --git a/test/testUpdate.cpp b/test/testUpdate.cpp index 0d00738..9c21343 100644 --- a/test/testUpdate.cpp +++ b/test/testUpdate.cpp @@ -6,6 +6,8 @@ void tvgDrawCmds(tvg::Canvas* canvas) { + if (!canvas) return; + //Shape auto shape = tvg::Shape::gen(); shape->appendRect(-100, -100, 200, 200, 0, 0); @@ -15,6 +17,8 @@ void tvgDrawCmds(tvg::Canvas* canvas) void tvgUpdateCmds(tvg::Canvas* canvas, float progress) { + if (!canvas) return; + //Explicitly clear all retained paint nodes. if (canvas->clear() != tvg::Result::Success) return; @@ -154,4 +158,4 @@ int main(int argc, char **argv) cout << "engine is not supported" << endl; } return 0; -} \ No newline at end of file +} -- 2.7.4 From 2ba529c8fb071bce45cbdb644a3186e920240aa1 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 16 Jul 2020 20:42:42 +0900 Subject: [PATCH 13/16] common transformation: fix transformation multiply Change-Id: Ibc95fab0abfc07aa7f0c4ff6c74785d4f73d02c7 --- src/lib/sw_engine/tvgSwFill.cpp | 12 ++++----- src/lib/sw_engine/tvgSwShape.cpp | 4 +-- src/lib/tvgRender.cpp | 31 +++++++++++----------- src/loaders/svg_loader/tvgSvgSceneBuilder.cpp | 38 ++------------------------- test/svgs/duke.svg | 25 ++++++++++++++++++ test/testCustomTransform.cpp | 12 ++++----- 6 files changed, 56 insertions(+), 66 deletions(-) create mode 100644 test/svgs/duke.svg diff --git a/src/lib/sw_engine/tvgSwFill.cpp b/src/lib/sw_engine/tvgSwFill.cpp index fd857f9..43514bc 100644 --- a/src/lib/sw_engine/tvgSwFill.cpp +++ b/src/lib/sw_engine/tvgSwFill.cpp @@ -100,12 +100,12 @@ bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix* tr auto cy = (y2 - y1) * 0.5f + y1; auto dx = x1 - cx; auto dy = y1 - cy; - x1 = dx * transform->e11 + dy * transform->e12 + transform->e31 + cx; - y1 = dx * transform->e21 + dy * transform->e22 + transform->e32 + cy; + x1 = dx * transform->e11 + dy * transform->e12 + transform->e13 + cx; + y1 = dx * transform->e21 + dy * transform->e22 + transform->e23 + cy; dx = x2 - cx; dy = y2 - cy; - x2 = dx * transform->e11 + dy * transform->e12 + transform->e31 + cx; - y2 = dx * transform->e21 + dy * transform->e22 + transform->e32 + cy; + x2 = dx * transform->e11 + dy * transform->e12 + transform->e13 + cx; + y2 = dx * transform->e21 + dy * transform->e22 + transform->e23 + cy; } fill->linear.dx = x2 - x1; @@ -131,8 +131,8 @@ bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix* tr if (radius < FLT_EPSILON) return true; if (transform) { - auto tx = fill->radial.cx * transform->e11 + fill->radial.cy * transform->e12 + transform->e31; - auto ty = fill->radial.cx * transform->e21 + fill->radial.cy * transform->e22 + transform->e32; + auto tx = fill->radial.cx * transform->e11 + fill->radial.cy * transform->e12 + transform->e13; + auto ty = fill->radial.cx * transform->e21 + fill->radial.cy * transform->e22 + transform->e23; fill->radial.cx = tx; fill->radial.cy = ty; radius *= transform->e33; diff --git a/src/lib/sw_engine/tvgSwShape.cpp b/src/lib/sw_engine/tvgSwShape.cpp index 66655b0..026dae0 100644 --- a/src/lib/sw_engine/tvgSwShape.cpp +++ b/src/lib/sw_engine/tvgSwShape.cpp @@ -239,8 +239,8 @@ static void _transformOutline(SwOutline* outline, const Matrix* transform) for(uint32_t i = 0; i < outline->ptsCnt; ++i) { auto dx = static_cast(outline->pts[i].x >> 6); auto dy = static_cast(outline->pts[i].y >> 6); - auto tx = dx * transform->e11 + dy * transform->e12 + transform->e31; - auto ty = dx * transform->e21 + dy * transform->e22 + transform->e32; + auto tx = dx * transform->e11 + dy * transform->e12 + transform->e13; + auto ty = dx * transform->e21 + dy * transform->e22 + transform->e23; auto pt = Point{round(tx), round(ty)}; outline->pts[i] = TO_SWPOINT(&pt); } diff --git a/src/lib/tvgRender.cpp b/src/lib/tvgRender.cpp index c1212c6..4317aac 100644 --- a/src/lib/tvgRender.cpp +++ b/src/lib/tvgRender.cpp @@ -66,7 +66,6 @@ bool RenderTransform::update() //scale m.e11 *= factor; m.e22 *= factor; - m.e33 *= factor; //rotation if (fabsf(degree) > FLT_EPSILON) { @@ -78,19 +77,19 @@ bool RenderTransform::update() auto t12 = m.e11 * -sinVal + m.e12 * cosVal; auto t21 = m.e21 * cosVal + m.e22 * sinVal; auto t22 = m.e21 * -sinVal + m.e22 * cosVal; - auto t31 = m.e31 * cosVal + m.e32 * sinVal; - auto t32 = m.e31 * -sinVal + m.e32 * cosVal; + auto t13 = m.e13 * cosVal + m.e23 * sinVal; + auto t23 = m.e13 * -sinVal + m.e23 * cosVal; m.e11 = t11; m.e12 = t12; m.e21 = t21; m.e22 = t22; - m.e31 = t31; - m.e32 = t32; + m.e13 = t13; + m.e23 = t23; } - m.e31 += x; - m.e32 += y; + m.e13 += x; + m.e23 += y; return true; } @@ -105,17 +104,17 @@ RenderTransform::RenderTransform(const RenderTransform* lhs, const RenderTransfo { assert(lhs && rhs); - auto dx = rhs->x * lhs->factor; - auto dy = rhs->y * lhs->factor; - auto tx = dx * lhs->m.e11 + dy * lhs->m.e12 + lhs->m.e13; - auto ty = dx * lhs->m.e21 + dy * lhs->m.e22 + lhs->m.e23; + m.e11 = lhs->m.e11 * rhs->m.e11 + lhs->m.e12 * rhs->m.e21 + lhs->m.e13 * rhs->m.e31; + m.e12 = lhs->m.e11 * rhs->m.e12 + lhs->m.e12 * rhs->m.e22 + lhs->m.e13 * rhs->m.e32; + m.e13 = lhs->m.e11 * rhs->m.e13 + lhs->m.e12 * rhs->m.e23 + lhs->m.e13 * rhs->m.e33; - x = lhs->x + tx; - y = lhs->y + ty; - degree = lhs->degree + rhs->degree; - factor = lhs->factor * rhs->factor; + m.e21 = lhs->m.e21 * rhs->m.e11 + lhs->m.e22 * rhs->m.e21 + lhs->m.e23 * rhs->m.e31; + m.e22 = lhs->m.e21 * rhs->m.e12 + lhs->m.e22 * rhs->m.e22 + lhs->m.e23 * rhs->m.e32; + m.e23 = lhs->m.e21 * rhs->m.e13 + lhs->m.e22 * rhs->m.e23 + lhs->m.e23 * rhs->m.e33; - update(); + m.e31 = lhs->m.e31 * rhs->m.e11 + lhs->m.e32 * rhs->m.e21 + lhs->m.e33 * rhs->m.e31; + m.e32 = lhs->m.e31 * rhs->m.e12 + lhs->m.e32 * rhs->m.e22 + lhs->m.e33 * rhs->m.e32; + m.e33 = lhs->m.e31 * rhs->m.e13 + lhs->m.e32 * rhs->m.e23 + lhs->m.e33 * rhs->m.e33; } #endif //_TVG_RENDER_CPP_ diff --git a/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp b/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp index c651368..53f0093 100644 --- a/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp +++ b/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp @@ -20,26 +20,6 @@ #include "tvgSvgSceneBuilder.h" - -static void _getTransformationData(Matrix* m, float* tx, float* ty, float* s, float* z) -{ - float rz, si, cs, zcs, zsi; - - *tx = m->e13; - *ty = m->e23; - - cs = m->e11; - si = m->e21; - rz = atan2(si, cs); - *z = rz * (180.0f / M_PI); - zcs = cosf(-1.0f * rz); - zsi = sinf(-1.0f * rz); - m->e11 = m->e11 * zcs + m->e12 * zsi; - m->e22 = m->e21 * (-1 * zsi) + m->e22 * zcs; - *s = m->e11 > m->e22 ? m->e11 : m->e22; -} - - unique_ptr _applyLinearGradientProperty(SvgStyleGradient* g, Shape* vg, float rx, float ry, float rw, float rh) { Fill::ColorStop* stops; @@ -225,15 +205,7 @@ void _applyProperty(SvgNode* node, Shape* vg, float vx, float vy, float vw, floa { SvgStyleProperty* style = node->style; - //Apply the transformation - if (node->transform) { - float tx = 0, ty = 0, s = 0, z = 0; - _getTransformationData(node->transform, &tx, &ty, &s, &z); - vg->scale(s); - vg->rotate(z); - vg->translate(tx, ty); - } - + if (node->transform) vg->transform(*node->transform); if (node->type == SvgNodeType::Doc) return; //If fill property is nullptr then do nothing @@ -359,13 +331,7 @@ unique_ptr _sceneBuildHelper(SvgNode* node, float vx, float vy, float vw, { if (node->type == SvgNodeType::Doc || node->type == SvgNodeType::G) { auto scene = Scene::gen(); - if (node->transform) { - float tx = 0, ty = 0, s = 0, z = 0; - _getTransformationData(node->transform, &tx, &ty, &s, &z); - scene->scale(s); - scene->rotate(z); - scene->translate(tx, ty); - } + if (node->transform) scene->transform(*node->transform); node->style->opacity = (node->style->opacity * parentOpacity) / 255.0f; for (auto child : node->child) { child->style->opacity = (child->style->opacity * node->style->opacity) / 255.0f; diff --git a/test/svgs/duke.svg b/test/svgs/duke.svg new file mode 100644 index 0000000..64cdcf8 --- /dev/null +++ b/test/svgs/duke.svg @@ -0,0 +1,25 @@ + + + + + diff --git a/test/testCustomTransform.cpp b/test/testCustomTransform.cpp index f95e41e..4803ef1 100644 --- a/test/testCustomTransform.cpp +++ b/test/testCustomTransform.cpp @@ -61,19 +61,19 @@ void tvgUpdateCmds(tvg::Canvas* canvas, float progress) auto t12 = m.e11 * -sinVal + m.e12 * cosVal; auto t21 = m.e21 * cosVal + m.e22 * sinVal; auto t22 = m.e21 * -sinVal + m.e22 * cosVal; - auto t31 = m.e31 * cosVal + m.e32 * sinVal; - auto t32 = m.e31 * -sinVal + m.e32 * cosVal; + auto t13 = m.e31 * cosVal + m.e32 * sinVal; + auto t23 = m.e31 * -sinVal + m.e32 * cosVal; m.e11 = t11; m.e12 = t12; m.e21 = t21; m.e22 = t22; - m.e31 = t31; - m.e32 = t32; + m.e13 = t13; + m.e23 = t23; //translate - m.e31 = progress * 300.0f + 300.0f; - m.e32 = progress * -100.0f + 300.0f; + m.e13 = progress * 300.0f + 300.0f; + m.e23 = progress * -100.0f + 300.0f; pShape->transform(m); -- 2.7.4 From 6cfb3cdb6c469301c8538e77a51b0281a88ead82 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Mon, 20 Jul 2020 11:44:32 +0900 Subject: [PATCH 14/16] test: replaced svg resources. Change-Id: I30ab48ecc0bbae158baecce1f6173fc36ecfbbb6 --- test/svgs/rect.svg | 7 ------- test/svgs/shape.svg | 18 ------------------ test/svgs/wikimedia.svg | 5 +++++ test/svgs/yinyang.svg | 6 ++++++ 4 files changed, 11 insertions(+), 25 deletions(-) delete mode 100644 test/svgs/rect.svg delete mode 100644 test/svgs/shape.svg create mode 100644 test/svgs/wikimedia.svg create mode 100644 test/svgs/yinyang.svg diff --git a/test/svgs/rect.svg b/test/svgs/rect.svg deleted file mode 100644 index 2e82905..0000000 --- a/test/svgs/rect.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/test/svgs/shape.svg b/test/svgs/shape.svg deleted file mode 100644 index a0b3677..0000000 --- a/test/svgs/shape.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/test/svgs/wikimedia.svg b/test/svgs/wikimedia.svg new file mode 100644 index 0000000..ad2c211 --- /dev/null +++ b/test/svgs/wikimedia.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/test/svgs/yinyang.svg b/test/svgs/yinyang.svg new file mode 100644 index 0000000..3c64a6c --- /dev/null +++ b/test/svgs/yinyang.svg @@ -0,0 +1,6 @@ + + + + + + -- 2.7.4 From 27ca82c140e0bdff0cf7646d61a650a7562356bb Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Tue, 21 Jul 2020 10:42:22 +0900 Subject: [PATCH 15/16] SvgLoader: Support display=none feature If display is none, scene does not create a child shape, and shape does not draw fills and strokes. Change-Id: I8af72c904be00107dff115429e27df7ba4cb83b6 --- src/loaders/svg_loader/tvgSvgSceneBuilder.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp b/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp index 53f0093..3b88d96 100644 --- a/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp +++ b/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp @@ -206,7 +206,7 @@ void _applyProperty(SvgNode* node, Shape* vg, float vx, float vy, float vw, floa SvgStyleProperty* style = node->style; if (node->transform) vg->transform(*node->transform); - if (node->type == SvgNodeType::Doc) return; + if (node->type == SvgNodeType::Doc || !node->display) return; //If fill property is nullptr then do nothing if (style->fill.paint.none) { @@ -333,10 +333,12 @@ unique_ptr _sceneBuildHelper(SvgNode* node, float vx, float vy, float vw, auto scene = Scene::gen(); if (node->transform) scene->transform(*node->transform); node->style->opacity = (node->style->opacity * parentOpacity) / 255.0f; - for (auto child : node->child) { - child->style->opacity = (child->style->opacity * node->style->opacity) / 255.0f; - if (child->type == SvgNodeType::Doc || child->type == SvgNodeType::G) scene->push(_sceneBuildHelper(child, vx, vy, vw, vh, node->style->opacity)); - else scene->push(_shapeBuildHelper(child, vx, vy, vw, vh)); + if (node->display) { + for (auto child : node->child) { + child->style->opacity = (child->style->opacity * node->style->opacity) / 255.0f; + if (child->type == SvgNodeType::Doc || child->type == SvgNodeType::G) scene->push(_sceneBuildHelper(child, vx, vy, vw, vh, node->style->opacity)); + else scene->push(_shapeBuildHelper(child, vx, vy, vw, vh)); + } } return move(scene); } -- 2.7.4 From 96477c0a24f4112170ff4d084518a735d8f6483e Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Tue, 21 Jul 2020 17:18:48 +0900 Subject: [PATCH 16/16] sw_engine: revise outline transform sw_engine simulates floating point by integer bit shifting, it loses the accuracy while converting the number data. This occurs the inacculated curve points result if it scales up very large size. So we transform points before converting data in order to avoid losing the numbers less decimal point. Change-Id: I0172e83f06b1a19143a2f65f667dc193e9a4396a --- src/lib/sw_engine/tvgSwCommon.h | 10 +--- src/lib/sw_engine/tvgSwRenderer.cpp | 2 +- src/lib/sw_engine/tvgSwShape.cpp | 101 +++++++++++++++++------------------- 3 files changed, 50 insertions(+), 63 deletions(-) diff --git a/src/lib/sw_engine/tvgSwCommon.h b/src/lib/sw_engine/tvgSwCommon.h index 5e47483..3639166 100644 --- a/src/lib/sw_engine/tvgSwCommon.h +++ b/src/lib/sw_engine/tvgSwCommon.h @@ -207,12 +207,6 @@ struct SwShape }; -static inline SwPoint TO_SWPOINT(const Point* pt) -{ - return {SwCoord(pt->x * 64), SwCoord(pt->y * 64)}; -} - - static inline SwCoord TO_SWCOORD(float val) { return SwCoord(val * 64); @@ -261,12 +255,12 @@ bool mathSmallCubic(SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& SwFixed mathMean(SwFixed angle1, SwFixed angle2); void shapeReset(SwShape& shape); -bool shapeGenOutline(SwShape& shape, const Shape* sdata); +bool shapeGenOutline(SwShape& shape, const Shape* sdata, const Matrix* transform); bool shapePrepare(SwShape& shape, const Shape* sdata, const SwSize& clip, const Matrix* transform); bool shapeGenRle(SwShape& shape, const Shape* sdata, const SwSize& clip, bool antiAlias); void shapeDelOutline(SwShape& shape); void shapeResetStroke(SwShape& shape, const Shape* sdata); -bool shapeGenStrokeRle(SwShape& shape, const Shape* sdata, const SwSize& clip); +bool shapeGenStrokeRle(SwShape& shape, const Shape* sdata, const Matrix* transform, const SwSize& clip); void shapeFree(SwShape& shape); void shapeDelStroke(SwShape& shape); bool shapeGenFillColors(SwShape& shape, const Fill* fill, const Matrix* transform, bool ctable); diff --git a/src/lib/sw_engine/tvgSwRenderer.cpp b/src/lib/sw_engine/tvgSwRenderer.cpp index adc3e9f..7c3ca8d 100644 --- a/src/lib/sw_engine/tvgSwRenderer.cpp +++ b/src/lib/sw_engine/tvgSwRenderer.cpp @@ -212,7 +212,7 @@ void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform* if (task->flags & (RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) { if (strokeAlpha > 0) { shapeResetStroke(task->shape, task->sdata); - if (!shapeGenStrokeRle(task->shape, task->sdata, task->clip)) return; + if (!shapeGenStrokeRle(task->shape, task->sdata, task->transform, task->clip)) return; } else { shapeDelStroke(task->shape); } diff --git a/src/lib/sw_engine/tvgSwShape.cpp b/src/lib/sw_engine/tvgSwShape.cpp index 026dae0..d302fd7 100644 --- a/src/lib/sw_engine/tvgSwShape.cpp +++ b/src/lib/sw_engine/tvgSwShape.cpp @@ -96,13 +96,25 @@ static void _outlineEnd(SwOutline& outline) } -static void _outlineMoveTo(SwOutline& outline, const Point* to) +static inline SwPoint _transform(const Point* to, const Matrix* transform) +{ + if (!transform) return {TO_SWCOORD(to->x), TO_SWCOORD(to->y)}; + + auto tx = round(to->x * transform->e11 + to->y * transform->e12 + transform->e13); + auto ty = round(to->x * transform->e21 + to->y * transform->e22 + transform->e23); + + return {TO_SWCOORD(tx), TO_SWCOORD(ty)}; +} + + +static void _outlineMoveTo(SwOutline& outline, const Point* to, const Matrix* transform) { assert(to); _growOutlinePoint(outline, 1); - outline.pts[outline.ptsCnt] = TO_SWPOINT(to); + outline.pts[outline.ptsCnt] = _transform(to, transform); + outline.types[outline.ptsCnt] = SW_CURVE_TYPE_POINT; if (outline.ptsCnt > 0) { @@ -115,33 +127,33 @@ static void _outlineMoveTo(SwOutline& outline, const Point* to) } -static void _outlineLineTo(SwOutline& outline, const Point* to) +static void _outlineLineTo(SwOutline& outline, const Point* to, const Matrix* transform) { assert(to); _growOutlinePoint(outline, 1); - outline.pts[outline.ptsCnt] = TO_SWPOINT(to); + outline.pts[outline.ptsCnt] = _transform(to, transform); outline.types[outline.ptsCnt] = SW_CURVE_TYPE_POINT; ++outline.ptsCnt; } -static void _outlineCubicTo(SwOutline& outline, const Point* ctrl1, const Point* ctrl2, const Point* to) +static void _outlineCubicTo(SwOutline& outline, const Point* ctrl1, const Point* ctrl2, const Point* to, const Matrix* transform) { assert(ctrl1 && ctrl2 && to); _growOutlinePoint(outline, 3); - outline.pts[outline.ptsCnt] = TO_SWPOINT(ctrl1); + outline.pts[outline.ptsCnt] = _transform(ctrl1, transform); outline.types[outline.ptsCnt] = SW_CURVE_TYPE_CUBIC; ++outline.ptsCnt; - outline.pts[outline.ptsCnt] = TO_SWPOINT(ctrl2); + outline.pts[outline.ptsCnt] = _transform(ctrl2, transform); outline.types[outline.ptsCnt] = SW_CURVE_TYPE_CUBIC; ++outline.ptsCnt; - outline.pts[outline.ptsCnt] = TO_SWPOINT(to); + outline.pts[outline.ptsCnt] = _transform(to, transform); outline.types[outline.ptsCnt] = SW_CURVE_TYPE_POINT; ++outline.ptsCnt; } @@ -230,24 +242,7 @@ static bool _checkValid(const SwOutline* outline, const SwBBox& bbox, const SwSi } -static void _transformOutline(SwOutline* outline, const Matrix* transform) -{ - if (!transform) return; - - assert(outline); - - for(uint32_t i = 0; i < outline->ptsCnt; ++i) { - auto dx = static_cast(outline->pts[i].x >> 6); - auto dy = static_cast(outline->pts[i].y >> 6); - auto tx = dx * transform->e11 + dy * transform->e12 + transform->e13; - auto ty = dx * transform->e21 + dy * transform->e22 + transform->e23; - auto pt = Point{round(tx), round(ty)}; - outline->pts[i] = TO_SWPOINT(&pt); - } -} - - -static void _dashLineTo(SwDashStroke& dash, const Point* to) +static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* transform) { _growOutlinePoint(*dash.outline, dash.outline->ptsCnt >> 1); _growOutlineContour(*dash.outline, dash.outline->cntrsCnt >> 1); @@ -258,8 +253,8 @@ static void _dashLineTo(SwDashStroke& dash, const Point* to) if (len < dash.curLen) { dash.curLen -= len; if (!dash.curOpGap) { - _outlineMoveTo(*dash.outline, &dash.ptCur); - _outlineLineTo(*dash.outline, to); + _outlineMoveTo(*dash.outline, &dash.ptCur, transform); + _outlineLineTo(*dash.outline, to, transform); } } else { while (len > dash.curLen) { @@ -268,8 +263,8 @@ static void _dashLineTo(SwDashStroke& dash, const Point* to) _lineSplitAt(cur, dash.curLen, left, right);; dash.curIdx = (dash.curIdx + 1) % dash.cnt; if (!dash.curOpGap) { - _outlineMoveTo(*dash.outline, &left.pt1); - _outlineLineTo(*dash.outline, &left.pt2); + _outlineMoveTo(*dash.outline, &left.pt1, transform); + _outlineLineTo(*dash.outline, &left.pt2, transform); } dash.curLen = dash.pattern[dash.curIdx]; dash.curOpGap = !dash.curOpGap; @@ -278,9 +273,9 @@ static void _dashLineTo(SwDashStroke& dash, const Point* to) } //leftovers dash.curLen -= len; - if (!dash.curOpGap) { - _outlineMoveTo(*dash.outline, &cur.pt1); - _outlineLineTo(*dash.outline, &cur.pt2); + if (!dash.curOpGap) { + _outlineMoveTo(*dash.outline, &cur.pt1, transform); + _outlineLineTo(*dash.outline, &cur.pt2, transform); } if (dash.curLen < 1) { //move to next dash @@ -293,7 +288,7 @@ static void _dashLineTo(SwDashStroke& dash, const Point* to) } -static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ctrl2, const Point* to) +static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ctrl2, const Point* to, const Matrix* transform) { _growOutlinePoint(*dash.outline, dash.outline->ptsCnt >> 1); _growOutlineContour(*dash.outline, dash.outline->cntrsCnt >> 1); @@ -304,8 +299,8 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct if (len < dash.curLen) { dash.curLen -= len; if (!dash.curOpGap) { - _outlineMoveTo(*dash.outline, &dash.ptCur); - _outlineCubicTo(*dash.outline, ctrl1, ctrl2, to); + _outlineMoveTo(*dash.outline, &dash.ptCur, transform); + _outlineCubicTo(*dash.outline, ctrl1, ctrl2, to, transform); } } else { while (len > dash.curLen) { @@ -314,8 +309,8 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct bezSplitAt(cur, dash.curLen, left, right); dash.curIdx = (dash.curIdx + 1) % dash.cnt; if (!dash.curOpGap) { - _outlineMoveTo(*dash.outline, &left.start); - _outlineCubicTo(*dash.outline, &left.ctrl1, &left.ctrl2, &left.end); + _outlineMoveTo(*dash.outline, &left.start, transform); + _outlineCubicTo(*dash.outline, &left.ctrl1, &left.ctrl2, &left.end, transform); } dash.curLen = dash.pattern[dash.curIdx]; dash.curOpGap = !dash.curOpGap; @@ -325,8 +320,8 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct //leftovers dash.curLen -= len; if (!dash.curOpGap) { - _outlineMoveTo(*dash.outline, &cur.start); - _outlineCubicTo(*dash.outline, &cur.ctrl1, &cur.ctrl2, &cur.end); + _outlineMoveTo(*dash.outline, &cur.start, transform); + _outlineCubicTo(*dash.outline, &cur.ctrl1, &cur.ctrl2, &cur.end, transform); } if (dash.curLen < 1) { //move to next dash @@ -339,7 +334,7 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct } -SwOutline* _genDashOutline(const Shape* sdata) +SwOutline* _genDashOutline(const Shape* sdata, const Matrix* transform) { assert(sdata); @@ -405,7 +400,7 @@ SwOutline* _genDashOutline(const Shape* sdata) while (cmdCnt-- > 0) { switch(*cmds) { case PathCommand::Close: { - _dashLineTo(dash, &dash.ptStart); + _dashLineTo(dash, &dash.ptStart, transform); break; } case PathCommand::MoveTo: { @@ -418,12 +413,12 @@ SwOutline* _genDashOutline(const Shape* sdata) break; } case PathCommand::LineTo: { - _dashLineTo(dash, pts); + _dashLineTo(dash, pts, transform); ++pts; break; } case PathCommand::CubicTo: { - _dashCubicTo(dash, pts, pts + 1, pts + 2); + _dashCubicTo(dash, pts, pts + 1, pts + 2, transform); pts += 3; break; } @@ -465,9 +460,7 @@ bool _fastTrack(const SwOutline* outline) bool shapePrepare(SwShape& shape, const Shape* sdata, const SwSize& clip, const Matrix* transform) { - if (!shapeGenOutline(shape, sdata)) return false; - - _transformOutline(shape.outline, transform); + if (!shapeGenOutline(shape, sdata, transform)) return false; if (!_updateBBox(shape.outline, shape.bbox)) return false; @@ -510,7 +503,7 @@ void shapeReset(SwShape& shape) } -bool shapeGenOutline(SwShape& shape, const Shape* sdata) +bool shapeGenOutline(SwShape& shape, const Shape* sdata, const Matrix* transform) { assert(sdata); @@ -571,17 +564,17 @@ bool shapeGenOutline(SwShape& shape, const Shape* sdata) break; } case PathCommand::MoveTo: { - _outlineMoveTo(*outline, pts); + _outlineMoveTo(*outline, pts, transform); ++pts; break; } case PathCommand::LineTo: { - _outlineLineTo(*outline, pts); + _outlineLineTo(*outline, pts, transform); ++pts; break; } case PathCommand::CubicTo: { - _outlineCubicTo(*outline, pts, pts + 1, pts + 2); + _outlineCubicTo(*outline, pts, pts + 1, pts + 2, transform); pts += 3; break; } @@ -638,7 +631,7 @@ void shapeResetStroke(SwShape& shape, const Shape* sdata) } -bool shapeGenStrokeRle(SwShape& shape, const Shape* sdata, const SwSize& clip) +bool shapeGenStrokeRle(SwShape& shape, const Shape* sdata, const Matrix* transform, const SwSize& clip) { assert(sdata); @@ -646,12 +639,12 @@ bool shapeGenStrokeRle(SwShape& shape, const Shape* sdata, const SwSize& clip) //Dash Style Stroke if (sdata->strokeDash(nullptr) > 0) { - shapeOutline = _genDashOutline(sdata); + shapeOutline = _genDashOutline(sdata, transform); if (!shapeOutline) return false; //Normal Style stroke } else { if (!shape.outline) { - if (!shapeGenOutline(shape, sdata)) return false; + if (!shapeGenOutline(shape, sdata, transform)) return false; } shapeOutline = shape.outline; } -- 2.7.4