Alexandre Julliard : winex11: Fall back to client-side blit for color -> monochrome conversions.
Alexandre Julliard
julliard at winehq.org
Tue Oct 11 14:03:37 CDT 2011
Module: wine
Branch: master
Commit: 40c2f3ff48e959d8269e2ea52b53ee033e493fe9
URL: http://source.winehq.org/git/wine.git/?a=commit;h=40c2f3ff48e959d8269e2ea52b53ee033e493fe9
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Oct 10 18:26:31 2011 +0200
winex11: Fall back to client-side blit for color -> monochrome conversions.
---
dlls/winex11.drv/bitblt.c | 128 ++++++++++++---------------------------------
1 files changed, 34 insertions(+), 94 deletions(-)
diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c
index c0ff7f3..e3703d3 100644
--- a/dlls/winex11.drv/bitblt.c
+++ b/dlls/winex11.drv/bitblt.c
@@ -582,21 +582,6 @@ int main()
#endif /* BITBLT_TEST */
-/* return a mask for meaningful bits when doing an XGetPixel on an image */
-static unsigned long image_pixel_mask( X11DRV_PDEVICE *physDev )
-{
- unsigned long ret;
- ColorShifts *shifts = physDev->color_shifts;
-
- if (!shifts) shifts = &X11DRV_PALETTE_default_shifts;
- ret = (shifts->physicalRed.max << shifts->physicalRed.shift) |
- (shifts->physicalGreen.max << shifts->physicalGreen.shift) |
- (shifts->physicalBlue.max << shifts->physicalBlue.shift);
- if (!ret) ret = (1 << physDev->depth) - 1;
- return ret;
-}
-
-
/***********************************************************************
* BITBLT_GetSrcArea
*
@@ -606,40 +591,49 @@ static unsigned long image_pixel_mask( X11DRV_PDEVICE *physDev )
static int BITBLT_GetSrcArea( X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst,
Pixmap pixmap, GC gc, RECT *visRectSrc )
{
- XImage *imageSrc, *imageDst;
+ XImage *imageSrc;
register INT x, y;
int exposures = 0;
INT width = visRectSrc->right - visRectSrc->left;
INT height = visRectSrc->bottom - visRectSrc->top;
BOOL memdc = (GetObjectType(physDevSrc->dev.hdc) == OBJ_MEMDC);
- if (physDevSrc->depth == physDevDst->depth)
+ if (physDevSrc->depth == 1)
{
+ /* MSDN says if StretchBlt must convert a bitmap from monochrome
+ to color or vice versa, the foreground and background color of
+ the device context are used. In fact, it also applies to the
+ case when it is converted from mono to mono. */
wine_tsx11_lock();
- if (!X11DRV_PALETTE_XPixelToPalette ||
- (physDevDst->depth == 1)) /* monochrome -> monochrome */
+ if (X11DRV_PALETTE_XPixelToPalette && physDevDst->depth != 1)
{
- if (physDevDst->depth == 1)
- {
- /* MSDN says if StretchBlt must convert a bitmap from monochrome
- to color or vice versa, the foreground and background color of
- the device context are used. In fact, it also applies to the
- case when it is converted from mono to mono. */
- XSetBackground( gdi_display, gc, physDevDst->textPixel );
- XSetForeground( gdi_display, gc, physDevDst->backgroundPixel );
- XCopyPlane( gdi_display, physDevSrc->drawable, pixmap, gc,
- physDevSrc->dc_rect.left + visRectSrc->left,
- physDevSrc->dc_rect.top + visRectSrc->top,
- width, height, 0, 0, 1);
- }
- else
- XCopyArea( gdi_display, physDevSrc->drawable, pixmap, gc,
- physDevSrc->dc_rect.left + visRectSrc->left,
- physDevSrc->dc_rect.top + visRectSrc->top,
- width, height, 0, 0);
+ XSetBackground( gdi_display, gc, X11DRV_PALETTE_XPixelToPalette[physDevDst->textPixel] );
+ XSetForeground( gdi_display, gc, X11DRV_PALETTE_XPixelToPalette[physDevDst->backgroundPixel]);
+ }
+ else
+ {
+ XSetBackground( gdi_display, gc, physDevDst->textPixel );
+ XSetForeground( gdi_display, gc, physDevDst->backgroundPixel );
+ }
+ XCopyPlane( gdi_display, physDevSrc->drawable, pixmap, gc,
+ physDevSrc->dc_rect.left + visRectSrc->left,
+ physDevSrc->dc_rect.top + visRectSrc->top,
+ width, height, 0, 0, 1 );
+ exposures++;
+ wine_tsx11_unlock();
+ }
+ else /* color -> color */
+ {
+ wine_tsx11_lock();
+ if (!X11DRV_PALETTE_XPixelToPalette)
+ {
+ XCopyArea( gdi_display, physDevSrc->drawable, pixmap, gc,
+ physDevSrc->dc_rect.left + visRectSrc->left,
+ physDevSrc->dc_rect.top + visRectSrc->top,
+ width, height, 0, 0);
exposures++;
}
- else /* color -> color */
+ else
{
if (memdc)
imageSrc = XGetImage( gdi_display, physDevSrc->drawable,
@@ -667,61 +661,6 @@ static int BITBLT_GetSrcArea( X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDe
}
wine_tsx11_unlock();
}
- else
- {
- if (physDevSrc->depth == 1) /* monochrome -> color */
- {
- wine_tsx11_lock();
- if (X11DRV_PALETTE_XPixelToPalette)
- {
- XSetBackground( gdi_display, gc, X11DRV_PALETTE_XPixelToPalette[physDevDst->textPixel] );
- XSetForeground( gdi_display, gc, X11DRV_PALETTE_XPixelToPalette[physDevDst->backgroundPixel]);
- }
- else
- {
- XSetBackground( gdi_display, gc, physDevDst->textPixel );
- XSetForeground( gdi_display, gc, physDevDst->backgroundPixel );
- }
- XCopyPlane( gdi_display, physDevSrc->drawable, pixmap, gc,
- physDevSrc->dc_rect.left + visRectSrc->left,
- physDevSrc->dc_rect.top + visRectSrc->top,
- width, height, 0, 0, 1 );
- exposures++;
- wine_tsx11_unlock();
- }
- else /* color -> monochrome */
- {
- unsigned long pixel_mask;
- wine_tsx11_lock();
- /* FIXME: avoid BadMatch error */
- imageSrc = XGetImage( gdi_display, physDevSrc->drawable,
- physDevSrc->dc_rect.left + visRectSrc->left,
- physDevSrc->dc_rect.top + visRectSrc->top,
- width, height, AllPlanes, ZPixmap );
- if (!imageSrc)
- {
- wine_tsx11_unlock();
- return exposures;
- }
- imageDst = X11DRV_DIB_CreateXImage( width, height, physDevDst->depth );
- if (!imageDst)
- {
- XDestroyImage(imageSrc);
- wine_tsx11_unlock();
- return exposures;
- }
- pixel_mask = image_pixel_mask( physDevSrc );
- for (y = 0; y < height; y++)
- for (x = 0; x < width; x++)
- XPutPixel(imageDst, x, y,
- !((XGetPixel(imageSrc,x,y) ^ physDevSrc->backgroundPixel) & pixel_mask));
- XPutImage( gdi_display, pixmap, gc, imageDst,
- 0, 0, 0, 0, width, height );
- XDestroyImage( imageSrc );
- X11DRV_DIB_DestroyXImage( imageDst );
- wine_tsx11_unlock();
- }
- }
return exposures;
}
@@ -960,7 +899,8 @@ BOOL X11DRV_StretchBlt( PHYSDEV dst_dev, struct bitblt_coords *dst,
GC tmpGC;
if (src_dev->funcs != dst_dev->funcs ||
- src->width != dst->width || src->height != dst->height) /* no stretching with core X11 */
+ src->width != dst->width || src->height != dst->height || /* no stretching with core X11 */
+ (physDevDst->depth == 1 && physDevSrc->depth != 1)) /* color -> mono done by hand */
{
dst_dev = GET_NEXT_PHYSDEV( dst_dev, pStretchBlt );
return dst_dev->funcs->pStretchBlt( dst_dev, dst, src_dev, src, rop );
More information about the wine-cvs
mailing list