1
0
Fork 0

Merge pull request #87869 from capnm/240202_thorvg_from_v0.12.3_to_0.12.4

ThorVG: update from v0.12.3 to v0.12.4
This commit is contained in:
Rémi Verschelde 2024-02-03 23:20:37 +01:00
commit cfc9a9f50b
No known key found for this signature in database
GPG Key ID: C3336907360768E1
16 changed files with 141 additions and 142 deletions

View File

@ -862,7 +862,7 @@ instead of `miniz.h` as an external dependency.
## thorvg ## thorvg
- Upstream: https://github.com/thorvg/thorvg - Upstream: https://github.com/thorvg/thorvg
- Version: 0.12.3 (9d79f0ccef632fd3b43b8ea02def529b6a8d2288, 2024) - Version: 0.12.4 (331839d49368e19ca15f35abee5ac541dbf23637, 2024)
- License: MIT - License: MIT
Files extracted from upstream source: Files extracted from upstream source:

View File

@ -9,5 +9,5 @@
// For internal debugging: // For internal debugging:
//#define THORVG_LOG_ENABLED //#define THORVG_LOG_ENABLED
#define THORVG_VERSION_STRING "0.12.3" #define THORVG_VERSION_STRING "0.12.4"
#endif #endif

View File

@ -51,8 +51,8 @@
#define _USE_MATH_DEFINES //Math Constants are not defined in Standard C/C++. #define _USE_MATH_DEFINES //Math Constants are not defined in Standard C/C++.
#include <cstring> #include <cstring>
#include <math.h>
#include <ctype.h> #include <ctype.h>
#include "tvgMath.h"
#include "tvgShape.h" #include "tvgShape.h"
#include "tvgSvgLoaderCommon.h" #include "tvgSvgLoaderCommon.h"
#include "tvgSvgPath.h" #include "tvgSvgPath.h"
@ -471,9 +471,16 @@ static bool _processCommand(Array<PathCommand>* cmds, Array<Point>* pts, char cm
} }
case 'a': case 'a':
case 'A': { case 'A': {
_pathAppendArcTo(cmds, pts, cur, curCtl, arr[5], arr[6], arr[0], arr[1], arr[2], arr[3], arr[4]); if (mathZero(arr[0]) || mathZero(arr[1])) {
Point p = {arr[5], arr[6]};
cmds->push(PathCommand::LineTo);
pts->push(p);
*cur = {arr[5], arr[6]};
} else if (!mathEqual(cur->x, arr[5]) || !mathEqual(cur->y, arr[6])) {
_pathAppendArcTo(cmds, pts, cur, curCtl, arr[5], arr[6], fabsf(arr[0]), fabsf(arr[1]), arr[2], arr[3], arr[4]);
*cur = *curCtl = {arr[5], arr[6]}; *cur = *curCtl = {arr[5], arr[6]};
*isQuadratic = false; *isQuadratic = false;
}
break; break;
} }
default: { default: {

View File

@ -63,7 +63,7 @@ struct SwTask : Task
return region; return region;
} }
virtual bool dispose() = 0; virtual void dispose() = 0;
virtual bool clip(SwRleData* target) = 0; virtual bool clip(SwRleData* target) = 0;
virtual SwRleData* rle() = 0; virtual SwRleData* rle() = 0;
@ -196,10 +196,9 @@ struct SwShapeTask : SwTask
shapeDelOutline(&shape, mpool, tid); shapeDelOutline(&shape, mpool, tid);
} }
bool dispose() override void dispose() override
{ {
shapeFree(&shape); shapeFree(&shape);
return true;
} }
}; };
@ -250,10 +249,9 @@ struct SwSceneTask : SwTask
} }
} }
bool dispose() override void dispose() override
{ {
rleFree(sceneRle); rleFree(sceneRle);
return true;
} }
}; };
@ -318,10 +316,9 @@ struct SwImageTask : SwTask
imageDelOutline(&image, mpool, tid); imageDelOutline(&image, mpool, tid);
} }
bool dispose() override void dispose() override
{ {
imageFree(&image); imageFree(&image);
return true;
} }
}; };
@ -703,17 +700,15 @@ ColorSpace SwRenderer::colorSpace()
} }
bool SwRenderer::dispose(RenderData data) void SwRenderer::dispose(RenderData data)
{ {
auto task = static_cast<SwTask*>(data); auto task = static_cast<SwTask*>(data);
if (!task) return true; if (!task) return;
task->done(); task->done();
task->dispose(); task->dispose();
if (task->pushed) task->disposed = true; if (task->pushed) task->disposed = true;
else delete(task); else delete(task);
return true;
} }

View File

@ -43,7 +43,7 @@ public:
bool renderShape(RenderData data) override; bool renderShape(RenderData data) override;
bool renderImage(RenderData data) override; bool renderImage(RenderData data) override;
bool postRender() override; bool postRender() override;
bool dispose(RenderData data) override; void dispose(RenderData data) override;
RenderRegion region(RenderData data) override; RenderRegion region(RenderData data) override;
RenderRegion viewport() override; RenderRegion viewport() override;
bool viewport(const RenderRegion& vp) override; bool viewport(const RenderRegion& vp) override;

View File

@ -122,7 +122,9 @@ static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* trans
Line cur = {dash.ptCur, *to}; Line cur = {dash.ptCur, *to};
auto len = _lineLength(cur.pt1, cur.pt2); auto len = _lineLength(cur.pt1, cur.pt2);
if (len < dash.curLen) { if (mathZero(len)) {
_outlineMoveTo(*dash.outline, &dash.ptCur, transform);
} else if (len < dash.curLen) {
dash.curLen -= len; dash.curLen -= len;
if (!dash.curOpGap) { if (!dash.curOpGap) {
if (dash.move) { if (dash.move) {
@ -179,7 +181,9 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct
Bezier cur = {dash.ptCur, *ctrl1, *ctrl2, *to}; Bezier cur = {dash.ptCur, *ctrl1, *ctrl2, *to};
auto len = bezLength(cur); auto len = bezLength(cur);
if (len < dash.curLen) { if (mathZero(len)) {
_outlineMoveTo(*dash.outline, &dash.ptCur, transform);
} else if (len < dash.curLen) {
dash.curLen -= len; dash.curLen -= len;
if (!dash.curOpGap) { if (!dash.curOpGap) {
if (dash.move) { if (dash.move) {

View File

@ -35,12 +35,28 @@ struct Canvas::Impl
Impl(RenderMethod* pRenderer) : renderer(pRenderer) Impl(RenderMethod* pRenderer) : renderer(pRenderer)
{ {
renderer->ref();
} }
~Impl() ~Impl()
{ {
clear(true); //make it sure any deffered jobs
delete(renderer); if (renderer) {
renderer->sync();
renderer->clear();
}
clearPaints();
if (renderer && (renderer->unref() == 0)) delete(renderer);
}
void clearPaints()
{
for (auto paint : paints) {
if (P(paint)->unref() == 0) delete(paint);
}
paints.clear();
} }
Result push(unique_ptr<Paint> paint) Result push(unique_ptr<Paint> paint)
@ -62,15 +78,8 @@ struct Canvas::Impl
if (!renderer || !renderer->clear()) return Result::InsufficientCondition; if (!renderer || !renderer->clear()) return Result::InsufficientCondition;
//Free paints //Free paints
if (free) { if (free) clearPaints();
for (auto paint : paints) {
P(paint)->unref();
if (paint->pImpl->dispose(*renderer) && P(paint)->refCnt == 0) {
delete(paint);
}
}
paints.clear();
}
drawing = false; drawing = false;
return Result::Success; return Result::Success;
@ -94,7 +103,7 @@ struct Canvas::Impl
//Optimize Me: Can we skip the searching? //Optimize Me: Can we skip the searching?
for (auto paint2 : paints) { for (auto paint2 : paints) {
if (paint2 == paint) { if (paint2 == paint) {
paint->pImpl->update(*renderer, nullptr, clips, 255, flag); paint->pImpl->update(renderer, nullptr, clips, 255, flag);
return Result::Success; return Result::Success;
} }
} }
@ -102,7 +111,7 @@ struct Canvas::Impl
//Update all retained paint nodes //Update all retained paint nodes
} else { } else {
for (auto paint : paints) { for (auto paint : paints) {
paint->pImpl->update(*renderer, nullptr, clips, 255, flag); paint->pImpl->update(renderer, nullptr, clips, 255, flag);
} }
} }
@ -117,7 +126,7 @@ struct Canvas::Impl
bool rendered = false; bool rendered = false;
for (auto paint : paints) { for (auto paint : paints) {
if (paint->pImpl->render(*renderer)) rendered = true; if (paint->pImpl->render(renderer)) rendered = true;
} }
if (!rendered || !renderer->postRender()) return Result::InsufficientCondition; if (!rendered || !renderer->postRender()) return Result::InsufficientCondition;

View File

@ -106,7 +106,7 @@ static bool _compFastTrack(Paint* cmpTarget, const RenderTransform* pTransform,
} }
RenderRegion Paint::Impl::bounds(RenderMethod& renderer) const RenderRegion Paint::Impl::bounds(RenderMethod* renderer) const
{ {
RenderRegion ret; RenderRegion ret;
PAINT_METHOD(ret, bounds(renderer)); PAINT_METHOD(ret, bounds(renderer));
@ -114,16 +114,6 @@ RenderRegion Paint::Impl::bounds(RenderMethod& renderer) const
} }
bool Paint::Impl::dispose(RenderMethod& renderer)
{
if (compData) compData->target->pImpl->dispose(renderer);
bool ret;
PAINT_METHOD(ret, dispose(renderer));
return ret;
}
Iterator* Paint::Impl::iterator() Iterator* Paint::Impl::iterator()
{ {
Iterator* ret; Iterator* ret;
@ -198,7 +188,7 @@ bool Paint::Impl::translate(float x, float y)
} }
bool Paint::Impl::render(RenderMethod& renderer) bool Paint::Impl::render(RenderMethod* renderer)
{ {
Compositor* cmp = nullptr; Compositor* cmp = nullptr;
@ -210,27 +200,33 @@ bool Paint::Impl::render(RenderMethod& renderer)
if (MASK_REGION_MERGING(compData->method)) region.add(P(compData->target)->bounds(renderer)); if (MASK_REGION_MERGING(compData->method)) region.add(P(compData->target)->bounds(renderer));
if (region.w == 0 || region.h == 0) return true; if (region.w == 0 || region.h == 0) return true;
cmp = renderer.target(region, COMPOSITE_TO_COLORSPACE(renderer, compData->method)); cmp = renderer->target(region, COMPOSITE_TO_COLORSPACE(renderer, compData->method));
if (renderer.beginComposite(cmp, CompositeMethod::None, 255)) { if (renderer->beginComposite(cmp, CompositeMethod::None, 255)) {
compData->target->pImpl->render(renderer); compData->target->pImpl->render(renderer);
} }
} }
if (cmp) renderer.beginComposite(cmp, compData->method, compData->target->pImpl->opacity); if (cmp) renderer->beginComposite(cmp, compData->method, compData->target->pImpl->opacity);
renderer.blend(blendMethod); renderer->blend(blendMethod);
bool ret; bool ret;
PAINT_METHOD(ret, render(renderer)); PAINT_METHOD(ret, render(renderer));
if (cmp) renderer.endComposite(cmp); if (cmp) renderer->endComposite(cmp);
return ret; return ret;
} }
RenderData Paint::Impl::update(RenderMethod& renderer, const RenderTransform* pTransform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) RenderData Paint::Impl::update(RenderMethod* renderer, const RenderTransform* pTransform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper)
{ {
if (this->renderer != renderer) {
if (this->renderer) TVGERR("RENDERER", "paint's renderer has been changed!");
renderer->ref();
this->renderer = renderer;
}
if (renderFlag & RenderUpdateFlag::Transform) { if (renderFlag & RenderUpdateFlag::Transform) {
if (!rTransform) return nullptr; if (!rTransform) return nullptr;
rTransform->update(); rTransform->update();
@ -265,9 +261,9 @@ RenderData Paint::Impl::update(RenderMethod& renderer, const RenderTransform* pT
if (tryFastTrack) { if (tryFastTrack) {
RenderRegion viewport2; RenderRegion viewport2;
if ((compFastTrack = _compFastTrack(target, pTransform, target->pImpl->rTransform, viewport2))) { if ((compFastTrack = _compFastTrack(target, pTransform, target->pImpl->rTransform, viewport2))) {
viewport = renderer.viewport(); viewport = renderer->viewport();
viewport2.intersect(viewport); viewport2.intersect(viewport);
renderer.viewport(viewport2); renderer->viewport(viewport2);
target->pImpl->ctxFlag |= ContextFlag::FastTrack; target->pImpl->ctxFlag |= ContextFlag::FastTrack;
} }
} }
@ -289,7 +285,7 @@ RenderData Paint::Impl::update(RenderMethod& renderer, const RenderTransform* pT
PAINT_METHOD(rd, update(renderer, &outTransform, clips, opacity, newFlag, clipper)); PAINT_METHOD(rd, update(renderer, &outTransform, clips, opacity, newFlag, clipper));
/* 3. Composition Post Processing */ /* 3. Composition Post Processing */
if (compFastTrack) renderer.viewport(viewport); if (compFastTrack) renderer->viewport(viewport);
else if (childClipper) clips.pop(); else if (childClipper) clips.pop();
return rd; return rd;

View File

@ -50,16 +50,15 @@ namespace tvg
Paint* paint = nullptr; Paint* paint = nullptr;
RenderTransform* rTransform = nullptr; RenderTransform* rTransform = nullptr;
Composite* compData = nullptr; Composite* compData = nullptr;
RenderMethod* renderer = nullptr;
BlendMethod blendMethod = BlendMethod::Normal; //uint8_t BlendMethod blendMethod = BlendMethod::Normal; //uint8_t
uint8_t renderFlag = RenderUpdateFlag::None; uint8_t renderFlag = RenderUpdateFlag::None;
uint8_t ctxFlag = ContextFlag::Invalid; uint8_t ctxFlag = ContextFlag::Invalid;
uint8_t id; uint8_t id;
uint8_t opacity = 255; uint8_t opacity = 255;
uint8_t refCnt = 0; uint8_t refCnt = 0; //reference count
Impl(Paint* pnt) : paint(pnt) Impl(Paint* pnt) : paint(pnt) {}
{
}
~Impl() ~Impl()
{ {
@ -68,18 +67,19 @@ namespace tvg
free(compData); free(compData);
} }
delete(rTransform); delete(rTransform);
if (renderer && (renderer->unref() == 0)) delete(renderer);
} }
uint8_t ref() uint8_t ref()
{ {
if (refCnt == 255) TVGERR("RENDERER", "Corrupted reference count!"); if (refCnt == 255) TVGERR("RENDERER", "Corrupted reference count!");
return (++refCnt); return ++refCnt;
} }
uint8_t unref() uint8_t unref()
{ {
if (refCnt == 0) TVGERR("RENDERER", "Corrupted reference count!"); if (refCnt == 0) TVGERR("RENDERER", "Corrupted reference count!");
return (--refCnt); return --refCnt;
} }
bool transform(const Matrix& m) bool transform(const Matrix& m)
@ -131,15 +131,14 @@ namespace tvg
return true; return true;
} }
RenderRegion bounds(RenderMethod& renderer) const; RenderRegion bounds(RenderMethod* renderer) const;
bool dispose(RenderMethod& renderer);
Iterator* iterator(); Iterator* iterator();
bool rotate(float degree); bool rotate(float degree);
bool scale(float factor); bool scale(float factor);
bool translate(float x, float y); bool translate(float x, float y);
bool bounds(float* x, float* y, float* w, float* h, bool transformed, bool stroking); bool bounds(float* x, float* y, float* w, float* h, bool transformed, bool stroking);
RenderData update(RenderMethod& renderer, const RenderTransform* pTransform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper = false); RenderData update(RenderMethod* renderer, const RenderTransform* pTransform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper = false);
bool render(RenderMethod& renderer); bool render(RenderMethod* renderer);
Paint* duplicate(); Paint* duplicate();
}; };
} }

View File

@ -69,18 +69,18 @@ bool Picture::Impl::needComposition(uint8_t opacity)
} }
bool Picture::Impl::render(RenderMethod &renderer) bool Picture::Impl::render(RenderMethod* renderer)
{ {
bool ret = false; bool ret = false;
if (surface) return renderer.renderImage(rd); if (surface) return renderer->renderImage(rd);
else if (paint) { else if (paint) {
Compositor* cmp = nullptr; Compositor* cmp = nullptr;
if (needComp) { if (needComp) {
cmp = renderer.target(bounds(renderer), renderer.colorSpace()); cmp = renderer->target(bounds(renderer), renderer->colorSpace());
renderer.beginComposite(cmp, CompositeMethod::None, 255); renderer->beginComposite(cmp, CompositeMethod::None, 255);
} }
ret = paint->pImpl->render(renderer); ret = paint->pImpl->render(renderer);
if (cmp) renderer.endComposite(cmp); if (cmp) renderer->endComposite(cmp);
} }
return ret; return ret;
} }
@ -95,9 +95,9 @@ bool Picture::Impl::size(float w, float h)
} }
RenderRegion Picture::Impl::bounds(RenderMethod& renderer) RenderRegion Picture::Impl::bounds(RenderMethod* renderer)
{ {
if (rd) return renderer.region(rd); if (rd) return renderer->region(rd);
if (paint) return paint->pImpl->bounds(renderer); if (paint) return paint->pImpl->bounds(renderer);
return {0, 0, 0, 0}; return {0, 0, 0, 0};
} }

View File

@ -70,9 +70,9 @@ struct Picture::Impl
RenderTransform resizeTransform(const RenderTransform* pTransform); RenderTransform resizeTransform(const RenderTransform* pTransform);
bool needComposition(uint8_t opacity); bool needComposition(uint8_t opacity);
bool render(RenderMethod &renderer); bool render(RenderMethod* renderer);
bool size(float w, float h); bool size(float w, float h);
RenderRegion bounds(RenderMethod& renderer); RenderRegion bounds(RenderMethod* renderer);
Result load(ImageLoader* ploader); Result load(ImageLoader* ploader);
Impl(Picture* p) : picture(p) Impl(Picture* p) : picture(p)
@ -82,24 +82,21 @@ struct Picture::Impl
~Impl() ~Impl()
{ {
LoaderMgr::retrieve(loader); LoaderMgr::retrieve(loader);
if (surface) {
if (auto renderer = PP(picture)->renderer) {
renderer->dispose(rd);
}
}
delete(paint); delete(paint);
} }
bool dispose(RenderMethod& renderer) RenderData update(RenderMethod* renderer, const RenderTransform* pTransform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper)
{
if (paint) paint->pImpl->dispose(renderer);
else if (surface) renderer.dispose(rd);
rd = nullptr;
return true;
}
RenderData update(RenderMethod &renderer, const RenderTransform* pTransform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper)
{ {
auto flag = load(); auto flag = load();
if (surface) { if (surface) {
auto transform = resizeTransform(pTransform); auto transform = resizeTransform(pTransform);
rd = renderer.prepare(surface, &rm, rd, &transform, clips, opacity, static_cast<RenderUpdateFlag>(pFlag | flag)); rd = renderer->prepare(surface, &rm, rd, &transform, clips, opacity, static_cast<RenderUpdateFlag>(pFlag | flag));
} else if (paint) { } else if (paint) {
if (resizing) { if (resizing) {
loader->resize(paint, w, h); loader->resize(paint, w, h);

View File

@ -261,7 +261,23 @@ struct RenderShape
class RenderMethod class RenderMethod
{ {
private:
uint32_t refCnt = 0; //reference count
Key key;
public: public:
uint32_t ref()
{
ScopedLock lock(key);
return (++refCnt);
}
uint32_t unref()
{
ScopedLock lock(key);
return (--refCnt);
}
virtual ~RenderMethod() {} virtual ~RenderMethod() {}
virtual RenderData prepare(const RenderShape& rshape, RenderData data, const RenderTransform* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) = 0; virtual RenderData prepare(const RenderShape& rshape, RenderData data, const RenderTransform* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) = 0;
virtual RenderData prepare(const Array<RenderData>& scene, RenderData data, const RenderTransform* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) = 0; virtual RenderData prepare(const Array<RenderData>& scene, RenderData data, const RenderTransform* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) = 0;
@ -270,7 +286,7 @@ public:
virtual bool renderShape(RenderData data) = 0; virtual bool renderShape(RenderData data) = 0;
virtual bool renderImage(RenderData data) = 0; virtual bool renderImage(RenderData data) = 0;
virtual bool postRender() = 0; virtual bool postRender() = 0;
virtual bool dispose(RenderData data) = 0; virtual void dispose(RenderData data) = 0;
virtual RenderRegion region(RenderData data) = 0; virtual RenderRegion region(RenderData data) = 0;
virtual RenderRegion viewport() = 0; virtual RenderRegion viewport() = 0;
virtual bool viewport(const RenderRegion& vp) = 0; virtual bool viewport(const RenderRegion& vp) = 0;
@ -322,7 +338,7 @@ static inline uint8_t CHANNEL_SIZE(ColorSpace cs)
} }
} }
static inline ColorSpace COMPOSITE_TO_COLORSPACE(RenderMethod& renderer, CompositeMethod method) static inline ColorSpace COMPOSITE_TO_COLORSPACE(RenderMethod* renderer, CompositeMethod method)
{ {
switch(method) { switch(method) {
case CompositeMethod::AlphaMask: case CompositeMethod::AlphaMask:
@ -335,7 +351,7 @@ static inline ColorSpace COMPOSITE_TO_COLORSPACE(RenderMethod& renderer, Composi
//TODO: Optimize Luma/InvLuma colorspace to Grayscale8 //TODO: Optimize Luma/InvLuma colorspace to Grayscale8
case CompositeMethod::LumaMask: case CompositeMethod::LumaMask:
case CompositeMethod::InvLumaMask: case CompositeMethod::InvLumaMask:
return renderer.colorSpace(); return renderer->colorSpace();
default: default:
TVGERR("RENDERER", "Unsupported Composite Size! = %d", (int)method); TVGERR("RENDERER", "Unsupported Composite Size! = %d", (int)method);
return ColorSpace::Unsupported; return ColorSpace::Unsupported;

View File

@ -59,7 +59,6 @@ struct SceneIterator : Iterator
struct Scene::Impl struct Scene::Impl
{ {
list<Paint*> paints; list<Paint*> paints;
RenderMethod* renderer = nullptr; //keep it for explicit clear
RenderData rd = nullptr; RenderData rd = nullptr;
Scene* scene = nullptr; Scene* scene = nullptr;
uint8_t opacity; //for composition uint8_t opacity; //for composition
@ -74,19 +73,10 @@ struct Scene::Impl
for (auto paint : paints) { for (auto paint : paints) {
if (P(paint)->unref() == 0) delete(paint); if (P(paint)->unref() == 0) delete(paint);
} }
if (auto renderer = PP(scene)->renderer) {
renderer->dispose(rd);
} }
bool dispose(RenderMethod& renderer)
{
for (auto paint : paints) {
paint->pImpl->dispose(renderer);
}
renderer.dispose(rd);
this->renderer = nullptr;
this->rd = nullptr;
return true;
} }
bool needComposition(uint8_t opacity) bool needComposition(uint8_t opacity)
@ -111,7 +101,7 @@ struct Scene::Impl
return true; return true;
} }
RenderData update(RenderMethod &renderer, const RenderTransform* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flag, bool clipper) RenderData update(RenderMethod* renderer, const RenderTransform* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flag, bool clipper)
{ {
if ((needComp = needComposition(opacity))) { if ((needComp = needComposition(opacity))) {
/* Overriding opacity value. If this scene is half-translucent, /* Overriding opacity value. If this scene is half-translucent,
@ -120,14 +110,12 @@ struct Scene::Impl
opacity = 255; opacity = 255;
} }
this->renderer = &renderer;
if (clipper) { if (clipper) {
Array<RenderData> rds(paints.size()); Array<RenderData> rds(paints.size());
for (auto paint : paints) { for (auto paint : paints) {
rds.push(paint->pImpl->update(renderer, transform, clips, opacity, flag, true)); rds.push(paint->pImpl->update(renderer, transform, clips, opacity, flag, true));
} }
rd = renderer.prepare(rds, rd, transform, clips, opacity, flag); rd = renderer->prepare(rds, rd, transform, clips, opacity, flag);
return rd; return rd;
} else { } else {
for (auto paint : paints) { for (auto paint : paints) {
@ -137,13 +125,13 @@ struct Scene::Impl
} }
} }
bool render(RenderMethod& renderer) bool render(RenderMethod* renderer)
{ {
Compositor* cmp = nullptr; Compositor* cmp = nullptr;
if (needComp) { if (needComp) {
cmp = renderer.target(bounds(renderer), renderer.colorSpace()); cmp = renderer->target(bounds(renderer), renderer->colorSpace());
renderer.beginComposite(cmp, CompositeMethod::None, opacity); renderer->beginComposite(cmp, CompositeMethod::None, opacity);
needComp = false; needComp = false;
} }
@ -151,12 +139,12 @@ struct Scene::Impl
if (!paint->pImpl->render(renderer)) return false; if (!paint->pImpl->render(renderer)) return false;
} }
if (cmp) renderer.endComposite(cmp); if (cmp) renderer->endComposite(cmp);
return true; return true;
} }
RenderRegion bounds(RenderMethod& renderer) const RenderRegion bounds(RenderMethod* renderer) const
{ {
if (paints.empty()) return {0, 0, 0, 0}; if (paints.empty()) return {0, 0, 0, 0};
@ -226,14 +214,10 @@ struct Scene::Impl
void clear(bool free) void clear(bool free)
{ {
auto dispose = renderer ? true : false;
for (auto paint : paints) { for (auto paint : paints) {
if (dispose) free &= P(paint)->dispose(*renderer);
if (P(paint)->unref() == 0 && free) delete(paint); if (P(paint)->unref() == 0 && free) delete(paint);
} }
paints.clear(); paints.clear();
renderer = nullptr;
} }
Iterator* iterator() Iterator* iterator()

View File

@ -41,25 +41,25 @@ struct Shape::Impl
{ {
} }
bool dispose(RenderMethod& renderer) ~Impl()
{ {
renderer.dispose(rd); if (auto renderer = PP(shape)->renderer) {
rd = nullptr; renderer->dispose(rd);
return true; }
} }
bool render(RenderMethod& renderer) bool render(RenderMethod* renderer)
{ {
Compositor* cmp = nullptr; Compositor* cmp = nullptr;
bool ret; bool ret;
if (needComp) { if (needComp) {
cmp = renderer.target(bounds(renderer), renderer.colorSpace()); cmp = renderer->target(bounds(renderer), renderer->colorSpace());
renderer.beginComposite(cmp, CompositeMethod::None, opacity); renderer->beginComposite(cmp, CompositeMethod::None, opacity);
needComp = false; needComp = false;
} }
ret = renderer.renderShape(rd); ret = renderer->renderShape(rd);
if (cmp) renderer.endComposite(cmp); if (cmp) renderer->endComposite(cmp);
return ret; return ret;
} }
@ -83,7 +83,7 @@ struct Shape::Impl
return true; return true;
} }
RenderData update(RenderMethod& renderer, const RenderTransform* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) RenderData update(RenderMethod* renderer, const RenderTransform* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper)
{ {
if ((needComp = needComposition(opacity))) { if ((needComp = needComposition(opacity))) {
/* Overriding opacity value. If this scene is half-translucent, /* Overriding opacity value. If this scene is half-translucent,
@ -92,14 +92,14 @@ struct Shape::Impl
opacity = 255; opacity = 255;
} }
rd = renderer.prepare(rs, rd, transform, clips, opacity, static_cast<RenderUpdateFlag>(pFlag | flag), clipper); rd = renderer->prepare(rs, rd, transform, clips, opacity, static_cast<RenderUpdateFlag>(pFlag | flag), clipper);
flag = RenderUpdateFlag::None; flag = RenderUpdateFlag::None;
return rd; return rd;
} }
RenderRegion bounds(RenderMethod& renderer) RenderRegion bounds(RenderMethod* renderer)
{ {
return renderer.region(rd); return renderer->region(rd);
} }
bool bounds(float* x, float* y, float* w, float* h, bool stroking) bool bounds(float* x, float* y, float* w, float* h, bool stroking)

View File

@ -35,7 +35,6 @@
struct Text::Impl struct Text::Impl
{ {
RenderData rd = nullptr;
FontLoader* loader = nullptr; FontLoader* loader = nullptr;
Shape* paint = nullptr; Shape* paint = nullptr;
char* utf8 = nullptr; char* utf8 = nullptr;
@ -92,12 +91,13 @@ struct Text::Impl
return Result::Success; return Result::Success;
} }
RenderRegion bounds(RenderMethod& renderer) RenderRegion bounds(RenderMethod* renderer)
{ {
return renderer.region(rd); if (paint) return P(paint)->bounds(renderer);
else return {0, 0, 0, 0};
} }
bool render(RenderMethod& renderer) bool render(RenderMethod* renderer)
{ {
if (paint) return PP(paint)->render(renderer); if (paint) return PP(paint)->render(renderer);
return false; return false;
@ -120,7 +120,7 @@ struct Text::Impl
return false; return false;
} }
RenderData update(RenderMethod& renderer, const RenderTransform* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) RenderData update(RenderMethod* renderer, const RenderTransform* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper)
{ {
if (!load()) return nullptr; if (!load()) return nullptr;
@ -142,8 +142,7 @@ struct Text::Impl
P(static_cast<RadialGradient*>(fill))->fr *= scale; P(static_cast<RadialGradient*>(fill))->fr *= scale;
} }
} }
rd = PP(paint)->update(renderer, transform, clips, opacity, pFlag, clipper); return PP(paint)->update(renderer, transform, clips, opacity, pFlag, clipper);
return rd;
} }
bool bounds(float* x, float* y, float* w, float* h, TVG_UNUSED bool stroking) bool bounds(float* x, float* y, float* w, float* h, TVG_UNUSED bool stroking)
@ -153,13 +152,6 @@ struct Text::Impl
return true; return true;
} }
bool dispose(RenderMethod& renderer)
{
renderer.dispose(rd);
this->rd = nullptr;
return true;
}
Paint* duplicate() Paint* duplicate()
{ {
load(); load();

View File

@ -1,6 +1,6 @@
#!/bin/bash -e #!/bin/bash -e
VERSION=0.12.3 VERSION=0.12.4
cd thirdparty/thorvg/ || true cd thirdparty/thorvg/ || true
rm -rf AUTHORS LICENSE inc/ src/ *.zip *.tar.gz tmp/ rm -rf AUTHORS LICENSE inc/ src/ *.zip *.tar.gz tmp/