(defined_color): If colormap is full, find closest match.
This commit is contained in:
parent
a992f9d90e
commit
829782956e
1 changed files with 61 additions and 8 deletions
69
src/xfns.c
69
src/xfns.c
|
@ -963,6 +963,7 @@ x_report_frame_params (f, alistptr)
|
|||
: FRAME_ICONIFIED_P (f) ? Qicon : Qnil));
|
||||
}
|
||||
|
||||
|
||||
/* Decide if color named COLOR is valid for the display associated with
|
||||
the selected frame; if so, return the rgb values in COLOR_DEF.
|
||||
If ALLOC is nonzero, allocate a new colormap cell. */
|
||||
|
@ -974,20 +975,72 @@ defined_color (f, color, color_def, alloc)
|
|||
XColor *color_def;
|
||||
int alloc;
|
||||
{
|
||||
register int foo;
|
||||
register int status;
|
||||
Colormap screen_colormap;
|
||||
Display *display = FRAME_X_DISPLAY (f);
|
||||
|
||||
BLOCK_INPUT;
|
||||
screen_colormap
|
||||
= DefaultColormap (FRAME_X_DISPLAY (f),
|
||||
XDefaultScreen (FRAME_X_DISPLAY (f)));
|
||||
screen_colormap = DefaultColormap (display, XDefaultScreen (display));
|
||||
|
||||
foo = XParseColor (FRAME_X_DISPLAY (f), screen_colormap, color, color_def);
|
||||
if (foo && alloc)
|
||||
foo = XAllocColor (FRAME_X_DISPLAY (f), screen_colormap, color_def);
|
||||
status = XParseColor (display, screen_colormap, color, color_def);
|
||||
if (status && alloc)
|
||||
{
|
||||
status = XAllocColor (display, screen_colormap, color_def);
|
||||
if (!status)
|
||||
{
|
||||
/* If we got to this point, the colormap is full, so we're
|
||||
going to try and get the next closest color.
|
||||
The algorithm used is a least-squares matching, which is
|
||||
what X uses for closest color matching with StaticColor visuals. */
|
||||
|
||||
XColor *cells;
|
||||
int no_cells;
|
||||
int nearest;
|
||||
long nearest_delta, trial_delta;
|
||||
int x;
|
||||
|
||||
no_cells = XDisplayCells (display, XDefaultScreen (display));
|
||||
cells = (XColor *) alloca (sizeof (XColor) * no_cells);
|
||||
|
||||
for (x = 0; x < no_cells; x++)
|
||||
cells[x].pixel = x;
|
||||
|
||||
XQueryColors (display, screen_colormap, cells, no_cells);
|
||||
nearest = 0;
|
||||
/* I'm assuming CSE so I'm not going to condense this. */
|
||||
nearest_delta = ((((color_def->red >> 8) - (cells[0].red >> 8))
|
||||
* ((color_def->red >> 8) - (cells[0].red >> 8)))
|
||||
+
|
||||
(((color_def->green >> 8) - (cells[0].green >> 8))
|
||||
* ((color_def->green >> 8) - (cells[0].green >> 8)))
|
||||
+
|
||||
(((color_def->blue >> 8) - (cells[0].blue >> 8))
|
||||
* ((color_def->blue >> 8) - (cells[0].blue >> 8))));
|
||||
for (x = 1; x < no_cells; x++)
|
||||
{
|
||||
trial_delta = ((((color_def->red >> 8) - (cells[x].red >> 8))
|
||||
* ((color_def->red >> 8) - (cells[x].red >> 8)))
|
||||
+
|
||||
(((color_def->green >> 8) - (cells[x].green >> 8))
|
||||
* ((color_def->green >> 8) - (cells[x].green >> 8))) +
|
||||
+
|
||||
(((color_def->blue >> 8) - (cells[x].blue >> 8))
|
||||
* ((color_def->blue >> 8) - (cells[x].blue >> 8))));
|
||||
if (trial_delta < nearest_delta)
|
||||
{
|
||||
nearest = x;
|
||||
nearest_delta = trial_delta;
|
||||
}
|
||||
}
|
||||
color_def->red = cells[nearest].red;
|
||||
color_def->green = cells[nearest].green;
|
||||
color_def->blue = cells[nearest].blue;
|
||||
status = XAllocColor (display, screen_colormap, color_def);
|
||||
}
|
||||
}
|
||||
UNBLOCK_INPUT;
|
||||
|
||||
if (foo)
|
||||
if (status)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue