mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +00:00
svg_loader: allow both clipPath and mask together (#622)
* svg_loader: allow both clipPath and mask together * svg_loader: allow both clipPath and mask together fix #1 Changed seperate functions _applyClipPathComposition and _applyMaskComposition into single function _applyComposition
This commit is contained in:
parent
02b3d7dd20
commit
c2ec997db5
3 changed files with 65 additions and 42 deletions
|
@ -873,15 +873,10 @@ static void _handleTransformAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node
|
|||
static void _handleClipPathAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value)
|
||||
{
|
||||
SvgStyleProperty* style = node->style;
|
||||
#ifdef THORVG_LOG_ENABLED
|
||||
if (style->comp.method != CompositeMethod::None) printf("SVG: Multiple Composition Tried!\n");
|
||||
#endif
|
||||
style->comp.method = CompositeMethod::ClipPath;
|
||||
int len = strlen(value);
|
||||
if (len >= 3 && !strncmp(value, "url", 3)) {
|
||||
//FIXME: Support multiple composition.
|
||||
if (style->comp.url) delete(style->comp.url);
|
||||
style->comp.url = _idFromUrl((const char*)(value + 3));
|
||||
if (style->clipPath.url) delete(style->clipPath.url);
|
||||
style->clipPath.url = _idFromUrl((const char*)(value + 3));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -889,15 +884,10 @@ static void _handleClipPathAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node,
|
|||
static void _handleMaskAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value)
|
||||
{
|
||||
SvgStyleProperty* style = node->style;
|
||||
#ifdef THORVG_LOG_ENABLED
|
||||
if (style->comp.method != CompositeMethod::None) printf("SVG: Multiple Composition Tried!\n");
|
||||
#endif
|
||||
style->comp.method = CompositeMethod::AlphaMask;
|
||||
int len = strlen(value);
|
||||
if (len >= 3 && !strncmp(value, "url", 3)) {
|
||||
//FIXME: Support multiple composition.
|
||||
if (style->comp.url) delete(style->comp.url);
|
||||
style->comp.url = _idFromUrl((const char*)(value + 3));
|
||||
if (style->mask.url) delete(style->mask.url);
|
||||
style->mask.url = _idFromUrl((const char*)(value + 3));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1707,7 +1697,8 @@ static void _copyAttr(SvgNode* to, const SvgNode* from)
|
|||
*to->style = *from->style;
|
||||
if (from->style->fill.paint.url) to->style->fill.paint.url = new string(from->style->fill.paint.url->c_str());
|
||||
if (from->style->stroke.paint.url) to->style->stroke.paint.url = new string(from->style->stroke.paint.url->c_str());
|
||||
if (from->style->comp.url) to->style->comp.url = new string(from->style->comp.url->c_str());
|
||||
if (from->style->clipPath.url) to->style->clipPath.url = new string(from->style->clipPath.url->c_str());
|
||||
if (from->style->mask.url) to->style->mask.url = new string(from->style->mask.url->c_str());
|
||||
|
||||
//Copy node attribute
|
||||
switch (from->type) {
|
||||
|
@ -2598,9 +2589,13 @@ static void _updateGradient(SvgNode* node, Array<SvgStyleGradient*>* gradients)
|
|||
|
||||
static void _updateComposite(SvgNode* node, SvgNode* root)
|
||||
{
|
||||
if (node->style->comp.url && !node->style->comp.node) {
|
||||
SvgNode *findResult = _findNodeById(root, node->style->comp.url);
|
||||
if (findResult) node->style->comp.node = findResult;
|
||||
if (node->style->clipPath.url && !node->style->clipPath.node) {
|
||||
SvgNode *findResult = _findNodeById(root, node->style->clipPath.url);
|
||||
if (findResult) node->style->clipPath.node = findResult;
|
||||
}
|
||||
if (node->style->mask.url && !node->style->mask.node) {
|
||||
SvgNode *findResult = _findNodeById(root, node->style->mask.url);
|
||||
if (findResult) node->style->mask.node = findResult;
|
||||
}
|
||||
if (node->child.count > 0) {
|
||||
auto child = node->child.data;
|
||||
|
@ -2615,8 +2610,9 @@ static void _freeNodeStyle(SvgStyleProperty* style)
|
|||
{
|
||||
if (!style) return;
|
||||
|
||||
//style->comp.node has only the addresses of node. Therefore, style->comp.node is released from _freeNode.
|
||||
delete(style->comp.url);
|
||||
//style->clipPath.node and style->mask.node has only the addresses of node. Therefore, node is released from _freeNode.
|
||||
delete(style->clipPath.url);
|
||||
delete(style->mask.url);
|
||||
|
||||
if (style->fill.paint.gradient) delete(style->fill.paint.gradient);
|
||||
if (style->stroke.paint.gradient) delete(style->stroke.paint.gradient);
|
||||
|
|
|
@ -225,10 +225,9 @@ struct SvgRadialGradient
|
|||
|
||||
struct SvgComposite
|
||||
{
|
||||
CompositeMethod method; //TODO: Currently support either one method
|
||||
string *url;
|
||||
SvgNode* node;
|
||||
bool applying; //flag for checking circualr dependency.
|
||||
bool applying; //flag for checking circular dependency.
|
||||
};
|
||||
|
||||
struct SvgColor
|
||||
|
@ -302,7 +301,8 @@ struct SvgStyleProperty
|
|||
{
|
||||
SvgStyleFill fill;
|
||||
SvgStyleStroke stroke;
|
||||
SvgComposite comp;
|
||||
SvgComposite clipPath;
|
||||
SvgComposite mask;
|
||||
int opacity;
|
||||
SvgColor color;
|
||||
bool curColorSet;
|
||||
|
|
|
@ -178,36 +178,63 @@ static bool _appendChildShape(SvgNode* node, Shape* shape, float vx, float vy, f
|
|||
|
||||
static void _applyComposition(Paint* paint, const SvgNode* node, float vx, float vy, float vw, float vh)
|
||||
{
|
||||
if (node->style->comp.method == CompositeMethod::None) return;
|
||||
|
||||
/* Do not drop in Circular Dependency.
|
||||
/* ClipPath */
|
||||
/* Do not drop in Circular Dependency for ClipPath.
|
||||
Composition can be applied recursively if its children nodes have composition target to this one. */
|
||||
if (node->style->comp.applying) {
|
||||
if (node->style->clipPath.applying) {
|
||||
#ifdef THORVG_LOG_ENABLED
|
||||
printf("SVG: Multiple Composition Tried! Check out Circular dependency?\n");
|
||||
#endif
|
||||
return;
|
||||
} else {
|
||||
auto compNode = node->style->clipPath.node;
|
||||
if (compNode && compNode->child.count > 0) {
|
||||
node->style->clipPath.applying = true;
|
||||
|
||||
auto comp = Shape::gen();
|
||||
comp->fill(255, 255, 255, 255);
|
||||
if (node->transform) comp->transform(*node->transform);
|
||||
|
||||
auto child = compNode->child.data;
|
||||
auto valid = false; //Composite only when valid shapes are existed
|
||||
|
||||
for (uint32_t i = 0; i < compNode->child.count; ++i, ++child) {
|
||||
if (_appendChildShape(*child, comp.get(), vx, vy, vw, vh)) valid = true;
|
||||
}
|
||||
|
||||
if (valid) paint->composite(move(comp), CompositeMethod::ClipPath);
|
||||
|
||||
node->style->clipPath.applying = false;
|
||||
}
|
||||
}
|
||||
|
||||
auto compNode = node->style->comp.node;
|
||||
if (!compNode || compNode->child.count == 0) return;
|
||||
/* Mask */
|
||||
/* Do not drop in Circular Dependency for Mask.
|
||||
Composition can be applied recursively if its children nodes have composition target to this one. */
|
||||
if (node->style->mask.applying) {
|
||||
#ifdef THORVG_LOG_ENABLED
|
||||
printf("SVG: Multiple Composition Tried! Check out Circular dependency?\n");
|
||||
#endif
|
||||
} else {
|
||||
auto compNode = node->style->mask.node;
|
||||
if (compNode && compNode->child.count > 0) {
|
||||
node->style->mask.applying = true;
|
||||
|
||||
node->style->comp.applying = true;
|
||||
auto comp = Shape::gen();
|
||||
comp->fill(255, 255, 255, 255);
|
||||
if (node->transform) comp->transform(*node->transform);
|
||||
|
||||
auto comp = Shape::gen();
|
||||
comp->fill(255, 255, 255, 255);
|
||||
if (node->transform) comp->transform(*node->transform);
|
||||
auto child = compNode->child.data;
|
||||
auto valid = false; //Composite only when valid shapes are existed
|
||||
|
||||
auto child = compNode->child.data;
|
||||
auto valid = false; //Composite only when valid shapes are existed
|
||||
for (uint32_t i = 0; i < compNode->child.count; ++i, ++child) {
|
||||
if (_appendChildShape(*child, comp.get(), vx, vy, vw, vh)) valid = true;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < compNode->child.count; ++i, ++child) {
|
||||
if (_appendChildShape(*child, comp.get(), vx, vy, vw, vh)) valid = true;
|
||||
if (valid) paint->composite(move(comp), CompositeMethod::AlphaMask);
|
||||
|
||||
node->style->mask.applying = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (valid) paint->composite(move(comp), node->style->comp.method);
|
||||
|
||||
node->style->comp.applying = false;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue