mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-15 12:34:30 +00:00
svg_loader: paint-order attrib handled
@Issue: https://github.com/thorvg/thorvg/issues/1340
This commit is contained in:
parent
69a9583354
commit
219e23855f
3 changed files with 52 additions and 2 deletions
|
@ -252,6 +252,36 @@ static SvgMaskType _toMaskType(const char* str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//The default rendering order: fill, stroke, markers
|
||||||
|
//If any is omitted, will be rendered in its default order after the specified ones.
|
||||||
|
static bool _toPaintOrder(const char* str)
|
||||||
|
{
|
||||||
|
uint8_t position = 1;
|
||||||
|
uint8_t strokePosition = 0;
|
||||||
|
uint8_t fillPosition = 0;
|
||||||
|
|
||||||
|
while (*str != '\0') {
|
||||||
|
str = _skipSpace(str, nullptr);
|
||||||
|
if (!strncmp(str, "fill", 4)) {
|
||||||
|
fillPosition = position++;
|
||||||
|
str += 4;
|
||||||
|
} else if (!strncmp(str, "stroke", 6)) {
|
||||||
|
strokePosition = position++;
|
||||||
|
str += 6;
|
||||||
|
} else if (!strncmp(str, "markers", 7)) {
|
||||||
|
str += 7;
|
||||||
|
} else {
|
||||||
|
return _toPaintOrder("fill stroke");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fillPosition == 0) fillPosition = position++;
|
||||||
|
if (strokePosition == 0) strokePosition = position++;
|
||||||
|
|
||||||
|
return fillPosition < strokePosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#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) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -1011,6 +1041,13 @@ static void _handleDisplayAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void _handlePaintOrderAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value)
|
||||||
|
{
|
||||||
|
node->style->flags = (SvgStyleFlags)((int)node->style->flags | (int)SvgStyleFlags::PaintOrder);
|
||||||
|
node->style->paintOrder = _toPaintOrder(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void _handleCssClassAttr(SvgLoaderData* loader, SvgNode* node, const char* value)
|
static void _handleCssClassAttr(SvgLoaderData* loader, SvgNode* node, const char* value)
|
||||||
{
|
{
|
||||||
auto cssClass = &node->style->cssClass;
|
auto cssClass = &node->style->cssClass;
|
||||||
|
@ -1061,7 +1098,8 @@ static constexpr struct
|
||||||
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(mask-type, MaskType, SvgStyleFlags::MaskType),
|
||||||
STYLE_DEF(display, Display, SvgStyleFlags::Display)
|
STYLE_DEF(display, Display, SvgStyleFlags::Display),
|
||||||
|
STYLE_DEF(paint-order, PaintOrder, SvgStyleFlags::PaintOrder)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1263,6 +1301,8 @@ static SvgNode* _createNode(SvgNode* parent, SvgNodeType type)
|
||||||
node->style->stroke.join = StrokeJoin::Miter;
|
node->style->stroke.join = StrokeJoin::Miter;
|
||||||
node->style->stroke.scale = 1.0;
|
node->style->stroke.scale = 1.0;
|
||||||
|
|
||||||
|
node->style->paintOrder = _toPaintOrder("fill stroke");
|
||||||
|
|
||||||
//Default display is true("inline").
|
//Default display is true("inline").
|
||||||
node->display = true;
|
node->display = true;
|
||||||
|
|
||||||
|
@ -2688,6 +2728,9 @@ static void _styleInherit(SvgStyleProperty* child, const SvgStyleProperty* paren
|
||||||
child->color = parent->color;
|
child->color = parent->color;
|
||||||
child->curColorSet = parent->curColorSet;
|
child->curColorSet = parent->curColorSet;
|
||||||
}
|
}
|
||||||
|
if (!((int)child->flags & (int)SvgStyleFlags::PaintOrder)) {
|
||||||
|
child->paintOrder = parent->paintOrder;
|
||||||
|
}
|
||||||
//Fill
|
//Fill
|
||||||
if (!((int)child->fill.flags & (int)SvgFillFlags::Paint)) {
|
if (!((int)child->fill.flags & (int)SvgFillFlags::Paint)) {
|
||||||
child->fill.paint.color = parent->fill.paint.color;
|
child->fill.paint.color = parent->fill.paint.color;
|
||||||
|
@ -2746,6 +2789,9 @@ static void _styleCopy(SvgStyleProperty* to, const SvgStyleProperty* from)
|
||||||
to->color = from->color;
|
to->color = from->color;
|
||||||
to->curColorSet = true;
|
to->curColorSet = true;
|
||||||
}
|
}
|
||||||
|
if (((int)from->flags & (int)SvgStyleFlags::PaintOrder)) {
|
||||||
|
to->paintOrder = from->paintOrder;
|
||||||
|
}
|
||||||
//Fill
|
//Fill
|
||||||
to->fill.flags = (SvgFillFlags)((int)to->fill.flags | (int)from->fill.flags);
|
to->fill.flags = (SvgFillFlags)((int)to->fill.flags | (int)from->fill.flags);
|
||||||
if (((int)from->fill.flags & (int)SvgFillFlags::Paint)) {
|
if (((int)from->fill.flags & (int)SvgFillFlags::Paint)) {
|
||||||
|
|
|
@ -115,7 +115,8 @@ enum class SvgStyleFlags
|
||||||
ClipPath = 0x1000,
|
ClipPath = 0x1000,
|
||||||
Mask = 0x2000,
|
Mask = 0x2000,
|
||||||
MaskType = 0x4000,
|
MaskType = 0x4000,
|
||||||
Display = 0x8000
|
Display = 0x8000,
|
||||||
|
PaintOrder = 0x10000
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class SvgStopStyleFlags
|
enum class SvgStopStyleFlags
|
||||||
|
@ -411,6 +412,7 @@ struct SvgStyleProperty
|
||||||
SvgColor color;
|
SvgColor color;
|
||||||
bool curColorSet;
|
bool curColorSet;
|
||||||
char* cssClass;
|
char* cssClass;
|
||||||
|
bool paintOrder; //true if default (fill, stroke), false otherwise
|
||||||
SvgStyleFlags flags;
|
SvgStyleFlags flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -330,6 +330,8 @@ static void _applyProperty(SvgNode* node, Shape* vg, const Box& vBox, const stri
|
||||||
|
|
||||||
//Apply the fill rule
|
//Apply the fill rule
|
||||||
vg->fill((tvg::FillRule)style->fill.fillRule);
|
vg->fill((tvg::FillRule)style->fill.fillRule);
|
||||||
|
//Rendering order
|
||||||
|
vg->order(!style->paintOrder);
|
||||||
|
|
||||||
//Apply node opacity
|
//Apply node opacity
|
||||||
if (style->opacity < 255) vg->opacity(style->opacity);
|
if (style->opacity < 255) vg->opacity(style->opacity);
|
||||||
|
|
Loading…
Add table
Reference in a new issue