summaryrefslogtreecommitdiff
path: root/src/drivers/GDI
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers/GDI')
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver.H86
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx43
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx4
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver_font.cxx38
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx74
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver_line_style.cxx2
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx36
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver_vertex.cxx22
-rw-r--r--src/drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx7
9 files changed, 183 insertions, 129 deletions
diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver.H b/src/drivers/GDI/Fl_GDI_Graphics_Driver.H
index 71a99b9b0..140e6acea 100644
--- a/src/drivers/GDI/Fl_GDI_Graphics_Driver.H
+++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver.H
@@ -34,7 +34,7 @@
*
This class is implemented only on the MSWindows platform.
*/
-class FL_EXPORT Fl_GDI_Graphics_Driver : public Fl_Graphics_Driver {
+class FL_EXPORT Fl_GDI_Graphics_Driver : public Fl_Scalable_Graphics_Driver {
private:
BOOL alpha_blend_(int x, int y, int w, int h, HDC src_gc, int srcx, int srcy, int srcw, int srch);
int depth; // to support translation
@@ -59,55 +59,58 @@ public:
// --- bitmap stuff
Fl_Bitmask create_bitmask(int w, int h, const uchar *array);
void delete_bitmask(Fl_Bitmask bm);
- void draw(const char* str, int n, int x, int y);
- void draw(int angle, const char *str, int n, int x, int y);
- void rtl_draw(const char* str, int n, int x, int y);
- void font(Fl_Font face, Fl_Fontsize size);
- 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);
+ virtual void draw_unscaled(const char* str, int n, int x, int y);
+ 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);
- 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);
+ 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);
fl_uintptr_t cache(Fl_Pixmap *img, int w, int h, const char *const*array);
fl_uintptr_t cache(Fl_Bitmap *img, int w, int h, const uchar *array);
void uncache(Fl_RGB_Image *img, fl_uintptr_t &id_, fl_uintptr_t &mask_);
- double width(const char *str, int n);
- double width(unsigned int c);
- void text_extents(const char*, int n, int& dx, int& dy, int& w, int& h);
- int height();
- int descent();
+ virtual double width_unscaled(const char *str, int n);
+ virtual double width_unscaled(unsigned int c);
+ void text_extents_unscaled(const char*, int n, int& dx, int& dy, int& w, int& h);
+ int height_unscaled();
+ int descent_unscaled();
+ Fl_Fontsize size_unscaled();
#if ! defined(FL_DOXYGEN)
void copy_offscreen_with_alpha(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy);
#endif
- void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy);
+ virtual void copy_offscreen_unscaled(float x, float y, float w, float h, Fl_Offscreen pixmap, float srcx, float srcy);
void add_rectangle_to_region(Fl_Region r, int x, int y, int w, int h);
Fl_Region XRectangleRegion(int x, int y, int w, int h);
void XDestroyRegion(Fl_Region r);
void translate_all(int x, int y);
void untranslate_all(void);
+ static HRGN scale_region(HRGN r, float f, bool keep, bool inflate=false);
+ virtual void scale(float f);
protected:
- void transformed_vertex0(int x, int y);
+ void transformed_vertex0(float x, float y);
void fixloop();
// --- implementation is in src/fl_rect.cxx which includes src/cfg_gfx/gdi_rect.cxx
- void point(int x, int y);
- void rect(int x, int y, int w, int h);
+ virtual void point_unscaled(float x, float y);
+ void rect_unscaled(float x, float y, float w, float h);
void focus_rect(int x, int y, int w, int h);
- void rectf(int x, int y, int w, int h);
- void line(int x, int y, int x1, int y1);
- void line(int x, int y, int x1, int y1, int x2, int y2);
- void xyline(int x, int y, int x1);
- void xyline(int x, int y, int x1, int y2);
- void xyline(int x, int y, int x1, int y2, int x3);
- void yxline(int x, int y, int y1);
- void yxline(int x, int y, int y1, int x2);
- void yxline(int x, int y, int y1, int x2, int y3);
- void loop(int x0, int y0, int x1, int y1, int x2, int y2);
- void loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3);
- void polygon(int x0, int y0, int x1, int y1, int x2, int y2);
- void polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3);
+ void rectf_unscaled(float x, float y, float w, float h);
+ virtual void line_unscaled(float x, float y, float x1, float y1);
+ virtual void line_unscaled(float x, float y, float x1, float y1, float x2, float y2);
+ virtual void xyline_unscaled(float x, float y, float x1);
+ virtual void xyline_unscaled(float x, float y, float x1, float y2);
+ virtual void xyline_unscaled(float x, float y, float x1, float y2, float x3);
+ virtual void yxline_unscaled(float x, float y, float y1);
+ virtual void yxline_unscaled(float x, float y, float y1, float x2);
+ virtual void yxline_unscaled(float x, float y, float y1, float x2, float y3);
+ virtual void loop_unscaled(float x0, float y0, float x1, float y1, float x2, float y2);
+ virtual void loop_unscaled(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3);
+ virtual void polygon_unscaled(float x0, float y0, float x1, float y1, float x2, float y2);
+ virtual void polygon_unscaled(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3);
// --- clipping
void push_clip(int x, int y, int w, int h);
int clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H);
@@ -115,24 +118,23 @@ protected:
void push_no_clip();
void pop_clip();
void restore_clip();
+ virtual Fl_Region scale_clip(float f);
// --- implementation is in src/fl_vertex.cxx which includes src/cfg_gfx/xxx_rect.cxx
void begin_complex_polygon();
- void transformed_vertex(double xf, double yf);
- void vertex(double x, double y);
void end_points();
void end_line();
void end_loop();
void end_polygon();
void end_complex_polygon();
void gap();
- void circle(double x, double y, double r);
+ virtual void ellipse_unscaled(double xt, double yt, double rx, double ry);
// --- implementation is in src/fl_arc.cxx which includes src/cfg_gfx/xxx_arc.cxx if needed
// using void Fl_Graphics_Driver::arc(double x, double y, double r, double start, double end);
// --- implementation is in src/fl_arci.cxx which includes src/cfg_gfx/xxx_arci.cxx
- void arc(int x, int y, int w, int h, double a1, double a2);
- void pie(int x, int y, int w, int h, double a1, double a2);
+ virtual void arc_unscaled(float x, float y, float w, float h, double a1, double a2);
+ virtual void pie_unscaled(float x, float y, float w, float h, double a1, double a2);
// --- implementation is in src/fl_line_style.cxx which includes src/cfg_gfx/xxx_line_style.cxx
- void line_style(int style, int width=0, char* dashes=0);
+ virtual void line_style_unscaled(int style, float width, char* dashes);
// --- implementation is in src/fl_color.cxx which includes src/cfg_gfx/xxx_color.cxx
void color(Fl_Color c);
Fl_Color color() { return color_; }
@@ -162,8 +164,8 @@ private:
transparent_f_type TransparentBlt();
public:
virtual int has_feature(driver_feature mask) { return mask & (NATIVE | PRINTER); }
- void draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
- void draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy);
+ 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);
};
diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx
index 6649e3f3d..e211f1e3a 100644
--- a/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx
+++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx
@@ -104,7 +104,7 @@ HDC fl_makeDC(HBITMAP bitmap) {
return new_gc;
}
-void Fl_GDI_Graphics_Driver::copy_offscreen(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy) {
+void Fl_GDI_Graphics_Driver::copy_offscreen_unscaled(float x, float y, float w, float h, Fl_Offscreen bitmap, float srcx, float srcy) {
HDC new_gc = CreateCompatibleDC(gc_);
int save = SaveDC(new_gc);
SelectObject(new_gc, bitmap);
@@ -162,7 +162,7 @@ void Fl_GDI_Graphics_Driver::add_rectangle_to_region(Fl_Region r, int X, int Y,
XDestroyRegion(R);
}
-void Fl_GDI_Graphics_Driver::transformed_vertex0(int x, int y) {
+void Fl_GDI_Graphics_Driver::transformed_vertex0(float x, float y) {
if (!n || x != p[n-1].x || y != p[n-1].y) {
if (n >= p_size) {
p_size = p ? 2*p_size : 16;
@@ -228,6 +228,45 @@ void Fl_GDI_Graphics_Driver::set_spot(int font, int size, int X, int Y, int W, i
}
+void Fl_GDI_Graphics_Driver::scale(float f) {
+ if (f != scale_) {
+ size_ = 0;
+ scale_ = f;
+ //line_style(FL_SOLID); // scale also default line width
+ }
+}
+
+
+/* Rescale region r with factor f and returns the scaled region.
+ The input region is deleted if keep is false.
+ The input region is inflated by 1 unit before rescaling if inflate is true.
+ Region r is returned unchanged if r is null or f is 1.
+ */
+HRGN Fl_GDI_Graphics_Driver::scale_region(HRGN r, float f, bool keep, bool inflate) {
+ if (r && f != 1) {
+ DWORD size = GetRegionData(r, 0, NULL);
+ RGNDATA *pdata = (RGNDATA*)malloc(size);
+ GetRegionData(r, size, pdata);
+ if (!keep) DeleteObject(r);
+ if (inflate) {
+ RECT *rects = (RECT*)&(pdata->Buffer);
+ for (DWORD i = 0; i < pdata->rdh.nCount; i++) {
+ InflateRect(rects+i, 1, 1);
+ }
+ }
+ XFORM xform = {f, 0, 0, f, 0, 0};
+ r = ExtCreateRegion(&xform, size, pdata);
+ free(pdata);
+ }
+ return r;
+}
+
+
+Fl_Region Fl_GDI_Graphics_Driver::scale_clip(float f) {
+ HRGN r = rstack[rstackptr];
+ HRGN r2 = scale_region(r, f, true);
+ return (r == r2 ? NULL : (rstack[rstackptr] = r2, r));
+}
//
// End of "$Id$".
diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx
index 77753139f..53ea13dcd 100644
--- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx
+++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx
@@ -35,7 +35,7 @@
#include <FL/math.h>
#include <FL/x.H>
-void Fl_GDI_Graphics_Driver::arc(int x,int y,int w,int h,double a1,double a2) {
+void Fl_GDI_Graphics_Driver::arc_unscaled(float x, float y, float w, float h, double a1, double a2) {
if (w <= 0 || h <= 0) return;
int xa = x+w/2+int(w*cos(a1/180.0*M_PI));
int ya = y+h/2-int(h*sin(a1/180.0*M_PI));
@@ -47,7 +47,7 @@ void Fl_GDI_Graphics_Driver::arc(int x,int y,int w,int h,double a1,double a2) {
} else Arc(gc_, x, y, x+w, y+h, xa, ya, xb, yb);
}
-void Fl_GDI_Graphics_Driver::pie(int x,int y,int w,int h,double a1,double a2) {
+void Fl_GDI_Graphics_Driver::pie_unscaled(float x, float y, float w, float h, double a1, double a2) {
if (w <= 0 || h <= 0) return;
if (a1 == a2) return;
int xa = x+w/2+int(w*cos(a1/180.0*M_PI));
diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_font.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_font.cxx
index 6204929bd..5aea512f7 100644
--- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_font.cxx
+++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver_font.cxx
@@ -323,34 +323,40 @@ static void fl_font(Fl_Graphics_Driver *driver, Fl_Font fnum, Fl_Fontsize size,
driver->Fl_Graphics_Driver::font(0, 0);
return;
}
- if (fnum == driver->Fl_Graphics_Driver::font() && size == driver->size() && angle == fl_angle_) return;
+ if (fnum == driver->Fl_Graphics_Driver::font() && size == ((Fl_GDI_Graphics_Driver*)driver)->size_unscaled() && angle == fl_angle_) return;
fl_angle_ = angle;
driver->Fl_Graphics_Driver::font(fnum, size);
driver->font_descriptor( find(fnum, size, angle) );
}
-void Fl_GDI_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize size) {
+void Fl_GDI_Graphics_Driver::font_unscaled(Fl_Font fnum, Fl_Fontsize size) {
fl_font(this, fnum, size, 0);
}
-int Fl_GDI_Graphics_Driver::height() {
+int Fl_GDI_Graphics_Driver::height_unscaled() {
Fl_Font_Descriptor *fl_fontsize = font_descriptor();
if (fl_fontsize) return (fl_fontsize->metr.tmAscent + fl_fontsize->metr.tmDescent);
else return -1;
}
-int Fl_GDI_Graphics_Driver::descent() {
+int Fl_GDI_Graphics_Driver::descent_unscaled() {
Fl_Font_Descriptor *fl_fontsize = font_descriptor();
if (fl_fontsize) return fl_fontsize->metr.tmDescent;
else return -1;
}
+Fl_Fontsize Fl_GDI_Graphics_Driver::size_unscaled() {
+ if (font_descriptor()) return size_;
+ return -1;
+}
+
+
// Unicode string buffer
static unsigned short *wstr = NULL;
static int wstr_len = 0;
-double Fl_GDI_Graphics_Driver::width(const char* c, int n) {
+double Fl_GDI_Graphics_Driver::width_unscaled(const char* c, int n) {
int i = 0;
if (!font_descriptor()) return -1.0;
double w = 0.0;
@@ -362,13 +368,13 @@ double Fl_GDI_Graphics_Driver::width(const char* c, int n) {
// if (l < 1) l = 1;
i += l;
if (!fl_nonspacing(ucs)) {
- w += width(ucs);
+ w += width_unscaled(ucs);
}
}
return w;
}
-double Fl_GDI_Graphics_Driver::width(unsigned int c) {
+double Fl_GDI_Graphics_Driver::width_unscaled(unsigned int c) {
Fl_Font_Descriptor *fl_fontsize = font_descriptor();
unsigned int r;
SIZE s;
@@ -466,7 +472,7 @@ static void on_printer_extents_update(int &dx, int &dy, int &w, int &h, HDC gc)
}
// Function to determine the extent of the "inked" area of the glyphs in a string
-void Fl_GDI_Graphics_Driver::text_extents(const char *c, int n, int &dx, int &dy, int &w, int &h) {
+void Fl_GDI_Graphics_Driver::text_extents_unscaled(const char *c, int n, int &dx, int &dy, int &w, int &h) {
Fl_Font_Descriptor *fl_fontsize = font_descriptor();
if (!fl_fontsize) { // no valid font, nothing to measure
@@ -571,14 +577,14 @@ void Fl_GDI_Graphics_Driver::text_extents(const char *c, int n, int &dx, int &dy
exit_error:
// some error here - just return fl_measure values
w = (int)width(c, n);
- h = height();
+ h = height_unscaled();
dx = 0;
- dy = descent() - h;
+ dy = descent_unscaled() - h;
EXTENTS_UPDATE(dx, dy, w, h, gc_);
return;
} // fl_text_extents
-void Fl_GDI_Graphics_Driver::draw(const char* str, int n, int x, int y) {
+void Fl_GDI_Graphics_Driver::draw_unscaled(const char* str, int n, int x, int y) {
COLORREF oldColor = SetTextColor(gc_, fl_RGB());
// avoid crash if no font has been set yet
if (!font_descriptor()) this->font(FL_HELVETICA, FL_NORMAL_SIZE);
@@ -593,8 +599,8 @@ void Fl_GDI_Graphics_Driver::draw(const char* str, int n, int x, int y) {
SetTextColor(gc_, oldColor); // restore initial state
}
-void Fl_GDI_Graphics_Driver::draw(int angle, const char* str, int n, int x, int y) {
- fl_font(this, Fl_Graphics_Driver::font(), size(), angle);
+void Fl_GDI_Graphics_Driver::draw_unscaled(int angle, const char* str, int n, int x, int y) {
+ fl_font(this, Fl_Graphics_Driver::font(), size_unscaled(), angle);
int wn = 0; // count of UTF16 cells to render full string
COLORREF oldColor = SetTextColor(gc_, fl_RGB());
SelectObject(gc_, font_descriptor()->fid);
@@ -606,10 +612,10 @@ void Fl_GDI_Graphics_Driver::draw(int angle, const char* str, int n, int x, int
}
TextOutW(gc_, x, y, (WCHAR*)wstr, wn);
SetTextColor(gc_, oldColor);
- fl_font(this, Fl_Graphics_Driver::font(), size(), 0);
+ fl_font(this, Fl_Graphics_Driver::font(), size_unscaled(), 0);
}
-void Fl_GDI_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) {
+void Fl_GDI_Graphics_Driver::rtl_draw_unscaled(const char* c, int n, int x, int y) {
int wn;
wn = fl_utf8toUtf16(c, n, wstr, wstr_len);
if(wn >= wstr_len) {
@@ -634,7 +640,7 @@ void Fl_GDI_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) {
}
#else
UINT old_align = SetTextAlign(gc_, TA_RIGHT | TA_RTLREADING);
- TextOutW(gc_, x, y - height() + descent(), (WCHAR*)wstr, wn);
+ TextOutW(gc_, x, y - height_unscaled() + descent_unscaled(), (WCHAR*)wstr, wn);
SetTextAlign(gc_, old_align);
#endif
SetTextColor(gc_, oldColor);
diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx
index 7006bc429..4749ad14a 100644
--- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx
+++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx
@@ -42,6 +42,7 @@
#include <FL/Fl_Printer.H>
#include <FL/fl_draw.H>
#include <FL/x.H>
+#include <FL/Fl_Image_Surface.H>
#define MAXBUFFER 0x40000 // 256k
@@ -284,7 +285,7 @@ static void innards(const uchar *buf, int X, int Y, int W, int H,
}
}
-void Fl_GDI_Graphics_Driver::draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){
+void Fl_GDI_Graphics_Driver::draw_image_unscaled(const uchar* buf, int x, int y, int w, int h, int d, int l){
if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) {
d ^= FL_IMAGE_WITH_ALPHA;
innards(buf,x,y,w,h,d,l,fl_abs(d),0,0, gc_);
@@ -293,7 +294,7 @@ void Fl_GDI_Graphics_Driver::draw_image(const uchar* buf, int x, int y, int w, i
}
}
-void Fl_GDI_Graphics_Driver::draw_image(Fl_Draw_Image_Cb cb, void* data,
+void Fl_GDI_Graphics_Driver::draw_image_unscaled(Fl_Draw_Image_Cb cb, void* data,
int x, int y, int w, int h,int d) {
if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) {
d ^= FL_IMAGE_WITH_ALPHA;
@@ -303,7 +304,7 @@ void Fl_GDI_Graphics_Driver::draw_image(Fl_Draw_Image_Cb cb, void* data,
}
}
-void Fl_GDI_Graphics_Driver::draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){
+void Fl_GDI_Graphics_Driver::draw_image_mono_unscaled(const uchar* buf, int x, int y, int w, int h, int d, int l){
if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) {
d ^= FL_IMAGE_WITH_ALPHA;
innards(buf,x,y,w,h,d,l,1,0,0, gc_);
@@ -312,7 +313,7 @@ void Fl_GDI_Graphics_Driver::draw_image_mono(const uchar* buf, int x, int y, int
}
}
-void Fl_GDI_Graphics_Driver::draw_image_mono(Fl_Draw_Image_Cb cb, void* data,
+void Fl_GDI_Graphics_Driver::draw_image_mono_unscaled(Fl_Draw_Image_Cb cb, void* data,
int x, int y, int w, int h,int d) {
if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) {
d ^= FL_IMAGE_WITH_ALPHA;
@@ -399,11 +400,15 @@ void Fl_GDI_Graphics_Driver::delete_bitmask(Fl_Bitmask bm) {
DeleteObject((HGDIOBJ)bm);
}
-void Fl_GDI_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
+void Fl_GDI_Graphics_Driver::draw_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;
+ cache_size(bm, W, H);
+ cx *= s; cy *= s;
HDC tempdc = CreateCompatibleDC(gc_);
int save = SaveDC(tempdc);
@@ -423,7 +428,7 @@ Fl_GDI_Printer_Graphics_Driver::transparent_f_type Fl_GDI_Printer_Graphics_Drive
return fpter;
}
-void Fl_GDI_Printer_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
+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) {
int X, Y, W, H;
transparent_f_type fl_TransparentBlt = TransparentBlt();
if (!fl_TransparentBlt) {
@@ -467,34 +472,33 @@ void Fl_GDI_Printer_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP,
static Fl_Offscreen build_id(Fl_RGB_Image *img, void **pmask)
{
- Fl_Offscreen offs = fl_create_offscreen(img->w(), img->h());
+ Fl_Image_Surface *surface = new Fl_Image_Surface(img->w(), img->h());
+ Fl_Surface_Device::push_current(surface);
if ((img->d() == 2 || img->d() == 4) && fl_can_do_alpha_blending()) {
- fl_begin_offscreen(offs);
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(offs);
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) {
*pmask = fl_create_alphamask(img->w(), img->h(), img->d(), img->ld(), img->array);
}
}
+ Fl_Surface_Device::pop_current();
+ Fl_Offscreen offs = surface->get_offscreen_before_delete();
+ delete surface;
return offs;
}
-void Fl_GDI_Graphics_Driver::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) {
- Fl_Graphics_Driver::draw_empty(img, XP, YP);
- return;
- }
- if (start_image(img, XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
- return;
+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;
+ cache_size(img, W, H);
+ cx *= s; cy *= s;
+ if (!*Fl_Graphics_Driver::id(img)) {
+ *Fl_Graphics_Driver::id(img) = (fl_uintptr_t)build_id(img, (void**)(Fl_Graphics_Driver::mask(img)));
+ *cache_scale(img) = 1;
}
- if (!*Fl_Graphics_Driver::id(img)) *Fl_Graphics_Driver::id(img) = (fl_uintptr_t)build_id(img, (void**)(Fl_Graphics_Driver::mask(img)));
+ Fl_Region r2 = scale_clip(s);
if (*Fl_Graphics_Driver::mask(img)) {
HDC new_gc = CreateCompatibleDC(gc_);
int save = SaveDC(new_gc);
@@ -509,6 +513,7 @@ void Fl_GDI_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP, int
} 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) {
@@ -525,21 +530,26 @@ int Fl_GDI_Printer_Graphics_Driver::draw_scaled(Fl_Image *img, int XP, int YP, i
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;
- if (!*Fl_Graphics_Driver::id(rgb)) *Fl_Graphics_Driver::id(rgb) = (fl_uintptr_t)build_id(rgb,
+ if (!*Fl_Graphics_Driver::id(rgb)) {
+ *Fl_Graphics_Driver::id(rgb) = (fl_uintptr_t)build_id(rgb,
(void**)(Fl_Graphics_Driver::mask(rgb)));
+ *cache_scale(rgb) = 1;
+ }
+ cache_size(img, WP, HP);
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, YP, WP, HP, new_gc, 0, 0, rgb->w(), rgb->h());
+ alpha_blend_(XP*scale_, YP*scale_, WP, HP, new_gc, 0, 0, rgb->w(), rgb->h());
} else {
SetStretchBltMode(gc_, HALFTONE);
- StretchBlt(gc_, XP, YP, WP, HP, new_gc, 0, 0, rgb->w(), rgb->h(), SRCCOPY);
+ StretchBlt(gc_, XP*scale_, YP*scale_, WP, HP, new_gc, 0, 0, rgb->w(), rgb->h(), SRCCOPY);
}
RestoreDC(new_gc, save);
DeleteDC(new_gc);
@@ -587,13 +597,17 @@ static Fl_Bitmask fl_create_bitmap(int w, int h, const uchar *data) {
return bm;
}
-fl_uintptr_t Fl_GDI_Graphics_Driver::cache(Fl_Bitmap*, int w, int h, const uchar *array) {
+fl_uintptr_t Fl_GDI_Graphics_Driver::cache(Fl_Bitmap *bm, int w, int h, const uchar *array) {
+ *cache_scale(bm) = Fl_Scalable_Graphics_Driver::scale();
return (fl_uintptr_t)fl_create_bitmap(w, h, array);
}
-void Fl_GDI_Graphics_Driver::draw(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;
+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;
+ cache_size(pxm, W, H);
+ cx *= s; cy *= s;
+ Fl_Region r2 = scale_clip(s);
if (*Fl_Graphics_Driver::mask(pxm)) {
HDC new_gc = CreateCompatibleDC(gc_);
int save = SaveDC(new_gc);
@@ -606,10 +620,11 @@ void Fl_GDI_Graphics_Driver::draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP
} else {
copy_offscreen(X, Y, W, H, (Fl_Offscreen)*Fl_Graphics_Driver::id(pxm), cx, cy);
}
+ unscale_clip(r2);
}
-void Fl_GDI_Printer_Graphics_Driver::draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) {
+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) {
int X, Y, W, H;
if (Fl_Graphics_Driver::prepare(pxm, XP, YP, WP, HP, cx, cy, X, Y, W, H)) return;
transparent_f_type fl_TransparentBlt = TransparentBlt();
@@ -642,6 +657,7 @@ fl_uintptr_t Fl_GDI_Graphics_Driver::cache(Fl_Pixmap *img, int w, int h, const c
delete[] bitmap;
}
fl_end_offscreen();
+ *cache_scale(img) = Fl_Scalable_Graphics_Driver::scale();
return (fl_uintptr_t)id;
}
diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_line_style.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_line_style.cxx
index 26dd842d9..35281265c 100644
--- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_line_style.cxx
+++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver_line_style.cxx
@@ -35,7 +35,7 @@
#include "Fl_GDI_Graphics_Driver.H"
-void Fl_GDI_Graphics_Driver::line_style(int style, int width, char* dashes) {
+void Fl_GDI_Graphics_Driver::line_style_unscaled(int style, float width, char* dashes) {
// According to Bill, the "default" cap and join should be the
// "fastest" mode supported for the platform. I don't know why
diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx
index 3ef206488..86698e386 100644
--- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx
+++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx
@@ -35,11 +35,11 @@
// --- line and polygon drawing with integer coordinates
-void Fl_GDI_Graphics_Driver::point(int x, int y) {
+void Fl_GDI_Graphics_Driver::point_unscaled(float x, float y) {
SetPixel(gc_, x, y, fl_RGB());
}
-void Fl_GDI_Graphics_Driver::rect(int x, int y, int w, int h) {
+void Fl_GDI_Graphics_Driver::rect_unscaled(float x, float y, float w, float h) {
if (w<=0 || h<=0) return;
MoveToEx(gc_, x, y, 0L);
LineTo(gc_, x+w-1, y);
@@ -59,7 +59,7 @@ void Fl_GDI_Graphics_Driver::focus_rect(int x, int y, int w, int h) {
for (yy = h; yy > 0; yy--, i++) if (i & 1) point(x, y + yy);
}
-void Fl_GDI_Graphics_Driver::rectf(int x, int y, int w, int h) {
+void Fl_GDI_Graphics_Driver::rectf_unscaled(float x, float y, float w, float h) {
if (w<=0 || h<=0) return;
RECT rect;
rect.left = x; rect.top = y;
@@ -67,24 +67,24 @@ void Fl_GDI_Graphics_Driver::rectf(int x, int y, int w, int h) {
FillRect(gc_, &rect, fl_brush());
}
-void Fl_GDI_Graphics_Driver::line(int x, int y, int x1, int y1) {
+void Fl_GDI_Graphics_Driver::line_unscaled(float x, float y, float x1, float y1) {
MoveToEx(gc_, x, y, 0L);
LineTo(gc_, x1, y1);
SetPixel(gc_, x1, y1, fl_RGB());
}
-void Fl_GDI_Graphics_Driver::line(int x, int y, int x1, int y1, int x2, int y2) {
+void Fl_GDI_Graphics_Driver::line_unscaled(float x, float y, float x1, float y1, float x2, float y2) {
MoveToEx(gc_, x, y, 0L);
LineTo(gc_, x1, y1);
LineTo(gc_, x2, y2);
SetPixel(gc_, x2, y2, fl_RGB());
}
-void Fl_GDI_Graphics_Driver::xyline(int x, int y, int x1) {
+void Fl_GDI_Graphics_Driver::xyline_unscaled(float x, float y, float x1) {
MoveToEx(gc_, x, y, 0L); LineTo(gc_, x1+1, y);
}
-void Fl_GDI_Graphics_Driver::xyline(int x, int y, int x1, int y2) {
+void Fl_GDI_Graphics_Driver::xyline_unscaled(float x, float y, float x1, float y2) {
if (y2 < y) y2--;
else y2++;
MoveToEx(gc_, x, y, 0L);
@@ -92,7 +92,7 @@ void Fl_GDI_Graphics_Driver::xyline(int x, int y, int x1, int y2) {
LineTo(gc_, x1, y2);
}
-void Fl_GDI_Graphics_Driver::xyline(int x, int y, int x1, int y2, int x3) {
+void Fl_GDI_Graphics_Driver::xyline_unscaled(float x, float y, float x1, float y2, float x3) {
if(x3 < x1) x3--;
else x3++;
MoveToEx(gc_, x, y, 0L);
@@ -101,13 +101,13 @@ void Fl_GDI_Graphics_Driver::xyline(int x, int y, int x1, int y2, int x3) {
LineTo(gc_, x3, y2);
}
-void Fl_GDI_Graphics_Driver::yxline(int x, int y, int y1) {
+void Fl_GDI_Graphics_Driver::yxline_unscaled(float x, float y, float y1) {
if (y1 < y) y1--;
else y1++;
MoveToEx(gc_, x, y, 0L); LineTo(gc_, x, y1);
}
-void Fl_GDI_Graphics_Driver::yxline(int x, int y, int y1, int x2) {
+void Fl_GDI_Graphics_Driver::yxline_unscaled(float x, float y, float y1, float x2) {
if (x2 > x) x2++;
else x2--;
MoveToEx(gc_, x, y, 0L);
@@ -115,7 +115,7 @@ void Fl_GDI_Graphics_Driver::yxline(int x, int y, int y1, int x2) {
LineTo(gc_, x2, y1);
}
-void Fl_GDI_Graphics_Driver::yxline(int x, int y, int y1, int x2, int y3) {
+void Fl_GDI_Graphics_Driver::yxline_unscaled(float x, float y, float y1, float x2, float y3) {
if(y3<y1) y3--;
else y3++;
MoveToEx(gc_, x, y, 0L);
@@ -124,14 +124,14 @@ void Fl_GDI_Graphics_Driver::yxline(int x, int y, int y1, int x2, int y3) {
LineTo(gc_, x2, y3);
}
-void Fl_GDI_Graphics_Driver::loop(int x, int y, int x1, int y1, int x2, int y2) {
+void Fl_GDI_Graphics_Driver::loop_unscaled(float x, float y, float x1, float y1, float x2, float y2) {
MoveToEx(gc_, x, y, 0L);
LineTo(gc_, x1, y1);
LineTo(gc_, x2, y2);
LineTo(gc_, x, y);
}
-void Fl_GDI_Graphics_Driver::loop(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) {
+void Fl_GDI_Graphics_Driver::loop_unscaled(float x, float y, float x1, float y1, float x2, float y2, float x3, float y3) {
MoveToEx(gc_, x, y, 0L);
LineTo(gc_, x1, y1);
LineTo(gc_, x2, y2);
@@ -139,7 +139,7 @@ void Fl_GDI_Graphics_Driver::loop(int x, int y, int x1, int y1, int x2, int y2,
LineTo(gc_, x, y);
}
-void Fl_GDI_Graphics_Driver::polygon(int x, int y, int x1, int y1, int x2, int y2) {
+void Fl_GDI_Graphics_Driver::polygon_unscaled(float x, float y, float x1, float y1, float x2, float y2) {
POINT p[3];
p[0].x = x; p[0].y = y;
p[1].x = x1; p[1].y = y1;
@@ -148,7 +148,7 @@ void Fl_GDI_Graphics_Driver::polygon(int x, int y, int x1, int y1, int x2, int y
Polygon(gc_, p, 3);
}
-void Fl_GDI_Graphics_Driver::polygon(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) {
+void Fl_GDI_Graphics_Driver::polygon_unscaled(float x, float y, float x1, float y1, float x2, float y2, float x3, float y3) {
POINT p[4];
p[0].x = x; p[0].y = y;
p[1].x = x1; p[1].y = y1;
@@ -244,8 +244,10 @@ void Fl_GDI_Graphics_Driver::pop_clip() {
void Fl_GDI_Graphics_Driver::restore_clip() {
fl_clip_state_number++;
if (gc_) {
- Fl_Region r = rstack[rstackptr];
- SelectClipRgn(gc_, r); // if r is NULL, clip is automatically cleared
+ HRGN r = NULL;
+ if (rstack[rstackptr]) r = scale_clip(scale_);
+ SelectClipRgn(gc_, rstack[rstackptr]); // if region is NULL, clip is automatically cleared
+ if (r) unscale_clip(r);
}
}
diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_vertex.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_vertex.cxx
index e4ce856b1..ee817bf4f 100644
--- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_vertex.cxx
+++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver_vertex.cxx
@@ -32,14 +32,6 @@
#include <FL/math.h>
-void Fl_GDI_Graphics_Driver::transformed_vertex(double xf, double yf) {
- transformed_vertex0(int(rint(xf)), int(rint(yf)));
-}
-
-void Fl_GDI_Graphics_Driver::vertex(double x,double y) {
- transformed_vertex0(int(x*m.a + y*m.c + m.x), int(x*m.b + y*m.d + m.y));
-}
-
void Fl_GDI_Graphics_Driver::end_points() {
for (int i=0; i<n; i++) SetPixel(gc_, p[i].x, p[i].y, fl_RGB());
}
@@ -54,7 +46,7 @@ void Fl_GDI_Graphics_Driver::end_line() {
void Fl_GDI_Graphics_Driver::end_loop() {
fixloop();
- if (n>2) transformed_vertex((int)p[0].x, (int)p[0].y);
+ if (n>2) transformed_vertex0(p[0].x, p[0].y);
end_line();
}
@@ -79,7 +71,7 @@ void Fl_GDI_Graphics_Driver::begin_complex_polygon() {
void Fl_GDI_Graphics_Driver::gap() {
while (n>gap_+2 && p[n-1].x == p[gap_].x && p[n-1].y == p[gap_].y) n--;
if (n > gap_+2) {
- transformed_vertex((int)p[gap_].x, (int)p[gap_].y);
+ transformed_vertex0(p[gap_].x, p[gap_].y);
counts[numcount++] = n-gap_;
gap_ = n;
} else {
@@ -99,15 +91,7 @@ void Fl_GDI_Graphics_Driver::end_complex_polygon() {
}
}
-// shortcut the closed circles so they use XDrawArc:
-// warning: these do not draw rotated ellipses correctly!
-// See fl_arc.c for portable version.
-
-void Fl_GDI_Graphics_Driver::circle(double x, double y,double r) {
- double xt = transform_x(x,y);
- double yt = transform_y(x,y);
- double rx = r * (m.c ? sqrt(m.a*m.a+m.c*m.c) : fabs(m.a));
- double ry = r * (m.b ? sqrt(m.b*m.b+m.d*m.d) : fabs(m.d));
+void Fl_GDI_Graphics_Driver::ellipse_unscaled(double xt, double yt, double rx, double ry) {
int llx = (int)rint(xt-rx);
int w = (int)rint(xt+rx)-llx;
int lly = (int)rint(yt-ry);
diff --git a/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx b/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx
index 5e0b636f5..e55e69583 100644
--- a/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx
+++ b/src/drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx
@@ -27,7 +27,6 @@
#include <windows.h>
class Fl_GDI_Image_Surface_Driver : public Fl_Image_Surface_Driver {
- friend class Fl_Image_Surface;
virtual void end_current_(Fl_Surface_Device*);
public:
Fl_Surface_Device *previous;
@@ -51,8 +50,14 @@ Fl_Image_Surface_Driver *Fl_Image_Surface_Driver::newImageSurfaceDriver(int w, i
Fl_GDI_Image_Surface_Driver::Fl_GDI_Image_Surface_Driver(int w, int h, int high_res, Fl_Offscreen off) : Fl_Image_Surface_Driver(w, h, high_res, 0) {
previous = 0;
+ float d = fl_graphics_driver->scale();
+ if (!off && d != 1 && high_res) {
+ w = int(w*d);
+ h = int(h*d);
+ }
offscreen = off ? off : CreateCompatibleBitmap( (fl_graphics_driver->gc() ? (HDC)fl_graphics_driver->gc() : fl_GetDC(0) ) , w, h);
driver(new Fl_GDI_Graphics_Driver);
+ if (d != 1 && high_res) driver()->scale(d);
_sgc = NULL;
}