Reorganizing color drawing code.

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11045 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Matthias Melcher
2016-01-24 16:22:50 +00:00
parent 49cf30286b
commit 60ec452d04
13 changed files with 512 additions and 438 deletions
+4 -20
View File
@@ -133,17 +133,6 @@ protected:
int rstackptr;
static const int region_stack_max = FL_REGION_STACK_SIZE - 1;
Fl_Region rstack[FL_REGION_STACK_SIZE];
#ifdef WIN32
int numcount;
int counts[20];
#elif defined(__APPLE__)
// not needed
#elif defined(FL_PORTING)
# pragma message "FL_PORTING: define variables for Fl_Graphics_Driver if needed."
// not needed
#else
// not needed in X11
#endif
Fl_Font_Descriptor *font_descriptor_;
protected:
@@ -175,8 +164,6 @@ protected:
friend void fl_draw(int angle, const char *str, int n, int x, int y);
friend void fl_rtl_draw(const char *str, int n, int x, int y);
friend void fl_font(Fl_Font face, Fl_Fontsize size);
friend void fl_color(Fl_Color c);
friend void fl_color(uchar r, uchar g, uchar b);
friend void fl_draw_image(const uchar* buf, int X,int Y,int W,int H, int D, int L);
friend void fl_draw_image_mono(const uchar* buf, int X,int Y,int W,int H, int D, int L);
@@ -203,11 +190,6 @@ protected:
virtual void draw(int angle, const char *str, int n, int x, int y) {}
/** \brief see fl_rtl_draw(const char *str, int n, int x, int y). */
virtual void rtl_draw(const char *str, int n, int x, int y) {};
/** \brief see fl_color(Fl_Color c). */
virtual void color(Fl_Color c) {color_ = c;}
/** \brief see fl_color(uchar r, uchar g, uchar b). */
virtual void color(uchar r, uchar g, uchar b) {}
// Images
/** \brief see fl_draw_image(const uchar* buf, int X,int Y,int W,int H, int D, int L). */
@@ -261,8 +243,6 @@ public:
virtual int height() {return size();}
/** \brief see fl_descent(). */
virtual int descent() {return 0;}
/** \brief see fl_color(void). */
Fl_Color color() {return color_;}
/** Returns a pointer to the current Fl_Font_Descriptor for the graphics driver */
inline Fl_Font_Descriptor *font_descriptor() { return font_descriptor_;}
/** Sets the current Fl_Font_Descriptor for the graphics driver */
@@ -336,6 +316,10 @@ public:
virtual void curve(double X0, double Y0, double X1, double Y1, double X2, double Y2, double X3, double Y3);
// --- implementation is in src/fl_line_style.cxx which includes src/cfg_gfx/xxx_line_style.cxx
virtual void line_style(int style, int width=0, char* dashes=0) = 0;
// --- implementation is in src/fl_color.cxx which includes src/cfg_gfx/xxx_color.cxx
virtual void color(Fl_Color c) { color_ = c; }
virtual Fl_Color color() { return color_; }
virtual void color(uchar r, uchar g, uchar b) = 0;
protected:
// --- implementation is in src/fl_vertex.cxx which includes src/cfg_gfx/xxx_rect.cxx
+3 -2
View File
@@ -53,10 +53,11 @@ const char *Fl_OpenGL_Display_Device::class_id = "Fl_OpenGL_Display_Device";
#endif
// ------ end of separate file! ------------------------------------------------
#include "cfg_gfx/opengl_arci.cxx"
#include "cfg_gfx/opengl_color.cxx"
#include "cfg_gfx/opengl_line_style.cxx"
#include "cfg_gfx/opengl_rect.cxx"
#include "cfg_gfx/opengl_vertex.cxx"
#include "cfg_gfx/opengl_arci.cxx"
#include "cfg_gfx/opengl_line_style.cxx"
#if defined(__APPLE__)
+6
View File
@@ -34,6 +34,9 @@
This class is implemented only on the MSWindows platform.
*/
class FL_EXPORT Fl_GDI_Graphics_Driver : public Fl_Graphics_Driver {
protected:
int numcount;
int counts[20];
public:
static const char *class_id;
const char *class_name() {return class_id;};
@@ -101,6 +104,9 @@ protected:
void pie(int x, int y, int w, int h, double a1, double a2);
// --- implementation is in src/fl_line_style.cxx which includes src/cfg_gfx/xxx_line_style.cxx
void line_style(int style, int width=0, char* dashes=0);
// --- implementation is in src/fl_color.cxx which includes src/cfg_gfx/xxx_color.cxx
void color(Fl_Color c);
void color(uchar r, uchar g, uchar b);
};
@@ -1,9 +1,9 @@
//
// "$Id$"
//
// WIN32 color functions for the Fast Light Tool Kit (FLTK).
// MSWidnows' GDI color functions for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2010 by Bill Spitzak and others.
// Copyright 1998-2016 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -21,15 +21,17 @@
// changes can be made. Not to be confused with the X colormap, which
// I try to hide completely.
// SGI compiler seems to have problems with unsigned char arguments
// being used to index arrays. So I always copy them to an integer
// before use.
#include <config.h>
#include <FL/Fl.H>
#include <FL/x.H>
#include <FL/fl_draw.H>
// FIXME: all the global functions in this file should probably be protected
// members of the driver class. Starting with 1.4 we will allow multiple drivers
// to co-exist, creating conflicts with multipe mapping.
// FIXME: maybe we can forget about color mapping and assume RGB?
static unsigned fl_cmap[256] = {
#include "fl_cmap.h" // this is a file produced by "cmap.cxx":
};
+3 -3
View File
@@ -36,9 +36,6 @@ public:
static const char *class_id;
const char *class_name() {return class_id;};
void draw(const char* str, int n, int x, int y);
void color(Fl_Color c);
void color(uchar r, uchar g, uchar b);
// --- line and polygon drawing with integer coordinates
void point(int x, int y);
void rect(int x, int y, int w, int h);
@@ -85,6 +82,9 @@ public:
void pie(int x, int y, int w, int h, double a1, double a2);
// --- implementation is in src/fl_line_style.cxx which includes src/cfg_gfx/xxx_line_style.cxx
void line_style(int style, int width=0, char* dashes=0);
// --- implementation is in src/fl_color.cxx which includes src/cfg_gfx/xxx_color.cxx
void color(Fl_Color c);
void color(uchar r, uchar g, uchar b);
};
+70
View File
@@ -0,0 +1,70 @@
//
// "$Id$"
//
// Color functions for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2016 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
// file is missing or damaged, see the license at:
//
// http://www.fltk.org/COPYING.php
//
// Please report all bugs and problems on the following page:
//
// http://www.fltk.org/str.php
//
/**
\file fl_color.cxx
\brief Color handling
*/
#include "opengl.H"
#include <FL/gl.h>
// Implementation of fl_color(i), fl_color(r,g,b).
void Fl_OpenGL_Graphics_Driver::color(Fl_Color i) {
// FIXME: do we need the code below?
/*
#if HAVE_GL_OVERLAY
#if defined(WIN32)
if (fl_overlay && fl_overlay_depth) {
if (fl_overlay_depth < 8) {
// only black & white produce the expected colors. This could
// be improved by fixing the colormap set in Fl_Gl_Overlay.cxx
int size = 1<<fl_overlay_depth;
if (!i) glIndexi(size-2);
else if (i >= size-2) glIndexi(size-1);
else glIndexi(i);
} else {
glIndexi(i ? i : FL_GRAY_RAMP);
}
return;
}
#else
if (fl_overlay) {glIndexi(int(fl_xpixel(i))); return;}
#endif
#endif
*/
if (i & 0xffffff00) {
unsigned rgb = (unsigned)i;
fl_color((uchar)(rgb >> 24), (uchar)(rgb >> 16), (uchar)(rgb >> 8));
} else {
Fl_Graphics_Driver::color(i);
uchar red, green, blue;
Fl::get_color(i, red, green, blue);
glColor3ub(red, green, blue);
}
}
void Fl_OpenGL_Graphics_Driver::color(uchar r,uchar g,uchar b) {
Fl_Graphics_Driver::color( fl_rgb_color(r, g, b) );
glColor3ub(r,g,b);
}
//
// End of "$Id$".
//
-9
View File
@@ -32,15 +32,6 @@ void Fl_OpenGL_Graphics_Driver::draw(const char* str, int n, int x, int y) {
gl_draw(str, n, x, y);
}
void Fl_OpenGL_Graphics_Driver::color(Fl_Color c) {
gl_color(c);
}
void Fl_OpenGL_Graphics_Driver::color(uchar r, uchar g, uchar b) {
unsigned int c = (r<<24)|(g<<16)|(b<<8);
gl_color(c);
}
// --- line and polygon drawing with integer coordinates
void Fl_OpenGL_Graphics_Driver::point(int x, int y) {
+5 -2
View File
@@ -43,8 +43,8 @@ class FL_EXPORT Fl_Quartz_Graphics_Driver : public Fl_Graphics_Driver {
public:
static const char *class_id;
const char *class_name() {return class_id;};
void color(Fl_Color c);
void color(uchar r, uchar g, uchar b);
// void color(Fl_Color c);
// void color(uchar r, uchar g, uchar b);
void draw(const char* str, int n, int x, int y);
#ifdef __APPLE__
void draw(const char *str, int n, float x, float y);
@@ -111,6 +111,9 @@ protected:
void pie(int x, int y, int w, int h, double a1, double a2);
// --- implementation is in src/fl_line_style.cxx which includes src/cfg_gfx/xxx_line_style.cxx
void line_style(int style, int width=0, char* dashes=0);
// --- implementation is in src/fl_color.cxx which includes src/cfg_gfx/xxx_color.cxx
void color(Fl_Color c);
void color(uchar r, uchar g, uchar b);
};
@@ -3,7 +3,7 @@
//
// MacOS color functions for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2010 by Bill Spitzak and others.
// Copyright 1998-2016 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -30,7 +30,7 @@
#include <FL/fl_draw.H>
static unsigned fl_cmap[256] = {
#include "fl_cmap.h" // this is a file produced by "cmap.cxx":
#include "../fl_cmap.h" // this is a file produced by "cmap.cxx":
};
void Fl_Quartz_Graphics_Driver::color(Fl_Color i) {
@@ -68,6 +68,7 @@ void Fl_Quartz_Graphics_Driver::color(uchar r, uchar g, uchar b) {
CGContextSetRGBStrokeColor(fl_gc, fr, fg, fb, 1.0f);
}
// FIXME: this function should not be here! It's not part of the driver.
void Fl::set_color(Fl_Color i, unsigned c) {
if (fl_cmap[i] != c) {
fl_cmap[i] = c;
+3
View File
@@ -100,6 +100,9 @@ protected:
void pie(int x, int y, int w, int h, double a1, double a2);
// --- implementation is in src/fl_line_style.cxx which includes src/cfg_gfx/xxx_line_style.cxx
void line_style(int style, int width=0, char* dashes=0);
// --- implementation is in src/fl_color.cxx which includes src/cfg_gfx/xxx_color.cxx
void color(Fl_Color c);
void color(uchar r, uchar g, uchar b);
};
+351
View File
@@ -0,0 +1,351 @@
//
// "$Id$"
//
// Color functions for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2010 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
// file is missing or damaged, see the license at:
//
// http://www.fltk.org/COPYING.php
//
// Please report all bugs and problems on the following page:
//
// http://www.fltk.org/str.php
//
// Implementation of fl_color(i), fl_color(r,g,b).
// FIXME: all the global functions in this file should probably be protected
// members of the driver class. Starting with 1.4 we will allow multiple drivers
// to co-exist, creating conflicts with multipe mapping.
// FIXME: maybe we can forget about color mapping and assume RGB?
// Also code to look at the X visual and figure out the best way to turn
// a color into a pixel value.
// SGI compiler seems to have problems with unsigned char arguments
// being used to index arrays. So I always copy them to an integer
// before use.
# include "Fl_XColor.H"
# include <FL/Fl.H>
# include <FL/x.H>
# include <FL/fl_draw.H>
////////////////////////////////////////////////////////////////
// figure_out_visual() calculates masks & shifts for generating
// pixels in true-color visuals:
uchar fl_redmask; /**< color mask used in current color map handling */
uchar fl_greenmask; /**< color mask used in current color map handling */
uchar fl_bluemask; /**< color mask used in current color map handling */
int fl_redshift; /**< color shift used in current color map handling */
int fl_greenshift; /**< color shift used in current color map handling */
int fl_blueshift; /**< color shift used in current color map handling */
int fl_extrashift; /**< color shift used in current color map handling */
static uchar beenhere;
static void figure_out_visual() {
beenhere = 1;
if (!fl_visual->red_mask || !fl_visual->green_mask || !fl_visual->blue_mask){
# if USE_COLORMAP
fl_redmask = 0;
return;
# else
Fl::fatal("Requires true color visual");
# endif
}
// get the bit masks into a more useful form:
int i,j,m;
for (i = 0, m = 1; m; i++, m<<=1) if (fl_visual->red_mask & m) break;
for (j = i; m; j++, m<<=1) if (!(fl_visual->red_mask & m)) break;
fl_redshift = j-8;
fl_redmask = (j-i >= 8) ? 0xFF : 0xFF-(255>>(j-i));
for (i = 0, m = 1; m; i++, m<<=1) if (fl_visual->green_mask & m) break;
for (j = i; m; j++, m<<=1) if (!(fl_visual->green_mask & m)) break;
fl_greenshift = j-8;
fl_greenmask = (j-i >= 8) ? 0xFF : 0xFF-(255>>(j-i));
for (i = 0, m = 1; m; i++, m<<=1) if (fl_visual->blue_mask & m) break;
for (j = i; m; j++, m<<=1) if (!(fl_visual->blue_mask & m)) break;
fl_blueshift = j-8;
fl_bluemask = (j-i >= 8) ? 0xFF : 0xFF-(255>>(j-i));
i = fl_redshift;
if (fl_greenshift < i) i = fl_greenshift;
if (fl_blueshift < i) i = fl_blueshift;
if (i < 0) {
fl_extrashift = -i;
fl_redshift -= i; fl_greenshift -= i; fl_blueshift -= i;
} else
fl_extrashift = 0;
}
static unsigned fl_cmap[256] = {
#include "fl_cmap.h" // this is a file produced by "cmap.cxx":
};
# if HAVE_OVERLAY
/** HAVE_OVERLAY determines whether fl_xmap is one or two planes */
Fl_XColor fl_xmap[2][256];
/** HAVE_OVERLAY determines whether fl_overlay is variable or defined as 0 */
uchar fl_overlay;
Colormap fl_overlay_colormap;
XVisualInfo* fl_overlay_visual;
ulong fl_transparent_pixel;
# else
/** HAVE_OVERLAY determines whether fl_xmap is one or two planes */
Fl_XColor fl_xmap[1][256];
/** HAVE_OVERLAY determines whether fl_overlay is variable or defined as 0 */
# define fl_overlay 0
# endif
void Fl_Xlib_Graphics_Driver::color(Fl_Color i) {
if (i & 0xffffff00) {
unsigned rgb = (unsigned)i;
fl_color((uchar)(rgb >> 24), (uchar)(rgb >> 16), (uchar)(rgb >> 8));
} else {
Fl_Graphics_Driver::color(i);
if(!fl_gc) return; // don't get a default gc if current window is not yet created/valid
XSetForeground(fl_display, fl_gc, fl_xpixel(i));
}
}
void Fl_Xlib_Graphics_Driver::color(uchar r,uchar g,uchar b) {
Fl_Graphics_Driver::color( fl_rgb_color(r, g, b) );
if(!fl_gc) return; // don't get a default gc if current window is not yet created/valid
XSetForeground(fl_display, fl_gc, fl_xpixel(r,g,b));
}
/** \addtogroup fl_attributes
@{ */
////////////////////////////////////////////////////////////////
// Get an rgb color. This is easy for a truecolor visual. For
// colormapped it picks the closest color out of the cube in the
// fltk colormap. However if this color cube entry has been
// requested before, you will get the earlier requested color, and
// even this may be approximated if the X colormap was full.
/**
Returns the X pixel number used to draw the given rgb color.
This is the X pixel that fl_color() would use.
\param[in] r,g,b color components
\return X pixel number
*/
ulong fl_xpixel(uchar r,uchar g,uchar b) {
if (!beenhere) figure_out_visual();
# if USE_COLORMAP
if (!fl_redmask) {
// find closest entry in the colormap:
Fl_Color i =
fl_color_cube(r*FL_NUM_RED/256,g*FL_NUM_GREEN/256,b*FL_NUM_BLUE/256);
Fl_XColor &xmap = fl_xmap[fl_overlay][i];
if (xmap.mapped) return xmap.pixel;
// if not black or white, change the entry to be an exact match:
if (i != FL_COLOR_CUBE && i != 0xFF)
fl_cmap[i] = (r<<24)|(g<<16)|(b<<8);
return fl_xpixel(i); // allocate an X color
}
# endif
return
(((r&fl_redmask) << fl_redshift)+
((g&fl_greenmask)<<fl_greenshift)+
((b&fl_bluemask)<< fl_blueshift)
) >> fl_extrashift;
}
////////////////////////////////////////////////////////////////
// Get a color out of the fltk colormap. Again for truecolor
// visuals this is easy. For colormap this actually tries to allocate
// an X color, and does a least-squares match to find the closest
// color if X cannot allocate that color.
// calculate what color is actually on the screen for a mask:
static inline uchar realcolor(uchar color, uchar mask) {
# if 0
// accurate version if the display has linear gamma, but fl_draw_image
// works better with the simpler version on most screens...
uchar m = mask;
uchar result = color&m;
for (;;) {
while (m&mask) {m>>=1; color>>=1;}
if (!m) break;
mask = m;
result |= color&m;
}
return result;
# else
return (color&mask) | ( (~mask)&(mask>>1) );
# endif
}
/**
Returns the X pixel number used to draw the given FLTK color index.
This is the X pixel that fl_color() would use.
\param[in] i color index
\return X pixel number
*/
ulong fl_xpixel(Fl_Color i) {
if (i & 0xffffff00) {
return fl_xpixel((i >> 24) & 255, (i >> 16) & 255, (i >> 8) & 255);
}
Fl_XColor &xmap = fl_xmap[fl_overlay][i];
if (xmap.mapped) return xmap.pixel;
if (!beenhere) figure_out_visual();
uchar r,g,b;
{unsigned c = fl_cmap[i]; r=uchar(c>>24); g=uchar(c>>16); b=uchar(c>>8);}
# if USE_COLORMAP
Colormap colormap = fl_colormap;
# if HAVE_OVERLAY
if (fl_overlay) colormap = fl_overlay_colormap; else
# endif
if (fl_redmask) {
# endif
// return color for a truecolor visual:
xmap.mapped = 2; // 2 prevents XFreeColor from being called
xmap.r = realcolor(r, fl_redmask);
xmap.g = realcolor(g, fl_greenmask);
xmap.b = realcolor(b, fl_bluemask);
return xmap.pixel =
(((r&fl_redmask) << fl_redshift)+
((g&fl_greenmask)<<fl_greenshift)+
((b&fl_bluemask)<< fl_blueshift)
) >> fl_extrashift;
# if USE_COLORMAP
}
# if HAVE_OVERLAY
static XColor* ac[2];
XColor*& allcolors = ac[fl_overlay];
static int nc[2];
int& numcolors = nc[fl_overlay];
# else
static XColor *allcolors;
static int numcolors;
# endif
// I don't try to allocate colors with XAllocColor once it fails
// with any color. It is possible that it will work, since a color
// may have been freed, but some servers are extremely slow and this
// avoids one round trip:
if (!numcolors) { // don't try after a failure
XColor xcol;
xcol.red = r<<8; xcol.green = g<<8; xcol.blue = b<<8;
if (XAllocColor(fl_display, colormap, &xcol)) {
xmap.mapped = 1;
xmap.r = xcol.red>>8;
xmap.g = xcol.green>>8;
xmap.b = xcol.blue>>8;
return xmap.pixel = xcol.pixel;
}
// I only read the colormap once. Again this is due to the slowness
// of round-trips to the X server, even though other programs may alter
// the colormap after this and make decisions here wrong.
# if HAVE_OVERLAY
if (fl_overlay) numcolors = fl_overlay_visual->colormap_size; else
# endif
numcolors = fl_visual->colormap_size;
if (!allcolors) allcolors = new XColor[numcolors];
for (int p = numcolors; p--;) allcolors[p].pixel = p;
XQueryColors(fl_display, colormap, allcolors, numcolors);
}
// find least-squares match:
int mindist = 0x7FFFFFFF;
unsigned int bestmatch = 0;
for (unsigned int n = numcolors; n--;) {
# if HAVE_OVERLAY
if (fl_overlay && n == fl_transparent_pixel) continue;
# endif
XColor &a = allcolors[n];
int d, t;
t = int(r)-int(a.red>>8); d = t*t;
t = int(g)-int(a.green>>8); d += t*t;
t = int(b)-int(a.blue>>8); d += t*t;
if (d <= mindist) {bestmatch = n; mindist = d;}
}
XColor &p = allcolors[bestmatch];
// It appears to "work" to not call this XAllocColor, which will
// avoid another round-trip to the server. But then X does not
// know that this program "owns" this value, and can (and will)
// change it when the program that did allocate it exits:
if (XAllocColor(fl_display, colormap, &p)) {
xmap.mapped = 1;
xmap.pixel = p.pixel;
} else {
// However, if that XAllocColor fails, I have to give up and
// assume the pixel is ok for the duration of the program. This
// is due to bugs (?) in the Solaris X and some X terminals
// where XAllocColor *always* fails when the colormap is full,
// even if we ask for a color already in it...
xmap.mapped = 2; // 2 prevents XFreeColor from being called
xmap.pixel = bestmatch;
}
xmap.r = p.red>>8;
xmap.g = p.green>>8;
xmap.b = p.blue>>8;
return xmap.pixel;
# endif
}
/**
Free color \p i if used, and clear mapping table entry.
\param[in] i color index
\param[in] overlay 0 for normal, 1 for overlay color
*/
void Fl::free_color(Fl_Color i, int overlay) {
# if HAVE_OVERLAY
# else
if (overlay) return;
# endif
if (fl_xmap[overlay][i].mapped) {
# if USE_COLORMAP
# if HAVE_OVERLAY
Colormap colormap = overlay ? fl_overlay_colormap : fl_colormap;
# else
Colormap colormap = fl_colormap;
# endif
if (fl_xmap[overlay][i].mapped == 1)
XFreeColors(fl_display, colormap, &(fl_xmap[overlay][i].pixel), 1, 0);
# endif
fl_xmap[overlay][i].mapped = 0;
}
}
/**
Set color mapping table entry \p i to color \p c
\param[in] i color index
\param[in] c color
*/
void Fl::set_color(Fl_Color i, unsigned c) {
if (fl_cmap[i] != c) {
free_color(i,0);
# if HAVE_OVERLAY
free_color(i,1);
# endif
fl_cmap[i] = c;
}
}
/**
@}
*/
//
// End of "$Id$".
//
+27 -315
View File
@@ -23,334 +23,45 @@
// Implementation of fl_color(i), fl_color(r,g,b).
#ifdef WIN32
# include "fl_color_win32.cxx"
#elif defined(__APPLE__)
# include "fl_color_mac.cxx"
#elif defined(FL_PORTING)
# pragma message "FL_PORTING: implement color handling in your own file based on fl_color.cxx"
# include "fl_color_porting.cxx"
#else
#include <config.h>
#include "config_lib.h"
// Also code to look at the X visual and figure out the best way to turn
// a color into a pixel value.
// SGI compiler seems to have problems with unsigned char arguments
// being used to index arrays. So I always copy them to an integer
// before use.
// -----------------------------------------------------------------------------
# include "Fl_XColor.H"
# include <FL/Fl.H>
# include <FL/x.H>
# include <FL/fl_draw.H>
////////////////////////////////////////////////////////////////
// figure_out_visual() calculates masks & shifts for generating
// pixels in true-color visuals:
#ifdef FL_CFG_GFX_QUARTZ
uchar fl_redmask; /**< color mask used in current color map handling */
uchar fl_greenmask; /**< color mask used in current color map handling */
uchar fl_bluemask; /**< color mask used in current color map handling */
# include "cfg_gfx/quartz_color.cxx"
int fl_redshift; /**< color shift used in current color map handling */
int fl_greenshift; /**< color shift used in current color map handling */
int fl_blueshift; /**< color shift used in current color map handling */
int fl_extrashift; /**< color shift used in current color map handling */
static uchar beenhere;
static void figure_out_visual() {
beenhere = 1;
if (!fl_visual->red_mask || !fl_visual->green_mask || !fl_visual->blue_mask){
# if USE_COLORMAP
fl_redmask = 0;
return;
# else
Fl::fatal("Requires true color visual");
# endif
}
// get the bit masks into a more useful form:
int i,j,m;
for (i = 0, m = 1; m; i++, m<<=1) if (fl_visual->red_mask & m) break;
for (j = i; m; j++, m<<=1) if (!(fl_visual->red_mask & m)) break;
fl_redshift = j-8;
fl_redmask = (j-i >= 8) ? 0xFF : 0xFF-(255>>(j-i));
for (i = 0, m = 1; m; i++, m<<=1) if (fl_visual->green_mask & m) break;
for (j = i; m; j++, m<<=1) if (!(fl_visual->green_mask & m)) break;
fl_greenshift = j-8;
fl_greenmask = (j-i >= 8) ? 0xFF : 0xFF-(255>>(j-i));
for (i = 0, m = 1; m; i++, m<<=1) if (fl_visual->blue_mask & m) break;
for (j = i; m; j++, m<<=1) if (!(fl_visual->blue_mask & m)) break;
fl_blueshift = j-8;
fl_bluemask = (j-i >= 8) ? 0xFF : 0xFF-(255>>(j-i));
i = fl_redshift;
if (fl_greenshift < i) i = fl_greenshift;
if (fl_blueshift < i) i = fl_blueshift;
if (i < 0) {
fl_extrashift = -i;
fl_redshift -= i; fl_greenshift -= i; fl_blueshift -= i;
} else
fl_extrashift = 0;
}
static unsigned fl_cmap[256] = {
#include "fl_cmap.h" // this is a file produced by "cmap.cxx":
};
# if HAVE_OVERLAY
/** HAVE_OVERLAY determines whether fl_xmap is one or two planes */
Fl_XColor fl_xmap[2][256];
/** HAVE_OVERLAY determines whether fl_overlay is variable or defined as 0 */
uchar fl_overlay;
Colormap fl_overlay_colormap;
XVisualInfo* fl_overlay_visual;
ulong fl_transparent_pixel;
# else
/** HAVE_OVERLAY determines whether fl_xmap is one or two planes */
Fl_XColor fl_xmap[1][256];
/** HAVE_OVERLAY determines whether fl_overlay is variable or defined as 0 */
# define fl_overlay 0
#endif
void Fl_Xlib_Graphics_Driver::color(Fl_Color i) {
if (i & 0xffffff00) {
unsigned rgb = (unsigned)i;
fl_color((uchar)(rgb >> 24), (uchar)(rgb >> 16), (uchar)(rgb >> 8));
} else {
Fl_Graphics_Driver::color(i);
if(!fl_gc) return; // don't get a default gc if current window is not yet created/valid
XSetForeground(fl_display, fl_gc, fl_xpixel(i));
}
}
void Fl_Xlib_Graphics_Driver::color(uchar r,uchar g,uchar b) {
Fl_Graphics_Driver::color( fl_rgb_color(r, g, b) );
if(!fl_gc) return; // don't get a default gc if current window is not yet created/valid
XSetForeground(fl_display, fl_gc, fl_xpixel(r,g,b));
}
// -----------------------------------------------------------------------------
#ifdef FL_CFG_GFX_GDI
# include "cfg_gfx/gdi_color.cxx"
#endif
// -----------------------------------------------------------------------------
#ifdef FL_CFG_GFX_XLIB
# include "cfg_gfx/xlib_color.cxx"
#endif
// -----------------------------------------------------------------------------
/** \addtogroup fl_attributes
@{ */
////////////////////////////////////////////////////////////////
// Get an rgb color. This is easy for a truecolor visual. For
// colormapped it picks the closest color out of the cube in the
// fltk colormap. However if this color cube entry has been
// requested before, you will get the earlier requested color, and
// even this may be approximated if the X colormap was full.
/**
Returns the X pixel number used to draw the given rgb color.
This is the X pixel that fl_color() would use.
\param[in] r,g,b color components
\return X pixel number
*/
ulong fl_xpixel(uchar r,uchar g,uchar b) {
if (!beenhere) figure_out_visual();
# if USE_COLORMAP
if (!fl_redmask) {
// find closest entry in the colormap:
Fl_Color i =
fl_color_cube(r*FL_NUM_RED/256,g*FL_NUM_GREEN/256,b*FL_NUM_BLUE/256);
Fl_XColor &xmap = fl_xmap[fl_overlay][i];
if (xmap.mapped) return xmap.pixel;
// if not black or white, change the entry to be an exact match:
if (i != FL_COLOR_CUBE && i != 0xFF)
fl_cmap[i] = (r<<24)|(g<<16)|(b<<8);
return fl_xpixel(i); // allocate an X color
}
# endif
return
(((r&fl_redmask) << fl_redshift)+
((g&fl_greenmask)<<fl_greenshift)+
((b&fl_bluemask)<< fl_blueshift)
) >> fl_extrashift;
}
////////////////////////////////////////////////////////////////
// Get a color out of the fltk colormap. Again for truecolor
// visuals this is easy. For colormap this actually tries to allocate
// an X color, and does a least-squares match to find the closest
// color if X cannot allocate that color.
// calculate what color is actually on the screen for a mask:
static inline uchar realcolor(uchar color, uchar mask) {
# if 0
// accurate version if the display has linear gamma, but fl_draw_image
// works better with the simpler version on most screens...
uchar m = mask;
uchar result = color&m;
for (;;) {
while (m&mask) {m>>=1; color>>=1;}
if (!m) break;
mask = m;
result |= color&m;
}
return result;
# else
return (color&mask) | ( (~mask)&(mask>>1) );
# endif
}
/**
Returns the X pixel number used to draw the given FLTK color index.
This is the X pixel that fl_color() would use.
\param[in] i color index
\return X pixel number
*/
ulong fl_xpixel(Fl_Color i) {
if (i & 0xffffff00) {
return fl_xpixel((i >> 24) & 255, (i >> 16) & 255, (i >> 8) & 255);
}
Fl_XColor &xmap = fl_xmap[fl_overlay][i];
if (xmap.mapped) return xmap.pixel;
if (!beenhere) figure_out_visual();
uchar r,g,b;
{unsigned c = fl_cmap[i]; r=uchar(c>>24); g=uchar(c>>16); b=uchar(c>>8);}
# if USE_COLORMAP
Colormap colormap = fl_colormap;
# if HAVE_OVERLAY
if (fl_overlay) colormap = fl_overlay_colormap; else
# endif
if (fl_redmask) {
# endif
// return color for a truecolor visual:
xmap.mapped = 2; // 2 prevents XFreeColor from being called
xmap.r = realcolor(r, fl_redmask);
xmap.g = realcolor(g, fl_greenmask);
xmap.b = realcolor(b, fl_bluemask);
return xmap.pixel =
(((r&fl_redmask) << fl_redshift)+
((g&fl_greenmask)<<fl_greenshift)+
((b&fl_bluemask)<< fl_blueshift)
) >> fl_extrashift;
# if USE_COLORMAP
}
# if HAVE_OVERLAY
static XColor* ac[2];
XColor*& allcolors = ac[fl_overlay];
static int nc[2];
int& numcolors = nc[fl_overlay];
# else
static XColor *allcolors;
static int numcolors;
# endif
// I don't try to allocate colors with XAllocColor once it fails
// with any color. It is possible that it will work, since a color
// may have been freed, but some servers are extremely slow and this
// avoids one round trip:
if (!numcolors) { // don't try after a failure
XColor xcol;
xcol.red = r<<8; xcol.green = g<<8; xcol.blue = b<<8;
if (XAllocColor(fl_display, colormap, &xcol)) {
xmap.mapped = 1;
xmap.r = xcol.red>>8;
xmap.g = xcol.green>>8;
xmap.b = xcol.blue>>8;
return xmap.pixel = xcol.pixel;
}
// I only read the colormap once. Again this is due to the slowness
// of round-trips to the X server, even though other programs may alter
// the colormap after this and make decisions here wrong.
# if HAVE_OVERLAY
if (fl_overlay) numcolors = fl_overlay_visual->colormap_size; else
# endif
numcolors = fl_visual->colormap_size;
if (!allcolors) allcolors = new XColor[numcolors];
for (int p = numcolors; p--;) allcolors[p].pixel = p;
XQueryColors(fl_display, colormap, allcolors, numcolors);
}
// find least-squares match:
int mindist = 0x7FFFFFFF;
unsigned int bestmatch = 0;
for (unsigned int n = numcolors; n--;) {
# if HAVE_OVERLAY
if (fl_overlay && n == fl_transparent_pixel) continue;
# endif
XColor &a = allcolors[n];
int d, t;
t = int(r)-int(a.red>>8); d = t*t;
t = int(g)-int(a.green>>8); d += t*t;
t = int(b)-int(a.blue>>8); d += t*t;
if (d <= mindist) {bestmatch = n; mindist = d;}
}
XColor &p = allcolors[bestmatch];
// It appears to "work" to not call this XAllocColor, which will
// avoid another round-trip to the server. But then X does not
// know that this program "owns" this value, and can (and will)
// change it when the program that did allocate it exits:
if (XAllocColor(fl_display, colormap, &p)) {
xmap.mapped = 1;
xmap.pixel = p.pixel;
} else {
// However, if that XAllocColor fails, I have to give up and
// assume the pixel is ok for the duration of the program. This
// is due to bugs (?) in the Solaris X and some X terminals
// where XAllocColor *always* fails when the colormap is full,
// even if we ask for a color already in it...
xmap.mapped = 2; // 2 prevents XFreeColor from being called
xmap.pixel = bestmatch;
}
xmap.r = p.red>>8;
xmap.g = p.green>>8;
xmap.b = p.blue>>8;
return xmap.pixel;
# endif
}
/**
Free color \p i if used, and clear mapping table entry.
\param[in] i color index
\param[in] overlay 0 for normal, 1 for overlay color
*/
void Fl::free_color(Fl_Color i, int overlay) {
# if HAVE_OVERLAY
# else
if (overlay) return;
# endif
if (fl_xmap[overlay][i].mapped) {
# if USE_COLORMAP
# if HAVE_OVERLAY
Colormap colormap = overlay ? fl_overlay_colormap : fl_colormap;
# else
Colormap colormap = fl_colormap;
# endif
if (fl_xmap[overlay][i].mapped == 1)
XFreeColors(fl_display, colormap, &(fl_xmap[overlay][i].pixel), 1, 0);
# endif
fl_xmap[overlay][i].mapped = 0;
}
}
/**
Set color mapping table entry \p i to color \p c
\param[in] i color index
\param[in] c color
*/
void Fl::set_color(Fl_Color i, unsigned c) {
if (fl_cmap[i] != c) {
free_color(i,0);
# if HAVE_OVERLAY
free_color(i,1);
# endif
fl_cmap[i] = c;
}
}
#endif // end of X-specific code
/**
Returns the RGB value(s) for the given FLTK color index.
@@ -460,6 +171,7 @@ Fl_Color fl_contrast(Fl_Color fg, Fl_Color bg) {
/**
@}
*/
//
// End of "$Id$".
//
-50
View File
@@ -1,50 +0,0 @@
//
// "$Id$"
//
// MacOS color functions for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2010 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
// file is missing or damaged, see the license at:
//
// http://www.fltk.org/COPYING.php
//
// Please report all bugs and problems on the following page:
//
// http://www.fltk.org/str.php
//
// The fltk "colormap". This allows ui colors to be stored in 8-bit
// locations, and provides a level of indirection so that global color
// changes can be made. Not to be confused with the X colormap, which
// I try to hide completely.
// matt: Neither Quartz nor Quickdraw support colormaps in this implementation
// matt: Quartz support done
#include <config.h>
#include <FL/Fl.H>
#include <FL/x.H>
#include <FL/fl_draw.H>
static unsigned fl_cmap[256] = {
#include "fl_cmap.h" // this is a file produced by "cmap.cxx":
};
//void Fl_XXX_Graphics_Driver::color(Fl_Color i) {
//}
//void Fl_XXX_Graphics_Driver::color(uchar r, uchar g, uchar b) {
//}
void Fl::set_color(Fl_Color i, unsigned c) {
if (fl_cmap[i] != c) {
fl_cmap[i] = c;
}
}
//
// End of "$Id$".
//