mirror of
https://github.com/thorvg/thorvg.git
synced 2025-07-23 22:58:44 +00:00
common shape: fixing stroking composition issue.
When combining Shape, Stroke, and AlphaMasking, there is a missing composition step which results in an incorrect output as expected by the user. This problem is resolved by introducing shape fill and stroking composition. @Issue: https://github.com/thorvg/thorvg/issues/209
This commit is contained in:
parent
4938c3253c
commit
6994925b9d
4 changed files with 42 additions and 4 deletions
|
@ -70,6 +70,7 @@ protected: \
|
|||
#define _TVG_DECLARE_ACCESSOR() \
|
||||
friend Canvas; \
|
||||
friend Scene; \
|
||||
friend Shape; \
|
||||
friend Picture; \
|
||||
friend Accessor; \
|
||||
friend IteratorAccessor
|
||||
|
@ -81,6 +82,7 @@ namespace tvg
|
|||
class RenderMethod;
|
||||
class IteratorAccessor;
|
||||
class Scene;
|
||||
class Shape;
|
||||
class Picture;
|
||||
class Canvas;
|
||||
class Accessor;
|
||||
|
|
|
@ -142,8 +142,9 @@ struct Picture::Impl
|
|||
const Paint* target;
|
||||
auto method = picture->composite(&target);
|
||||
if (!target || method == tvg::CompositeMethod::ClipPath) return false;
|
||||
if (target->pImpl->opacity < 255 && target->pImpl->opacity > 0) return true;
|
||||
return false;
|
||||
if (target->pImpl->opacity == 255 || target->pImpl->opacity == 0) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
RenderData update(RenderMethod &renderer, const RenderTransform* pTransform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag pFlag, bool clipper)
|
||||
|
|
|
@ -32,7 +32,7 @@ constexpr auto PATH_KAPPA = 0.552284f;
|
|||
/* External Class Implementation */
|
||||
/************************************************************************/
|
||||
|
||||
Shape :: Shape() : pImpl(new Impl())
|
||||
Shape :: Shape() : pImpl(new Impl(this))
|
||||
{
|
||||
Paint::pImpl->id = TVG_CLASS_ID_SHAPE;
|
||||
Paint::pImpl->method(new PaintMethod<Shape::Impl>(pImpl));
|
||||
|
|
|
@ -35,6 +35,12 @@ struct Shape::Impl
|
|||
RenderShape rs; //shape data
|
||||
RenderData rd = nullptr; //engine data
|
||||
uint32_t flag = RenderUpdateFlag::None;
|
||||
Shape* shape;
|
||||
bool needComp; //for composition
|
||||
|
||||
Impl(Shape* s) : shape(s)
|
||||
{
|
||||
}
|
||||
|
||||
bool dispose(RenderMethod& renderer)
|
||||
{
|
||||
|
@ -45,11 +51,40 @@ struct Shape::Impl
|
|||
|
||||
bool render(RenderMethod& renderer)
|
||||
{
|
||||
return renderer.renderShape(rd);
|
||||
Compositor* cmp = nullptr;
|
||||
bool ret;
|
||||
|
||||
if (needComp) {
|
||||
cmp = renderer.target(bounds(renderer), renderer.colorSpace());
|
||||
renderer.beginComposite(cmp, CompositeMethod::None, 255);
|
||||
}
|
||||
ret = renderer.renderShape(rd);
|
||||
if (cmp) renderer.endComposite(cmp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool needComposition(uint32_t opacity)
|
||||
{
|
||||
//In this case, paint(shape) would try composition by backends. (See: SwShapeTask::run())
|
||||
//TODO: that composition should be moved here?
|
||||
if (opacity < 255) return false;
|
||||
|
||||
//Shape composition is only necessary when stroking is valid.
|
||||
if (!rs.stroke || rs.stroke->width < FLT_EPSILON || rs.stroke->color[3] == 0) return false;
|
||||
|
||||
//Composition test
|
||||
const Paint* target;
|
||||
auto method = shape->composite(&target);
|
||||
if (!target || method == tvg::CompositeMethod::ClipPath) return false;
|
||||
if (target->pImpl->opacity == 255 || target->pImpl->opacity == 0) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
RenderData update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag pFlag, bool clipper)
|
||||
{
|
||||
needComp = needComposition(opacity);
|
||||
|
||||
rd = renderer.prepare(rs, rd, transform, opacity, clips, static_cast<RenderUpdateFlag>(pFlag | flag), clipper);
|
||||
flag = RenderUpdateFlag::None;
|
||||
return rd;
|
||||
|
|
Loading…
Add table
Reference in a new issue