common sw_engine: code refactoring & stabilizing.

Apply tvg Array instead of std::vector

Also Fixed to compList in update() to passed by reference, not copying.
Also Fixed Composition Target memory leak

Here is the binary size result:

[libthorvg.so] 1785376 >> 1607416
[text] 121255 >> 118277
[data] 7792 >> 7736
[dec] 129119 >> 126085
This commit is contained in:
Hermet Park 2020-12-09 19:56:59 +09:00 committed by GitHub
parent d13cd37094
commit 1ed611386d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 96 additions and 73 deletions

View file

@ -162,14 +162,14 @@ bool GlRenderer::dispose(void *data)
} }
void* GlRenderer::prepare(TVG_UNUSED const Picture& picture, TVG_UNUSED void* data, TVG_UNUSED uint32_t *buffer, TVG_UNUSED const RenderTransform* transform, TVG_UNUSED uint32_t opacity, TVG_UNUSED vector<Composite>& compList, TVG_UNUSED RenderUpdateFlag flags) void* GlRenderer::prepare(TVG_UNUSED const Picture& picture, TVG_UNUSED void* data, TVG_UNUSED uint32_t *buffer, TVG_UNUSED const RenderTransform* transform, TVG_UNUSED uint32_t opacity, TVG_UNUSED Array<Composite>& compList, TVG_UNUSED RenderUpdateFlag flags)
{ {
//TODO: //TODO:
return nullptr; return nullptr;
} }
void* GlRenderer::prepare(const Shape& shape, void* data, TVG_UNUSED const RenderTransform* transform, TVG_UNUSED uint32_t opacity, vector<Composite>& compList, RenderUpdateFlag flags) void* GlRenderer::prepare(const Shape& shape, void* data, TVG_UNUSED const RenderTransform* transform, TVG_UNUSED uint32_t opacity, Array<Composite>& compList, RenderUpdateFlag flags)
{ {
//prepare shape data //prepare shape data
GlShape* sdata = static_cast<GlShape*>(data); GlShape* sdata = static_cast<GlShape*>(data);

View file

@ -30,8 +30,8 @@ class GlRenderer : public RenderMethod
public: public:
Surface surface = {nullptr, 0, 0, 0}; Surface surface = {nullptr, 0, 0, 0};
void* prepare(const Shape& shape, void* data, const RenderTransform* transform, uint32_t opacity, vector<Composite>& compList, RenderUpdateFlag flags) override; void* prepare(const Shape& shape, void* data, const RenderTransform* transform, uint32_t opacity, Array<Composite>& compList, RenderUpdateFlag flags) override;
void* prepare(const Picture& picture, void* data, uint32_t *buffer, const RenderTransform* transform, uint32_t opacity, vector<Composite>& compList, RenderUpdateFlag flags) override; void* prepare(const Picture& picture, void* data, uint32_t *buffer, const RenderTransform* transform, uint32_t opacity, Array<Composite>& compList, RenderUpdateFlag flags) override;
bool dispose(void *data) override; bool dispose(void *data) override;
void* beginComposite(uint32_t x, uint32_t y, uint32_t w, uint32_t h) override; void* beginComposite(uint32_t x, uint32_t y, uint32_t w, uint32_t h) override;
bool endComposite(void* ctx, uint32_t opacity) override; bool endComposite(void* ctx, uint32_t opacity) override;

View file

@ -43,7 +43,7 @@ struct SwTask : Task
Matrix* transform = nullptr; Matrix* transform = nullptr;
SwSurface* surface = nullptr; SwSurface* surface = nullptr;
RenderUpdateFlag flags = RenderUpdateFlag::None; RenderUpdateFlag flags = RenderUpdateFlag::None;
vector<Composite> compList; Array<Composite> compList;
uint32_t opacity; uint32_t opacity;
virtual bool dispose() = 0; virtual bool dispose() = 0;
@ -91,7 +91,7 @@ struct SwShapeTask : SwTask
shape outline below stroke could be full covered by stroke drawing. shape outline below stroke could be full covered by stroke drawing.
Thus it turns off antialising in that condition. */ Thus it turns off antialising in that condition. */
auto antiAlias = (strokeAlpha == 255 && strokeWidth > 2) ? false : true; auto antiAlias = (strokeAlpha == 255 && strokeWidth > 2) ? false : true;
if (!shapeGenRle(&shape, sdata, clip, antiAlias, compList.size() > 0 ? true : false)) goto end; if (!shapeGenRle(&shape, sdata, clip, antiAlias, compList.count > 0 ? true : false)) goto end;
++addStroking; ++addStroking;
} }
} }
@ -121,9 +121,9 @@ struct SwShapeTask : SwTask
} }
//Composition //Composition
for (auto comp : compList) { for (auto comp = compList.data; comp < (compList.data + compList.count); ++comp) {
if (comp.method == CompositeMethod::ClipPath) { if ((*comp).method == CompositeMethod::ClipPath) {
auto compShape = &static_cast<SwShapeTask*>(comp.edata)->shape; auto compShape = &static_cast<SwShapeTask*>((*comp).edata)->shape;
//Clip shape rle //Clip shape rle
if (shape.rle) { if (shape.rle) {
if (compShape->rect) rleClipRect(shape.rle, &compShape->bbox); if (compShape->rect) rleClipRect(shape.rle, &compShape->bbox);
@ -169,12 +169,12 @@ struct SwImageTask : SwTask
if (!imagePrepare(&image, pdata, tid, clip, transform)) goto end; if (!imagePrepare(&image, pdata, tid, clip, transform)) goto end;
//Composition? //Composition?
if (compList.size() > 0) { if (compList.count > 0) {
if (!imageGenRle(&image, pdata, clip, false, true)) goto end; if (!imageGenRle(&image, pdata, clip, false, true)) goto end;
if (image.rle) { if (image.rle) {
for (auto comp : compList) { for (auto comp = compList.data; comp < (compList.data + compList.count); ++comp) {
if (comp.method == CompositeMethod::ClipPath) { if ((*comp).method == CompositeMethod::ClipPath) {
auto compShape = &static_cast<SwShapeTask*>(comp.edata)->shape; auto compShape = &static_cast<SwShapeTask*>((*comp).edata)->shape;
if (compShape->rect) rleClipRect(image.rle, &compShape->bbox); if (compShape->rect) rleClipRect(image.rle, &compShape->bbox);
else if (compShape->rle) rleClipPath(image.rle, compShape->rle); else if (compShape->rle) rleClipPath(image.rle, compShape->rle);
} }
@ -220,7 +220,7 @@ SwRenderer::~SwRenderer()
bool SwRenderer::clear() bool SwRenderer::clear()
{ {
for (auto task : tasks) task->done(); for (auto task = tasks.data; task < (tasks.data + tasks.count); ++task) (*task)->done();
tasks.clear(); tasks.clear();
return true; return true;
@ -411,12 +411,14 @@ bool SwRenderer::dispose(void *data)
} }
void SwRenderer::prepareCommon(SwTask* task, const RenderTransform* transform, uint32_t opacity, vector<Composite>& compList, RenderUpdateFlag flags) void SwRenderer::prepareCommon(SwTask* task, const RenderTransform* transform, uint32_t opacity, Array<Composite>& compList, RenderUpdateFlag flags)
{ {
if (compList.size() > 0) { if (compList.count > 0) {
//Guarantee composition targets get ready. //Guarantee composition targets get ready.
for (auto comp : compList) static_cast<SwShapeTask*>(comp.edata)->done(); for (auto comp = compList.data; comp < (compList.data + compList.count); ++comp) {
task->compList.assign(compList.begin(), compList.end()); static_cast<SwShapeTask*>((*comp).edata)->done();
}
task->compList = compList;
} }
if (transform) { if (transform) {
@ -431,12 +433,12 @@ void SwRenderer::prepareCommon(SwTask* task, const RenderTransform* transform, u
task->surface = surface; task->surface = surface;
task->flags = flags; task->flags = flags;
tasks.push_back(task); tasks.push(task);
TaskScheduler::request(task); TaskScheduler::request(task);
} }
void* SwRenderer::prepare(const Picture& pdata, void* data, uint32_t *pixels, const RenderTransform* transform, uint32_t opacity, vector<Composite>& compList, RenderUpdateFlag flags) void* SwRenderer::prepare(const Picture& pdata, void* data, uint32_t *pixels, const RenderTransform* transform, uint32_t opacity, Array<Composite>& compList, RenderUpdateFlag flags)
{ {
//prepare task //prepare task
auto task = static_cast<SwImageTask*>(data); auto task = static_cast<SwImageTask*>(data);
@ -459,7 +461,7 @@ void* SwRenderer::prepare(const Picture& pdata, void* data, uint32_t *pixels, co
} }
void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform* transform, uint32_t opacity, vector<Composite>& compList, RenderUpdateFlag flags) void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform* transform, uint32_t opacity, Array<Composite>& compList, RenderUpdateFlag flags)
{ {
//prepare task //prepare task
auto task = static_cast<SwShapeTask*>(data); auto task = static_cast<SwShapeTask*>(data);

View file

@ -22,7 +22,6 @@
#ifndef _TVG_SW_RENDERER_H_ #ifndef _TVG_SW_RENDERER_H_
#define _TVG_SW_RENDERER_H_ #define _TVG_SW_RENDERER_H_
#include <vector>
#include "tvgRender.h" #include "tvgRender.h"
struct SwSurface; struct SwSurface;
@ -36,8 +35,8 @@ namespace tvg
class SwRenderer : public RenderMethod class SwRenderer : public RenderMethod
{ {
public: public:
void* prepare(const Shape& shape, void* data, const RenderTransform* transform, uint32_t opacity, vector<Composite>& compList, RenderUpdateFlag flags) override; void* prepare(const Shape& shape, void* data, const RenderTransform* transform, uint32_t opacity, Array<Composite>& compList, RenderUpdateFlag flags) override;
void* prepare(const Picture& picture, void* data, uint32_t *buffer, const RenderTransform* transform, uint32_t opacity, vector<Composite>& compList, RenderUpdateFlag flags) override; void* prepare(const Picture& picture, void* data, uint32_t *buffer, const RenderTransform* transform, uint32_t opacity, Array<Composite>& compList, RenderUpdateFlag flags) override;
void* beginComposite(uint32_t x, uint32_t y, uint32_t w, uint32_t h) override; void* beginComposite(uint32_t x, uint32_t y, uint32_t w, uint32_t h) override;
bool endComposite(void* ctx, uint32_t opacity) override; bool endComposite(void* ctx, uint32_t opacity) override;
bool dispose(void *data) override; bool dispose(void *data) override;
@ -54,13 +53,13 @@ public:
static bool term(); static bool term();
private: private:
SwSurface* surface = nullptr; SwSurface* surface = nullptr;
vector<SwTask*> tasks; Array<SwTask*> tasks;
SwRenderer(){}; SwRenderer(){};
~SwRenderer(); ~SwRenderer();
void prepareCommon(SwTask* task, const RenderTransform* transform, uint32_t opacity, vector<Composite>& compList, RenderUpdateFlag flags); void prepareCommon(SwTask* task, const RenderTransform* transform, uint32_t opacity, Array<Composite>& compList, RenderUpdateFlag flags);
}; };
} }

View file

@ -621,7 +621,7 @@ SwSpan* _intersectSpansRegion(const SwRleData *clip, const SwRleData *targetRle,
auto clipSpans = clip->spans; auto clipSpans = clip->spans;
auto clipEnd = clip->spans + clip->size; auto clipEnd = clip->spans + clip->size;
while (spanCnt && spans < end ) { while (spanCnt > 0 && spans < end ) {
if (clipSpans > clipEnd) { if (clipSpans > clipEnd) {
spans = end; spans = end;
break; break;

View file

@ -22,6 +22,7 @@
#ifndef _TVG_ARRAY_H_ #ifndef _TVG_ARRAY_H_
#define _TVG_ARRAY_H_ #define _TVG_ARRAY_H_
#include <memory.h>
namespace tvg namespace tvg
{ {
@ -42,12 +43,20 @@ struct Array
data[count++] = element; data[count++] = element;
} }
void reserve(uint32_t size)
{
if (size > reserved) {
reserved = size;
data = static_cast<T*>(realloc(data, sizeof(T) * reserved));
}
}
void pop() void pop()
{ {
if (count > 0) --count; if (count > 0) --count;
} }
void clear() void reset()
{ {
if (data) { if (data) {
free(data); free(data);
@ -56,6 +65,18 @@ struct Array
count = reserved = 0; count = reserved = 0;
} }
void clear()
{
count = 0;
}
void operator=(const Array& rhs)
{
reserve(rhs.count);
memcpy(data, rhs.data, sizeof(T) * reserved);
count = rhs.count;
}
~Array() ~Array()
{ {
if (data) free(data); if (data) free(data);

View file

@ -22,7 +22,6 @@
#ifndef _TVG_CANVAS_IMPL_H_ #ifndef _TVG_CANVAS_IMPL_H_
#define _TVG_CANVAS_IMPL_H_ #define _TVG_CANVAS_IMPL_H_
#include <vector>
#include "tvgPaint.h" #include "tvgPaint.h"
/************************************************************************/ /************************************************************************/
@ -31,7 +30,7 @@
struct Canvas::Impl struct Canvas::Impl
{ {
vector<Paint*> paints; Array<Paint*> paints;
RenderMethod* renderer; RenderMethod* renderer;
Impl(RenderMethod* pRenderer):renderer(pRenderer) Impl(RenderMethod* pRenderer):renderer(pRenderer)
@ -48,7 +47,7 @@ struct Canvas::Impl
{ {
auto p = paint.release(); auto p = paint.release();
if (!p) return Result::MemoryCorruption; if (!p) return Result::MemoryCorruption;
paints.push_back(p); paints.push(p);
return update(p); return update(p);
} }
@ -62,9 +61,9 @@ struct Canvas::Impl
//free paints //free paints
if (free) { if (free) {
for (auto paint : paints) { for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) {
paint->pImpl->dispose(*renderer); (*paint)->pImpl->dispose(*renderer);
delete(paint); delete(*paint);
} }
} }
@ -77,15 +76,15 @@ struct Canvas::Impl
{ {
if (!renderer) return Result::InsufficientCondition; if (!renderer) return Result::InsufficientCondition;
vector<Composite> compList; Array<Composite> compList;
//Update single paint node //Update single paint node
if (paint) { if (paint) {
paint->pImpl->update(*renderer, nullptr, 255, compList, RenderUpdateFlag::None); paint->pImpl->update(*renderer, nullptr, 255, compList, RenderUpdateFlag::None);
//Update all retained paint nodes //Update all retained paint nodes
} else { } else {
for (auto paint : paints) { for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) {
paint->pImpl->update(*renderer, nullptr, 255, compList, RenderUpdateFlag::None); (*paint)->pImpl->update(*renderer, nullptr, 255, compList, RenderUpdateFlag::None);
} }
} }
return Result::Success; return Result::Success;
@ -97,8 +96,8 @@ struct Canvas::Impl
if (!renderer->preRender()) return Result::InsufficientCondition; if (!renderer->preRender()) return Result::InsufficientCondition;
for (auto paint : paints) { for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) {
if (!paint->pImpl->render(*renderer)) return Result::InsufficientCondition; if (!(*paint)->pImpl->render(*renderer)) return Result::InsufficientCondition;
} }
if (!renderer->postRender()) return Result::InsufficientCondition; if (!renderer->postRender()) return Result::InsufficientCondition;

View file

@ -26,6 +26,7 @@
#include <math.h> #include <math.h>
#include "tvgRender.h" #include "tvgRender.h"
namespace tvg namespace tvg
{ {
struct StrategyMethod struct StrategyMethod
@ -33,7 +34,7 @@ namespace tvg
virtual ~StrategyMethod() {} virtual ~StrategyMethod() {}
virtual bool dispose(RenderMethod& renderer) = 0; virtual bool dispose(RenderMethod& renderer) = 0;
virtual void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, vector<Composite> compList, RenderUpdateFlag pFlag) = 0; //Return engine data if it has. virtual void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, Array<Composite>& compList, RenderUpdateFlag pFlag) = 0; //Return engine data if it has.
virtual bool render(RenderMethod& renderer) = 0; virtual bool render(RenderMethod& renderer) = 0;
virtual bool bounds(float* x, float* y, float* w, float* h) const = 0; virtual bool bounds(float* x, float* y, float* w, float* h) const = 0;
virtual Paint* duplicate() = 0; virtual Paint* duplicate() = 0;
@ -51,6 +52,7 @@ namespace tvg
uint8_t opacity = 255; uint8_t opacity = 255;
~Impl() { ~Impl() {
if (compTarget) delete(compTarget);
if (smethod) delete(smethod); if (smethod) delete(smethod);
if (rTransform) delete(rTransform); if (rTransform) delete(rTransform);
} }
@ -129,7 +131,7 @@ namespace tvg
return smethod->dispose(renderer); return smethod->dispose(renderer);
} }
void* update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t opacity, vector<Composite>& compList, uint32_t pFlag) void* update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t opacity, Array<Composite>& compList, uint32_t pFlag)
{ {
if (flag & RenderUpdateFlag::Transform) { if (flag & RenderUpdateFlag::Transform) {
if (!rTransform) return nullptr; if (!rTransform) return nullptr;
@ -143,7 +145,7 @@ namespace tvg
if (compTarget && compMethod == CompositeMethod::ClipPath) { if (compTarget && compMethod == CompositeMethod::ClipPath) {
compdata = compTarget->pImpl->update(renderer, pTransform, opacity, compList, pFlag); compdata = compTarget->pImpl->update(renderer, pTransform, opacity, compList, pFlag);
if (compdata) compList.push_back({compdata, compMethod}); if (compdata) compList.push({compdata, compMethod});
} }
void *edata = nullptr; void *edata = nullptr;
@ -159,7 +161,7 @@ namespace tvg
edata = smethod->update(renderer, outTransform, opacity, compList, newFlag); edata = smethod->update(renderer, outTransform, opacity, compList, newFlag);
} }
if (compdata) compList.pop_back(); if (compdata) compList.pop();
return edata; return edata;
} }
@ -215,7 +217,7 @@ namespace tvg
return inst->dispose(renderer); return inst->dispose(renderer);
} }
void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, vector<Composite> compList, RenderUpdateFlag flag) override void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, Array<Composite>& compList, RenderUpdateFlag flag) override
{ {
return inst->update(renderer, transform, opacity, compList, flag); return inst->update(renderer, transform, opacity, compList, flag);
} }

View file

@ -110,7 +110,7 @@ struct Picture::Impl
return RenderUpdateFlag::None; return RenderUpdateFlag::None;
} }
void* update(RenderMethod &renderer, const RenderTransform* transform, uint32_t opacity, vector<Composite>& compList, RenderUpdateFlag pFlag) void* update(RenderMethod &renderer, const RenderTransform* transform, uint32_t opacity, Array<Composite>& compList, RenderUpdateFlag pFlag)
{ {
uint32_t flag = reload(); uint32_t flag = reload();

View file

@ -22,8 +22,8 @@
#ifndef _TVG_RENDER_H_ #ifndef _TVG_RENDER_H_
#define _TVG_RENDER_H_ #define _TVG_RENDER_H_
#include <vector>
#include "tvgCommon.h" #include "tvgCommon.h"
#include "tvgArray.h"
namespace tvg namespace tvg
{ {
@ -65,8 +65,8 @@ class RenderMethod
{ {
public: public:
virtual ~RenderMethod() {} virtual ~RenderMethod() {}
virtual void* prepare(const Shape& shape, void* data, const RenderTransform* transform, uint32_t opacity, vector<Composite>& compList, RenderUpdateFlag flags) = 0; virtual void* prepare(const Shape& shape, void* data, const RenderTransform* transform, uint32_t opacity, Array<Composite>& compList, RenderUpdateFlag flags) = 0;
virtual void* prepare(const Picture& picture, void* data, uint32_t *buffer, const RenderTransform* transform, uint32_t opacity, vector<Composite>& compList, RenderUpdateFlag flags) = 0; virtual void* prepare(const Picture& picture, void* data, uint32_t *buffer, const RenderTransform* transform, uint32_t opacity, Array<Composite>& compList, RenderUpdateFlag flags) = 0;
virtual void* beginComposite(uint32_t x, uint32_t y, uint32_t w, uint32_t h) = 0; virtual void* beginComposite(uint32_t x, uint32_t y, uint32_t w, uint32_t h) = 0;
virtual bool endComposite(void* ctx, uint32_t opacity) = 0; virtual bool endComposite(void* ctx, uint32_t opacity) = 0;
virtual bool dispose(void *data) = 0; virtual bool dispose(void *data) = 0;

View file

@ -47,7 +47,7 @@ Result Scene::push(unique_ptr<Paint> paint) noexcept
{ {
auto p = paint.release(); auto p = paint.release();
if (!p) return Result::MemoryCorruption; if (!p) return Result::MemoryCorruption;
pImpl->paints.push_back(p); pImpl->paints.push(p);
return Result::Success; return Result::Success;
} }

View file

@ -22,7 +22,6 @@
#ifndef _TVG_SCENE_IMPL_H_ #ifndef _TVG_SCENE_IMPL_H_
#define _TVG_SCENE_IMPL_H_ #define _TVG_SCENE_IMPL_H_
#include <vector>
#include "tvgPaint.h" #include "tvgPaint.h"
/************************************************************************/ /************************************************************************/
@ -31,21 +30,21 @@
struct Scene::Impl struct Scene::Impl
{ {
vector<Paint*> paints; Array<Paint*> paints;
uint32_t opacity; uint32_t opacity;
bool dispose(RenderMethod& renderer) bool dispose(RenderMethod& renderer)
{ {
for (auto paint : paints) { for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) {
paint->pImpl->dispose(renderer); (*paint)->pImpl->dispose(renderer);
delete(paint); delete(*paint);
} }
paints.clear(); paints.clear();
return true; return true;
} }
void* update(RenderMethod &renderer, const RenderTransform* transform, uint32_t opacity, vector<Composite>& compList, RenderUpdateFlag flag) void* update(RenderMethod &renderer, const RenderTransform* transform, uint32_t opacity, Array<Composite>& compList, RenderUpdateFlag flag)
{ {
this->opacity = opacity; this->opacity = opacity;
@ -57,8 +56,8 @@ struct Scene::Impl
This is necessary for scene composition */ This is necessary for scene composition */
void* edata = nullptr; void* edata = nullptr;
for (auto paint : paints) { for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) {
edata = paint->pImpl->update(renderer, transform, opacity, compList, static_cast<uint32_t>(flag)); edata = (*paint)->pImpl->update(renderer, transform, opacity, compList, static_cast<uint32_t>(flag));
} }
return edata; return edata;
@ -77,8 +76,8 @@ struct Scene::Impl
ctx = renderer.beginComposite(0, 0, 0, 0); ctx = renderer.beginComposite(0, 0, 0, 0);
} }
for (auto paint : paints) { for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) {
if (!paint->pImpl->render(renderer)) return false; if (!(*paint)->pImpl->render(renderer)) return false;
} }
if (ctx) return renderer.endComposite(ctx, opacity); if (ctx) return renderer.endComposite(ctx, opacity);
@ -88,20 +87,20 @@ struct Scene::Impl
bool bounds(float* px, float* py, float* pw, float* ph) bool bounds(float* px, float* py, float* pw, float* ph)
{ {
if (paints.size() == 0) return false; if (paints.count == 0) return false;
auto x1 = FLT_MAX; auto x1 = FLT_MAX;
auto y1 = FLT_MAX; auto y1 = FLT_MAX;
auto x2 = 0.0f; auto x2 = 0.0f;
auto y2 = 0.0f; auto y2 = 0.0f;
for (auto paint : paints) { for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) {
auto x = FLT_MAX; auto x = FLT_MAX;
auto y = FLT_MAX; auto y = FLT_MAX;
auto w = 0.0f; auto w = 0.0f;
auto h = 0.0f; auto h = 0.0f;
if (!paint->pImpl->bounds(&x, &y, &w, &h)) continue; if (!(*paint)->pImpl->bounds(&x, &y, &w, &h)) continue;
//Merge regions //Merge regions
if (x < x1) x1 = x; if (x < x1) x1 = x;
@ -124,10 +123,10 @@ struct Scene::Impl
if (!ret) return nullptr; if (!ret) return nullptr;
auto dup = ret.get()->pImpl; auto dup = ret.get()->pImpl;
dup->paints.reserve(paints.size()); dup->paints.reserve(paints.count);
for (auto paint : paints) { for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) {
dup->paints.push_back(paint->duplicate()); dup->paints.push((*paint)->duplicate());
} }
return ret.release(); return ret.release();

View file

@ -223,7 +223,7 @@ struct Shape::Impl
return renderer.render(*shape, edata); return renderer.render(*shape, edata);
} }
void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, vector<Composite>& compList, RenderUpdateFlag pFlag) void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, Array<Composite>& compList, RenderUpdateFlag pFlag)
{ {
this->edata = renderer.prepare(*shape, this->edata, transform, opacity, compList, static_cast<RenderUpdateFlag>(pFlag | flag)); this->edata = renderer.prepare(*shape, this->edata, transform, opacity, compList, static_cast<RenderUpdateFlag>(pFlag | flag));
flag = RenderUpdateFlag::None; flag = RenderUpdateFlag::None;

View file

@ -2196,6 +2196,7 @@ static void _styleInherit(SvgStyleProperty* child, SvgStyleProperty* parent)
if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Dash)) { if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Dash)) {
if (parent->stroke.dash.array.count > 0) { if (parent->stroke.dash.array.count > 0) {
child->stroke.dash.array.clear(); child->stroke.dash.array.clear();
child->stroke.dash.array.reserve(parent->stroke.dash.array.count);
for (uint32_t i = 0; i < parent->stroke.dash.array.count; ++i) { for (uint32_t i = 0; i < parent->stroke.dash.array.count; ++i) {
child->stroke.dash.array.push(parent->stroke.dash.array.data[i]); child->stroke.dash.array.push(parent->stroke.dash.array.data[i]);
} }
@ -2297,7 +2298,7 @@ static void _freeGradientStyle(SvgStyleGradient* grad)
auto colorStop = grad->stops.data[i]; auto colorStop = grad->stops.data[i];
free(colorStop); free(colorStop);
} }
grad->stops.clear(); grad->stops.reset();
free(grad); free(grad);
} }
@ -2308,7 +2309,7 @@ static void _freeNodeStyle(SvgStyleProperty* style)
_freeGradientStyle(style->fill.paint.gradient); _freeGradientStyle(style->fill.paint.gradient);
delete style->fill.paint.url; delete style->fill.paint.url;
_freeGradientStyle(style->stroke.paint.gradient); _freeGradientStyle(style->stroke.paint.gradient);
if (style->stroke.dash.array.count > 0) style->stroke.dash.array.clear(); if (style->stroke.dash.array.count > 0) style->stroke.dash.array.reset();
delete style->stroke.paint.url; delete style->stroke.paint.url;
free(style); free(style);
} }
@ -2321,7 +2322,7 @@ static void _freeNode(SvgNode* node)
for (uint32_t i = 0; i < node->child.count; ++i, ++child) { for (uint32_t i = 0; i < node->child.count; ++i, ++child) {
_freeNode(*child); _freeNode(*child);
} }
node->child.clear(); node->child.reset();
delete node->id; delete node->id;
free(node->transform); free(node->transform);
@ -2349,7 +2350,7 @@ static void _freeNode(SvgNode* node)
_freeGradientStyle(*gradients); _freeGradientStyle(*gradients);
++gradients; ++gradients;
} }
node->node.defs.gradients.clear(); node->node.defs.gradients.reset();
break; break;
} }
default: { default: {
@ -2540,11 +2541,11 @@ bool SvgLoader::close()
_freeGradientStyle(*gradients); _freeGradientStyle(*gradients);
++gradients; ++gradients;
} }
loaderData.gradients.clear(); loaderData.gradients.reset();
_freeNode(loaderData.doc); _freeNode(loaderData.doc);
loaderData.doc = nullptr; loaderData.doc = nullptr;
loaderData.stack.clear(); loaderData.stack.reset();
return true; return true;
} }