summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorManolo Gouy <Manolo>2018-04-12 13:07:00 +0000
committerManolo Gouy <Manolo>2018-04-12 13:07:00 +0000
commit16705ef734cd00e114e422e2cb4a5c84ad49c09f (patch)
tree11ee243812b0fce99549d7a41b8a4a91f1efa568 /src/drivers
parentefc3ec1b7b54718be4d2f5145342484607b5059e (diff)
Image drawing: simplify the code organisation to better support Fl_Image::scale().
Graphics drivers now use up to 6 virtual member functions to support Fl_Image drawing in the context of GUI and image rescaling : virtual void draw_pixmap(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) virtual void draw_bitmap(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) virtual void draw_rgb(Fl_RGB_Image *rgb, int XP, int YP, int WP, int HP, int cx, int cy) and 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) git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12828 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/Android/Fl_Android_Graphics_Driver.H22
-rw-r--r--src/drivers/Android/Fl_Android_Graphics_Driver.cxx120
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver.H15
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx2
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx169
-rw-r--r--src/drivers/Pico/Fl_Pico_Graphics_Driver.H1
-rw-r--r--src/drivers/PicoAndroid/Fl_PicoAndroid_Graphics_Driver.H1
-rw-r--r--src/drivers/PicoSDL/Fl_PicoSDL_Graphics_Driver.H1
-rw-r--r--src/drivers/PostScript/Fl_PostScript_image.cxx8
-rw-r--r--src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H7
-rw-r--r--src/drivers/Quartz/Fl_Quartz_Graphics_Driver_image.cxx64
-rw-r--r--src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H10
-rw-r--r--src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx118
13 files changed, 275 insertions, 263 deletions
diff --git a/src/drivers/Android/Fl_Android_Graphics_Driver.H b/src/drivers/Android/Fl_Android_Graphics_Driver.H
index a8c7ddfd7..046735c1c 100644
--- a/src/drivers/Android/Fl_Android_Graphics_Driver.H
+++ b/src/drivers/Android/Fl_Android_Graphics_Driver.H
@@ -54,6 +54,9 @@ protected:
// - methods marked with // super: use the implemnetation of the super class
// - virtual ... override functions are implemented for Android
private:
+ virtual void draw_fixed(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy) override;
+ virtual void draw_fixed(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, int cy) override;
+ virtual void draw_fixed(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) override;
// some platforms may need to reimplement this
// This is called from the surface device, see: end_current_()
// super: virtual void set_current_();
@@ -67,6 +70,7 @@ protected:
virtual fl_uintptr_t cache(Fl_Pixmap *img) override;
/** Support function for Fl_Bitmap drawing */
virtual fl_uintptr_t cache(Fl_Bitmap *img) override;
+ virtual fl_uintptr_t cache(Fl_RGB_Image *img) override;
/** Support function for Fl_RGB_Image drawing */
virtual void uncache(Fl_RGB_Image *img, fl_uintptr_t &id_, fl_uintptr_t &mask_) override;
// --- implementation is in src/drivers/xxx/Fl_xxx_Graphics_Driver_image.cxx
@@ -78,20 +82,6 @@ protected:
virtual void draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3) override;
/** see fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D) */
virtual void draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=1) override;
- /** \brief Draws an Fl_RGB_Image object using this graphics driver. */
- virtual void draw(Fl_RGB_Image * rgb,int XP, int YP, int WP, int HP, int cx, int cy) override;
- /** \brief Draws an Fl_Pixmap object using this graphics driver.
- *
- Specifies a bounding box for the image, with the origin (upper left-hand corner) of
- the image offset by the cx and cy arguments.
- */
- virtual void draw(Fl_Pixmap * pxm,int XP, int YP, int WP, int HP, int cx, int cy) override;
- /** \brief Draws an Fl_Bitmap object using this graphics driver.
- *
- Specifies a bounding box for the image, with the origin (upper left-hand corner) of
- the image offset by the cx and cy arguments.
- */
- virtual void draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) override;
#if 0
virtual void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy);
@@ -282,9 +272,6 @@ public:
virtual const char *font_name(int num) override;
/** Support for Fl::set_font() */
virtual void font_name(int num, const char *name) override;
- // Draws an Fl_Image scaled to width W & height H
- // TODO: we don't seem to need this until we introduce a scaling graphis driver
- // super: virtual int draw_scaled(Fl_Image *img, int X, int Y, int W, int H);
/** Support function for fl_overlay_rect() and scaled GUI.
Defaut implementation may be enough */
// super: virtual bool overlay_rect_unscaled();
@@ -358,7 +345,6 @@ public:
virtual int has_feature(driver_feature mask) { return mask & (NATIVE | PRINTER); }
void draw_unscaled(Fl_Pixmap *pxm, float s, int XP, int YP, int WP, int HP, int cx, int cy);
void draw_unscaled(Fl_Bitmap *bm, float s, int XP, int YP, int WP, int HP, int cx, int cy);
- int draw_scaled(Fl_Image *img, int XP, int YP, int WP, int HP);
#endif
diff --git a/src/drivers/Android/Fl_Android_Graphics_Driver.cxx b/src/drivers/Android/Fl_Android_Graphics_Driver.cxx
index d4cd77951..05af4bed6 100644
--- a/src/drivers/Android/Fl_Android_Graphics_Driver.cxx
+++ b/src/drivers/Android/Fl_Android_Graphics_Driver.cxx
@@ -962,31 +962,23 @@ void Fl_Android_Graphics_Driver::circle(double x, double y, double r)
}
-void Fl_Android_Graphics_Driver::draw(Fl_Pixmap * pxm, int XP, int YP, int WP, int HP, int cx, int cy)
+void Fl_Android_Graphics_Driver::draw_fixed(Fl_Pixmap * pxm, int X, int Y, int W, int H, int cx, int cy)
{
- int X, Y, W, H;
- if (Fl_Graphics_Driver::prepare(pxm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
- return;
- }
if (*Fl_Graphics_Driver::id(pxm)) {
Fl_Android_565A_Map *cache = (Fl_Android_565A_Map*)*Fl_Graphics_Driver::id(pxm);
for (const auto &it: pClippingRegion.overlapping(Fl_Rect_Region(X, Y, W, H))) {
- draw(XP, YP, cache, it->clipped_rect());
+ draw(X-cx, Y-cy, cache, it->clipped_rect());
}
}
}
-void Fl_Android_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy)
+void Fl_Android_Graphics_Driver::draw_fixed(Fl_Bitmap *bm, int X, int Y, int W, int H, int cx, int cy)
{
- int X, Y, W, H;
- if (Fl_Graphics_Driver::prepare(bm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
- return;
- }
if (*Fl_Graphics_Driver::id(bm)) {
Fl_Android_Bytemap *cache = (Fl_Android_Bytemap*)*Fl_Graphics_Driver::id(bm);
for (const auto &it: pClippingRegion.overlapping(Fl_Rect_Region(X, Y, W, H))) {
- draw(XP, YP, cache, it->clipped_rect());
+ draw(X-cx, Y-cy, cache, it->clipped_rect());
}
}
}
@@ -1050,68 +1042,65 @@ void Fl_Android_Graphics_Driver::uncache_pixmap(fl_uintptr_t p)
delete img;
}
-
-void Fl_Android_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy)
+fl_uintptr_t Fl_Android_Graphics_Driver::cache(Fl_RGB_Image *img)
{
- int X, Y, W, H;
- // Don't draw an empty image...
- if (!img->d() || !img->array) {
- Fl_Graphics_Driver::draw_empty(img, XP, YP);
- return;
- }
- if (start_image(img, XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
- return;
- }
- Fl_Android_565A_Map *cgimg = (Fl_Android_565A_Map*)*Fl_Graphics_Driver::id(img);
- if (!cgimg) {
- int w = img->w(), h = img->h(), d = img->d(), stride = w*d + img->ld();
- cgimg = new Fl_Android_565A_Map(w, h);
- *Fl_Graphics_Driver::id(img) = (fl_uintptr_t)cgimg;
- if (d==1) { // grayscale
- for (int iy=0; iy<h; iy++) {
- const uchar *src = img->array + iy*stride;
- uint32_t *dst = cgimg->pWords + iy*cgimg->pStride;
- for (int ix=0; ix<w; ix++) {
- uchar l = *src++;
- uint32_t rgba = Fl_Android_565A_Map::toRGBA(l, l, l, 255);
- *dst++ = rgba;
- }
+ int w = img->data_w(), h = img->data_h(), d = img->d(), stride = w*d + img->ld();
+ Fl_Android_565A_Map *cgimg = new Fl_Android_565A_Map(w, h);
+ *Fl_Graphics_Driver::id(img) = (fl_uintptr_t)cgimg;
+ int *pw, *ph;
+ cache_w_h(img, pw, ph);
+ *pw = img->data_w();
+ *ph = img->data_h();
+ if (d==1) { // grayscale
+ for (int iy=0; iy<h; iy++) {
+ const uchar *src = img->array + iy*stride;
+ uint32_t *dst = cgimg->pWords + iy*cgimg->pStride;
+ for (int ix=0; ix<w; ix++) {
+ uchar l = *src++;
+ uint32_t rgba = Fl_Android_565A_Map::toRGBA(l, l, l, 255);
+ *dst++ = rgba;
}
- } else if (d==2) { // gray + alpha
- for (int iy=0; iy<h; iy++) {
- const uchar *src = img->array + iy*stride;
- uint32_t *dst = cgimg->pWords + iy*cgimg->pStride;
- for (int ix=0; ix<w; ix++) {
- uchar l = *src++, a = *src++;
- uint32_t rgba = Fl_Android_565A_Map::toRGBA(l, l, l, a);
- *dst++ = rgba;
- }
+ }
+ } else if (d==2) { // gray + alpha
+ for (int iy=0; iy<h; iy++) {
+ const uchar *src = img->array + iy*stride;
+ uint32_t *dst = cgimg->pWords + iy*cgimg->pStride;
+ for (int ix=0; ix<w; ix++) {
+ uchar l = *src++, a = *src++;
+ uint32_t rgba = Fl_Android_565A_Map::toRGBA(l, l, l, a);
+ *dst++ = rgba;
}
- } else if (d==3) { // rgb
- for (int iy=0; iy<h; iy++) {
- const uchar *src = img->array + iy*stride;
- uint32_t *dst = cgimg->pWords + iy*cgimg->pStride;
- for (int ix=0; ix<w; ix++) {
- uchar r = *src++, g = *src++, b = *src++;
- uint32_t rgba = Fl_Android_565A_Map::toRGBA(r, g, b, 255);
- *dst++ = rgba;
- }
+ }
+ } else if (d==3) { // rgb
+ for (int iy=0; iy<h; iy++) {
+ const uchar *src = img->array + iy*stride;
+ uint32_t *dst = cgimg->pWords + iy*cgimg->pStride;
+ for (int ix=0; ix<w; ix++) {
+ uchar r = *src++, g = *src++, b = *src++;
+ uint32_t rgba = Fl_Android_565A_Map::toRGBA(r, g, b, 255);
+ *dst++ = rgba;
}
- } else if (d==4) { // rgb + alpha
- for (int iy=0; iy<h; iy++) {
- const uchar *src = img->array + iy*stride;
- uint32_t *dst = cgimg->pWords + iy*cgimg->pStride;
- for (int ix=0; ix<w; ix++) {
- uchar r = *src++, g = *src++, b = *src++, a = *src++;
- uint32_t rgba = Fl_Android_565A_Map::toRGBA(r, g, b, a);
- *dst++ = rgba;
- }
+ }
+ } else if (d==4) { // rgb + alpha
+ for (int iy=0; iy<h; iy++) {
+ const uchar *src = img->array + iy*stride;
+ uint32_t *dst = cgimg->pWords + iy*cgimg->pStride;
+ for (int ix=0; ix<w; ix++) {
+ uchar r = *src++, g = *src++, b = *src++, a = *src++;
+ uint32_t rgba = Fl_Android_565A_Map::toRGBA(r, g, b, a);
+ *dst++ = rgba;
}
}
}
+ return (fl_uintptr_t)cgimg;
+}
+
+void Fl_Android_Graphics_Driver::draw_fixed(Fl_RGB_Image *img, int X, int Y, int W, int H, int cx, int cy)
+{
+ Fl_Android_565A_Map *cgimg = (Fl_Android_565A_Map*)*Fl_Graphics_Driver::id(img);
if (cgimg) {
for (const auto &it: pClippingRegion.overlapping(Fl_Rect_Region(X, Y, W, H))) {
- draw(XP, YP, cgimg, it->clipped_rect());
+ draw(X-cx, Y-cy, cgimg, it->clipped_rect());
}
}
}
@@ -1232,6 +1221,7 @@ void Fl_Android_Graphics_Driver::uncache(Fl_RGB_Image*, fl_uintptr_t &id_, fl_ui
{
Fl_Android_565A_Map *cgimg = (Fl_Android_565A_Map*)id_;
delete cgimg;
+ id_ = 0;
}
diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver.H b/src/drivers/GDI/Fl_GDI_Graphics_Driver.H
index f6554a076..eae3b7925 100644
--- a/src/drivers/GDI/Fl_GDI_Graphics_Driver.H
+++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver.H
@@ -40,7 +40,11 @@ private:
int depth; // to support translation
POINT *origins; // to support translation
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);
protected:
+ void draw_fixed(Fl_RGB_Image *rgb, int XP, int YP, int WP, int HP, int cx, int cy);
+ fl_uintptr_t cache(Fl_RGB_Image *rgb);
HDC gc_;
int numcount;
int counts[20];
@@ -64,10 +68,7 @@ public:
virtual void draw_unscaled(int angle, const char *str, int n, int x, int y);
virtual void rtl_draw_unscaled(const char* str, int n, int x, int y);
virtual void font_unscaled(Fl_Font face, Fl_Fontsize size);
- void draw_unscaled(Fl_Pixmap *pxm, float s, int XP, int YP, int WP, int HP, int cx, int cy);
- void draw_unscaled(Fl_Bitmap *pxm, float s, int XP, int YP, int WP, int HP, int cx, int cy);
- void draw_unscaled(Fl_RGB_Image *img, float s, int XP, int YP, int WP, int HP, int cx, int cy);
- int draw_scaled(Fl_Image *img, int XP, int YP, int WP, int HP);
+ virtual void draw_rgb(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy);
virtual void draw_image_unscaled(const uchar* buf, int X,int Y,int W,int H, int D=3, int L=0);
virtual void draw_image_unscaled(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3);
virtual void draw_image_mono_unscaled(const uchar* buf, int X,int Y,int W,int H, int D=1, int L=0);
@@ -163,9 +164,9 @@ private:
transparent_f_type TransparentBlt();
public:
virtual int has_feature(driver_feature mask) { return mask & (NATIVE | PRINTER); }
- void draw_unscaled(Fl_Pixmap *pxm, float s, int XP, int YP, int WP, int HP, int cx, int cy);
- void draw_unscaled(Fl_Bitmap *bm, float s, int XP, int YP, int WP, int HP, int cx, int cy);
- int draw_scaled(Fl_Image *img, int XP, int YP, int WP, int HP);
+ void draw_pixmap(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
+ void draw_bitmap(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy);
+ void draw_rgb(Fl_RGB_Image *rgb, int XP, int YP, int WP, int HP, int cx, int cy);
};
diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx
index acc58c860..a07e97313 100644
--- a/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx
+++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx
@@ -125,7 +125,7 @@ void Fl_GDI_Graphics_Driver::copy_offscreen_with_alpha(int x,int y,int w,int h,H
SelectObject(new_gc, bitmap);
BOOL alpha_ok = 0;
// first try to alpha blend
- if ( can_do_alpha_blending() ) {
+ if ( fl_can_do_alpha_blending() ) {
alpha_ok = alpha_blend_(x, y, w, h, new_gc, srcx, srcy, w, h);
}
// if that failed (it shouldn't), still copy the bitmap over, but now alpha is 1
diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx
index 6b9cb6d87..af919cf5e 100644
--- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx
+++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx
@@ -400,15 +400,11 @@ void Fl_GDI_Graphics_Driver::delete_bitmask(Fl_Bitmask bm) {
DeleteObject((HGDIOBJ)bm);
}
-void Fl_GDI_Graphics_Driver::draw_unscaled(Fl_Bitmap *bm, float s, int XP, int YP, int WP, int HP, int cx, int cy) {
- int X, Y, W, H;
- if (Fl_Graphics_Driver::prepare(bm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
- return;
- }
- X = X*s;
- Y = Y*s;
+void Fl_GDI_Graphics_Driver::draw_fixed(Fl_Bitmap *bm, int X, int Y, int W, int H, int cx, int cy) {
+ X = X*scale_;
+ Y = Y*scale_;
cache_size(bm, W, H);
- cx *= s; cy *= s;
+ cx *= scale_; cy *= scale_;
HDC tempdc = CreateCompatibleDC(gc_);
int save = SaveDC(tempdc);
@@ -428,17 +424,26 @@ Fl_GDI_Printer_Graphics_Driver::transparent_f_type Fl_GDI_Printer_Graphics_Drive
return fpter;
}
-void Fl_GDI_Printer_Graphics_Driver::draw_unscaled(Fl_Bitmap *bm, float s, int XP, int YP, int WP, int HP, int cx, int cy) {
+void Fl_GDI_Printer_Graphics_Driver::draw_bitmap(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
int X, Y, W, H;
+ if (Fl_Graphics_Driver::start_image(bm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
+ return;
+ }
transparent_f_type fl_TransparentBlt = TransparentBlt();
if (!fl_TransparentBlt) {
- Fl_GDI_Graphics_Driver::draw(bm, XP, YP, WP, HP, cx, cy);
+ Fl_Graphics_Driver::draw_bitmap(bm, X, Y, W, H, cx, cy);
return;
}
- if (Fl_Graphics_Driver::prepare(bm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
- return;
+ bool recache = false;
+ if (*id(bm)) {
+ int *pw, *ph;
+ cache_w_h(bm, pw, ph);
+ recache = (*pw != bm->data_w() || *ph != bm->data_h());
+ }
+ if (recache || !*id(bm)) {
+ bm->uncache();
+ *Fl_Graphics_Driver::id(bm) = cache(bm);
}
-
HDC tempdc;
int save;
// algorithm for bitmap output to Fl_GDI_Printer
@@ -449,28 +454,31 @@ void Fl_GDI_Printer_Graphics_Driver::draw_unscaled(Fl_Bitmap *bm, float s, int X
g = 255-g;
b = 255-b;
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);
- fl_begin_offscreen(tmp_id);
+ Fl_Image_Surface *img_surf = new Fl_Image_Surface(bm->data_w(), bm->data_h());
+ Fl_Surface_Device::push_current(img_surf);
fl_color(background);
- fl_rectf(0,0,W,H); // use this color as offscreen background
+ fl_rectf(0,0, bm->data_w(), bm->data_h()); // use this color as offscreen background
fl_color(save_c); // back to bitmap's color
HDC off_gc = (HDC)fl_graphics_driver->gc();
tempdc = CreateCompatibleDC(off_gc);
save = SaveDC(tempdc);
SelectObject(tempdc, (HGDIOBJ)*Fl_Graphics_Driver::id(bm));
SelectObject(off_gc, fl_brush()); // use bitmap's desired color
- BitBlt(off_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
+ BitBlt(off_gc, 0, 0, bm->data_w(), bm->data_h(), tempdc, 0, 0, 0xE20746L); // draw bitmap to offscreen
+ Fl_Surface_Device::pop_current();
+ SelectObject(tempdc, (HGDIOBJ)img_surf->offscreen()); // use offscreen data
// draw it to printer context with background color as transparent
- fl_TransparentBlt(gc_, X,Y,W,H, tempdc, cx, cy, bm->data_w(), bm->data_h(), RGB(r, g, b) );
- fl_delete_offscreen(tmp_id);
+ float scaleW = bm->data_w()/float(bm->w());
+ float scaleH = bm->data_h()/float(bm->h());
+ fl_TransparentBlt(gc_, X, Y, W, H, tempdc, cx * scaleW, cy * scaleH, W * scaleW, H * scaleH, RGB(r, g, b) );
+ delete img_surf;
RestoreDC(tempdc, save);
DeleteDC(tempdc);
-}
+ if (recache) bm->uncache();
+}
-static Fl_Offscreen build_id(Fl_RGB_Image *img, void **pmask)
+fl_uintptr_t Fl_GDI_Graphics_Driver::cache(Fl_RGB_Image *img)
{
Fl_Image_Surface *surface = new Fl_Image_Surface(img->data_w(), img->data_h());
Fl_Surface_Device::push_current(surface);
@@ -479,31 +487,35 @@ static Fl_Offscreen build_id(Fl_RGB_Image *img, void **pmask)
} else {
fl_draw_image(img->array, 0, 0, img->data_w(), img->data_h(), img->d(), img->ld());
if (img->d() == 2 || img->d() == 4) {
- *pmask = fl_create_alphamask(img->data_w(), img->data_h(), img->d(), img->ld(), img->array);
+ *Fl_Graphics_Driver::mask(img) = (fl_uintptr_t)fl_create_alphamask(img->data_w(), img->data_h(), img->d(), img->ld(), img->array);
}
}
Fl_Surface_Device::pop_current();
Fl_Offscreen offs = surface->get_offscreen_before_delete();
delete surface;
- return offs;
+ int *pw, *ph;
+ cache_w_h(img, pw, ph);
+ *pw = img->data_w();
+ *ph = img->data_h();
+ *Fl_Graphics_Driver::id(img) = (fl_uintptr_t)offs;
+ return (fl_uintptr_t)offs;
}
-void Fl_GDI_Graphics_Driver::draw_unscaled(Fl_RGB_Image *img, float s, int X, int Y, int W, int H, int cx, int cy) {
- X = X*s;
- Y = Y*s;
+void Fl_GDI_Graphics_Driver::draw_fixed(Fl_RGB_Image *img, int X, int Y, int W, int H, int cx, int cy) {
+ X = X*scale_;
+ Y = Y*scale_;
cache_size(img, W, H);
- cx *= s; cy *= s;
+ cx *= scale_; cy *= scale_;
if (W + cx > img->data_w()) W = img->data_w() - cx;
if (H + cy > img->data_h()) H = img->data_h() - cy;
if (!*Fl_Graphics_Driver::id(img)) {
- *Fl_Graphics_Driver::id(img) = (fl_uintptr_t)build_id(img, (void**)(Fl_Graphics_Driver::mask(img)));
+ *Fl_Graphics_Driver::id(img) = (fl_uintptr_t)cache(img);
int *pw, *ph;
cache_w_h(img, pw, ph);
*pw = img->data_w();
*ph = img->data_h();
}
- Fl_Region r2 = scale_clip(s);
if (*Fl_Graphics_Driver::mask(img)) {
HDC new_gc = CreateCompatibleDC(gc_);
int save = SaveDC(new_gc);
@@ -518,52 +530,65 @@ void Fl_GDI_Graphics_Driver::draw_unscaled(Fl_RGB_Image *img, float s, int X, in
} else {
copy_offscreen(X, Y, W, H, (Fl_Offscreen)*Fl_Graphics_Driver::id(img), cx, cy);
}
- unscale_clip(r2);
-}
-
-int Fl_GDI_Printer_Graphics_Driver::draw_scaled(Fl_Image *img, int XP, int YP, int WP, int HP) {
- XFORM old_tr, tr;
- GetWorldTransform(gc_, &old_tr); // storing old transform
- tr.eM11 = float(WP)/float(img->data_w());
- tr.eM22 = float(HP)/float(img->data_h());
- tr.eM12 = tr.eM21 = 0;
- tr.eDx = float(XP);
- tr.eDy = float(YP);
- ModifyWorldTransform(gc_, &tr, MWT_LEFTMULTIPLY);
- img->draw(0, 0, img->data_w(), img->data_h(), 0, 0);
- SetWorldTransform(gc_, &old_tr);
- return 1;
}
-int Fl_GDI_Graphics_Driver::draw_scaled(Fl_Image *img, int XP, int YP, int WP, int HP) {
- Fl_RGB_Image *rgb = img->as_rgb_image();
- if (!rgb || !rgb->array) return 0; // for bitmaps and pixmaps
- if ((rgb->d() % 2) == 0 && !can_do_alpha_blending()) return 0;
-
+void Fl_GDI_Graphics_Driver::draw_rgb(Fl_RGB_Image *rgb, int XP, int YP, int WP, int HP, int cx, int cy) {
+ if (Fl_Graphics_Driver::start_image(rgb, XP, YP, WP, HP, cx, cy, XP, YP, WP, HP)) {
+ return;
+ }
+ if ((rgb->d() % 2) == 0 && !fl_can_do_alpha_blending()) {
+ Fl_Graphics_Driver::draw_rgb(rgb, XP, YP, WP, HP, cx, cy);
+ return;
+ }
if (!*Fl_Graphics_Driver::id(rgb)) {
- *Fl_Graphics_Driver::id(rgb) = (fl_uintptr_t)build_id(rgb,
- (void**)(Fl_Graphics_Driver::mask(rgb)));
+ *Fl_Graphics_Driver::id(rgb) = (fl_uintptr_t)cache(rgb);
int *pw, *ph;
cache_w_h(rgb, pw, ph);
*pw = rgb->data_w();
*ph = rgb->data_h();
}
- cache_size(img, WP, HP);
+ float scaleW = float(rgb->data_w())/rgb->w();
+ float scaleH = float(rgb->data_h())/rgb->h();
+ int W = WP, H = HP;
+ cache_size(rgb, W, H);
HDC new_gc = CreateCompatibleDC(gc_);
int save = SaveDC(new_gc);
SelectObject(new_gc, (HBITMAP)*Fl_Graphics_Driver::id(rgb));
if ( (rgb->d() % 2) == 0 ) {
- alpha_blend_(XP*scale_, YP*scale_, WP, HP, new_gc, 0, 0, rgb->data_w(), rgb->data_h());
+ alpha_blend_(XP*scale_, YP*scale_, W, H, new_gc, cx*scaleW, cy*scaleH, WP*scaleW, HP*scaleH);
} else {
SetStretchBltMode(gc_, HALFTONE);
- StretchBlt(gc_, XP*scale_, YP*scale_, WP, HP, new_gc, 0, 0, rgb->data_w(), rgb->data_h(), SRCCOPY);
+ StretchBlt(gc_, XP*scale_, YP*scale_, W, H, new_gc, cx*scaleW, cy*scaleH, WP*scaleW, HP*scaleH, SRCCOPY);
}
RestoreDC(new_gc, save);
DeleteDC(new_gc);
- return 1;
}
+
+void Fl_GDI_Printer_Graphics_Driver::draw_rgb(Fl_RGB_Image *rgb, int XP, int YP, int WP, int HP, int cx, int cy) {
+ if (Fl_Graphics_Driver::start_image(rgb, XP, YP, WP, HP, cx, cy, XP, YP, WP, HP)) {
+ return;
+ }
+ XFORM old_tr, tr;
+ GetWorldTransform(gc_, &old_tr); // storing old transform
+ tr.eM11 = float(rgb->w())/float(rgb->data_w());
+ tr.eM22 = float(rgb->h())/float(rgb->data_h());
+ tr.eM12 = tr.eM21 = 0;
+ tr.eDx = float(XP);
+ tr.eDy = float(YP);
+ ModifyWorldTransform(gc_, &tr, MWT_LEFTMULTIPLY);
+ if (*id(rgb)) {
+ int *pw, *ph;
+ cache_w_h(rgb, pw, ph);
+ if ( *pw != rgb->data_w() || *ph != rgb->data_h()) rgb->uncache();
+ }
+ if (!*id(rgb)) cache(rgb);
+ draw_fixed(rgb, 0, 0, WP/tr.eM11, HP/tr.eM22, cx/tr.eM11, cy/tr.eM22);
+ SetWorldTransform(gc_, &old_tr);
+}
+
+
void Fl_GDI_Graphics_Driver::uncache(Fl_RGB_Image*, fl_uintptr_t &id_, fl_uintptr_t &mask_)
{
if (id_) {
@@ -613,12 +638,12 @@ fl_uintptr_t Fl_GDI_Graphics_Driver::cache(Fl_Bitmap *bm) {
return (fl_uintptr_t)fl_create_bitmap(bm->data_w(), bm->data_h(), bm->array);
}
-void Fl_GDI_Graphics_Driver::draw_unscaled(Fl_Pixmap *pxm, float s, int X, int Y, int W, int H, int cx, int cy) {
- X = X*s;
- Y = Y*s;
+void Fl_GDI_Graphics_Driver::draw_fixed(Fl_Pixmap *pxm, int X, int Y, int W, int H, int cx, int cy) {
+ X = X*scale_;
+ Y = Y*scale_;
cache_size(pxm, W, H);
- cx *= s; cy *= s;
- Fl_Region r2 = scale_clip(s);
+ cx *= scale_; cy *= scale_;
+ Fl_Region r2 = scale_clip(scale_);
if (*Fl_Graphics_Driver::mask(pxm)) {
HDC new_gc = CreateCompatibleDC(gc_);
int save = SaveDC(new_gc);
@@ -635,18 +660,32 @@ void Fl_GDI_Graphics_Driver::draw_unscaled(Fl_Pixmap *pxm, float s, int X, int Y
}
-void Fl_GDI_Printer_Graphics_Driver::draw_unscaled(Fl_Pixmap *pxm, float s, int XP, int YP, int WP, int HP, int cx, int cy) {
+void Fl_GDI_Printer_Graphics_Driver::draw_pixmap(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) {
int X, Y, W, H;
- if (Fl_Graphics_Driver::prepare(pxm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) return;
+ 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();
+ *Fl_Graphics_Driver::id(pxm) = cache(pxm);
+ }
HDC new_gc = CreateCompatibleDC(gc_);
int save = SaveDC(new_gc);
SelectObject(new_gc, (void*)*Fl_Graphics_Driver::id(pxm));
// print all of offscreen but its parts in background color
- fl_TransparentBlt(gc_, X, Y, W, H, new_gc, cx, cy, W, H, *Fl_Graphics_Driver::pixmap_bg_color(pxm) );
+ 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) );
RestoreDC(new_gc,save);
DeleteDC(new_gc);
+ if (recache) pxm->uncache();
}
else {
copy_offscreen(X, Y, W, H, (Fl_Offscreen)*Fl_Graphics_Driver::id(pxm), cx, cy);
diff --git a/src/drivers/Pico/Fl_Pico_Graphics_Driver.H b/src/drivers/Pico/Fl_Pico_Graphics_Driver.H
index b7cca4529..bfc55c630 100644
--- a/src/drivers/Pico/Fl_Pico_Graphics_Driver.H
+++ b/src/drivers/Pico/Fl_Pico_Graphics_Driver.H
@@ -195,7 +195,6 @@ class Fl_Pico_Graphics_Driver : public Fl_Graphics_Driver {
// the image offset by the cx and cy arguments.
// */
// virtual void draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {}
-// virtual int draw_scaled(Fl_Image *img, int X, int Y, int W, int H);
// virtual void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy);
//
// /** Sets the value of the driver-specific graphics context. */
diff --git a/src/drivers/PicoAndroid/Fl_PicoAndroid_Graphics_Driver.H b/src/drivers/PicoAndroid/Fl_PicoAndroid_Graphics_Driver.H
index 05cc6cc9b..e7708dc11 100644
--- a/src/drivers/PicoAndroid/Fl_PicoAndroid_Graphics_Driver.H
+++ b/src/drivers/PicoAndroid/Fl_PicoAndroid_Graphics_Driver.H
@@ -49,7 +49,6 @@ public:
// void draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
// void draw(Fl_Bitmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
// void draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy);
- // int draw_scaled(Fl_Image *img, int XP, int YP, int WP, int HP);
// void draw_image(const uchar* buf, int X,int Y,int W,int H, int D=3, int L=0);
// void draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3);
// void draw_image_mono(const uchar* buf, int X,int Y,int W,int H, int D=1, int L=0);
diff --git a/src/drivers/PicoSDL/Fl_PicoSDL_Graphics_Driver.H b/src/drivers/PicoSDL/Fl_PicoSDL_Graphics_Driver.H
index d0bb20ff5..fd1a696a5 100644
--- a/src/drivers/PicoSDL/Fl_PicoSDL_Graphics_Driver.H
+++ b/src/drivers/PicoSDL/Fl_PicoSDL_Graphics_Driver.H
@@ -48,7 +48,6 @@ public:
// void draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
// void draw(Fl_Bitmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
// void draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy);
- // int draw_scaled(Fl_Image *img, int XP, int YP, int WP, int HP);
// void draw_image(const uchar* buf, int X,int Y,int W,int H, int D=3, int L=0);
// void draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3);
// void draw_image_mono(const uchar* buf, int X,int Y,int W,int H, int D=1, int L=0);
diff --git a/src/drivers/PostScript/Fl_PostScript_image.cxx b/src/drivers/PostScript/Fl_PostScript_image.cxx
index cc91f24da..4b7c26744 100644
--- a/src/drivers/PostScript/Fl_PostScript_image.cxx
+++ b/src/drivers/PostScript/Fl_PostScript_image.cxx
@@ -575,7 +575,7 @@ void Fl_PostScript_Graphics_Driver::draw(Fl_Pixmap * pxm,int XP, int YP, int WP,
int need_clip = cx || cy || WP != pxm->w() || HP != pxm->h();
if (need_clip) push_clip(XP, YP, WP, HP);
if (pxm->w() != pxm->data_w() || pxm->h() != pxm->data_h()) {
- draw_scaled(pxm, XP-cx, YP-cy, pxm->w(), pxm->h());
+ scale_and_draw(pxm, XP-cx, YP-cy, pxm->w(), pxm->h());
} else {
const char * const * di =pxm->data();
int w,h;
@@ -597,7 +597,7 @@ void Fl_PostScript_Graphics_Driver::draw(Fl_RGB_Image * rgb,int XP, int YP, int
int need_clip = cx || cy || WP != rgb->w() || HP != rgb->h();
if (need_clip) push_clip(XP, YP, WP, HP);
if (rgb->w() != rgb->data_w() || rgb->h() != rgb->data_h()) {
- draw_scaled(rgb, XP-cx, YP-cy, rgb->w(), rgb->h());
+ scale_and_draw(rgb, XP-cx, YP-cy, rgb->w(), rgb->h());
} else {
const uchar * di = rgb->array;
int w = rgb->w();
@@ -612,7 +612,7 @@ void Fl_PostScript_Graphics_Driver::draw(Fl_RGB_Image * rgb,int XP, int YP, int
if (need_clip) pop_clip();
}
-int Fl_PostScript_Graphics_Driver::draw_scaled(Fl_Image *img, int XP, int YP, int WP, int HP){
+int Fl_PostScript_Graphics_Driver::scale_and_draw(Fl_Image *img, int XP, int YP, int WP, int HP){
int X, Y, W, H;
clip_box(XP,YP,WP,HP,X,Y,W,H); // X,Y,W,H will give the unclipped area of XP,YP,WP,HP
if (W == 0 || H == 0) return 1;
@@ -632,7 +632,7 @@ void Fl_PostScript_Graphics_Driver::draw(Fl_Bitmap * bitmap,int XP, int YP, int
int need_clip = cx || cy || WP != bitmap->w() || HP != bitmap->h();
if (need_clip) push_clip(XP, YP, WP, HP);
if (bitmap->w() != bitmap->data_w() || bitmap->h() != bitmap->data_h()) {
- draw_scaled(bitmap, XP-cx, YP-cy, bitmap->w(), bitmap->h());
+ scale_and_draw(bitmap, XP-cx, YP-cy, bitmap->w(), bitmap->h());
} else {
const uchar * di = bitmap->array;
int w,h;
diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H
index 6aa8f9ef9..97389d15a 100644
--- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H
+++ b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H
@@ -67,15 +67,16 @@ public:
// --- bitmap stuff
Fl_Bitmask create_bitmask(int w, int h, const uchar *array);
void delete_bitmask(Fl_Bitmask bm);
- void draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
- void draw(Fl_Bitmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
- void draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy);
+ void draw_pixmap(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
+ void draw_bitmap(Fl_Bitmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
+ void draw_rgb(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy);
void draw_image(const uchar* buf, int X,int Y,int W,int H, int D=3, int L=0);
void draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3);
void draw_image_mono(const uchar* buf, int X,int Y,int W,int H, int D=1, int L=0);
void draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=1);
fl_uintptr_t cache(Fl_Pixmap *img);
fl_uintptr_t cache(Fl_Bitmap *img);
+ fl_uintptr_t cache(Fl_RGB_Image *img);
void uncache(Fl_RGB_Image *img, fl_uintptr_t &id_, fl_uintptr_t &mask_);
void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy);
void draw_CGImage(CGImageRef cgimg, int x, int y, int w, int h, int srcx, int srcy, int sw, int sh);
diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_image.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_image.cxx
index db00f7935..2d8c1074f 100644
--- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_image.cxx
+++ b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_image.cxx
@@ -132,7 +132,7 @@ void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) {
fl_rectf(x,y,w,h);
}
-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_bitmap(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
int X, Y, W, H;
if (Fl_Graphics_Driver::prepare(bm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
return;
@@ -142,8 +142,38 @@ void Fl_Quartz_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int
}
}
+fl_uintptr_t Fl_Quartz_Graphics_Driver::cache(Fl_RGB_Image *rgb) {
+ CGColorSpaceRef lut = rgb->d()<=2 ? CGColorSpaceCreateDeviceGray() : CGColorSpaceCreateDeviceRGB();
+ int ld = rgb->ld();
+ if (!ld) ld = rgb->data_w() * rgb->d();
+ CGDataProviderRef src;
+ if ( has_feature(PRINTER) ) {
+ // When printing, the data at rgb->array are used when the printed page is completed,
+ // that is, after return from this function.
+ // At that stage, the rgb object has possibly been deleted. It is therefore necessary
+ // to use a copy of rgb->array for printing. The mask_ member of rgb
+ // is used to avoid repeating the copy operation if rgb is printed again.
+ // The CGImage data provider deletes the copy at the latest of these two events:
+ // deletion of rgb, and completion of the page where rgb was printed.
+ size_t total = ld * rgb->data_h();
+ uchar *copy = new uchar[total];
+ memcpy(copy, rgb->array, total);
+ src = CGDataProviderCreateWithData(NULL, copy, total, dataReleaseCB);
+ *Fl_Graphics_Driver::mask(rgb) = 1;
+ } else {
+ // the CGImage data provider must not release the image data.
+ src = CGDataProviderCreateWithData(NULL, rgb->array, ld * rgb->data_h(), NULL);
+ }
+ CGImageRef cgimg = CGImageCreate(rgb->data_w(), rgb->data_h(), 8, rgb->d()*8, ld,
+ lut, (rgb->d()&1)?kCGImageAlphaNone:kCGImageAlphaLast,
+ src, 0L, false, kCGRenderingIntentDefault);
+ *Fl_Graphics_Driver::id(rgb) = (fl_uintptr_t)cgimg;
+ CGColorSpaceRelease(lut);
+ CGDataProviderRelease(src);
+ return (fl_uintptr_t)cgimg;
+}
-void Fl_Quartz_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy) {
+void Fl_Quartz_Graphics_Driver::draw_rgb(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) {
@@ -160,40 +190,14 @@ void Fl_Quartz_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP,
cgimg = NULL;
}
if (!cgimg) {
- CGColorSpaceRef lut = img->d()<=2 ? CGColorSpaceCreateDeviceGray() : CGColorSpaceCreateDeviceRGB();
- int ld = img->ld();
- if (!ld) ld = img->data_w() * img->d();
- CGDataProviderRef src;
- if ( has_feature(PRINTER) ) {
- // When printing, the data at img->array are used when the printed page is completed,
- // that is, after return from this function.
- // At that stage, the img object has possibly been deleted. It is therefore necessary
- // to use a copy of img->array for printing. The mask_ member of img
- // is used to avoid repeating the copy operation if img is printed again.
- // The CGImage data provider deletes the copy at the latest of these two events:
- // deletion of img, and completion of the page where img was printed.
- size_t total = ld * img->data_h();
- uchar *copy = new uchar[total];
- memcpy(copy, img->array, total);
- src = CGDataProviderCreateWithData(NULL, copy, total, dataReleaseCB);
- *Fl_Graphics_Driver::mask(img) = 1;
- } else {
- // the CGImage data provider must not release the image data.
- src = CGDataProviderCreateWithData(NULL, img->array, ld * img->data_h(), NULL);
- }
- cgimg = CGImageCreate(img->data_w(), img->data_h(), 8, img->d()*8, ld,
- lut, (img->d()&1)?kCGImageAlphaNone:kCGImageAlphaLast,
- src, 0L, false, kCGRenderingIntentDefault);
- *Fl_Graphics_Driver::id(img) = (fl_uintptr_t)cgimg;
- CGColorSpaceRelease(lut);
- CGDataProviderRelease(src);
+ cgimg = (CGImageRef)cache(img);
}
if (cgimg && gc_) {
draw_CGImage(cgimg, X,Y,W,H, cx,cy, img->w(), img->h());
}
}
-void Fl_Quartz_Graphics_Driver::draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) {
+void Fl_Quartz_Graphics_Driver::draw_pixmap(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) {
int X, Y, W, H;
if (Fl_Graphics_Driver::prepare(pxm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) return;
CGImageRef cgimg = (CGImageRef)*Fl_Graphics_Driver::id(pxm);
diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H
index 785c76369..7d56cad61 100644
--- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H
+++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H
@@ -62,16 +62,16 @@ private:
int line_delta_;
virtual void set_current_();
int clip_max_; // +/- x/y coordinate limit (16-bit coordinate space)
+ 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 *pxm, 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);
protected:
- virtual void draw_unscaled(Fl_Pixmap *pxm, float s, int XP, int YP, int WP, int HP, int cx, int cy);
- virtual void draw_unscaled(Fl_Bitmap *pxm, float s, int XP, int YP, int WP, int HP, int cx, int cy);
- virtual void draw_unscaled(Fl_RGB_Image *img, float s, int XP, int YP, int WP, int HP, int cx, int cy);
+ virtual void draw_rgb(Fl_RGB_Image *rgb, int XP, int YP, int WP, int HP, int cx, int cy);
virtual void draw_image_unscaled(const uchar* buf, int X,int Y,int W,int H, int D=3, int L=0);
virtual void draw_image_unscaled(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3);
virtual void draw_image_mono_unscaled(const uchar* buf, int X,int Y,int W,int H, int D=1, int L=0);
virtual void draw_image_mono_unscaled(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=1);
#if HAVE_XRENDER
- virtual int draw_scaled(Fl_Image *img, int XP, int YP, int WP, int HP);
int scale_and_render_pixmap(Fl_Offscreen pixmap, int depth, double scale_x, double scale_y, int srcx, int srcy, int XP, int YP, int WP, int HP);
#endif
virtual int height_unscaled();
@@ -101,7 +101,7 @@ protected:
static Window draw_window;
static struct _XftDraw* draw_;
#endif
- Fl_Offscreen cache_rgb(Fl_RGB_Image *img);
+ fl_uintptr_t cache(Fl_RGB_Image *img);
public:
Fl_Xlib_Graphics_Driver(void);
virtual ~Fl_Xlib_Graphics_Driver();
diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx
index c271dae53..b9271e3b5 100644
--- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx
+++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx
@@ -624,14 +624,14 @@ void Fl_Xlib_Graphics_Driver::delete_bitmask(Fl_Bitmask bm) {
XFreePixmap(fl_display, bm);
}
-void Fl_Xlib_Graphics_Driver::draw_unscaled(Fl_Bitmap *bm, float s, int X, int Y, int W, int H, int cx, int cy) {
- X = (X+offset_x_)*s;
- Y = (Y+offset_y_)*s;
+void Fl_Xlib_Graphics_Driver::draw_fixed(Fl_Bitmap *bm, int X, int Y, int W, int H, int cx, int cy) {
+ X = (X+offset_x_)*scale_;
+ Y = (Y+offset_y_)*scale_;
cache_size(bm, W, H);
- cx *= s; cy *= s;
+ cx *= scale_; cy *= scale_;
XSetStipple(fl_display, gc_, *Fl_Graphics_Driver::id(bm));
- int ox = X-cx; if (ox < 0) ox += bm->w()*s;
- int oy = Y-cy; if (oy < 0) oy += bm->h()*s;
+ int ox = X-cx; if (ox < 0) ox += bm->w()*scale_;
+ int oy = Y-cy; if (oy < 0) oy += bm->h()*scale_;
XSetTSOrigin(fl_display, gc_, ox, oy);
XSetFillStyle(fl_display, gc_, FillStippled);
XFillRectangle(fl_display, fl_window, gc_, X, Y, W, H);
@@ -696,7 +696,7 @@ static void alpha_blend(Fl_RGB_Image *img, int X, int Y, int W, int H, int cx, i
delete[] dst;
}
-Fl_Offscreen Fl_Xlib_Graphics_Driver::cache_rgb(Fl_RGB_Image *img) {
+fl_uintptr_t Fl_Xlib_Graphics_Driver::cache(Fl_RGB_Image *img) {
Fl_Image_Surface *surface;
int depth = img->d();
if (depth == 1 || depth == 3) {
@@ -717,48 +717,53 @@ Fl_Offscreen Fl_Xlib_Graphics_Driver::cache_rgb(Fl_RGB_Image *img) {
cache_w_h(img, pw, ph);
*pw = img->data_w();
*ph = img->data_h();
- return off;
+ *Fl_Graphics_Driver::id(img) = (fl_uintptr_t)off;
+ return (fl_uintptr_t)off;
}
-// X,Y,W,H,cx,cy are in FLTK units
-// if s != 1 and id(img) != 0, the offscreen has been previously scaled by s
-// if s != 1 and id(img) == 0, img has been previously scaled by s
-void Fl_Xlib_Graphics_Driver::draw_unscaled(Fl_RGB_Image *img, float s, int X, int Y, int W, int H, int cx, int cy) {
- X = (X+offset_x_)*s;
- Y = (Y+offset_y_)*s;
+
+void Fl_Xlib_Graphics_Driver::draw_fixed(Fl_RGB_Image *img, int X, int Y, int W, int H, int cx, int cy) {
+ X = (X+offset_x_)*scale_;
+ Y = (Y+offset_y_)*scale_;
cache_size(img, W, H);
- cx *= s; cy *= s;
- if (W + cx > img->data_w()) W = img->data_w() - cx;
- if (H + cy > img->data_h()) H = img->data_h() - cy;
- if (!*Fl_Graphics_Driver::id(img)) {
- *Fl_Graphics_Driver::id(img) = cache_rgb(img);
- }
- Fl_Region r2 = scale_clip(s);
- if (*Fl_Graphics_Driver::id(img)) {
- if (img->d() == 4 || img->d() == 2) {
-#if HAVE_XRENDER
- scale_ = 1;
- scale_and_render_pixmap(*Fl_Graphics_Driver::id(img), img->d(), 1, 1, cx, cy, X, Y, W, H);
- scale_ = s;
-#endif
- } else {
- XCopyArea(fl_display, *Fl_Graphics_Driver::id(img), fl_window, gc_, cx, cy, W, H, X, Y);
- }
- } else {
- // Composite image with alpha manually each time...
- scale_ = 1;
- int ox = offset_x_, oy = offset_y_;
- offset_x_ = offset_y_ = 0;
- Fl_X11_Screen_Driver *d = (Fl_X11_Screen_Driver*)Fl::screen_driver();
- int nscreen = Fl_Window::current()->driver()->screen_num();
- float keep = d->scale(nscreen);
- d->scale(nscreen, 1);
- alpha_blend(img, X, Y, W, H, cx, cy);
- d->scale(nscreen, keep);
- scale_ = s;
- offset_x_ = ox; offset_y_ = oy;
+ cx *= scale_; cy *= scale_;
+ if (img->d() == 1 || img->d() == 3) {
+ XCopyArea(fl_display, *Fl_Graphics_Driver::id(img), fl_window, gc_, cx, cy, W, H, X, Y);
+ return;
}
- unscale_clip(r2);
+ // Composite image with alpha manually each time...
+ float s = scale_;
+ scale_ = 1;
+ int ox = offset_x_, oy = offset_y_;
+ offset_x_ = offset_y_ = 0;
+ Fl_X11_Screen_Driver *d = (Fl_X11_Screen_Driver*)Fl::screen_driver();
+ int nscreen = Fl_Window::current()->driver()->screen_num();
+ float keep = d->scale(nscreen);
+ d->scale(nscreen, 1);
+ push_no_clip();
+ alpha_blend(img, X, Y, W, H, cx, cy);
+ pop_clip();
+ d->scale(nscreen, keep);
+ scale_ = s;
+ offset_x_ = ox; offset_y_ = oy;
+}
+
+void Fl_Xlib_Graphics_Driver::draw_rgb(Fl_RGB_Image *rgb, int XP, int YP, int WP, int HP, int cx, int cy) {
+ if (!fl_can_do_alpha_blending()) {
+ Fl_Graphics_Driver::draw_rgb(rgb, XP, YP, WP, HP, cx, cy);
+ return;
+ }
+ int X, Y, W, H;
+ if (Fl_Graphics_Driver::start_image(rgb, XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
+ return;
+ }
+ if (!*Fl_Graphics_Driver::id(rgb)) {
+ *Fl_Graphics_Driver::id(rgb) = cache(rgb);
+ }
+ cache_size(rgb, W, H);
+ scale_and_render_pixmap( *Fl_Graphics_Driver::id(rgb), rgb->d(),
+ rgb->data_w() / double(rgb->w()*scale_), rgb->data_h() / double(rgb->h()*scale_),
+ cx*scale_, cy*scale_, (X + offset_x_)*scale_, (Y + offset_y_)*scale_, W, H);
}
void Fl_Xlib_Graphics_Driver::uncache(Fl_RGB_Image*, fl_uintptr_t &id_, fl_uintptr_t &mask_)
@@ -777,12 +782,12 @@ fl_uintptr_t Fl_Xlib_Graphics_Driver::cache(Fl_Bitmap *bm) {
return (fl_uintptr_t)create_bitmask(bm->data_w(), bm->data_h(), bm->array);
}
-void Fl_Xlib_Graphics_Driver::draw_unscaled(Fl_Pixmap *pxm, float s, int X, int Y, int W, int H, int cx, int cy) {
- X = (X+offset_x_)*s;
- Y = (Y+offset_y_)*s;
+void Fl_Xlib_Graphics_Driver::draw_fixed(Fl_Pixmap *pxm, int X, int Y, int W, int H, int cx, int cy) {
+ X = (X+offset_x_)*scale_;
+ Y = (Y+offset_y_)*scale_;
cache_size(pxm, W, H);
- cx *= s; cy *= s;
- Fl_Region r2 = scale_clip(s);
+ cx *= scale_; cy *= scale_;
+ Fl_Region r2 = scale_clip(scale_);
if (*Fl_Graphics_Driver::mask(pxm)) {
// make X use the bitmap as a mask:
XSetClipMask(fl_display, gc_, *Fl_Graphics_Driver::mask(pxm));
@@ -813,7 +818,7 @@ void Fl_Xlib_Graphics_Driver::draw_unscaled(Fl_Pixmap *pxm, float s, int X, int
}
// put the old clip region back
XSetClipOrigin(fl_display, gc_, 0, 0);
- s = scale_; scale_ = 1;
+ float s = scale_; scale_ = 1;
restore_clip();
scale_ = s;
}
@@ -884,17 +889,6 @@ int Fl_Xlib_Graphics_Driver::scale_and_render_pixmap(Fl_Offscreen pixmap, int de
return 1;
}
-// XP,YP,WP,HP are in FLTK units
-int Fl_Xlib_Graphics_Driver::draw_scaled(Fl_Image *img, int XP, int YP, int WP, int HP) {
- Fl_RGB_Image *rgb = img->as_rgb_image();
- if (!rgb || !can_do_alpha_blending()) return 0;
- if (!*Fl_Graphics_Driver::id(rgb)) {
- *Fl_Graphics_Driver::id(rgb) = cache_rgb(rgb);
- }
- cache_size(img, WP, HP);
- return scale_and_render_pixmap( *Fl_Graphics_Driver::id(rgb), rgb->d(),
- rgb->data_w() / double(WP), rgb->data_h() / double(HP), 0, 0, (XP + offset_x_)*scale_, (YP + offset_y_)*scale_, WP, HP);
-}
#endif // HAVE_XRENDER