mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 05:33:36 +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();
|
auto strokeWidth = validStrokeWidth();
|
||||||
SwBBox renderRegion{};
|
SwBBox renderRegion{};
|
||||||
auto visibleFill = false;
|
auto updateShape = (RenderUpdateFlag::Path | RenderUpdateFlag::Transform | RenderUpdateFlag::Clip);
|
||||||
|
auto updateFill = 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);
|
|
||||||
|
|
||||||
//Shape
|
//Shape
|
||||||
if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Transform) || prepareShape) {
|
if (updateShape || flags & (RenderUpdateFlag::Color | RenderUpdateFlag::Gradient)) {
|
||||||
uint8_t alpha = 0;
|
uint8_t alpha = 0;
|
||||||
rshape->fillColor(nullptr, nullptr, nullptr, &alpha);
|
rshape->fillColor(nullptr, nullptr, nullptr, &alpha);
|
||||||
alpha = MULTIPLY(alpha, opacity);
|
updateFill = (MULTIPLY(alpha, opacity) || rshape->fill);
|
||||||
visibleFill = (alpha > 0 || rshape->fill);
|
if (updateShape) shapeReset(&shape);
|
||||||
shapeReset(&shape);
|
if (updateFill || clipper) {
|
||||||
if (visibleFill || clipper) {
|
if (shapePrepare(&shape, rshape, transform, bbox, renderRegion, mpool, tid, clips.count > 0 ? true : false)) {
|
||||||
if (!shapePrepare(&shape, rshape, transform, bbox, renderRegion, mpool, tid, clips.count > 0 ? true : false)) {
|
if (!shapeGenRle(&shape, rshape, antialiasing(strokeWidth))) goto err;
|
||||||
visibleFill = false;
|
} else {
|
||||||
|
updateFill = false;
|
||||||
renderRegion.reset();
|
renderRegion.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Fill
|
//Fill
|
||||||
if (flags & (RenderUpdateFlag::Path |RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) {
|
if (updateFill) {
|
||||||
if (visibleFill || clipper) {
|
|
||||||
if (!shapeGenRle(&shape, rshape, antialiasing(strokeWidth))) goto err;
|
|
||||||
}
|
|
||||||
if (auto fill = rshape->fill) {
|
if (auto fill = rshape->fill) {
|
||||||
auto ctable = (flags & RenderUpdateFlag::Gradient) ? true : false;
|
auto ctable = (flags & RenderUpdateFlag::Gradient) ? true : false;
|
||||||
if (ctable) shapeResetFill(&shape);
|
if (ctable) shapeResetFill(&shape);
|
||||||
if (!shapeGenFillColors(&shape, fill, transform, surface, opacity, ctable)) goto err;
|
if (!shapeGenFillColors(&shape, fill, transform, surface, opacity, ctable)) goto err;
|
||||||
} else {
|
|
||||||
shapeDelFill(&shape);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Stroke
|
//Stroke
|
||||||
if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) {
|
if ((updateShape || flags & RenderUpdateFlag::Stroke) && (strokeWidth > 0.0f)) {
|
||||||
if (strokeWidth > 0.0f) {
|
|
||||||
shapeResetStroke(&shape, rshape, transform);
|
shapeResetStroke(&shape, rshape, transform);
|
||||||
|
|
||||||
if (!shapeGenStrokeRle(&shape, rshape, transform, bbox, renderRegion, mpool, tid)) goto err;
|
if (!shapeGenStrokeRle(&shape, rshape, transform, bbox, renderRegion, mpool, tid)) goto err;
|
||||||
if (auto fill = rshape->strokeFill()) {
|
if (auto fill = rshape->strokeFill()) {
|
||||||
auto ctable = (flags & RenderUpdateFlag::GradientStroke) ? true : false;
|
auto ctable = (flags & RenderUpdateFlag::GradientStroke) ? true : false;
|
||||||
if (ctable) shapeResetStrokeFill(&shape);
|
if (ctable) shapeResetStrokeFill(&shape);
|
||||||
if (!shapeGenStrokeFillColors(&shape, fill, transform, surface, opacity, ctable)) goto err;
|
if (!shapeGenStrokeFillColors(&shape, fill, transform, surface, opacity, ctable)) goto err;
|
||||||
} else {
|
|
||||||
shapeDelStrokeFill(&shape);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
shapeDelStroke(&shape);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -276,16 +276,19 @@ RenderData Paint::Impl::update(RenderMethod* renderer, const Matrix& pm, Array<R
|
||||||
|
|
||||||
/* 2. Clipping */
|
/* 2. Clipping */
|
||||||
if (this->clipper) {
|
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();
|
viewport = renderer->viewport();
|
||||||
/* TODO: Intersect the clipper's clipper, if both are FastTrack.
|
/* TODO: Intersect the clipper's clipper, if both are FastTrack.
|
||||||
Update the subsequent clipper first and check its ctxFlag. */
|
Update the subsequent clipper first and check its ctxFlag. */
|
||||||
if (!P(this->clipper)->clipper && (compFastTrack = _compFastTrack(renderer, this->clipper, pm, viewport)) == Result::Success) {
|
if (!pclip->clipper && _compFastTrack(renderer, this->clipper, pm, viewport) == Result::Success) {
|
||||||
P(this->clipper)->ctxFlag |= ContextFlag::FastTrack;
|
pclip->ctxFlag |= ContextFlag::FastTrack;
|
||||||
}
|
compFastTrack = Result::Success;
|
||||||
if (compFastTrack == Result::InsufficientCondition) {
|
} else {
|
||||||
trd = P(this->clipper)->update(renderer, pm, clips, 255, pFlag, true);
|
trd = pclip->update(renderer, pm, clips, 255, pFlag, true);
|
||||||
clips.push(trd);
|
clips.push(trd);
|
||||||
|
compFastTrack = Result::InsufficientCondition;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,8 +72,8 @@ namespace tvg
|
||||||
tvg::rotate(&m, degree);
|
tvg::rotate(&m, degree);
|
||||||
}
|
}
|
||||||
} tr;
|
} tr;
|
||||||
|
RenderUpdateFlag renderFlag = RenderUpdateFlag::None;
|
||||||
BlendMethod blendMethod;
|
BlendMethod blendMethod;
|
||||||
uint8_t renderFlag;
|
|
||||||
uint8_t ctxFlag;
|
uint8_t ctxFlag;
|
||||||
uint8_t opacity;
|
uint8_t opacity;
|
||||||
uint8_t refCnt = 0; //reference count
|
uint8_t refCnt = 0; //reference count
|
||||||
|
|
|
@ -37,9 +37,14 @@ using pixel_t = uint32_t;
|
||||||
|
|
||||||
#define DASH_PATTERN_THRESHOLD 0.001f
|
#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
|
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
|
//TODO: Move this in public header unifying with SwCanvas::Colorspace
|
||||||
enum ColorSpace : uint8_t
|
enum ColorSpace : uint8_t
|
||||||
{
|
{
|
||||||
|
|
|
@ -33,7 +33,7 @@ struct Shape::Impl
|
||||||
RenderShape rs; //shape data
|
RenderShape rs; //shape data
|
||||||
RenderData rd = nullptr; //engine data
|
RenderData rd = nullptr; //engine data
|
||||||
Shape* shape;
|
Shape* shape;
|
||||||
uint8_t rFlag = RenderUpdateFlag::None;
|
RenderUpdateFlag rFlag = RenderUpdateFlag::None;
|
||||||
uint8_t cFlag = CompositionFlag::Invalid;
|
uint8_t cFlag = CompositionFlag::Invalid;
|
||||||
uint8_t opacity; //for composition
|
uint8_t opacity; //for composition
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue