From 957fa1fe3751a10478d4ce4c5971d9d9dd17966d Mon Sep 17 00:00:00 2001 From: ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> Date: Tue, 15 Oct 2024 18:02:48 +0200 Subject: [PATCH] Improve method to draw boxes of type FL_BORDER_BOX and FL_SHADOW_BOX (#1089) These types of boxes frame a background with a rectangular frame of another color. The previous procedure to draw them was not robust to GUI rescaling creating cases where space between the border and the background was not drawn. The new drawing procedure for these boxes first paints the whole area (frame included) with the background color and next draws the frame over the just painted rectangle. No uncolored space is possible. It was also necessary to very slightly modify Fl_Scalable_Graphics_Driver::rect() used by the Windows and X11 (no Cairo) backends to make sure fl_rect(x,y,w,h) exactly frames fl_rectf(x,y,w,h) without drawing outside the filled area. --- src/Fl_Graphics_Driver.cxx | 9 +++++---- src/fl_boxtype.cxx | 7 +++++-- src/fl_shadow_box.cxx | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Fl_Graphics_Driver.cxx b/src/Fl_Graphics_Driver.cxx index 5af14a2c2..50889bccf 100644 --- a/src/Fl_Graphics_Driver.cxx +++ b/src/Fl_Graphics_Driver.cxx @@ -751,10 +751,11 @@ Fl_Scalable_Graphics_Driver::Fl_Scalable_Graphics_Driver() : Fl_Graphics_Driver( void Fl_Scalable_Graphics_Driver::rect(int x, int y, int w, int h) { if (w > 0 && h > 0) { - int s = (int)scale()/2; - rect_unscaled(this->floor(x) + s, this->floor(y) + s, - this->floor(x + w - 1) - this->floor(x), - this->floor(y + h - 1) - this->floor(y)); + int s = (int)scale(); + int d = s / 2; + rect_unscaled(this->floor(x) + d, this->floor(y) + d, + this->floor(x + w) - this->floor(x) - s, + this->floor(y + h) - this->floor(y) - s); } } diff --git a/src/fl_boxtype.cxx b/src/fl_boxtype.cxx index ea8571b93..a78c74b4a 100644 --- a/src/fl_boxtype.cxx +++ b/src/fl_boxtype.cxx @@ -267,10 +267,13 @@ void fl_embossed_box(int x, int y, int w, int h, Fl_Color c) { Equivalent to drawing a box of type FL_BORDER_BOX. */ void fl_rectbound(int x, int y, int w, int h, Fl_Color bgcolor) { + // New algorithm (see Discussion #1089): + // 1) draw with adequate bg color a filled rectangle that covers also the rectangle border + // 2) draw with adequate border color the rectangle border overwriting what was drawn at 1) + Fl::set_box_color(bgcolor); + fl_rectf(x, y, w, h); Fl::set_box_color(FL_BLACK); fl_rect(x, y, w, h); - Fl::set_box_color(bgcolor); - fl_rectf(x+1, y+1, w-2, h-2); } #define fl_border_box fl_rectbound /**< allow consistent naming */ diff --git a/src/fl_shadow_box.cxx b/src/fl_shadow_box.cxx index 57b0cf048..16d874afc 100644 --- a/src/fl_shadow_box.cxx +++ b/src/fl_shadow_box.cxx @@ -32,7 +32,7 @@ static void fl_shadow_frame(int x, int y, int w, int h, Fl_Color c) { static void fl_shadow_box(int x, int y, int w, int h, Fl_Color c) { Fl::set_box_color(c); - fl_rectf(x+1,y+1,w-2-BW,h-2-BW); + fl_rectf(x,y,w-BW,h-BW); fl_shadow_frame(x,y,w,h,FL_GRAY0); }