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