From 79b2c201a0d36651e97140ddff215a3b1bbde93e Mon Sep 17 00:00:00 2001 From: Manolo Gouy <Manolo> Date: Wed, 14 Apr 2010 20:12:06 +0000 Subject: [PATCH] Fl_Pixmap: improved algorithm for WIN32 printing git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@7503 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- src/Fl_Pixmap.cxx | 27 ++++-------------- src/fl_draw_pixmap.cxx | 62 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 24 deletions(-) diff --git a/src/Fl_Pixmap.cxx b/src/Fl_Pixmap.cxx index 0bb602e8e..d20132a35 100644 --- a/src/Fl_Pixmap.cxx +++ b/src/Fl_Pixmap.cxx @@ -152,37 +152,20 @@ void Fl_Pixmap::generic_device_draw(int XP, int YP, int WP, int HP, int cx, int if(hMod) fl_TransparentBlt = (fl_transp_func)GetProcAddress(hMod, "TransparentBlt"); } if (hMod) { -# define UNLIKELY_RGB_COLOR 2,3,4 // a nearly black color unlikely to occur in pixmaps -# define WIN_COLOR RGB(2,3,4) Fl_Offscreen tmp_id = fl_create_offscreen(w(), h()); fl_begin_offscreen(tmp_id); uchar *bitmap = 0; fl_mask_bitmap = &bitmap; - // draw pixmap to offscreen using the unlikely color for background - fl_draw_pixmap(data(), 0, 0, fl_rgb_color(UNLIKELY_RGB_COLOR) ); + // draw pixmap to offscreen + fl_draw_pixmap(data(), 0, 0); fl_end_offscreen(); HDC new_gc = CreateCompatibleDC(fl_gc); int save = SaveDC(new_gc); SelectObject(new_gc, (void*)tmp_id); - // print all of offscreen but its parts using unlikely color - fl_TransparentBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, w(), h(), WIN_COLOR ); + // print all of offscreen but its parts in background color + extern UINT win_pixmap_bg_color; // computed by fl_draw_pixmap() + fl_TransparentBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, w(), h(), win_pixmap_bg_color ); RestoreDC(new_gc,save); - // This is an approximate algorithm that fails to print pixmap pixels that would use the unlikely color. - // It can be transformed into an exact algorithm by adding the following commented out statements - // that print pixmap one more time hiding another color (any color would fit) - /* -# define UNLIKELY_RGB_COLOR2 4,3,2 -# define WIN_COLOR2 RGB(4,3,2) - { - fl_begin_offscreen(tmp_id); - fl_draw_pixmap(data(), 0, 0, fl_rgb_color(UNLIKELY_RGB_COLOR2) ); - fl_end_offscreen(); - } - save = SaveDC(new_gc); - SelectObject(new_gc, (void*)tmp_id); - fl_TransparentBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, w(), h(), WIN_COLOR2 ); - RestoreDC(new_gc,save); - */ DeleteDC(new_gc); fl_delete_offscreen(tmp_id); } diff --git a/src/fl_draw_pixmap.cxx b/src/fl_draw_pixmap.cxx index 64bfd0589..f6dd07b3c 100644 --- a/src/fl_draw_pixmap.cxx +++ b/src/fl_draw_pixmap.cxx @@ -179,6 +179,40 @@ int fl_draw_pixmap(/*const*/ char* const* data, int x,int y,Fl_Color bg) { return fl_draw_pixmap((const char*const*)data,x,y,bg); } +#ifdef WIN32 +// to compute an unused color to be used for the pixmap background +FL_EXPORT UINT win_pixmap_bg_color; // the RGB() of the pixmap background color +static int color_count; // # of non-transparent colors used in pixmap +static uchar *used_colors; // used_colors[3*i+j] j=0,1,2 are the RGB values of the ith used color + +static void make_unused_color(uchar &r, uchar &g, uchar &b) +// makes an RGB triplet different from all the colors used in the pixmap +// and compute win_pixmap_bg_color from this triplet +{ + int i; + r = 2; g = 3; b = 4; + while (1) { + for ( i = 0; i < color_count; i++) { + if(used_colors[3*i] == r && used_colors[3*i+1] == g && used_colors[3*i+2] == b) break; + } + if (i >= color_count) { + free(used_colors); + win_pixmap_bg_color = RGB(r, g, b); + return; + } + if (r < 255) r++; + else { + r = 0; + if (g < 255) g++; + else { + g = 0; + b++; + } + } + } +} +#endif + /** Draw XPM image data, with the top-left corner at the given position. \see fl_draw_pixmap(char* const* data, int x, int y, Fl_Color bg) @@ -188,6 +222,11 @@ int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) { if (!fl_measure_pixmap(cdata, d.w, d.h)) return 0; const uchar*const* data = (const uchar*const*)(cdata+1); int transparent_index = -1; + uchar *transparent_c; // such that transparent_c[0,1,2] are the RGB of the transparent color +#ifdef WIN32 + color_count = 0; + used_colors = (uchar *)malloc(abs(ncolors)*3*sizeof(uchar)); +#endif if (ncolors < 0) { // FLTK (non standard) compressed colormap ncolors = -ncolors; @@ -204,6 +243,7 @@ int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) { #endif transparent_index = ' '; Fl::get_color(bg, c[0], c[1], c[2]); c[3] = 0; + transparent_c = c; p += 4; ncolors--; } @@ -215,6 +255,12 @@ int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) { # if WORDS_BIGENDIAN c += 4; # endif +#endif +#ifdef WIN32 + used_colors[3*color_count] = *p; + used_colors[3*color_count+1] = *(p+1); + used_colors[3*color_count+2] = *(p+2); + color_count++; #endif *c++ = *p++; *c++ = *p++; @@ -266,7 +312,16 @@ int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) { #ifdef __APPLE_QUARTZ__ c[3] = 255; #endif - if (!fl_parse_color((const char*)p, c[0], c[1], c[2])) { + int parse = fl_parse_color((const char*)p, c[0], c[1], c[2]); + if (parse) { +#ifdef WIN32 + used_colors[3*color_count] = c[0]; + used_colors[3*color_count+1] = c[1]; + used_colors[3*color_count+2] = c[2]; + color_count++; +#endif + } + else { // assume "None" or "#transparent" for any errors // "bg" should be transparent... Fl::get_color(bg, c[0], c[1], c[2]); @@ -274,11 +329,14 @@ int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) { c[3] = 0; #endif transparent_index = ind; + transparent_c = c; } } } d.data = data; - +#ifdef WIN32 + make_unused_color(transparent_c[0], transparent_c[1], transparent_c[2]); +#endif #ifndef __APPLE_QUARTZ__ // build the mask bitmap used by Fl_Pixmap: -- GitLab