mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-07 21:23:32 +00:00
renderer: fixed a clippging update isssue
ThorVG did not consider updates to the clipping path when a paint object was modified after being added to the scene. This fix ensures that any updates to clipping are correctly reflected during rendering. issue: https://github.com/thorvg/thorvg/issues/3403
This commit is contained in:
parent
8b2024a8f4
commit
1b37743b2c
5 changed files with 35 additions and 40 deletions
|
@ -118,53 +118,40 @@ struct SwShapeTask : SwTask
|
|||
|
||||
auto strokeWidth = validStrokeWidth();
|
||||
SwBBox renderRegion{};
|
||||
auto visibleFill = false;
|
||||
|
||||
//This checks also for the case, if the invisible shape turned to visible by alpha.
|
||||
auto prepareShape = !shapePrepared(&shape) && flags & (RenderUpdateFlag::Color | RenderUpdateFlag::Gradient);
|
||||
auto updateShape = (RenderUpdateFlag::Path | RenderUpdateFlag::Transform | RenderUpdateFlag::Clip);
|
||||
auto updateFill = false;
|
||||
|
||||
//Shape
|
||||
if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Transform) || prepareShape) {
|
||||
if (updateShape || flags & (RenderUpdateFlag::Color | RenderUpdateFlag::Gradient)) {
|
||||
uint8_t alpha = 0;
|
||||
rshape->fillColor(nullptr, nullptr, nullptr, &alpha);
|
||||
alpha = MULTIPLY(alpha, opacity);
|
||||
visibleFill = (alpha > 0 || rshape->fill);
|
||||
shapeReset(&shape);
|
||||
if (visibleFill || clipper) {
|
||||
if (!shapePrepare(&shape, rshape, transform, bbox, renderRegion, mpool, tid, clips.count > 0 ? true : false)) {
|
||||
visibleFill = false;
|
||||
updateFill = (MULTIPLY(alpha, opacity) || rshape->fill);
|
||||
if (updateShape) shapeReset(&shape);
|
||||
if (updateFill || clipper) {
|
||||
if (shapePrepare(&shape, rshape, transform, bbox, renderRegion, mpool, tid, clips.count > 0 ? true : false)) {
|
||||
if (!shapeGenRle(&shape, rshape, antialiasing(strokeWidth))) goto err;
|
||||
} else {
|
||||
updateFill = false;
|
||||
renderRegion.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
//Fill
|
||||
if (flags & (RenderUpdateFlag::Path |RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) {
|
||||
if (visibleFill || clipper) {
|
||||
if (!shapeGenRle(&shape, rshape, antialiasing(strokeWidth))) goto err;
|
||||
}
|
||||
if (updateFill) {
|
||||
if (auto fill = rshape->fill) {
|
||||
auto ctable = (flags & RenderUpdateFlag::Gradient) ? true : false;
|
||||
if (ctable) shapeResetFill(&shape);
|
||||
if (!shapeGenFillColors(&shape, fill, transform, surface, opacity, ctable)) goto err;
|
||||
} else {
|
||||
shapeDelFill(&shape);
|
||||
}
|
||||
}
|
||||
//Stroke
|
||||
if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) {
|
||||
if (strokeWidth > 0.0f) {
|
||||
shapeResetStroke(&shape, rshape, transform);
|
||||
|
||||
if (!shapeGenStrokeRle(&shape, rshape, transform, bbox, renderRegion, mpool, tid)) goto err;
|
||||
if (auto fill = rshape->strokeFill()) {
|
||||
auto ctable = (flags & RenderUpdateFlag::GradientStroke) ? true : false;
|
||||
if (ctable) shapeResetStrokeFill(&shape);
|
||||
if (!shapeGenStrokeFillColors(&shape, fill, transform, surface, opacity, ctable)) goto err;
|
||||
} else {
|
||||
shapeDelStrokeFill(&shape);
|
||||
}
|
||||
} else {
|
||||
shapeDelStroke(&shape);
|
||||
if ((updateShape || flags & RenderUpdateFlag::Stroke) && (strokeWidth > 0.0f)) {
|
||||
shapeResetStroke(&shape, rshape, transform);
|
||||
if (!shapeGenStrokeRle(&shape, rshape, transform, bbox, renderRegion, mpool, tid)) goto err;
|
||||
if (auto fill = rshape->strokeFill()) {
|
||||
auto ctable = (flags & RenderUpdateFlag::GradientStroke) ? true : false;
|
||||
if (ctable) shapeResetStrokeFill(&shape);
|
||||
if (!shapeGenStrokeFillColors(&shape, fill, transform, surface, opacity, ctable)) goto err;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -276,16 +276,19 @@ RenderData Paint::Impl::update(RenderMethod* renderer, const Matrix& pm, Array<R
|
|||
|
||||
/* 2. Clipping */
|
||||
if (this->clipper) {
|
||||
P(this->clipper)->ctxFlag &= ~ContextFlag::FastTrack; //reset
|
||||
auto pclip = P(this->clipper);
|
||||
if (pclip->renderFlag | static_cast<Shape*>(this->clipper)->pImpl->rFlag) renderFlag |= RenderUpdateFlag::Clip;
|
||||
pclip->ctxFlag &= ~ContextFlag::FastTrack; //reset
|
||||
viewport = renderer->viewport();
|
||||
/* TODO: Intersect the clipper's clipper, if both are FastTrack.
|
||||
Update the subsequent clipper first and check its ctxFlag. */
|
||||
if (!P(this->clipper)->clipper && (compFastTrack = _compFastTrack(renderer, this->clipper, pm, viewport)) == Result::Success) {
|
||||
P(this->clipper)->ctxFlag |= ContextFlag::FastTrack;
|
||||
}
|
||||
if (compFastTrack == Result::InsufficientCondition) {
|
||||
trd = P(this->clipper)->update(renderer, pm, clips, 255, pFlag, true);
|
||||
if (!pclip->clipper && _compFastTrack(renderer, this->clipper, pm, viewport) == Result::Success) {
|
||||
pclip->ctxFlag |= ContextFlag::FastTrack;
|
||||
compFastTrack = Result::Success;
|
||||
} else {
|
||||
trd = pclip->update(renderer, pm, clips, 255, pFlag, true);
|
||||
clips.push(trd);
|
||||
compFastTrack = Result::InsufficientCondition;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -72,8 +72,8 @@ namespace tvg
|
|||
tvg::rotate(&m, degree);
|
||||
}
|
||||
} tr;
|
||||
RenderUpdateFlag renderFlag = RenderUpdateFlag::None;
|
||||
BlendMethod blendMethod;
|
||||
uint8_t renderFlag;
|
||||
uint8_t ctxFlag;
|
||||
uint8_t opacity;
|
||||
uint8_t refCnt = 0; //reference count
|
||||
|
|
|
@ -37,9 +37,14 @@ using pixel_t = uint32_t;
|
|||
|
||||
#define DASH_PATTERN_THRESHOLD 0.001f
|
||||
|
||||
enum RenderUpdateFlag : uint8_t {None = 0, Path = 1, Color = 2, Gradient = 4, Stroke = 8, Transform = 16, Image = 32, GradientStroke = 64, Blend = 128, All = 255};
|
||||
enum RenderUpdateFlag : uint16_t {None = 0, Path = 1, Color = 2, Gradient = 4, Stroke = 8, Transform = 16, Image = 32, GradientStroke = 64, Blend = 128, Clip = 256, All = 0xffff};
|
||||
enum CompositionFlag : uint8_t {Invalid = 0, Opacity = 1, Blending = 2, Masking = 4, PostProcessing = 8}; //Composition Purpose
|
||||
|
||||
static inline void operator|=(RenderUpdateFlag& a, const RenderUpdateFlag b)
|
||||
{
|
||||
a = RenderUpdateFlag(uint16_t(a) | uint16_t(b));
|
||||
}
|
||||
|
||||
//TODO: Move this in public header unifying with SwCanvas::Colorspace
|
||||
enum ColorSpace : uint8_t
|
||||
{
|
||||
|
|
|
@ -33,7 +33,7 @@ struct Shape::Impl
|
|||
RenderShape rs; //shape data
|
||||
RenderData rd = nullptr; //engine data
|
||||
Shape* shape;
|
||||
uint8_t rFlag = RenderUpdateFlag::None;
|
||||
RenderUpdateFlag rFlag = RenderUpdateFlag::None;
|
||||
uint8_t cFlag = CompositionFlag::Invalid;
|
||||
uint8_t opacity; //for composition
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue