summaryrefslogtreecommitdiffstats
path: root/thirdparty/thorvg/src/renderer/tvgPaint.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/thorvg/src/renderer/tvgPaint.cpp')
-rw-r--r--thirdparty/thorvg/src/renderer/tvgPaint.cpp142
1 files changed, 72 insertions, 70 deletions
diff --git a/thirdparty/thorvg/src/renderer/tvgPaint.cpp b/thirdparty/thorvg/src/renderer/tvgPaint.cpp
index 0ce6540f20..11cee0c54a 100644
--- a/thirdparty/thorvg/src/renderer/tvgPaint.cpp
+++ b/thirdparty/thorvg/src/renderer/tvgPaint.cpp
@@ -41,7 +41,7 @@
}
-static Result _clipRect(RenderMethod* renderer, const Point* pts, const RenderTransform* pTransform, RenderTransform* rTransform, RenderRegion& before)
+static Result _clipRect(RenderMethod* renderer, const Point* pts, const Matrix& pm, const Matrix& rm, RenderRegion& before)
{
//sorting
Point tmp[4];
@@ -50,8 +50,8 @@ static Result _clipRect(RenderMethod* renderer, const Point* pts, const RenderTr
for (int i = 0; i < 4; ++i) {
tmp[i] = pts[i];
- if (rTransform) tmp[i] *= rTransform->m;
- if (pTransform) tmp[i] *= pTransform->m;
+ tmp[i] *= rm;
+ tmp[i] *= pm;
if (tmp[i].x < min.x) min.x = tmp[i].x;
if (tmp[i].x > max.x) max.x = tmp[i].x;
if (tmp[i].y < min.y) min.y = tmp[i].y;
@@ -73,7 +73,7 @@ static Result _clipRect(RenderMethod* renderer, const Point* pts, const RenderTr
}
-static Result _compFastTrack(RenderMethod* renderer, Paint* cmpTarget, const RenderTransform* pTransform, RenderTransform* rTransform, RenderRegion& before)
+static Result _compFastTrack(RenderMethod* renderer, Paint* cmpTarget, const Matrix& pm, RenderRegion& before)
{
/* Access Shape class by Paint is bad... but it's ok still it's an internal usage. */
auto shape = static_cast<Shape*>(cmpTarget);
@@ -84,18 +84,17 @@ static Result _compFastTrack(RenderMethod* renderer, Paint* cmpTarget, const Ren
//nothing to clip
if (ptsCnt == 0) return Result::InvalidArguments;
-
if (ptsCnt != 4) return Result::InsufficientCondition;
- if (rTransform && (cmpTarget->pImpl->renderFlag & RenderUpdateFlag::Transform)) rTransform->update();
+ auto& rm = P(cmpTarget)->transform();
//No rotation and no skewing, still can try out clipping the rect region.
auto tryClip = false;
- if (pTransform && (!mathRightAngle(&pTransform->m) || mathSkewed(&pTransform->m))) tryClip = true;
- if (rTransform && (!mathRightAngle(&rTransform->m) || mathSkewed(&rTransform->m))) tryClip = true;
+ if ((!mathRightAngle(pm) || mathSkewed(pm))) tryClip = true;
+ if ((!mathRightAngle(rm) || mathSkewed(rm))) tryClip = true;
- if (tryClip) return _clipRect(renderer, pts, pTransform, rTransform, before);
+ if (tryClip) return _clipRect(renderer, pts, pm, rm, before);
//Perpendicular Rectangle?
auto pt1 = pts + 0;
@@ -110,16 +109,10 @@ static Result _compFastTrack(RenderMethod* renderer, Paint* cmpTarget, const Ren
auto v1 = *pt1;
auto v2 = *pt3;
-
- if (rTransform) {
- v1 *= rTransform->m;
- v2 *= rTransform->m;
- }
-
- if (pTransform) {
- v1 *= pTransform->m;
- v2 *= pTransform->m;
- }
+ v1 *= rm;
+ v2 *= rm;
+ v1 *= pm;
+ v2 *= pm;
//sorting
if (v1.x > v2.x) std::swap(v1.x, v2.x);
@@ -158,17 +151,15 @@ Iterator* Paint::Impl::iterator()
}
-Paint* Paint::Impl::duplicate()
+Paint* Paint::Impl::duplicate(Paint* ret)
{
- Paint* ret;
- PAINT_METHOD(ret, duplicate());
+ if (ret) ret->composite(nullptr, CompositeMethod::None);
+
+ PAINT_METHOD(ret, duplicate(ret));
//duplicate Transform
- if (rTransform) {
- ret->pImpl->rTransform = new RenderTransform();
- *ret->pImpl->rTransform = *rTransform;
- ret->pImpl->renderFlag |= RenderUpdateFlag::Transform;
- }
+ ret->pImpl->tr = tr;
+ ret->pImpl->renderFlag |= RenderUpdateFlag::Transform;
ret->pImpl->opacity = opacity;
@@ -180,14 +171,9 @@ Paint* Paint::Impl::duplicate()
bool Paint::Impl::rotate(float degree)
{
- if (rTransform) {
- if (rTransform->overriding) return false;
- if (mathEqual(degree, rTransform->degree)) return true;
- } else {
- if (mathZero(degree)) return true;
- rTransform = new RenderTransform();
- }
- rTransform->degree = degree;
+ if (tr.overriding) return false;
+ if (mathEqual(degree, tr.degree)) return true;
+ tr.degree = degree;
renderFlag |= RenderUpdateFlag::Transform;
return true;
@@ -196,14 +182,9 @@ bool Paint::Impl::rotate(float degree)
bool Paint::Impl::scale(float factor)
{
- if (rTransform) {
- if (rTransform->overriding) return false;
- if (mathEqual(factor, rTransform->scale)) return true;
- } else {
- if (mathEqual(factor, 1.0f)) return true;
- rTransform = new RenderTransform();
- }
- rTransform->scale = factor;
+ if (tr.overriding) return false;
+ if (mathEqual(factor, tr.scale)) return true;
+ tr.scale = factor;
renderFlag |= RenderUpdateFlag::Transform;
return true;
@@ -212,15 +193,10 @@ bool Paint::Impl::scale(float factor)
bool Paint::Impl::translate(float x, float y)
{
- if (rTransform) {
- if (rTransform->overriding) return false;
- if (mathEqual(x, rTransform->m.e13) && mathEqual(y, rTransform->m.e23)) return true;
- } else {
- if (mathZero(x) && mathZero(y)) return true;
- rTransform = new RenderTransform();
- }
- rTransform->m.e13 = x;
- rTransform->m.e23 = y;
+ if (tr.overriding) return false;
+ if (mathEqual(x, tr.m.e13) && mathEqual(y, tr.m.e23)) return true;
+ tr.m.e13 = x;
+ tr.m.e23 = y;
renderFlag |= RenderUpdateFlag::Transform;
return true;
@@ -229,6 +205,8 @@ bool Paint::Impl::translate(float x, float y)
bool Paint::Impl::render(RenderMethod* renderer)
{
+ if (opacity == 0) return true;
+
Compositor* cmp = nullptr;
/* Note: only ClipPath is processed in update() step.
@@ -258,7 +236,7 @@ bool Paint::Impl::render(RenderMethod* renderer)
}
-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 Matrix& pm, 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!");
@@ -266,7 +244,7 @@ RenderData Paint::Impl::update(RenderMethod* renderer, const RenderTransform* pT
this->renderer = renderer;
}
- if (renderFlag & RenderUpdateFlag::Transform) rTransform->update();
+ if (renderFlag & RenderUpdateFlag::Transform) tr.update();
/* 1. Composition Pre Processing */
RenderData trd = nullptr; //composite target render data
@@ -277,7 +255,7 @@ RenderData Paint::Impl::update(RenderMethod* renderer, const RenderTransform* pT
if (compData) {
auto target = compData->target;
auto method = compData->method;
- target->pImpl->ctxFlag &= ~ContextFlag::FastTrack; //reset
+ P(target)->ctxFlag &= ~ContextFlag::FastTrack; //reset
/* If the transformation has no rotational factors and the ClipPath/Alpha(InvAlpha)Masking involves a simple rectangle,
we can optimize by using the viewport instead of the regular ClipPath/AlphaMasking sequence for improved performance. */
@@ -296,14 +274,14 @@ RenderData Paint::Impl::update(RenderMethod* renderer, const RenderTransform* pT
}
if (tryFastTrack) {
viewport = renderer->viewport();
- if ((compFastTrack = _compFastTrack(renderer, target, pTransform, target->pImpl->rTransform, viewport)) == Result::Success) {
- target->pImpl->ctxFlag |= ContextFlag::FastTrack;
+ if ((compFastTrack = _compFastTrack(renderer, target, pm, viewport)) == Result::Success) {
+ P(target)->ctxFlag |= ContextFlag::FastTrack;
}
}
}
if (compFastTrack == Result::InsufficientCondition) {
childClipper = compData->method == CompositeMethod::ClipPath ? true : false;
- trd = target->pImpl->update(renderer, pTransform, clips, 255, pFlag, childClipper);
+ trd = P(target)->update(renderer, pm, clips, 255, pFlag, childClipper);
if (childClipper) clips.push(trd);
}
}
@@ -314,8 +292,9 @@ RenderData Paint::Impl::update(RenderMethod* renderer, const RenderTransform* pT
opacity = MULTIPLY(opacity, this->opacity);
RenderData rd = nullptr;
- RenderTransform outTransform(pTransform, rTransform);
- PAINT_METHOD(rd, update(renderer, &outTransform, clips, opacity, newFlag, clipper));
+
+ tr.cm = pm * tr.m;
+ PAINT_METHOD(rd, update(renderer, tr.cm, clips, opacity, newFlag, clipper));
/* 3. Composition Post Processing */
if (compFastTrack == Result::Success) renderer->viewport(viewport);
@@ -325,13 +304,13 @@ RenderData Paint::Impl::update(RenderMethod* renderer, const RenderTransform* pT
}
-bool Paint::Impl::bounds(float* x, float* y, float* w, float* h, bool transformed, bool stroking)
+bool Paint::Impl::bounds(float* x, float* y, float* w, float* h, bool transformed, bool stroking, bool origin)
{
- Matrix* m = nullptr;
bool ret;
+ const auto& m = this->transform(origin);
//Case: No transformed, quick return!
- if (!transformed || !(m = this->transform())) {
+ if (!transformed || mathIdentity(&m)) {
PAINT_METHOD(ret, bounds(x, y, w, h, stroking));
return ret;
}
@@ -355,7 +334,7 @@ bool Paint::Impl::bounds(float* x, float* y, float* w, float* h, bool transforme
//Compute the AABB after transformation
for (int i = 0; i < 4; i++) {
- pt[i] *= *m;
+ pt[i] *= m;
if (pt[i].x < x1) x1 = pt[i].x;
if (pt[i].x > x2) x2 = pt[i].x;
@@ -372,6 +351,26 @@ bool Paint::Impl::bounds(float* x, float* y, float* w, float* h, bool transforme
}
+void Paint::Impl::reset()
+{
+ if (compData) {
+ if (P(compData->target)->unref() == 0) delete(compData->target);
+ free(compData);
+ compData = nullptr;
+ }
+ mathIdentity(&tr.m);
+ tr.degree = 0.0f;
+ tr.scale = 1.0f;
+ tr.overriding = false;
+
+ blendMethod = BlendMethod::Normal;
+ renderFlag = RenderUpdateFlag::None;
+ ctxFlag = ContextFlag::Invalid;
+ opacity = 255;
+ paint->id = 0;
+}
+
+
/************************************************************************/
/* External Class Implementation */
/************************************************************************/
@@ -417,9 +416,7 @@ Result Paint::transform(const Matrix& m) noexcept
Matrix Paint::transform() noexcept
{
- auto pTransform = pImpl->transform();
- if (pTransform) return *pTransform;
- return {1, 0, 0, 0, 1, 0, 0, 0, 1};
+ return pImpl->transform();
}
@@ -429,9 +426,9 @@ TVG_DEPRECATED Result Paint::bounds(float* x, float* y, float* w, float* h) cons
}
-Result Paint::bounds(float* x, float* y, float* w, float* h, bool transform) const noexcept
+Result Paint::bounds(float* x, float* y, float* w, float* h, bool transformed) const noexcept
{
- if (pImpl->bounds(x, y, w, h, transform, true)) return Result::Success;
+ if (pImpl->bounds(x, y, w, h, transformed, true, transformed)) return Result::Success;
return Result::InsufficientCondition;
}
@@ -444,6 +441,11 @@ Paint* Paint::duplicate() const noexcept
Result Paint::composite(std::unique_ptr<Paint> target, CompositeMethod method) noexcept
{
+ if (method == CompositeMethod::ClipPath && target && target->identifier() != TVG_CLASS_ID_SHAPE) {
+ TVGERR("RENDERER", "ClipPath only allows the Shape!");
+ return Result::NonSupport;
+ }
+
auto p = target.release();
if (pImpl->composite(this, p, method)) return Result::Success;
delete(p);
@@ -486,7 +488,7 @@ uint32_t Paint::identifier() const noexcept
}
-Result Paint::blend(BlendMethod method) const noexcept
+Result Paint::blend(BlendMethod method) noexcept
{
if (pImpl->blendMethod != method) {
pImpl->blendMethod = method;