svg_loader: mask-type attribute introduced

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.
This commit is contained in:
Mira Grudzinska 2022-01-02 02:23:11 +01:00 committed by Hermet Park
parent 1f5b66c256
commit 2f7e7e9923
3 changed files with 34 additions and 3 deletions

View 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) \ #define _PARSE_TAG(Type, Name, Name1, Tags_Array, Default) \
static Type _to##Name1(const char* str) \ 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) static void _handleDisplayAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value)
{ {
//TODO : The display attribute can have various values as well as "none". //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(transform, Transform, SvgStyleFlags::Transform),
STYLE_DEF(clip-path, ClipPath, SvgStyleFlags::ClipPath), STYLE_DEF(clip-path, ClipPath, SvgStyleFlags::ClipPath),
STYLE_DEF(mask, Mask, SvgStyleFlags::Mask), STYLE_DEF(mask, Mask, SvgStyleFlags::Mask),
STYLE_DEF(mask-type, MaskType, SvgStyleFlags::MaskType),
STYLE_DEF(display, Display, SvgStyleFlags::Display) 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); node->id = _copyId(value);
} else if (!strcmp(key, "maskContentUnits")) { } else if (!strcmp(key, "maskContentUnits")) {
if (!strcmp(value, "objectBoundingBox")) mask->userSpace = false; if (!strcmp(value, "objectBoundingBox")) mask->userSpace = false;
} else if (!strcmp(key, "mask-type")) {
mask->type = _toMaskType(value);
} else { } else {
return _parseStyleAttr(loader, key, value, false); 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; if (!loader->svgParse->node) return nullptr;
loader->svgParse->node->node.mask.userSpace = true; loader->svgParse->node->node.mask.userSpace = true;
loader->svgParse->node->node.mask.type = SvgMaskType::Luminance;
simpleXmlParseAttributes(buf, bufLength, _attrParseMaskNode, loader); simpleXmlParseAttributes(buf, bufLength, _attrParseMaskNode, loader);

View file

@ -111,7 +111,8 @@ enum class SvgStyleFlags
Transform = 0x800, Transform = 0x800,
ClipPath = 0x1000, ClipPath = 0x1000,
Mask = 0x2000, Mask = 0x2000,
Display = 0x4000 MaskType = 0x4000,
Display = 0x8000
}; };
enum class SvgStopStyleFlags enum class SvgStopStyleFlags
@ -127,6 +128,12 @@ enum class SvgFillRule
OddEven = 1 OddEven = 1
}; };
enum class SvgMaskType
{
Luminance = 0,
Alpha
};
//Length type to recalculate %, pt, pc, mm, cm etc //Length type to recalculate %, pt, pc, mm, cm etc
enum class SvgParserLengthType enum class SvgParserLengthType
{ {
@ -222,6 +229,7 @@ struct SvgClipNode
struct SvgMaskNode struct SvgMaskNode
{ {
SvgMaskType type;
bool userSpace; bool userSpace;
}; };

View 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. */ Composition can be applied recursively if its children nodes have composition target to this one. */
if (node->style->mask.applying) { if (node->style->mask.applying) {
TVGLOG("SVG", "Multiple Composition Tried! Check out Circular dependency?"); TVGLOG("SVG", "Multiple Composition Tried! Check out Circular dependency?");
} else { } else {
auto compNode = node->style->mask.node; auto compNode = node->style->mask.node;
if (compNode && compNode->child.count > 0) { if (compNode && compNode->child.count > 0) {
node->style->mask.applying = true; 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); auto comp = _sceneBuildHelper(compNode, vBox, svgPath, true);
if (comp) { if (comp) {
if (node->transform) comp->transform(*node->transform); 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; node->style->mask.applying = false;