summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthias Melcher <fltk@matthiasm.com>2008-02-25 15:03:48 +0000
committerMatthias Melcher <fltk@matthiasm.com>2008-02-25 15:03:48 +0000
commita4c3c685dd41187db4faca7023c2ba43256fa76c (patch)
tree26703915b840f8cd7e66a908af169f57b47e7e74 /src
parent5382d3c8d552e4e2e1b245f0c26b5fbd3cd27702 (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
Diffstat (limited to 'src')
-rw-r--r--src/fl_read_image.cxx66
1 files changed, 66 insertions, 0 deletions
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;