On Sat, 09 Apr 2005 10:19:36 +0200, you wrote: > > Are you suggesting more checks then that the pixels are within the > > dimensions of the drawable? > you need at least to use the intersection of the bitmap and the drawable (not > sure both start at (0,0) corner though).
I tried to do this, you need to clip to the visible region as well. I could not get it 100% full proof because of races between the clip calculations and the actual positions on the screen. So I get the pixels now from the root window (clipped to the screen) and everything is rock solid. The code is simpler too. > I was also wondering what would happen when stretching is required, but IIRC > this is done way before (normally) Funny, in my tests StretchDIBits() with such bitmaps leaves black gaps (Wine2K and WinME) as long as you do not do a 1:1 stretch. With 1:1 stretches or using SetDIBitsToDevice I see the behavior as you described. Changelog: dlls/x11drv : dib.c In X11DRV_DIB_SetImageBits avoid BadMatch errors when calling XGetSubImage. Rein.
--- wine/dlls/x11drv/dib.c 2005-04-01 13:32:29.000000000 +0200 +++ mywine/dlls/x11drv/dib.c 2005-04-11 15:33:39.000000000 +0200 @@ -3434,6 +3444,32 @@ static void X11DRV_DIB_GetImageBits_32( } /*********************************************************************** + * X11DRV_DIB_SetImageBits_GetSubImage + * + * Helper for X11DRV_DIB_SetImageBits + */ +static void X11DRV_DIB_SetImageBits_GetSubImage( + const X11DRV_DIB_IMAGEBITS_DESCR *descr, XImage *bmpImage) +{ + /* compressed bitmaps may contain gaps in them. So make a copy + * of the existing pixels first */ + RECT bmprc = { descr->xDest, descr->yDest, + descr->xDest + descr->width , descr->yDest + descr->height}; + RECT rc = { 0, 0, screen_width, screen_height}; + + /* - convert to screen coordinates */ + OffsetRect( &bmprc, descr->physDev->drawable_org.x, + descr->physDev->drawable_org.y); + /* clip to screen rectangle */ + if( IntersectRect( &rc, &rc, &bmprc)) + XGetSubImage( gdi_display, root_window, rc.left, rc.top, + rc.right - rc.left, rc.bottom - rc.top, AllPlanes, + ZPixmap, bmpImage, + descr->xSrc + rc.left - bmprc.left, + descr->ySrc + rc.top - bmprc.top); +} + +/*********************************************************************** * X11DRV_DIB_SetImageBits * * Transfer the bits to an X image. @@ -3475,10 +3511,7 @@ static int X11DRV_DIB_SetImageBits( cons break; case 4: if (descr->compression) { - XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest, - descr->width, descr->height, AllPlanes, ZPixmap, - bmpImage, descr->xSrc, descr->ySrc ); - + X11DRV_DIB_SetImageBits_GetSubImage( descr, bmpImage); X11DRV_DIB_SetImageBits_RLE4( descr->lines, descr->bits, descr->infoWidth, descr->width, descr->xSrc, (int *)(descr->colorMap), @@ -3491,9 +3524,7 @@ static int X11DRV_DIB_SetImageBits( cons break; case 8: if (descr->compression) { - XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest, - descr->width, descr->height, AllPlanes, ZPixmap, - bmpImage, descr->xSrc, descr->ySrc ); + X11DRV_DIB_SetImageBits_GetSubImage( descr, bmpImage); X11DRV_DIB_SetImageBits_RLE8( descr->lines, descr->bits, descr->infoWidth, descr->width, descr->xSrc, (int *)(descr->colorMap),