diff options
Diffstat (limited to 'thirdparty/thorvg/src/renderer/tvgPaint.cpp')
-rw-r--r-- | thirdparty/thorvg/src/renderer/tvgPaint.cpp | 142 |
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; |