Huw Davies : gdi32: Add support for 32 bpp BI_BITFIELDS.
Alexandre Julliard
julliard at winehq.org
Tue Apr 5 11:23:32 CDT 2011
Module: wine
Branch: master
Commit: ba3d34875a844ec09648499fba226241ad34f1f1
URL: http://source.winehq.org/git/wine.git/?a=commit;h=ba3d34875a844ec09648499fba226241ad34f1f1
Author: Huw Davies <huw at 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;
More information about the wine-cvs
mailing list