mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-07 21:23:32 +00:00
common picture: fix a composition bug.
Previously, a picture with a half-translucent mask would not function correctly. This fix addresses the bug by applying the expected composition step. Note: Even after applying this patch, a half-translucent mask with shape fill alpha will still not work properly. We should consider removing the fill alpha property, as it duplicates the Paint opacity. @Issue: https://github.com/thorvg/thorvg/issues/1423
This commit is contained in:
parent
c7d77b3517
commit
d8687314a6
4 changed files with 37 additions and 6 deletions
|
@ -37,7 +37,9 @@ void tvgDrawCmds(tvg::Canvas* canvas)
|
|||
|
||||
auto mask = tvg::Shape::gen();
|
||||
mask->appendCircle(WIDTH/2, HEIGHT/2, WIDTH/2, HEIGHT/2);
|
||||
mask->fill(255, 255, 255, 100);
|
||||
mask->fill(255, 255, 255, 255);
|
||||
//Use the opacity for a half-translucent mask.
|
||||
mask->opacity(125);
|
||||
|
||||
auto picture = tvg::Picture::gen();
|
||||
picture->load(EXAMPLE_DIR"/tiger.svg");
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
/* External Class Implementation */
|
||||
/************************************************************************/
|
||||
|
||||
Picture::Picture() : pImpl(new Impl)
|
||||
Picture::Picture() : pImpl(new Impl(this))
|
||||
{
|
||||
Paint::pImpl->id = TVG_CLASS_ID_PICTURE;
|
||||
Paint::pImpl->method(new PaintMethod<Picture::Impl>(pImpl));
|
||||
|
|
|
@ -67,7 +67,13 @@ struct Picture::Impl
|
|||
RenderData rd = nullptr; //engine data
|
||||
float w = 0, h = 0;
|
||||
RenderMesh rm; //mesh data
|
||||
Picture* picture = nullptr;
|
||||
bool resizing = false;
|
||||
bool needComp = false; //need composition
|
||||
|
||||
Impl(Picture* p) : picture(p)
|
||||
{
|
||||
}
|
||||
|
||||
~Impl()
|
||||
{
|
||||
|
@ -127,6 +133,19 @@ struct Picture::Impl
|
|||
else return RenderTransform(pTransform, &tmp);
|
||||
}
|
||||
|
||||
bool needComposition(uint32_t opacity)
|
||||
{
|
||||
//In this case, paint(scene) would try composition itself.
|
||||
if (opacity < 255) return false;
|
||||
|
||||
//Composition test
|
||||
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;
|
||||
}
|
||||
|
||||
RenderData update(RenderMethod &renderer, const RenderTransform* pTransform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag pFlag, bool clipper)
|
||||
{
|
||||
auto flag = load();
|
||||
|
@ -139,6 +158,7 @@ struct Picture::Impl
|
|||
loader->resize(paint, w, h);
|
||||
resizing = false;
|
||||
}
|
||||
needComp = needComposition(opacity) ? true : false;
|
||||
rd = paint->pImpl->update(renderer, pTransform, opacity, clips, static_cast<RenderUpdateFlag>(pFlag | flag), clipper);
|
||||
}
|
||||
return rd;
|
||||
|
@ -146,9 +166,18 @@ struct Picture::Impl
|
|||
|
||||
bool render(RenderMethod &renderer)
|
||||
{
|
||||
bool ret = false;
|
||||
if (surface) return renderer.renderImage(rd);
|
||||
else if (paint) return paint->pImpl->render(renderer);
|
||||
return false;
|
||||
else if (paint) {
|
||||
Compositor* cmp = nullptr;
|
||||
if (needComp) {
|
||||
cmp = renderer.target(bounds(renderer), renderer.colorSpace());
|
||||
renderer.beginComposite(cmp, CompositeMethod::None, 255);
|
||||
}
|
||||
ret = paint->pImpl->render(renderer);
|
||||
if (cmp) renderer.endComposite(cmp);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool viewbox(float* x, float* y, float* w, float* h)
|
||||
|
|
|
@ -59,10 +59,10 @@ struct SceneIterator : Iterator
|
|||
struct Scene::Impl
|
||||
{
|
||||
Array<Paint*> paints;
|
||||
uint8_t opacity; //for composition
|
||||
RenderMethod* renderer = nullptr; //keep it for explicit clear
|
||||
RenderData rd = nullptr;
|
||||
Scene* scene = nullptr;
|
||||
uint8_t opacity; //for composition
|
||||
|
||||
Impl(Scene* s) : scene(s)
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue