Module: wine Branch: master Commit: ba3d34875a844ec09648499fba226241ad34f1f1 URL: http://source.winehq.org/git/wine.git/?a=commit;h=ba3d34875a844ec09648499fba...
Author: Huw Davies huw@codeweavers.com Date: Tue Apr 5 13:26:08 2011 +0100
gdi32: Add support for 32 bpp BI_BITFIELDS.
---
dlls/gdi32/dibdrv/dc.c | 28 ++++++++++++++++++++++++---- dlls/gdi32/dibdrv/dibdrv.h | 1 + dlls/gdi32/dibdrv/primitives.c | 30 ++++++++++++++++++++++++++++++ dlls/gdi32/gdi_private.h | 2 ++ 4 files changed, 57 insertions(+), 4 deletions(-)
diff --git a/dlls/gdi32/dibdrv/dc.c b/dlls/gdi32/dibdrv/dc.c index a230fbf..473bf82 100644 --- a/dlls/gdi32/dibdrv/dc.c +++ b/dlls/gdi32/dibdrv/dc.c @@ -36,11 +36,34 @@ static BOOL CDECL dibdrv_DeleteDC( PHYSDEV dev ) return 0; }
+static void calc_shift_and_len(DWORD mask, int *shift, int *len) +{ + int s, l; + + s = 0; + while ((mask & 1) == 0) + { + mask >>= 1; + s++; + } + l = 0; + while ((mask & 1) == 1) + { + mask >>= 1; + l++; + } + *shift = s; + *len = l; +} + static void init_bit_fields(dib_info *dib, const DWORD *bit_fields) { dib->red_mask = bit_fields[0]; dib->green_mask = bit_fields[1]; dib->blue_mask = bit_fields[2]; + calc_shift_and_len(dib->red_mask, &dib->red_shift, &dib->red_len); + calc_shift_and_len(dib->green_mask, &dib->green_shift, &dib->green_len); + calc_shift_and_len(dib->blue_mask, &dib->blue_shift, &dib->blue_len); }
static BOOL init_dib(dib_info *dib, const BITMAPINFOHEADER *bi, const DWORD *bit_fields, void *bits) @@ -71,10 +94,7 @@ static BOOL init_dib(dib_info *dib, const BITMAPINFOHEADER *bi, const DWORD *bit if(dib->red_mask == 0xff0000 && dib->green_mask == 0x00ff00 && dib->blue_mask == 0x0000ff) dib->funcs = &funcs_8888; else - { - TRACE("32 bpp bitmasks not supported, will forward to graphics driver.\n"); - return FALSE; - } + dib->funcs = &funcs_32; break;
default: diff --git a/dlls/gdi32/dibdrv/dibdrv.h b/dlls/gdi32/dibdrv/dibdrv.h index da41f21..9ed7661 100644 --- a/dlls/gdi32/dibdrv/dibdrv.h +++ b/dlls/gdi32/dibdrv/dibdrv.h @@ -29,4 +29,5 @@ typedef struct primitive_funcs } primitive_funcs;
extern const primitive_funcs funcs_8888 DECLSPEC_HIDDEN; +extern const primitive_funcs funcs_32 DECLSPEC_HIDDEN; extern const primitive_funcs funcs_null DECLSPEC_HIDDEN; diff --git a/dlls/gdi32/dibdrv/primitives.c b/dlls/gdi32/dibdrv/primitives.c index 8bbfc4d..92559d2 100644 --- a/dlls/gdi32/dibdrv/primitives.c +++ b/dlls/gdi32/dibdrv/primitives.c @@ -26,6 +26,31 @@ static DWORD colorref_to_pixel_888(const dib_info *dib, COLORREF color) return ( ((color >> 16) & 0xff) | (color & 0xff00) | ((color << 16) & 0xff0000) ); }
+static inline DWORD put_field(DWORD field, int shift, int len) +{ + shift = shift - (8 - len); + if (len <= 8) + field &= (((1 << len) - 1) << (8 - len)); + if (shift < 0) + field >>= -shift; + else + field <<= shift; + return field; +} + +static DWORD colorref_to_pixel_masks(const dib_info *dib, COLORREF colour) +{ + DWORD r,g,b; + + r = GetRValue(colour); + g = GetGValue(colour); + b = GetBValue(colour); + + return put_field(r, dib->red_shift, dib->red_len) | + put_field(g, dib->green_shift, dib->green_len) | + put_field(b, dib->blue_shift, dib->blue_len); +} + static DWORD colorref_to_pixel_null(const dib_info *dib, COLORREF color) { return 0; @@ -36,6 +61,11 @@ const primitive_funcs funcs_8888 = colorref_to_pixel_888 };
+const primitive_funcs funcs_32 = +{ + colorref_to_pixel_masks +}; + const primitive_funcs funcs_null = { colorref_to_pixel_null diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 8aa23bd..5f27106 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -86,6 +86,8 @@ typedef struct void *bits; /* points to the top-left corner of the dib. */
DWORD red_mask, green_mask, blue_mask; + int red_shift, green_shift, blue_shift; + int red_len, green_len, blue_len;
const struct primitive_funcs *funcs; } dib_info;