summaryrefslogtreecommitdiff
path: root/src/drivers/GDI
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/GDI
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/GDI')
-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
3 files changed, 113 insertions, 73 deletions
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);