diff --git a/fluid/Fluid_Image.cxx b/fluid/Fluid_Image.cxx index 6f28b8d9b..f0ccedc93 100644 --- a/fluid/Fluid_Image.cxx +++ b/fluid/Fluid_Image.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fluid_Image.cxx,v 1.7.2.5 2000/06/29 07:23:56 spitzak Exp $" +// "$Id: Fluid_Image.cxx,v 1.7.2.6 2000/07/07 08:38:58 spitzak Exp $" // // Pixmap label support for the Fast Light Tool Kit (FLTK). // @@ -74,7 +74,7 @@ void pixmap_image::write_static() { write_c("static char *%s[] = {\n", unique_id(this, "image", filename_name(name()), 0)); int l; - for (l = 0; l < numlines && p->data[l]; l++) { + for (l = 0; l < numlines; l++) { if (l) write_c(",\n"); write_cstring(p->data[l],linelength[l]); } @@ -101,7 +101,7 @@ static int hexdigit(int x) { #define INITIALLINES 1024 pixmap_image::pixmap_image(const char *name, FILE *f) : Fluid_Image(name) { - if (!f) {numlines = 0x7ffffff; return;} // for subclasses + if (!f) return; // for subclasses // read all the c-strings out of the file: char* local_data[INITIALLINES]; char** data = local_data; @@ -212,10 +212,9 @@ int gif2xpm( gif_image::gif_image(const char *name, FILE *f) : pixmap_image(name,0) { char** datap; - if (gif2xpm(name,f,&datap,&linelength,0)) { - p = new Fl_Pixmap(datap); - } else - p = 0; + numlines = gif2xpm(name,f,&datap,&linelength,0); + if (numlines) p = new Fl_Pixmap(datap); + else p = 0; } gif_image::~gif_image() { @@ -437,5 +436,5 @@ Fluid_Image *ui_find_image(const char *oldname) { } // -// End of "$Id: Fluid_Image.cxx,v 1.7.2.5 2000/06/29 07:23:56 spitzak Exp $". +// End of "$Id: Fluid_Image.cxx,v 1.7.2.6 2000/07/07 08:38:58 spitzak Exp $". // diff --git a/fluid/gif.cxx b/fluid/gif.cxx index e008365e8..f09bc6a82 100644 --- a/fluid/gif.cxx +++ b/fluid/gif.cxx @@ -1,5 +1,5 @@ // -// "$Id: gif.cxx,v 1.3.2.2 2000/06/05 21:20:43 mike Exp $" +// "$Id: gif.cxx,v 1.3.2.3 2000/07/07 08:38:58 spitzak Exp $" // // GIF support for the Fast Light Tool Kit (FLTK). // @@ -355,9 +355,9 @@ int gif2xpm( } data[Height+2] = 0; // null to end string array - return 1; + return Height+1; } // -// End of "$Id: gif.cxx,v 1.3.2.2 2000/06/05 21:20:43 mike Exp $". +// End of "$Id: gif.cxx,v 1.3.2.3 2000/07/07 08:38:58 spitzak Exp $". // diff --git a/makeinclude.in b/makeinclude.in index 574ae88a9..f3afc3614 100644 --- a/makeinclude.in +++ b/makeinclude.in @@ -1,5 +1,5 @@ # -# "$Id: makeinclude.in,v 1.7.2.4 2000/06/05 21:20:17 mike Exp $" +# "$Id: makeinclude.in,v 1.7.2.5 2000/07/07 08:38:58 spitzak Exp $" # # Make include file for the Fast Light Tool Kit (FLTK). # @configure_input@ @@ -64,12 +64,12 @@ GLDLIBS =@LDFLAGS@ @LIBS@ @GLLIB@ -lX11 -lXext @X_EXTRA_LIBS@ -lm .c.o: echo Compiling $@... - $(CC) -I.. $(CXXFLAGS) $< -c + $(CC) -I.. $(CFLAGS) $< -c .cxx.o: echo Compiling $@... $(CXX) -I.. $(CXXFLAGS) $< -c # -# End of "$Id: makeinclude.in,v 1.7.2.4 2000/06/05 21:20:17 mike Exp $". +# End of "$Id: makeinclude.in,v 1.7.2.5 2000/07/07 08:38:58 spitzak Exp $". # diff --git a/src/Fl_Button.cxx b/src/Fl_Button.cxx index 96817f398..eb9b9362b 100644 --- a/src/Fl_Button.cxx +++ b/src/Fl_Button.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Button.cxx,v 1.4.2.4 2000/06/05 21:20:48 mike Exp $" +// "$Id: Fl_Button.cxx,v 1.4.2.5 2000/07/07 08:38:58 spitzak Exp $" // // Button widget for the Fast Light Tool Kit (FLTK). // @@ -50,7 +50,7 @@ void Fl_Button::setonly() { // set this radio button on, turn others off } void Fl_Button::draw() { - if (type() == FL_HIDDEN_BUTTON || box() == FL_NO_BOX) return; + if (type() == FL_HIDDEN_BUTTON) return; Fl_Color col = value() ? selection_color() : color(); //if (col == FL_GRAY && Fl::belowmouse()==this) col = FL_LIGHT1; draw_box(value() ? (down_box()?down_box():down(box())) : box(), col); @@ -118,5 +118,5 @@ Fl_Button::Fl_Button(int x,int y,int w,int h, const char *l) } // -// End of "$Id: Fl_Button.cxx,v 1.4.2.4 2000/06/05 21:20:48 mike Exp $". +// End of "$Id: Fl_Button.cxx,v 1.4.2.5 2000/07/07 08:38:58 spitzak Exp $". // diff --git a/src/Fl_Gl_Window.cxx b/src/Fl_Gl_Window.cxx index d2a32bbfe..895fa0985 100644 --- a/src/Fl_Gl_Window.cxx +++ b/src/Fl_Gl_Window.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Gl_Window.cxx,v 1.12.2.15 2000/06/10 19:30:01 carl Exp $" +// "$Id: Fl_Gl_Window.cxx,v 1.12.2.16 2000/07/07 08:38:58 spitzak Exp $" // // OpenGL window code for the Fast Light Tool Kit (FLTK). // @@ -30,6 +30,8 @@ #include #include #include "Fl_Gl_Choice.H" +#include +#include //////////////////////////////////////////////////////////////// @@ -42,22 +44,17 @@ // this reason you can define some symbols to describe what is left in // the back buffer. -// The default of SWAP_SWAP works on an SGI, and will also work (but -// is sub-optimal) on machines that should be SWAP_COPY or SWAP_NODAMAGE. -// The win32 emulation of OpenGL can use COPY, but some (all?) OpenGL -// cards use SWAP. +// Having not found any way to determine this from glx (or wgl) I have +// resorted to letting the user specify it with an environment variable, +// GL_SWAP_TYPE, it should be equal to one of these symbols: // contents of back buffer after glXSwapBuffers(): -#define UNDEFINED 0 // unknown -#define SWAP 1 // former front buffer -#define COPY 2 // unchanged -#define NODAMAGE 3 // unchanged even by X expose() events +#define UNDEFINED 1 // anything +#define SWAP 2 // former front buffer (same as unknown) +#define COPY 3 // unchanged +#define NODAMAGE 4 // unchanged even by X expose() events -//#ifdef MESA -//#define SWAP_TYPE NODAMAGE -//#else -#define SWAP_TYPE SWAP -//#endif +static char SWAP_TYPE; // 0 = determine it from environment variable //////////////////////////////////////////////////////////////// @@ -196,66 +193,71 @@ void Fl_Gl_Window::flush() { if (g->d) { -#if SWAP_TYPE == NODAMAGE + if (!SWAP_TYPE) { + SWAP_TYPE = UNDEFINED; + const char* c = getenv("GL_SWAP_TYPE"); + if (c) { + if (!strcmp(c,"COPY")) SWAP_TYPE = COPY; + else if (!strcmp(c, "NODAMAGE")) SWAP_TYPE = NODAMAGE; + } + } - // don't draw if only overlay damage or expose events: - if ((damage()&~(FL_DAMAGE_OVERLAY|FL_DAMAGE_EXPOSE)) || !save_valid) draw(); - swap_buffers(); + if (SWAP_TYPE == NODAMAGE) { -#elif SWAP_TYPE == COPY + // don't draw if only overlay damage or expose events: + if ((damage()&~(FL_DAMAGE_OVERLAY|FL_DAMAGE_EXPOSE)) || !save_valid) + draw(); + swap_buffers(); - // don't draw if only the overlay is damaged: - if (damage() != FL_DAMAGE_OVERLAY || !save_valid) draw(); - swap_buffers(); - -#else // SWAP_TYPE == SWAP || SWAP_TYPE == UNDEFINED - - if (overlay == this) { // Use CopyPixels to act like SWAP_TYPE == COPY + } else if (SWAP_TYPE == COPY) { // don't draw if only the overlay is damaged: - if (damage1_ || damage() != FL_DAMAGE_OVERLAY || !save_valid) draw(); - // we use a seperate context for the copy because rasterpos must be 0 - // and depth test needs to be off: - static GLXContext ortho_context = 0; - static Fl_Gl_Window* ortho_window = 0; - int init = !ortho_context; - if (init) { + if (damage() != FL_DAMAGE_OVERLAY || !save_valid) draw(); + swap_buffers(); + + } else { // SWAP_TYPE == UNDEFINED + + // If we are faking the overlay, use CopyPixels to act like + // SWAP_TYPE == COPY. Otherwise overlay redraw is way too slow. + if (overlay == this) { + // don't draw if only the overlay is damaged: + if (damage1_ || damage() != FL_DAMAGE_OVERLAY || !save_valid) draw(); + // we use a seperate context for the copy because rasterpos must be 0 + // and depth test needs to be off: + static GLXContext ortho_context = 0; + static Fl_Gl_Window* ortho_window = 0; + int init = !ortho_context; + if (init) { #ifdef _WIN32 - ortho_context = wglCreateContext(Fl_X::i(this)->private_dc); + ortho_context = wglCreateContext(Fl_X::i(this)->private_dc); #else - ortho_context = glXCreateContext(fl_display,g->vis,fl_first_context,1); + ortho_context =glXCreateContext(fl_display,g->vis,fl_first_context,1); #endif - } - fl_set_gl_context(this, ortho_context); - if (init || !save_valid || ortho_window != this) { - glDisable(GL_DEPTH_TEST); - glReadBuffer(GL_BACK); - glDrawBuffer(GL_FRONT); - glLoadIdentity(); - glViewport(0, 0, w(), h()); - glOrtho(0, w(), 0, h(), -1, 1); - glRasterPos2i(0,0); - ortho_window = this; - } - glCopyPixels(0,0,w(),h(),GL_COLOR); - make_current(); // set current context back to draw overlay - damage1_ = 0; + } + fl_set_gl_context(this, ortho_context); + if (init || !save_valid || ortho_window != this) { + glDisable(GL_DEPTH_TEST); + glReadBuffer(GL_BACK); + glDrawBuffer(GL_FRONT); + glLoadIdentity(); + glViewport(0, 0, w(), h()); + glOrtho(0, w(), 0, h(), -1, 1); + glRasterPos2i(0,0); + ortho_window = this; + } + glCopyPixels(0,0,w(),h(),GL_COLOR); + make_current(); // set current context back to draw overlay + damage1_ = 0; - } else { + } else { -#if SWAP_TYPE == SWAP - uchar old_damage = damage(); - clear_damage(damage1_|old_damage); draw(); - swap_buffers(); - damage1_ = old_damage; -#else // SWAP_TYPE == UNDEFINED - clear_damage(~0); draw(); - swap_buffers(); - damage1_ = ~0; -#endif + damage1_ = damage(); + clear_damage(~0); draw(); + swap_buffers(); + + } } -#endif if (overlay==this) { // fake overlay in front buffer glDrawBuffer(GL_FRONT); @@ -269,6 +271,7 @@ void Fl_Gl_Window::flush() { draw(); if (overlay == this) draw_overlay(); glFlush(); + } #ifdef _WIN32 @@ -321,7 +324,6 @@ void Fl_Gl_Window::init() { context = 0; g = 0; overlay = 0; - damage1_ = 0; } void Fl_Gl_Window::draw_overlay() {} @@ -329,5 +331,5 @@ void Fl_Gl_Window::draw_overlay() {} #endif // -// End of "$Id: Fl_Gl_Window.cxx,v 1.12.2.15 2000/06/10 19:30:01 carl Exp $". +// End of "$Id: Fl_Gl_Window.cxx,v 1.12.2.16 2000/07/07 08:38:58 spitzak Exp $". // diff --git a/src/Fl_XColor.H b/src/Fl_XColor.H index db7616972..8e2c1bbf3 100644 --- a/src/Fl_XColor.H +++ b/src/Fl_XColor.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_XColor.H,v 1.6.2.2 2000/06/05 21:20:59 mike Exp $" +// "$Id: Fl_XColor.H,v 1.6.2.3 2000/07/07 08:38:58 spitzak Exp $" // // X-specific color definitions for the Fast Light Tool Kit (FLTK). // @@ -33,12 +33,12 @@ struct Fl_XColor { unsigned char mapped; // true when XAllocColor done unsigned long pixel; // the X pixel to use }; -extern FL_EXPORT Fl_XColor fl_xmap[/*overlay*/][256]; +extern Fl_XColor fl_xmap[/*overlay*/][256]; // mask & shifts to produce xcolor for truecolor visuals: -extern FL_EXPORT unsigned char fl_redmask, fl_greenmask, fl_bluemask; -extern FL_EXPORT int fl_redshift, fl_greenshift, fl_blueshift, fl_extrashift; +extern unsigned char fl_redmask, fl_greenmask, fl_bluemask; +extern int fl_redshift, fl_greenshift, fl_blueshift, fl_extrashift; // -// End of "$Id: Fl_XColor.H,v 1.6.2.2 2000/06/05 21:20:59 mike Exp $". +// End of "$Id: Fl_XColor.H,v 1.6.2.3 2000/07/07 08:38:58 spitzak Exp $". // diff --git a/src/fl_color.cxx b/src/fl_color.cxx index 90114afc5..6398f9a4f 100644 --- a/src/fl_color.cxx +++ b/src/fl_color.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_color.cxx,v 1.12.2.3 2000/06/27 23:30:54 easysw Exp $" +// "$Id: fl_color.cxx,v 1.12.2.4 2000/07/07 08:38:58 spitzak Exp $" // // Color functions for the Fast Light Tool Kit (FLTK). // @@ -89,23 +89,41 @@ static void figure_out_visual() { } +static unsigned fl_cmap[256] = { +#include "fl_cmap.h" // this is a file produced by "cmap.C": +}; + +#if HAVE_OVERLAY +Fl_XColor fl_xmap[2][256]; +uchar fl_overlay; +Colormap fl_overlay_colormap; +XVisualInfo* fl_overlay_visual; +ulong fl_transparent_pixel; +#else +Fl_XColor fl_xmap[1][256]; +#define fl_overlay 0 +#endif + //////////////////////////////////////////////////////////////// // Get an rgb color. This is easy for a truecolor visual. For -// colormapped it picks the closest color out of the fltk colormap -// but be warned that this results in *two* approximations: one -// to the fltk colormap, and another to whatever colors X allocates. +// 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. ulong fl_xpixel(uchar r,uchar g,uchar b) { if (!beenhere) figure_out_visual(); #if USE_COLORMAP if (!fl_redmask) { - Fl_Color i; - if (r == g && r == b) { // get it out of gray ramp - i = fl_gray_ramp(r*FL_NUM_GRAY/256); - } else { // get it out of color cube: - i = fl_color_cube(r*FL_NUM_RED/256,g*FL_NUM_GREEN/256,b*FL_NUM_BLUE/256); - } - return fl_xpixel(i); + // 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 @@ -125,23 +143,9 @@ void fl_color(uchar r,uchar g,uchar b) { // an X color, and does a least-squares match to find the closest // color if X cannot allocate that color. -unsigned fl_cmap[256] = { -#include "fl_cmap.h" // this is a file produced by "cmap.C": -}; - -#if HAVE_OVERLAY -Fl_XColor fl_xmap[2][256]; -uchar fl_overlay; -Colormap fl_overlay_colormap; -XVisualInfo* fl_overlay_visual; -ulong fl_transparent_pixel; -#else -Fl_XColor fl_xmap[1][256]; -#endif - // calculate what color is actually on the screen for a mask: static inline uchar realcolor(uchar color, uchar mask) { -#if 1 +#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; @@ -159,107 +163,107 @@ static inline uchar realcolor(uchar color, uchar mask) { } ulong fl_xpixel(Fl_Color i) { - -#if HAVE_OVERLAY Fl_XColor &xmap = fl_xmap[fl_overlay][i]; -#else - Fl_XColor &xmap = fl_xmap[0][i]; -#endif 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; + Colormap colormap = fl_colormap; #if HAVE_OVERLAY - if (fl_overlay) {colormap = fl_overlay_colormap; goto J1;} + if (fl_overlay) colormap = fl_overlay_colormap; else #endif - if (!fl_redmask) { - colormap = fl_colormap; -#if HAVE_OVERLAY - J1: - 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; + if (fl_redmask) { #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 - // assumme 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; + // 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 + // assumme 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 - // 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 = fl_xpixel(r,g,b); } Fl_Color fl_color_; @@ -351,5 +355,5 @@ Fl_Color contrast(Fl_Color fg, Fl_Color bg) { } // -// End of "$Id: fl_color.cxx,v 1.12.2.3 2000/06/27 23:30:54 easysw Exp $". +// End of "$Id: fl_color.cxx,v 1.12.2.4 2000/07/07 08:38:58 spitzak Exp $". // diff --git a/src/fl_draw_image.cxx b/src/fl_draw_image.cxx index 2a62a7f56..163844bc7 100644 --- a/src/fl_draw_image.cxx +++ b/src/fl_draw_image.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_draw_image.cxx,v 1.5.2.4 2000/06/27 23:30:54 easysw Exp $" +// "$Id: fl_draw_image.cxx,v 1.5.2.5 2000/07/07 08:38:58 spitzak Exp $" // // Image drawing routines for the Fast Light Tool Kit (FLTK). // @@ -76,83 +76,8 @@ static int ri,gi,bi; // saved error-diffusion value //////////////////////////////////////////////////////////////// // 8-bit converter with error diffusion -// I make a 16x16x16 cube of the closest colors in the fltk colormap -// we could allocate to each of the colors in a 4-bit image. This is -// then used to find the pixel values and actual colors for error diffusion. -static uchar cube[16*16*16]; -extern unsigned fl_cmap[]; - -// calculate sum-of-squares error between 4-bit index and pixel colors: -static int calc_error(int r, int g, int b, int i) { - int t; int s; - t = ((r<<4)+8)-((fl_cmap[i] >> 24) & 255); s = t*t; - t = ((g<<4)+8)-((fl_cmap[i] >> 16) & 255); s += t*t; - t = ((b<<4)+8)-((fl_cmap[i] >> 8) & 255); s += t*t; - return s; -} - -// replace the color stored at a location with a better one: -static void improve(uchar *p, int& e, int r, int g, int b, int i) { - if (i < FL_GRAY_RAMP || i > 255) return; - int e1 = calc_error(r,g,b,i); - if (e1 < e) {*p = i; e = e1;} -} - -static int filled_color_cube; -static char alloc_color[256]; // 1 = allocated, 0 = not allocated - -static void fill_color_cube() { - filled_color_cube = 1; - -#if 0 // Delay color filling to reduce colormap usage... - int i; - // allocate all the colors in the fltk color cube and gray ramp: - // allocate widely seperated values first so that the bad ones are - // distributed evenly through the colormap: - for (i=0;;) { - fl_xpixel((Fl_Color)(i+FL_COLOR_CUBE)); - i = (i+109)%(FL_NUM_RED*FL_NUM_GREEN*FL_NUM_BLUE); if (!i) break; - } - for (i=0;;) { - fl_xpixel((Fl_Color)(i+FL_GRAY_RAMP)); - i = (i+7)%FL_NUM_GRAY; if (!i) break; - } - memset(alloc_color, 1, sizeof(alloc_color)); -#else - memset(alloc_color, 0, sizeof(alloc_color)); -#endif /* 0 */ - - // fill in the 16x16x16 cube: - uchar *p = cube; - for (int r = 0; r<16; r++) { - for (int g = 0; g<16; g++) { - for (int b = 0; b<16; b++, p++) { - // initial try is value from color cube: - Fl_Color i = fl_color_cube(r*FL_NUM_RED/16, g*FL_NUM_GREEN/16, - b*FL_NUM_BLUE/16); - int e = calc_error(r,g,b,i); - *p = uchar(i); - // try neighbor pixels in the cube to see if they are better: - improve(p,e,r,g,b,i+FL_NUM_RED*FL_NUM_GREEN); - improve(p,e,r,g,b,i-FL_NUM_RED*FL_NUM_GREEN); - improve(p,e,r,g,b,i+FL_NUM_GREEN); - improve(p,e,r,g,b,i-FL_NUM_GREEN); - improve(p,e,r,g,b,i+1); - improve(p,e,r,g,b,i-1); - // try the gray ramp: - i = fl_gray_ramp(g*FL_NUM_GRAY/15); - improve(p,e,r,g,b,i); - improve(p,e,r,g,b,i+1); - improve(p,e,r,g,b,i-1); - } - } - } -} - static void color8_converter(const uchar *from, uchar *to, int w, int delta) { - if (!filled_color_cube) fill_color_cube(); int r=ri, g=gi, b=bi; - int i; int d, td; if (dir) { dir = 0; @@ -169,25 +94,19 @@ static void color8_converter(const uchar *from, uchar *to, int w, int delta) { r += from[0]; if (r < 0) r = 0; else if (r>255) r = 255; g += from[1]; if (g < 0) g = 0; else if (g>255) g = 255; b += from[2]; if (b < 0) b = 0; else if (b>255) b = 255; - i = cube[((r<<4)&0xf00)+(g&0xf0)+(b>>4)]; - if (!alloc_color[i]) - { - fl_xpixel((Fl_Color)i); - alloc_color[i] = 1; - } - Fl_XColor* x = fl_xmap[0] + i; - r -= x->r; - g -= x->g; - b -= x->b; - *to = uchar(x->pixel); + 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[0][i]; + if (!xmap.mapped) {if (!fl_redmask) fl_xpixel(r,g,b); else fl_xpixel(i);} + r -= xmap.r; + g -= xmap.g; + b -= xmap.b; + *to = uchar(xmap.pixel); } ri = r; gi = g; bi = b; } static void mono8_converter(const uchar *from, uchar *to, int w, int delta) { - if (!filled_color_cube) fill_color_cube(); - int r=ri; - int i; + int r=ri, g=gi, b=bi; int d, td; if (dir) { dir = 0; @@ -202,17 +121,17 @@ static void mono8_converter(const uchar *from, uchar *to, int w, int delta) { } for (; w--; from += d, to += td) { r += from[0]; if (r < 0) r = 0; else if (r>255) r = 255; - i = cube[(r>>4)*0x111]; - if (!alloc_color[i]) - { - fl_xpixel((Fl_Color)i); - alloc_color[i] = 1; - } - Fl_XColor* x = fl_xmap[0] + i; - r -= x->g; - *to = uchar(x->pixel); + g += from[0]; if (g < 0) g = 0; else if (g>255) g = 255; + b += from[0]; if (b < 0) b = 0; else if (b>255) b = 255; + 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[0][i]; + if (!xmap.mapped) {if (!fl_redmask) fl_xpixel(r,g,b); else fl_xpixel(i);} + r -= xmap.r; + g -= xmap.g; + b -= xmap.b; + *to = uchar(xmap.pixel); } - ri = r; + ri = r; gi = g; bi = b; } #endif @@ -428,6 +347,9 @@ mono32_converter(const uchar *from,uchar *to,int w, int delta) { static void figure_out_visual() { + fl_xpixel(FL_BLACK); // setup fl_redmask, etc, in fl_color.C + fl_xpixel(FL_WHITE); // also make sure white is allocated + static XPixmapFormatValues *pfvlist; static int FL_NUM_pfv; if (!pfvlist) pfvlist = XListPixmapFormats(fl_display,&FL_NUM_pfv); @@ -463,7 +385,6 @@ static void figure_out_visual() { #endif // otherwise it is a TrueColor visual: - fl_xpixel(0,0,0); // setup fl_redmask, etc, in fl_color.C int rs = fl_redshift; int gs = fl_greenshift; @@ -652,5 +573,5 @@ void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) { #endif // -// End of "$Id: fl_draw_image.cxx,v 1.5.2.4 2000/06/27 23:30:54 easysw Exp $". +// End of "$Id: fl_draw_image.cxx,v 1.5.2.5 2000/07/07 08:38:58 spitzak Exp $". //