[cairo] [RFC] Color space API (partial proposal)

Bill Spitzak spitzak at gmail.com
Fri Feb 26 11:51:55 PST 2010

Adrian Johnson wrote:

>  double cmyk[4] = { 0.1, 0.2, 0.3, 0.4 };
>  c = cairo_color_create (dest_col_space, &cmyk);
>  cairo_set_source_color (cr, c);

Here I would prefer an api that looks like this:

   double cmyk[4] = {...};
   cairo_set_source_color(cr, dest_col_space, &cmyk);

I don't see any reason to create a temporary structure, though at least 
your design does not require copying the data! Cairo's color management 
must be designed so that the backend can IMMEDIATELY throw away this 
color space and convert the color to some other one, so this structure 
is much too short-lived to be useful.

> For case #2 (CMYK + spot) we need API for creating spot colors. To do
> this we need to specify the name of the spot color, the alternate
> color space for simulating the spot for when the output device does not
> support it, and the tint transform to specify the alternate color for
> any given tint value between 0 and 1.
> Do you have any suggestions on what the API should look like?

Something that is trivial to translate to some SUBSET of the pdf spec.

> cairo_color_space_create_spot (const char    *name,
>                                cairo_color_t *first_color,
>                                cairo_color_t *second_color);
> where first_color and second_color must be in the same color space.
> The color space of first_color/second_color will be used as the
> alternate color space. The tint transform will map tint values between 0 
> and 1 to the linear interpolation between first_color and
> second_color.

Since zero tint is (I think) the same as not drawing in the spot color 
at all, I don't see how this can work.

A scheme I think will work is really simple, where the spot color has 
exactly one color and color space specified:

  cairo_create_spot_color(const char* name, cairo_color_space_t X, float*)

What happens is that any tint is a linear interpolation in color space X 
between "nothing" (whatever that means) and the given color. The 
interpolated color is converted from X to the surface's blending space 
and mixed in there.

In normal use this color space is some generic CMYK or whatever you 
happen to have the equivalent of the color in.

If there is a complex tinting function that you need to reproduce, then 
the color space X can be constructed so that a linear interpolation in 
that space turns into the tinting function. I assume color space 
definitions are a superset of what you can do with the pdf tinting 
functions so this will always work.

The problems I see are:

1. This is probably a superset of what you can put into a pdf (as 
nothing limits the color space to ones that can be translated to the pdf 
tinting functions).

2. An application trying to reproduce a pdf with cairo needs to be able 
to turn the tinting functions into a color space. Thus there must be 
apis to create color spaces more complicated than "read it from this file".

A second much simpler proposal is to use the exact same API:

  cairo_create_spot_color(const char* name, cairo_color_space_t X, float*)

But in this case the color is IMMEDIATELY translated to the surface 
blending space, just like any other use by Cairo of a color. Tinting is 
assumed to be a linear ramp in blending space. If more complex tinting 
function is needed it would be done by specifying a different spot color 
that in it's name says that partial ink is wanted and a different 
equivalent color for it.

Though obviously limited it may be worthwhile to see if any actual users 
need anything more complex than this.

More information about the cairo mailing list