From 60ec452d043e44bcbb05860381e2077a3b56b09c Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Sun, 24 Jan 2016 16:22:50 +0000 Subject: Reorganizing color drawing code. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11045 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- src/Fl_Gl_Device_Plugin.cxx | 5 +- src/cfg_gfx/gdi.H | 6 + src/cfg_gfx/gdi_color.cxx | 245 +++++++++++++++++++++++++ src/cfg_gfx/opengl.H | 6 +- src/cfg_gfx/opengl_color.cxx | 70 +++++++ src/cfg_gfx/opengl_rect.cxx | 9 - src/cfg_gfx/quartz.H | 7 +- src/cfg_gfx/quartz_color.cxx | 80 ++++++++ src/cfg_gfx/xlib.H | 3 + src/cfg_gfx/xlib_color.cxx | 351 +++++++++++++++++++++++++++++++++++ src/fl_color.cxx | 424 +++++++------------------------------------ src/fl_color_mac.cxx | 79 -------- src/fl_color_porting.cxx | 50 ----- src/fl_color_win32.cxx | 243 ------------------------- 14 files changed, 834 insertions(+), 744 deletions(-) create mode 100644 src/cfg_gfx/gdi_color.cxx create mode 100644 src/cfg_gfx/opengl_color.cxx create mode 100644 src/cfg_gfx/quartz_color.cxx create mode 100644 src/cfg_gfx/xlib_color.cxx delete mode 100644 src/fl_color_mac.cxx delete mode 100644 src/fl_color_porting.cxx delete mode 100644 src/fl_color_win32.cxx (limited to 'src') 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/cfg_gfx/gdi_color.cxx b/src/cfg_gfx/gdi_color.cxx new file mode 100644 index 000000000..624546f39 --- /dev/null +++ b/src/cfg_gfx/gdi_color.cxx @@ -0,0 +1,245 @@ +// +// "$Id$" +// +// MSWidnows' GDI 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 +// + +// 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. + +#include +#include +#include +#include + +// 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": +}; + +// Translations to win32 data structures: +Fl_XMap fl_xmap[256]; + +Fl_XMap* fl_current_xmap; + +HPALETTE fl_palette; +static HGDIOBJ tmppen=0; +static HPEN savepen=0; + +void fl_cleanup_pens(void) { + for (int i=0; i<256; i++) { + if (fl_xmap[i].pen) DeleteObject(fl_xmap[i].pen); + } +} + +void fl_save_pen(void) { + if(!tmppen) tmppen = CreatePen(PS_SOLID, 1, 0); + savepen = (HPEN)SelectObject(fl_gc, tmppen); +} + +void fl_restore_pen(void) { + if (savepen) SelectObject(fl_gc, savepen); + DeleteObject(tmppen); + tmppen = 0; + savepen = 0; +} + +static void clear_xmap(Fl_XMap& xmap) { + if (xmap.pen) { + HGDIOBJ tmppen = GetStockObject(BLACK_PEN); + HGDIOBJ oldpen = SelectObject(fl_gc, tmppen); // Push out the current pen of the gc + if(oldpen != xmap.pen) SelectObject(fl_gc, oldpen); // Put it back if it is not the one we are about to delete + DeleteObject((HGDIOBJ)(xmap.pen)); + xmap.pen = 0; + xmap.brush = -1; + } +} + +static void set_xmap(Fl_XMap& xmap, COLORREF c) { + xmap.rgb = c; + if (xmap.pen) { + HGDIOBJ oldpen = SelectObject(fl_gc,GetStockObject(BLACK_PEN)); // replace current pen with safe one + if (oldpen != xmap.pen)SelectObject(fl_gc,oldpen); // if old one not xmap.pen, need to put it back + DeleteObject(xmap.pen); // delete pen + } + xmap.pen = CreatePen(PS_SOLID, 1, xmap.rgb); // get a pen into xmap.pen + xmap.brush = -1; +} + +void Fl_GDI_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); + Fl_XMap &xmap = fl_xmap[i]; + if (!xmap.pen) { +#if USE_COLORMAP + if (fl_palette) { + set_xmap(xmap, PALETTEINDEX(i)); + } else { +#endif + unsigned c = fl_cmap[i]; + set_xmap(xmap, RGB(uchar(c>>24), uchar(c>>16), uchar(c>>8))); +#if USE_COLORMAP + } +#endif + } + fl_current_xmap = ⟼ + SelectObject(fl_gc, (HGDIOBJ)(xmap.pen)); + } +} + +void Fl_GDI_Graphics_Driver::color(uchar r, uchar g, uchar b) { + static Fl_XMap xmap; + COLORREF c = RGB(r,g,b); + Fl_Graphics_Driver::color( fl_rgb_color(r, g, b) ); + if (!xmap.pen || c != xmap.rgb) { + clear_xmap(xmap); + set_xmap(xmap, c); + } + fl_current_xmap = ⟼ + SelectObject(fl_gc, (HGDIOBJ)(xmap.pen)); +} + +HBRUSH fl_brush() { + return fl_brush_action(0); +} + +HBRUSH fl_brush_action(int action) { + Fl_XMap *xmap = fl_current_xmap; + // Wonko: we use some statistics to cache only a limited number + // of brushes: +#define FL_N_BRUSH 16 + static struct Fl_Brush { + HBRUSH brush; + unsigned short usage; + Fl_XMap* backref; + } brushes[FL_N_BRUSH]; + + if (action) { + SelectObject(fl_gc, GetStockObject(BLACK_BRUSH)); // Load stock object + for (int i=0; ibrush; // find the associated brush + if (i != -1) { // if the brush was allready allocated + if (brushes[i].brush == NULL) goto CREATE_BRUSH; + if ( (++brushes[i].usage) > 32000 ) { // keep a usage statistic + for (int j=0; j16000) + brushes[j].usage -= 16000; + else + brushes[j].usage = 0; + } + } + return brushes[i].brush; + } else { + int umin = 32000, imin = 0; + for (i=0; ibrush = -1; + } +CREATE_BRUSH: + brushes[i].brush = CreateSolidBrush(xmap->rgb); + brushes[i].usage = 0; + brushes[i].backref = xmap; + xmap->brush = i; + return brushes[i].brush; +} + +void Fl::free_color(Fl_Color i, int overlay) { + if (overlay) return; // do something about GL overlay? + clear_xmap(fl_xmap[i]); +} + +void Fl::set_color(Fl_Color i, unsigned c) { + if (fl_cmap[i] != c) { + clear_xmap(fl_xmap[i]); + fl_cmap[i] = c; + } +} + +#if USE_COLORMAP + +// 'fl_select_palette()' - Make a color palette for 8-bit displays if necessary +// Thanks to Michael Sweet @ Easy Software Products for this + +HPALETTE +fl_select_palette(void) +{ + static char beenhere; + if (!beenhere) { + beenhere = 1; + + //if (GetDeviceCaps(fl_gc, BITSPIXEL) > 8) return NULL; + int nColors = GetDeviceCaps(fl_gc, SIZEPALETTE); + if (nColors <= 0 || nColors > 256) return NULL; + // this will try to work on < 256 color screens, but will probably + // come out quite badly. + + // I lamely try to get this variable-sized object allocated on stack: + ulong foo[(sizeof(LOGPALETTE)+256*sizeof(PALETTEENTRY))/sizeof(ulong)+1]; + LOGPALETTE *pPal = (LOGPALETTE*)foo; + + pPal->palVersion = 0x300; + pPal->palNumEntries = nColors; + + // Build 256 colors from the standard FLTK colormap... + + for (int i = 0; i < nColors; i ++) { + pPal->palPalEntry[i].peRed = (fl_cmap[i] >> 24) & 255; + pPal->palPalEntry[i].peGreen = (fl_cmap[i] >> 16) & 255; + pPal->palPalEntry[i].peBlue = (fl_cmap[i] >> 8) & 255; + pPal->palPalEntry[i].peFlags = 0; + }; + + // Create the palette: + fl_palette = CreatePalette(pPal); + } + if (fl_palette) { + SelectPalette(fl_gc, fl_palette, FALSE); + RealizePalette(fl_gc); + } + return fl_palette; +} + +#endif + +// +// End of "$Id$". +// 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 + +// 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<= 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/cfg_gfx/quartz_color.cxx b/src/cfg_gfx/quartz_color.cxx new file mode 100644 index 000000000..b4ca35f7c --- /dev/null +++ b/src/cfg_gfx/quartz_color.cxx @@ -0,0 +1,80 @@ +// +// "$Id$" +// +// MacOS 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 +// + +// 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 +#include +#include +#include + +static unsigned fl_cmap[256] = { +#include "../fl_cmap.h" // this is a file produced by "cmap.cxx": +}; + +void Fl_Quartz_Graphics_Driver::color(Fl_Color i) { + Fl_Graphics_Driver::color(i); + int index; + uchar r, g, b; + if (i & 0xFFFFFF00) { + // translate rgb colors into color index + r = i>>24; + g = i>>16; + b = i>> 8; + } else { + // translate index into rgb: + index = i; + unsigned c = fl_cmap[i]; + r = c>>24; + g = c>>16; + b = c>> 8; + } + if (!fl_gc) return; // no context yet? We will assign the color later. + float fr = r/255.0f; + float fg = g/255.0f; + float fb = b/255.0f; + CGContextSetRGBFillColor(fl_gc, fr, fg, fb, 1.0f); + CGContextSetRGBStrokeColor(fl_gc, fr, fg, fb, 1.0f); +} + +void Fl_Quartz_Graphics_Driver::color(uchar r, uchar g, uchar b) { + Fl_Graphics_Driver::color( fl_rgb_color(r, g, b) ); + float fr = r/255.0f; + float fg = g/255.0f; + float fb = b/255.0f; + if (!fl_gc) return; // no context yet? We will assign the color later. + CGContextSetRGBFillColor(fl_gc, fr, fg, fb, 1.0f); + 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; + } +} + +// +// End of "$Id$". +// 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 +# include +# include + +//////////////////////////////////////////////////////////////// +// 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_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_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 -# include -# include - -//////////////////////////////////////////////////////////////// -// 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 +#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_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_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_mac.cxx b/src/fl_color_mac.cxx deleted file mode 100644 index 4699ef31d..000000000 --- a/src/fl_color_mac.cxx +++ /dev/null @@ -1,79 +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 -#include -#include -#include - -static unsigned fl_cmap[256] = { -#include "fl_cmap.h" // this is a file produced by "cmap.cxx": -}; - -void Fl_Quartz_Graphics_Driver::color(Fl_Color i) { - Fl_Graphics_Driver::color(i); - int index; - uchar r, g, b; - if (i & 0xFFFFFF00) { - // translate rgb colors into color index - r = i>>24; - g = i>>16; - b = i>> 8; - } else { - // translate index into rgb: - index = i; - unsigned c = fl_cmap[i]; - r = c>>24; - g = c>>16; - b = c>> 8; - } - if (!fl_gc) return; // no context yet? We will assign the color later. - float fr = r/255.0f; - float fg = g/255.0f; - float fb = b/255.0f; - CGContextSetRGBFillColor(fl_gc, fr, fg, fb, 1.0f); - CGContextSetRGBStrokeColor(fl_gc, fr, fg, fb, 1.0f); -} - -void Fl_Quartz_Graphics_Driver::color(uchar r, uchar g, uchar b) { - Fl_Graphics_Driver::color( fl_rgb_color(r, g, b) ); - float fr = r/255.0f; - float fg = g/255.0f; - float fb = b/255.0f; - if (!fl_gc) return; // no context yet? We will assign the color later. - CGContextSetRGBFillColor(fl_gc, fr, fg, fb, 1.0f); - CGContextSetRGBStrokeColor(fl_gc, fr, fg, fb, 1.0f); -} - -void Fl::set_color(Fl_Color i, unsigned c) { - if (fl_cmap[i] != c) { - fl_cmap[i] = c; - } -} - -// -// 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 -#include -#include -#include - -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$". -// diff --git a/src/fl_color_win32.cxx b/src/fl_color_win32.cxx deleted file mode 100644 index 60dd7c46e..000000000 --- a/src/fl_color_win32.cxx +++ /dev/null @@ -1,243 +0,0 @@ -// -// "$Id$" -// -// WIN32 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. - -// 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 -#include -#include -#include - -static unsigned fl_cmap[256] = { -#include "fl_cmap.h" // this is a file produced by "cmap.cxx": -}; - -// Translations to win32 data structures: -Fl_XMap fl_xmap[256]; - -Fl_XMap* fl_current_xmap; - -HPALETTE fl_palette; -static HGDIOBJ tmppen=0; -static HPEN savepen=0; - -void fl_cleanup_pens(void) { - for (int i=0; i<256; i++) { - if (fl_xmap[i].pen) DeleteObject(fl_xmap[i].pen); - } -} - -void fl_save_pen(void) { - if(!tmppen) tmppen = CreatePen(PS_SOLID, 1, 0); - savepen = (HPEN)SelectObject(fl_gc, tmppen); -} - -void fl_restore_pen(void) { - if (savepen) SelectObject(fl_gc, savepen); - DeleteObject(tmppen); - tmppen = 0; - savepen = 0; -} - -static void clear_xmap(Fl_XMap& xmap) { - if (xmap.pen) { - HGDIOBJ tmppen = GetStockObject(BLACK_PEN); - HGDIOBJ oldpen = SelectObject(fl_gc, tmppen); // Push out the current pen of the gc - if(oldpen != xmap.pen) SelectObject(fl_gc, oldpen); // Put it back if it is not the one we are about to delete - DeleteObject((HGDIOBJ)(xmap.pen)); - xmap.pen = 0; - xmap.brush = -1; - } -} - -static void set_xmap(Fl_XMap& xmap, COLORREF c) { - xmap.rgb = c; - if (xmap.pen) { - HGDIOBJ oldpen = SelectObject(fl_gc,GetStockObject(BLACK_PEN)); // replace current pen with safe one - if (oldpen != xmap.pen)SelectObject(fl_gc,oldpen); // if old one not xmap.pen, need to put it back - DeleteObject(xmap.pen); // delete pen - } - xmap.pen = CreatePen(PS_SOLID, 1, xmap.rgb); // get a pen into xmap.pen - xmap.brush = -1; -} - -void Fl_GDI_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); - Fl_XMap &xmap = fl_xmap[i]; - if (!xmap.pen) { -#if USE_COLORMAP - if (fl_palette) { - set_xmap(xmap, PALETTEINDEX(i)); - } else { -#endif - unsigned c = fl_cmap[i]; - set_xmap(xmap, RGB(uchar(c>>24), uchar(c>>16), uchar(c>>8))); -#if USE_COLORMAP - } -#endif - } - fl_current_xmap = ⟼ - SelectObject(fl_gc, (HGDIOBJ)(xmap.pen)); - } -} - -void Fl_GDI_Graphics_Driver::color(uchar r, uchar g, uchar b) { - static Fl_XMap xmap; - COLORREF c = RGB(r,g,b); - Fl_Graphics_Driver::color( fl_rgb_color(r, g, b) ); - if (!xmap.pen || c != xmap.rgb) { - clear_xmap(xmap); - set_xmap(xmap, c); - } - fl_current_xmap = ⟼ - SelectObject(fl_gc, (HGDIOBJ)(xmap.pen)); -} - -HBRUSH fl_brush() { - return fl_brush_action(0); -} - -HBRUSH fl_brush_action(int action) { - Fl_XMap *xmap = fl_current_xmap; - // Wonko: we use some statistics to cache only a limited number - // of brushes: -#define FL_N_BRUSH 16 - static struct Fl_Brush { - HBRUSH brush; - unsigned short usage; - Fl_XMap* backref; - } brushes[FL_N_BRUSH]; - - if (action) { - SelectObject(fl_gc, GetStockObject(BLACK_BRUSH)); // Load stock object - for (int i=0; ibrush; // find the associated brush - if (i != -1) { // if the brush was allready allocated - if (brushes[i].brush == NULL) goto CREATE_BRUSH; - if ( (++brushes[i].usage) > 32000 ) { // keep a usage statistic - for (int j=0; j16000) - brushes[j].usage -= 16000; - else - brushes[j].usage = 0; - } - } - return brushes[i].brush; - } else { - int umin = 32000, imin = 0; - for (i=0; ibrush = -1; - } -CREATE_BRUSH: - brushes[i].brush = CreateSolidBrush(xmap->rgb); - brushes[i].usage = 0; - brushes[i].backref = xmap; - xmap->brush = i; - return brushes[i].brush; -} - -void Fl::free_color(Fl_Color i, int overlay) { - if (overlay) return; // do something about GL overlay? - clear_xmap(fl_xmap[i]); -} - -void Fl::set_color(Fl_Color i, unsigned c) { - if (fl_cmap[i] != c) { - clear_xmap(fl_xmap[i]); - fl_cmap[i] = c; - } -} - -#if USE_COLORMAP - -// 'fl_select_palette()' - Make a color palette for 8-bit displays if necessary -// Thanks to Michael Sweet @ Easy Software Products for this - -HPALETTE -fl_select_palette(void) -{ - static char beenhere; - if (!beenhere) { - beenhere = 1; - - //if (GetDeviceCaps(fl_gc, BITSPIXEL) > 8) return NULL; - int nColors = GetDeviceCaps(fl_gc, SIZEPALETTE); - if (nColors <= 0 || nColors > 256) return NULL; - // this will try to work on < 256 color screens, but will probably - // come out quite badly. - - // I lamely try to get this variable-sized object allocated on stack: - ulong foo[(sizeof(LOGPALETTE)+256*sizeof(PALETTEENTRY))/sizeof(ulong)+1]; - LOGPALETTE *pPal = (LOGPALETTE*)foo; - - pPal->palVersion = 0x300; - pPal->palNumEntries = nColors; - - // Build 256 colors from the standard FLTK colormap... - - for (int i = 0; i < nColors; i ++) { - pPal->palPalEntry[i].peRed = (fl_cmap[i] >> 24) & 255; - pPal->palPalEntry[i].peGreen = (fl_cmap[i] >> 16) & 255; - pPal->palPalEntry[i].peBlue = (fl_cmap[i] >> 8) & 255; - pPal->palPalEntry[i].peFlags = 0; - }; - - // Create the palette: - fl_palette = CreatePalette(pPal); - } - if (fl_palette) { - SelectPalette(fl_gc, fl_palette, FALSE); - RealizePalette(fl_gc); - } - return fl_palette; -} - -#endif - -// -// End of "$Id$". -// -- cgit v1.2.3