[PATCH 2/3] gdi32: Support the WINE_GGO_GRAY16_BITMAP at the dibdrv.
Byeongsik Jeon
bsjeon at hanmail.net
Sun Nov 4 18:23:25 CST 2018
Signed-off-by: Byeongsik Jeon <bsjeon at hanmail.net>
---
dlls/gdi32/dibdrv/dibdrv.h | 3 +-
dlls/gdi32/dibdrv/graphics.c | 28 ++++++++++-
dlls/gdi32/dibdrv/primitives.c | 88 ++++++++++++++++++++++------------
3 files changed, 85 insertions(+), 34 deletions(-)
diff --git a/dlls/gdi32/dibdrv/dibdrv.h b/dlls/gdi32/dibdrv/dibdrv.h
index 02164c9692..a5ff595496 100644
--- a/dlls/gdi32/dibdrv/dibdrv.h
+++ b/dlls/gdi32/dibdrv/dibdrv.h
@@ -87,6 +87,7 @@ struct intensity_range
struct font_intensities
{
+ int max_level;
struct intensity_range ranges[17];
struct font_gamma_ramp *gamma_ramp;
};
@@ -196,7 +197,7 @@ typedef struct primitive_funcs
void (* mask_rect)(const dib_info *dst, const RECT *rc, const dib_info *src,
const POINT *origin, int rop2);
void (* draw_glyph)(const dib_info *dst, const RECT *rc, const dib_info *glyph,
- const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges);
+ const POINT *origin, DWORD text_pixel, const struct font_intensities *intensity);
void (* draw_subpixel_glyph)(const dib_info *dst, const RECT *rc, const dib_info *glyph,
const POINT *origin, DWORD text_pixel, const struct font_gamma_ramp *gamma_ramp);
DWORD (* get_pixel)(const dib_info *dib, int x, int y);
diff --git a/dlls/gdi32/dibdrv/graphics.c b/dlls/gdi32/dibdrv/graphics.c
index 7d71fbb12a..9e10ffd4df 100644
--- a/dlls/gdi32/dibdrv/graphics.c
+++ b/dlls/gdi32/dibdrv/graphics.c
@@ -708,7 +708,7 @@ static void draw_glyph( dib_info *dib, int x, int y, const GLYPHMETRICS *metrics
text_color, intensity->gamma_ramp );
else
dib->funcs->draw_glyph( dib, &clipped_rect, glyph_dib, &src_origin,
- text_color, intensity->ranges );
+ text_color, intensity );
}
}
}
@@ -734,6 +734,29 @@ static int get_glyph_depth( UINT aa_flags )
}
}
+static int get_glyph_max_level( UINT aa_flags )
+{
+ switch (aa_flags)
+ {
+ case GGO_BITMAP: /* we'll convert to GGO_GRAY4_BITMAP format */
+ case GGO_GRAY4_BITMAP: return 16;
+
+ /* FIXME: confirm the native Windows. */
+ case GGO_GRAY2_BITMAP: return 16;
+ case GGO_GRAY8_BITMAP: return 16;
+
+ case WINE_GGO_HRGB_BITMAP:
+ case WINE_GGO_HBGR_BITMAP:
+ case WINE_GGO_VRGB_BITMAP:
+ case WINE_GGO_VBGR_BITMAP:
+ case WINE_GGO_GRAY16_BITMAP: return 255;
+
+ default:
+ ERR("Unexpected flags %08x\n", aa_flags);
+ return 0;
+ }
+}
+
static const BYTE masks[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
static const int padding[4] = {0, 3, 2, 1};
@@ -826,7 +849,8 @@ static void render_string( DC *dc, dib_info *dib, struct cached_font *font, INT
text_color = get_pixel_color( dc, dib, dc->textColor, TRUE );
- if (glyph_dib.bit_count == 32)
+ intensity.max_level = get_glyph_max_level( font->aa_flags );
+ if (intensity.max_level == 255)
intensity.gamma_ramp = dc->font_gamma_ramp;
else
get_aa_ranges( dib->funcs->pixel_to_colorref( dib, text_color ), intensity.ranges );
diff --git a/dlls/gdi32/dibdrv/primitives.c b/dlls/gdi32/dibdrv/primitives.c
index 01a1c7c1d8..e21c1d6ca7 100644
--- a/dlls/gdi32/dibdrv/primitives.c
+++ b/dlls/gdi32/dibdrv/primitives.c
@@ -6059,18 +6059,50 @@ static inline BYTE aa_color( BYTE dst, BYTE text, BYTE min_comp, BYTE max_comp )
}
}
-static inline DWORD aa_rgb( BYTE r_dst, BYTE g_dst, BYTE b_dst, DWORD text, const struct intensity_range *range )
+static inline BYTE blend_color_gamma( BYTE dst, BYTE text, BYTE alpha,
+ const struct font_gamma_ramp *gamma_ramp )
{
+ if (alpha == 0) return dst;
+ if (alpha == 255) return text;
+ if (dst == text) return dst;
+
+ return gamma_ramp->encode[ blend_color( gamma_ramp->decode[dst],
+ gamma_ramp->decode[text],
+ alpha ) ];
+}
+
+static inline DWORD aa_rgb( BYTE r_dst, BYTE g_dst, BYTE b_dst, DWORD text, const BYTE alpha,
+ const struct font_intensities *intensity )
+{
+ const struct intensity_range *range;
+ const struct font_gamma_ramp *gamma_ramp;
+
+ if (intensity->max_level == 255)
+ {
+ gamma_ramp = intensity->gamma_ramp;
+ if (gamma_ramp != NULL && gamma_ramp->gamma != 1000)
+ {
+ return blend_color_gamma( r_dst, text >> 16, alpha, gamma_ramp ) << 16 |
+ blend_color_gamma( g_dst, text >> 8, alpha, gamma_ramp ) << 8 |
+ blend_color_gamma( b_dst, text, alpha, gamma_ramp );
+ }
+ return blend_color( r_dst, text >> 16, alpha ) << 16 |
+ blend_color( g_dst, text >> 8, alpha ) << 8 |
+ blend_color( b_dst, text, alpha );
+ }
+
+ range = &intensity->ranges[alpha];
return (aa_color( b_dst, text, range->b_min, range->b_max ) |
aa_color( g_dst, text >> 8, range->g_min, range->g_max ) << 8 |
aa_color( r_dst, text >> 16, range->r_min, range->r_max ) << 16);
}
static void draw_glyph_8888( const dib_info *dib, const RECT *rect, const dib_info *glyph,
- const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
+ const POINT *origin, DWORD text_pixel, const struct font_intensities *intensity )
{
DWORD *dst_ptr = get_pixel_ptr_32( dib, rect->left, rect->top );
const BYTE *glyph_ptr = get_pixel_ptr_8( glyph, origin->x, origin->y );
+ const int max_level = intensity->max_level;
int x, y;
for (y = rect->top; y < rect->bottom; y++)
@@ -6078,8 +6110,9 @@ static void draw_glyph_8888( const dib_info *dib, const RECT *rect, const dib_in
for (x = 0; x < rect->right - rect->left; x++)
{
if (glyph_ptr[x] <= 1) continue;
- if (glyph_ptr[x] >= 16) { dst_ptr[x] = text_pixel; continue; }
- dst_ptr[x] = aa_rgb( dst_ptr[x] >> 16, dst_ptr[x] >> 8, dst_ptr[x], text_pixel, ranges + glyph_ptr[x] );
+ if (glyph_ptr[x] >= max_level) { dst_ptr[x] = text_pixel; continue; }
+ dst_ptr[x] = aa_rgb( dst_ptr[x] >> 16, dst_ptr[x] >> 8, dst_ptr[x],
+ text_pixel, glyph_ptr[x], intensity );
}
dst_ptr += dib->stride / 4;
glyph_ptr += glyph->stride;
@@ -6087,10 +6120,11 @@ static void draw_glyph_8888( const dib_info *dib, const RECT *rect, const dib_in
}
static void draw_glyph_32( const dib_info *dib, const RECT *rect, const dib_info *glyph,
- const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
+ const POINT *origin, DWORD text_pixel, const struct font_intensities *intensity )
{
DWORD *dst_ptr = get_pixel_ptr_32( dib, rect->left, rect->top );
const BYTE *glyph_ptr = get_pixel_ptr_8( glyph, origin->x, origin->y );
+ const int max_level = intensity->max_level;
int x, y;
DWORD text, val;
@@ -6103,11 +6137,11 @@ static void draw_glyph_32( const dib_info *dib, const RECT *rect, const dib_info
for (x = 0; x < rect->right - rect->left; x++)
{
if (glyph_ptr[x] <= 1) continue;
- if (glyph_ptr[x] >= 16) { dst_ptr[x] = text_pixel; continue; }
+ if (glyph_ptr[x] >= max_level) { dst_ptr[x] = text_pixel; continue; }
val = aa_rgb( get_field(dst_ptr[x], dib->red_shift, dib->red_len),
get_field(dst_ptr[x], dib->green_shift, dib->green_len),
get_field(dst_ptr[x], dib->blue_shift, dib->blue_len),
- text, ranges + glyph_ptr[x] );
+ text, glyph_ptr[x], intensity );
dst_ptr[x] = rgb_to_pixel_masks( dib, val >> 16, val >> 8, val );
}
dst_ptr += dib->stride / 4;
@@ -6116,10 +6150,11 @@ static void draw_glyph_32( const dib_info *dib, const RECT *rect, const dib_info
}
static void draw_glyph_24( const dib_info *dib, const RECT *rect, const dib_info *glyph,
- const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
+ const POINT *origin, DWORD text_pixel, const struct font_intensities *intensity )
{
BYTE *dst_ptr = get_pixel_ptr_24( dib, rect->left, rect->top );
const BYTE *glyph_ptr = get_pixel_ptr_8( glyph, origin->x, origin->y );
+ const int max_level = intensity->max_level;
int x, y;
DWORD val;
@@ -6128,11 +6163,11 @@ static void draw_glyph_24( const dib_info *dib, const RECT *rect, const dib_info
for (x = 0; x < rect->right - rect->left; x++)
{
if (glyph_ptr[x] <= 1) continue;
- if (glyph_ptr[x] >= 16)
+ if (glyph_ptr[x] >= max_level)
val = text_pixel;
else
val = aa_rgb( dst_ptr[x * 3 + 2], dst_ptr[x * 3 + 1], dst_ptr[x * 3],
- text_pixel, ranges + glyph_ptr[x] );
+ text_pixel, glyph_ptr[x], intensity );
dst_ptr[x * 3] = val;
dst_ptr[x * 3 + 1] = val >> 8;
dst_ptr[x * 3 + 2] = val >> 16;
@@ -6143,10 +6178,11 @@ static void draw_glyph_24( const dib_info *dib, const RECT *rect, const dib_info
}
static void draw_glyph_555( const dib_info *dib, const RECT *rect, const dib_info *glyph,
- const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
+ const POINT *origin, DWORD text_pixel, const struct font_intensities *intensity )
{
WORD *dst_ptr = get_pixel_ptr_16( dib, rect->left, rect->top );
const BYTE *glyph_ptr = get_pixel_ptr_8( glyph, origin->x, origin->y );
+ const int max_level = intensity->max_level;
int x, y;
DWORD text, val;
@@ -6159,11 +6195,11 @@ static void draw_glyph_555( const dib_info *dib, const RECT *rect, const dib_inf
for (x = 0; x < rect->right - rect->left; x++)
{
if (glyph_ptr[x] <= 1) continue;
- if (glyph_ptr[x] >= 16) { dst_ptr[x] = text_pixel; continue; }
+ if (glyph_ptr[x] >= max_level) { dst_ptr[x] = text_pixel; continue; }
val = aa_rgb( ((dst_ptr[x] >> 7) & 0xf8) | ((dst_ptr[x] >> 12) & 0x07),
((dst_ptr[x] >> 2) & 0xf8) | ((dst_ptr[x] >> 7) & 0x07),
((dst_ptr[x] << 3) & 0xf8) | ((dst_ptr[x] >> 2) & 0x07),
- text, ranges + glyph_ptr[x] );
+ text, glyph_ptr[x], intensity );
dst_ptr[x] = ((val >> 9) & 0x7c00) | ((val >> 6) & 0x03e0) | ((val >> 3) & 0x001f);
}
dst_ptr += dib->stride / 2;
@@ -6172,10 +6208,11 @@ static void draw_glyph_555( const dib_info *dib, const RECT *rect, const dib_inf
}
static void draw_glyph_16( const dib_info *dib, const RECT *rect, const dib_info *glyph,
- const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
+ const POINT *origin, DWORD text_pixel, const struct font_intensities *intensity )
{
WORD *dst_ptr = get_pixel_ptr_16( dib, rect->left, rect->top );
const BYTE *glyph_ptr = get_pixel_ptr_8( glyph, origin->x, origin->y );
+ const int max_level = intensity->max_level;
int x, y;
DWORD text, val;
@@ -6188,11 +6225,11 @@ static void draw_glyph_16( const dib_info *dib, const RECT *rect, const dib_info
for (x = 0; x < rect->right - rect->left; x++)
{
if (glyph_ptr[x] <= 1) continue;
- if (glyph_ptr[x] >= 16) { dst_ptr[x] = text_pixel; continue; }
+ if (glyph_ptr[x] >= max_level) { dst_ptr[x] = text_pixel; continue; }
val = aa_rgb( get_field(dst_ptr[x], dib->red_shift, dib->red_len),
get_field(dst_ptr[x], dib->green_shift, dib->green_len),
get_field(dst_ptr[x], dib->blue_shift, dib->blue_len),
- text, ranges + glyph_ptr[x] );
+ text, glyph_ptr[x], intensity );
dst_ptr[x] = rgb_to_pixel_masks( dib, val >> 16, val >> 8, val );
}
dst_ptr += dib->stride / 2;
@@ -6201,7 +6238,7 @@ static void draw_glyph_16( const dib_info *dib, const RECT *rect, const dib_info
}
static void draw_glyph_8( const dib_info *dib, const RECT *rect, const dib_info *glyph,
- const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
+ const POINT *origin, DWORD text_pixel, const struct font_intensities *intensity )
{
BYTE *dst_ptr = get_pixel_ptr_8( dib, rect->left, rect->top );
const BYTE *glyph_ptr = get_pixel_ptr_8( glyph, origin->x, origin->y );
@@ -6221,7 +6258,7 @@ static void draw_glyph_8( const dib_info *dib, const RECT *rect, const dib_info
}
static void draw_glyph_4( const dib_info *dib, const RECT *rect, const dib_info *glyph,
- const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
+ const POINT *origin, DWORD text_pixel, const struct font_intensities *intensity )
{
BYTE *dst_ptr = get_pixel_ptr_4( dib, rect->left, rect->top );
const BYTE *glyph_ptr = get_pixel_ptr_8( glyph, origin->x, origin->y );
@@ -6246,7 +6283,7 @@ static void draw_glyph_4( const dib_info *dib, const RECT *rect, const dib_info
}
static void draw_glyph_1( const dib_info *dib, const RECT *rect, const dib_info *glyph,
- const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
+ const POINT *origin, DWORD text_pixel, const struct font_intensities *intensity )
{
BYTE *dst_ptr = get_pixel_ptr_1( dib, rect->left, rect->top );
const BYTE *glyph_ptr = get_pixel_ptr_8( glyph, origin->x, origin->y );
@@ -6268,21 +6305,10 @@ static void draw_glyph_1( const dib_info *dib, const RECT *rect, const dib_info
}
static void draw_glyph_null( const dib_info *dib, const RECT *rect, const dib_info *glyph,
- const POINT *origin, DWORD text_pixel, const struct intensity_range *ranges )
+ const POINT *origin, DWORD text_pixel, const struct font_intensities *intensity )
{
return;
}
-static inline BYTE blend_color_gamma( BYTE dst, BYTE text, BYTE alpha,
- const struct font_gamma_ramp *gamma_ramp )
-{
- if (alpha == 0) return dst;
- if (alpha == 255) return text;
- if (dst == text) return dst;
-
- return gamma_ramp->encode[ blend_color( gamma_ramp->decode[dst],
- gamma_ramp->decode[text],
- alpha ) ];
-}
static inline DWORD blend_subpixel( BYTE r, BYTE g, BYTE b, DWORD text, DWORD alpha,
const struct font_gamma_ramp *gamma_ramp )
--
2.19.1
More information about the wine-devel
mailing list