mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 05:33:36 +00:00
sw_engine: allow the stroke clipper
clipping with a stroke is useful for various visual effects. TVG can support this approach as it offers better efficiency compared to alpha masking. If a valid stroke is defined in the clipper shape, the renderer prioritizes clipping with the stroke over the shape's fill. issue: https://github.com/thorvg/thorvg/issues/3063
This commit is contained in:
parent
0f253aac27
commit
324bff30d1
2 changed files with 5 additions and 11 deletions
|
@ -88,14 +88,14 @@ struct SwShapeTask : SwTask
|
||||||
return strokeWidth < 2.0f || rshape->stroke->dashCnt > 0 || rshape->stroke->strokeFirst || rshape->strokeTrim() || rshape->stroke->color.a < 255;
|
return strokeWidth < 2.0f || rshape->stroke->dashCnt > 0 || rshape->stroke->strokeFirst || rshape->strokeTrim() || rshape->stroke->color.a < 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
float validStrokeWidth()
|
float validStrokeWidth(bool clipper)
|
||||||
{
|
{
|
||||||
if (!rshape->stroke) return 0.0f;
|
if (!rshape->stroke) return 0.0f;
|
||||||
|
|
||||||
auto width = rshape->stroke->width;
|
auto width = rshape->stroke->width;
|
||||||
if (tvg::zero(width)) return 0.0f;
|
if (tvg::zero(width)) return 0.0f;
|
||||||
|
|
||||||
if (!rshape->stroke->fill && (MULTIPLY(rshape->stroke->color.a, opacity) == 0)) return 0.0f;
|
if (!clipper && (!rshape->stroke->fill && (MULTIPLY(rshape->stroke->color.a, opacity) == 0))) return 0.0f;
|
||||||
if (tvg::zero(rshape->stroke->trim.begin - rshape->stroke->trim.end)) return 0.0f;
|
if (tvg::zero(rshape->stroke->trim.begin - rshape->stroke->trim.end)) return 0.0f;
|
||||||
|
|
||||||
return (width * sqrt(transform.e11 * transform.e11 + transform.e12 * transform.e12));
|
return (width * sqrt(transform.e11 * transform.e11 + transform.e12 * transform.e12));
|
||||||
|
@ -103,8 +103,9 @@ struct SwShapeTask : SwTask
|
||||||
|
|
||||||
bool clip(SwRle* target) override
|
bool clip(SwRle* target) override
|
||||||
{
|
{
|
||||||
|
if (shape.strokeRle) return rleClip(target, shape.strokeRle);
|
||||||
if (shape.fastTrack) return rleClip(target, &bbox);
|
if (shape.fastTrack) return rleClip(target, &bbox);
|
||||||
else if (shape.rle) return rleClip(target, shape.rle);
|
if (shape.rle) return rleClip(target, shape.rle);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +117,7 @@ struct SwShapeTask : SwTask
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto strokeWidth = validStrokeWidth();
|
auto strokeWidth = validStrokeWidth(clipper);
|
||||||
SwBBox renderRegion{};
|
SwBBox renderRegion{};
|
||||||
auto visibleFill = false;
|
auto visibleFill = false;
|
||||||
|
|
||||||
|
@ -154,14 +155,11 @@ struct SwShapeTask : SwTask
|
||||||
if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) {
|
if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) {
|
||||||
if (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 {
|
} else {
|
||||||
shapeDelStroke(&shape);
|
shapeDelStroke(&shape);
|
||||||
|
|
|
@ -511,10 +511,6 @@ bool shapePrepared(const SwShape* shape)
|
||||||
|
|
||||||
bool shapeGenRle(SwShape* shape, TVG_UNUSED const RenderShape* rshape, bool antiAlias)
|
bool shapeGenRle(SwShape* shape, TVG_UNUSED const RenderShape* rshape, bool antiAlias)
|
||||||
{
|
{
|
||||||
//FIXME: Should we draw it?
|
|
||||||
//Case: Stroke Line
|
|
||||||
//if (shape.outline->opened) return true;
|
|
||||||
|
|
||||||
//Case A: Fast Track Rectangle Drawing
|
//Case A: Fast Track Rectangle Drawing
|
||||||
if (shape->fastTrack) return true;
|
if (shape->fastTrack) return true;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue