do clipping prior to XGetImage, just in case the image would extend beyond the screen's bounds

This commit is contained in:
Brian Paul 2004-11-09 01:20:57 +00:00
parent 2a10ad16a6
commit b12594d2a0
1 changed files with 53 additions and 1 deletions

View File

@ -3456,6 +3456,47 @@ static void write_pixels_index_ximage( INDEX_PIXELS_ARGS )
/***** Pixel reading *****/
/**********************************************************************/
#ifndef XFree86Server
/**
* Do clip testing prior to calling XGetImage. If any of the region lies
* outside the screen's bounds, XGetImage will return NULL.
* We use XTranslateCoordinates() to check if that's the case and
* adjust the x, y and length parameters accordingly.
* \return -1 if span is totally clipped away,
* else return number of pixels to skip in the destination array.
*/
static int
clip_for_xgetimage(XMesaContext xmesa, GLuint *n, GLint *x, GLint *y)
{
XMesaBuffer source = xmesa->xm_buffer;
Window rootWin = RootWindow(xmesa->display, 0);
Window child;
int screenWidth = WidthOfScreen(DefaultScreenOfDisplay(xmesa->display));
int dx, dy;
XTranslateCoordinates(xmesa->display, source->buffer, rootWin,
*x, *y, &dx, &dy, &child);
if (dx >= screenWidth) {
/* totally clipped on right */
return -1;
}
if (dx < 0) {
/* clipped on left */
int clip = -dx;
if (clip >= *n)
return -1; /* totally clipped on left */
*x += clip;
*n -= clip;
dx = 0;
return clip;
}
if (dx + *n > screenWidth) {
/* clipped on right */
int clip = dx + *n - screenWidth;
*n -= clip;
}
return 0;
}
#endif
/*
@ -3474,6 +3515,11 @@ static void read_index_span( const GLcontext *ctx,
#ifndef XFree86Server
XMesaImage *span = NULL;
int error;
int k = clip_for_xgetimage(xmesa, &n, &x, &y);
if (k < 0)
return;
index += k;
catch_xgetimage_errors( xmesa->display );
span = XGetImage( xmesa->display, source->buffer,
x, y, n, 1, AllPlanes, ZPixmap );
@ -3530,9 +3576,15 @@ static void read_color_span( const GLcontext *ctx,
x, FLIP(source, y), n, 1, ZPixmap,
~0L, (pointer)span->data);
#else
int k;
y = FLIP(source, y);
k = clip_for_xgetimage(xmesa, &n, &x, &y);
if (k < 0)
return;
rgba += k;
catch_xgetimage_errors( xmesa->display );
span = XGetImage( xmesa->display, source->buffer,
x, FLIP(source, y), n, 1, AllPlanes, ZPixmap );
x, y, n, 1, AllPlanes, ZPixmap );
error = check_xgetimage_errors();
#endif
if (span && !error) {