mirror of
https://github.com/fltk/fltk.git
synced 2026-05-26 10:07:06 +08:00
WIN32 platform: more progress for full HiDPI support
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12273 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
@@ -55,6 +55,9 @@ extern FL_EXPORT struct Fl_XMap {
|
||||
COLORREF rgb; // this should be the type the RGB() macro returns
|
||||
HPEN pen; // pen, 0 if none created yet
|
||||
int brush; // ref to solid brush, 0 if none created yet
|
||||
#ifdef FLTK_HIDPI_SUPPORT
|
||||
int pwidth; // the width of the pen, if present
|
||||
#endif
|
||||
} *fl_current_xmap;
|
||||
inline COLORREF fl_RGB() {return fl_current_xmap->rgb;}
|
||||
inline HPEN fl_pen() {return fl_current_xmap->pen;}
|
||||
|
||||
+4
-4
@@ -491,7 +491,7 @@ int Fl_WinAPI_Screen_Driver::ready() {
|
||||
return get_wsock_mod() ? s_wsock_select(0,&fdt[0],&fdt[1],&fdt[2],&t) : 0;
|
||||
}
|
||||
|
||||
//FILE *LOG=fopen("log.log","w");
|
||||
//extern FILE*LOG;
|
||||
|
||||
void Fl_WinAPI_Screen_Driver::open_display_platform() {
|
||||
static char beenHereDoneThat = 0;
|
||||
@@ -1158,7 +1158,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
|
||||
}
|
||||
|
||||
// convert i->region in FLTK units to R2 in drawing units
|
||||
R2 = Fl_GDI_Graphics_Driver::scale_region(i->region, scale, NULL, false);
|
||||
R2 = Fl_GDI_Graphics_Driver::scale_region(i->region, scale, NULL);
|
||||
|
||||
if (R2) {
|
||||
// Also tell WIN32 that we are drawing someplace else as well...
|
||||
@@ -1173,7 +1173,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
|
||||
}
|
||||
|
||||
// convert R2 in drawing units to i->region in FLTK units
|
||||
i->region = Fl_GDI_Graphics_Driver::scale_region(R2, 1/scale, NULL, false /*, true*/);
|
||||
i->region = Fl_GDI_Graphics_Driver::scale_region(R2, 1/scale, NULL);
|
||||
|
||||
window->clear_damage((uchar)(window->damage()|FL_DAMAGE_EXPOSE));
|
||||
// These next two statements should not be here, so that all update
|
||||
@@ -1433,7 +1433,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
|
||||
Fl::handle(FL_SHOW, window);
|
||||
resize_bug_fix = window;
|
||||
window->size( ceil(LOWORD(lParam)/scale), ceil(HIWORD(lParam)/scale) );
|
||||
//fprintf(LOG,"WM_SIZE parent size(%d,%d) s=%.2f\n",int(LOWORD(lParam)/scale),int(HIWORD(lParam)/scale),scale);
|
||||
//fprintf(LOG,"WM_SIZE size(%.0f,%.0f) graph(%d,%d) s=%.2f\n",ceil(LOWORD(lParam)/scale),ceil(HIWORD(lParam)/scale),LOWORD(lParam),HIWORD(lParam),scale);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -89,7 +89,7 @@ public:
|
||||
void XDestroyRegion(Fl_Region r);
|
||||
void translate_all(int x, int y);
|
||||
void untranslate_all(void);
|
||||
static HRGN scale_region(HRGN r, float f, Fl_GDI_Graphics_Driver *dr, bool keep/*, bool inflate=false*/);
|
||||
static HRGN scale_region(HRGN r, float f, Fl_GDI_Graphics_Driver *dr);
|
||||
virtual void scale(float f);
|
||||
virtual float scale();
|
||||
protected:
|
||||
|
||||
@@ -232,7 +232,7 @@ void Fl_GDI_Graphics_Driver::scale(float f) {
|
||||
if (f != scale_) {
|
||||
size_ = 0;
|
||||
scale_ = f;
|
||||
//line_style(FL_SOLID); // scale also default line width
|
||||
//fprintf(LOG,"set scale to %f\n",f);fflush(LOG);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,45 +242,35 @@ float Fl_GDI_Graphics_Driver::scale() {
|
||||
|
||||
|
||||
/* 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.
|
||||
The input region is deleted if dr is null.
|
||||
*/
|
||||
HRGN Fl_GDI_Graphics_Driver::scale_region(HRGN r, float f, Fl_GDI_Graphics_Driver *dr, bool keep/*, bool inflate*/) {
|
||||
HRGN Fl_GDI_Graphics_Driver::scale_region(HRGN r, float f, Fl_GDI_Graphics_Driver *dr) {
|
||||
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) { // seems no longer useful
|
||||
RECT *rects = (RECT*)&(pdata->Buffer);
|
||||
for (DWORD i = 0; i < pdata->rdh.nCount; i++) {
|
||||
InflateRect(rects+i, 1, 1);
|
||||
}
|
||||
}*/
|
||||
if (!dr) DeleteObject(r);
|
||||
POINT pt = {0, 0};
|
||||
if (dr && dr->depth >= 1) { // account for both scaling and translation
|
||||
if (dr && dr->depth >= 1) { // account for translation
|
||||
GetWindowOrgEx((HDC)dr->gc(), &pt);
|
||||
pt.x *= (f - 1);
|
||||
pt.y *= (f - 1);
|
||||
}
|
||||
XFORM xform = {f, 0, 0, f, (FLOAT)pt.x , (FLOAT)pt.y};
|
||||
r = ExtCreateRegion(&xform, size, pdata);
|
||||
free(pdata);
|
||||
|
||||
if (dr && int(f) != f && f > 1) { // needed for clean checkers demo
|
||||
DWORD size = GetRegionData(r, 0, NULL);
|
||||
RGNDATA *pdata = (RGNDATA*)malloc(size);
|
||||
GetRegionData(r, size, pdata);
|
||||
DeleteObject(r);
|
||||
RECT *rects = (RECT*)&(pdata->Buffer);
|
||||
for (DWORD i = 0; i < pdata->rdh.nCount; i++) {
|
||||
InflateRect(rects+i, 1, 1);
|
||||
}
|
||||
r = ExtCreateRegion(NULL, size, pdata);
|
||||
free(pdata);
|
||||
RECT *rects = (RECT*)&(pdata->Buffer);
|
||||
int delta = (f > 1.75 ? 1 : 0) - int(f/2);
|
||||
for (DWORD i = 0; i < pdata->rdh.nCount; i++) {
|
||||
int x = rects[i].left * f + pt.x;
|
||||
int y = rects[i].top * f + pt.y;
|
||||
RECT R2;
|
||||
R2.left = x + delta;
|
||||
R2.top = y + delta;
|
||||
R2.right = int(rects[i].right * f) + pt.x - x + R2.left;
|
||||
R2.bottom = int(rects[i].bottom * f) + pt.y - y + R2.top;
|
||||
rects[i] = R2;
|
||||
}
|
||||
|
||||
r = ExtCreateRegion(NULL, size, pdata);
|
||||
free(pdata);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@@ -288,7 +278,7 @@ HRGN Fl_GDI_Graphics_Driver::scale_region(HRGN r, float f, Fl_GDI_Graphics_Drive
|
||||
|
||||
Fl_Region Fl_GDI_Graphics_Driver::scale_clip(float f) {
|
||||
HRGN r = rstack[rstackptr];
|
||||
HRGN r2 = scale_region(r, f, this, true);
|
||||
HRGN r2 = scale_region(r, f, this);
|
||||
return (r == r2 ? NULL : (rstack[rstackptr] = r2, r));
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ static void clear_xmap(Fl_XMap& xmap) {
|
||||
}
|
||||
}
|
||||
|
||||
static void set_xmap(Fl_XMap& xmap, COLORREF c) {
|
||||
static void set_xmap(Fl_XMap& xmap, COLORREF c, int lw) {
|
||||
xmap.rgb = c;
|
||||
if (xmap.pen) {
|
||||
HDC gc = (HDC)fl_graphics_driver->gc();
|
||||
@@ -83,7 +83,12 @@ static void set_xmap(Fl_XMap& xmap, COLORREF c) {
|
||||
if (oldpen != xmap.pen)SelectObject(gc,oldpen); // if old one not xmap.pen, need to put it back
|
||||
DeleteObject(xmap.pen); // delete pen
|
||||
}
|
||||
xmap.pen = CreatePen(PS_SOLID, 1, xmap.rgb); // get a pen into xmap.pen
|
||||
// xmap.pen = CreatePen(PS_SOLID, 1, xmap.rgb); // get a pen into xmap.pen
|
||||
LOGBRUSH penbrush = {BS_SOLID, xmap.rgb, 0};
|
||||
xmap.pen = ExtCreatePen(PS_GEOMETRIC | PS_ENDCAP_FLAT | PS_JOIN_ROUND, lw, &penbrush, 0, 0);
|
||||
#ifdef FLTK_HIDPI_SUPPORT
|
||||
xmap.pwidth = lw;
|
||||
#endif
|
||||
xmap.brush = -1;
|
||||
}
|
||||
|
||||
@@ -94,14 +99,19 @@ void Fl_GDI_Graphics_Driver::color(Fl_Color i) {
|
||||
} else {
|
||||
Fl_Graphics_Driver::color(i);
|
||||
Fl_XMap &xmap = fl_xmap[i];
|
||||
if (!xmap.pen) {
|
||||
int tw = line_width_ ? line_width_ : int(scale_); if (!tw) tw = 1;
|
||||
if (!xmap.pen
|
||||
#ifdef FLTK_HIDPI_SUPPORT
|
||||
|| xmap.pwidth != tw
|
||||
#endif
|
||||
) {
|
||||
#if USE_COLORMAP
|
||||
if (fl_palette) {
|
||||
set_xmap(xmap, PALETTEINDEX(i));
|
||||
set_xmap(xmap, PALETTEINDEX(i), tw);
|
||||
} else {
|
||||
#endif
|
||||
unsigned c = fl_cmap[i];
|
||||
set_xmap(xmap, RGB(uchar(c>>24), uchar(c>>16), uchar(c>>8)));
|
||||
set_xmap(xmap, RGB(uchar(c>>24), uchar(c>>16), uchar(c>>8)), tw);
|
||||
#if USE_COLORMAP
|
||||
}
|
||||
#endif
|
||||
@@ -115,9 +125,14 @@ void Fl_GDI_Graphics_Driver::color(uchar r, uchar g, uchar b) {
|
||||
static Fl_XMap xmap;
|
||||
COLORREF c = RGB(r,g,b);
|
||||
Fl_Graphics_Driver::color( fl_rgb_color(r, g, b) );
|
||||
if (!xmap.pen || c != xmap.rgb) {
|
||||
int tw = line_width_ ? line_width_ : int(scale_); if (!tw) tw = 1;
|
||||
if (!xmap.pen || c != xmap.rgb
|
||||
#ifdef FLTK_HIDPI_SUPPORT
|
||||
|| tw != xmap.pwidth
|
||||
#endif
|
||||
) {
|
||||
clear_xmap(xmap);
|
||||
set_xmap(xmap, c);
|
||||
set_xmap(xmap, c, tw);
|
||||
}
|
||||
fl_current_xmap = ⟼
|
||||
SelectObject(gc_, (HGDIOBJ)(xmap.pen));
|
||||
|
||||
@@ -50,9 +50,11 @@ void Fl_GDI_Graphics_Driver::line_style_unscaled(int style, float width, char* d
|
||||
} else {
|
||||
s1 |= style & 0xff; // allow them to pass any low 8 bits for style
|
||||
}
|
||||
if ((style || n) && !width) width = 1; // fix cards that do nothing for 0?
|
||||
if ((style || n) && !width) width = scale_; // fix cards that do nothing for 0?
|
||||
if (!fl_current_xmap) color(FL_BLACK);
|
||||
LOGBRUSH penbrush = {BS_SOLID,fl_RGB(),0}; // can this be fl_brush()?
|
||||
HPEN newpen = ExtCreatePen(s1, width, &penbrush, n, n ? a : 0);
|
||||
int tw = width < 1? 1: width;
|
||||
HPEN newpen = ExtCreatePen(s1, tw, &penbrush, n, n ? a : 0);
|
||||
if (!newpen) {
|
||||
Fl::error("fl_line_style(): Could not create GDI pen object.");
|
||||
return;
|
||||
|
||||
@@ -41,10 +41,13 @@ void Fl_GDI_Graphics_Driver::point_unscaled(float x, float y) {
|
||||
|
||||
void Fl_GDI_Graphics_Driver::rect_unscaled(float x, float y, float w, float h) {
|
||||
if (w<=0 || h<=0) return;
|
||||
int line_delta_ = (scale_ > 1.75 ? 1 : 0);//TMP
|
||||
x += line_delta_; y += line_delta_;
|
||||
int tw = line_width_ ? line_width_ : 1; // true line width
|
||||
MoveToEx(gc_, x, y, 0L);
|
||||
LineTo(gc_, x+w-1, y);
|
||||
LineTo(gc_, x+w-1, y+h-1);
|
||||
LineTo(gc_, x, y+h-1);
|
||||
LineTo(gc_, x+w-tw, y);
|
||||
LineTo(gc_, x+w-tw, y+h-tw);
|
||||
LineTo(gc_, x, y+h-tw);
|
||||
LineTo(gc_, x, y);
|
||||
}
|
||||
|
||||
@@ -80,16 +83,31 @@ void Fl_GDI_Graphics_Driver::line_unscaled(float x, float y, float x1, float y1,
|
||||
SetPixel(gc_, x2, y2, fl_RGB());
|
||||
}
|
||||
|
||||
//extern FILE*LOG;
|
||||
void Fl_GDI_Graphics_Driver::xyline_unscaled(float x, float y, float x1) {
|
||||
MoveToEx(gc_, x, y, 0L); LineTo(gc_, x1+1, y);
|
||||
int line_delta_ = (scale_ > 1.75 ? 1 : 0);
|
||||
int tw = line_width_ ? line_width_ : 1; // true line width
|
||||
if (x > x1) { float exch = x; x = x1; x1 = exch; }
|
||||
int ix = x+line_delta_; if (scale_ >= 2) ix -= int(scale_/2);
|
||||
int iy = y+line_delta_;
|
||||
int ix1 = int(x1/scale_+1.5)*scale_-1; // extend line to pixel before line beginning at x1/scale_ + 1
|
||||
ix1 += line_delta_; if (scale_ >= 2) ix1 -= 1;; if (scale_ >= 4) ix1 -= 1;
|
||||
MoveToEx(gc_, ix, iy, 0L); LineTo(gc_, ix1+1, iy);
|
||||
// try and make sure no unfilled area lies between xyline(x,y,x1) and xyline(x,y+1,x1)
|
||||
if (int(scale_) != scale_ && y+line_delta_ + scale_ >= iy + tw+1 - 0.001 ) {
|
||||
MoveToEx(gc_, ix, iy+1, 0L); LineTo(gc_, ix1+1, iy+1);
|
||||
}
|
||||
//fprintf(LOG,"xyline_unscaled tw=%d s=%f gc_=%p\n",tw,scale_,gc_);fflush(LOG);
|
||||
}
|
||||
|
||||
void Fl_GDI_Graphics_Driver::xyline_unscaled(float x, float y, float x1, float y2) {
|
||||
if (y2 < y) y2--;
|
||||
/*if (y2 < y) y2--;
|
||||
else y2++;
|
||||
MoveToEx(gc_, x, y, 0L);
|
||||
LineTo(gc_, x1, y);
|
||||
LineTo(gc_, x1, y2);
|
||||
LineTo(gc_, x1, y2);*/
|
||||
xyline_unscaled(x, y, x1);
|
||||
yxline_unscaled(x1, y, y2);
|
||||
}
|
||||
|
||||
void Fl_GDI_Graphics_Driver::xyline_unscaled(float x, float y, float x1, float y2, float x3) {
|
||||
@@ -102,17 +120,30 @@ void Fl_GDI_Graphics_Driver::xyline_unscaled(float x, float y, float x1, float y
|
||||
}
|
||||
|
||||
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);
|
||||
if (y1 < y) { float exch = y; y = y1; y1 = exch;}
|
||||
int line_delta_ = (scale_ > 1.75 ? 1 : 0);
|
||||
int tw = line_width_ ? line_width_ : 1; // true line width
|
||||
|
||||
int ix = x+line_delta_;
|
||||
int iy = y+line_delta_; if (scale_ >= 2) iy -= int(scale_/2);
|
||||
int iy1 = int(y1/scale_+1.5)*scale_-1;
|
||||
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)
|
||||
if (int(scale_) != scale_ && x+line_delta_+scale_ >= ix + tw+1 -0.001) {
|
||||
MoveToEx(gc_, ix+1, iy, 0L); LineTo(gc_, ix+1, iy1+1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Fl_GDI_Graphics_Driver::yxline_unscaled(float x, float y, float y1, float x2) {
|
||||
if (x2 > x) x2++;
|
||||
/*if (x2 > x) x2++;
|
||||
else x2--;
|
||||
MoveToEx(gc_, x, y, 0L);
|
||||
LineTo(gc_, x, y1);
|
||||
LineTo(gc_, x2, y1);
|
||||
LineTo(gc_, x2, y1);*/
|
||||
yxline_unscaled(x, y, y1);
|
||||
xyline_unscaled(x, y1, x2);
|
||||
}
|
||||
|
||||
void Fl_GDI_Graphics_Driver::yxline_unscaled(float x, float y, float y1, float x2, float y3) {
|
||||
|
||||
@@ -389,7 +389,8 @@ void Fl_WinAPI_Window_Driver::make_current() {
|
||||
#endif // USE_COLORMAP
|
||||
|
||||
fl_graphics_driver->clip_region(0);
|
||||
fl_graphics_driver->scale(Fl::screen_driver()->scale(0));
|
||||
fl_graphics_driver->scale(Fl::screen_driver()->scale(0));
|
||||
fl_graphics_driver->line_style(FL_SOLID); // scale also default line width
|
||||
}
|
||||
|
||||
void Fl_WinAPI_Window_Driver::label(const char *name,const char *iname) {
|
||||
|
||||
Reference in New Issue
Block a user