svg_loader: mask-type attribute introduced 14/288814/1
authorMira Grudzinska <m.grudzinska@samsung.com>
Sun, 2 Jan 2022 01:23:11 +0000 (02:23 +0100)
committerMichal Szczecinski <mihashco89@gmail.com>
Thu, 23 Feb 2023 09:04:18 +0000 (10:04 +0100)
In an svg file the mask-type attribute can be specified.
It takes one of the two values: Luminosity or Alpha.
After the LumaMask is introduced into TVG, this attribute can be
properly read by the svg loader.

Change-Id: I8de1c94aed6bc0e7b31c1026b57f3336f29c2e30

src/loaders/svg/tvgSvgLoader.cpp
src/loaders/svg/tvgSvgLoaderCommon.h
src/loaders/svg/tvgSvgSceneBuilder.cpp

index 5a9eae2..aef549e 100644 (file)
@@ -199,6 +199,14 @@ static int _toOpacity(const char* str)
 }
 
 
+static SvgMaskType _toMaskType(const char* str)
+{
+    if (!strcmp(str, "Alpha")) return SvgMaskType::Alpha;
+
+    return SvgMaskType::Luminance;
+}
+
+
 #define _PARSE_TAG(Type, Name, Name1, Tags_Array, Default)                        \
     static Type _to##Name1(const char* str)                                       \
     {                                                                             \
@@ -921,6 +929,12 @@ static void _handleMaskAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, con
 }
 
 
+static void _handleMaskTypeAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value)
+{
+    node->node.mask.type = _toMaskType(value);
+}
+
+
 static void _handleDisplayAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value)
 {
     //TODO : The display attribute can have various values as well as "none".
@@ -958,6 +972,7 @@ static constexpr struct
     STYLE_DEF(transform, Transform, SvgStyleFlags::Transform),
     STYLE_DEF(clip-path, ClipPath, SvgStyleFlags::ClipPath),
     STYLE_DEF(mask, Mask, SvgStyleFlags::Mask),
+    STYLE_DEF(mask-type, MaskType, SvgStyleFlags::MaskType),
     STYLE_DEF(display, Display, SvgStyleFlags::Display)
 };
 
@@ -1062,6 +1077,8 @@ static bool _attrParseMaskNode(void* data, const char* key, const char* value)
         node->id = _copyId(value);
     } else if (!strcmp(key, "maskContentUnits")) {
         if (!strcmp(value, "objectBoundingBox")) mask->userSpace = false;
+    } else if (!strcmp(key, "mask-type")) {
+        mask->type = _toMaskType(value);
     } else {
         return _parseStyleAttr(loader, key, value, false);
     }
@@ -1172,6 +1189,7 @@ static SvgNode* _createMaskNode(SvgLoaderData* loader, SvgNode* parent, TVG_UNUS
     if (!loader->svgParse->node) return nullptr;
 
     loader->svgParse->node->node.mask.userSpace = true;
+    loader->svgParse->node->node.mask.type = SvgMaskType::Luminance;
 
     simpleXmlParseAttributes(buf, bufLength, _attrParseMaskNode, loader);
 
index 585e4e1..bf94beb 100644 (file)
@@ -111,7 +111,8 @@ enum class SvgStyleFlags
     Transform = 0x800,
     ClipPath = 0x1000,
     Mask = 0x2000,
-    Display = 0x4000
+    MaskType = 0x4000,
+    Display = 0x8000
 };
 
 enum class SvgStopStyleFlags
@@ -127,6 +128,12 @@ enum class SvgFillRule
     OddEven = 1
 };
 
+enum class SvgMaskType
+{
+    Luminance = 0,
+    Alpha
+};
+
 //Length type to recalculate %, pt, pc, mm, cm etc
 enum class SvgParserLengthType
 {
@@ -222,6 +229,7 @@ struct SvgClipNode
 
 struct SvgMaskNode
 {
+    SvgMaskType type;
     bool userSpace;
 };
 
index 8701fe3..b6b581a 100644 (file)
@@ -275,7 +275,7 @@ static void _applyComposition(Paint* paint, const SvgNode* node, const Box& vBox
        Composition can be applied recursively if its children nodes have composition target to this one. */
     if (node->style->mask.applying) {
         TVGLOG("SVG", "Multiple Composition Tried! Check out Circular dependency?");
-    } else  {
+    } else {
         auto compNode = node->style->mask.node;
         if (compNode && compNode->child.count > 0) {
             node->style->mask.applying = true;
@@ -283,7 +283,12 @@ static void _applyComposition(Paint* paint, const SvgNode* node, const Box& vBox
             auto comp = _sceneBuildHelper(compNode, vBox, svgPath, true);
             if (comp) {
                 if (node->transform) comp->transform(*node->transform);
-                paint->composite(move(comp), CompositeMethod::AlphaMask);
+
+                if (compNode->node.mask.type == SvgMaskType::Luminance) {
+                    paint->composite(move(comp), CompositeMethod::LumaMask);
+                } else {
+                    paint->composite(move(comp), CompositeMethod::AlphaMask);
+                }
             }
 
             node->style->mask.applying = false;