mirror of
https://github.com/thorvg/thorvg.git
synced 2025-07-28 17:15:57 +00:00
common: enhance clipping behavior.
If a paint is used as a clipper, it must be determined in the paint behavior.
Propagate its decision to the immediate derived classes so that
not only shapes but also scenes must be dealt as a clipper properly.
This revised this change 0de3872be3
for better a solution.
This commit is contained in:
parent
6452f4a591
commit
d701f6dae4
10 changed files with 26 additions and 25 deletions
|
@ -197,7 +197,7 @@ RenderData GlRenderer::prepare(TVG_UNUSED Surface* image, TVG_UNUSED Polygon* tr
|
|||
}
|
||||
|
||||
|
||||
RenderData GlRenderer::prepare(const Shape& shape, RenderData data, const RenderTransform* transform, TVG_UNUSED uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags)
|
||||
RenderData GlRenderer::prepare(const Shape& shape, RenderData data, const RenderTransform* transform, TVG_UNUSED uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags, TVG_UNUSED bool clipper)
|
||||
{
|
||||
//prepare shape data
|
||||
GlShape* sdata = static_cast<GlShape*>(data);
|
||||
|
|
|
@ -30,7 +30,7 @@ class GlRenderer : public RenderMethod
|
|||
public:
|
||||
Surface surface = {nullptr, 0, 0, 0};
|
||||
|
||||
RenderData prepare(const Shape& shape, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags) override;
|
||||
RenderData prepare(const Shape& shape, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags, bool clipper) override;
|
||||
RenderData prepare(Surface* image, Polygon* triangles, uint32_t triangleCnt, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags) override;
|
||||
bool preRender() override;
|
||||
bool renderShape(RenderData data) override;
|
||||
|
|
|
@ -74,12 +74,11 @@ struct SwShapeTask : SwTask
|
|||
SwShape shape;
|
||||
const Shape* sdata = nullptr;
|
||||
bool cmpStroking = false;
|
||||
bool clipper = false;
|
||||
|
||||
void run(unsigned tid) override
|
||||
{
|
||||
auto compMethod = CompositeMethod::None;
|
||||
auto usedAsClip = (sdata->composite(nullptr, &compMethod) == Result::Success) && (compMethod == CompositeMethod::ClipPath);
|
||||
if (opacity == 0 && !usedAsClip) return; //Invisible
|
||||
if (opacity == 0 && !clipper) return; //Invisible
|
||||
|
||||
uint8_t strokeAlpha = 0;
|
||||
auto visibleStroke = false;
|
||||
|
@ -101,7 +100,7 @@ struct SwShapeTask : SwTask
|
|||
sdata->fillColor(nullptr, nullptr, nullptr, &alpha);
|
||||
alpha = static_cast<uint8_t>(static_cast<uint32_t>(alpha) * opacity / 255);
|
||||
visibleFill = (alpha > 0 || sdata->fill());
|
||||
if (visibleFill || visibleStroke || usedAsClip) {
|
||||
if (visibleFill || visibleStroke || clipper) {
|
||||
shapeReset(&shape);
|
||||
if (!shapePrepare(&shape, sdata, transform, clipRegion, bbox, mpool, tid, clips.count > 0 ? true : false)) goto err;
|
||||
}
|
||||
|
@ -113,7 +112,7 @@ struct SwShapeTask : SwTask
|
|||
|
||||
//Fill
|
||||
if (flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) {
|
||||
if (visibleFill || usedAsClip) {
|
||||
if (visibleFill || clipper) {
|
||||
/* We assume that if stroke width is bigger than 2,
|
||||
shape outline below stroke could be full covered by stroke drawing.
|
||||
Thus it turns off antialising in that condition.
|
||||
|
@ -644,13 +643,14 @@ RenderData SwRenderer::prepare(Surface* image, Polygon* triangles, uint32_t tria
|
|||
}
|
||||
|
||||
|
||||
RenderData SwRenderer::prepare(const Shape& sdata, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags)
|
||||
RenderData SwRenderer::prepare(const Shape& sdata, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags, bool clipper)
|
||||
{
|
||||
//prepare task
|
||||
auto task = static_cast<SwShapeTask*>(data);
|
||||
if (!task) {
|
||||
task = new SwShapeTask;
|
||||
task->sdata = &sdata;
|
||||
task->clipper = clipper;
|
||||
}
|
||||
return prepareCommon(task, transform, opacity, clips, flags);
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace tvg
|
|||
class SwRenderer : public RenderMethod
|
||||
{
|
||||
public:
|
||||
RenderData prepare(const Shape& shape, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags) override;
|
||||
RenderData prepare(const Shape& shape, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags, bool clipper) override;
|
||||
RenderData prepare(Surface* image, Polygon* triangles, uint32_t triangleCnt, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags) override;
|
||||
bool preRender() override;
|
||||
bool renderShape(RenderData data) override;
|
||||
|
|
|
@ -184,7 +184,7 @@ bool Paint::Impl::render(RenderMethod& renderer)
|
|||
}
|
||||
|
||||
|
||||
void* Paint::Impl::update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t opacity, Array<RenderData>& clips, uint32_t pFlag)
|
||||
void* Paint::Impl::update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t opacity, Array<RenderData>& clips, uint32_t pFlag, bool clipper)
|
||||
{
|
||||
if (renderFlag & RenderUpdateFlag::Transform) {
|
||||
if (!rTransform) return nullptr;
|
||||
|
@ -224,7 +224,8 @@ void* Paint::Impl::update(RenderMethod& renderer, const RenderTransform* pTransf
|
|||
}
|
||||
}
|
||||
if (!compFastTrack) {
|
||||
tdata = target->pImpl->update(renderer, pTransform, 255, clips, pFlag);
|
||||
auto clipper = compData->method == CompositeMethod::ClipPath ? true : false;
|
||||
tdata = target->pImpl->update(renderer, pTransform, 255, clips, pFlag, clipper);
|
||||
if (method == CompositeMethod::ClipPath) clips.push(tdata);
|
||||
}
|
||||
}
|
||||
|
@ -237,10 +238,10 @@ void* Paint::Impl::update(RenderMethod& renderer, const RenderTransform* pTransf
|
|||
|
||||
if (rTransform && pTransform) {
|
||||
RenderTransform outTransform(pTransform, rTransform);
|
||||
edata = smethod->update(renderer, &outTransform, opacity, clips, newFlag);
|
||||
edata = smethod->update(renderer, &outTransform, opacity, clips, newFlag, clipper);
|
||||
} else {
|
||||
auto outTransform = pTransform ? pTransform : rTransform;
|
||||
edata = smethod->update(renderer, outTransform, opacity, clips, newFlag);
|
||||
edata = smethod->update(renderer, outTransform, opacity, clips, newFlag, clipper);
|
||||
}
|
||||
|
||||
/* 3. Composition Post Processing */
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace tvg
|
|||
virtual ~StrategyMethod() {}
|
||||
|
||||
virtual bool dispose(RenderMethod& renderer) = 0;
|
||||
virtual void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag pFlag) = 0; //Return engine data if it has.
|
||||
virtual void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag pFlag, bool clipper) = 0; //Return engine data if it has.
|
||||
virtual bool render(RenderMethod& renderer) = 0;
|
||||
virtual bool bounds(float* x, float* y, float* w, float* h) = 0;
|
||||
virtual RenderRegion bounds(RenderMethod& renderer) const = 0;
|
||||
|
@ -149,7 +149,7 @@ namespace tvg
|
|||
bool scale(float factor);
|
||||
bool translate(float x, float y);
|
||||
bool bounds(float* x, float* y, float* w, float* h, bool transformed);
|
||||
void* update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t opacity, Array<RenderData>& clips, uint32_t pFlag);
|
||||
void* update(RenderMethod& renderer, const RenderTransform* pTransform, uint32_t opacity, Array<RenderData>& clips, uint32_t pFlag, bool clipper = false);
|
||||
bool render(RenderMethod& renderer);
|
||||
Paint* duplicate();
|
||||
};
|
||||
|
@ -178,9 +178,9 @@ namespace tvg
|
|||
return inst->dispose(renderer);
|
||||
}
|
||||
|
||||
void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag renderFlag) override
|
||||
void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag renderFlag, bool clipper) override
|
||||
{
|
||||
return inst->update(renderer, transform, opacity, clips, renderFlag);
|
||||
return inst->update(renderer, transform, opacity, clips, renderFlag, clipper);
|
||||
}
|
||||
|
||||
bool render(RenderMethod& renderer) override
|
||||
|
|
|
@ -126,7 +126,7 @@ struct Picture::Impl
|
|||
else return RenderTransform(pTransform, &tmp);
|
||||
}
|
||||
|
||||
void* update(RenderMethod &renderer, const RenderTransform* pTransform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag pFlag)
|
||||
void* update(RenderMethod &renderer, const RenderTransform* pTransform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag pFlag, bool clipper)
|
||||
{
|
||||
auto flag = reload();
|
||||
|
||||
|
@ -138,7 +138,7 @@ struct Picture::Impl
|
|||
loader->resize(paint, w, h);
|
||||
resizing = false;
|
||||
}
|
||||
rdata = paint->pImpl->update(renderer, pTransform, opacity, clips, static_cast<RenderUpdateFlag>(pFlag | flag));
|
||||
rdata = paint->pImpl->update(renderer, pTransform, opacity, clips, static_cast<RenderUpdateFlag>(pFlag | flag), clipper);
|
||||
}
|
||||
return rdata;
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ class RenderMethod
|
|||
{
|
||||
public:
|
||||
virtual ~RenderMethod() {}
|
||||
virtual RenderData prepare(const Shape& shape, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags) = 0;
|
||||
virtual RenderData prepare(const Shape& shape, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags, bool clipper) = 0;
|
||||
virtual RenderData prepare(Surface* image, Polygon* triangles, uint32_t triangleCnt, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags) = 0;
|
||||
virtual bool preRender() = 0;
|
||||
virtual bool renderShape(RenderData data) = 0;
|
||||
|
|
|
@ -102,7 +102,7 @@ struct Scene::Impl
|
|||
return false;
|
||||
}
|
||||
|
||||
void* update(RenderMethod &renderer, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flag)
|
||||
void* update(RenderMethod &renderer, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flag, bool clipper)
|
||||
{
|
||||
/* Overriding opacity value. If this scene is half-translucent,
|
||||
It must do intermeidate composition with that opacity value. */
|
||||
|
@ -110,7 +110,7 @@ struct Scene::Impl
|
|||
if (needComposition(opacity)) opacity = 255;
|
||||
|
||||
for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) {
|
||||
(*paint)->pImpl->update(renderer, transform, opacity, clips, static_cast<uint32_t>(flag));
|
||||
(*paint)->pImpl->update(renderer, transform, opacity, clips, static_cast<uint32_t>(flag), clipper);
|
||||
}
|
||||
|
||||
/* FXIME: it requires to return list of children engine data
|
||||
|
|
|
@ -235,9 +235,9 @@ struct Shape::Impl
|
|||
return renderer.renderShape(rdata);
|
||||
}
|
||||
|
||||
void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag pFlag)
|
||||
void* update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag pFlag, bool clipper)
|
||||
{
|
||||
this->rdata = renderer.prepare(*shape, this->rdata, transform, opacity, clips, static_cast<RenderUpdateFlag>(pFlag | flag));
|
||||
this->rdata = renderer.prepare(*shape, this->rdata, transform, opacity, clips, static_cast<RenderUpdateFlag>(pFlag | flag), clipper);
|
||||
flag = RenderUpdateFlag::None;
|
||||
return this->rdata;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue