r1 = ramp[aa] r2 = ramp[16 - aa]
min = text * r1 / 0xff max = r2 + ( 0xff - r2 ) * text / 0xff
dst < text: diff = text - dst range = text - min
dst = text - diff * range / text = text - ( text - dst ) * ( text - min ) / text = text - ( text - dst ) * ( text - text * r1 / 0xff ) / text = text - ( text - dst ) * ( 0xff - r1 ) / 0xff = ( text * r1 + dst * ( 0xff - r1 )) / 0xff = ( text * ramp[aa] + dst * ( 0xff - ramp[aa] )) / 0xff
dst > text: diff = dst - text range = max - text
dst = text + diff * range / ( 0xff - text ) = text + ( dst - text ) * ( max - text ) / ( 0xff - text ) = text + ( dst - text ) * (( 0xff - text) * r2 / 0xff ) / ( 0xff - text ) = text + ( dst - text ) * r2 / 0xff = ( dst * r2 + text * ( 0xff - r2 )) / 0xff = ( dst * ramp[16 - aa] + text * ( 0xff - ramp[16 - aa] )) / 0xff
Signed-off-by: Byeongsik Jeon bsjeon@hanmail.net --- I focused on doing equal functions without adding new features.
It is a different formula from the usual gamma correction pattern, but it takes a roughly similar graph shape because it is classified as "dst > text".
0.4315 to = 1/2.3: The gamma value is too large, so the rendering quality is bad. This value seems to be related to SPI_SETFONTSMOOTHINGENTRAST.
The dibdrv gray text format is limited to GGO_GRAY4_BITMAP, which lowers the quality of text rendering.
Is there a special reason?
dlls/gdi32/dibdrv/dibdrv.h | 2 +- dlls/gdi32/dibdrv/graphics.c | 57 ++---------------------------- dlls/gdi32/dibdrv/primitives.c | 64 ++++++++++++++++++---------------- 3 files changed, 37 insertions(+), 86 deletions(-)
diff --git a/dlls/gdi32/dibdrv/dibdrv.h b/dlls/gdi32/dibdrv/dibdrv.h index f79f5b0867..5697645229 100644 --- a/dlls/gdi32/dibdrv/dibdrv.h +++ b/dlls/gdi32/dibdrv/dibdrv.h @@ -190,7 +190,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); void (* draw_subpixel_glyph)(const dib_info *dst, const RECT *rc, const dib_info *glyph, const POINT *origin, DWORD text_pixel ); 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 08f8c3d6d2..4387eaa10a 100644 --- a/dlls/gdi32/dibdrv/graphics.c +++ b/dlls/gdi32/dibdrv/graphics.c @@ -474,52 +474,6 @@ done: return ret; }
-/* Intensities of the 17 glyph levels when drawn with text component of 0xff on a - black bkgnd. [A log-log plot of these data gives: y = 77.05 * x^0.4315]. */ -static const BYTE ramp[17] = -{ - 0, 0x4d, 0x68, 0x7c, - 0x8c, 0x9a, 0xa7, 0xb2, - 0xbd, 0xc7, 0xd0, 0xd9, - 0xe1, 0xe9, 0xf0, 0xf8, - 0xff -}; - -/* For a give text-color component and a glyph level, calculate the - range of dst intensities, the min/max corresponding to 0/0xff bkgnd - components respectively. - - The minimum is a linear interpolation between 0 and the value in - the ramp table. - - The maximum is a linear interpolation between the value from the - ramp table read in reverse and 0xff. - - To find the resulting pixel intensity, we note that if the text and - bkgnd intensities are the same then the result must be that - intensity. Otherwise we linearly interpolate between either the - min or the max value and this intermediate value depending on which - side of the inequality we lie. -*/ - -static inline void get_range( BYTE aa, DWORD text_comp, BYTE *min_comp, BYTE *max_comp ) -{ - *min_comp = (ramp[aa] * text_comp) / 0xff; - *max_comp = ramp[16 - aa] + ((0xff - ramp[16 - aa]) * text_comp) / 0xff; -} - -static inline void get_aa_ranges( COLORREF col, struct intensity_range intensities[17] ) -{ - int i; - - for (i = 0; i < 17; i++) - { - get_range( i, GetRValue(col), &intensities[i].r_min, &intensities[i].r_max ); - get_range( i, GetGValue(col), &intensities[i].g_min, &intensities[i].g_max ); - get_range( i, GetBValue(col), &intensities[i].b_min, &intensities[i].b_max ); - } -} - static DWORD font_cache_hash( struct cached_font *font ) { DWORD hash = 0, *ptr, two_chars; @@ -683,8 +637,7 @@ static inline void get_text_bkgnd_masks( DC *dc, const dib_info *dib, rop_mask *
static void draw_glyph( dib_info *dib, int x, int y, const GLYPHMETRICS *metrics, const dib_info *glyph_dib, DWORD text_color, - const struct intensity_range *ranges, const struct clipped_rects *clipped_rects, - RECT *bounds ) + const struct clipped_rects *clipped_rects, RECT *bounds ) { int i; RECT rect, clipped_rect; @@ -708,7 +661,7 @@ static void draw_glyph( dib_info *dib, int x, int y, const GLYPHMETRICS *metrics text_color ); else dib->funcs->draw_glyph( dib, &clipped_rect, glyph_dib, &src_origin, - text_color, ranges ); + text_color ); } } } @@ -816,7 +769,6 @@ static void render_string( DC *dc, dib_info *dib, struct cached_font *font, INT struct cached_glyph *glyph; dib_info glyph_dib; DWORD text_color; - struct intensity_range ranges[17];
glyph_dib.bit_count = get_glyph_depth( font->aa_flags ); glyph_dib.rect.left = 0; @@ -826,9 +778,6 @@ 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 == 8) - get_aa_ranges( dib->funcs->pixel_to_colorref( dib, text_color ), ranges ); - for (i = 0; i < count; i++) { if (!(glyph = get_cached_glyph( font, str[i], flags )) && @@ -841,7 +790,7 @@ static void render_string( DC *dc, dib_info *dib, struct cached_font *font, INT glyph_dib.stride = get_dib_stride( glyph->metrics.gmBlackBoxX, glyph_dib.bit_count ); glyph_dib.bits.ptr = glyph->bits;
- draw_glyph( dib, x, y, &glyph->metrics, &glyph_dib, text_color, ranges, clipped_rects, bounds ); + draw_glyph( dib, x, y, &glyph->metrics, &glyph_dib, text_color, clipped_rects, bounds );
if (dx) { diff --git a/dlls/gdi32/dibdrv/primitives.c b/dlls/gdi32/dibdrv/primitives.c index 0d097b2da6..caf2d890b5 100644 --- a/dlls/gdi32/dibdrv/primitives.c +++ b/dlls/gdi32/dibdrv/primitives.c @@ -6039,35 +6039,36 @@ static void mask_rect_null( const dib_info *dst, const RECT *rc, { }
-static inline BYTE aa_color( BYTE dst, BYTE text, BYTE min_comp, BYTE max_comp ) +/* Intensities of the 17 glyph levels when drawn with text component of 0xff on a + black bkgnd. [A log-log plot of these data gives: y = 77.05 * x^0.4315]. */ +static const BYTE ramp[17] = +{ + 0, 0x4d, 0x68, 0x7c, + 0x8c, 0x9a, 0xa7, 0xb2, + 0xbd, 0xc7, 0xd0, 0xd9, + 0xe1, 0xe9, 0xf0, 0xf8, + 0xff +}; + +static inline BYTE aa_color( BYTE dst, BYTE text, BYTE alpha ) { if (dst == text) return dst;
if (dst > text) - { - DWORD diff = dst - text; - DWORD range = max_comp - text; - dst = text + (diff * range ) / (0xff - text); - return dst; - } + return ( text * ( 0xff - ramp[16 - alpha] ) + dst * ramp[16 - alpha] ) / 0xff; else - { - DWORD diff = text - dst; - DWORD range = text - min_comp; - dst = text - (diff * range) / text; - return dst; - } + return ( text * ramp[alpha] + dst * ( 0xff - ramp[alpha] ) ) / 0xff; }
-static inline DWORD aa_rgb( BYTE r_dst, BYTE g_dst, BYTE b_dst, DWORD text, const struct intensity_range *range ) +static inline DWORD aa_rgb( BYTE r_dst, BYTE g_dst, BYTE b_dst, DWORD text, BYTE 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); + return (aa_color( b_dst, text, alpha ) | + aa_color( g_dst, text >> 8, alpha ) << 8 | + aa_color( r_dst, text >> 16, alpha ) << 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 ) { 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 ); @@ -6079,7 +6080,8 @@ static void draw_glyph_8888( const dib_info *dib, const RECT *rect, const dib_in { 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] ); + dst_ptr[x] = aa_rgb( dst_ptr[x] >> 16, dst_ptr[x] >> 8, dst_ptr[x], + text_pixel, glyph_ptr[x] ); } dst_ptr += dib->stride / 4; glyph_ptr += glyph->stride; @@ -6087,7 +6089,7 @@ 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 ) { 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 ); @@ -6107,7 +6109,7 @@ static void draw_glyph_32( const dib_info *dib, const RECT *rect, const dib_info 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] ); dst_ptr[x] = rgb_to_pixel_masks( dib, val >> 16, val >> 8, val ); } dst_ptr += dib->stride / 4; @@ -6116,7 +6118,7 @@ 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 ) { 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 ); @@ -6132,7 +6134,7 @@ static void draw_glyph_24( const dib_info *dib, const RECT *rect, const dib_info 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] ); dst_ptr[x * 3] = val; dst_ptr[x * 3 + 1] = val >> 8; dst_ptr[x * 3 + 2] = val >> 16; @@ -6143,7 +6145,7 @@ 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 ) { 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 ); @@ -6163,7 +6165,7 @@ static void draw_glyph_555( const dib_info *dib, const RECT *rect, const dib_inf 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] ); dst_ptr[x] = ((val >> 9) & 0x7c00) | ((val >> 6) & 0x03e0) | ((val >> 3) & 0x001f); } dst_ptr += dib->stride / 2; @@ -6172,7 +6174,7 @@ 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 ) { 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 ); @@ -6192,7 +6194,7 @@ static void draw_glyph_16( const dib_info *dib, const RECT *rect, const dib_info 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] ); dst_ptr[x] = rgb_to_pixel_masks( dib, val >> 16, val >> 8, val ); } dst_ptr += dib->stride / 2; @@ -6201,7 +6203,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 ) { 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 +6223,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 ) { 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 +6248,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 ) { 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,7 +6270,7 @@ 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 ) { return; }