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

ecir hana ecir.hana at gmail.com
Tue Feb 23 03:27:00 PST 2010

On Tue, Feb 23, 2010 at 11:45 AM, Adrian Johnson <ajohnson at redneon.com> wrote:
> Andrea Canciani wrote:
>> The attached changes to cairo.h are the base of what will probably be
>> my API change proposal for color space handling.
> This looks to be very close to what we need to be able to create PDF files
> with ICC based colors.
>> Basically all surfaces and patterns will have a color space in which
>> all the "math" related to them happens (compositing/blending for
>> surfaces, interpolation for patterns) and their colors are
>> interpreted. I think that after the creation the color space should
>> not be changed so I didn't write functions to permit it as this
>> operation seems to have no meaning in terms of colors.
> Changing the color space of surfaces after creation is not compatible with
> PDF and probably other vector backends.
>> Are there use cases where the proposed API is inadequate?
> We a need way to specify the color space when creating a surface. In PDF
> each page can have a different color space for the top level page group. So
> something like:
>  void
>  cairo_pdf_surface_set_color_space (cairo_surface_t     *surface,
>                                    cairo_color_space_t *color_space);
> or a generic function for all surfaces:
>  void
>  cairo_surface_set_color_space (cairo_surface_t     *surface,
>                                cairo_color_space_t *color_space);
> While the proposed API supports ICC CMYK colors, some users may want device
> CMYK colors. This is easy to add.
>  cairo_color_space_t *
>  cairo_color_space_create_device_cmyk ()
>  cairo_color_t *
>  cairo_color_create_cmyka (double cyan,
>                           double magenta,
>                           double yellow,
>                           double black,
>                           double alpha);
> Also missing are spot and DeviceN colors.
> In PDF spot colors are known as separation color spaces. A separation color
> space is defined by a name object that specifies the colorant, an
> alternative color space, and tint transform.
> A color value in a separation color space consists of a tint value between 0
> and 1. Zero means the minimum amount of colorant. One means the maximum
> amount of colorant.
> Name objects can be up to 127 8-bit characters excluding NULL. If the device
> does not support the colorant the alternative color is used. This color is
> in the alternate color space and is obtained by transforming the tint value
> by the tint transform function. The alternative color space must not be a
> DeviceN or separation color space.
> Specifying a transform function in an API is complicated and probably not
> necessary for supporting spot colors. We could just specify an alternative
> color for the separation color space and use the tint value as an alpha
> value for the alternative color.
> A DeviceN color space allows multiple colorants in the color space. Specify
> a color in a DeviceN color space requires specifying the tint value of each
> component.
> The DeviceN API could look something like:
> /* Create a Device N color space. alternate_color_space specifies
>  * the color space to be used for the alternative colors for each
>  * component
>  */
>  cairo_color_space_t *
>  cairo_color_space_create_device_n (
>                     cairo_color_space_t *alternate_color_space)
> /* Add a colorant to the DeviceN color space. "name" is the name of the
>  * colorant. alternate_color is an array of components specifying the
>  * a color in the alternate_color_space.
>  */
>  void
>  cairo_color_space_add_colorant (cairo_space_color_t *color_space,
>                                 const char          *name,
>                                 double              *alternate_color)
> To create a DeviceN color, use the
>  cairo_color_create (cairo_color_t *color_space, double *components)
> function and specify the tint value of each component.
> Spot color spaces are the same as a DeviceN color space with one component.
> We could provide a convenience function for creating DeviceN color space
> with one color:
>  cairo_color_space_t *
>  cairo_color_space_create_spot (const char    *name,
>                                cairo_color_t *alternate);
> This allows the alternative color space and color to be specified with a
> cairo_color_t.

Three comments:

- I have yet to see CMYKA used in practice. But I guess, for the sake
of completeness, it is good to have it there....

- "use the tint value as an alpha value" - alpha is not the same as
tint, as long as you are not using overprint, and even then I'm not
sure if it is ok not to distinguish "alpha" and "tint"

- Not sure what good is to define color space in
"cairo_color_space_create_device_n()" for if you are able to define
alternative spaces in each of its colorant.

Otherwise, it looks perfect to me. I especially like Device CMYK.

More information about the cairo mailing list