mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-13 19:44:28 +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) \
|
||||
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)
|
||||
{
|
||||
auto cssClass = &node->style->cssClass;
|
||||
|
@ -1061,7 +1098,8 @@ static constexpr struct
|
|||
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)
|
||||
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.scale = 1.0;
|
||||
|
||||
node->style->paintOrder = _toPaintOrder("fill stroke");
|
||||
|
||||
//Default display is true("inline").
|
||||
node->display = true;
|
||||
|
||||
|
@ -2688,6 +2728,9 @@ static void _styleInherit(SvgStyleProperty* child, const SvgStyleProperty* paren
|
|||
child->color = parent->color;
|
||||
child->curColorSet = parent->curColorSet;
|
||||
}
|
||||
if (!((int)child->flags & (int)SvgStyleFlags::PaintOrder)) {
|
||||
child->paintOrder = parent->paintOrder;
|
||||
}
|
||||
//Fill
|
||||
if (!((int)child->fill.flags & (int)SvgFillFlags::Paint)) {
|
||||
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->curColorSet = true;
|
||||
}
|
||||
if (((int)from->flags & (int)SvgStyleFlags::PaintOrder)) {
|
||||
to->paintOrder = from->paintOrder;
|
||||
}
|
||||
//Fill
|
||||
to->fill.flags = (SvgFillFlags)((int)to->fill.flags | (int)from->fill.flags);
|
||||
if (((int)from->fill.flags & (int)SvgFillFlags::Paint)) {
|
||||
|
|
|
@ -115,7 +115,8 @@ enum class SvgStyleFlags
|
|||
ClipPath = 0x1000,
|
||||
Mask = 0x2000,
|
||||
MaskType = 0x4000,
|
||||
Display = 0x8000
|
||||
Display = 0x8000,
|
||||
PaintOrder = 0x10000
|
||||
};
|
||||
|
||||
enum class SvgStopStyleFlags
|
||||
|
@ -411,6 +412,7 @@ struct SvgStyleProperty
|
|||
SvgColor color;
|
||||
bool curColorSet;
|
||||
char* cssClass;
|
||||
bool paintOrder; //true if default (fill, stroke), false otherwise
|
||||
SvgStyleFlags flags;
|
||||
};
|
||||
|
||||
|
|
|
@ -330,6 +330,8 @@ static void _applyProperty(SvgNode* node, Shape* vg, const Box& vBox, const stri
|
|||
|
||||
//Apply the fill rule
|
||||
vg->fill((tvg::FillRule)style->fill.fillRule);
|
||||
//Rendering order
|
||||
vg->order(!style->paintOrder);
|
||||
|
||||
//Apply node opacity
|
||||
if (style->opacity < 255) vg->opacity(style->opacity);
|
||||
|
|
Loading…
Add table
Reference in a new issue