svg_loader: a function to establish shapes boundries without a stroke introduced
authorMira Grudzinska <m.grudzinska@samsung.com>
Wed, 24 Nov 2021 22:07:35 +0000 (23:07 +0100)
committerHermet Park <chuneon.park@samsung.com>
Tue, 30 Nov 2021 03:48:18 +0000 (12:48 +0900)
To handle the objectBoundingBox units, the shape's boundaries have to be known.
According to the SVG standard, a stroke shouldn't be taken into account. Since
the bounds() api uses the shape's stroke information, a new function is introduced,
that compensates this and returns boundaries without any strokes.

src/loaders/svg/tvgSvgSceneBuilder.cpp

index c37bcb0..8701fe3 100644 (file)
@@ -77,6 +77,24 @@ static inline bool _isGroupType(SvgNodeType type)
 }
 
 
+//According to: https://www.w3.org/TR/SVG11/coords.html#ObjectBoundingBoxUnits (the last paragraph)
+//a stroke width should be ignored for bounding box calculations
+static Box _boundingBox(const Shape* shape)
+{
+    float x, y, w, h;
+    shape->bounds(&x, &y, &w, &h, false);
+
+    if (auto strokeW = shape->strokeWidth()) {
+        x += 0.5f * strokeW;
+        y += 0.5f * strokeW;
+        w -= strokeW;
+        h -= strokeW;
+    }
+
+    return {x, y, w, h};
+}
+
+
 static void _transformMultiply(const Matrix* mBBox, Matrix* gradTransf)
 {
     gradTransf->e13 = gradTransf->e13 * mBBox->e11 + mBBox->e13;
@@ -286,17 +304,7 @@ static void _applyProperty(SvgNode* node, Shape* vg, const Box& vBox, const stri
         //Do nothing
     } else if (style->fill.paint.gradient) {
         Box bBox = vBox;
-        if (!style->fill.paint.gradient->userSpace) {
-            vg->bounds(&bBox.x, &bBox.y, &bBox.w, &bBox.h, false);
-            //According to: https://www.w3.org/TR/SVG11/coords.html#ObjectBoundingBoxUnits (the last paragraph)
-            //a stroke width should be ignored for bounding box calculations
-            if (auto strokeW = vg->strokeWidth()) {
-                bBox.x += 0.5f * strokeW;
-                bBox.y += 0.5f * strokeW;
-                bBox.w -= strokeW;
-                bBox.h -= strokeW;
-            }
-        }
+        if (!style->fill.paint.gradient->userSpace) bBox = _boundingBox(vg);
 
         if (style->fill.paint.gradient->type == SvgGradientType::Linear) {
              auto linear = _applyLinearGradientProperty(style->fill.paint.gradient, vg, bBox, style->fill.opacity);
@@ -336,17 +344,7 @@ static void _applyProperty(SvgNode* node, Shape* vg, const Box& vBox, const stri
         //Do nothing
     } else if (style->stroke.paint.gradient) {
         Box bBox = vBox;
-        if (!style->stroke.paint.gradient->userSpace) {
-            //According to: https://www.w3.org/TR/SVG11/coords.html#ObjectBoundingBoxUnits (the last paragraph)
-            //a stroke width should be ignored for bounding box calculations
-            vg->bounds(&bBox.x, &bBox.y, &bBox.w, &bBox.h, false);
-            if (auto strokeW = vg->strokeWidth()) {
-                bBox.x += 0.5f * strokeW;
-                bBox.y += 0.5f * strokeW;
-                bBox.w -= strokeW;
-                bBox.h -= strokeW;
-            }
-        }
+        if (!style->stroke.paint.gradient->userSpace) bBox = _boundingBox(vg);
 
         if (style->stroke.paint.gradient->type == SvgGradientType::Linear) {
              auto linear = _applyLinearGradientProperty(style->stroke.paint.gradient, vg, bBox, style->stroke.opacity);