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

Andrea Canciani ranma42 at gmail.com
Mon Feb 22 03:28:16 PST 2010

On Mon, Feb 22, 2010 at 11:10 AM, Kai-Uwe Behrmann <ku.b at gmx.de> wrote:
> Thanks for the proposal. I hope my comments map obvious to your diff.
> Blending space:
> A intentional once selected then fixed blending colour space makes sense to
> me. The interpretation of output from cairo as well as some internal details
> will be easier. Most apps would take the easy route and avoid pitfalls. Its
> a good barrier.
> Users wanting several blending colour spaces would have to do that on their
> own. Beside this overall statement I am not shure how it would be possible
> to construct vector output with changing blending spaces by combining cairo
> output. For flat data that would be trivial.
> That said I can well imagine situations where parts of a document is
> rendered in one space, while other elements in an other, e.g. by combining
> documents.
> If the API allowes by some not too difficult means to produce mixed blending
> space documents (PDF, SVG?) I think that would be fine.
> +cairo_surface_create_similar_with_color_space() ?

To produce documents with multiple blending spaces with the proposed
API you would
use either cairo_surface_create_similar_with_color_space or
This would hopefully work in a straightforward way in pdf, where each
tranparency group
has its own blending space and I think the same should be possible in
most vector backends.

> cairo_color_t/cairo_t meta data:
> Rendering intents are defined by the ICC standard. But as the system is
> evolving several additional arguments are in the queue or will become to
> that. Think of black point compensation (BPC) typical supported by most
> colour managed linux graphics applications, or CMM specific options like
> lcms' preserve black one.
> So rather than placing this stuff into cairo_t
> +cairo_public void
> +cairo_set_render_intent (cairo_t                      *cr,
> +                        cairo_render_intent_t  render_intent);
> +
> I would find it much more adequate to place it into cairo_color_t.
> cairo_public void
> cairo_color_set_render_intent (cairo_color_t         *color,
>                               cairo_render_intent_t  render_intent);

Since rendering intent is actually used only when a color space
conversion is done,
basically we can choose whether select a rendering intent for all the sources
we are going to use (colors, patterns) or for all the destinations
(cairo_t, gradients (they
convert color stops to the pattern color space)).
I think it's just a matter of choosing what is more straightforward.
I asked a few people what they would do and most of them would have
put the rendering intent
in the destination, but they were not color management specialists, so
someone else might
shed some light on what is better. For what it's worth, quartz let
users choose the rendering
intent in the destination (and this is probably the reason I found it
more natural to
do so, but my friends proposed the same thing even if they didn't see
this diff and are no
quartz programmers).

> The state of rendering intent and so on can be preserved for subsequent
> usage:
> cairo_public cairo_color_t *
> cairo_color_copy (cairo_color_t *color);

It looks like copy is quite useless since...

> cairo_public void
> cairo_color_set_components (cairo_color_t *color,
>                           double *components);

... setting the components of a color is not expected to be possible.
Just create another one
(non mutable objects have a much better behaviour with respect to
retaining (aka referencing)).

> As well I would expect a means to transport non standard options (BPC) to
> the final CMM (lcms?). This could then as well help with the spot colour
> case and bring some flexibility in. Otherwise Cairo will quite often
> requests about even small adds.
> The situation is perhaps much like with specific cairo backend functions. A
> key/value pair sort of API would be good? In my personal view it would fit
> logical well to the cairo_color_t type of objects.

Non-standard options are not planned yet. They could be added later, if needed.

> rgb(a) equivalents:
> +cairo_color_create_rgba( .. )
> +cairo_color_create_rgb( .. )
> Can this simply be skipped? As I understand the cairo_set_source_rgb/a() API
> would cover these cases already and assign a assumed Rgb automatically. A
> special API for assumed Rgb would be helpful.

cairo_set_source_rgb[a] would not be removed. These functions might be
useful for
being able to abstracting color in the aopplication and not having to
deal with multiple
cases (for example when setting the source color, but also gradient stops).

> gradient colour space:
> Can users specify in which colour space a gradient is created? While mapping
> to vector output this would mean a desire to switch the actual editing
> colour space. Or is the cairo_color_space_t specified with
> +cairo_pattern_create_linear_with_color_space or
> +cairo_pattern_create_radial_with_color_space the editing space for gradient
> contruction?

I don't get what you mean by "editing". The color space of a pattern
is the color space
in which interpolation between the stops happens (thus also the color
space of the
"output" colors). The idea is: stops are converted to the gradient
color space, then
they are interpolated.

> images:
> just for comleteness; images need a cairo_profile_t assigned.

That is a backend issue, I will add constructors for backends later (plus you
will probably be able to do that also through create_similar_with_colorspace).

More information about the cairo mailing list