mirror of
https://github.com/fltk/fltk.git
synced 2026-05-31 13:55:38 +08:00
Improve precision of GUI scaling for Windows platform.
This commit is contained in:
@@ -237,6 +237,7 @@ protected:
|
|||||||
|
|
||||||
Fl_Graphics_Driver();
|
Fl_Graphics_Driver();
|
||||||
virtual void cache_size(Fl_Image *img, int &width, int &height);
|
virtual void cache_size(Fl_Image *img, int &width, int &height);
|
||||||
|
void cache_size_finalize(Fl_Image *img, int &width, int &height);
|
||||||
static unsigned need_pixmap_bg_color;
|
static unsigned need_pixmap_bg_color;
|
||||||
public:
|
public:
|
||||||
virtual ~Fl_Graphics_Driver() {} ///< Destructor
|
virtual ~Fl_Graphics_Driver() {} ///< Destructor
|
||||||
@@ -444,6 +445,7 @@ protected:
|
|||||||
virtual void circle(double x, double y, double r);
|
virtual void circle(double x, double y, double r);
|
||||||
virtual void ellipse_unscaled(double xt, double yt, double rx, double ry);
|
virtual void ellipse_unscaled(double xt, double yt, double rx, double ry);
|
||||||
virtual void font(Fl_Font face, Fl_Fontsize size);
|
virtual void font(Fl_Font face, Fl_Fontsize size);
|
||||||
|
virtual Fl_Font font();
|
||||||
virtual void font_unscaled(Fl_Font face, Fl_Fontsize size);
|
virtual void font_unscaled(Fl_Font face, Fl_Fontsize size);
|
||||||
virtual double width(const char *str, int n);
|
virtual double width(const char *str, int n);
|
||||||
virtual double width(unsigned int c);
|
virtual double width(unsigned int c);
|
||||||
@@ -461,8 +463,10 @@ protected:
|
|||||||
virtual void draw_unscaled(const char *str, int n, int x, int y);
|
virtual void draw_unscaled(const char *str, int n, int x, int y);
|
||||||
virtual void draw(int angle, const char *str, int n, int x, int y);
|
virtual void draw(int angle, 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 draw_unscaled(int angle, const char *str, int n, int x, int y);
|
||||||
|
virtual void draw(const char *str, int nChars, float x, float y);
|
||||||
virtual void rtl_draw(const char* str, int n, int x, int y);
|
virtual void rtl_draw(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 rtl_draw_unscaled(const char* str, int n, int x, int y);
|
||||||
|
virtual void arc(double x, double y, double r, double start, double end);
|
||||||
virtual void arc(int x, int y, int w, int h, double a1, double a2);
|
virtual void arc(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 arc_unscaled(float x, float y, float w, float h, double a1, double a2);
|
||||||
virtual void pie(int x, int y, int w, int h, double a1, double a2);
|
virtual void pie(int x, int y, int w, int h, double a1, double a2);
|
||||||
|
|||||||
@@ -211,6 +211,10 @@ void Fl_Graphics_Driver::cache_size(Fl_Image *img, int &width, int &height)
|
|||||||
fs = height * s;
|
fs = height * s;
|
||||||
height = (fs - int(fs) < 0.001 ? int(fs) :
|
height = (fs - int(fs) < 0.001 ? int(fs) :
|
||||||
int((height+1) * s));
|
int((height+1) * s));
|
||||||
|
cache_size_finalize(img, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Fl_Graphics_Driver::cache_size_finalize(Fl_Image *img, int &width, int &height) {
|
||||||
if (img) img->cache_size_(width, height);
|
if (img) img->cache_size_(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -754,6 +758,10 @@ void Fl_Scalable_Graphics_Driver::font(Fl_Font face, Fl_Fontsize size) {
|
|||||||
font_unscaled(face, Fl_Fontsize(size * scale()));
|
font_unscaled(face, Fl_Fontsize(size * scale()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Fl_Font Fl_Scalable_Graphics_Driver::font() {
|
||||||
|
return Fl_Graphics_Driver::font();
|
||||||
|
}
|
||||||
|
|
||||||
double Fl_Scalable_Graphics_Driver::width(const char *str, int n) {
|
double Fl_Scalable_Graphics_Driver::width(const char *str, int n) {
|
||||||
return width_unscaled(str, n)/scale();
|
return width_unscaled(str, n)/scale();
|
||||||
}
|
}
|
||||||
@@ -790,6 +798,10 @@ void Fl_Scalable_Graphics_Driver::draw(const char *str, int n, int x, int y) {
|
|||||||
unscale_clip(r2);
|
unscale_clip(r2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Fl_Scalable_Graphics_Driver::draw(const char *str, int n, float x, float y) {
|
||||||
|
Fl_Graphics_Driver::draw(str, n, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
void Fl_Scalable_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y) {
|
void Fl_Scalable_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y) {
|
||||||
if (!size_ || !font_descriptor()) font(FL_HELVETICA, FL_NORMAL_SIZE);
|
if (!size_ || !font_descriptor()) font(FL_HELVETICA, FL_NORMAL_SIZE);
|
||||||
Fl_Region r2 = scale_clip(scale());
|
Fl_Region r2 = scale_clip(scale());
|
||||||
@@ -805,6 +817,10 @@ void Fl_Scalable_Graphics_Driver::arc(int x,int y,int w,int h,double a1,double a
|
|||||||
arc_unscaled(x * scale(), y * scale(), w * scale(), h * scale(), a1, a2);
|
arc_unscaled(x * scale(), y * scale(), w * scale(), h * scale(), a1, a2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Fl_Scalable_Graphics_Driver::arc(double x, double y, double r, double start, double end) {
|
||||||
|
Fl_Graphics_Driver::arc(x, y, r, start, end);
|
||||||
|
}
|
||||||
|
|
||||||
void Fl_Scalable_Graphics_Driver::pie(int x,int y,int w,int h,double a1,double a2) {
|
void Fl_Scalable_Graphics_Driver::pie(int x,int y,int w,int h,double a1,double a2) {
|
||||||
pie_unscaled(x * scale(), y * scale(), w * scale(), h * scale(), a1, a2);
|
pie_unscaled(x * scale(), y * scale(), w * scale(), h * scale(), a1, a2);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ Fl_GDI_Copy_Surface_Driver::~Fl_GDI_Copy_Surface_Driver() {
|
|||||||
SetClipboardData (CF_ENHMETAFILE, hmf);
|
SetClipboardData (CF_ENHMETAFILE, hmf);
|
||||||
// then put a BITMAP version of the graphics in the clipboard
|
// then put a BITMAP version of the graphics in the clipboard
|
||||||
float scaling = driver()->scale();
|
float scaling = driver()->scale();
|
||||||
int W = int(width * scaling), H = int(height * scaling);
|
int W = Fl_GDI_Graphics_Driver::floor(width, scaling), H = Fl_GDI_Graphics_Driver::floor(height, scaling);
|
||||||
RECT rect = {0, 0, W, H};
|
RECT rect = {0, 0, W, H};
|
||||||
Fl_Image_Surface *surf = new Fl_Image_Surface(W, H);
|
Fl_Image_Surface *surf = new Fl_Image_Surface(W, H);
|
||||||
Fl_Surface_Device::push_current(surf);
|
Fl_Surface_Device::push_current(surf);
|
||||||
|
|||||||
@@ -58,6 +58,11 @@ public:
|
|||||||
char can_do_alpha_blending();
|
char can_do_alpha_blending();
|
||||||
virtual void gc(void *ctxt) { gc_ = (HDC)ctxt; global_gc(); }
|
virtual void gc(void *ctxt) { gc_ = (HDC)ctxt; global_gc(); }
|
||||||
virtual void *gc() {return gc_;}
|
virtual void *gc() {return gc_;}
|
||||||
|
// This function aims to compute accurately int(x * s) in
|
||||||
|
// presence of rounding errors existing with floating point numbers
|
||||||
|
// and that sometimes differ between 32 and 64 bits.
|
||||||
|
static inline int floor(int x, float s) { return int(x * s + 0.001f); }
|
||||||
|
inline int floor(int x) { return Fl_GDI_Graphics_Driver::floor(x, scale()); }
|
||||||
|
|
||||||
// --- bitmap stuff
|
// --- bitmap stuff
|
||||||
Fl_Bitmask create_bitmask(int w, int h, const uchar *array);
|
Fl_Bitmask create_bitmask(int w, int h, const uchar *array);
|
||||||
@@ -96,14 +101,18 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
void transformed_vertex0(float x, float y);
|
void transformed_vertex0(float x, float y);
|
||||||
void fixloop();
|
void fixloop();
|
||||||
virtual void point_unscaled(float x, float y);
|
virtual void point(int x, int y);
|
||||||
virtual void rect(int x, int y, int w, int h);
|
virtual void rect(int x, int y, int w, int h);
|
||||||
void focus_rect(int x, int y, int w, int h);
|
void focus_rect(int x, int y, int w, int h);
|
||||||
void rectf_unscaled(float x, float y, float w, float h);
|
virtual void rectf(int x, int y, int w, int 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);
|
||||||
virtual void line_unscaled(float x, float y, float x1, float y1, float x2, float y2);
|
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(int x, int y, int x1);
|
||||||
virtual void yxline_unscaled(float x, float y, float y1);
|
virtual void xyline(int x, int y, int x1, int y2);
|
||||||
|
virtual void xyline(int x, int y, int x1, int y2, int x3);
|
||||||
|
virtual void yxline(int x, int y, int y1);
|
||||||
|
virtual void yxline(int x, int y, int y1, int x2);
|
||||||
|
virtual void yxline(int x, int y, int y1, int x2, int 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);
|
||||||
virtual void loop_unscaled(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3);
|
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);
|
||||||
@@ -144,6 +153,7 @@ protected:
|
|||||||
virtual void font_name(int num, const char *name);
|
virtual void font_name(int num, const char *name);
|
||||||
void global_gc();
|
void global_gc();
|
||||||
virtual void overlay_rect(int x, int y, int w , int h);
|
virtual void overlay_rect(int x, int y, int w , int h);
|
||||||
|
virtual void cache_size(Fl_Image *img, int &width, int &height);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -260,15 +260,14 @@ HRGN Fl_GDI_Graphics_Driver::scale_region(HRGN r, float f, Fl_GDI_Graphics_Drive
|
|||||||
pt.y = int(pt.y * (f - 1));
|
pt.y = int(pt.y * (f - 1));
|
||||||
}
|
}
|
||||||
RECT *rects = (RECT*)&(pdata->Buffer);
|
RECT *rects = (RECT*)&(pdata->Buffer);
|
||||||
int delta = (f > 1.75 ? 1 : 0) - int(f/2);
|
|
||||||
for (DWORD i = 0; i < pdata->rdh.nCount; i++) {
|
for (DWORD i = 0; i < pdata->rdh.nCount; i++) {
|
||||||
int x = int(rects[i].left * f) + pt.x;
|
int x = Fl_GDI_Graphics_Driver::floor(rects[i].left, f) + pt.x;
|
||||||
int y = int(rects[i].top * f) + pt.y;
|
int y = Fl_GDI_Graphics_Driver::floor(rects[i].top, f) + pt.y;
|
||||||
RECT R2;
|
RECT R2;
|
||||||
R2.left = x + delta;
|
R2.left = x;
|
||||||
R2.top = y + delta;
|
R2.top = y;
|
||||||
R2.right = int(rects[i].right * f) + pt.x - x + R2.left;
|
R2.right = Fl_GDI_Graphics_Driver::floor(rects[i].right, f) + pt.x - x + R2.left;
|
||||||
R2.bottom = int(rects[i].bottom * f) + pt.y - y + R2.top;
|
R2.bottom = Fl_GDI_Graphics_Driver::floor(rects[i].bottom, f) + pt.y - y + R2.top;
|
||||||
rects[i] = R2;
|
rects[i] = R2;
|
||||||
}
|
}
|
||||||
r = ExtCreateRegion(NULL, size, pdata);
|
r = ExtCreateRegion(NULL, size, pdata);
|
||||||
@@ -287,3 +286,11 @@ Fl_Region Fl_GDI_Graphics_Driver::scale_clip(float f) {
|
|||||||
void Fl_GDI_Graphics_Driver::set_current_() {
|
void Fl_GDI_Graphics_Driver::set_current_() {
|
||||||
restore_clip();
|
restore_clip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Fl_GDI_Graphics_Driver::cache_size(Fl_Image *img, int &width, int &height)
|
||||||
|
{
|
||||||
|
float s = scale();
|
||||||
|
width = (s == int(s) ? width * int(s) : floor(width+1));
|
||||||
|
height = (s == int(s) ? height * int(s) : floor(height+1));
|
||||||
|
cache_size_finalize(img, width, height);
|
||||||
|
}
|
||||||
|
|||||||
@@ -398,10 +398,10 @@ void Fl_GDI_Graphics_Driver::delete_bitmask(Fl_Bitmask bm) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Fl_GDI_Graphics_Driver::draw_fixed(Fl_Bitmap *bm, int X, int Y, int W, int H, int cx, int cy) {
|
void Fl_GDI_Graphics_Driver::draw_fixed(Fl_Bitmap *bm, int X, int Y, int W, int H, int cx, int cy) {
|
||||||
X = int(X * scale());
|
X = this->floor(X);
|
||||||
Y = int(Y * scale());
|
Y = this->floor(Y);
|
||||||
cache_size(bm, W, H);
|
cache_size(bm, W, H);
|
||||||
cx = int(cx * scale()); cy = int(cy * scale());
|
cx = this->floor(cx); cy = this->floor(cy);
|
||||||
|
|
||||||
HDC tempdc = CreateCompatibleDC(gc_);
|
HDC tempdc = CreateCompatibleDC(gc_);
|
||||||
int save = SaveDC(tempdc);
|
int save = SaveDC(tempdc);
|
||||||
@@ -499,10 +499,10 @@ void Fl_GDI_Graphics_Driver::cache(Fl_RGB_Image *img)
|
|||||||
|
|
||||||
|
|
||||||
void Fl_GDI_Graphics_Driver::draw_fixed(Fl_RGB_Image *img, int X, int Y, int W, int H, int cx, int cy) {
|
void Fl_GDI_Graphics_Driver::draw_fixed(Fl_RGB_Image *img, int X, int Y, int W, int H, int cx, int cy) {
|
||||||
X = int(X * scale());
|
X = this->floor(X);
|
||||||
Y = int(Y * scale());
|
Y = this->floor(Y);
|
||||||
cache_size(img, W, H);
|
cache_size(img, W, H);
|
||||||
cx = int(cx * scale()); cy = int(cy * scale());
|
cx = this->floor(cx); cy = this->floor(cy);
|
||||||
if (W + cx > img->data_w()) W = img->data_w() - cx;
|
if (W + cx > img->data_w()) W = img->data_w() - cx;
|
||||||
if (H + cy > img->data_h()) H = img->data_h() - cy;
|
if (H + cy > img->data_h()) H = img->data_h() - cy;
|
||||||
if (!*Fl_Graphics_Driver::id(img)) {
|
if (!*Fl_Graphics_Driver::id(img)) {
|
||||||
@@ -547,10 +547,10 @@ void Fl_GDI_Graphics_Driver::draw_rgb(Fl_RGB_Image *rgb, int XP, int YP, int WP,
|
|||||||
int save = SaveDC(new_gc);
|
int save = SaveDC(new_gc);
|
||||||
SelectObject(new_gc, (HBITMAP)*Fl_Graphics_Driver::id(rgb));
|
SelectObject(new_gc, (HBITMAP)*Fl_Graphics_Driver::id(rgb));
|
||||||
if ( (rgb->d() % 2) == 0 ) {
|
if ( (rgb->d() % 2) == 0 ) {
|
||||||
alpha_blend_(int(XP*scale()), int(YP*scale()), W, H, new_gc, 0, 0, rgb->data_w(), rgb->data_h());
|
alpha_blend_(this->floor(XP), this->floor(YP), W, H, new_gc, 0, 0, rgb->data_w(), rgb->data_h());
|
||||||
} else {
|
} else {
|
||||||
SetStretchBltMode(gc_, HALFTONE);
|
SetStretchBltMode(gc_, HALFTONE);
|
||||||
StretchBlt(gc_, int(XP*scale()), int(YP*scale()), W, H, new_gc, 0, 0, rgb->data_w(), rgb->data_h(), SRCCOPY);
|
StretchBlt(gc_, this->floor(XP), this->floor(YP), W, H, new_gc, 0, 0, rgb->data_w(), rgb->data_h(), SRCCOPY);
|
||||||
}
|
}
|
||||||
RestoreDC(new_gc, save);
|
RestoreDC(new_gc, save);
|
||||||
DeleteDC(new_gc);
|
DeleteDC(new_gc);
|
||||||
@@ -631,10 +631,10 @@ void Fl_GDI_Graphics_Driver::cache(Fl_Bitmap *bm) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Fl_GDI_Graphics_Driver::draw_fixed(Fl_Pixmap *pxm, int X, int Y, int W, int H, int cx, int cy) {
|
void Fl_GDI_Graphics_Driver::draw_fixed(Fl_Pixmap *pxm, int X, int Y, int W, int H, int cx, int cy) {
|
||||||
X = int(X * scale());
|
X = this->floor(X);
|
||||||
Y = int(Y * scale());
|
Y = this->floor(Y);
|
||||||
cache_size(pxm, W, H);
|
cache_size(pxm, W, H);
|
||||||
cx = int(cx * scale()); cy = int(cy * scale());
|
cx = this->floor(cx); cy = this->floor(cy);
|
||||||
Fl_Region r2 = scale_clip(scale());
|
Fl_Region r2 = scale_clip(scale());
|
||||||
if (*Fl_Graphics_Driver::mask(pxm)) {
|
if (*Fl_Graphics_Driver::mask(pxm)) {
|
||||||
HDC new_gc = CreateCompatibleDC(gc_);
|
HDC new_gc = CreateCompatibleDC(gc_);
|
||||||
|
|||||||
@@ -31,47 +31,51 @@
|
|||||||
|
|
||||||
// --- line and polygon drawing with integer coordinates
|
// --- line and polygon drawing with integer coordinates
|
||||||
|
|
||||||
void Fl_GDI_Graphics_Driver::point_unscaled(float fx, float fy) {
|
void Fl_GDI_Graphics_Driver::point(int x, int y) {
|
||||||
int width = (scale() >= 1 ? int(scale()) : 1);
|
rectf(x, y, 1, 1);
|
||||||
RECT rect;
|
|
||||||
rect.left = int(fx); rect.top = int(fy);
|
|
||||||
rect.right = int(fx) + width; rect.bottom = int(fy) + width;
|
|
||||||
FillRect(gc_, &rect, fl_brush());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fl_GDI_Graphics_Driver::overlay_rect(int x, int y, int w , int h) {
|
void Fl_GDI_Graphics_Driver::overlay_rect(int x, int y, int w , int h) {
|
||||||
// make pen have a one-pixel width
|
// make pen have a one-pixel width
|
||||||
line_style_unscaled( (color()==FL_WHITE?FL_SOLID:FL_DOT), 1, NULL);
|
line_style_unscaled( (color()==FL_WHITE?FL_SOLID:FL_DOT), 1, NULL);
|
||||||
loop(x, y, x+w-1, y, x+w-1, y+h-1, x, y+h-1);
|
int right = this->floor(x+w-1), bottom = this->floor(y+h-1);
|
||||||
|
x = this->floor(x); y = this->floor(y);
|
||||||
|
MoveToEx(gc_, x, y, 0L);
|
||||||
|
LineTo(gc_, right, y);
|
||||||
|
LineTo(gc_, right, bottom);
|
||||||
|
LineTo(gc_, x, bottom);
|
||||||
|
LineTo(gc_, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fl_GDI_Graphics_Driver::rect(int x, int y, int w, int h)
|
void Fl_GDI_Graphics_Driver::rect(int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
if (w > 0 && h > 0) {
|
if (w > 0 && h > 0) {
|
||||||
float s = scale();
|
xyline(x, y, (x+w-1));
|
||||||
xyline_unscaled(x*s, y*s, (x+w-1)*s);
|
yxline(x, y, (y+h-1));
|
||||||
yxline_unscaled(x*s, y*s, (y+h-1)*s);
|
yxline((x+w-1), y, (y+h-1));
|
||||||
yxline_unscaled((x+w-1)*s, y*s, (y+h-1)*s);
|
xyline(x, (y+h-1), (x+w-1));
|
||||||
xyline_unscaled(x*s, (y+h-1)*s, (x+w-1)*s);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fl_GDI_Graphics_Driver::focus_rect(int x, int y, int w, int h) {
|
void Fl_GDI_Graphics_Driver::focus_rect(int x, int y, int w, int h) {
|
||||||
// Windows 95/98/ME do not implement the dotted line style, so draw
|
// Windows 95/98/ME do not implement the dotted line style, so draw
|
||||||
// every other pixel around the focus area...
|
// every other pixel around the focus area...
|
||||||
w--; h--;
|
w = floor(x+w-1) - floor(x) + 1;
|
||||||
|
h = floor(y+h-1) - floor(y) + 1;
|
||||||
|
x = floor(x); y = floor(y);
|
||||||
int i=1, xx, yy;
|
int i=1, xx, yy;
|
||||||
for (xx = 0; xx < w; xx++, i++) if (i & 1) point(x + xx, y);
|
COLORREF c = fl_RGB();
|
||||||
for (yy = 0; yy < h; yy++, i++) if (i & 1) point(x + w, y + yy);
|
for (xx = 0; xx < w; xx++, i++) if (i & 1) SetPixel(gc_, x+xx, y, c);
|
||||||
for (xx = w; xx > 0; xx--, i++) if (i & 1) point(x + xx, y + h);
|
for (yy = 0; yy < h; yy++, i++) if (i & 1) SetPixel(gc_, x+w, y+yy, c);
|
||||||
for (yy = h; yy > 0; yy--, i++) if (i & 1) point(x, y + yy);
|
for (xx = w; xx > 0; xx--, i++) if (i & 1) SetPixel(gc_, x+xx, y+h, c);
|
||||||
|
for (yy = h; yy > 0; yy--, i++) if (i & 1) SetPixel(gc_, x, y+yy, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fl_GDI_Graphics_Driver::rectf_unscaled(float x, float y, float w, float h) {
|
void Fl_GDI_Graphics_Driver::rectf(int x, int y, int w, int h) {
|
||||||
if (w<=0 || h<=0) return;
|
if (w<=0 || h<=0) return;
|
||||||
RECT rect;
|
RECT rect;
|
||||||
rect.left = int(x); rect.top = int(y);
|
rect.left = this->floor(x); rect.top = this->floor(y);
|
||||||
rect.right = int(x + w); rect.bottom = int(y + h);
|
rect.right = this->floor(x + w); rect.bottom = this->floor(y + h);
|
||||||
FillRect(gc_, &rect, fl_brush());
|
FillRect(gc_, &rect, fl_brush());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,38 +92,74 @@ void Fl_GDI_Graphics_Driver::line_unscaled(float x, float y, float x1, float y1,
|
|||||||
SetPixel(gc_, int(x2), int(y2), fl_RGB());
|
SetPixel(gc_, int(x2), int(y2), fl_RGB());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fl_GDI_Graphics_Driver::xyline_unscaled(float x, float y, float x1) {
|
static HPEN change_pen_width(int width, HDC gc) { // set the width of the pen, return previous pen
|
||||||
int line_delta_ = (scale() > 1.75 ? 1 : 0);
|
LOGBRUSH penbrush = {BS_SOLID, fl_RGB(), 0};
|
||||||
int tw = line_width_ ? line_width_ : 1; // true line width
|
HPEN newpen = ExtCreatePen(PS_GEOMETRIC | PS_ENDCAP_FLAT | PS_JOIN_ROUND, width, &penbrush, 0, 0);
|
||||||
if (x > x1) { float exch = x; x = x1; x1 = exch; }
|
return (HPEN)SelectObject(gc, newpen);
|
||||||
int ix = int(x) + line_delta_; if (scale() >= 2.f) ix -= int(scale()/2);
|
}
|
||||||
int iy = int(y) + line_delta_;
|
|
||||||
if (scale() > 1.9 && line_width_/scale() >= 2) iy--;
|
void Fl_GDI_Graphics_Driver::xyline(int x, int y, int x1) {
|
||||||
int ix1 = int( int(x1/scale()+1.5f) * scale() ) - 1; // extend line to pixel before line beginning at x1/scale_ + 1
|
if (y < 0) return;
|
||||||
ix1 += line_delta_; if (scale() >= 2) ix1 -= 1;; if (scale() >= 4) ix1 -= 1;
|
float s = scale();
|
||||||
MoveToEx(gc_, ix, iy, 0L); LineTo(gc_, ix1+1, iy);
|
int xx = (x < x1 ? x : x1);
|
||||||
// try and make sure no unfilled area lies between xyline(x,y,x1) and xyline(x,y+1,x1)
|
int xx1 = (x < x1 ? x1 : x);
|
||||||
if (int(scale()) != scale() && y+line_delta_ + scale() >= iy + tw+1 - 0.001 ) {
|
if (s != int(s) && line_width_ <= int(s)) {
|
||||||
MoveToEx(gc_, ix, iy+1, 0L); LineTo(gc_, ix1+1, iy+1);
|
int lwidth = this->floor((y+1)) - this->floor(y);
|
||||||
|
bool need_pen = (lwidth != int(s));
|
||||||
|
HPEN oldpen = (need_pen ? change_pen_width(lwidth, gc_) : NULL);
|
||||||
|
MoveToEx(gc_, this->floor(xx), this->floor(y) + int(lwidth/2.f) , 0L);
|
||||||
|
LineTo(gc_, this->floor((xx1+1)), this->floor(y) + int(lwidth/2.f));
|
||||||
|
if (need_pen) {
|
||||||
|
DeleteObject(SelectObject(gc_, oldpen));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
y = int((y + 0.5f) * s);
|
||||||
|
MoveToEx(gc_, this->floor(xx), y, 0L);
|
||||||
|
LineTo(gc_, this->floor(xx1) + int(s) , y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fl_GDI_Graphics_Driver::yxline_unscaled(float x, float y, float y1) {
|
void Fl_GDI_Graphics_Driver::xyline(int x, int y, int x1, int y2) {
|
||||||
if (y1 < y) { float exch = y; y = y1; y1 = exch;}
|
xyline(x, y, x1);
|
||||||
int line_delta_ = (scale() > 1.75 ? 1 : 0);
|
yxline(x1, y, y2);
|
||||||
int tw = line_width_ ? line_width_ : 1; // true line width
|
}
|
||||||
|
|
||||||
int ix = int(x) + line_delta_;
|
void Fl_GDI_Graphics_Driver::xyline(int x, int y, int x1, int y2, int x3) {
|
||||||
if (scale() > 1.9 && line_width_/scale() >= 2) ix--;
|
xyline(x, y, x1);
|
||||||
int iy = int(y) + line_delta_; if (scale() >= 2) iy -= int(scale()/2);
|
yxline(x1, y, y2);
|
||||||
int iy1 = int( int(y1/scale()+1.5) * scale() ) - 1;
|
xyline(x1, y2, x3);
|
||||||
iy1 += line_delta_; if (scale() >= 2) iy1 -= 1;; if (scale() >= 4) iy1 -= 1; // extend line to pixel before line beginning at y1/scale_ + 1
|
}
|
||||||
MoveToEx(gc_, ix, iy, 0L); LineTo(gc_, ix, iy1+1);
|
|
||||||
// try and make sure no unfilled area lies between yxline(x,y,y1) and yxline(x+1,y,y1)
|
void Fl_GDI_Graphics_Driver::yxline(int x, int y, int y1) {
|
||||||
if (int(scale()) != scale() && x+line_delta_+scale() >= ix + tw+1 -0.001) {
|
if (x < 0) return;
|
||||||
MoveToEx(gc_, ix+1, iy, 0L); LineTo(gc_, ix+1, iy1+1);
|
double s = scale();
|
||||||
|
int yy = (y < y1 ? y : y1);
|
||||||
|
int yy1 = (y < y1 ? y1 : y);
|
||||||
|
if (s != int(s) && line_width_ <= int(s)) {
|
||||||
|
int lwidth = (this->floor((x+1)) - this->floor(x));
|
||||||
|
bool need_pen = (lwidth != int(s));
|
||||||
|
HPEN oldpen = (need_pen ? change_pen_width(lwidth, gc_) : NULL);
|
||||||
|
MoveToEx(gc_, this->floor(x) + int(lwidth/2.f), this->floor(yy), 0L);
|
||||||
|
LineTo(gc_, this->floor(x) + int(lwidth/2.f), this->floor((yy1+1)) );
|
||||||
|
if (need_pen) {
|
||||||
|
DeleteObject(SelectObject(gc_, oldpen));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
x = int((x + 0.5f) * s);
|
||||||
|
MoveToEx(gc_, x, this->floor(yy), 0L);
|
||||||
|
LineTo(gc_, x, this->floor(yy1) + int(s));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Fl_GDI_Graphics_Driver::yxline(int x, int y, int y1, int x2) {
|
||||||
|
yxline(x, y, y1);
|
||||||
|
xyline(x, y1, x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Fl_GDI_Graphics_Driver::yxline(int x, int y, int y1, int x2, int y3) {
|
||||||
|
yxline(x, y, y1);
|
||||||
|
xyline(x, y1, x2);
|
||||||
|
yxline(x2, y1, y3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fl_GDI_Graphics_Driver::loop_unscaled(float x, float y, float x1, float y1, float x2, float y2) {
|
void Fl_GDI_Graphics_Driver::loop_unscaled(float x, float y, float x1, float y1, float x2, float y2) {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
#include "../GDI/Fl_Font.H"
|
#include "../GDI/Fl_Font.H"
|
||||||
#include <FL/Fl.H>
|
#include <FL/Fl.H>
|
||||||
#include <FL/platform.H>
|
#include <FL/platform.H>
|
||||||
#include <FL/Fl_Graphics_Driver.H>
|
#include "../GDI/Fl_GDI_Graphics_Driver.H"
|
||||||
#include <FL/Fl_RGB_Image.H>
|
#include <FL/Fl_RGB_Image.H>
|
||||||
#include <FL/fl_ask.H>
|
#include <FL/fl_ask.H>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -499,14 +499,14 @@ Fl_WinAPI_Screen_Driver::read_win_rectangle(
|
|||||||
{
|
{
|
||||||
float s = Fl_Surface_Device::surface()->driver()->scale();
|
float s = Fl_Surface_Device::surface()->driver()->scale();
|
||||||
int ws, hs;
|
int ws, hs;
|
||||||
if (int(s) == s) { ws = int(w * s); hs = int(h * s);}
|
if (int(s) == s) { ws = w * int(s); hs = h * int(s);}
|
||||||
else {
|
else {
|
||||||
ws = int((w+1) * s); // approximates what Fl_Graphics_Driver::cache_size() does
|
ws = Fl_GDI_Graphics_Driver::floor(w+1, s); // approximates what Fl_Graphics_Driver::cache_size() does
|
||||||
hs = int((h+1) * s);
|
hs = Fl_GDI_Graphics_Driver::floor(h+1, s);
|
||||||
if (ws < 1) ws = 1;
|
if (ws < 1) ws = 1;
|
||||||
if (hs < 1) hs = 1;
|
if (hs < 1) hs = 1;
|
||||||
}
|
}
|
||||||
return read_win_rectangle_unscaled(int(X*s), int(Y*s), ws, hs, win);
|
return read_win_rectangle_unscaled(Fl_GDI_Graphics_Driver::floor(X, s), Fl_GDI_Graphics_Driver::floor(Y, s), ws, hs, win);
|
||||||
}
|
}
|
||||||
|
|
||||||
Fl_RGB_Image *Fl_WinAPI_Screen_Driver::read_win_rectangle_unscaled(int X, int Y, int w, int h, Fl_Window *win)
|
Fl_RGB_Image *Fl_WinAPI_Screen_Driver::read_win_rectangle_unscaled(int X, int Y, int w, int h, Fl_Window *win)
|
||||||
|
|||||||
Reference in New Issue
Block a user