PS/PDF API Change Proposal: (Re: [cairo] Semantics of transparent objects)

Owen Taylor otaylor at
Thu Jan 19 13:54:34 PST 2006

On Thu, 2006-01-19 at 08:21 -0800, Carl Worth wrote:
> On Wed, 18 Jan 2006 23:07:14 -0500, Owen Taylor wrote:


> >  B) It's good for slicing and dicing objects - cutting one
> >     object out of another, and so forth.
> Of the use cases you point out, this is the one I'll pick to talk
> about, (though there is a more general issue I think).
> >                                          This is basically
> >     always done in a group rather than on the final destination
> >     surface (Because, other than in A) above, we need to
> >     end up with an opaque surface in the end, so cutting
> >     something out of your destination is a bad idea...)
> Since destination-alpha surfaces do exist, code can be written that
> does do slicing and dicing on the final destination and not in a
> group. And this is one of the scenario I imagined causing a problem. I
> imagine it like this:
> 	* User writes a program to display a "donut" shape achieved by
> 	  drawing an opaque circle then "cutting out" a smaller circle
> 	  with an operator such as CLEAR.
> 	* User directs the same drawing code to a PS surface (without
>           destination-alpha semantics) and prints it.
> 	* User is bewildered to discover that outside the donut shape,
>           things are transparent (as expected) but the inside of the
>           donut shape is solid blank ink, not transparent.
> 	* User files bug report against cairo.

The thing is, if the original code was used, say, in a GTK+ expose
handler for a normal window, you'd get the exact same black hole.
The way you draw a donut with a hole is

 You create a group
 You draw the circle
 You cut out the hole
 You composite the group

(Using "group" as a shorthand for the moment.) That clearly has to
work. But I don't think there would be a user expectation that drawing
directly on a PS document behaves differently from drawing on a window
or pixmap with a white background.

> What's the answer to give this user? Is it, "Oh, you shouldn't be
> drawing like that. Go back and change your rendering operations so
> that they work without ever relying on destination-alpha semantics." ?

My expectation is that we'd tell the person to do it the same way
as we would tell them to do it if they had the same problem drawing
to a no-alpha destination surface.

The only reason I think people may be having a problem with this
idea is that they can look at a piece of printed output and say:

 - There is ink here
 - There is no ink here

So, "CLEAR" seems like it should mean "don't draw any ink", while
for a no-alpha pixmap, it's easier to accept that it is a 
nonsense operation. But if that's the argument, then the only real
solution is to make the COLOR_ALPHA behavior the normal behavior.

You can't solve people's confusion by adding an option to do it
in a non-confusing way :-)

> One might challenge the assumption of my scenario saying that users
> probably won't draw things this way, but that seems a rather fragile
> basis for deciding the semantics of the imaging model for cairo's
> print output.
> My desire is that print output from cairo provides output consistent
> with what is possible with display output. If there are operations
> that are going to be just plain unsupported for print output, then I
> would argue they don't belong in display output.

We already have a clear distinction between the behavior of surfaces
with and without destination alpha. So, having PS/PDF surfaces behave
like surfaces without destination alpha isn't introducing anything
new. The question is then which model do we choose for PS/PDF, or
do we offer both.

There are several concerns I have with offering both:

 - Considering only basic Postscript/PDF where white is simply
   the media color:

   To a first approximation, all operations that actually require
   destination alpha will require image fallbacks. So, having the
   option there is a trap for users.

   If there were things you couldn't draw without using destination
   alpha on the final surface, then we'd have a clear reason to
   offer the option. But we know that Cairo is a complete 
   drawing API without destination alpha for the final surface
   because that's how it works for screen rendering...

 - Considering more advanced Postscript/PDF pre-press applications
   where destination alpha has a real meaning:

   I don't think what we're discussing now will work for that, and
   so we throw something in, we may be tying ourselves to a 
   set of behaviors that aren't what we want.


> It's not an entirely new code path. The necessary change in the code
> is quite small. Basically, we just have to adjust the
> ps_surface_can_implement_operation_natively to consider the
> cairo_content_t value in addition to the operator and source pattern
> type, etc.

It's pretty close to a tautology:

 If it doesn't make a difference to the final output whether there
 is destination alpha or not we *can* implement
 just as efficient postscript output for both cases.

It may be that that this is actually the case in practice -
the question really is whether there are any operators
other than OVER which are actually interesting to use when drawing
on an opaque surface.


> > will give exactly the same result, but CAIRO_CONTENT_COLOR_ALPHA
> > will likely be considerably less efficient.
> I agree that for many common uses the two modes will be
> equivalent. No matter what we do that means it will be easy for users
> to have the wrong option set for a while before noticing.
> I disagree that supporting COLOR_ALPHA will be less efficient. For
> the common uses where the result is the same, I believe the
> performance will also be the same.
> All I want to be sure of is that when the user does realize that they
> are getting the wrong results that we can just say "Pass the other
> cairo_content_t value" and allow the user to get the desired result
> without changing all of the user's rendering code.

However, perhaps the user *should* change all of their rendering
code? If the user is doing stuff where the mode makes a difference
then they are going to be producing bad postscript / PDF output.

> > Plus, I'd argue that CAIRO_CONTENT_COLOR_ALPHA here really
> > doesn't mean the same thing here as it does in the rest of the
> > API. You say that you think we should be able to create Win32
> > surfaces with alpha... you certainly don't mean that you should
> > be able to create Win32 surfaces that magically composite
> > against white, do you?


> >                                                    What would
> > be the analogy elsewhere? If I create a ARGB surface for an
> > xRGB X window that doesn't have transparency, then areas I leave
> > with alpha < 1.0 come out black not white. for their printer or for
> > redistribution. 
> I think I would prefer if it were not possible to create an ARGB
> surface for a display device that doesn't actually support the alpha
> channel. We perhaps don't have the technical means of detecting that
> in the X world right now, but we'll probably need that, (applications
> will need to know if they can rely on alpha or not).

That was the way that I had set up the X API at some point, but Keith
was unhappy with that because he wanted to be able to use SATURATE -
where the alpha is used temporarily but doesn't show up in the 
final image.

> > As I said at the beginning, I don't object strenuously here,
> > but it is a parameter to confuse users, and a code path to
> > confuse implementers that in the end doesn't seem useful
> > to me, except for making our test cases look more orthogonal
> > and consistent. PS and PDF don't have transparency.
> And in summary, I don't think the lack of transparency in the final
> PostScript output has any relevance here. The point is that the cairo
> imaging model does have operations that rely on destination alpha, and
> I would like our print output to support the entire cairo imaging
> model.

Are you unhappy that drawing to the screen on a 16bpp display doesn't
support the entire cairo image model? It's exactly parallel.

If you want to argue that printing inherently has an alpha channel -
letting the paper show through - that's a stronger argument to me.

In fact, this may even be the model of PDF ... in the 1.4 spec
(what I have at hand), section 7.3.6 entitled "Page Group" describes
how all the elements of the page are considered to be part of a
transparent group which is normally composited to the output media,
but in some applications could be composited on top of other graphics

But then it becomes very unclear to me why we provide the choice of
CAIRO_CONTENT_COLOR ... you've claimed above that we can make 
where they produce the same output. Are there then cases where you
*want* the different results of CAIRO_CONTENT_COLOR?

You also have the problem of taking this logical model and representing
it properly in the output file once there are fallbacks involved;
we can do this for PDF by emitting the fallbacks as images with
alpha channels (hopefully the viewers won't choke...) but we can't
really do that for PS. So you'd have to chose between:

 - Compositing against white. Works for normal cases
 - Representing the fallbacks as an image mask combination,
   which will be atrociously ugly for the large number of devices
   that only support 1-bit alpha.

(Since PDF probably is the desired transport medium going forward,
having PS output be somewhat limited is not a huge deal.)

> PostScript also doesn't provide for source alpha either, but you
> certainly would not recommend we abandon all of our image fallback
> plans to emulate source alpha on PostScript, right?

I don't think that's parallel. We support source alpha on all devices.
We don't support destination alpha on all devices.


More information about the cairo mailing list