summaryrefslogtreecommitdiff
path: root/src/Fl_Pixmap.cxx
diff options
context:
space:
mode:
authorManolo Gouy <Manolo>2010-04-16 20:19:09 +0000
committerManolo Gouy <Manolo>2010-04-16 20:19:09 +0000
commit913530758af63f00676c6746988aef8b35b02531 (patch)
treed6b59be15047e3c2742158eb5063aca55ea94eba /src/Fl_Pixmap.cxx
parent0f180e130639f1017e7ca6b668357304632c1a62 (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/Fl_Pixmap.cxx')
-rw-r--r--src/Fl_Pixmap.cxx167
1 files changed, 104 insertions, 63 deletions
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.