do clipping prior to XGetImage, just in case the image would extend beyond the screen's bounds
This commit is contained in:
parent
2a10ad16a6
commit
b12594d2a0
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue