Signed-off-by: Byeongsik Jeon bsjeon@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 )