Fix: Rounding issues with Fl_RGB_Image::draw() + window scaling (#1128)

This commit is contained in:
ManoloFLTK 2024-11-18 17:20:36 +01:00
parent d547e19567
commit 2cd0ec7e33

View File

@ -709,8 +709,38 @@ void Fl_RGB_Image::desaturate() {
d(new_d);
}
#define fl_max(a,b) ((a) > (b) ? (a) : (b))
#define fl_min(a,b) ((a) < (b) ? (a) : (b))
typedef struct {int x; int y; int width; int height;} rectangle_int_t;
static void crect_intersect(rectangle_int_t *to, rectangle_int_t *with) {
int x = fl_max(to->x, with->x);
to->width = fl_min(to->x + to->width, with->x + with->width) - x;
if (to->width < 0) to->width = 0;
int y = fl_max(to->y, with->y);
to->height = fl_min(to->y + to->height, with->y + with->height) - y;
if (to->height < 0) to->height = 0;
to->x = x;
to->y = y;
}
void Fl_RGB_Image::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
fl_graphics_driver->draw_rgb(this, XP, YP, WP, HP, cx, cy);
float s = fl_graphics_driver->scale();
if (s != int(s) && (cx || cy || WP != w() || HP != h())) {
// See issue #1128: clipping to a part of the image while the scaling
// has a fractional value creates problems
rectangle_int_t r1 = { XP-cx, YP-cy, w(), h() };
rectangle_int_t r2 = { XP, YP, WP, HP };
crect_intersect(&r1, &r2);
// After this, r1.x,r1.y = position of top-left of drawn image part;
// r1.width,r1.height = size of drawn image part, in FLTK units;
// fl_max(cx, 0),fl_max(cy, 0) = top-left of drawn part in image.
int l = (ld() ? ld() : d() * w());
const uchar *p = array + fl_max(cy, 0) * l + fl_max(cx, 0) * d();
fl_graphics_driver->draw_image(p, XP, YP, WP, HP, d(), l);
} else
fl_graphics_driver->draw_rgb(this, XP, YP, WP, HP, cx, cy);
}
void Fl_RGB_Image::label(Fl_Widget* widget) {