diff --git a/src/loaders/svg/tvgSvgLoader.cpp b/src/loaders/svg/tvgSvgLoader.cpp index c6c7cc81..67a9838b 100644 --- a/src/loaders/svg/tvgSvgLoader.cpp +++ b/src/loaders/svg/tvgSvgLoader.cpp @@ -1588,22 +1588,23 @@ static void _cloneGradStops(Array& dst, const Arraytype = from->type; grad->id = from->id ? _copyId(from->id->c_str()) : nullptr; grad->ref = from->ref ? _copyId(from->ref->c_str()) : nullptr; grad->spread = from->spread; grad->usePercentage = from->usePercentage; grad->userSpace = from->userSpace; + if (from->transform) { grad->transform = (Matrix*)calloc(1, sizeof(Matrix)); if (grad->transform) memcpy(grad->transform, from->transform, sizeof(Matrix)); } + if (grad->type == SvgGradientType::Linear) { grad->linear = (SvgLinearGradient*)calloc(1, sizeof(SvgLinearGradient)); if (!grad->linear) goto error_grad_alloc; @@ -1615,13 +1616,11 @@ static SvgStyleGradient* _cloneGradient(SvgStyleGradient* from) } _cloneGradStops(grad->stops, from->stops); + return grad; + error_grad_alloc: - //LOG: allocation failed. out of memory - if (grad->transform) free(grad->transform); - if (grad->ref) delete grad->ref; - if (grad->id) delete grad->id; - if (grad) free(grad); + if (grad) delete(grad); return nullptr; } @@ -1960,15 +1959,16 @@ static bool _attrParseRadialGradientNode(void* data, const char* key, const char static SvgStyleGradient* _createRadialGradient(SvgLoaderData* loader, const char* buf, unsigned bufLength) { - SvgStyleGradient* grad = (SvgStyleGradient*)calloc(1, sizeof(SvgStyleGradient)); + auto grad = new SvgStyleGradient; if (!grad) return nullptr; + loader->svgParse->styleGrad = grad; grad->type = SvgGradientType::Radial; grad->userSpace = false; grad->radial = (SvgRadialGradient*)calloc(1, sizeof(SvgRadialGradient)); if (!grad->radial) { - free(grad); + delete(grad); return nullptr; } /** @@ -2145,15 +2145,16 @@ static bool _attrParseLinearGradientNode(void* data, const char* key, const char static SvgStyleGradient* _createLinearGradient(SvgLoaderData* loader, const char* buf, unsigned bufLength) { - SvgStyleGradient* grad = (SvgStyleGradient*)calloc(1, sizeof(SvgStyleGradient)); + auto grad = new SvgStyleGradient; if (!grad) return nullptr; + loader->svgParse->styleGrad = grad; grad->type = SvgGradientType::Linear; grad->userSpace = false; grad->linear = (SvgLinearGradient*)calloc(1, sizeof(SvgLinearGradient)); if (!grad->linear) { - free(grad); + delete(grad); return nullptr; } /** @@ -2504,14 +2505,17 @@ static void _updateGradient(SvgNode* node, Array* gradients) } } else { if (node->style->fill.paint.url) { + if (node->style->fill.paint.gradient) delete(node->style->fill.paint.gradient); node->style->fill.paint.gradient = _gradientDup(gradients, node->style->fill.paint.url); } if (node->style->stroke.paint.url) { + if (node->style->stroke.paint.gradient) delete(node->style->stroke.paint.gradient); node->style->stroke.paint.gradient = _gradientDup(gradients, node->style->stroke.paint.url); } } } + static void _updateComposite(SvgNode* node, SvgNode* root) { if (node->style->comp.url && !node->style->comp.node) { @@ -2526,34 +2530,23 @@ static void _updateComposite(SvgNode* node, SvgNode* root) } } -static void _freeGradientStyle(SvgStyleGradient* grad) -{ - if (!grad) return; - - delete grad->id; - delete grad->ref; - free(grad->radial); - free(grad->linear); - if (grad->transform) free(grad->transform); - grad->stops.reset(); - free(grad); -} 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; + delete(style->comp.url); - _freeGradientStyle(style->fill.paint.gradient); - delete style->fill.paint.url; - _freeGradientStyle(style->stroke.paint.gradient); - if (style->stroke.dash.array.count > 0) style->stroke.dash.array.reset(); - delete style->stroke.paint.url; + if (style->fill.paint.gradient) delete(style->fill.paint.gradient); + if (style->stroke.paint.gradient) delete(style->stroke.paint.gradient); + delete(style->fill.paint.url); + delete(style->stroke.paint.url); + style->stroke.dash.array.reset(); free(style); } + static void _freeNode(SvgNode* node) { if (!node) return; @@ -2587,7 +2580,7 @@ static void _freeNode(SvgNode* node) case SvgNodeType::Defs: { auto gradients = node->node.defs.gradients.data; for (size_t i = 0; i < node->node.defs.gradients.count; ++i) { - _freeGradientStyle(*gradients); + delete(*gradients); ++gradients; } node->node.defs.gradients.reset(); @@ -2800,7 +2793,7 @@ bool SvgLoader::close() } auto gradients = loaderData.gradients.data; for (size_t i = 0; i < loaderData.gradients.count; ++i) { - _freeGradientStyle(*gradients); + delete(*gradients); ++gradients; } loaderData.gradients.reset(); diff --git a/src/loaders/svg/tvgSvgLoaderCommon.h b/src/loaders/svg/tvgSvgLoaderCommon.h index efba6751..03e28876 100644 --- a/src/loaders/svg/tvgSvgLoaderCommon.h +++ b/src/loaders/svg/tvgSvgLoaderCommon.h @@ -247,16 +247,26 @@ struct SvgDash struct SvgStyleGradient { - SvgGradientType type; - string *id; - string *ref; - FillSpread spread; - SvgRadialGradient* radial; - SvgLinearGradient* linear; - Matrix* transform; + SvgGradientType type = SvgGradientType::Linear; + string *id = nullptr; + string *ref = nullptr; + FillSpread spread = FillSpread::Pad; + SvgRadialGradient* radial = nullptr; + SvgLinearGradient* linear = nullptr; + Matrix* transform = nullptr; Array stops; - bool userSpace; - bool usePercentage; + bool userSpace = false; + bool usePercentage = false; + + ~SvgStyleGradient() + { + stops.reset(); + free(transform); + free(radial); + free(linear); + delete(ref); + delete(id); + } }; struct SvgStyleFill @@ -319,7 +329,7 @@ struct SvgParser { SvgNode* node; SvgStyleGradient* styleGrad; - Fill::ColorStop gradStop; + Fill::ColorStop gradStop; SvgStopStyleFlags flags; struct {