mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 05:33:36 +00:00
svg_loader: gradient inheritance implemented
Till now only the grad stops were inherited. Now all grad attribs are. Inheritance from different grad type is not supported. @Issue: https://github.com/thorvg/thorvg/issues/1209
This commit is contained in:
parent
66ef84e7d7
commit
598c28a597
2 changed files with 270 additions and 22 deletions
|
@ -1891,6 +1891,7 @@ static constexpr struct
|
|||
{"height", SvgParserLengthType::Vertical, sizeof("height"), offsetof(SvgUseNode, h)}
|
||||
};
|
||||
|
||||
|
||||
static void _cloneNode(SvgNode* from, SvgNode* parent, int depth);
|
||||
static bool _attrParseUseNode(void* data, const char* key, const char* value)
|
||||
{
|
||||
|
@ -2086,13 +2087,99 @@ static void _recalcRadialRAttr(SvgLoaderData* loader, SvgRadialGradient* radial,
|
|||
}
|
||||
|
||||
|
||||
static void _recalcInheritedRadialCxAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace)
|
||||
{
|
||||
if (!radial->isCxPercentage) {
|
||||
if (userSpace) radial->cx /= loader->svgParse->global.w;
|
||||
else radial->cx *= loader->svgParse->global.w;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void _recalcInheritedRadialCyAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace)
|
||||
{
|
||||
if (!radial->isCyPercentage) {
|
||||
if (userSpace) radial->cy /= loader->svgParse->global.h;
|
||||
else radial->cy *= loader->svgParse->global.h;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void _recalcInheritedRadialFxAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace)
|
||||
{
|
||||
if (!radial->isFxPercentage) {
|
||||
if (userSpace) radial->fx /= loader->svgParse->global.w;
|
||||
else radial->fx *= loader->svgParse->global.w;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void _recalcInheritedRadialFyAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace)
|
||||
{
|
||||
if (!radial->isFyPercentage) {
|
||||
if (userSpace) radial->fy /= loader->svgParse->global.h;
|
||||
else radial->fy *= loader->svgParse->global.h;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void _recalcInheritedRadialRAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace)
|
||||
{
|
||||
if (!radial->isRPercentage) {
|
||||
if (userSpace) radial->r /= sqrtf(powf(loader->svgParse->global.h, 2) + powf(loader->svgParse->global.w, 2)) / sqrtf(2.0);
|
||||
else radial->r *= sqrtf(powf(loader->svgParse->global.h, 2) + powf(loader->svgParse->global.w, 2)) / sqrtf(2.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void _inheritRadialCxAttr(SvgStyleGradient* to, SvgStyleGradient* from)
|
||||
{
|
||||
to->radial->cx = from->radial->cx;
|
||||
to->radial->isCxPercentage = from->radial->isCxPercentage;
|
||||
to->flags = (SvgGradientFlags)((int)to->flags | (int)SvgGradientFlags::Cx);
|
||||
}
|
||||
|
||||
|
||||
static void _inheritRadialCyAttr(SvgStyleGradient* to, SvgStyleGradient* from)
|
||||
{
|
||||
to->radial->cy = from->radial->cy;
|
||||
to->radial->isCyPercentage = from->radial->isCyPercentage;
|
||||
to->flags = (SvgGradientFlags)((int)to->flags | (int)SvgGradientFlags::Cy);
|
||||
}
|
||||
|
||||
|
||||
static void _inheritRadialFxAttr(SvgStyleGradient* to, SvgStyleGradient* from)
|
||||
{
|
||||
to->radial->fx = from->radial->fx;
|
||||
to->radial->isFxPercentage = from->radial->isFxPercentage;
|
||||
to->flags = (SvgGradientFlags)((int)to->flags | (int)SvgGradientFlags::Fx);
|
||||
}
|
||||
|
||||
|
||||
static void _inheritRadialFyAttr(SvgStyleGradient* to, SvgStyleGradient* from)
|
||||
{
|
||||
to->radial->fy = from->radial->fy;
|
||||
to->radial->isFyPercentage = from->radial->isFyPercentage;
|
||||
to->flags = (SvgGradientFlags)((int)to->flags | (int)SvgGradientFlags::Fy);
|
||||
}
|
||||
|
||||
|
||||
static void _inheritRadialRAttr(SvgStyleGradient* to, SvgStyleGradient* from)
|
||||
{
|
||||
to->radial->r = from->radial->r;
|
||||
to->radial->isRPercentage = from->radial->isRPercentage;
|
||||
to->flags = (SvgGradientFlags)((int)to->flags | (int)SvgGradientFlags::R);
|
||||
}
|
||||
|
||||
|
||||
typedef void (*radialMethod)(SvgLoaderData* loader, SvgRadialGradient* radial, const char* value);
|
||||
typedef void (*radialInheritMethod)(SvgStyleGradient* to, SvgStyleGradient* from);
|
||||
typedef void (*radialMethodRecalc)(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace);
|
||||
|
||||
|
||||
#define RADIAL_DEF(Name, Name1) \
|
||||
#define RADIAL_DEF(Name, Name1, Flag) \
|
||||
{ \
|
||||
#Name, sizeof(#Name), _handleRadial##Name1##Attr, _recalcRadial##Name1##Attr \
|
||||
#Name, sizeof(#Name), _handleRadial##Name1##Attr, _inheritRadial##Name1##Attr, _recalcRadial##Name1##Attr, _recalcInheritedRadial##Name1##Attr, Flag \
|
||||
}
|
||||
|
||||
|
||||
|
@ -2101,13 +2188,16 @@ static constexpr struct
|
|||
const char* tag;
|
||||
int sz;
|
||||
radialMethod tagHandler;
|
||||
radialInheritMethod tagInheritHandler;
|
||||
radialMethodRecalc tagRecalc;
|
||||
radialMethodRecalc tagInheritedRecalc;
|
||||
SvgGradientFlags flag;
|
||||
} radialTags[] = {
|
||||
RADIAL_DEF(cx, Cx),
|
||||
RADIAL_DEF(cy, Cy),
|
||||
RADIAL_DEF(fx, Fx),
|
||||
RADIAL_DEF(fy, Fy),
|
||||
RADIAL_DEF(r, R)
|
||||
RADIAL_DEF(cx, Cx, SvgGradientFlags::Cx),
|
||||
RADIAL_DEF(cy, Cy, SvgGradientFlags::Cy),
|
||||
RADIAL_DEF(fx, Fx, SvgGradientFlags::Fx),
|
||||
RADIAL_DEF(fy, Fy, SvgGradientFlags::Fy),
|
||||
RADIAL_DEF(r, R, SvgGradientFlags::R)
|
||||
};
|
||||
|
||||
|
||||
|
@ -2121,6 +2211,7 @@ static bool _attrParseRadialGradientNode(void* data, const char* key, const char
|
|||
for (unsigned int i = 0; i < sizeof(radialTags) / sizeof(radialTags[0]); i++) {
|
||||
if (radialTags[i].sz - 1 == sz && !strncmp(radialTags[i].tag, key, sz)) {
|
||||
radialTags[i].tagHandler(loader, radial, value);
|
||||
grad->flags = (SvgGradientFlags)((int)grad->flags | (int)radialTags[i].flag);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -2130,11 +2221,13 @@ static bool _attrParseRadialGradientNode(void* data, const char* key, const char
|
|||
grad->id = _copyId(value);
|
||||
} else if (!strcmp(key, "spreadMethod")) {
|
||||
grad->spread = _parseSpreadValue(value);
|
||||
grad->flags = (SvgGradientFlags)((int)grad->flags | (int)SvgGradientFlags::SpreadMethod);
|
||||
} else if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) {
|
||||
if (grad->ref && value) free(grad->ref);
|
||||
grad->ref = _idFromHref(value);
|
||||
} else if (!strcmp(key, "gradientUnits")) {
|
||||
if (!strcmp(value, "userSpaceOnUse")) grad->userSpace = true;
|
||||
grad->flags = (SvgGradientFlags)((int)grad->flags | (int)SvgGradientFlags::GradientUnits);
|
||||
} else if (!strcmp(key, "gradientTransform")) {
|
||||
grad->transform = _parseTransformationMatrix(value);
|
||||
} else {
|
||||
|
@ -2150,6 +2243,7 @@ static SvgStyleGradient* _createRadialGradient(SvgLoaderData* loader, const char
|
|||
auto grad = (SvgStyleGradient*)(calloc(1, sizeof(SvgStyleGradient)));
|
||||
loader->svgParse->styleGrad = grad;
|
||||
|
||||
grad->flags = SvgGradientFlags::None;
|
||||
grad->type = SvgGradientType::Radial;
|
||||
grad->userSpace = false;
|
||||
grad->radial = (SvgRadialGradient*)calloc(1, sizeof(SvgRadialGradient));
|
||||
|
@ -2277,13 +2371,82 @@ static void _recalcLinearY2Attr(SvgLoaderData* loader, SvgLinearGradient* linear
|
|||
}
|
||||
|
||||
|
||||
static void _recalcInheritedLinearX1Attr(SvgLoaderData* loader, SvgLinearGradient* linear, bool userSpace)
|
||||
{
|
||||
if (!linear->isX1Percentage) {
|
||||
if (userSpace) linear->x1 /= loader->svgParse->global.w;
|
||||
else linear->x1 *= loader->svgParse->global.w;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void _recalcInheritedLinearX2Attr(SvgLoaderData* loader, SvgLinearGradient* linear, bool userSpace)
|
||||
{
|
||||
if (!linear->isX2Percentage) {
|
||||
if (userSpace) linear->x2 /= loader->svgParse->global.w;
|
||||
else linear->x2 *= loader->svgParse->global.w;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void _recalcInheritedLinearY1Attr(SvgLoaderData* loader, SvgLinearGradient* linear, bool userSpace)
|
||||
{
|
||||
if (!linear->isY1Percentage) {
|
||||
if (userSpace) linear->y1 /= loader->svgParse->global.h;
|
||||
else linear->y1 *= loader->svgParse->global.h;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void _recalcInheritedLinearY2Attr(SvgLoaderData* loader, SvgLinearGradient* linear, bool userSpace)
|
||||
{
|
||||
if (!linear->isY2Percentage) {
|
||||
if (userSpace) linear->y2 /= loader->svgParse->global.h;
|
||||
else linear->y2 *= loader->svgParse->global.h;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void _inheritLinearX1Attr(SvgStyleGradient* to, SvgStyleGradient* from)
|
||||
{
|
||||
to->linear->x1 = from->linear->x1;
|
||||
to->linear->isX1Percentage = from->linear->isX1Percentage;
|
||||
to->flags = (SvgGradientFlags)((int)to->flags | (int)SvgGradientFlags::X1);
|
||||
}
|
||||
|
||||
|
||||
static void _inheritLinearX2Attr(SvgStyleGradient* to, SvgStyleGradient* from)
|
||||
{
|
||||
to->linear->x2 = from->linear->x2;
|
||||
to->linear->isX2Percentage = from->linear->isX2Percentage;
|
||||
to->flags = (SvgGradientFlags)((int)to->flags | (int)SvgGradientFlags::X2);
|
||||
}
|
||||
|
||||
|
||||
static void _inheritLinearY1Attr(SvgStyleGradient* to, SvgStyleGradient* from)
|
||||
{
|
||||
to->linear->y1 = from->linear->y1;
|
||||
to->linear->isY1Percentage = from->linear->isY1Percentage;
|
||||
to->flags = (SvgGradientFlags)((int)to->flags | (int)SvgGradientFlags::Y1);
|
||||
}
|
||||
|
||||
|
||||
static void _inheritLinearY2Attr(SvgStyleGradient* to, SvgStyleGradient* from)
|
||||
{
|
||||
to->linear->y2 = from->linear->y2;
|
||||
to->linear->isY2Percentage = from->linear->isY2Percentage;
|
||||
to->flags = (SvgGradientFlags)((int)to->flags | (int)SvgGradientFlags::Y2);
|
||||
}
|
||||
|
||||
|
||||
typedef void (*Linear_Method)(SvgLoaderData* loader, SvgLinearGradient* linear, const char* value);
|
||||
typedef void (*Linear_Inherit_Method)(SvgStyleGradient* to, SvgStyleGradient* from);
|
||||
typedef void (*Linear_Method_Recalc)(SvgLoaderData* loader, SvgLinearGradient* linear, bool userSpace);
|
||||
|
||||
|
||||
#define LINEAR_DEF(Name, Name1) \
|
||||
#define LINEAR_DEF(Name, Name1, Flag) \
|
||||
{ \
|
||||
#Name, sizeof(#Name), _handleLinear##Name1##Attr, _recalcLinear##Name1##Attr \
|
||||
#Name, sizeof(#Name), _handleLinear##Name1##Attr, _inheritLinear##Name1##Attr, _recalcLinear##Name1##Attr, _recalcInheritedLinear##Name1##Attr, Flag \
|
||||
}
|
||||
|
||||
|
||||
|
@ -2292,12 +2455,15 @@ static constexpr struct
|
|||
const char* tag;
|
||||
int sz;
|
||||
Linear_Method tagHandler;
|
||||
Linear_Inherit_Method tagInheritHandler;
|
||||
Linear_Method_Recalc tagRecalc;
|
||||
Linear_Method_Recalc tagInheritedRecalc;
|
||||
SvgGradientFlags flag;
|
||||
} linear_tags[] = {
|
||||
LINEAR_DEF(x1, X1),
|
||||
LINEAR_DEF(y1, Y1),
|
||||
LINEAR_DEF(x2, X2),
|
||||
LINEAR_DEF(y2, Y2)
|
||||
LINEAR_DEF(x1, X1, SvgGradientFlags::X1),
|
||||
LINEAR_DEF(y1, Y1, SvgGradientFlags::Y1),
|
||||
LINEAR_DEF(x2, X2, SvgGradientFlags::X2),
|
||||
LINEAR_DEF(y2, Y2, SvgGradientFlags::Y2)
|
||||
};
|
||||
|
||||
|
||||
|
@ -2311,6 +2477,7 @@ static bool _attrParseLinearGradientNode(void* data, const char* key, const char
|
|||
for (unsigned int i = 0; i < sizeof(linear_tags) / sizeof(linear_tags[0]); i++) {
|
||||
if (linear_tags[i].sz - 1 == sz && !strncmp(linear_tags[i].tag, key, sz)) {
|
||||
linear_tags[i].tagHandler(loader, linear, value);
|
||||
grad->flags = (SvgGradientFlags)((int)grad->flags | (int)linear_tags[i].flag);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -2320,11 +2487,13 @@ static bool _attrParseLinearGradientNode(void* data, const char* key, const char
|
|||
grad->id = _copyId(value);
|
||||
} else if (!strcmp(key, "spreadMethod")) {
|
||||
grad->spread = _parseSpreadValue(value);
|
||||
grad->flags = (SvgGradientFlags)((int)grad->flags | (int)SvgGradientFlags::SpreadMethod);
|
||||
} else if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) {
|
||||
if (grad->ref && value) free(grad->ref);
|
||||
grad->ref = _idFromHref(value);
|
||||
} else if (!strcmp(key, "gradientUnits")) {
|
||||
if (!strcmp(value, "userSpaceOnUse")) grad->userSpace = true;
|
||||
grad->flags = (SvgGradientFlags)((int)grad->flags | (int)SvgGradientFlags::GradientUnits);
|
||||
} else if (!strcmp(key, "gradientTransform")) {
|
||||
grad->transform = _parseTransformationMatrix(value);
|
||||
} else {
|
||||
|
@ -2340,6 +2509,7 @@ static SvgStyleGradient* _createLinearGradient(SvgLoaderData* loader, const char
|
|||
auto grad = (SvgStyleGradient*)(calloc(1, sizeof(SvgStyleGradient)));
|
||||
loader->svgParse->styleGrad = grad;
|
||||
|
||||
grad->flags = SvgGradientFlags::None;
|
||||
grad->type = SvgGradientType::Linear;
|
||||
grad->userSpace = false;
|
||||
grad->linear = (SvgLinearGradient*)calloc(1, sizeof(SvgLinearGradient));
|
||||
|
@ -2407,6 +2577,67 @@ static void _cloneGradStops(Array<Fill::ColorStop>& dst, const Array<Fill::Color
|
|||
}
|
||||
|
||||
|
||||
static void _inheritGradient(SvgLoaderData* loader, SvgStyleGradient* to, SvgStyleGradient* from)
|
||||
{
|
||||
if (!to || !from) return;
|
||||
|
||||
if (!((int)to->flags & (int)SvgGradientFlags::SpreadMethod) &&
|
||||
((int)from->flags & (int)SvgGradientFlags::SpreadMethod)) {
|
||||
to->spread = from->spread;
|
||||
to->flags = (SvgGradientFlags)((int)to->flags | (int)SvgGradientFlags::SpreadMethod);
|
||||
}
|
||||
bool gradUnitSet = (int)to->flags & (int)SvgGradientFlags::GradientUnits;
|
||||
if (!((int)to->flags & (int)SvgGradientFlags::GradientUnits) &&
|
||||
((int)from->flags & (int)SvgGradientFlags::GradientUnits)) {
|
||||
to->userSpace = from->userSpace;
|
||||
to->flags = (SvgGradientFlags)((int)to->flags | (int)SvgGradientFlags::GradientUnits);
|
||||
}
|
||||
|
||||
if (!to->transform && from->transform) {
|
||||
to->transform = (Matrix*)malloc(sizeof(Matrix));
|
||||
if (to->transform) memcpy(to->transform, from->transform, sizeof(Matrix));
|
||||
}
|
||||
|
||||
if (to->type == SvgGradientType::Linear && from->type == SvgGradientType::Linear) {
|
||||
for (unsigned int i = 0; i < sizeof(linear_tags) / sizeof(linear_tags[0]); i++) {
|
||||
bool coordSet = (int)to->flags & (int)linear_tags[i].flag;
|
||||
if (!((int)to->flags & (int)linear_tags[i].flag) && ((int)from->flags & (int)linear_tags[i].flag)) {
|
||||
linear_tags[i].tagInheritHandler(to, from);
|
||||
}
|
||||
|
||||
//GradUnits not set directly, coord set
|
||||
if (!gradUnitSet && coordSet) {
|
||||
linear_tags[i].tagRecalc(loader, to->linear, to->userSpace);
|
||||
}
|
||||
//GradUnits set, coord not set directly
|
||||
if (to->userSpace == from->userSpace) continue;
|
||||
if (gradUnitSet && !coordSet) {
|
||||
linear_tags[i].tagInheritedRecalc(loader, to->linear, to->userSpace);
|
||||
}
|
||||
}
|
||||
} else if (to->type == SvgGradientType::Radial && from->type == SvgGradientType::Radial) {
|
||||
for (unsigned int i = 0; i < sizeof(radialTags) / sizeof(radialTags[0]); i++) {
|
||||
bool coordSet = (int)to->flags & (int)radialTags[i].flag;
|
||||
if (!((int)to->flags & (int)radialTags[i].flag) && ((int)from->flags & (int)radialTags[i].flag)) {
|
||||
radialTags[i].tagInheritHandler(to, from);
|
||||
}
|
||||
|
||||
//GradUnits not set directly, coord set
|
||||
if (!gradUnitSet && coordSet) {
|
||||
radialTags[i].tagRecalc(loader, to->radial, to->userSpace);
|
||||
}
|
||||
//GradUnits set, coord not set directly
|
||||
if (to->userSpace == from->userSpace) continue;
|
||||
if (gradUnitSet && !coordSet) {
|
||||
radialTags[i].tagInheritedRecalc(loader, to->radial, to->userSpace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (to->stops.count == 0) _cloneGradStops(to->stops, from->stops);
|
||||
}
|
||||
|
||||
|
||||
static SvgStyleGradient* _cloneGradient(SvgStyleGradient* from)
|
||||
{
|
||||
if (!from) return nullptr;
|
||||
|
@ -2419,6 +2650,7 @@ static SvgStyleGradient* _cloneGradient(SvgStyleGradient* from)
|
|||
grad->ref = from->ref ? _copyId(from->ref) : nullptr;
|
||||
grad->spread = from->spread;
|
||||
grad->userSpace = from->userSpace;
|
||||
grad->flags = from->flags;
|
||||
|
||||
if (from->transform) {
|
||||
grad->transform = (Matrix*)calloc(1, sizeof(Matrix));
|
||||
|
@ -2948,7 +3180,7 @@ static void _updateStyle(SvgNode* node, SvgStyleProperty* parentStyle)
|
|||
}
|
||||
|
||||
|
||||
static SvgStyleGradient* _gradientDup(Array<SvgStyleGradient*>* gradients, const char* id)
|
||||
static SvgStyleGradient* _gradientDup(SvgLoaderData* loader, Array<SvgStyleGradient*>* gradients, const char* id)
|
||||
{
|
||||
SvgStyleGradient* result = nullptr;
|
||||
|
||||
|
@ -2966,8 +3198,7 @@ static SvgStyleGradient* _gradientDup(Array<SvgStyleGradient*>* gradients, const
|
|||
gradList = gradients->data;
|
||||
for (uint32_t i = 0; i < gradients->count; ++i) {
|
||||
if ((*gradList)->id && !strcmp((*gradList)->id, result->ref)) {
|
||||
if (result->stops.count == 0) _cloneGradStops(result->stops, (*gradList)->stops);
|
||||
//TODO: Properly inherit other property
|
||||
_inheritGradient(loader, result, *gradList);
|
||||
break;
|
||||
}
|
||||
++gradList;
|
||||
|
@ -2978,12 +3209,12 @@ static SvgStyleGradient* _gradientDup(Array<SvgStyleGradient*>* gradients, const
|
|||
}
|
||||
|
||||
|
||||
static void _updateGradient(SvgNode* node, Array<SvgStyleGradient*>* gradients)
|
||||
static void _updateGradient(SvgLoaderData* loader, SvgNode* node, Array<SvgStyleGradient*>* gradients)
|
||||
{
|
||||
if (node->child.count > 0) {
|
||||
auto child = node->child.data;
|
||||
for (uint32_t i = 0; i < node->child.count; ++i, ++child) {
|
||||
_updateGradient(*child, gradients);
|
||||
_updateGradient(loader, *child, gradients);
|
||||
}
|
||||
} else {
|
||||
if (node->style->fill.paint.url) {
|
||||
|
@ -2991,14 +3222,14 @@ static void _updateGradient(SvgNode* node, Array<SvgStyleGradient*>* gradients)
|
|||
node->style->fill.paint.gradient->clear();
|
||||
free(node->style->fill.paint.gradient);
|
||||
}
|
||||
node->style->fill.paint.gradient = _gradientDup(gradients, node->style->fill.paint.url);
|
||||
node->style->fill.paint.gradient = _gradientDup(loader, gradients, node->style->fill.paint.url);
|
||||
}
|
||||
if (node->style->stroke.paint.url) {
|
||||
if (node->style->stroke.paint.gradient) {
|
||||
node->style->stroke.paint.gradient->clear();
|
||||
free(node->style->stroke.paint.gradient);
|
||||
}
|
||||
node->style->stroke.paint.gradient = _gradientDup(gradients, node->style->stroke.paint.url);
|
||||
node->style->stroke.paint.gradient = _gradientDup(loader, gradients, node->style->stroke.paint.url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3205,8 +3436,8 @@ void SvgLoader::run(unsigned tid)
|
|||
_updateComposite(loaderData.doc, loaderData.doc);
|
||||
if (defs) _updateComposite(loaderData.doc, defs);
|
||||
|
||||
if (loaderData.gradients.count > 0) _updateGradient(loaderData.doc, &loaderData.gradients);
|
||||
if (defs) _updateGradient(loaderData.doc, &defs->node.defs.gradients);
|
||||
if (loaderData.gradients.count > 0) _updateGradient(&loaderData, loaderData.doc, &loaderData.gradients);
|
||||
if (defs) _updateGradient(&loaderData, loaderData.doc, &defs->node.defs.gradients);
|
||||
|
||||
_updateStyle(loaderData.doc, nullptr);
|
||||
}
|
||||
|
|
|
@ -125,6 +125,22 @@ enum class SvgStopStyleFlags
|
|||
StopColor = 0x02
|
||||
};
|
||||
|
||||
enum class SvgGradientFlags
|
||||
{
|
||||
None = 0x0,
|
||||
GradientUnits = 0x1,
|
||||
SpreadMethod = 0x2,
|
||||
X1 = 0x4,
|
||||
X2 = 0x8,
|
||||
Y1 = 0x10,
|
||||
Y2 = 0x20,
|
||||
Cx = 0x40,
|
||||
Cy = 0x80,
|
||||
R = 0x100,
|
||||
Fx = 0x200,
|
||||
Fy = 0x400
|
||||
};
|
||||
|
||||
enum class SvgFillRule
|
||||
{
|
||||
Winding = 0,
|
||||
|
@ -349,6 +365,7 @@ struct SvgStyleGradient
|
|||
SvgLinearGradient* linear;
|
||||
Matrix* transform;
|
||||
Array<Fill::ColorStop> stops;
|
||||
SvgGradientFlags flags;
|
||||
bool userSpace;
|
||||
|
||||
void clear()
|
||||
|
|
Loading…
Add table
Reference in a new issue