diff options
| author | Matthias Melcher <fltk@matthiasm.com> | 2016-01-24 16:22:50 +0000 |
|---|---|---|
| committer | Matthias Melcher <fltk@matthiasm.com> | 2016-01-24 16:22:50 +0000 |
| commit | 60ec452d043e44bcbb05860381e2077a3b56b09c (patch) | |
| tree | 1eaf13dc05a6da6a53a949fc1a66df6030cab943 | |
| parent | 49cf30286b505e15ca0496605efca5546c7bbf85 (diff) | |
Reorganizing color drawing code.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11045 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
| -rw-r--r-- | FL/Fl_Device.H | 24 | ||||
| -rw-r--r-- | src/Fl_Gl_Device_Plugin.cxx | 5 | ||||
| -rw-r--r-- | src/cfg_gfx/gdi.H | 6 | ||||
| -rw-r--r-- | src/cfg_gfx/gdi_color.cxx (renamed from src/fl_color_win32.cxx) | 14 | ||||
| -rw-r--r-- | src/cfg_gfx/opengl.H | 6 | ||||
| -rw-r--r-- | src/cfg_gfx/opengl_color.cxx | 70 | ||||
| -rw-r--r-- | src/cfg_gfx/opengl_rect.cxx | 9 | ||||
| -rw-r--r-- | src/cfg_gfx/quartz.H | 7 | ||||
| -rw-r--r-- | src/cfg_gfx/quartz_color.cxx (renamed from src/fl_color_mac.cxx) | 5 | ||||
| -rw-r--r-- | src/cfg_gfx/xlib.H | 3 | ||||
| -rw-r--r-- | src/cfg_gfx/xlib_color.cxx | 351 | ||||
| -rw-r--r-- | src/fl_color.cxx | 424 | ||||
| -rw-r--r-- | src/fl_color_porting.cxx | 50 |
13 files changed, 524 insertions, 450 deletions
diff --git a/FL/Fl_Device.H b/FL/Fl_Device.H index 3e88db3e8..0e6e2ab34 100644 --- a/FL/Fl_Device.H +++ b/FL/Fl_Device.H @@ -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 diff --git a/src/Fl_Gl_Device_Plugin.cxx b/src/Fl_Gl_Device_Plugin.cxx index 3066a70db..12430df07 100644 --- a/src/Fl_Gl_Device_Plugin.cxx +++ b/src/Fl_Gl_Device_Plugin.cxx @@ -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_rect.cxx" -#include "cfg_gfx/opengl_vertex.cxx" #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" #if defined(__APPLE__) diff --git a/src/cfg_gfx/gdi.H b/src/cfg_gfx/gdi.H index 5fe4ca89b..1c70e2277 100644 --- a/src/cfg_gfx/gdi.H +++ b/src/cfg_gfx/gdi.H @@ -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); }; diff --git a/src/fl_color_win32.cxx b/src/cfg_gfx/gdi_color.cxx index 60dd7c46e..624546f39 100644 --- a/src/fl_color_win32.cxx +++ b/src/cfg_gfx/gdi_color.cxx @@ -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": }; diff --git a/src/cfg_gfx/opengl.H b/src/cfg_gfx/opengl.H index b8dd2bb86..8987e9e37 100644 --- a/src/cfg_gfx/opengl.H +++ b/src/cfg_gfx/opengl.H @@ -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); }; diff --git a/src/cfg_gfx/opengl_color.cxx b/src/cfg_gfx/opengl_color.cxx new file mode 100644 index 000000000..9413be75e --- /dev/null +++ b/src/cfg_gfx/opengl_color.cxx @@ -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$". +// diff --git a/src/cfg_gfx/opengl_rect.cxx b/src/cfg_gfx/opengl_rect.cxx index 8511d8c93..ff10474a1 100644 --- a/src/cfg_gfx/opengl_rect.cxx +++ b/src/cfg_gfx/opengl_rect.cxx @@ -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) { diff --git a/src/cfg_gfx/quartz.H b/src/cfg_gfx/quartz.H index 33ef68086..a85f200c1 100644 --- a/src/cfg_gfx/quartz.H +++ b/src/cfg_gfx/quartz.H @@ -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); }; diff --git a/src/fl_color_mac.cxx b/src/cfg_gfx/quartz_color.cxx index 4699ef31d..b4ca35f7c 100644 --- a/src/fl_color_mac.cxx +++ b/src/cfg_gfx/quartz_color.cxx @@ -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; diff --git a/src/cfg_gfx/xlib.H b/src/cfg_gfx/xlib.H index 460e02e10..c0102a726 100644 --- a/src/cfg_gfx/xlib.H +++ b/src/cfg_gfx/xlib.H @@ -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); }; diff --git a/src/cfg_gfx/xlib_color.cxx b/src/cfg_gfx/xlib_color.cxx new file mode 100644 index 000000000..f7e1ac5e6 --- /dev/null +++ b/src/cfg_gfx/xlib_color.cxx @@ -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$". +// diff --git a/src/fl_color.cxx b/src/fl_color.cxx index 9723e2b38..ddcb8a3ca 100644 --- a/src/fl_color.cxx +++ b/src/fl_color.cxx @@ -23,362 +23,73 @@ // 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 - -// 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; +#include <config.h> +#include "config_lib.h" -} -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. +#ifdef FL_CFG_GFX_QUARTZ -/** - 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; -} +# include "cfg_gfx/quartz_color.cxx" -//////////////////////////////////////////////////////////////// -// 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 -} +#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; - } -} +// ----------------------------------------------------------------------------- + + +#ifdef FL_CFG_GFX_GDI + +# include "cfg_gfx/gdi_color.cxx" + +#endif + + +// ----------------------------------------------------------------------------- -/** - 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 +#ifdef FL_CFG_GFX_XLIB + +# include "cfg_gfx/xlib_color.cxx" + +#endif + + +// ----------------------------------------------------------------------------- + +/** \addtogroup fl_attributes + @{ */ + /** - Returns the RGB value(s) for the given FLTK color index. - - This form returns the RGB values packed in a 32-bit unsigned - integer with the red value in the upper 8 bits, the green value - in the next 8 bits, and the blue value in bits 8-15. The lower - 8 bits will always be 0. -*/ + Returns the RGB value(s) for the given FLTK color index. + + This form returns the RGB values packed in a 32-bit unsigned + integer with the red value in the upper 8 bits, the green value + in the next 8 bits, and the blue value in bits 8-15. The lower + 8 bits will always be 0. + */ unsigned Fl::get_color(Fl_Color i) { if (i & 0xffffff00) return (i); else return fl_cmap[i]; } /** - Sets an entry in the fl_color index table. You can set it to - any 8-bit RGB color. The color is not allocated until fl_color(i) - is used. -*/ + Sets an entry in the fl_color index table. You can set it to + any 8-bit RGB color. The color is not allocated until fl_color(i) + is used. + */ void Fl::set_color(Fl_Color i, uchar red, uchar green, uchar blue) { Fl::set_color((Fl_Color)(i & 255), - ((unsigned)red<<24)+((unsigned)green<<16)+((unsigned)blue<<8)); + ((unsigned)red<<24)+((unsigned)green<<16)+((unsigned)blue<<8)); } /** - Returns the RGB value(s) for the given FLTK color index. - - This form returns the red, green, and blue values - separately in referenced variables. + Returns the RGB value(s) for the given FLTK color index. + + This form returns the red, green, and blue values + separately in referenced variables. - See also unsigned get_color(Fl_Color c) + See also unsigned get_color(Fl_Color c) */ void Fl::get_color(Fl_Color i, uchar &red, uchar &green, uchar &blue) { unsigned c; @@ -392,16 +103,16 @@ void Fl::get_color(Fl_Color i, uchar &red, uchar &green, uchar &blue) { } /** - Returns the weighted average color between the two given colors. - The red, green and blue values are averages using the following formula: - \code - color = color1 * weight + color2 * (1 - weight) - \endcode - Thus, a \p weight value of 1.0 will return the first color, while a - value of 0.0 will return the second color. - \param[in] color1, color2 boundary colors - \param[in] weight weighting factor -*/ + Returns the weighted average color between the two given colors. + The red, green and blue values are averages using the following formula: + \code + color = color1 * weight + color2 * (1 - weight) + \endcode + Thus, a \p weight value of 1.0 will return the first color, while a + value of 0.0 will return the second color. + \param[in] color1, color2 boundary colors + \param[in] weight weighting factor + */ Fl_Color fl_color_average(Fl_Color color1, Fl_Color color2, float weight) { unsigned rgb1; unsigned rgb2; @@ -421,20 +132,20 @@ Fl_Color fl_color_average(Fl_Color color1, Fl_Color color2, float weight) { } /** - Returns the inactive, dimmed version of the given color -*/ + Returns the inactive, dimmed version of the given color + */ Fl_Color fl_inactive(Fl_Color c) { return fl_color_average(c, FL_GRAY, .33f); } /** - Returns a color that contrasts with the background color. - This will be the foreground color if it contrasts sufficiently with the - background color. Otherwise, returns \p FL_WHITE or \p FL_BLACK depending - on which color provides the best contrast. - \param[in] fg,bg foreground and background colors - \return contrasting color -*/ + Returns a color that contrasts with the background color. + This will be the foreground color if it contrasts sufficiently with the + background color. Otherwise, returns \p FL_WHITE or \p FL_BLACK depending + on which color provides the best contrast. + \param[in] fg,bg foreground and background colors + \return contrasting color + */ Fl_Color fl_contrast(Fl_Color fg, Fl_Color bg) { unsigned c1, c2; // RGB colors int l1, l2; // Luminosities @@ -458,8 +169,9 @@ Fl_Color fl_contrast(Fl_Color fg, Fl_Color bg) { else return FL_WHITE; } /** - @} -*/ + @} + */ + // // End of "$Id$". // diff --git a/src/fl_color_porting.cxx b/src/fl_color_porting.cxx deleted file mode 100644 index 8dc6b850f..000000000 --- a/src/fl_color_porting.cxx +++ /dev/null @@ -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$". -// |
