[PATCH 1/3] dibdrv: Refactoring the gray text rendering intensities control code.

Byeongsik Jeon bsjeon at hanmail.net
Thu Oct 11 08:12:12 CDT 2018


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 at 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;
 }
-- 
2.19.1




More information about the wine-devel mailing list