diff options
| author | Matthias Melcher <fltk@matthiasm.com> | 2008-02-25 15:03:48 +0000 |
|---|---|---|
| committer | Matthias Melcher <fltk@matthiasm.com> | 2008-02-25 15:03:48 +0000 |
| commit | a4c3c685dd41187db4faca7023c2ba43256fa76c (patch) | |
| tree | 26703915b840f8cd7e66a908af169f57b47e7e74 | |
| parent | 5382d3c8d552e4e2e1b245f0c26b5fbd3cd27702 (diff) | |
STR #1716: Fixed image read for partial regions on X11
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.1@6046 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
| -rw-r--r-- | CHANGES | 2 | ||||
| -rw-r--r-- | src/fl_read_image.cxx | 66 |
2 files changed, 68 insertions, 0 deletions
@@ -6,6 +6,8 @@ CHANGES IN FLTK 1.1.8 STR #1742, STR #1777, STR #1794, STR #1827, STR #1843, STR #1796, STR #1815, STR #1726, STR #1753, STR #1855, STR #1862, STR #1867, STR #1874) + - Fixed image read for partial regions on X11 + (STR #1716) - Fixed KDE/Gnome icon paths (STR #1795) - Fixed Tab key to wrap around menu bars (STR #1877) - Fixed possible timer leak in Scrollbar (STR #1880) diff --git a/src/fl_read_image.cxx b/src/fl_read_image.cxx index f0370a9c6..e2d6b61e2 100644 --- a/src/fl_read_image.cxx +++ b/src/fl_read_image.cxx @@ -26,6 +26,7 @@ // #include <FL/x.H> +#include <FL/Fl.H> #include <FL/fl_draw.H> #include "flstring.h" @@ -41,6 +42,8 @@ # include <X11/Xutil.h> # ifdef __sgi # include <X11/extensions/readdisplay.h> +# else +# include <stdlib.h> # endif // __sgi // Defined in fl_color.cxx @@ -48,6 +51,34 @@ extern uchar fl_redmask, fl_greenmask, fl_bluemask; extern int fl_redshift, fl_greenshift, fl_blueshift, fl_extrashift; // +// 'fl_subimage_offsets()' - Calculate subimage offsets for an axis +static inline int +fl_subimage_offsets(int a, int aw, int b, int bw, int &obw) +{ + int off; + int ob; + + if (b >= a) { + ob = b; + off = 0; + } else { + ob = a; + off = a - b; + } + + bw -= off; + + if (ob + bw <= a + aw) { + obw = bw; + } else { + obw = (a + aw) - ob; + } + + return off; +} + + +// // 'fl_read_image()' - Read an image from the current window. // @@ -92,7 +123,42 @@ fl_read_image(uchar *p, // I - Pixel buffer or NULL to allocate # endif // __sgi if (!image) { + // fetch absolute coordinates + int dx, dy; + Window child_win; + XTranslateCoordinates(fl_display, fl_window, + RootWindow(fl_display, fl_screen), X, Y, &dx, &dy, &child_win); + + // screen dimensions + int sx, sy, sw, sh; + Fl::screen_xywh(sx, sy, sw, sh, fl_screen); + + if (dx >= sx && dy >= sy && dx + w <= sw && dy + h <= sh) { + // the image is fully contained, we can use the traditional method image = XGetImage(fl_display, fl_window, X, Y, w, h, AllPlanes, ZPixmap); + } else { + // image is crossing borders, determine visible region + int nw, nh, noffx, noffy; + noffx = fl_subimage_offsets(sx, sw, dx, w, nw); + noffy = fl_subimage_offsets(sy, sh, dy, h, nh); + if (nw <= 0 || nh <= 0) return 0; + + // allocate the image + int bpp = fl_visual->depth + ((fl_visual->depth / 8) % 2) * 8; + char* buf = (char*)malloc(bpp / 8 * w * h); + image = XCreateImage(fl_display, fl_visual->visual, + fl_visual->depth, ZPixmap, 0, buf, w, h, bpp, 0); + if (!image) { + if (buf) free(buf); + return 0; + } + + if (!XGetSubImage(fl_display, fl_window, X + noffx, Y + noffy, + nw, nh, AllPlanes, ZPixmap, image, noffx, noffy)) { + XDestroyImage(image); + return 0; + } + } } if (!image) return 0; |
