mirror of
https://github.com/fltk/fltk.git
synced 2026-05-30 21:25:30 +08:00
Better separate printer-specific code using virtual Fl_GDI_Printer_Graphics_Driver::draw(Fl_Bitmap*...)
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10110 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
+3
-1
@@ -33,6 +33,7 @@ struct Fl_Menu_Item;
|
|||||||
class FL_EXPORT Fl_Bitmap : public Fl_Image {
|
class FL_EXPORT Fl_Bitmap : public Fl_Image {
|
||||||
friend class Fl_Quartz_Graphics_Driver;
|
friend class Fl_Quartz_Graphics_Driver;
|
||||||
friend class Fl_GDI_Graphics_Driver;
|
friend class Fl_GDI_Graphics_Driver;
|
||||||
|
friend class Fl_GDI_Printer_Graphics_Driver;
|
||||||
friend class Fl_Xlib_Graphics_Driver;
|
friend class Fl_Xlib_Graphics_Driver;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -42,7 +43,8 @@ public:
|
|||||||
int alloc_array;
|
int alloc_array;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
int start(int XP, int YP, int WP, int HP, int &cx, int &cy,
|
||||||
|
int &X, int &Y, int &W, int &H);
|
||||||
#if defined(__APPLE__) || defined(WIN32)
|
#if defined(__APPLE__) || defined(WIN32)
|
||||||
/** for internal use */
|
/** for internal use */
|
||||||
void *id_;
|
void *id_;
|
||||||
|
|||||||
@@ -482,6 +482,7 @@ public:
|
|||||||
static const char *class_id;
|
static const char *class_id;
|
||||||
const char *class_name() {return class_id;};
|
const char *class_name() {return class_id;};
|
||||||
void draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
|
void draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||||
|
void draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
#if !(defined(__APPLE__) || defined(WIN32))
|
#if !(defined(__APPLE__) || defined(WIN32))
|
||||||
|
|||||||
+64
-63
@@ -243,33 +243,37 @@ void Fl_Bitmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
|
|||||||
fl_graphics_driver->draw(this, XP, YP, WP, HP, cx, cy);
|
fl_graphics_driver->draw(this, XP, YP, WP, HP, cx, cy);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int start(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int w, int h, int &cx, int &cy,
|
int Fl_Bitmap::start(int XP, int YP, int WP, int HP, int &cx, int &cy,
|
||||||
int &X, int &Y, int &W, int &H)
|
int &X, int &Y, int &W, int &H)
|
||||||
{
|
{
|
||||||
|
if (!array) {
|
||||||
|
draw_empty(XP, YP);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
// account for current clip region (faster on Irix):
|
// account for current clip region (faster on Irix):
|
||||||
fl_clip_box(XP,YP,WP,HP,X,Y,W,H);
|
fl_clip_box(XP,YP,WP,HP,X,Y,W,H);
|
||||||
cx += X-XP; cy += Y-YP;
|
cx += X-XP; cy += Y-YP;
|
||||||
// clip the box down to the size of image, quit if empty:
|
// clip the box down to the size of image, quit if empty:
|
||||||
if (cx < 0) {W += cx; X -= cx; cx = 0;}
|
if (cx < 0) {W += cx; X -= cx; cx = 0;}
|
||||||
if (cx+W > w) W = w-cx;
|
if (cx+W > w()) W = w()-cx;
|
||||||
if (W <= 0) return 1;
|
if (W <= 0) return 1;
|
||||||
if (cy < 0) {H += cy; Y -= cy; cy = 0;}
|
if (cy < 0) {H += cy; Y -= cy; cy = 0;}
|
||||||
if (cy+H > h) H = h-cy;
|
if (cy+H > h()) H = h()-cy;
|
||||||
if (H <= 0) return 1;
|
if (H <= 0) return 1;
|
||||||
|
#if defined(WIN32)
|
||||||
|
if (!id_) id_ = fl_create_bitmap(w(), h(), array);
|
||||||
|
#else
|
||||||
|
if (!id_) id_ = fl_create_bitmask(w(), h(), array);
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
void Fl_Quartz_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
|
void Fl_Quartz_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||||
int X, Y, W, H;
|
int X, Y, W, H;
|
||||||
if (!bm->array) {
|
if (bm->start(XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
|
||||||
bm->draw_empty(XP, YP);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (start(bm, XP, YP, WP, HP, bm->w(), bm->h(), cx, cy, X, Y, W, H)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!bm->id_) bm->id_ = fl_create_bitmask(bm->w(), bm->h(), bm->array);
|
|
||||||
if (bm->id_ && fl_gc) {
|
if (bm->id_ && fl_gc) {
|
||||||
CGRect rect = { { X, Y }, { W, H } };
|
CGRect rect = { { X, Y }, { W, H } };
|
||||||
Fl_X::q_begin_image(rect, cx, cy, bm->w(), bm->h());
|
Fl_X::q_begin_image(rect, cx, cy, bm->w(), bm->h());
|
||||||
@@ -281,60 +285,62 @@ void Fl_Quartz_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int
|
|||||||
#elif defined(WIN32)
|
#elif defined(WIN32)
|
||||||
void Fl_GDI_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
|
void Fl_GDI_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||||
int X, Y, W, H;
|
int X, Y, W, H;
|
||||||
if (!bm->array) {
|
if (bm->start(XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
|
||||||
bm->draw_empty(XP, YP);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (start(bm, XP, YP, WP, HP, bm->w(), bm->h(), cx, cy, X, Y, W, H)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!bm->id_) bm->id_ = fl_create_bitmap(bm->w(), bm->h(), bm->array);
|
|
||||||
|
|
||||||
|
HDC tempdc = CreateCompatibleDC(fl_gc);
|
||||||
|
int save = SaveDC(tempdc);
|
||||||
|
SelectObject(tempdc, (HGDIOBJ)bm->id_);
|
||||||
|
SelectObject(fl_gc, fl_brush());
|
||||||
|
// secret bitblt code found in old MSWindows reference manual:
|
||||||
|
BitBlt(fl_gc, X, Y, W, H, tempdc, cx, cy, 0xE20746L);
|
||||||
|
RestoreDC(tempdc, save);
|
||||||
|
DeleteDC(tempdc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Fl_GDI_Printer_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||||
|
int X, Y, W, H;
|
||||||
typedef BOOL (WINAPI* fl_transp_func) (HDC,int,int,int,int,HDC,int,int,int,int,UINT);
|
typedef BOOL (WINAPI* fl_transp_func) (HDC,int,int,int,int,HDC,int,int,int,int,UINT);
|
||||||
static fl_transp_func fl_TransparentBlt;
|
static fl_transp_func fl_TransparentBlt = NULL;
|
||||||
|
static HMODULE hMod = NULL;
|
||||||
|
if (!hMod) {
|
||||||
|
hMod = LoadLibrary("MSIMG32.DLL");
|
||||||
|
if (hMod) fl_TransparentBlt = (fl_transp_func)GetProcAddress(hMod, "TransparentBlt");
|
||||||
|
}
|
||||||
|
if (!fl_TransparentBlt) {
|
||||||
|
Fl_GDI_Graphics_Driver::draw(bm, XP, YP, WP, HP, cx, cy);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (bm->start(XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
HDC tempdc;
|
HDC tempdc;
|
||||||
int save;
|
int save;
|
||||||
BOOL use_print_algo = false;
|
// algorithm for bitmap output to Fl_GDI_Printer
|
||||||
if (Fl_Surface_Device::surface() != Fl_Display_Device::display_device()) {
|
Fl_Color save_c = fl_color(); // save bitmap's desired color
|
||||||
static HMODULE hMod = NULL;
|
uchar r, g, b;
|
||||||
if (!hMod) {
|
Fl::get_color(save_c, r, g, b);
|
||||||
hMod = LoadLibrary("MSIMG32.DLL");
|
r = 255-r;
|
||||||
if (hMod) fl_TransparentBlt = (fl_transp_func)GetProcAddress(hMod, "TransparentBlt");
|
g = 255-g;
|
||||||
}
|
b = 255-b;
|
||||||
if (fl_TransparentBlt) use_print_algo = true;
|
Fl_Color background = fl_rgb_color(r, g, b); // a color very different from the bitmap's
|
||||||
}
|
Fl_Offscreen tmp_id = fl_create_offscreen(W, H);
|
||||||
if (use_print_algo) { // algorithm for bitmap output to Fl_GDI_Printer
|
fl_begin_offscreen(tmp_id);
|
||||||
Fl_Color save_c = fl_color(); // save bitmap's desired color
|
fl_color(background);
|
||||||
uchar r, g, b;
|
fl_rectf(0,0,W,H); // use this color as offscreen background
|
||||||
Fl::get_color(save_c, r, g, b);
|
fl_color(save_c); // back to bitmap's color
|
||||||
r = 255-r;
|
tempdc = CreateCompatibleDC(fl_gc);
|
||||||
g = 255-g;
|
save = SaveDC(tempdc);
|
||||||
b = 255-b;
|
SelectObject(tempdc, (HGDIOBJ)bm->id_);
|
||||||
Fl_Color background = fl_rgb_color(r, g, b); // a color very different from the bitmap's
|
SelectObject(fl_gc, fl_brush()); // use bitmap's desired color
|
||||||
Fl_Offscreen tmp_id = fl_create_offscreen(W, H);
|
BitBlt(fl_gc, 0, 0, W, H, tempdc, 0, 0, 0xE20746L); // draw bitmap to offscreen
|
||||||
fl_begin_offscreen(tmp_id);
|
fl_end_offscreen(); // offscreen data is in tmp_id
|
||||||
fl_color(background);
|
SelectObject(tempdc, (HGDIOBJ)tmp_id); // use offscreen data
|
||||||
fl_rectf(0,0,W,H); // use this color as offscreen background
|
// draw it to printer context with background color as transparent
|
||||||
fl_color(save_c); // back to bitmap's color
|
fl_TransparentBlt(fl_gc, X,Y,W,H, tempdc, cx, cy, bm->w(), bm->h(), RGB(r, g, b) );
|
||||||
tempdc = CreateCompatibleDC(fl_gc);
|
fl_delete_offscreen(tmp_id);
|
||||||
save = SaveDC(tempdc);
|
|
||||||
SelectObject(tempdc, (HGDIOBJ)bm->id_);
|
|
||||||
SelectObject(fl_gc, fl_brush()); // use bitmap's desired color
|
|
||||||
BitBlt(fl_gc, 0, 0, W, H, tempdc, 0, 0, 0xE20746L); // draw bitmap to offscreen
|
|
||||||
fl_end_offscreen(); // offscreen data is in tmp_id
|
|
||||||
SelectObject(tempdc, (HGDIOBJ)tmp_id); // use offscreen data
|
|
||||||
// draw it to printer context with background color as transparent
|
|
||||||
fl_TransparentBlt(fl_gc, X,Y,W,H, tempdc, cx, cy, bm->w(), bm->h(), RGB(r, g, b) );
|
|
||||||
fl_delete_offscreen(tmp_id);
|
|
||||||
}
|
|
||||||
else { // algorithm for bitmap output to display
|
|
||||||
tempdc = CreateCompatibleDC(fl_gc);
|
|
||||||
save = SaveDC(tempdc);
|
|
||||||
SelectObject(tempdc, (HGDIOBJ)bm->id_);
|
|
||||||
SelectObject(fl_gc, fl_brush());
|
|
||||||
// secret bitblt code found in old MSWindows reference manual:
|
|
||||||
BitBlt(fl_gc, X, Y, W, H, tempdc, cx, cy, 0xE20746L);
|
|
||||||
}
|
|
||||||
RestoreDC(tempdc, save);
|
RestoreDC(tempdc, save);
|
||||||
DeleteDC(tempdc);
|
DeleteDC(tempdc);
|
||||||
}
|
}
|
||||||
@@ -342,14 +348,9 @@ void Fl_GDI_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP,
|
|||||||
#else // Xlib
|
#else // Xlib
|
||||||
void Fl_Xlib_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
|
void Fl_Xlib_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||||
int X, Y, W, H;
|
int X, Y, W, H;
|
||||||
if (!bm->array) {
|
if (bm->start(XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
|
||||||
bm->draw_empty(XP, YP);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (start(bm, XP, YP, WP, HP, bm->w(), bm->h(), cx, cy, X, Y, W, H)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!bm->id_) bm->id_ = fl_create_bitmask(bm->w(), bm->h(), bm->array);
|
|
||||||
|
|
||||||
XSetStipple(fl_display, fl_gc, bm->id_);
|
XSetStipple(fl_display, fl_gc, bm->id_);
|
||||||
int ox = X-cx; if (ox < 0) ox += bm->w();
|
int ox = X-cx; if (ox < 0) ox += bm->w();
|
||||||
|
|||||||
Reference in New Issue
Block a user