mirror of
https://github.com/fltk/fltk.git
synced 2026-05-30 21:25:30 +08:00
Fl_Pixmap: improved algorithm for WIN32 printing
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@7503 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
+5
-22
@@ -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) fl_TransparentBlt = (fl_transp_func)GetProcAddress(hMod, "TransparentBlt");
|
||||||
}
|
}
|
||||||
if (hMod) {
|
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_Offscreen tmp_id = fl_create_offscreen(w(), h());
|
||||||
fl_begin_offscreen(tmp_id);
|
fl_begin_offscreen(tmp_id);
|
||||||
uchar *bitmap = 0;
|
uchar *bitmap = 0;
|
||||||
fl_mask_bitmap = &bitmap;
|
fl_mask_bitmap = &bitmap;
|
||||||
// draw pixmap to offscreen using the unlikely color for background
|
// draw pixmap to offscreen
|
||||||
fl_draw_pixmap(data(), 0, 0, fl_rgb_color(UNLIKELY_RGB_COLOR) );
|
fl_draw_pixmap(data(), 0, 0);
|
||||||
fl_end_offscreen();
|
fl_end_offscreen();
|
||||||
HDC new_gc = CreateCompatibleDC(fl_gc);
|
HDC new_gc = CreateCompatibleDC(fl_gc);
|
||||||
int save = SaveDC(new_gc);
|
int save = SaveDC(new_gc);
|
||||||
SelectObject(new_gc, (void*)tmp_id);
|
SelectObject(new_gc, (void*)tmp_id);
|
||||||
// print all of offscreen but its parts using unlikely color
|
// print all of offscreen but its parts in background color
|
||||||
fl_TransparentBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, w(), h(), WIN_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);
|
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);
|
DeleteDC(new_gc);
|
||||||
fl_delete_offscreen(tmp_id);
|
fl_delete_offscreen(tmp_id);
|
||||||
}
|
}
|
||||||
|
|||||||
+60
-2
@@ -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);
|
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.
|
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)
|
\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;
|
if (!fl_measure_pixmap(cdata, d.w, d.h)) return 0;
|
||||||
const uchar*const* data = (const uchar*const*)(cdata+1);
|
const uchar*const* data = (const uchar*const*)(cdata+1);
|
||||||
int transparent_index = -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
|
if (ncolors < 0) { // FLTK (non standard) compressed colormap
|
||||||
ncolors = -ncolors;
|
ncolors = -ncolors;
|
||||||
@@ -204,6 +243,7 @@ int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) {
|
|||||||
#endif
|
#endif
|
||||||
transparent_index = ' ';
|
transparent_index = ' ';
|
||||||
Fl::get_color(bg, c[0], c[1], c[2]); c[3] = 0;
|
Fl::get_color(bg, c[0], c[1], c[2]); c[3] = 0;
|
||||||
|
transparent_c = c;
|
||||||
p += 4;
|
p += 4;
|
||||||
ncolors--;
|
ncolors--;
|
||||||
}
|
}
|
||||||
@@ -215,6 +255,12 @@ int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) {
|
|||||||
# if WORDS_BIGENDIAN
|
# if WORDS_BIGENDIAN
|
||||||
c += 4;
|
c += 4;
|
||||||
# endif
|
# 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
|
#endif
|
||||||
*c++ = *p++;
|
*c++ = *p++;
|
||||||
*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__
|
#ifdef __APPLE_QUARTZ__
|
||||||
c[3] = 255;
|
c[3] = 255;
|
||||||
#endif
|
#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
|
// assume "None" or "#transparent" for any errors
|
||||||
// "bg" should be transparent...
|
// "bg" should be transparent...
|
||||||
Fl::get_color(bg, c[0], c[1], c[2]);
|
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;
|
c[3] = 0;
|
||||||
#endif
|
#endif
|
||||||
transparent_index = ind;
|
transparent_index = ind;
|
||||||
|
transparent_c = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d.data = data;
|
d.data = data;
|
||||||
|
#ifdef WIN32
|
||||||
|
make_unused_color(transparent_c[0], transparent_c[1], transparent_c[2]);
|
||||||
|
#endif
|
||||||
#ifndef __APPLE_QUARTZ__
|
#ifndef __APPLE_QUARTZ__
|
||||||
|
|
||||||
// build the mask bitmap used by Fl_Pixmap:
|
// build the mask bitmap used by Fl_Pixmap:
|
||||||
|
|||||||
Reference in New Issue
Block a user