gdi32: Add support for 8 bpp dibs.
This commit is contained in:
parent
a44aa8a954
commit
30f26b3bca
|
@ -114,6 +114,10 @@ static BOOL init_dib_info(dib_info *dib, const BITMAPINFOHEADER *bi, const DWORD
|
|||
dib->funcs = &funcs_16;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
dib->funcs = &funcs_8;
|
||||
break;
|
||||
|
||||
default:
|
||||
TRACE("bpp %d not supported, will forward to graphics driver.\n", dib->bit_count);
|
||||
return FALSE;
|
||||
|
|
|
@ -49,6 +49,7 @@ extern const primitive_funcs funcs_8888 DECLSPEC_HIDDEN;
|
|||
extern const primitive_funcs funcs_32 DECLSPEC_HIDDEN;
|
||||
extern const primitive_funcs funcs_555 DECLSPEC_HIDDEN;
|
||||
extern const primitive_funcs funcs_16 DECLSPEC_HIDDEN;
|
||||
extern const primitive_funcs funcs_8 DECLSPEC_HIDDEN;
|
||||
extern const primitive_funcs funcs_null DECLSPEC_HIDDEN;
|
||||
|
||||
extern void calc_and_xor_masks(INT rop, DWORD color, DWORD *and, DWORD *xor) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -35,6 +35,11 @@ static inline WORD *get_pixel_ptr_16(const dib_info *dib, int x, int y)
|
|||
return (WORD *)((BYTE*)dib->bits + y * dib->stride + x * 2);
|
||||
}
|
||||
|
||||
static inline BYTE *get_pixel_ptr_8(const dib_info *dib, int x, int y)
|
||||
{
|
||||
return (BYTE*)dib->bits + y * dib->stride + x;
|
||||
}
|
||||
|
||||
static inline void do_rop_32(DWORD *ptr, DWORD and, DWORD xor)
|
||||
{
|
||||
*ptr = (*ptr & and) ^ xor;
|
||||
|
@ -45,6 +50,11 @@ static inline void do_rop_16(WORD *ptr, WORD and, WORD xor)
|
|||
*ptr = (*ptr & and) ^ xor;
|
||||
}
|
||||
|
||||
static inline void do_rop_8(BYTE *ptr, BYTE and, BYTE xor)
|
||||
{
|
||||
*ptr = (*ptr & and) ^ xor;
|
||||
}
|
||||
|
||||
static void solid_rects_32(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
|
||||
{
|
||||
DWORD *ptr, *start;
|
||||
|
@ -73,6 +83,20 @@ static void solid_rects_16(const dib_info *dib, int num, const RECT *rc, DWORD a
|
|||
}
|
||||
}
|
||||
|
||||
static void solid_rects_8(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
|
||||
{
|
||||
BYTE *ptr, *start;
|
||||
int x, y, i;
|
||||
|
||||
for(i = 0; i < num; i++, rc++)
|
||||
{
|
||||
start = get_pixel_ptr_8(dib, rc->left, rc->top);
|
||||
for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
|
||||
for(x = rc->left, ptr = start; x < rc->right; x++)
|
||||
do_rop_8(ptr++, and, xor);
|
||||
}
|
||||
}
|
||||
|
||||
static void solid_rects_null(const dib_info *dib, int num, const RECT *rc, DWORD and, DWORD xor)
|
||||
{
|
||||
return;
|
||||
|
@ -194,6 +218,52 @@ static void pattern_rects_16(const dib_info *dib, int num, const RECT *rc, const
|
|||
}
|
||||
}
|
||||
|
||||
static void pattern_rects_8(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
|
||||
const dib_info *brush, void *and_bits, void *xor_bits)
|
||||
{
|
||||
BYTE *ptr, *start, *start_and, *and_ptr, *start_xor, *xor_ptr;
|
||||
int x, y, i;
|
||||
POINT offset;
|
||||
|
||||
for(i = 0; i < num; i++, rc++)
|
||||
{
|
||||
offset = calc_brush_offset(rc, brush, origin);
|
||||
|
||||
start = get_pixel_ptr_8(dib, rc->left, rc->top);
|
||||
start_and = (BYTE*)and_bits + offset.y * brush->stride;
|
||||
start_xor = (BYTE*)xor_bits + offset.y * brush->stride;
|
||||
|
||||
for(y = rc->top; y < rc->bottom; y++, start += dib->stride)
|
||||
{
|
||||
and_ptr = start_and + offset.x;
|
||||
xor_ptr = start_xor + offset.x;
|
||||
|
||||
for(x = rc->left, ptr = start; x < rc->right; x++)
|
||||
{
|
||||
do_rop_8(ptr++, *and_ptr++, *xor_ptr++);
|
||||
if(and_ptr == start_and + brush->width)
|
||||
{
|
||||
and_ptr = start_and;
|
||||
xor_ptr = start_xor;
|
||||
}
|
||||
}
|
||||
|
||||
offset.y++;
|
||||
if(offset.y == brush->height)
|
||||
{
|
||||
start_and = and_bits;
|
||||
start_xor = xor_bits;
|
||||
offset.y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
start_and += brush->stride;
|
||||
start_xor += brush->stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pattern_rects_null(const dib_info *dib, int num, const RECT *rc, const POINT *origin,
|
||||
const dib_info *brush, void *and_bits, void *xor_bits)
|
||||
{
|
||||
|
@ -235,6 +305,37 @@ static DWORD colorref_to_pixel_555(const dib_info *dib, COLORREF color)
|
|||
return ( ((color >> 19) & 0x1f) | ((color >> 6) & 0x03e0) | ((color << 7) & 0x7c00) );
|
||||
}
|
||||
|
||||
static DWORD colorref_to_pixel_colortable(const dib_info *dib, COLORREF color)
|
||||
{
|
||||
int i, best_index = 0;
|
||||
RGBQUAD rgb;
|
||||
DWORD diff, best_diff = 0xffffffff;
|
||||
|
||||
rgb.rgbRed = GetRValue(color);
|
||||
rgb.rgbGreen = GetGValue(color);
|
||||
rgb.rgbBlue = GetBValue(color);
|
||||
|
||||
for(i = 0; i < dib->color_table_size; i++)
|
||||
{
|
||||
RGBQUAD *cur = dib->color_table + i;
|
||||
diff = (rgb.rgbRed - cur->rgbRed) * (rgb.rgbRed - cur->rgbRed)
|
||||
+ (rgb.rgbGreen - cur->rgbGreen) * (rgb.rgbGreen - cur->rgbGreen)
|
||||
+ (rgb.rgbBlue - cur->rgbBlue) * (rgb.rgbBlue - cur->rgbBlue);
|
||||
|
||||
if(diff == 0)
|
||||
{
|
||||
best_index = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if(diff < best_diff)
|
||||
{
|
||||
best_diff = diff;
|
||||
best_index = i;
|
||||
}
|
||||
}
|
||||
return best_index;
|
||||
}
|
||||
|
||||
static DWORD colorref_to_pixel_null(const dib_info *dib, COLORREF color)
|
||||
{
|
||||
|
@ -524,6 +625,79 @@ static BOOL convert_to_16(dib_info *dst, const dib_info *src, const RECT *src_re
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL convert_to_8(dib_info *dst, const dib_info *src, const RECT *src_rect)
|
||||
{
|
||||
BYTE *dst_start = dst->bits, *dst_pixel;
|
||||
INT x, y;
|
||||
DWORD src_val;
|
||||
|
||||
switch(src->bit_count)
|
||||
{
|
||||
case 32:
|
||||
{
|
||||
DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
|
||||
|
||||
if(src->funcs == &funcs_8888)
|
||||
{
|
||||
for(y = src_rect->top; y < src_rect->bottom; y++)
|
||||
{
|
||||
dst_pixel = dst_start;
|
||||
src_pixel = src_start;
|
||||
for(x = src_rect->left; x < src_rect->right; x++)
|
||||
{
|
||||
src_val = *src_pixel++;
|
||||
*dst_pixel++ = colorref_to_pixel_colortable(dst, ((src_val >> 16) & 0x0000ff) |
|
||||
( src_val & 0x00ff00) |
|
||||
((src_val << 16) & 0xff0000) );
|
||||
}
|
||||
dst_start += dst->stride;
|
||||
src_start += src->stride / 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("Unsupported conversion: 32 -> 8\n");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 16:
|
||||
{
|
||||
WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
|
||||
if(src->funcs == &funcs_555)
|
||||
{
|
||||
for(y = src_rect->top; y < src_rect->bottom; y++)
|
||||
{
|
||||
dst_pixel = dst_start;
|
||||
src_pixel = src_start;
|
||||
for(x = src_rect->left; x < src_rect->right; x++)
|
||||
{
|
||||
src_val = *src_pixel++;
|
||||
*dst_pixel++ = colorref_to_pixel_colortable(dst, ((src_val >> 7) & 0x0000f8) | ((src_val >> 12) & 0x000007) |
|
||||
((src_val << 6) & 0x00f800) | ((src_val << 1) & 0x000700) |
|
||||
((src_val << 19) & 0xf80000) | ((src_val << 14) & 0x070000) );
|
||||
}
|
||||
dst_start += dst->stride;
|
||||
src_start += src->stride / 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("Unsupported conversion: 16 -> 8\n");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
FIXME("Unsupported conversion: %d -> 8\n", src->bit_count);
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL convert_to_null(dib_info *dst, const dib_info *src, const RECT *src_rect)
|
||||
{
|
||||
return TRUE;
|
||||
|
@ -561,6 +735,14 @@ const primitive_funcs funcs_16 =
|
|||
convert_to_16
|
||||
};
|
||||
|
||||
const primitive_funcs funcs_8 =
|
||||
{
|
||||
solid_rects_8,
|
||||
pattern_rects_8,
|
||||
colorref_to_pixel_colortable,
|
||||
convert_to_8
|
||||
};
|
||||
|
||||
const primitive_funcs funcs_null =
|
||||
{
|
||||
solid_rects_null,
|
||||
|
|
Loading…
Reference in New Issue