summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthias Melcher <fltk@matthiasm.com>2016-01-24 16:22:50 +0000
committerMatthias Melcher <fltk@matthiasm.com>2016-01-24 16:22:50 +0000
commit60ec452d043e44bcbb05860381e2077a3b56b09c (patch)
tree1eaf13dc05a6da6a53a949fc1a66df6030cab943 /src
parent49cf30286b505e15ca0496605efca5546c7bbf85 (diff)
Reorganizing color drawing code.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11045 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src')
-rw-r--r--src/Fl_Gl_Device_Plugin.cxx5
-rw-r--r--src/cfg_gfx/gdi.H6
-rw-r--r--src/cfg_gfx/gdi_color.cxx (renamed from src/fl_color_win32.cxx)14
-rw-r--r--src/cfg_gfx/opengl.H6
-rw-r--r--src/cfg_gfx/opengl_color.cxx70
-rw-r--r--src/cfg_gfx/opengl_rect.cxx9
-rw-r--r--src/cfg_gfx/quartz.H7
-rw-r--r--src/cfg_gfx/quartz_color.cxx (renamed from src/fl_color_mac.cxx)5
-rw-r--r--src/cfg_gfx/xlib.H3
-rw-r--r--src/cfg_gfx/xlib_color.cxx351
-rw-r--r--src/fl_color.cxx424
-rw-r--r--src/fl_color_porting.cxx50
12 files changed, 520 insertions, 430 deletions
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$".
-//