From 3b385d1d5496d27217582c11a34c659e5ac601de Mon Sep 17 00:00:00 2001 From: Pranay Kumar Samanta Date: Wed, 15 Jul 2020 19:02:27 +0530 Subject: [PATCH 01/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 02/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 03/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 04/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 05/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 06/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 07/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 08/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 From 5dcafb8b89928d36821a5c92573df2009b6ae821 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Wed, 22 Jul 2020 18:45:11 +0900 Subject: [PATCH 09/16] comon: code refactoring renamed internal variable for better readibility. Change-Id: I07dc66c4bd63f2aec8036aab14ec3ed608820fbc --- src/lib/tvgRender.cpp | 6 +++--- src/lib/tvgRender.h | 2 +- src/lib/tvgSceneImpl.h | 4 ++-- src/lib/tvgShapeImpl.h | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/lib/tvgRender.cpp b/src/lib/tvgRender.cpp index 4317aac..89edcb1 100644 --- a/src/lib/tvgRender.cpp +++ b/src/lib/tvgRender.cpp @@ -48,7 +48,7 @@ bool RenderTransform::update() //Init Status if (fabsf(x) <= FLT_EPSILON && fabsf(y) <= FLT_EPSILON && - fabsf(degree) <= FLT_EPSILON && fabsf(factor - 1) <= FLT_EPSILON) { + fabsf(degree) <= FLT_EPSILON && fabsf(scale - 1) <= FLT_EPSILON) { return false; } @@ -64,8 +64,8 @@ bool RenderTransform::update() m.e33 = 1.0f; //scale - m.e11 *= factor; - m.e22 *= factor; + m.e11 *= scale; + m.e22 *= scale; //rotation if (fabsf(degree) > FLT_EPSILON) { diff --git a/src/lib/tvgRender.h b/src/lib/tvgRender.h index e20271b..576961e 100644 --- a/src/lib/tvgRender.h +++ b/src/lib/tvgRender.h @@ -36,7 +36,7 @@ struct RenderTransform float x = 0.0f; float y = 0.0f; float degree = 0.0f; //rotation degree - float factor = 1.0f; //scale factor + float scale = 1.0f; //scale factor bool overriding = false; //user transform? bool update(); diff --git a/src/lib/tvgSceneImpl.h b/src/lib/tvgSceneImpl.h index a70991c..9972d72 100644 --- a/src/lib/tvgSceneImpl.h +++ b/src/lib/tvgSceneImpl.h @@ -166,13 +166,13 @@ struct Scene::Impl bool scale(float factor) { if (rTransform) { - if (fabsf(factor - rTransform->factor) <= FLT_EPSILON) return true; + if (fabsf(factor - rTransform->scale) <= FLT_EPSILON) return true; } else { if (fabsf(factor) <= FLT_EPSILON) return true; rTransform = new RenderTransform(); if (!rTransform) return false; } - rTransform->factor = factor; + rTransform->scale = factor; flag |= RenderUpdateFlag::Transform; return true; diff --git a/src/lib/tvgShapeImpl.h b/src/lib/tvgShapeImpl.h index fa670f0..54d37a3 100644 --- a/src/lib/tvgShapeImpl.h +++ b/src/lib/tvgShapeImpl.h @@ -105,13 +105,13 @@ struct Shape::Impl bool scale(float factor) { if (rTransform) { - if (fabsf(factor - rTransform->factor) <= FLT_EPSILON) return true; + if (fabsf(factor - rTransform->scale) <= FLT_EPSILON) return true; } else { if (fabsf(factor) <= FLT_EPSILON) return true; rTransform = new RenderTransform(); if (!rTransform) return false; } - rTransform->factor = factor; + rTransform->scale = factor; if (!rTransform->overriding) flag |= RenderUpdateFlag::Transform; return true; -- 2.7.4 From 4d72eeda1556e179ecf7b60bc2a7829a476ef8e8 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Tue, 21 Jul 2020 20:24:25 +0900 Subject: [PATCH 10/16] sw_engine: revise scale transform logic. Basically, stroke width size is linear, engine couldn't apply scale factor from the matrix which contains 2 dimensional values. Thus, we can apply it if the scale factor of x/y is identical. Otherwise, we should transform every stroke points in the stroking process. That scenario can be improved with another patch. Change-Id: I070dcf29d2e42f21e182bdf4239781464158ef73 --- src/lib/sw_engine/tvgSwCommon.h | 5 +++-- src/lib/sw_engine/tvgSwRenderer.cpp | 4 ++-- src/lib/sw_engine/tvgSwShape.cpp | 4 ++-- src/lib/sw_engine/tvgSwStroke.cpp | 11 +++++++++-- src/lib/tvgRender.h | 2 +- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/lib/sw_engine/tvgSwCommon.h b/src/lib/sw_engine/tvgSwCommon.h index 3639166..b1d38af 100644 --- a/src/lib/sw_engine/tvgSwCommon.h +++ b/src/lib/sw_engine/tvgSwCommon.h @@ -156,6 +156,7 @@ struct SwStroke bool firstPt; bool openSubPath; bool handleWideStrokes; + bool preScaled; }; struct SwDashStroke @@ -259,7 +260,7 @@ 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); +void shapeResetStroke(SwShape& shape, const Shape* sdata, const Matrix* transform); bool shapeGenStrokeRle(SwShape& shape, const Shape* sdata, const Matrix* transform, const SwSize& clip); void shapeFree(SwShape& shape); void shapeDelStroke(SwShape& shape); @@ -267,7 +268,7 @@ bool shapeGenFillColors(SwShape& shape, const Fill* fill, const Matrix* transfor void shapeResetFill(SwShape& shape); void shapeDelFill(SwShape& shape); -void strokeReset(SwStroke& stroke, const Shape* shape); +void strokeReset(SwStroke& stroke, const Shape* shape, const Matrix* transform); bool strokeParseOutline(SwStroke& stroke, const SwOutline& outline); SwOutline* strokeExportOutline(SwStroke& stroke); void strokeFree(SwStroke* stroke); diff --git a/src/lib/sw_engine/tvgSwRenderer.cpp b/src/lib/sw_engine/tvgSwRenderer.cpp index 7c3ca8d..aac6d8e 100644 --- a/src/lib/sw_engine/tvgSwRenderer.cpp +++ b/src/lib/sw_engine/tvgSwRenderer.cpp @@ -211,7 +211,7 @@ void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform* //Stroke if (task->flags & (RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) { if (strokeAlpha > 0) { - shapeResetStroke(task->shape, task->sdata); + shapeResetStroke(task->shape, task->sdata, task->transform); if (!shapeGenStrokeRle(task->shape, task->sdata, task->transform, task->clip)) return; } else { shapeDelStroke(task->shape); @@ -257,4 +257,4 @@ SwRenderer* SwRenderer::inst() return static_cast(RenderInitializer::inst(renderInit)); } -#endif /* _TVG_SW_RENDERER_CPP_ */ +#endif /* _TVG_SW_RENDERER_CPP_ */ \ No newline at end of file diff --git a/src/lib/sw_engine/tvgSwShape.cpp b/src/lib/sw_engine/tvgSwShape.cpp index d302fd7..c3aced8 100644 --- a/src/lib/sw_engine/tvgSwShape.cpp +++ b/src/lib/sw_engine/tvgSwShape.cpp @@ -618,13 +618,13 @@ void shapeDelStroke(SwShape& shape) } -void shapeResetStroke(SwShape& shape, const Shape* sdata) +void shapeResetStroke(SwShape& shape, const Shape* sdata, const Matrix* transform) { if (!shape.stroke) shape.stroke = static_cast(calloc(1, sizeof(SwStroke))); auto stroke = shape.stroke; assert(stroke); - strokeReset(*stroke, sdata); + strokeReset(*stroke, sdata, transform); rleFree(shape.strokeRle); shape.strokeRle = nullptr; diff --git a/src/lib/sw_engine/tvgSwStroke.cpp b/src/lib/sw_engine/tvgSwStroke.cpp index d45ddd8..abaf455 100644 --- a/src/lib/sw_engine/tvgSwStroke.cpp +++ b/src/lib/sw_engine/tvgSwStroke.cpp @@ -818,11 +818,18 @@ void strokeFree(SwStroke* stroke) } -void strokeReset(SwStroke& stroke, const Shape* sdata) +void strokeReset(SwStroke& stroke, const Shape* sdata, const Matrix* transform) { assert(sdata); - stroke.width = TO_SWCOORD(sdata->strokeWidth() * 0.5); + //If x/y scale factor is identical, we can scale width size simply. + auto scale = 1.0f; + if (transform && fabsf(transform->e11 - transform->e22) < FLT_EPSILON) { + scale = transform->e11; + stroke.preScaled = true; + } + + stroke.width = TO_SWCOORD(sdata->strokeWidth() * 0.5 * scale); stroke.cap = sdata->strokeCap(); //Save line join: it can be temporarily changed when stroking curves... diff --git a/src/lib/tvgRender.h b/src/lib/tvgRender.h index 576961e..6a0897e 100644 --- a/src/lib/tvgRender.h +++ b/src/lib/tvgRender.h @@ -32,7 +32,7 @@ enum RenderUpdateFlag {None = 0, Path = 1, Color = 2, Gradient = 4, Stroke = 8, struct RenderTransform { - Matrix m; //3x3 Matrix Elements + Matrix m; //3x3 Matrix Elements float x = 0.0f; float y = 0.0f; float degree = 0.0f; //rotation degree -- 2.7.4 From 62aa24d9adcb1c84b623b1bdfe6197b6234a1160 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Thu, 23 Jul 2020 10:14:46 +0900 Subject: [PATCH 11/16] SvgLoader: Fix opacity propagation Remove duplicate opacity calculation of the scene. Change-Id: I1253ea290e78fdbf946a492ebfcaaa082fbfc121 --- src/loaders/svg_loader/tvgSvgSceneBuilder.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp b/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp index 3b88d96..4d7a27a 100644 --- a/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp +++ b/src/loaders/svg_loader/tvgSvgSceneBuilder.cpp @@ -335,9 +335,11 @@ unique_ptr _sceneBuildHelper(SvgNode* node, float vx, float vy, float vw, node->style->opacity = (node->style->opacity * parentOpacity) / 255.0f; 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)); + else { + child->style->opacity = (child->style->opacity * node->style->opacity) / 255.0f; + scene->push(_shapeBuildHelper(child, vx, vy, vw, vh)); + } } } return move(scene); -- 2.7.4 From f1aab529589fa4ff0bbafe86965d9e25ec40e3b0 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Wed, 22 Jul 2020 20:31:57 +0900 Subject: [PATCH 12/16] sw_engine: support bidirectional stroke scaling. if the transform scale factor for x/y is not identical, it keeps its both xy scale factor then apply them for stroking calculation. Change-Id: I519dfce3ce7b4a12c13da1801d6a00e139e7400f --- src/lib/sw_engine/tvgSwCommon.h | 5 ++- src/lib/sw_engine/tvgSwShape.cpp | 22 +++++++------- src/lib/sw_engine/tvgSwStroke.cpp | 64 +++++++++++++++++++++++++++++++-------- 3 files changed, 66 insertions(+), 25 deletions(-) diff --git a/src/lib/sw_engine/tvgSwCommon.h b/src/lib/sw_engine/tvgSwCommon.h index b1d38af..bad159b 100644 --- a/src/lib/sw_engine/tvgSwCommon.h +++ b/src/lib/sw_engine/tvgSwCommon.h @@ -153,10 +153,13 @@ struct SwStroke SwStrokeBorder borders[2]; + float sx; + float sy; + bool firstPt; bool openSubPath; bool handleWideStrokes; - bool preScaled; + bool postScale; }; struct SwDashStroke diff --git a/src/lib/sw_engine/tvgSwShape.cpp b/src/lib/sw_engine/tvgSwShape.cpp index c3aced8..2165f42 100644 --- a/src/lib/sw_engine/tvgSwShape.cpp +++ b/src/lib/sw_engine/tvgSwShape.cpp @@ -30,6 +30,17 @@ struct Line }; +static 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 float _lineLength(const Point& pt1, const Point& pt2) { /* approximate sqrt(x*x + y*y) using alpha max plus beta min algorithm. @@ -96,17 +107,6 @@ static void _outlineEnd(SwOutline& outline) } -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); diff --git a/src/lib/sw_engine/tvgSwStroke.cpp b/src/lib/sw_engine/tvgSwStroke.cpp index abaf455..53fae90 100644 --- a/src/lib/sw_engine/tvgSwStroke.cpp +++ b/src/lib/sw_engine/tvgSwStroke.cpp @@ -34,6 +34,15 @@ static inline SwFixed SIDE_TO_ROTATE(const int32_t s) } +static inline void SCALE(SwStroke& stroke, SwPoint& pt) +{ + if (stroke.postScale) { + pt.x = pt.x * stroke.sx; + pt.y = pt.y * stroke.sy; + } +} + + static void _growBorder(SwStrokeBorder* border, uint32_t newPts) { assert(border); @@ -132,11 +141,12 @@ static void _borderCubicTo(SwStrokeBorder* border, SwPoint& ctrl1, SwPoint& ctrl } -static void _borderArcTo(SwStrokeBorder* border, SwPoint& center, SwFixed radius, SwFixed angleStart, SwFixed angleDiff) +static void _borderArcTo(SwStrokeBorder* border, SwPoint& center, SwFixed radius, SwFixed angleStart, SwFixed angleDiff, SwStroke& stroke) { constexpr SwFixed ARC_CUBIC_ANGLE = SW_ANGLE_PI / 2; SwPoint a = {radius, 0}; mathRotate(a, angleStart); + SCALE(stroke, a); a += center; auto total = angleDiff; @@ -157,6 +167,7 @@ static void _borderArcTo(SwStrokeBorder* border, SwPoint& center, SwFixed radius //compute end point SwPoint b = {radius, 0}; mathRotate(b, next); + SCALE(stroke, b); b += center; //compute first and second control points @@ -164,10 +175,12 @@ static void _borderArcTo(SwStrokeBorder* border, SwPoint& center, SwFixed radius SwPoint a2 = {length, 0}; mathRotate(a2, angle + rotate); + SCALE(stroke, a2); a2 += a; SwPoint b2 = {length, 0}; mathRotate(b2, next - rotate); + SCALE(stroke, b2); b2 += b; //add cubic arc @@ -224,7 +237,7 @@ static void _arcTo(SwStroke& stroke, int32_t side) auto total = mathDiff(stroke.angleIn, stroke.angleOut); if (total == SW_ANGLE_PI) total = -rotate * 2; - _borderArcTo(border, stroke.center, stroke.width, stroke.angleIn + rotate, total); + _borderArcTo(border, stroke.center, stroke.width, stroke.angleIn + rotate, total, stroke); border->movable = false; } @@ -268,6 +281,7 @@ static void _outside(SwStroke& stroke, int32_t side, SwFixed lineLength) if (bevel) { SwPoint delta = {stroke.width, 0}; mathRotate(delta, stroke.angleOut + rotate); + SCALE(stroke, delta); delta += stroke.center; border->movable = false; _borderLineTo(border, delta, false); @@ -276,6 +290,7 @@ static void _outside(SwStroke& stroke, int32_t side, SwFixed lineLength) auto length = mathDivide(stroke.width, thcos); SwPoint delta = {length, 0}; mathRotate(delta, phi); + SCALE(stroke, delta); delta += stroke.center; _borderLineTo(border, delta, false); @@ -284,6 +299,7 @@ static void _outside(SwStroke& stroke, int32_t side, SwFixed lineLength) if (lineLength == 0) { delta = {stroke.width, 0}; mathRotate(delta, stroke.angleOut + rotate); + SCALE(stroke, delta); delta += stroke.center; _borderLineTo(border, delta, false); } @@ -312,15 +328,16 @@ static void _inside(SwStroke& stroke, int32_t side, SwFixed lineLength) if (!intersect) { delta = {stroke.width, 0}; mathRotate(delta, stroke.angleOut + rotate); + SCALE(stroke, delta); delta += stroke.center; border->movable = false; } else { //compute median angle auto phi = stroke.angleIn + theta; auto thcos = mathCos(theta); - auto length = mathDivide(stroke.width, thcos); - delta = {length, 0}; + delta = {mathDivide(stroke.width, thcos), 0}; mathRotate(delta, phi + rotate); + SCALE(stroke, delta); delta += stroke.center; } @@ -353,6 +370,7 @@ void _firstSubPath(SwStroke& stroke, SwFixed startAngle, SwFixed lineLength) { SwPoint delta = {stroke.width, 0}; mathRotate(delta, startAngle + SW_ANGLE_PI2); + SCALE(stroke, delta); auto pt = stroke.center + delta; auto border = stroke.borders; @@ -383,6 +401,7 @@ static void _lineTo(SwStroke& stroke, const SwPoint& to) delta = {stroke.width, 0}; mathRotate(delta, angle + SW_ANGLE_PI2); + SCALE(stroke, delta); //process corner if necessary if (stroke.firstPt) { @@ -428,9 +447,9 @@ static void _cubicTo(SwStroke& stroke, const SwPoint& ctrl1, const SwPoint& ctrl } SwPoint bezStack[37]; //TODO: static? - auto firstArc = true; auto limit = bezStack + 32; auto arc = bezStack; + auto firstArc = true; arc[0] = to; arc[1] = ctrl2; arc[2] = ctrl1; @@ -494,15 +513,18 @@ static void _cubicTo(SwStroke& stroke, const SwPoint& ctrl1, const SwPoint& ctrl //compute control points SwPoint _ctrl1 = {length1, 0}; mathRotate(_ctrl1, phi1 + rotate); + SCALE(stroke, _ctrl1); _ctrl1 += arc[2]; SwPoint _ctrl2 = {length2, 0}; mathRotate(_ctrl2, phi2 + rotate); + SCALE(stroke, _ctrl2); _ctrl2 += arc[1]; //compute end point SwPoint _end = {stroke.width, 0}; mathRotate(_end, angleOut + rotate); + SCALE(stroke, _end); _end += arc[0]; if (stroke.handleWideStrokes) { @@ -526,6 +548,7 @@ static void _cubicTo(SwStroke& stroke, const SwPoint& ctrl1, const SwPoint& ctrl SwPoint delta = {alen, 0}; mathRotate(delta, beta); + SCALE(stroke, delta); delta += _start; //circumnavigate the negative sector backwards @@ -557,25 +580,28 @@ static void _cubicTo(SwStroke& stroke, const SwPoint& ctrl1, const SwPoint& ctrl static void _addCap(SwStroke& stroke, SwFixed angle, int32_t side) { - if (stroke.cap == StrokeCap::Square) { + if (stroke.cap == StrokeCap::Square) { auto rotate = SIDE_TO_ROTATE(side); auto border = stroke.borders + side; SwPoint delta = {stroke.width, 0}; mathRotate(delta, angle); + SCALE(stroke, delta); SwPoint delta2 = {stroke.width, 0}; mathRotate(delta2, angle + rotate); + SCALE(stroke, delta2); delta += stroke.center + delta2; _borderLineTo(border, delta, false); delta = {stroke.width, 0}; mathRotate(delta, angle); + SCALE(stroke, delta); delta2 = {stroke.width, 0}; mathRotate(delta2, angle - rotate); - + SCALE(stroke, delta2); delta += delta2 + stroke.center; _borderLineTo(border, delta, false); @@ -593,14 +619,14 @@ static void _addCap(SwStroke& stroke, SwFixed angle, int32_t side) SwPoint delta = {stroke.width, 0}; mathRotate(delta, angle + rotate); - + SCALE(stroke, delta); delta += stroke.center; _borderLineTo(border, delta, false); delta = {stroke.width, 0}; mathRotate(delta, angle - rotate); - + SCALE(stroke, delta); delta += stroke.center; _borderLineTo(border, delta, false); @@ -822,11 +848,23 @@ void strokeReset(SwStroke& stroke, const Shape* sdata, const Matrix* transform) { assert(sdata); - //If x/y scale factor is identical, we can scale width size simply. auto scale = 1.0f; - if (transform && fabsf(transform->e11 - transform->e22) < FLT_EPSILON) { - scale = transform->e11; - stroke.preScaled = true; + + if (transform) { + //Fast Track: if x/y scale factor is identical, we can scale width size simply. + auto sx = sqrt(pow(transform->e11, 2) + pow(transform->e21, 2)); + auto sy = sqrt(pow(transform->e12, 2) + pow(transform->e22, 2)); + if (fabsf(sx - sy) < FLT_EPSILON) { + scale = sx; + stroke.postScale = false; + //Try scaling stroke with normal approach. + } else { + stroke.postScale = true; + stroke.sx = sx; + stroke.sy = sy; + } + } else { + stroke.postScale = false; } stroke.width = TO_SWCOORD(sdata->strokeWidth() * 0.5 * scale); -- 2.7.4 From 5fdc1f7fc86b9a9667741491c63d060ecfb15dd6 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Fri, 24 Jul 2020 11:03:20 +0900 Subject: [PATCH 13/16] sw_engine: revise stroke scaling logic. previous fast track logic is useless, it actually doesn't helpful for performance, just increase the code complexity. Change-Id: Ib6ad204edfb241d74c41413dfec7ab42fb02af81 --- src/lib/sw_engine/tvgSwCommon.h | 4 +--- src/lib/sw_engine/tvgSwStroke.cpp | 27 ++++++--------------------- 2 files changed, 7 insertions(+), 24 deletions(-) diff --git a/src/lib/sw_engine/tvgSwCommon.h b/src/lib/sw_engine/tvgSwCommon.h index bad159b..5f7ec46 100644 --- a/src/lib/sw_engine/tvgSwCommon.h +++ b/src/lib/sw_engine/tvgSwCommon.h @@ -153,13 +153,11 @@ struct SwStroke SwStrokeBorder borders[2]; - float sx; - float sy; + float sx, sy; bool firstPt; bool openSubPath; bool handleWideStrokes; - bool postScale; }; struct SwDashStroke diff --git a/src/lib/sw_engine/tvgSwStroke.cpp b/src/lib/sw_engine/tvgSwStroke.cpp index 53fae90..15cbf02 100644 --- a/src/lib/sw_engine/tvgSwStroke.cpp +++ b/src/lib/sw_engine/tvgSwStroke.cpp @@ -36,10 +36,8 @@ static inline SwFixed SIDE_TO_ROTATE(const int32_t s) static inline void SCALE(SwStroke& stroke, SwPoint& pt) { - if (stroke.postScale) { - pt.x = pt.x * stroke.sx; - pt.y = pt.y * stroke.sy; - } + pt.x *= stroke.sx; + pt.y *= stroke.sy; } @@ -548,7 +546,6 @@ static void _cubicTo(SwStroke& stroke, const SwPoint& ctrl1, const SwPoint& ctrl SwPoint delta = {alen, 0}; mathRotate(delta, beta); - SCALE(stroke, delta); delta += _start; //circumnavigate the negative sector backwards @@ -848,26 +845,14 @@ void strokeReset(SwStroke& stroke, const Shape* sdata, const Matrix* transform) { assert(sdata); - auto scale = 1.0f; - if (transform) { - //Fast Track: if x/y scale factor is identical, we can scale width size simply. - auto sx = sqrt(pow(transform->e11, 2) + pow(transform->e21, 2)); - auto sy = sqrt(pow(transform->e12, 2) + pow(transform->e22, 2)); - if (fabsf(sx - sy) < FLT_EPSILON) { - scale = sx; - stroke.postScale = false; - //Try scaling stroke with normal approach. - } else { - stroke.postScale = true; - stroke.sx = sx; - stroke.sy = sy; - } + stroke.sx = sqrt(pow(transform->e11, 2) + pow(transform->e21, 2)); + stroke.sy = sqrt(pow(transform->e12, 2) + pow(transform->e22, 2)); } else { - stroke.postScale = false; + stroke.sx = stroke.sy = 1.0f; } - stroke.width = TO_SWCOORD(sdata->strokeWidth() * 0.5 * scale); + stroke.width = TO_SWCOORD(sdata->strokeWidth() * 0.5); stroke.cap = sdata->strokeCap(); //Save line join: it can be temporarily changed when stroking curves... -- 2.7.4 From 76a7c900bebceb7735712366cb7571b2fa105874 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 23 Jul 2020 20:56:05 +0900 Subject: [PATCH 14/16] sw_engine gradient: support x/y scale for radial gradient Change-Id: Id725637e261642d0e92d100c73841278b7f44c1c --- src/lib/sw_engine/tvgSwCommon.h | 2 ++ src/lib/sw_engine/tvgSwFill.cpp | 19 ++++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/lib/sw_engine/tvgSwCommon.h b/src/lib/sw_engine/tvgSwCommon.h index 5f7ec46..469ce0f 100644 --- a/src/lib/sw_engine/tvgSwCommon.h +++ b/src/lib/sw_engine/tvgSwCommon.h @@ -193,6 +193,8 @@ struct SwFill uint32_t* ctable; FillSpread spread; + float sx, sy; + bool translucent; }; diff --git a/src/lib/sw_engine/tvgSwFill.cpp b/src/lib/sw_engine/tvgSwFill.cpp index 43514bc..0ac9383 100644 --- a/src/lib/sw_engine/tvgSwFill.cpp +++ b/src/lib/sw_engine/tvgSwFill.cpp @@ -130,12 +130,25 @@ bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix* tr if (radial->radial(&fill->radial.cx, &fill->radial.cy, &radius) != Result::Success) return false; if (radius < FLT_EPSILON) return true; + fill->sx = 1.0f; + fill->sy = 1.0f; + if (transform) { 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; + + auto sx = sqrt(pow(transform->e11, 2) + pow(transform->e21, 2)); + auto sy = sqrt(pow(transform->e12, 2) + pow(transform->e22, 2)); + + //FIXME; Scale + Rotation is not working properly + radius *= sx; + + if (fabsf(sx - sy) > FLT_EPSILON) { + fill->sx = sx; + fill->sy = sy; + } } fill->radial.a = radius * radius; @@ -190,8 +203,8 @@ void fillFetchRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, if (fill->radial.a < FLT_EPSILON) return; //Rotation - auto rx = x + 0.5f - fill->radial.cx; - auto ry = y + 0.5f - fill->radial.cy; + auto rx = (x + 0.5f - fill->radial.cx) * fill->sy; + auto ry = (y + 0.5f - fill->radial.cy) * fill->sx; auto inv2a = fill->radial.inv2a; auto rxy = rx * rx + ry * ry; auto rxryPlus = 2 * rx; -- 2.7.4 From bee94d48fee5c2d17716d63f5b15d79c45feab36 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Fri, 24 Jul 2020 21:09:24 +0900 Subject: [PATCH 15/16] sw_engine gradient: support x/y scale for linear gradient Change-Id: Ic58e7cc61a3c90307b6cfb629eb8af69b75fb903 --- src/lib/sw_engine/tvgSwFill.cpp | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/lib/sw_engine/tvgSwFill.cpp b/src/lib/sw_engine/tvgSwFill.cpp index 0ac9383..266acaa 100644 --- a/src/lib/sw_engine/tvgSwFill.cpp +++ b/src/lib/sw_engine/tvgSwFill.cpp @@ -96,16 +96,18 @@ bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix* tr if (linear->linear(&x1, &y1, &x2, &y2) != Result::Success) return false; if (transform) { + auto sx = sqrt(pow(transform->e11, 2) + pow(transform->e21, 2)); + auto sy = sqrt(pow(transform->e12, 2) + pow(transform->e22, 2)); auto cx = (x2 - x1) * 0.5f + x1; auto cy = (y2 - y1) * 0.5f + y1; auto dx = x1 - cx; auto dy = y1 - cy; - x1 = dx * transform->e11 + dy * transform->e12 + transform->e13 + cx; - y1 = dx * transform->e21 + dy * transform->e22 + transform->e23 + cy; + x1 = dx * transform->e11 + dy * transform->e12 + transform->e13 + (cx * sx); + y1 = dx * transform->e21 + dy * transform->e22 + transform->e23 + (cy * sy); dx = x2 - cx; dy = y2 - cy; - x2 = dx * transform->e11 + dy * transform->e12 + transform->e13 + cx; - y2 = dx * transform->e21 + dy * transform->e22 + transform->e23 + cy; + x2 = dx * transform->e11 + dy * transform->e12 + transform->e13 + (cx * sx); + y2 = dx * transform->e21 + dy * transform->e22 + transform->e23 + (cy * sy); } fill->linear.dx = x2 - x1; @@ -116,7 +118,7 @@ bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix* tr fill->linear.dx /= fill->linear.len; fill->linear.dy /= fill->linear.len; - fill->linear.offset = -fill->linear.dx * x1 - fill->linear.dy * y1; + fill->linear.offset = -fill->linear.dx * x1 -fill->linear.dy * y1; return true; } @@ -158,20 +160,23 @@ bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix* tr } -static inline uint32_t _clamp(const SwFill* fill, uint32_t pos) +static inline uint32_t _clamp(const SwFill* fill, int32_t pos) { switch (fill->spread) { case FillSpread::Pad: { if (pos >= GRADIENT_STOP_SIZE) pos = GRADIENT_STOP_SIZE - 1; + else if (pos < 0) pos = 0; break; } case FillSpread::Repeat: { + if (pos < 0) pos = GRADIENT_STOP_SIZE + pos; pos = pos % GRADIENT_STOP_SIZE; break; } case FillSpread::Reflect: { auto limit = GRADIENT_STOP_SIZE * 2; pos = pos % limit; + if (pos < 0) pos = limit + pos; if (pos >= GRADIENT_STOP_SIZE) pos = (limit - pos - 1); break; } @@ -180,16 +185,16 @@ static inline uint32_t _clamp(const SwFill* fill, uint32_t pos) } -static inline uint32_t _fixedPixel(const SwFill* fill, uint32_t pos) +static inline uint32_t _fixedPixel(const SwFill* fill, int32_t pos) { - auto i = (pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS; + int32_t i = (pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS; return fill->ctable[_clamp(fill, i)]; } static inline uint32_t _pixel(const SwFill* fill, float pos) { - auto i = static_cast(pos * (GRADIENT_STOP_SIZE - 1) + 0.5f); + auto i = static_cast(pos * (GRADIENT_STOP_SIZE - 1) + 0.5f); return fill->ctable[_clamp(fill, i)]; } @@ -226,13 +231,13 @@ void fillFetchLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, if (fill->linear.len < FLT_EPSILON) return; //Rotation - auto rx = x + 0.5f; - auto ry = y + 0.5f; - auto t = (fill->linear.dx * rx + fill->linear.dy * ry + fill->linear.offset) * (GRADIENT_STOP_SIZE - 1); - auto inc = (fill->linear.dx) * (GRADIENT_STOP_SIZE - 1); + float rx = x + 0.5f; + float ry = y + 0.5f; + float t = (fill->linear.dx * rx + fill->linear.dy * ry + fill->linear.offset) * (GRADIENT_STOP_SIZE - 1); + float inc = (fill->linear.dx) * (GRADIENT_STOP_SIZE - 1); if (fabsf(inc) < FLT_EPSILON) { - auto color = _fixedPixel(fill, static_cast(t * FIXPT_SIZE)); + auto color = _fixedPixel(fill, static_cast(t * FIXPT_SIZE)); rasterARGB32(dst, color, offset, len); return; } -- 2.7.4 From 87a6b5219f4c61ce747f71a76845b0d641917299 Mon Sep 17 00:00:00 2001 From: Mateusz Palkowski Date: Mon, 27 Jul 2020 14:07:03 +0200 Subject: [PATCH 16/16] capi: Added wrapper for tvg::Shape::scale Change-Id: Ie8380478d9e5bf99c924f3b93cfbb3d80ff55611 --- inc/thorvg_capi.h | 1 + src/bindings/capi/tvgCapi.cpp | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/inc/thorvg_capi.h b/inc/thorvg_capi.h index 7c92184..d7f98ec 100644 --- a/inc/thorvg_capi.h +++ b/inc/thorvg_capi.h @@ -140,6 +140,7 @@ TVG_EXPORT Tvg_Result tvg_shape_set_stroke_dash(Tvg_Paint* paint, const float* d 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); +TVG_EXPORT Tvg_Result tvg_shape_scale(Tvg_Paint* paint, float factor); #ifdef __cplusplus } diff --git a/src/bindings/capi/tvgCapi.cpp b/src/bindings/capi/tvgCapi.cpp index 6ba0e6d..2e4e866 100644 --- a/src/bindings/capi/tvgCapi.cpp +++ b/src/bindings/capi/tvgCapi.cpp @@ -226,6 +226,11 @@ TVG_EXPORT Tvg_Result tvg_shape_fill_color(Tvg_Paint* paint, uint8_t r, uint8_t return (Tvg_Result) reinterpret_cast(paint)->fill(r, g, b, a); } +TVG_EXPORT Tvg_Result tvg_shape_scale(Tvg_Paint* paint, float factor) +{ + return (Tvg_Result) reinterpret_cast(paint)->scale(factor); +} + #ifdef __cplusplus } #endif \ No newline at end of file -- 2.7.4