mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +00:00
sw_engine: fixed incorrect image blending operations
The anti-aliased outline color was incorrectly blended at the multiply option. The fix can be observed in the example: 'examples/lottie/resourcesguitar.json' in order to do this, RenderMehthod::blend() method introduced `bool direct` for figuring out the intermediate composition.
This commit is contained in:
parent
078b1c8d86
commit
38697022f0
14 changed files with 25 additions and 18 deletions
|
@ -913,11 +913,10 @@ const Surface* GlRenderer::mainSurface()
|
|||
}
|
||||
|
||||
|
||||
bool GlRenderer::blend(TVG_UNUSED BlendMethod method)
|
||||
bool GlRenderer::blend(TVG_UNUSED BlendMethod method, TVG_UNUSED bool direct)
|
||||
{
|
||||
if (method != BlendMethod::Normal) {
|
||||
return true;
|
||||
}
|
||||
if (method != BlendMethod::Normal) return true;
|
||||
|
||||
//TODO:
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ public:
|
|||
RenderRegion region(RenderData data) override;
|
||||
RenderRegion viewport() override;
|
||||
bool viewport(const RenderRegion& vp) override;
|
||||
bool blend(BlendMethod method) override;
|
||||
bool blend(BlendMethod method, bool direct) override;
|
||||
ColorSpace colorSpace() override;
|
||||
const Surface* mainSurface() override;
|
||||
|
||||
|
|
|
@ -363,7 +363,7 @@ static inline uint32_t opBlendSrcOver(uint32_t s, TVG_UNUSED uint32_t d, TVG_UNU
|
|||
}
|
||||
|
||||
//TODO: BlendMethod could remove the alpha parameter.
|
||||
static inline uint32_t opBlendDifference(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
|
||||
static inline uint32_t opBlendDifference(uint32_t s, uint32_t d, uint8_t a)
|
||||
{
|
||||
//if (s > d) => s - d
|
||||
//else => d - s
|
||||
|
@ -400,8 +400,7 @@ static inline uint32_t opBlendScreen(uint32_t s, uint32_t d, TVG_UNUSED uint8_t
|
|||
return JOIN(255, c1, c2, c3);
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t opBlendMultiply(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
|
||||
static inline uint32_t opBlendDirectMultiply(uint32_t s, uint32_t d, uint8_t a)
|
||||
{
|
||||
// s * d
|
||||
auto c1 = MULTIPLY(C1(s), C1(d));
|
||||
|
@ -410,6 +409,10 @@ static inline uint32_t opBlendMultiply(uint32_t s, uint32_t d, TVG_UNUSED uint8_
|
|||
return JOIN(255, c1, c2, c3);
|
||||
}
|
||||
|
||||
static inline uint32_t opBlendMultiply(uint32_t s, uint32_t d, uint8_t a)
|
||||
{
|
||||
return opBlendDirectMultiply(s, d, a) + ALPHA_BLEND(d, IA(s));
|
||||
}
|
||||
|
||||
static inline uint32_t opBlendOverlay(uint32_t s, uint32_t d, TVG_UNUSED uint8_t a)
|
||||
{
|
||||
|
|
|
@ -1383,7 +1383,7 @@ static bool _rasterDirectBlendingImage(SwSurface* surface, const SwImage* image,
|
|||
*dst = INTERPOLATE(tmp, *dst, A(*src));
|
||||
}
|
||||
} else {
|
||||
for (auto x = region.min.x; x < region.max.x; ++x, ++dst, ++src) {
|
||||
for (auto x = region.min.x; x < region.max.x; x++, dst++, src++) {
|
||||
auto tmp = ALPHA_BLEND(*src, opacity);
|
||||
auto tmp2 = surface->blender(tmp, *dst, 255);
|
||||
*dst = INTERPOLATE(tmp2, *dst, A(tmp));
|
||||
|
|
|
@ -100,7 +100,6 @@ struct SwShapeTask : SwTask
|
|||
return (width * sqrt(transform.e11 * transform.e11 + transform.e12 * transform.e12));
|
||||
}
|
||||
|
||||
|
||||
bool clip(SwRle* target) override
|
||||
{
|
||||
if (shape.fastTrack) rleClipRect(target, &bbox);
|
||||
|
@ -442,7 +441,7 @@ bool SwRenderer::renderShape(RenderData data)
|
|||
}
|
||||
|
||||
|
||||
bool SwRenderer::blend(BlendMethod method)
|
||||
bool SwRenderer::blend(BlendMethod method, bool direct)
|
||||
{
|
||||
if (surface->blendMethod == method) return true;
|
||||
surface->blendMethod = method;
|
||||
|
@ -455,7 +454,7 @@ bool SwRenderer::blend(BlendMethod method)
|
|||
surface->blender = opBlendScreen;
|
||||
break;
|
||||
case BlendMethod::Multiply:
|
||||
surface->blender = opBlendMultiply;
|
||||
surface->blender = direct ? opBlendDirectMultiply : opBlendMultiply;
|
||||
break;
|
||||
case BlendMethod::Overlay:
|
||||
surface->blender = opBlendOverlay;
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
RenderRegion region(RenderData data) override;
|
||||
RenderRegion viewport() override;
|
||||
bool viewport(const RenderRegion& vp) override;
|
||||
bool blend(BlendMethod method) override;
|
||||
bool blend(BlendMethod method, bool direct) override;
|
||||
ColorSpace colorSpace() override;
|
||||
const Surface* mainSurface() override;
|
||||
|
||||
|
|
|
@ -225,8 +225,6 @@ bool Paint::Impl::render(RenderMethod* renderer)
|
|||
|
||||
if (cmp) renderer->beginComposite(cmp, compData->method, compData->target->pImpl->opacity);
|
||||
|
||||
renderer->blend(blendMethod);
|
||||
|
||||
bool ret;
|
||||
PAINT_METHOD(ret, render(renderer));
|
||||
|
||||
|
|
|
@ -73,6 +73,8 @@ bool Picture::Impl::needComposition(uint8_t opacity)
|
|||
bool Picture::Impl::render(RenderMethod* renderer)
|
||||
{
|
||||
bool ret = false;
|
||||
renderer->blend(picture->blend(), true);
|
||||
|
||||
if (surface) return renderer->renderImage(rd);
|
||||
else if (paint) {
|
||||
Compositor* cmp = nullptr;
|
||||
|
|
|
@ -294,7 +294,7 @@ public:
|
|||
virtual RenderRegion region(RenderData data) = 0;
|
||||
virtual RenderRegion viewport() = 0;
|
||||
virtual bool viewport(const RenderRegion& vp) = 0;
|
||||
virtual bool blend(BlendMethod method) = 0;
|
||||
virtual bool blend(BlendMethod method, bool direct = false) = 0;
|
||||
virtual ColorSpace colorSpace() = 0;
|
||||
virtual const Surface* mainSurface() = 0;
|
||||
|
||||
|
|
|
@ -120,6 +120,8 @@ struct Scene::Impl
|
|||
Compositor* cmp = nullptr;
|
||||
auto ret = true;
|
||||
|
||||
renderer->blend(scene->blend());
|
||||
|
||||
if (needComp) {
|
||||
cmp = renderer->target(bounds(renderer), renderer->colorSpace());
|
||||
renderer->beginComposite(cmp, CompositeMethod::None, opacity);
|
||||
|
|
|
@ -54,10 +54,13 @@ struct Shape::Impl
|
|||
Compositor* cmp = nullptr;
|
||||
bool ret;
|
||||
|
||||
renderer->blend(shape->blend(), !needComp);
|
||||
|
||||
if (needComp) {
|
||||
cmp = renderer->target(bounds(renderer), renderer->colorSpace());
|
||||
renderer->beginComposite(cmp, CompositeMethod::None, opacity);
|
||||
}
|
||||
|
||||
ret = renderer->renderShape(rd);
|
||||
if (cmp) renderer->endComposite(cmp);
|
||||
return ret;
|
||||
|
|
|
@ -89,6 +89,7 @@ struct Text::Impl
|
|||
|
||||
bool render(RenderMethod* renderer)
|
||||
{
|
||||
renderer->blend(paint->blend(), true);
|
||||
return PP(shape)->render(renderer);
|
||||
}
|
||||
|
||||
|
|
|
@ -218,7 +218,7 @@ bool WgRenderer::viewport(const RenderRegion& vp)
|
|||
}
|
||||
|
||||
|
||||
bool WgRenderer::blend(BlendMethod method)
|
||||
bool WgRenderer::blend(BlendMethod method, TVG_UNUSED bool direct)
|
||||
{
|
||||
mBlendMethod = method;
|
||||
return false;
|
||||
|
|
|
@ -38,7 +38,7 @@ public:
|
|||
RenderRegion region(RenderData data) override;
|
||||
RenderRegion viewport() override;
|
||||
bool viewport(const RenderRegion& vp) override;
|
||||
bool blend(BlendMethod method) override;
|
||||
bool blend(BlendMethod method, bool direct) override;
|
||||
ColorSpace colorSpace() override;
|
||||
const Surface* mainSurface() override;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue