Simplify the implementation of printing of Fl_Pixmap images under Windows.

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12851 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Manolo Gouy 2018-04-18 15:03:51 +00:00
parent 231e0edff6
commit 15e3f4b2d2
8 changed files with 26 additions and 37 deletions

View File

@ -86,6 +86,7 @@ class FL_EXPORT Fl_Graphics_Driver {
friend void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D);
friend void fl_draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D);
friend void fl_copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy);
friend int fl_convert_pixmap(const char*const* cdata, uchar* out, Fl_Color bg);
friend FL_EXPORT void gl_start();
friend FL_EXPORT void gl_finish();
friend FL_EXPORT Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *array);
@ -137,6 +138,8 @@ private:
virtual void draw_fixed(Fl_Pixmap *pxm,int XP, int YP, int WP, int HP, int cx, int cy) {}
virtual void draw_fixed(Fl_Bitmap *bm,int XP, int YP, int WP, int HP, int cx, int cy) {}
virtual void draw_fixed(Fl_RGB_Image *rgb,int XP, int YP, int WP, int HP, int cx, int cy) {}
// the default implementation of make_unused_color_() is most probably enough
virtual void make_unused_color_(unsigned char &r, unsigned char &g, unsigned char &b) {}
// some platforms may need to reimplement this
virtual void set_current_();
protected:
@ -259,13 +262,12 @@ protected:
pwidth = &(rgb->cache_w_);
pheight = &(rgb->cache_h_);
}
/** Accessor to a private member variable of Fl_Pixmap */
static Fl_Color* pixmap_bg_color(Fl_Pixmap *pm) {return &(pm->pixmap_bg_color);}
/** For internal library use only */
static void draw_empty(Fl_Image* img, int X, int Y) {img->draw_empty(X, Y);}
Fl_Graphics_Driver();
void cache_size(Fl_Image *img, int &width, int &height);
static unsigned need_pixmap_bg_color;
public:
virtual ~Fl_Graphics_Driver() {} ///< Destructor
static Fl_Graphics_Driver &default_driver();

View File

@ -52,7 +52,6 @@ private:
// for internal use
fl_uintptr_t id_;
fl_uintptr_t mask_;
Fl_Color pixmap_bg_color;
int cache_w_, cache_h_; // size of pixmap when cached
public:

View File

@ -173,9 +173,6 @@ public:
virtual void* thread_message() {return NULL;}
// implement to support Fl_File_Icon
virtual int file_type(const char *filename);
// the default implementations of pixmap_extra_transparent_processing() and make_unused_color() and are most probably enough
virtual int pixmap_extra_transparent_processing() {return 0;}
virtual void make_unused_color(unsigned char &r, unsigned char &g, unsigned char &b) {}
// implement to return the user's home directory name
virtual const char *home_directory_name() { return ""; }
// the default implementation is most probably enough

View File

@ -413,6 +413,7 @@ void Fl_Graphics_Driver::draw_rgb(Fl_RGB_Image *img, int XP, int YP, int WP, int
}
}
unsigned Fl_Graphics_Driver::need_pixmap_bg_color = 0;
void Fl_Scalable_Graphics_Driver::font(Fl_Font face, Fl_Fontsize size) {
if (!font_descriptor()) fl_open_display(); // to catch the correct initial value of scale_

View File

@ -42,6 +42,7 @@ private:
void set_current_();
void draw_fixed(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
void draw_fixed(Fl_Bitmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
virtual void make_unused_color_(unsigned char &r, unsigned char &g, unsigned char &b);
protected:
void draw_fixed(Fl_RGB_Image *rgb, int XP, int YP, int WP, int HP, int cx, int cy);
void cache(Fl_RGB_Image *rgb);

View File

@ -647,7 +647,9 @@ void Fl_GDI_Graphics_Driver::draw_fixed(Fl_Pixmap *pxm, int X, int Y, int W, int
RestoreDC(new_gc,save);
DeleteDC(new_gc);
} else {
float s = scale_; scale_ = 1;
copy_offscreen(X, Y, W, H, (Fl_Offscreen)*Fl_Graphics_Driver::id(pxm), cx, cy);
scale_ = s;
}
unscale_clip(r2);
}
@ -658,16 +660,9 @@ void Fl_GDI_Printer_Graphics_Driver::draw_pixmap(Fl_Pixmap *pxm, int XP, int YP,
if (start_image(pxm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) return;
transparent_f_type fl_TransparentBlt = TransparentBlt();
if (fl_TransparentBlt) {
bool recache = false;
if (*id(pxm)) {
int *pw, *ph;
cache_w_h(pxm, pw, ph);
recache = (*pw != pxm->data_w() || *ph != pxm->data_h());
}
if (recache || !*id(pxm)) {
pxm->uncache();
cache(pxm);
}
need_pixmap_bg_color = 1;
pxm->uncache();
cache(pxm);
HDC new_gc = CreateCompatibleDC(gc_);
int save = SaveDC(new_gc);
SelectObject(new_gc, (void*)*Fl_Graphics_Driver::id(pxm));
@ -675,10 +670,11 @@ void Fl_GDI_Printer_Graphics_Driver::draw_pixmap(Fl_Pixmap *pxm, int XP, int YP,
float scaleW = pxm->data_w()/float(pxm->w());
float scaleH = pxm->data_h()/float(pxm->h());
fl_TransparentBlt(gc_, X, Y, W, H, new_gc, cx * scaleW, cy * scaleH, W * scaleW, H * scaleH,
*Fl_Graphics_Driver::pixmap_bg_color(pxm) );
need_pixmap_bg_color );
need_pixmap_bg_color = 0;
RestoreDC(new_gc,save);
DeleteDC(new_gc);
if (recache) pxm->uncache();
need_pixmap_bg_color = 0;
}
else {
copy_offscreen(X, Y, W, H, (Fl_Offscreen)*Fl_Graphics_Driver::id(pxm), cx, cy);
@ -692,7 +688,6 @@ void Fl_GDI_Graphics_Driver::cache(Fl_Pixmap *img) {
uchar **pbitmap = surf->driver()->mask_bitmap();
*pbitmap = 0;
fl_draw_pixmap(img->data(), 0, 0, FL_BLACK);
*Fl_Graphics_Driver::pixmap_bg_color(img) = Fl_WinAPI_System_Driver::win_pixmap_bg_color; // computed by fl_draw_pixmap()
uchar *bitmap = *pbitmap;
if (bitmap) {
*Fl_Graphics_Driver::mask(img) = (fl_uintptr_t)create_bitmask(img->data_w(), img->data_h(), bitmap);

View File

@ -41,7 +41,6 @@
class Fl_WinAPI_System_Driver : public Fl_System_Driver
{
public:
static unsigned win_pixmap_bg_color; // the RGB() of the pixmap background color
virtual void warning(const char *format, va_list args);
virtual void error(const char *format, va_list args);
virtual void fatal(const char *format, va_list args);
@ -95,9 +94,6 @@ public:
// this one is implemented in Fl_win32.cxx
virtual void* thread_message();
virtual int file_type(const char *filename);
virtual int pixmap_extra_transparent_processing() {return 1;}
// this one is implemented in fl_draw_pixmap.cxx
virtual void make_unused_color(unsigned char &r, unsigned char &g, unsigned char &b);
virtual const char *home_directory_name();
virtual const char *filesystems_label() { return "My Computer"; }
virtual int backslash_as_slash() {return 1;}

View File

@ -36,7 +36,7 @@
#include <FL/Fl.H>
#include <FL/Fl_System_Driver.H>
#if defined(FL_CFG_SYS_WIN32)
#include "drivers/WinAPI/Fl_WinAPI_System_Driver.H"
#include "drivers/GDI/Fl_GDI_Graphics_Driver.H"
#endif
#include <FL/platform.H>
#include <FL/fl_draw.H>
@ -91,11 +91,10 @@ int fl_draw_pixmap(/*const*/ char* const* data, int x,int y,Fl_Color bg) {
#if defined(FL_CFG_SYS_WIN32)
unsigned Fl_WinAPI_System_Driver::win_pixmap_bg_color = 0; // the RGB() of the pixmap background color
// Makes an RGB triplet different from all the colors used in the pixmap
// and compute win_pixmap_bg_color from this triplet
void Fl_WinAPI_System_Driver::make_unused_color(uchar &r, uchar &g, uchar &b) {
// and compute Fl_Graphics_Driver::need_pixmap_bg_color from this triplet
void Fl_GDI_Graphics_Driver::make_unused_color_(uchar &r, uchar &g, uchar &b) {
int i;
r = 2; g = 3; b = 4;
while (1) {
@ -106,7 +105,7 @@ void Fl_WinAPI_System_Driver::make_unused_color(uchar &r, uchar &g, uchar &b) {
break;
if (i >= color_count) {
free((void*)used_colors); used_colors = NULL;
win_pixmap_bg_color = RGB(r, g, b);
need_pixmap_bg_color = RGB(r, g, b);
return;
}
if (r < 255) {
@ -128,7 +127,6 @@ void Fl_WinAPI_System_Driver::make_unused_color(uchar &r, uchar &g, uchar &b) {
int fl_convert_pixmap(const char*const* cdata, uchar* out, Fl_Color bg) {
int w, h;
const uchar*const* data = (const uchar*const*)(cdata+1);
static int use_extra_transparent_processing = Fl::system_driver()->pixmap_extra_transparent_processing();
uchar *transparent_c = (uchar *)0; // such that transparent_c[0,1,2] are the RGB of the transparent color
if (!fl_measure_pixmap(cdata, w, h))
@ -140,7 +138,7 @@ int fl_convert_pixmap(const char*const* cdata, uchar* out, Fl_Color bg) {
typedef uchar uchar4[4];
uchar4 *colors = new uchar4[1<<(chars_per_pixel*8)];
if (use_extra_transparent_processing) {
if (Fl_Graphics_Driver::need_pixmap_bg_color) {
color_count = 0;
used_colors = (UsedColor*)malloc(abs(ncolors) * sizeof(UsedColor));
}
@ -153,14 +151,14 @@ int fl_convert_pixmap(const char*const* cdata, uchar* out, Fl_Color bg) {
if (*p == ' ') {
uchar* c = colors[(int)' '];
Fl::get_color(bg, c[0], c[1], c[2]); c[3] = 0;
if (use_extra_transparent_processing) transparent_c = c;
if (Fl_Graphics_Driver::need_pixmap_bg_color) transparent_c = c;
p += 4;
ncolors--;
}
// read all the rest of the colors:
for (int i=0; i < ncolors; i++) {
uchar* c = colors[*p++];
if (use_extra_transparent_processing) {
if (Fl_Graphics_Driver::need_pixmap_bg_color) {
used_colors[color_count].r = *(p+0);
used_colors[color_count].g = *(p+1);
used_colors[color_count].b = *(p+2);
@ -195,7 +193,7 @@ int fl_convert_pixmap(const char*const* cdata, uchar* out, Fl_Color bg) {
int parse = fl_parse_color((const char*)p, c[0], c[1], c[2]);
c[3] = 255;
if (parse) {
if (use_extra_transparent_processing) {
if (Fl_Graphics_Driver::need_pixmap_bg_color) {
used_colors[color_count].r = c[0];
used_colors[color_count].g = c[1];
used_colors[color_count].b = c[2];
@ -206,16 +204,16 @@ int fl_convert_pixmap(const char*const* cdata, uchar* out, Fl_Color bg) {
// "bg" should be transparent...
Fl::get_color(bg, c[0], c[1], c[2]);
c[3] = 0;
if (use_extra_transparent_processing) transparent_c = c;
if (Fl_Graphics_Driver::need_pixmap_bg_color) transparent_c = c;
} // if parse
} // for ncolors
} // if ncolors
if (use_extra_transparent_processing) {
if (Fl_Graphics_Driver::need_pixmap_bg_color) {
if (transparent_c) {
Fl::system_driver()->make_unused_color(transparent_c[0], transparent_c[1], transparent_c[2]);
fl_graphics_driver->make_unused_color_(transparent_c[0], transparent_c[1], transparent_c[2]);
} else {
uchar r, g, b;
Fl::system_driver()->make_unused_color(r, g, b);
fl_graphics_driver->make_unused_color_(r, g, b);
}
}