Huw Davies : gdi32: Add support for colour tables.

Alexandre Julliard julliard at winehq.org
Fri May 27 11:03:43 CDT 2011


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

Author: Huw Davies <huw at codeweavers.com>
Date:   Fri May 27 14:17:20 2011 +0100

gdi32: Add support for colour tables.

---

 dlls/gdi32/dibdrv/dc.c      |   65 ++++++++++++++++++++++++++++++++++++------
 dlls/gdi32/dibdrv/dibdrv.h  |    2 +-
 dlls/gdi32/dibdrv/objects.c |    4 ++-
 dlls/gdi32/gdi_private.h    |    3 ++
 4 files changed, 62 insertions(+), 12 deletions(-)

diff --git a/dlls/gdi32/dibdrv/dc.c b/dlls/gdi32/dibdrv/dc.c
index 07227a1..d6023b0 100644
--- a/dlls/gdi32/dibdrv/dc.c
+++ b/dlls/gdi32/dibdrv/dc.c
@@ -63,7 +63,8 @@ static void init_bit_fields(dib_info *dib, const DWORD *bit_fields)
     calc_shift_and_len(dib->blue_mask,  &dib->blue_shift,  &dib->blue_len);
 }
 
-static BOOL init_dib_info(dib_info *dib, const BITMAPINFOHEADER *bi, const DWORD *bit_fields, void *bits)
+static BOOL init_dib_info(dib_info *dib, const BITMAPINFOHEADER *bi, const DWORD *bit_fields,
+                          RGBQUAD *color_table, int color_table_size, void *bits)
 {
     static const DWORD bit_fields_888[3] = {0xff0000, 0x00ff00, 0x0000ff};
     static const DWORD bit_fields_555[3] = {0x7c00, 0x03e0, 0x001f};
@@ -118,13 +119,26 @@ static BOOL init_dib_info(dib_info *dib, const BITMAPINFOHEADER *bi, const DWORD
         return FALSE;
     }
 
+    if(color_table)
+    {
+        dib->color_table = HeapAlloc(GetProcessHeap(), 0, color_table_size * sizeof(dib->color_table[0]));
+        if(!dib->color_table) return FALSE;
+        dib->color_table_size = color_table_size;
+        memcpy(dib->color_table, color_table, color_table_size * sizeof(color_table[0]));
+    }
+    else
+    {
+        dib->color_table = NULL;
+        dib->color_table_size = 0;
+    }
+
     return TRUE;
 }
 
-BOOL init_dib_info_from_packed(dib_info *dib, const BITMAPINFOHEADER *bi, WORD usage)
+BOOL init_dib_info_from_packed(dib_info *dib, const BITMAPINFOHEADER *bi, WORD usage, HPALETTE palette)
 {
     DWORD *masks = NULL;
-    RGBQUAD *color_table = NULL;
+    RGBQUAD *color_table = NULL, pal_table[256];
     BYTE *ptr = (BYTE*)bi + bi->biSize;
     int num_colors = bi->biClrUsed;
 
@@ -135,17 +149,37 @@ BOOL init_dib_info_from_packed(dib_info *dib, const BITMAPINFOHEADER *bi, WORD u
     }
 
     if(!num_colors && bi->biBitCount <= 8) num_colors = 1 << bi->biBitCount;
-    if(num_colors) color_table = (RGBQUAD*)ptr;
-    if(usage == DIB_PAL_COLORS)
-        ptr += num_colors * sizeof(WORD);
-    else
-        ptr += num_colors * sizeof(*color_table);
+    if(num_colors)
+    {
+        if(usage == DIB_PAL_COLORS)
+        {
+            PALETTEENTRY entries[256];
+            const WORD *index = (const WORD*) ptr;
+            UINT i, count = GetPaletteEntries( palette, 0, num_colors, entries );
+            for (i = 0; i < num_colors; i++, index++)
+            {
+                PALETTEENTRY *entry = &entries[*index % count];
+                pal_table[i].rgbRed      = entry->peRed;
+                pal_table[i].rgbGreen    = entry->peGreen;
+                pal_table[i].rgbBlue     = entry->peBlue;
+                pal_table[i].rgbReserved = 0;
+            }
+            color_table = pal_table;
+            ptr += num_colors * sizeof(WORD);
+        }
+        else
+        {
+            color_table = (RGBQUAD*)ptr;
+            ptr += num_colors * sizeof(*color_table);
+        }
+    }
 
-    return init_dib_info(dib, bi, masks, ptr);
+    return init_dib_info(dib, bi, masks, color_table, num_colors, ptr);
 }
 
 static void clear_dib_info(dib_info *dib)
 {
+    dib->color_table = NULL;
     dib->bits = NULL;
 }
 
@@ -156,6 +190,8 @@ static void clear_dib_info(dib_info *dib)
  */
 void free_dib_info(dib_info *dib, BOOL free_bits)
 {
+    HeapFree(GetProcessHeap(), 0, dib->color_table);
+    dib->color_table = NULL;
     if(free_bits)
     {
         HeapFree(GetProcessHeap(), 0, dib->bits);
@@ -176,6 +212,14 @@ void copy_dib_color_info(dib_info *dst, const dib_info *src)
     dst->green_shift      = src->green_shift;
     dst->blue_shift       = src->blue_shift;
     dst->funcs            = src->funcs;
+    dst->color_table_size = src->color_table_size;
+    dst->color_table      = NULL;
+    if(dst->color_table_size)
+    {
+        int size = dst->color_table_size * sizeof(dst->color_table[0]);
+        dst->color_table = HeapAlloc(GetProcessHeap(), 0, size);
+        memcpy(dst->color_table, src->color_table, size);
+    }
 }
 
 /**************************************************************
@@ -239,7 +283,8 @@ static HBITMAP CDECL dibdrv_SelectBitmap( PHYSDEV dev, HBITMAP bitmap )
     clear_dib_info(&pdev->brush_dib);
     pdev->brush_and_bits = pdev->brush_xor_bits = NULL;
 
-    if(!init_dib_info(&pdev->dib, &bmp->dib->dsBmih, bmp->dib->dsBitfields, bmp->dib->dsBm.bmBits))
+    if(!init_dib_info(&pdev->dib, &bmp->dib->dsBmih, bmp->dib->dsBitfields,
+                      bmp->color_table, bmp->nb_colors, bmp->dib->dsBm.bmBits))
         pdev->defer |= DEFER_FORMAT;
 
     GDI_ReleaseObj( bitmap );
diff --git a/dlls/gdi32/dibdrv/dibdrv.h b/dlls/gdi32/dibdrv/dibdrv.h
index a8e1dd9..a330d0a 100644
--- a/dlls/gdi32/dibdrv/dibdrv.h
+++ b/dlls/gdi32/dibdrv/dibdrv.h
@@ -54,7 +54,7 @@ extern const primitive_funcs funcs_null DECLSPEC_HIDDEN;
 extern void calc_and_xor_masks(INT rop, DWORD color, DWORD *and, DWORD *xor) DECLSPEC_HIDDEN;
 extern void update_brush_rop( dibdrv_physdev *pdev, INT rop ) DECLSPEC_HIDDEN;
 extern void reset_dash_origin(dibdrv_physdev *pdev) DECLSPEC_HIDDEN;
-extern BOOL init_dib_info_from_packed(dib_info *dib, const BITMAPINFOHEADER *bi, WORD usage) DECLSPEC_HIDDEN;
+extern BOOL init_dib_info_from_packed(dib_info *dib, const BITMAPINFOHEADER *bi, WORD usage, HPALETTE pal) DECLSPEC_HIDDEN;
 extern void free_dib_info(dib_info *dib, BOOL free_bits) DECLSPEC_HIDDEN;
 extern void free_pattern_brush(dibdrv_physdev *pdev) DECLSPEC_HIDDEN;
 extern void copy_dib_color_info(dib_info *dst, const dib_info *src) DECLSPEC_HIDDEN;
diff --git a/dlls/gdi32/dibdrv/objects.c b/dlls/gdi32/dibdrv/objects.c
index ebe94c0..ce6e710 100644
--- a/dlls/gdi32/dibdrv/objects.c
+++ b/dlls/gdi32/dibdrv/objects.c
@@ -1117,9 +1117,11 @@ HBRUSH CDECL dibdrv_SelectBrush( PHYSDEV dev, HBRUSH hbrush )
     {
         BITMAPINFOHEADER *bi = GlobalLock((HGLOBAL)logbrush.lbHatch);
         dib_info orig_dib;
+        WORD usage = LOWORD(logbrush.lbColor);
+        HPALETTE pal = (usage == DIB_PAL_COLORS) ? GetCurrentObject(dev->hdc, OBJ_PAL) : NULL;
 
         if(!bi) return NULL;
-        if(init_dib_info_from_packed(&orig_dib, bi, LOWORD(logbrush.lbColor)))
+        if(init_dib_info_from_packed(&orig_dib, bi, usage, pal))
         {
             copy_dib_color_info(&pdev->brush_dib, &pdev->dib);
             if(convert_dib(&pdev->brush_dib, &orig_dib))
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index 0f59f48..9a188ee 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -89,6 +89,9 @@ typedef struct
     int red_shift, green_shift, blue_shift;
     int red_len, green_len, blue_len;
 
+    RGBQUAD *color_table;
+    DWORD color_table_size;
+
     const struct primitive_funcs *funcs;
 } dib_info;
 




More information about the wine-cvs mailing list