From 1b48bf10fe01e2026296c3eef6fe82e471889e56 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Thu, 9 Jul 2020 20:12:48 +0900 Subject: [PATCH 01/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 02/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 03/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 04/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 05/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 06/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 07/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 08/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 09/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 10/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 11/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 12/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 13/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 14/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 15/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 16/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