Transparent regions of masks are rendered opaque in cairo-based exports

Bug #597974 reported by su_v
30
This bug affects 4 people
Affects Status Importance Assigned to Milestone
Inkscape
Fix Released
Medium
Unassigned

Bug Description

According the Inkscape manual, regions outside the mask will be fully transparent: Inkscape renders masked objects, where the mask is smaller or partially overlapping the masked object as expected, in cairo-based exports (PNG, PDF, EPS) however the region outside the mask is rendered fully opaque.

reproduced on OS X 10.5.8 with
- Inkscape 0.47 (cairo 1.8.8)
- Inkscape 0.47+devel r9529 (cairo 1.8.10)

references:
<http://tavmjong.free.fr/INKSCAPE/MANUAL/html/Clip-Masking.html>

Revision history for this message
su_v (suv-lp) wrote :
Revision history for this message
su_v (suv-lp) wrote :
Revision history for this message
su_v (suv-lp) wrote :
Revision history for this message
jazzynico (jazzynico) wrote :

Reproduced on Ubuntu 10.04 and Windows XP, Inkscape 0.47 and r9530.

Changed in inkscape:
importance: Undecided → Medium
status: New → Confirmed
Revision history for this message
su_v (suv-lp) wrote :

Further tests show that the underlying cause seems to be that in cairo-based exports transparent bits of the mask are differently interpreted than by Inkscape:

In Inkscape, regions with minimum Alpha (zero alpha) are fully transparent.
In cairo-based exports, regions with minimum Alpha (zero alpha) are fully opaque.

Revision history for this message
su_v (suv-lp) wrote :
Revision history for this message
su_v (suv-lp) wrote :
su_v (suv-lp)
summary: - Masked objects in cairo-based exports with unexpected opaque region
+ Transparent regions of masks are rendered opaque in cairo-based exports
Revision history for this message
McPower (marco-kraft-googlemail) wrote :

Is the rendering engine for output on (hardware-)printers cairo-based too? On a printed piece of paper I see a correctly rendered gradient from opaque to transparent, but in the regions outside the mask the alpha jumps to opaque.

So I confirm this bug.

Revision history for this message
su_v (suv-lp) wrote :

> Is the rendering engine for output on (hardware-)printers cairo-based too?

Cairo-based:
Print dialog > Rendering > Backend > Vector

Inkscape's renderer (masking is printed as rendered on-canvas):
Print dialog > Rendering > Backend > Bitmap

Revision history for this message
Tavmjong Bah (tavmjong-free) wrote :

The relevant code is in the function:

void CairoRenderContext::popLayer()

in the file:

src/extensions/internal/cairo-render-context.cpp

The routine does not take alpha into account. The alpha values don't seem to be available in the pixel data (it is always set to FF, i.e. 1), only the RGB values. The "alpha" of the mask should be the luminance (calculated from RGB) * alpha * opacity.

In Inkscape Cairo output, masking works by creating a bitmap the size of the page and then painting it with the <mask>. Regions outside of the mask should have alpha=0 and/or RGB=000000. Currently outside the mask alpha is FF and RGB is FFFFFF. (BTW, this method fails if a mask is defined out of the page and the translated into the page.)

A couple other problems I see:

1. The calculation of luminance is wrong. The calculated value is too small. This is a more accurate calculation:

                    float luminance = (((*pixel & 0x00ff0000) >> 16) * 0.2125/255.0 +
                                       ((*pixel & 0x0000ff00) >> 8) * 0.7154/255.0 +
                                       ((*pixel & 0x000000ff) ) * 0.0721/255.0 );

    If it is desired to avoid using floats then changing 13817 to 13981, 46518 to 47068, 4688 to 4744 will get the luminance more accurately (256*256*256/255 * 0.2125, 0.7154, or 0.0721)..

2. The masked object (bitmap resulting from mask) is shifted up a little bit.

Revision history for this message
su_v (suv-lp) wrote :

> 2. The masked object (bitmap resulting from mask) is
> shifted up a little bit.

Could be related to a cairo bug, see
Bug #562592 “misaligned transparent paths in pdf export”
<https://bugs.launchpad.net/inkscape/+bug/562592>

Revision history for this message
Tavmjong Bah (tavmjong-free) wrote :

Fix checked into trunk. Will backport to 0.48 if no one cries foul in the next day or two. The fix is to initialize the mask bitmap black rather than white. I was wrong about the routine not taking alpha into account, the RGB values are already multiplied by alpha, fill_opacity, etc. (my original test cases hid this). I also fixed the luminance calculation. I used floats since speed isn't a big factor in exporting.

I found a new problem. In the screen display of masked objects, the mask RGB values are added linearly. They should be added as described above. This results in the screen display looking different from the PDF export and from display in browsers. The location of the relevant code is in nr-arena-item.cpp (two places). This is mission critical code so I'll ask for help in fixing it.

One additional possible problem, is that luminance should be calculated with linear RGB values. I believe the code is using sRGB however the results seem to match other SVG renderers.

Revision history for this message
Tavmjong Bah (tavmjong-free) wrote :

Fixed luminance to alpha calculation for masks in trunk. I will attach a test file.

Revision history for this message
Tavmjong Bah (tavmjong-free) wrote :

Test file for luminance to alpha calculation for masks. Each large rectangle consists of two parts, a background part with a hole cut out which shows the target color and a center part that has a square masked with a solid red, green, blue, or grey mask.

For the red, green, and blue large rectangle, if you cannot distinguish between the background and center parts, the test passes.

For the grey square, Inkscape differs from other renderers. This is presumably because Inkscape is using sRGB when the spec calls for linearRGB. The left half of the inner square is masked to match Inkscape while the right half is masked to match Firefox and Batik.

Revision history for this message
su_v (suv-lp) wrote :

Tavmjong Bah wrote on 2010-11-21:
> Fix checked into trunk. Will backport to 0.48 if no one cries foul in the next day or two.

Inkscape trunk: r9913
Inkscape 0.48.x: r9732

Tavmjong Bah wrote on 2010-11-22:
> Fixed luminance to alpha calculation for masks in trunk. I will attach a test file.

Inkscape trunk: r9914
Inkscape 0.48.x: r9732

Closing this report as 'Fix Released' milestoned to 0.48.1. Please revert if you don't agree.

Changed in inkscape:
milestone: none → 0.48.1
status: Confirmed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Duplicates of this bug

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.