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