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; }
for ( x = 1; x < 17; x++ ) printf("0x%02x ", (int)( 255. * pow( (double)x / 16., 0.4315 ) + .5 )); for ( x = 1; x < 17; x++ ) printf("0x%02x ", (int)( 77.05 * pow( (double)x, 0.4315 ) + .5 ));
0x4d 0x68 0x7c 0x8c 0x9a 0xa7 0xb2 0xbd 0xc7 0xd0 0xd9 0xe1 0xe9 0xf1 0xf8 0xff 0x4d 0x68 0x7c 0x8c 0x9a 0xa7 0xb2 0xbd 0xc7 0xd0 0xd9 0xe1 0xe9 0xf1 0xf8 0xff
Signed-off-by: Byeongsik Jeon bsjeon@hanmail.net --- dlls/gdi32/dibdrv/primitives.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/gdi32/dibdrv/primitives.c b/dlls/gdi32/dibdrv/primitives.c index caf2d890b5..ecdf52c7cc 100644 --- a/dlls/gdi32/dibdrv/primitives.c +++ b/dlls/gdi32/dibdrv/primitives.c @@ -6046,7 +6046,7 @@ static const BYTE ramp[17] = 0, 0x4d, 0x68, 0x7c, 0x8c, 0x9a, 0xa7, 0xb2, 0xbd, 0xc7, 0xd0, 0xd9, - 0xe1, 0xe9, 0xf0, 0xf8, + 0xe1, 0xe9, 0xf1, 0xf8, 0xff };
On Thu, Oct 11, 2018 at 10:12:13PM +0900, Byeongsik Jeon wrote:
for ( x = 1; x < 17; x++ ) printf("0x%02x ", (int)( 255. * pow( (double)x / 16., 0.4315 ) + .5 )); for ( x = 1; x < 17; x++ ) printf("0x%02x ", (int)( 77.05 * pow( (double)x, 0.4315 ) + .5 ));
0x4d 0x68 0x7c 0x8c 0x9a 0xa7 0xb2 0xbd 0xc7 0xd0 0xd9 0xe1 0xe9 0xf1 0xf8 0xff 0x4d 0x68 0x7c 0x8c 0x9a 0xa7 0xb2 0xbd 0xc7 0xd0 0xd9 0xe1 0xe9 0xf1 0xf8 0xff
Signed-off-by: Byeongsik Jeon bsjeon@hanmail.net
dlls/gdi32/dibdrv/primitives.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/gdi32/dibdrv/primitives.c b/dlls/gdi32/dibdrv/primitives.c index caf2d890b5..ecdf52c7cc 100644 --- a/dlls/gdi32/dibdrv/primitives.c +++ b/dlls/gdi32/dibdrv/primitives.c @@ -6046,7 +6046,7 @@ static const BYTE ramp[17] = 0, 0x4d, 0x68, 0x7c, 0x8c, 0x9a, 0xa7, 0xb2, 0xbd, 0xc7, 0xd0, 0xd9,
- 0xe1, 0xe9, 0xf0, 0xf8,
- 0xe1, 0xe9, 0xf1, 0xf8, 0xff
The original values were obtained from native, so the numbers are 'correct'. As mentioned in the comment, the data were then to used obtain the equation (mainly just for the sake of interest).
Huw.
Signed-off-by: Byeongsik Jeon bsjeon@hanmail.net --- dlls/gdi32/dibdrv/primitives.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/gdi32/dibdrv/primitives.c b/dlls/gdi32/dibdrv/primitives.c index ecdf52c7cc..c300051c38 100644 --- a/dlls/gdi32/dibdrv/primitives.c +++ b/dlls/gdi32/dibdrv/primitives.c @@ -6052,12 +6052,12 @@ static const BYTE ramp[17] =
static inline BYTE aa_color( BYTE dst, BYTE text, BYTE alpha ) { + BYTE intensity; + if (dst == text) return dst;
- if (dst > text) - return ( text * ( 0xff - ramp[16 - alpha] ) + dst * ramp[16 - alpha] ) / 0xff; - else - return ( text * ramp[alpha] + dst * ( 0xff - ramp[alpha] ) ) / 0xff; + intensity = ( dst > text )? 0xff - ramp[16 - alpha] : ramp[alpha]; + return blend_color( dst, text, intensity ); }
static inline DWORD aa_rgb( BYTE r_dst, BYTE g_dst, BYTE b_dst, DWORD text, BYTE alpha )
On Thu, Oct 11, 2018 at 10:12:12PM +0900, Byeongsik Jeon wrote:
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?
The ramp values were deliberately kept out of primitive.c as these are parameters rather than the implemention. The numbers in the ramp table come from comparing with the native values.
Huw.
PS, for dibdrv patches, please prefix the commit log with "gdi32:".
On Fri, 12 Oct 2018 08:15:40 +0100, Huw Davies huw@codeweavers.com wrote:
The ramp values were deliberately kept out of primitive.c as these are parameters rather than the implemention. The numbers in the ramp table come from comparing with the native values.
Huw.
PS, for dibdrv patches, please prefix the commit log with "gdi32:".
OK.
On Fri, 12 Oct 2018 16:20:24 +0900, Byeongsik Jeon bsjeon@hanmail.net wrote:> Sorry.
Please cancel this patch 1,3.
This patch will be rewritten in the process of creating another additional patch. This patch is moving code incorrectly. But I would appreciate it if you could point out whether the idea of the code strip is correct.
I'm creating a subpixel intensities adjustment patch related SPI_SETFONTSMOOTHINGCONTRAST.
Please comment for the SPI_SETFONTSMOOTHINGCONTRAST. I'm going to use the following formula to implement this.
gamma_encode( blend_color( gamma_decode(dst), gamma_decode(text), alpha );
This gamma is a different meaning from the display gamma. This is close to the contrast. Only the formula uses the gamma correction pattern.
On Fri, Oct 12, 2018 at 04:47:49PM +0900, Byeongsik Jeon wrote:
Please comment for the SPI_SETFONTSMOOTHINGCONTRAST. I'm going to use the following formula to implement this.
gamma_encode( blend_color( gamma_decode(dst), gamma_decode(text), alpha );
This gamma is a different meaning from the display gamma. This is close to the contrast. Only the formula uses the gamma correction pattern.
Please send in the patch you want me to comment on.
Huw.
Sorry.
Please cancel this patch 1,3.
This patch will be rewritten in the process of creating another additional patch. This patch is moving code incorrectly. But I would appreciate it if you could point out whether the idea of the code strip is correct.
I'm creating a subpixel intensities adjustment patch related SPI_SETFONTSMOOTHINGCONTRAST.
Thanks.
On Thu, 11 Oct 2018 22:12:12 +0900, Byeongsik Jeon bsjeon@hanmail.net wrote:
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);
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);const POINT *origin, DWORD text_pixel);
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;
- }
elsereturn ( text * ( 0xff - ramp[16 - alpha] ) + dst * ramp[16 - alpha] ) / 0xff;
- {
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; }