https://bugs.documentfoundation.org/show_bug.cgi?id=156361

--- Comment #5 from Patrick Luby <plub...@neooffice.org> ---
So after thinking about this more, I think I now know what is happening. Note:
masks on master and libreoffice-7-6 branches so 0 is black (opaque) and 1 is
white (transparent) in the examples below. Also, alpha masks are filled with
opaque grayscale colors so we don't need to factor in any blending of alpha
channels.

In the case of the white areas in the semi-transparent .svg image, the white
areas are VirtualDevices with their own AlphaMask drawn on top of an
overlapping stack of other VirtualDevices with their own separate AlphaMask.
Then, the bottom most VirtualDevice is drawn with a gray (50% transparency)
alpha mask onto a white background.

Blending the alpha masks works fine for the bottom most VirtualDevice because
its alpha mask is gray (0.5) and the VirtualDevice it is being drawn to has an
opaque (0.0) alpha mask. Applying SkBlendMode::kMultiply blends these two into
a dark gray (0.25) alpha mask. So far so good.

The problem arises when the destination VirtualDevice (as is the case in the
white shapes) is filled with gray and/or white pixels (greater than 0.0 up to
1.0) blending will darken (i.e. make more opaque) the destination's alpha mask
darken.

For a really simplistic example, say we have a source VirtualDevice that has a
50% transparent (0.5) alpha mask. But the destination VirtualDevice's alpha
mask we want to draw to already has a 100% transparent (1.0) alpha mask. In
theory, after blending with SkBlendMode::kMultiply, the destination's alpha
mask is filled with gray (1.0 * 0.5) but should be filled with white (1.0)
because if the destination's alpha mask is fully transparent, nothing will be
drawn regardless of the alpha mask of the source.

To summarize the issue: mpGraphics->BlendBitmap() makes the destination's alpha
mask more opaque than it should be when the destination's alpha bitmap is
semi-transparent or fully transparent.

So, I think mpGraphics->BlendBitmap() needs to use the following blending
algorithm:

r = 1 - ((1 - d) + ((1 - d) * (1 - s)))

This should prevent the source alpha mask passed into mpGraphics->BlendBitmap()
from making semi-transparent and fully transparent areas in the destination
more opaque.

-- 
You are receiving this mail because:
You are the assignee for the bug.

Reply via email to