diff options
Diffstat (limited to 'src/drivers/GDI')
| -rw-r--r-- | src/drivers/GDI/Fl_GDI_Graphics_Driver.H | 86 | ||||
| -rw-r--r-- | src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx | 43 | ||||
| -rw-r--r-- | src/drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx | 4 | ||||
| -rw-r--r-- | src/drivers/GDI/Fl_GDI_Graphics_Driver_font.cxx | 38 | ||||
| -rw-r--r-- | src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx | 74 | ||||
| -rw-r--r-- | src/drivers/GDI/Fl_GDI_Graphics_Driver_line_style.cxx | 2 | ||||
| -rw-r--r-- | src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx | 36 | ||||
| -rw-r--r-- | src/drivers/GDI/Fl_GDI_Graphics_Driver_vertex.cxx | 22 | ||||
| -rw-r--r-- | src/drivers/GDI/Fl_GDI_Image_Surface_Driver.cxx | 7 |
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; } |
