Module: wine Branch: master Commit: efa37f56ec51e76c1127c3f1b0cb8ef9d75d3112 URL: http://source.winehq.org/git/wine.git/?a=commit;h=efa37f56ec51e76c1127c3f1b0...
Author: Roderick Colenbrander thunderbird2k@gmail.com Date: Thu Sep 10 10:41:51 2009 +0200
winex11: Add helper function for copying brushes.
---
dlls/winex11.drv/brush.c | 11 ++++------- dlls/winex11.drv/x11drv.h | 1 + dlls/winex11.drv/xrender.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 7 deletions(-)
diff --git a/dlls/winex11.drv/brush.c b/dlls/winex11.drv/brush.c index c94e04e..372cb13 100644 --- a/dlls/winex11.drv/brush.c +++ b/dlls/winex11.drv/brush.c @@ -215,25 +215,22 @@ static BOOL BRUSH_SelectPatternBrush( X11DRV_PDEVICE *physDev, HBITMAP hbitmap )
if (!physBitmap || !GetObjectW( hbitmap, sizeof(bitmap), &bitmap )) return FALSE;
- wine_tsx11_lock(); if ((physDev->depth == 1) && (physBitmap->pixmap_depth != 1)) { + wine_tsx11_lock(); /* Special case: a color pattern on a monochrome DC */ physDev->brush.pixmap = XCreatePixmap( gdi_display, root_window, bitmap.bmWidth, bitmap.bmHeight, 1); /* FIXME: should probably convert to monochrome instead */ XCopyPlane( gdi_display, physBitmap->pixmap, physDev->brush.pixmap, get_bitmap_gc(1), 0, 0, bitmap.bmWidth, bitmap.bmHeight, 0, 0, 1 ); + wine_tsx11_unlock(); } else { - physDev->brush.pixmap = XCreatePixmap( gdi_display, root_window, - bitmap.bmWidth, bitmap.bmHeight, - physBitmap->pixmap_depth ); - XCopyArea( gdi_display, physBitmap->pixmap, physDev->brush.pixmap, - get_bitmap_gc(physBitmap->pixmap_depth), 0, 0, bitmap.bmWidth, bitmap.bmHeight, 0, 0 ); + /* XRender is needed because of possible depth conversion */ + X11DRV_XRender_CopyBrush(physDev, physBitmap, bitmap.bmWidth, bitmap.bmHeight); } - wine_tsx11_unlock();
if (physBitmap->pixmap_depth > 1) { diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 078b1fd..62b0d63 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -286,6 +286,7 @@ extern void X11DRV_XRender_Init(void); extern void X11DRV_XRender_Finalize(void); extern BOOL X11DRV_XRender_SelectFont(X11DRV_PDEVICE*, HFONT); extern void X11DRV_XRender_DeleteDC(X11DRV_PDEVICE*); +extern void X11DRV_XRender_CopyBrush(X11DRV_PDEVICE *physDev, X_PHYSBITMAP *physBitmap, int width, int height); extern BOOL X11DRV_XRender_ExtTextOut(X11DRV_PDEVICE *physDev, INT x, INT y, UINT flags, const RECT *lprect, LPCWSTR wstr, UINT count, const INT *lpDx); diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c index bc759a8..efa8d02 100644 --- a/dlls/winex11.drv/xrender.c +++ b/dlls/winex11.drv/xrender.c @@ -1984,6 +1984,40 @@ BOOL CDECL X11DRV_AlphaBlend(X11DRV_PDEVICE *devDst, INT xDst, INT yDst, INT wid return TRUE; }
+void X11DRV_XRender_CopyBrush(X11DRV_PDEVICE *physDev, X_PHYSBITMAP *physBitmap, int width, int height) +{ + /* At depths >1, the depth of physBitmap and physDev might not be the same e.g. the physbitmap might be a 16-bit DIB while the physdev uses 24-bit */ + int depth = physBitmap->pixmap_depth == 1 ? 1 : physDev->depth; + + wine_tsx11_lock(); + physDev->brush.pixmap = XCreatePixmap(gdi_display, root_window, width, height, depth); + + /* Use XCopyArea when the physBitmap and brush.pixmap have the same depth. */ + if(physBitmap->pixmap_depth == 1 || physDev->depth == physBitmap->pixmap_depth) + { + XCopyArea( gdi_display, physBitmap->pixmap, physDev->brush.pixmap, + get_bitmap_gc(physBitmap->pixmap_depth), 0, 0, width, height, 0, 0 ); + } + else /* We meed depth conversion */ + { + WineXRenderFormat *src_format = get_xrender_format_from_color_shifts(physBitmap->pixmap_depth, &physBitmap->pixmap_color_shifts); + WineXRenderFormat *dst_format = get_xrender_format_from_color_shifts(physDev->depth, physDev->color_shifts); + + Picture src_pict, dst_pict; + XRenderPictureAttributes pa; + pa.subwindow_mode = IncludeInferiors; + pa.repeat = RepeatNone; + + src_pict = pXRenderCreatePicture(gdi_display, physBitmap->pixmap, src_format->pict_format, CPSubwindowMode|CPRepeat, &pa); + dst_pict = pXRenderCreatePicture(gdi_display, physDev->brush.pixmap, dst_format->pict_format, CPSubwindowMode|CPRepeat, &pa); + + xrender_blit(src_pict, 0, dst_pict, 0, 0, 1.0, 1.0, width, height); + pXRenderFreePicture(gdi_display, src_pict); + pXRenderFreePicture(gdi_display, dst_pict); + } + wine_tsx11_unlock(); +} + BOOL X11DRV_XRender_GetSrcAreaStretch(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst, Pixmap pixmap, GC gc, INT widthSrc, INT heightSrc, @@ -2125,6 +2159,16 @@ BOOL X11DRV_AlphaBlend(X11DRV_PDEVICE *devDst, INT xDst, INT yDst, INT widthDst, return FALSE; }
+void X11DRV_XRender_CopyBrush(X11DRV_PDEVICE *physDev, X_PHYSBITMAP *physBitmap, int width, int height) +{ + wine_tsx11_lock(); + physDev->brush.pixmap = XCreatePixmap(gdi_display, root_window, width, height, physBitmap->pixmap_depth); + + XCopyArea( gdi_display, physBitmap->pixmap, physDev->brush.pixmap, + get_bitmap_gc(physBitmap->pixmap_depth), 0, 0, width, height, 0, 0 ); + wine_tsx11_unlock(); +} + BOOL X11DRV_XRender_GetSrcAreaStretch(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst, Pixmap pixmap, GC gc, INT widthSrc, INT heightSrc,