Roderick Colenbrander : winex11: Add helper function for copying brushes.

Alexandre Julliard julliard at winehq.org
Thu Sep 10 09:08:37 CDT 2009


Module: wine
Branch: master
Commit: efa37f56ec51e76c1127c3f1b0cb8ef9d75d3112
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=efa37f56ec51e76c1127c3f1b0cb8ef9d75d3112

Author: Roderick Colenbrander <thunderbird2k at 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,




More information about the wine-cvs mailing list