Alexandre Julliard : winex11: Take the alpha channel into account to compute the region of layered windows .
Alexandre Julliard
julliard at winehq.org
Tue Oct 2 14:09:39 CDT 2012
Module: wine
Branch: master
Commit: d8247efd5ecb8c4604624eb2bbf47e194ce59e7e
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d8247efd5ecb8c4604624eb2bbf47e194ce59e7e
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu Sep 27 20:47:08 2012 +0200
winex11: Take the alpha channel into account to compute the region of layered windows.
---
dlls/winex11.drv/bitblt.c | 45 ++++++++++++++++++++++++++++++++++-----------
dlls/winex11.drv/window.c | 5 +++--
dlls/winex11.drv/x11drv.h | 3 ++-
3 files changed, 39 insertions(+), 14 deletions(-)
diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c
index 8701d73..ceecb0c 100644
--- a/dlls/winex11.drv/bitblt.c
+++ b/dlls/winex11.drv/bitblt.c
@@ -1545,6 +1545,7 @@ struct x11drv_window_surface
XImage *image;
RECT bounds;
BOOL is_r8g8b8;
+ BOOL is_argb;
COLORREF color_key;
struct gdi_image_bits bits;
CRITICAL_SECTION crit;
@@ -1598,7 +1599,7 @@ static void update_surface_region( struct x11drv_window_surface *surface )
int x, y, start, width;
HRGN rgn;
- if (surface->color_key == CLR_INVALID)
+ if (!surface->is_argb && surface->color_key == CLR_INVALID)
{
XShapeCombineMask( gdi_display, surface->window, ShapeBounding, 0, 0, None, ShapeSet );
return;
@@ -1662,17 +1663,38 @@ static void update_surface_region( struct x11drv_window_surface *surface )
case 32:
{
DWORD *bits = surface->bits.ptr;
- UINT mask = info->bmiHeader.biCompression == BI_RGB ? 0xffffff : (masks[0] | masks[1] | masks[2]);
- for (y = surface->header.rect.top; y < surface->header.rect.bottom; y++, bits += width)
+ if (info->bmiHeader.biCompression == BI_RGB)
{
- x = 0;
- while (x < width)
+ for (y = surface->header.rect.top; y < surface->header.rect.bottom; y++, bits += width)
{
- while (x < width && (bits[x] & mask) == surface->color_key) x++;
- start = x;
- while (x < width && (bits[x] & mask) != surface->color_key) x++;
- add_row( rgn, data, surface->header.rect.left + start, y, x - start );
+ x = 0;
+ while (x < width)
+ {
+ while (x < width &&
+ ((bits[x] & 0xffffff) == surface->color_key ||
+ (surface->is_argb && !(bits[x] & 0xff000000)))) x++;
+ start = x;
+ while (x < width &&
+ ((bits[x] & 0xffffff) != surface->color_key ||
+ !(surface->is_argb && !(bits[x] & 0xff000000)))) x++;
+ add_row( rgn, data, surface->header.rect.left + start, y, x - start );
+ }
+ }
+ }
+ else
+ {
+ UINT mask = masks[0] | masks[1] | masks[2];
+ for (y = surface->header.rect.top; y < surface->header.rect.bottom; y++, bits += width)
+ {
+ x = 0;
+ while (x < width)
+ {
+ while (x < width && (bits[x] & mask) == surface->color_key) x++;
+ start = x;
+ while (x < width && (bits[x] & mask) != surface->color_key) x++;
+ add_row( rgn, data, surface->header.rect.left + start, y, x - start );
+ }
}
}
break;
@@ -1782,7 +1804,7 @@ static void x11drv_surface_flush( struct window_surface *window_surface )
surface, coords.width, coords.height,
wine_dbgstr_rect( &surface->bounds ), surface->bits.ptr );
- if (surface->color_key != CLR_INVALID) update_surface_region( surface );
+ if (surface->is_argb || surface->color_key != CLR_INVALID) update_surface_region( surface );
if (surface->image->bits_per_pixel == 4 || surface->image->bits_per_pixel == 8)
mapping = X11DRV_PALETTE_PaletteToXPixel;
@@ -1836,7 +1858,7 @@ static const struct window_surface_funcs x11drv_surface_funcs =
* create_surface
*/
struct window_surface *create_surface( Window window, const XVisualInfo *vis, const RECT *rect,
- COLORREF color_key )
+ COLORREF color_key, BOOL use_alpha )
{
const XPixmapFormatValues *format = pixmap_formats[vis->depth];
struct x11drv_window_surface *surface;
@@ -1862,6 +1884,7 @@ struct window_surface *create_surface( Window window, const XVisualInfo *vis, co
surface->header.ref = 1;
surface->window = window;
surface->is_r8g8b8 = is_r8g8b8( vis );
+ surface->is_argb = (use_alpha && vis->depth == 32 && surface->info.bmiHeader.biCompression == BI_RGB);
set_color_key( surface, color_key );
reset_bounds( &surface->bounds );
if (!(surface->bits.ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index f090b2d..5b68968 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -2084,7 +2084,7 @@ void CDECL X11DRV_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flag
if (!layered || !GetLayeredWindowAttributes( hwnd, &key, NULL, &flags ) || !(flags & LWA_COLORKEY))
key = CLR_INVALID;
- *surface = create_surface( data->whole_window, &data->vis, &surface_rect, key );
+ *surface = create_surface( data->whole_window, &data->vis, &surface_rect, key, FALSE );
done:
release_win_data( data );
@@ -2384,7 +2384,8 @@ BOOL CDECL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO
surface = data->surface;
if (!surface || memcmp( &surface->rect, &rect, sizeof(RECT) ))
{
- data->surface = create_surface( data->whole_window, &data->vis, &rect, color_key );
+ data->surface = create_surface( data->whole_window, &data->vis, &rect,
+ color_key, !data->embedded );
if (surface) window_surface_release( surface );
surface = data->surface;
}
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index f496158..05c8ca9 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -190,7 +190,8 @@ extern Pixmap create_pixmap_from_image( HDC hdc, const XVisualInfo *vis, const B
const struct gdi_image_bits *bits, UINT coloruse ) DECLSPEC_HIDDEN;
extern DWORD get_pixmap_image( Pixmap pixmap, int width, int height, const XVisualInfo *vis,
BITMAPINFO *info, struct gdi_image_bits *bits ) DECLSPEC_HIDDEN;
-extern struct window_surface *create_surface( Window window, const XVisualInfo *vis, const RECT *rect, COLORREF color_key ) DECLSPEC_HIDDEN;
+extern struct window_surface *create_surface( Window window, const XVisualInfo *vis, const RECT *rect,
+ COLORREF color_key, BOOL use_alpha ) DECLSPEC_HIDDEN;
extern void set_surface_color_key( struct window_surface *window_surface, COLORREF color_key ) DECLSPEC_HIDDEN;
extern RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp ) DECLSPEC_HIDDEN;
More information about the wine-cvs
mailing list