A GdkColor stores an RGB
value and a pixel. Red, green, and blue are given as
16-bit unsigned integers; so they are in the range [0,
65535]. The contents of the pixel depend on the visual.
Here is GdkColor:
typedef struct _GdkColor GdkColor;
struct _GdkColor
{
gulong pixel;
gushort red;
gushort green;
gushort blue;
};
|
Before you can use a color to draw, you must:
-
Ensure that the pixel value contains an appropriate
value.
-
Ensure that the color exists in the colormap of the
drawable you intend to draw to. (A drawable is a window or pixmap you
can draw to; see the
section called Drawables and
Pixmaps.)
In Xlib, this is an enormously complicated process,
because it has to be done differently for every kind of
visual. GDK conceals things fairly well. You simply call
gdk_colormap_alloc_color() to
fill in the pixel value and add the color to the colormap
(Figure
3). Here is an example; it assumes a preexisting
GdkColormap* colormap,
which should be the colormap of the drawable you are
targetting:
GdkColor color;
/* Describe a pure red */
color.red = 65535;
color.green = 0;
color.blue = 0;
if (gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE))
{
/* Success! */
}
|
If gdk_colormap_alloc_color()
returns TRUE, then the
color was allocated and
color.pixel contains a valid value. The color can
then be used to draw. The two boolean arguments to gdk_colormap_alloc_color() specify
whether the color should be
writeable, and whether to try to find a "best match"
if the color can't be allocated. If a best match is used
instead of allocating a new color, the color's RGB values
will be changed to the best match. If you request a best
match for a non-writeable entry, allocation really should
not fail, since even on a black and white display either
black or white will be the best match; only an empty
colormap could cause failure. The only way to get an
empty colormap is to create a custom colormap yourself.
If you don't ask for the best match, failure is quite
possible on displays with a limited number of colors.
Failure is always possible with writeable colormap
entries (where best match makes no sense, because the
entry can be modified).
A writeable colormap entry is
one that you can change at any time; some visuals support
this, and some don't. The purpose of a writeable colormap
entry is to change an on-screen color without redrawing
the graphics. Some hardware stores pixels as indices into
a color lookup table, so changing the lookup table
changes how the pixels are displayed. The disadvantages
of writeable colormap entries are numerous. Most notably:
not all visuals support them, and writeable colormap
entries can't be used by other applications (read-only
entries can be shared, since other applications know the
color will remain constant). Thus, it is a good idea to
avoid allocating writeable colors. On modern hardware,
they are more trouble than they're worth; the speed gain
compared to simply redrawing your graphics will not be
noticeable.
When you're finished with a color, you can remove it from
the colormap with
gdk_colormap_free_colors(). This is only really
important for pseudo color and grayscale visuals, where
colors are in short supply and the colormap can be
modified by clients. GDK will automatically do the right
thing for each visual type, so always call this function.
A convenient way to obtain RGB values is the gdk_color_parse() function. This takes an
X color specification, and fills in the red,
green, and blue
fields of a GdkColor. An
X color specification can have many forms; one
possibility is an RGB string:
This specifies white (red, green, and blue are all at
full intensity). The RGB:
specifies a "color space," and determines the meaning of
the numbers after it. X also understands several more
obscure color spaces. If the color specification string
doesn't begin with a recognized color space, X assumes
it's a color name and looks it up in a database of names.
So you can write code like this:
GdkColor color;
if (gdk_color_parse("orange", &color))
{
if (gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE))
{
/* We have orange! */
}
}
|
As you can see,
gdk_color_parse() returns
TRUE if it figures out the string you pass it.
There is no way to know exactly what will be in the color
database, so always check this return value.