svg_loader: paint-order attrib handled

@Issue: https://github.com/thorvg/thorvg/issues/1340
This commit is contained in:
Mira Grudzinska 2023-04-16 12:22:18 +02:00 committed by Hermet Park
parent 69a9583354
commit 219e23855f
3 changed files with 52 additions and 2 deletions

View file

@ -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)) {

View file

@ -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;
};

View file

@ -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);