diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Fl_Image.cxx | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/src/Fl_Image.cxx b/src/Fl_Image.cxx index 21a7db2b9..aaa706b08 100644 --- a/src/Fl_Image.cxx +++ b/src/Fl_Image.cxx @@ -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) { |
