[PATCH v2 2/3] gdi32: Support the WINE_GGO_GRAY16_BITMAP at the dibdrv.

Byeongsik Jeon bsjeon at hanmail.net
Sun Nov 4 23:08:51 CST 2018


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




More information about the wine-devel mailing list