diff options
| author | Manolo Gouy <Manolo> | 2010-04-16 20:19:09 +0000 |
|---|---|---|
| committer | Manolo Gouy <Manolo> | 2010-04-16 20:19:09 +0000 |
| commit | 913530758af63f00676c6746988aef8b35b02531 (patch) | |
| tree | d6b59be15047e3c2742158eb5063aca55ea94eba /src | |
| parent | 0f180e130639f1017e7ca6b668357304632c1a62 (diff) | |
Improved the hierarchy of Fl_Device subclasses to allow separation of platform-specific devices.
This introduces multiple inheritance.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@7520 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src')
| -rw-r--r-- | src/Fl_Abstract_Printer.cxx | 18 | ||||
| -rw-r--r-- | src/Fl_Bitmap.cxx | 109 | ||||
| -rw-r--r-- | src/Fl_Device.cxx | 28 | ||||
| -rw-r--r-- | src/Fl_Double_Window.cxx | 6 | ||||
| -rw-r--r-- | src/Fl_GDI_Printer.cxx | 2 | ||||
| -rw-r--r-- | src/Fl_Image.cxx | 140 | ||||
| -rw-r--r-- | src/Fl_PS_Printer.cxx | 127 | ||||
| -rw-r--r-- | src/Fl_Pixmap.cxx | 167 | ||||
| -rw-r--r-- | src/Fl_Printer.cxx | 14 | ||||
| -rw-r--r-- | src/Fl_Quartz_Printer.mm | 2 | ||||
| -rw-r--r-- | src/Fl_cocoa.mm | 16 | ||||
| -rw-r--r-- | src/Fl_win32.cxx | 8 | ||||
| -rw-r--r-- | src/Fl_x.cxx | 17 | ||||
| -rw-r--r-- | src/fl_draw_image_win32.cxx | 3 | ||||
| -rw-r--r-- | src/fl_font_win32.cxx | 5 | ||||
| -rw-r--r-- | src/fl_line_style.cxx | 6 | ||||
| -rw-r--r-- | src/fl_rect.cxx | 7 | ||||
| -rw-r--r-- | src/ps_image.cxx | 37 |
18 files changed, 460 insertions, 252 deletions
diff --git a/src/Fl_Abstract_Printer.cxx b/src/Fl_Abstract_Printer.cxx index 0490dcc68..4560ad7df 100644 --- a/src/Fl_Abstract_Printer.cxx +++ b/src/Fl_Abstract_Printer.cxx @@ -70,7 +70,7 @@ void Fl_Abstract_Printer::print_widget(Fl_Widget* widget, int delta_x, int delta int width, height; this->printable_rect(&width, &height); drawn_by_plugin = pi->print(widget, 0, 0, height); - } + } } if (!drawn_by_plugin) { widget->draw(); @@ -126,7 +126,7 @@ void Fl_Abstract_Printer::origin(int *x, int *y) void Fl_Abstract_Printer::print_window_part(Fl_Window *win, int x, int y, int w, int h, int delta_x, int delta_y) { int slice, width, offset, count = 0; - Fl_Device::display_device()->set_current(); + Fl_Device *current = Fl_Device::display_device()->set_current(); Fl_Window *save_front = Fl::first_window(); win->show(); fl_gc = NULL; @@ -144,7 +144,7 @@ void Fl_Abstract_Printer::print_window_part(Fl_Window *win, int x, int y, int w, image_data[count++] = fl_read_image(NULL, x + offset, y, width, h); } save_front->show(); - this->set_current(); + current->set_current(); for ( int i = 0, offset = 0; i < count; i++, offset += slice) { width = slice; if (offset + width > w) width = w - offset; @@ -179,18 +179,6 @@ void Fl_Abstract_Printer::delete_image_list() } #endif -Fl_Device *Fl_Abstract_Printer::set_current(void) -{ -#ifdef __APPLE__ - fl_gc = (CGContextRef)gc; -#elif defined(WIN32) - fl_gc = (HDC)gc; -#else - fl_gc = (_XGC*)gc; -#endif - return this->Fl_Device::set_current(); -} - /** @brief Starts a print job. diff --git a/src/Fl_Bitmap.cxx b/src/Fl_Bitmap.cxx index 13d5bcaee..18d26cc6a 100644 --- a/src/Fl_Bitmap.cxx +++ b/src/Fl_Bitmap.cxx @@ -37,6 +37,7 @@ #include <FL/Fl_Widget.H> #include <FL/Fl_Menu_Item.H> #include <FL/Fl_Bitmap.H> +#include <FL/Fl_Printer.H> #include "flstring.h" #if defined(__APPLE_QUARTZ__) @@ -251,49 +252,66 @@ void Fl_Bitmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) { fl_device->draw(this, XP, YP, WP, HP, cx, cy); } -void Fl_Bitmap::generic_device_draw(int XP, int YP, int WP, int HP, int cx, int cy) { - if (!array) { - draw_empty(XP, YP); - return; - } - +static int start(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int w, int h, int cx, int cy, + int &X, int &Y, int &W, int &H) +{ // account for current clip region (faster on Irix): - int X,Y,W,H; 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; // clip the box down to the size of image, quit if empty: if (cx < 0) {W += cx; X -= cx; cx = 0;} - if ((cx+W) > w()) W = w()-cx; - if (W <= 0) return; + if (cx+W > w) W = w-cx; + if (W <= 0) return 1; if (cy < 0) {H += cy; Y -= cy; cy = 0;} - if ((cy+H) > h()) H = h()-cy; - if (H <= 0) return; + if (cy+H > h) H = h-cy; + if (H <= 0) return 1; + return 0; +} -#if defined(USE_X11) - if (!id_) id_ = fl_create_bitmask(w(), h(), array); +#ifdef __APPLE__ +void Fl_Quartz_Device::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + if (!bm->array) { + bm->draw_empty(XP, YP); + 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) { + CGRect rect = { { X, Y }, { W, H } }; + Fl_X::q_begin_image(rect, cx, cy, bm->w(), bm->h()); + CGContextDrawImage(fl_gc, rect, (CGImageRef)bm->id_); + Fl_X::q_end_image(); + } +} - XSetStipple(fl_display, fl_gc, id_); - int ox = X-cx; if (ox < 0) ox += w(); - int oy = Y-cy; if (oy < 0) oy += h(); - XSetTSOrigin(fl_display, fl_gc, ox, oy); - XSetFillStyle(fl_display, fl_gc, FillStippled); - XFillRectangle(fl_display, fl_window, fl_gc, X, Y, W, H); - XSetFillStyle(fl_display, fl_gc, FillSolid); #elif defined(WIN32) - if (!id_) id_ = fl_create_bitmap(w(), h(), array); - +void Fl_GDI_Device::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + if (!bm->array) { + bm->draw_empty(XP, YP); + 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); + typedef BOOL (WINAPI* fl_transp_func) (HDC,int,int,int,int,HDC,int,int,int,int,UINT); static fl_transp_func fl_TransparentBlt; HDC tempdc; int save; BOOL use_print_algo = false; - if (fl_device->type() == Fl_Device::gdi_printer) { + if (fl_device->type() == Fl_Printer::device_type) { static HMODULE hMod = NULL; if (!hMod) { hMod = LoadLibrary("MSIMG32.DLL"); if (hMod) fl_TransparentBlt = (fl_transp_func)GetProcAddress(hMod, "TransparentBlt"); - } - if (hMod) use_print_algo = true; } + if (hMod) use_print_algo = true; + } if (use_print_algo) { // algorithm for bitmap output to Fl_GDI_Printer Fl_Offscreen tmp_id = fl_create_offscreen(W, H); fl_begin_offscreen(tmp_id); @@ -309,37 +327,48 @@ void Fl_Bitmap::generic_device_draw(int XP, int YP, int WP, int HP, int cx, int fl_color(save_c); // back to bitmap's color tempdc = CreateCompatibleDC(fl_gc); save = SaveDC(tempdc); - SelectObject(tempdc, (HGDIOBJ)id_); + 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, w(), h(), RGB(r, g, b) ); + 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)id_); + 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); -#elif defined(__APPLE_QUARTZ__) - if (!id_) id_ = fl_create_bitmask(w(), h(), array); - if (id_ && fl_gc) { - CGRect rect = { { X, Y }, { W, H } }; - Fl_X::q_begin_image(rect, cx, cy, w(), h()); - CGContextDrawImage(fl_gc, rect, (CGImageRef)id_); - Fl_X::q_end_image(); +} + +#else // Xlib +void Fl_Xlib_Device::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + if (!bm->array) { + bm->draw_empty(XP, YP); + return; } -#else -# error unsupported platform -#endif + 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_); + int ox = X-cx; if (ox < 0) ox += bm->w(); + int oy = Y-cy; if (oy < 0) oy += bm->h(); + XSetTSOrigin(fl_display, fl_gc, ox, oy); + XSetFillStyle(fl_display, fl_gc, FillStippled); + XFillRectangle(fl_display, fl_window, fl_gc, X, Y, W, H); + XSetFillStyle(fl_display, fl_gc, FillSolid); } +#endif /** The destructor free all memory and server resources that are used by diff --git a/src/Fl_Device.cxx b/src/Fl_Device.cxx index 9c76d3f6f..ceead089f 100644 --- a/src/Fl_Device.cxx +++ b/src/Fl_Device.cxx @@ -29,32 +29,10 @@ #include <FL/Fl_Device.H> #include <FL/Fl_Image.H> -/** \brief Draws an Fl_Pixmap object to the device. - * - Specifies a bounding box for the image, with the origin (upper left-hand corner) of - the image offset by the cx and cy arguments. - */ -void Fl_Device::draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) { - pxm->generic_device_draw(XP, YP, WP, HP, cx, cy); -} - -/** \brief Draws an Fl_Bitmap object to the device. - * - Specifies a bounding box for the image, with the origin (upper left-hand corner) of - the image offset by the cx and cy arguments. - */ -void Fl_Device::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) { - bm->generic_device_draw(XP, YP, WP, HP, cx, cy); -} +const char *Fl_Device::device_type = "Fl_Device"; +const char *Fl_Display_Device::device_type = "Fl_Display_Device"; +const char *Fl_Graphics_Device::device_type = "Fl_Graphics_Device"; -/** \brief Draws an Fl_RGB_Image object to the device. - * - Specifies a bounding box for the image, with the origin (upper left-hand corner) of - the image offset by the cx and cy arguments. - */ -void Fl_Device::draw(Fl_RGB_Image *rgb, int XP, int YP, int WP, int HP, int cx, int cy) { - rgb->generic_device_draw(XP, YP, WP, HP, cx, cy); -} /** @brief Sets this device (display, printer, local file) as the target of future graphics calls. diff --git a/src/Fl_Double_Window.cxx b/src/Fl_Double_Window.cxx index 89f838844..70462a2ab 100644 --- a/src/Fl_Double_Window.cxx +++ b/src/Fl_Double_Window.cxx @@ -28,6 +28,7 @@ #include <config.h> #include <FL/Fl.H> #include <FL/Fl_Double_Window.H> +#include <FL/Fl_Printer.H> #include <FL/x.H> #include <FL/fl_draw.H> @@ -148,8 +149,9 @@ void fl_copy_offscreen_with_alpha(int x,int y,int w,int h,HBITMAP bitmap,int src SelectObject(new_gc, bitmap); BOOL alpha_ok = 0; // first try to alpha blend - int to_display = Fl_Device::current()->type() < 256; // true iff display output - if ( (!to_display) || fl_can_do_alpha_blending()) // if not on display, always try alpha_blend + // if to printer, always try alpha_blend + int to_display = Fl_Device::current()->type() == Fl_Display_Device::device_type; // true iff display output + if ( (to_display && fl_can_do_alpha_blending()) || Fl_Device::current()->type() == Fl_Printer::device_type) alpha_ok = fl_alpha_blend(fl_gc, x, y, w, h, new_gc, srcx, srcy, w, h, blendfunc); // if that failed (it shouldn't), still copy the bitmap over, but now alpha is 1 if (!alpha_ok) diff --git a/src/Fl_GDI_Printer.cxx b/src/Fl_GDI_Printer.cxx index f89374095..8a4648881 100644 --- a/src/Fl_GDI_Printer.cxx +++ b/src/Fl_GDI_Printer.cxx @@ -36,7 +36,7 @@ extern HWND fl_window; Fl_Printer::Fl_Printer(void) : Fl_Abstract_Printer() { hPr = NULL; - type_ = gdi_printer; + type_ = device_type; } Fl_Printer::~Fl_Printer(void) { diff --git a/src/Fl_Image.cxx b/src/Fl_Image.cxx index bf39f6b09..360789523 100644 --- a/src/Fl_Image.cxx +++ b/src/Fl_Image.cxx @@ -437,7 +437,7 @@ void Fl_RGB_Image::draw(int XP, int YP, int WP, int HP, int cx, int cy) { fl_device->draw(this, XP, YP, WP, HP, cx, cy); } -void Fl_RGB_Image::generic_device_draw(int XP, int YP, int WP, int HP, int cx, int cy) { +/*void Fl_RGB_Image::generic_device_draw(int XP, int YP, int WP, int HP, int cx, int cy) { // Don't draw an empty image... if (!d() || !array) { draw_empty(XP, YP); @@ -542,8 +542,146 @@ void Fl_RGB_Image::generic_device_draw(int XP, int YP, int WP, int HP, int cx, i #else # error unsupported platform #endif +}*/ + +static int start(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int w, int h, int cx, int cy, + int &X, int &Y, int &W, int &H) +{ + // account for current clip region (faster on Irix): + fl_clip_box(XP,YP,WP,HP,X,Y,W,H); + cx += X-XP; cy += Y-YP; + // clip the box down to the size of image, quit if empty: + if (cx < 0) {W += cx; X -= cx; cx = 0;} + if (cx+W > w) W = w-cx; + if (W <= 0) return 1; + if (cy < 0) {H += cy; Y -= cy; cy = 0;} + if (cy+H > h) H = h-cy; + if (H <= 0) return 1; + return 0; } +#ifdef __APPLE__ +void Fl_Quartz_Device::draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + // Don't draw an empty image... + if (!img->d() || !img->array) { + img->draw_empty(XP, YP); + return; + } + if (start(img, XP, YP, WP, HP, img->w(), img->h(), cx, cy, X, Y, W, H)) { + return; + } + if (!img->id_) { + CGColorSpaceRef lut = 0; + if (img->d()<=2) + lut = CGColorSpaceCreateDeviceGray(); + else + lut = CGColorSpaceCreateDeviceRGB(); + CGDataProviderRef src = CGDataProviderCreateWithData( 0L, img->array, img->w()*img->h()*img->d(), 0L); + img->id_ = CGImageCreate( img->w(), img->h(), 8, img->d()*8, img->ld()?img->ld():img->w()*img->d(), + lut, (img->d()&1)?kCGImageAlphaNone:kCGImageAlphaLast, + src, 0L, false, kCGRenderingIntentDefault); + CGColorSpaceRelease(lut); + CGDataProviderRelease(src); + } + if (img->id_ && fl_gc) { + CGRect rect = { { X, Y }, { W, H } }; + Fl_X::q_begin_image(rect, cx, cy, img->w(), img->h()); + CGContextDrawImage(fl_gc, rect, (CGImageRef)img->id_); + Fl_X::q_end_image(); + } +} + +#elif defined(WIN32) +void Fl_GDI_Device::draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + // Don't draw an empty image... + if (!img->d() || !img->array) { + img->draw_empty(XP, YP); + return; + } + if (start(img, XP, YP, WP, HP, img->w(), img->h(), cx, cy, X, Y, W, H)) { + return; + } + if (!img->id_) { + img->id_ = fl_create_offscreen(img->w(), img->h()); + if ((img->d() == 2 || img->d() == 4) && fl_can_do_alpha_blending()) { + fl_begin_offscreen((Fl_Offscreen)img->id_); + fl_draw_image(img->array, 0, 0, img->w(), img->h(), img->d()|FL_IMAGE_WITH_ALPHA, img->ld()); + fl_end_offscreen(); + } else { + fl_begin_offscreen((Fl_Offscreen)img->id_); + fl_draw_image(img->array, 0, 0, img->w(), img->h(), img->d(), img->ld()); + fl_end_offscreen(); + if (img->d() == 2 || img->d() == 4) { + img->mask_ = fl_create_alphamask(img->w(), img->h(), img->d(), img->ld(), img->array); + } + } + } + if (img->mask_) { + HDC new_gc = CreateCompatibleDC(fl_gc); + int save = SaveDC(new_gc); + SelectObject(new_gc, (void*)img->mask_); + BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCAND); + SelectObject(new_gc, (void*)img->id_); + BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCPAINT); + RestoreDC(new_gc,save); + DeleteDC(new_gc); + } else if (img->d()==2 || img->d()==4) { + fl_copy_offscreen_with_alpha(X, Y, W, H, (Fl_Offscreen)img->id_, cx, cy); + } else { + fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)img->id_, cx, cy); + } +} + +#else +void Fl_Xlib_Device::draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + // Don't draw an empty image... + if (!img->d() || !img->array) { + img->draw_empty(XP, YP); + return; + } + if (start(img, XP, YP, WP, HP, img->w(), img->h(), cx, cy, X, Y, W, H)) { + return; + } + if (!img->id_) { + if (img->d() == 1 || img->d() == 3) { + img->id_ = fl_create_offscreen(img->w(), img->h()); + fl_begin_offscreen((Fl_Offscreen)img->id_); + fl_draw_image(img->array, 0, 0, img->w(), img->h(), img->d(), img->ld()); + fl_end_offscreen(); + } + } + if (img->id_) { + if (img->mask_) { + // I can't figure out how to combine a mask with existing region, + // so cut the image down to a clipped rectangle: + int nx, ny; fl_clip_box(X,Y,W,H,nx,ny,W,H); + cx += nx-X; X = nx; + cy += ny-Y; Y = ny; + // make X use the bitmap as a mask: + XSetClipMask(fl_display, fl_gc, img->mask_); + int ox = X-cx; if (ox < 0) ox += img->w(); + int oy = Y-cy; if (oy < 0) oy += img->h(); + XSetClipOrigin(fl_display, fl_gc, X-cx, Y-cy); + } + + fl_copy_offscreen(X, Y, W, H, img->id_, cx, cy); + + if (img->mask_) { + // put the old clip region back + XSetClipOrigin(fl_display, fl_gc, 0, 0); + fl_restore_clip(); + } + } else { + // Composite image with alpha manually each time... + alpha_blend(img, X, Y, W, H, cx, cy); + } +} + +#endif + void Fl_RGB_Image::label(Fl_Widget* widget) { widget->image(this); } diff --git a/src/Fl_PS_Printer.cxx b/src/Fl_PS_Printer.cxx index 347c40644..e79ff8a3b 100644 --- a/src/Fl_PS_Printer.cxx +++ b/src/Fl_PS_Printer.cxx @@ -32,25 +32,34 @@ #include <FL/Fl_PSfile_Device.H> #include <FL/Fl_Native_File_Chooser.H> +const char *Fl_PS_Device::device_type = "Fl_PS_Device"; +const char *Fl_PSfile_Device::device_type = "Fl_PSfile_Device"; const char *Fl_PSfile_Device::file_chooser_title = "Select a .ps file"; /** @brief The constructor. */ -Fl_PSfile_Device::Fl_PSfile_Device(void) +Fl_PS_Device::Fl_PS_Device(void) { close_cmd_ = 0; //lang_level_ = 3; lang_level_ = 2; mask = 0; ps_filename_ = NULL; - type_ = postscript_device; + type_ = device_type; scale_x = scale_y = 1.; +} + +/** + @brief The constructor. + */ +Fl_PSfile_Device::Fl_PSfile_Device(void) +{ + type_ = device_type; #ifdef __APPLE__ gc = fl_gc; // the display context is used by fl_text_extents() #endif } - /** @brief Begins the session where all graphics requests will go to a local PostScript file. * @@ -107,7 +116,7 @@ Fl_PSfile_Device::~Fl_PSfile_Device() { #include "print_panel.cxx" #endif -const Fl_PSfile_Device::page_format Fl_PSfile_Device::page_formats[NO_PAGE_FORMATS] = { // order of enum Page_Format +const Fl_PS_Device::page_format Fl_PS_Device::page_formats[NO_PAGE_FORMATS] = { // order of enum Page_Format // comes from appendix B of 5003.PPD_Spec_v4.3.pdf // A* // index(Ai) = i @@ -459,7 +468,7 @@ static const char * prolog_3 = // prolog relevant only if lang_level >2 // end prolog -int Fl_PSfile_Device::start_postscript (int pagecount, enum Page_Format format, enum Page_Layout layout) +int Fl_PS_Device::start_postscript (int pagecount, enum Page_Format format, enum Page_Layout layout) //returns 0 iff OK { int w, h, x; @@ -517,13 +526,13 @@ int Fl_PSfile_Device::start_postscript (int pagecount, enum Page_Format format, return 0; } -void Fl_PSfile_Device::recover(){ +void Fl_PS_Device::recover(){ color(cr_,cg_,cb_); line_style(linestyle_,linewidth_,linedash_); font(font_,size_); } -void Fl_PSfile_Device::reset(){ +void Fl_PS_Device::reset(){ gap_=1; clip_=0; cr_=cg_=cb_=0; @@ -542,7 +551,7 @@ void Fl_PSfile_Device::reset(){ } -void Fl_PSfile_Device::page_policy(int p){ +void Fl_PS_Device::page_policy(int p){ page_policy_ = p; if(lang_level_>=2) fprintf(output,"<< /Policies << /Pagesize %i >> >> setpagedevice\n", p); @@ -552,7 +561,7 @@ void Fl_PSfile_Device::page_policy(int p){ -void Fl_PSfile_Device::page(double pw, double ph, int media) { +void Fl_PS_Device::page(double pw, double ph, int media) { if (nPages){ fprintf(output, "CR\nGR\nGR\nGR\nSP\nrestore\n"); @@ -601,20 +610,20 @@ void Fl_PSfile_Device::page(double pw, double ph, int media) { fprintf(output, "GS\nCS\n"); }; -void Fl_PSfile_Device::page(int format){ +void Fl_PS_Device::page(int format){ if(format & LANDSCAPE){ - ph_=Fl_PSfile_Device::page_formats[format & 0xFF].width; - pw_=Fl_PSfile_Device::page_formats[format & 0xFF].height; + ph_=Fl_PS_Device::page_formats[format & 0xFF].width; + pw_=Fl_PS_Device::page_formats[format & 0xFF].height; }else{ - pw_=Fl_PSfile_Device::page_formats[format & 0xFF].width; - ph_=Fl_PSfile_Device::page_formats[format & 0xFF].height; + pw_=Fl_PS_Device::page_formats[format & 0xFF].width; + ph_=Fl_PS_Device::page_formats[format & 0xFF].height; } page(pw_,ph_,format & 0xFF00);//,orientation only; }; -void Fl_PSfile_Device::rect(int x, int y, int w, int h) { +void Fl_PS_Device::rect(int x, int y, int w, int h) { // Commented code does not work, i can't find the bug ;-( // fprintf(output, "GS\n"); // fprintf(output, "%i, %i, %i, %i R\n", x , y , w, h); @@ -629,17 +638,17 @@ void Fl_PSfile_Device::rect(int x, int y, int w, int h) { fprintf(output, "GR\n"); } -void Fl_PSfile_Device::rectf(int x, int y, int w, int h) { +void Fl_PS_Device::rectf(int x, int y, int w, int h) { fprintf(output, "%g %g %i %i FR\n", x-0.5, y-0.5, w, h); } -void Fl_PSfile_Device::line(int x1, int y1, int x2, int y2) { +void Fl_PS_Device::line(int x1, int y1, int x2, int y2) { fprintf(output, "GS\n"); fprintf(output, "%i %i %i %i L\n", x1 , y1, x2 ,y2); fprintf(output, "GR\n"); } -void Fl_PSfile_Device::line(int x0, int y0, int x1, int y1, int x2, int y2) { +void Fl_PS_Device::line(int x0, int y0, int x1, int y1, int x2, int y2) { fprintf(output, "GS\n"); fprintf(output,"BP\n"); fprintf(output, "%i %i MT\n", x0 , y0); @@ -649,7 +658,7 @@ void Fl_PSfile_Device::line(int x0, int y0, int x1, int y1, int x2, int y2) { fprintf(output, "GR\n"); } -void Fl_PSfile_Device::xyline(int x, int y, int x1, int y2, int x3){ +void Fl_PS_Device::xyline(int x, int y, int x1, int y2, int x3){ fprintf(output, "GS\n"); fprintf(output,"BP\n"); fprintf(output, "%i %i MT\n", x , y ); @@ -661,7 +670,7 @@ void Fl_PSfile_Device::xyline(int x, int y, int x1, int y2, int x3){ }; -void Fl_PSfile_Device::xyline(int x, int y, int x1, int y2){ +void Fl_PS_Device::xyline(int x, int y, int x1, int y2){ fprintf(output, "GS\n"); fprintf(output,"BP\n"); @@ -672,7 +681,7 @@ void Fl_PSfile_Device::xyline(int x, int y, int x1, int y2){ fprintf(output, "GR\n"); }; -void Fl_PSfile_Device::xyline(int x, int y, int x1){ +void Fl_PS_Device::xyline(int x, int y, int x1){ fprintf(output, "GS\n"); fprintf(output,"BP\n"); fprintf(output, "%i %i MT\n", x , y); @@ -682,7 +691,7 @@ void Fl_PSfile_Device::xyline(int x, int y, int x1){ fprintf(output, "GR\n"); }; -void Fl_PSfile_Device::yxline(int x, int y, int y1, int x2, int y3){ +void Fl_PS_Device::yxline(int x, int y, int y1, int x2, int y3){ fprintf(output, "GS\n"); fprintf(output,"BP\n"); @@ -694,7 +703,7 @@ void Fl_PSfile_Device::yxline(int x, int y, int y1, int x2, int y3){ fprintf(output, "GR\n"); }; -void Fl_PSfile_Device::yxline(int x, int y, int y1, int x2){ +void Fl_PS_Device::yxline(int x, int y, int y1, int x2){ fprintf(output, "GS\n"); fprintf(output,"BP\n"); fprintf(output, "%i %i MT\n", x , y); @@ -704,7 +713,7 @@ void Fl_PSfile_Device::yxline(int x, int y, int y1, int x2){ fprintf(output, "GR\n"); }; -void Fl_PSfile_Device::yxline(int x, int y, int y1){ +void Fl_PS_Device::yxline(int x, int y, int y1){ fprintf(output, "GS\n"); fprintf(output,"BP\n"); fprintf(output, "%i %i MT\n", x , y); @@ -713,7 +722,7 @@ void Fl_PSfile_Device::yxline(int x, int y, int y1){ fprintf(output, "GR\n"); }; -void Fl_PSfile_Device::loop(int x0, int y0, int x1, int y1, int x2, int y2) { +void Fl_PS_Device::loop(int x0, int y0, int x1, int y1, int x2, int y2) { fprintf(output, "GS\n"); fprintf(output,"BP\n"); fprintf(output, "%i %i MT\n", x0 , y0); @@ -723,7 +732,7 @@ void Fl_PSfile_Device::loop(int x0, int y0, int x1, int y1, int x2, int y2) { fprintf(output, "GR\n"); } -void Fl_PSfile_Device::loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) { +void Fl_PS_Device::loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) { fprintf(output, "GS\n"); fprintf(output,"BP\n"); fprintf(output, "%i %i MT\n", x0 , y0); @@ -734,7 +743,7 @@ void Fl_PSfile_Device::loop(int x0, int y0, int x1, int y1, int x2, int y2, int fprintf(output, "GR\n"); } -void Fl_PSfile_Device::polygon(int x0, int y0, int x1, int y1, int x2, int y2) { +void Fl_PS_Device::polygon(int x0, int y0, int x1, int y1, int x2, int y2) { fprintf(output, "GS\n"); fprintf(output,"BP\n"); fprintf(output, "%i %i MT\n", x0 , y0); @@ -744,7 +753,7 @@ void Fl_PSfile_Device::polygon(int x0, int y0, int x1, int y1, int x2, int y2) { fprintf(output, "GR\n"); } -void Fl_PSfile_Device::polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) { +void Fl_PS_Device::polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) { fprintf(output, "GS\n"); fprintf(output,"BP\n"); fprintf(output, "%i %i MT\n", x0 , y0 ); @@ -756,7 +765,7 @@ void Fl_PSfile_Device::polygon(int x0, int y0, int x1, int y1, int x2, int y2, i fprintf(output, "GR\n"); } -void Fl_PSfile_Device::point(int x, int y){ +void Fl_PS_Device::point(int x, int y){ rectf(x,y,1,1); } @@ -779,7 +788,7 @@ static double dashes_cap[5][7]={ }; -void Fl_PSfile_Device::line_style(int style, int width, char* dashes){ +void Fl_PS_Device::line_style(int style, int width, char* dashes){ //line_styled_=1; linewidth_=width; @@ -857,16 +866,16 @@ static const char *_fontNames[] = { "ZapfDingbats" }; -void Fl_PSfile_Device::font(int f, int s) { +void Fl_PS_Device::font(int f, int s) { if (f >= FL_FREE_FONT) f = FL_COURIER; fprintf(output, "/%s SF\n" , _fontNames[f]); fprintf(output,"%i FS\n", s); - Fl_Device::display_device()->font(f,s); // Use display fonts for font measurement + display_device()->font(f,s); // Use display fonts for font measurement font_ = f; size_ = s; }; -void Fl_PSfile_Device::color(Fl_Color c) { +void Fl_PS_Device::color(Fl_Color c) { //colored_=1; color_=c; Fl::get_color(c, cr_, cg_, cb_); @@ -883,7 +892,7 @@ void Fl_PSfile_Device::color(Fl_Color c) { } } -void Fl_PSfile_Device::color(unsigned char r, unsigned char g, unsigned char b) { +void Fl_PS_Device::color(unsigned char r, unsigned char g, unsigned char b) { //colored_=1; cr_=r;cg_=g;cb_=b; if (r==g && g==b) { @@ -898,14 +907,14 @@ void Fl_PSfile_Device::color(unsigned char r, unsigned char g, unsigned char b) } } -void Fl_PSfile_Device::draw(int angle, const char *str, int n, int x, int y) +void Fl_PS_Device::draw(int angle, const char *str, int n, int x, int y) { fprintf(output, "GS %d %d translate %d rotate\n", x, y, - angle); this->transformed_draw(str, n, 0, 0); fprintf(output, "GR\n"); } -void Fl_PSfile_Device::transformed_draw(const char* str, int n, double x, double y){ +void Fl_PS_Device::transformed_draw(const char* str, int n, double x, double y){ if (!n || !str || !*str)return; fprintf(output,"%g (", fl_width(str, n)); int i=1; @@ -930,18 +939,18 @@ void Fl_PSfile_Device::transformed_draw(const char* str, int n, double x, double struct matrix {double a, b, c, d, x, y;}; extern matrix * fl_matrix; -void Fl_PSfile_Device::concat(){ +void Fl_PS_Device::concat(){ fprintf(output,"[%g %g %g %g %g %g] CT\n", fl_matrix->a , fl_matrix->b , fl_matrix->c , fl_matrix->d , fl_matrix->x , fl_matrix->y); } -void Fl_PSfile_Device::reconcat(){ +void Fl_PS_Device::reconcat(){ fprintf(output, "[%g %g %g %g %g %g] RCT\n" , fl_matrix->a , fl_matrix->b , fl_matrix->c , fl_matrix->d , fl_matrix->x , fl_matrix->y); } ///////////////// transformed (double) drawings //////////////////////////////// -void Fl_PSfile_Device::begin_points(){ +void Fl_PS_Device::begin_points(){ fprintf(output, "GS\n"); concat(); @@ -950,7 +959,7 @@ void Fl_PSfile_Device::begin_points(){ shape_=POINTS; }; -void Fl_PSfile_Device::begin_line(){ +void Fl_PS_Device::begin_line(){ fprintf(output, "GS\n"); concat(); fprintf(output, "BP\n"); @@ -958,7 +967,7 @@ void Fl_PSfile_Device::begin_line(){ shape_=LINE; }; -void Fl_PSfile_Device::begin_loop(){ +void Fl_PS_Device::begin_loop(){ fprintf(output, "GS\n"); concat(); fprintf(output, "BP\n"); @@ -966,7 +975,7 @@ void Fl_PSfile_Device::begin_loop(){ shape_=LOOP; }; -void Fl_PSfile_Device::begin_polygon(){ +void Fl_PS_Device::begin_polygon(){ fprintf(output, "GS\n"); concat(); fprintf(output, "BP\n"); @@ -974,7 +983,7 @@ void Fl_PSfile_Device::begin_polygon(){ shape_=POLYGON; }; -void Fl_PSfile_Device::vertex(double x, double y){ +void Fl_PS_Device::vertex(double x, double y){ if(shape_==POINTS){ fprintf(output,"%g %g MT\n", x , y); gap_=1; @@ -987,7 +996,7 @@ void Fl_PSfile_Device::vertex(double x, double y){ fprintf(output, "%g %g LT\n", x , y); }; -void Fl_PSfile_Device::curve(double x, double y, double x1, double y1, double x2, double y2, double x3, double y3){ +void Fl_PS_Device::curve(double x, double y, double x1, double y1, double x2, double y2, double x3, double y3){ if(shape_==NONE) return; if(gap_) fprintf(output,"%g %g MT\n", x , y); @@ -999,7 +1008,7 @@ void Fl_PSfile_Device::curve(double x, double y, double x1, double y1, double x2 }; -void Fl_PSfile_Device::circle(double x, double y, double r){ +void Fl_PS_Device::circle(double x, double y, double r){ if(shape_==NONE){ fprintf(output, "GS\n"); concat(); @@ -1014,7 +1023,7 @@ void Fl_PSfile_Device::circle(double x, double y, double r){ }; -void Fl_PSfile_Device::arc(double x, double y, double r, double start, double a){ +void Fl_PS_Device::arc(double x, double y, double r, double start, double a){ if(shape_==NONE) return; gap_=0; if(start>a) @@ -1024,7 +1033,7 @@ void Fl_PSfile_Device::arc(double x, double y, double r, double start, double a) }; -void Fl_PSfile_Device::arc(int x, int y, int w, int h, double a1, double a2) { +void Fl_PS_Device::arc(int x, int y, int w, int h, double a1, double a2) { fprintf(output, "GS\n"); //fprintf(output, "BP\n"); begin_line(); @@ -1043,7 +1052,7 @@ void Fl_PSfile_Device::arc(int x, int y, int w, int h, double a1, double a2) { fprintf(output, "GR\n"); } -void Fl_PSfile_Device::pie(int x, int y, int w, int h, double a1, double a2) { +void Fl_PS_Device::pie(int x, int y, int w, int h, double a1, double a2) { fprintf(output, "GS\n"); fprintf(output, "%g %g TR\n", x + w/2.0 -0.5 , y + h/2.0 - 0.5); @@ -1055,7 +1064,7 @@ void Fl_PSfile_Device::pie(int x, int y, int w, int h, double a1, double a2) { fprintf(output, "GR\n"); } -void Fl_PSfile_Device::end_points(){ +void Fl_PS_Device::end_points(){ gap_=1; reconcat(); fprintf(output, "ELP\n"); //?? @@ -1063,14 +1072,14 @@ void Fl_PSfile_Device::end_points(){ shape_=NONE; } -void Fl_PSfile_Device::end_line(){ +void Fl_PS_Device::end_line(){ gap_=1; reconcat(); fprintf(output, "ELP\n"); fprintf(output, "GR\n"); shape_=NONE; } -void Fl_PSfile_Device::end_loop(){ +void Fl_PS_Device::end_loop(){ gap_=1; reconcat(); fprintf(output, "ECP\n"); @@ -1078,7 +1087,7 @@ void Fl_PSfile_Device::end_loop(){ shape_=NONE; } -void Fl_PSfile_Device::end_polygon(){ +void Fl_PS_Device::end_polygon(){ gap_=1; reconcat(); @@ -1087,7 +1096,7 @@ void Fl_PSfile_Device::end_polygon(){ shape_=NONE; } -void Fl_PSfile_Device::transformed_vertex(double x, double y){ +void Fl_PS_Device::transformed_vertex(double x, double y){ reconcat(); if(gap_){ fprintf(output, "%g %g MT\n", x , y); @@ -1099,7 +1108,7 @@ void Fl_PSfile_Device::transformed_vertex(double x, double y){ ///////////////////////////// Clipping ///////////////////////////////////////////// -void Fl_PSfile_Device::push_clip(int x, int y, int w, int h) { +void Fl_PS_Device::push_clip(int x, int y, int w, int h) { Clip * c=new Clip(); clip_box(x,y,w,h,c->x,c->y,c->w,c->h); c->prev=clip_; @@ -1111,7 +1120,7 @@ void Fl_PSfile_Device::push_clip(int x, int y, int w, int h) { } -void Fl_PSfile_Device::push_no_clip() { +void Fl_PS_Device::push_no_clip() { Clip * c = new Clip(); c->prev=clip_; clip_=c; @@ -1121,7 +1130,7 @@ void Fl_PSfile_Device::push_no_clip() { recover(); } -void Fl_PSfile_Device::pop_clip() { +void Fl_PS_Device::pop_clip() { if(!clip_)return; Clip * c=clip_; clip_=clip_->prev; @@ -1134,7 +1143,7 @@ void Fl_PSfile_Device::pop_clip() { recover(); } -int Fl_PSfile_Device::clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H){ +int Fl_PS_Device::clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H){ if(!clip_){ X=x;Y=y;W=w;H=h; return 1; @@ -1170,7 +1179,7 @@ int Fl_PSfile_Device::clip_box(int x, int y, int w, int h, int &X, int &Y, int & return ret; }; -int Fl_PSfile_Device::not_clipped(int x, int y, int w, int h){ +int Fl_PS_Device::not_clipped(int x, int y, int w, int h){ if(!clip_) return 1; if(clip_->w < 0) return 1; int X, Y, W, H; @@ -1342,7 +1351,7 @@ int Fl_Printer::start_job(int pages, int *firstpage, int *lastpage) { return 1; } - return Fl_PSfile_Device::start_postscript(pages, format, layout); // start printing + return Fl_PS_Device::start_postscript(pages, format, layout); // start printing } #endif // ! (defined(__APPLE__) || defined(WIN32) ) diff --git a/src/Fl_Pixmap.cxx b/src/Fl_Pixmap.cxx index d20132a35..a75b25a75 100644 --- a/src/Fl_Pixmap.cxx +++ b/src/Fl_Pixmap.cxx @@ -47,6 +47,7 @@ #include <FL/Fl_Widget.H> #include <FL/Fl_Menu_Item.H> #include <FL/Fl_Pixmap.H> +#include <FL/Fl_Printer.H> #include <stdio.h> #include "flstring.h" @@ -77,121 +78,161 @@ void Fl_Pixmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) { fl_device->draw(this, XP, YP, WP, HP, cx, cy); } -void Fl_Pixmap::generic_device_draw(int XP, int YP, int WP, int HP, int cx, int cy) { +static int start(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int w, int h, int cx, int cy, + int &X, int &Y, int &W, int &H) +{ // ignore empty or bad pixmap data: - if (!data()) { - draw_empty(XP, YP); - return; + if (!pxm->data()) { + return 2; } - if (w()<0) measure(); - if (WP==-1) { - WP = w(); - HP = h(); + if (WP == -1) { + WP = w; + HP = h; } - if (!w()) { - draw_empty(XP, YP); - return; + if (!w) { + return 2; } // account for current clip region (faster on Irix): - int X,Y,W,H; 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; // clip the box down to the size of image, quit if empty: if (cx < 0) {W += cx; X -= cx; cx = 0;} - if (cx+W > w()) W = w()-cx; - if (W <= 0) return; + if (cx+W > w) W = w-cx; + if (W <= 0) return 1; if (cy < 0) {H += cy; Y -= cy; cy = 0;} - if (cy+H > h()) H = h()-cy; - if (H <= 0) return; - if (!id_) { -#ifdef __APPLE_QUARTZ__ - id_ = fl_create_offscreen_with_alpha(w(), h()); - fl_begin_offscreen((Fl_Offscreen)id_); - fl_draw_pixmap(data(), 0, 0, FL_GREEN); + if (cy+H > h) H = h-cy; + if (H <= 0) return 1; + return 0; +} + +#ifdef __APPLE__ +void Fl_Quartz_Device::draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + if (pxm->w() < 0) pxm->measure(); + int code = start(pxm, XP, YP, WP, HP, pxm->w(), pxm->h(), cx, cy, X, Y, W, H); + if (code) { + if (code == 2) pxm->draw_empty(XP, YP); + return; + } + if (!pxm->id_) { + pxm->id_ = fl_create_offscreen_with_alpha(pxm->w(), pxm->h()); + fl_begin_offscreen((Fl_Offscreen)pxm->id_); + fl_draw_pixmap(pxm->data(), 0, 0, FL_GREEN); fl_end_offscreen(); -#else - id_ = fl_create_offscreen(w(), h()); - fl_begin_offscreen((Fl_Offscreen)id_); + } + fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)pxm->id_, cx, cy); +} + +#elif defined(WIN32) +void Fl_GDI_Device::draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + if (pxm->w() < 0) pxm->measure(); + int code = start(pxm, XP, YP, WP, HP, pxm->w(), pxm->h(), cx, cy, X, Y, W, H); + if (code) { + if (code == 2) pxm->draw_empty(XP, YP); + return; + } + if (!pxm->id_) { + pxm->id_ = fl_create_offscreen(pxm->w(), pxm->h()); + fl_begin_offscreen((Fl_Offscreen)pxm->id_); uchar *bitmap = 0; fl_mask_bitmap = &bitmap; - fl_draw_pixmap(data(), 0, 0, FL_BLACK); + fl_draw_pixmap(pxm->data(), 0, 0, FL_BLACK); fl_mask_bitmap = 0; if (bitmap) { - mask_ = fl_create_bitmask(w(), h(), bitmap); + pxm->mask_ = fl_create_bitmask(pxm->w(), pxm->h(), bitmap); delete[] bitmap; } fl_end_offscreen(); -#endif - } - -#if defined(USE_X11) - if (mask_) { - // I can't figure out how to combine a mask with existing region, - // so cut the image down to a clipped rectangle: - int nx, ny; fl_clip_box(X,Y,W,H,nx,ny,W,H); - cx += nx-X; X = nx; - cy += ny-Y; Y = ny; - // make X use the bitmap as a mask: - XSetClipMask(fl_display, fl_gc, mask_); - int ox = X-cx; if (ox < 0) ox += w(); - int oy = Y-cy; if (oy < 0) oy += h(); - XSetClipOrigin(fl_display, fl_gc, X-cx, Y-cy); } - fl_copy_offscreen(X, Y, W, H, id_, cx, cy); - if (mask_) { - // put the old clip region back - XSetClipOrigin(fl_display, fl_gc, 0, 0); - fl_restore_clip(); - } -#elif defined(WIN32) - if (fl_device->type() == Fl_Device::gdi_printer) { + if (fl_device->type() == Fl_Printer::device_type) { typedef BOOL (WINAPI* fl_transp_func) (HDC,int,int,int,int,HDC,int,int,int,int,UINT); static HMODULE hMod = NULL; static fl_transp_func fl_TransparentBlt = NULL; if (!hMod) { hMod = LoadLibrary("MSIMG32.DLL"); if(hMod) fl_TransparentBlt = (fl_transp_func)GetProcAddress(hMod, "TransparentBlt"); - } + } if (hMod) { - Fl_Offscreen tmp_id = fl_create_offscreen(w(), h()); + Fl_Offscreen tmp_id = fl_create_offscreen(pxm->w(), pxm->h()); fl_begin_offscreen(tmp_id); uchar *bitmap = 0; fl_mask_bitmap = &bitmap; // draw pixmap to offscreen - fl_draw_pixmap(data(), 0, 0); + fl_draw_pixmap(pxm->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 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 ); + fl_TransparentBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, pxm->w(), pxm->h(), win_pixmap_bg_color ); RestoreDC(new_gc,save); DeleteDC(new_gc); fl_delete_offscreen(tmp_id); } else { - fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id_, cx, cy); + fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)pxm->id_, cx, cy); } } - else if (mask_) { + else if (pxm->mask_) { HDC new_gc = CreateCompatibleDC(fl_gc); int save = SaveDC(new_gc); - SelectObject(new_gc, (void*)mask_); + SelectObject(new_gc, (void*)pxm->mask_); BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCAND); - SelectObject(new_gc, (void*)id_); + SelectObject(new_gc, (void*)pxm->id_); BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCPAINT); RestoreDC(new_gc,save); DeleteDC(new_gc); } else { - fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id_, cx, cy); + fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)pxm->id_, cx, cy); } -#elif defined(__APPLE_QUARTZ__) - fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id_, cx, cy); -#else -# error unsupported platform -#endif } +#else // Xlib +void Fl_Xlib_Device::draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) { + int X, Y, W, H; + if (pxm->w() < 0) pxm->measure(); + int code = start(pxm, XP, YP, WP, HP, pxm->w(), pxm->h(), cx, cy, X, Y, W, H); + if (code) { + if (code == 2) pxm->draw_empty(XP, YP); + return; + } + if (!pxm->id_) { + pxm->id_ = fl_create_offscreen(pxm->w(), pxm->h()); + fl_begin_offscreen((Fl_Offscreen)pxm->id_); + uchar *bitmap = 0; + fl_mask_bitmap = &bitmap; + fl_draw_pixmap(pxm->data(), 0, 0, FL_BLACK); + fl_mask_bitmap = 0; + if (bitmap) { + pxm->mask_ = fl_create_bitmask(pxm->w(), pxm->h(), bitmap); + delete[] bitmap; + } + fl_end_offscreen(); + } + if (pxm->mask_) { + // I can't figure out how to combine a mask with existing region, + // so cut the image down to a clipped rectangle: + int nx, ny; fl_clip_box(X,Y,W,H,nx,ny,W,H); + cx += nx-X; X = nx; + cy += ny-Y; Y = ny; + // make X use the bitmap as a mask: + XSetClipMask(fl_display, fl_gc, pxm->mask_); + int ox = X-cx; if (ox < 0) ox += pxm->w(); + int oy = Y-cy; if (oy < 0) oy += pxm->h(); + XSetClipOrigin(fl_display, fl_gc, X-cx, Y-cy); + } + fl_copy_offscreen(X, Y, W, H, pxm->id_, cx, cy); + if (pxm->mask_) { + // put the old clip region back + XSetClipOrigin(fl_display, fl_gc, 0, 0); + fl_restore_clip(); + } +} + +#endif + /** The destructor free all memory and server resources that are used by the pixmap. diff --git a/src/Fl_Printer.cxx b/src/Fl_Printer.cxx index d6e8425b3..6072c8515 100644 --- a/src/Fl_Printer.cxx +++ b/src/Fl_Printer.cxx @@ -58,6 +58,20 @@ const char *Fl_Printer::property_use = "Use"; const char *Fl_Printer::property_save = "Save"; const char *Fl_Printer::property_cancel = "Cancel"; +const char *Fl_Printer::device_type = "Fl_Printer"; + +Fl_Device *Fl_Printer::set_current(void) +{ +#ifdef __APPLE__ + fl_gc = (CGContextRef)gc; +#elif defined(WIN32) + fl_gc = (HDC)gc; +#else + fl_gc = (_XGC*)gc; +#endif + return this->Fl_Device::set_current(); +} + // // End of "$Id$". // diff --git a/src/Fl_Quartz_Printer.mm b/src/Fl_Quartz_Printer.mm index 874686d3a..3d1fc4877 100644 --- a/src/Fl_Quartz_Printer.mm +++ b/src/Fl_Quartz_Printer.mm @@ -40,7 +40,7 @@ Fl_Printer::Fl_Printer(void) x_offset = 0; y_offset = 0; scale_x = scale_y = 1.; - type_ = quartz_printer; + type_ = device_type; } Fl_Printer::~Fl_Printer(void) {} diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm index 6a9654f75..2efbe55cc 100644 --- a/src/Fl_cocoa.mm +++ b/src/Fl_cocoa.mm @@ -131,9 +131,9 @@ static void createAppleMenu(void); static Fl_Region MacRegionMinusRect(Fl_Region r, int x,int y,int w,int h); static void cocoaMouseHandler(NSEvent *theEvent); -static Fl_Quartz_Display fl_quartz_device; -FL_EXPORT Fl_Display *fl_display_device = (Fl_Display*)&fl_quartz_device; // does not change -FL_EXPORT Fl_Device *fl_device = (Fl_Device*)&fl_quartz_device; // the current target device of graphics operations +static Fl_Display_Device fl_quartz_display; +FL_EXPORT Fl_Display_Device *fl_display_device = (Fl_Display_Device*)&fl_quartz_display; // does not change +FL_EXPORT Fl_Device *fl_device = (Fl_Device*)&fl_quartz_display; // the current target device of graphics operations // public variables int fl_screen; @@ -2100,7 +2100,7 @@ void Fl_X::make(Fl_Window* w) winstyle |= NSResizableWindowMask; } } else { - if (w->resizable()) { + if (w->resizable()) { Fl_Widget *o = w->resizable(); int minw = o->w(); if (minw > 100) minw = 100; int minh = o->h(); if (minh > 100) minh = 100; @@ -2121,8 +2121,7 @@ void Fl_X::make(Fl_Window* w) winstyle = NSBorderlessWindowMask; } } else if (w->modal()) { - winstyle &= ~NSMiniaturizableWindowMask; - // winstyle &= ~(NSResizableWindowMask | NSMiniaturizableWindowMask); + winstyle &= ~(NSResizableWindowMask | NSMiniaturizableWindowMask); // winlevel = NSModalPanelWindowLevel; } else if (w->non_modal()) { @@ -2999,6 +2998,7 @@ int MACscreen_init(XRectangle screens[]) printer.end_page(); printer.end_job(); } + @end static NSMenu *appleMenu; @@ -3028,7 +3028,7 @@ static void createAppleMenu(void) [appleMenu setAutoenablesItems:NO]; [menuItem setEnabled:YES]; [appleMenu addItem:[NSMenuItem separatorItem]]; -// end of temporary for testing Fl_Printer + // end of temporary for testing Fl_Printer // Services Menu services = [[NSMenu alloc] init]; [appleMenu addItemWithTitle:@"Services" action:nil keyEquivalent:@""]; @@ -3475,7 +3475,7 @@ WindowRef MACwindowRef(Fl_Window *w) // so a CGRect matches exactly what is denoted x,y,w,h for clipping purposes CGRect fl_cgrectmake_cocoa(int x, int y, int w, int h) { - if (Fl_Device::current()->type() == Fl_Device::quartz_printer) return CGRectMake(x, y, w-1.5 , h-1.5 ); + if ( Fl_Device::current()->type() == Fl_Printer::device_type ) return CGRectMake(x, y, w-1.5 , h-1.5 ); return CGRectMake(x, y, w > 0 ? w - 0.9 : 0, h > 0 ? h - 0.9 : 0); } diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx index f26d639db..bcc07715c 100644 --- a/src/Fl_win32.cxx +++ b/src/Fl_win32.cxx @@ -95,9 +95,9 @@ for async mode proper operation, not mentioning the side effects... */ -static Fl_GDI_Display fl_gdi_device; -FL_EXPORT Fl_Display *fl_display_device = (Fl_Display*)&fl_gdi_device; // does not change -FL_EXPORT Fl_Device *fl_device = (Fl_Device*)&fl_gdi_device; // the current target device of graphics operations +static Fl_Display_Device fl_gdi_display; +FL_EXPORT Fl_Display_Device *fl_display_device = (Fl_Display_Device*)&fl_gdi_display; // does not change +FL_EXPORT Fl_Device *fl_device = (Fl_Device*)&fl_gdi_display; // the current target device of graphics operations // dynamic wsock dll handling api: #if defined(__CYGWIN__) && !defined(SOCKET) @@ -1925,7 +1925,7 @@ void fl_cleanup_dc_list(void) { // clean up the list } Fl_Region XRectangleRegion(int x, int y, int w, int h) { - if (Fl_Device::current()->type() < 256) return CreateRectRgn(x,y,x+w,y+h); + if (Fl_Device::current()->type() == Fl_Display_Device::device_type) return CreateRectRgn(x,y,x+w,y+h); // because rotation may apply, the rectangle becomes a polygon in device coords POINT pt[4] = { {x, y}, {x + w, y}, {x + w, y + h}, {x, y + h} }; LPtoDP(fl_gc, pt, 4); diff --git a/src/Fl_x.cxx b/src/Fl_x.cxx index 1c81503f8..f80c11096 100644 --- a/src/Fl_x.cxx +++ b/src/Fl_x.cxx @@ -51,9 +51,9 @@ # include <X11/Xlocale.h> # include <X11/Xlib.h> -static Fl_Xlib_Display fl_xlib_device; -FL_EXPORT Fl_Display *fl_display_device = (Fl_Display*)&fl_xlib_device; // does not change -FL_EXPORT Fl_Device *fl_device = (Fl_Device*)&fl_xlib_device; // the current target device of graphics operations +static Fl_Display_Device fl_xlib_display; +FL_EXPORT Fl_Display_Device *fl_display_device = (Fl_Display_Device*)&fl_xlib_display; // does not change +FL_EXPORT Fl_Device *fl_device = (Fl_Device*)&fl_xlib_display; // the current target device of graphics operations //////////////////////////////////////////////////////////////// // interface to poll/select call: @@ -136,9 +136,7 @@ void Fl::add_fd(int n, void (*cb)(int, void*), void* v) { void Fl::remove_fd(int n, int events) { int i,j; -# if !USE_POLL maxfd = -1; // recalculate maxfd on the fly -# endif for (i=j=0; i<nfds; i++) { # if USE_POLL if (pollfds[i].fd == n) { @@ -152,8 +150,8 @@ void Fl::remove_fd(int n, int events) { if (!e) continue; // if no events left, delete this fd fd[i].events = e; } - if (fd[i].fd > maxfd) maxfd = fd[i].fd; # endif + if (fd[i].fd > maxfd) maxfd = fd[i].fd; // move it down in the array if necessary: if (j<i) { fd[j] = fd[i]; @@ -1588,13 +1586,6 @@ void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap) XFree(hints); } - // set the window type for menu and tooltip windows to avoid animations (compiz) - if (win->menu_window() || win->tooltip_window()) { - Atom net_wm_type = XInternAtom(fl_display, "_NET_WM_WINDOW_TYPE", False); - Atom net_wm_type_kind = XInternAtom(fl_display, "_NET_WM_WINDOW_TYPE_MENU", False); - int ret = XChangeProperty(fl_display, xp->xid, net_wm_type, XA_ATOM, 32, PropModeReplace, (unsigned char*)&net_wm_type_kind, 1); - } - XMapWindow(fl_display, xp->xid); if (showit) { win->set_visible(); diff --git a/src/fl_draw_image_win32.cxx b/src/fl_draw_image_win32.cxx index 403dfd9fe..fd7ee64ea 100644 --- a/src/fl_draw_image_win32.cxx +++ b/src/fl_draw_image_win32.cxx @@ -46,6 +46,7 @@ #include <config.h> #include <FL/Fl.H> +#include <FL/Fl_Printer.H> #include <FL/fl_draw.H> #include <FL/x.H> @@ -254,7 +255,7 @@ static void innards(const uchar *buf, int X, int Y, int W, int H, } } } - if(Fl_Device::current()->type() == Fl_Device::gdi_printer) { + if(Fl_Device::current()->type() == Fl_Printer::device_type) { // if print context, device and logical units are not equal, so SetDIBitsToDevice // does not do the expected job, whereas StretchDIBits does it. StretchDIBits(fl_gc, x, y+j-k, w, k, 0, 0, w, k, diff --git a/src/fl_font_win32.cxx b/src/fl_font_win32.cxx index fd0e3fdbf..23521a678 100644 --- a/src/fl_font_win32.cxx +++ b/src/fl_font_win32.cxx @@ -24,6 +24,9 @@ // // http://www.fltk.org/str.php // + +#include <FL/Fl_Printer.H> + static int fl_angle_ = 0; #ifndef FL_DOXYGEN @@ -247,7 +250,7 @@ static void on_printer_extents_update(int &dx, int &dy, int &w, int &h) // if printer context, extents shd be converted to logical coords #define EXTENTS_UPDATE(x,y,w,h) \ - if (Fl_Device::current()->type() == Fl_Device::gdi_printer) { on_printer_extents_update(x,y,w,h); } + if (Fl_Device::current()->type() == Fl_Printer::device_type) { on_printer_extents_update(x,y,w,h); } static unsigned short *ext_buff = NULL; // UTF-16 converted version of input UTF-8 string static unsigned wc_len = 0; // current string buffer dimension diff --git a/src/fl_line_style.cxx b/src/fl_line_style.cxx index e93f159ec..1dbea0a91 100644 --- a/src/fl_line_style.cxx +++ b/src/fl_line_style.cxx @@ -33,8 +33,10 @@ #include <FL/Fl.H> #include <FL/fl_draw.H> #include <FL/x.H> +#include <FL/Fl_Printer.H> #include "flstring.h" #include <stdio.h> +#include <FL/fl_ask.H>//TMP #ifdef __APPLE_QUARTZ__ float fl_quartz_line_width_ = 1.0f; @@ -117,7 +119,9 @@ void Fl_Device::line_style(int style, int width, char* dashes) { fl_quartz_line_width_ = (float)width; fl_quartz_line_cap_ = Cap[(style>>8)&3]; // when printing kCGLineCapSquare seems better for solid lines - if (Fl_Device::current()->type() == quartz_printer && style == FL_SOLID) fl_quartz_line_cap_ = kCGLineCapSquare; + if ( Fl_Device::current()->type() == Fl_Printer::device_type && style == FL_SOLID && dashes == NULL ) { + fl_quartz_line_cap_ = kCGLineCapSquare; + } fl_quartz_line_join_ = Join[(style>>12)&3]; char *d = dashes; static CGFloat pattern[16]; diff --git a/src/fl_rect.cxx b/src/fl_rect.cxx index df8cbef9a..c9bdf6c47 100644 --- a/src/fl_rect.cxx +++ b/src/fl_rect.cxx @@ -38,12 +38,13 @@ #include <config.h> #include <FL/Fl.H> #include <FL/Fl_Widget.H> +#include <FL/Fl_Printer.H> #include <FL/fl_draw.H> #include <FL/x.H> #ifdef __APPLE_QUARTZ__ extern float fl_quartz_line_width_; -#define USINGQUARTZPRINTER (Fl_Device::current()->type() == quartz_printer) +#define USINGQUARTZPRINTER (Fl_Device::current()->type() == Fl_Printer::device_type) #endif void Fl_Device::rect(int x, int y, int w, int h) { @@ -510,7 +511,7 @@ int Fl_Device::not_clipped(int x, int y, int w, int h) { #elif defined(WIN32) if (!r) return 1; RECT rect; - if (Fl_Device::current()->type() == Fl_Device::gdi_printer) { // in case of print context, convert coords from logical to device + if (Fl_Device::current()->type() == Fl_Printer::device_type) { // in case of print context, convert coords from logical to device POINT pt[2] = { {x, y}, {x + w, y + h} }; LPtoDP(fl_gc, pt, 2); rect.left = pt[0].x; rect.top = pt[0].y; rect.right = pt[1].x; rect.bottom = pt[1].y; @@ -572,7 +573,7 @@ int Fl_Device::clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& } else { // partial intersection RECT rect; GetRgnBox(temp, &rect); - if(Fl_Device::current()->type() == Fl_Device::gdi_printer) { // if print context, convert coords from device to logical + if(Fl_Device::current()->type() == Fl_Printer::device_type) { // if print context, convert coords from device to logical POINT pt[2] = { {rect.left, rect.top}, {rect.right, rect.bottom} }; DPtoLP(fl_gc, pt, 2); X = pt[0].x; Y = pt[0].y; W = pt[1].x - X; H = pt[1].y - Y; diff --git a/src/ps_image.cxx b/src/ps_image.cxx index 61534238c..65e967755 100644 --- a/src/ps_image.cxx +++ b/src/ps_image.cxx @@ -34,7 +34,7 @@ #include <FL/Fl_Pixmap.H> #include <FL/Fl_Bitmap.H> -int Fl_PSfile_Device::alpha_mask(const uchar * data, int w, int h, int D, int LD){ +int Fl_PS_Device::alpha_mask(const uchar * data, int w, int h, int D, int LD){ mask = 0; if((D/2)*2 != D){ //no mask info @@ -182,18 +182,27 @@ int Fl_PSfile_Device::alpha_mask(const uchar * data, int w, int h, int D, int LD return 0; } -// bitwise inversion of all 4-bit quantities -static const unsigned char swapped[16] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15}; -// bitwise inversion of a byte -static inline uchar swap_byte(const uchar b){ - return (swapped[b & 0xF] << 4) | swapped[b >> 4]; - } + +// TODO: anybody has more efficient algoritm? +static inline uchar swap_byte(const uchar i){ + uchar b =0; + if(i & 1) b |= 128; + if(i & 2) b |= 64; + if(i & 4) b |= 32; + if(i & 8) b |= 16; + if(i & 16) b |= 8; + if(i & 32) b |= 4; + if(i & 64) b |= 2; + if(i & 128) b |= 1; + return b; +} + extern uchar **fl_mask_bitmap; -void Fl_PSfile_Device::draw_scaled_image(const uchar *data, double x, double y, double w, double h, int iw, int ih, int D, int LD) { +void Fl_PS_Device::draw_scaled_image(const uchar *data, double x, double y, double w, double h, int iw, int ih, int D, int LD) { if(D<3){ //mono @@ -260,7 +269,7 @@ void Fl_PSfile_Device::draw_scaled_image(const uchar *data, double x, double y, }; -void Fl_PSfile_Device::draw_scaled_image(Fl_Draw_Image_Cb call, void *data, double x, double y, double w, double h, int iw, int ih, int D) { +void Fl_PS_Device::draw_scaled_image(Fl_Draw_Image_Cb call, void *data, double x, double y, double w, double h, int iw, int ih, int D) { int level2_mask = 0; fprintf(output,"save\n"); @@ -348,7 +357,7 @@ void Fl_PSfile_Device::draw_scaled_image(Fl_Draw_Image_Cb call, void *data, doub delete[] rgbdata; } -void Fl_PSfile_Device::draw_scaled_image_mono(const uchar *data, double x, double y, double w, double h, int iw, int ih, int D, int LD) { +void Fl_PS_Device::draw_scaled_image_mono(const uchar *data, double x, double y, double w, double h, int iw, int ih, int D, int LD) { fprintf(output,"save\n"); @@ -409,7 +418,7 @@ void Fl_PSfile_Device::draw_scaled_image_mono(const uchar *data, double x, doubl -void Fl_PSfile_Device::draw_scaled_image_mono(Fl_Draw_Image_Cb call, void *data, double x, double y, double w, double h, int iw, int ih, int D) { +void Fl_PS_Device::draw_scaled_image_mono(Fl_Draw_Image_Cb call, void *data, double x, double y, double w, double h, int iw, int ih, int D) { fprintf(output,"save\n"); int i,j,k; @@ -458,7 +467,7 @@ void Fl_PSfile_Device::draw_scaled_image_mono(Fl_Draw_Image_Cb call, void *data, ////////////////////////////// Image classes ////////////////////// -void Fl_PSfile_Device::draw(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, int cy){ +void Fl_PS_Device::draw(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, int cy){ const char * const * di =pxm->data(); int w,h; if (!fl_measure_pixmap(di, w, h)) return; @@ -474,7 +483,7 @@ void Fl_PSfile_Device::draw(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int fl_mask_bitmap=0; }; -void Fl_PSfile_Device::draw(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy){ +void Fl_PS_Device::draw(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy){ const uchar * di = rgb->array; int w = rgb->w(); int h = rgb->h(); @@ -488,7 +497,7 @@ void Fl_PSfile_Device::draw(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, i mask=0; }; -void Fl_PSfile_Device::draw(Fl_Bitmap * bitmap,int XP, int YP, int WP, int HP, int cx, int cy){ +void Fl_PS_Device::draw(Fl_Bitmap * bitmap,int XP, int YP, int WP, int HP, int cx, int cy){ const uchar * di = bitmap->array; int w,h; int LD=(bitmap->w()+7)/8; |
