diff --git a/dlls/gdi32/dibdrv/dc.c b/dlls/gdi32/dibdrv/dc.c index 3ccdd043c4f..0a75bd2fc55 100644 --- a/dlls/gdi32/dibdrv/dc.c +++ b/dlls/gdi32/dibdrv/dc.c @@ -528,6 +528,7 @@ static COLORREF dibdrv_SetTextColor( PHYSDEV dev, COLORREF color ) dibdrv_physdev *pdev = get_dibdrv_pdev(dev); pdev->text_color = get_pixel_color( pdev, color, TRUE ); + update_aa_ranges( pdev ); return next->funcs->pSetTextColor( next, color ); } diff --git a/dlls/gdi32/dibdrv/dibdrv.h b/dlls/gdi32/dibdrv/dibdrv.h index 2e7ac01d61f..46ce0047d7d 100644 --- a/dlls/gdi32/dibdrv/dibdrv.h +++ b/dlls/gdi32/dibdrv/dibdrv.h @@ -67,6 +67,13 @@ typedef struct void *xor; } rop_mask_bits; +struct intensity_range +{ + BYTE r_min, r_max; + BYTE g_min, g_max; + BYTE b_min, b_max; +}; + typedef struct dibdrv_physdev { struct gdi_physdev dev; @@ -100,6 +107,7 @@ typedef struct dibdrv_physdev /* text */ DWORD text_color; + struct intensity_range glyph_intensities[17]; } dibdrv_physdev; #define DEFER_FORMAT 1 @@ -218,6 +226,7 @@ extern HRGN add_extra_clipping_region( dibdrv_physdev *pdev, HRGN rgn ) DECLSPEC extern void restore_clipping_region( dibdrv_physdev *pdev, HRGN rgn ) DECLSPEC_HIDDEN; extern int clip_line(const POINT *start, const POINT *end, const RECT *clip, const bres_params *params, POINT *pt1, POINT *pt2) DECLSPEC_HIDDEN; +extern void update_aa_ranges( dibdrv_physdev *pdev ) DECLSPEC_HIDDEN; static inline BOOL defer_pen(dibdrv_physdev *pdev) { diff --git a/dlls/gdi32/dibdrv/graphics.c b/dlls/gdi32/dibdrv/graphics.c index 82aaafac484..343dd0d3306 100644 --- a/dlls/gdi32/dibdrv/graphics.c +++ b/dlls/gdi32/dibdrv/graphics.c @@ -56,6 +56,53 @@ static RECT get_device_rect( HDC hdc, int left, int top, int right, int bottom, return rect; } +/* 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; +} + +void update_aa_ranges( dibdrv_physdev *pdev ) +{ + int i; + COLORREF text = pdev->dib.funcs->pixel_to_colorref( &pdev->dib, pdev->text_color ); + + for (i = 0; i < 17; i++) + { + get_range( i, GetRValue(text), &pdev->glyph_intensities[i].r_min, &pdev->glyph_intensities[i].r_max ); + get_range( i, GetGValue(text), &pdev->glyph_intensities[i].g_min, &pdev->glyph_intensities[i].g_max ); + get_range( i, GetBValue(text), &pdev->glyph_intensities[i].b_min, &pdev->glyph_intensities[i].b_max ); + } +} + /********************************************************************** * get_text_bkgnd_masks *