|
@@ -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;
|