--- v2: [PATCH 5/5] ~0u -> 0xffffff
"if (glyph_ptr[x] == ~0u) { dst_ptr[x] = text_pixel; continue; }" I realized that this line is not working. I'm sorry that didn't review it more carefully.
I got 10% additional performance improvement, so re-tested the entire test.
--- After commit 649dd12, I propose some improvements related to the dibdrv FontSmoothingGamma code. Using pre-computed value and Removing branches in the inline function can provide some performance improvements.
CrystalMark2004R7 GDI Text Bench result(5times average) [1][2]:
- OLD : 6673 (100%) pre 649dd12 - CURRENT : 5584 ( 84%) with gamma == 1000 - CURRENT : 4989 ( 75%) with gamma != 1000 - PATCH v2 1/5: 5125 ( 77%) - PATCH v2 2/5: 5528 ( 83%) - PATCH v2 5/5: 6772 (101%)
Please, Note that OLD and CURRENT(gamma == 1000) doesn't have FontSmoothingGamma ability.
These improvements allow to change the gamma default value to 1400(MS GDI32 default value), while reducing performance losses.
[1] If the dibdrv glyph caching code is turned off, the CrystalMark result value is reduced by 10 times! With the dibdrv glyph cache ON, the performance factors in the pre-caching phase are hidden. This indicates that dibdrv::draw_glyph() performance is the dominant factor of the CrystalMark result value.
The result does not represent GDI32 text engine performance in all situations, but it can be referred to in the current situation.
[2] CrystalMark apply different weights to the result value calculation depending on the fontsmoothing type. And current Wine does not synchronize the xrdb resource values and the SystemParametersInfo() results.
Therefore, required some attention in the configuration of the test environment and the result analysis. I tested it under the conditions below:
$ xrdb -remove $ winetricks fontsmooth=rgb
Byeong-Sik Jeon (5): win32u: Remove gamma == 1000 special case code. win32u: Use pre-calculated decoded_text value. win32u: Remove the gamma value calibration code. win32u: Set the default gamma value to 1400. win32u: Remove the branches in blend_color_gamma().
dlls/win32u/dibdrv/primitives.c | 74 +++++++++++++++++---------------- dlls/win32u/font.c | 13 ++---- dlls/win32u/freetype.c | 4 +- 3 files changed, 43 insertions(+), 48 deletions(-)
Signed-off-by: Byeongsik Jeon bsjeon@hanmail.net --- v2: no change.
dlls/win32u/dibdrv/primitives.c | 12 +++--------- dlls/win32u/font.c | 10 ++++------ 2 files changed, 7 insertions(+), 15 deletions(-)
diff --git a/dlls/win32u/dibdrv/primitives.c b/dlls/win32u/dibdrv/primitives.c index 3633c687e78..c9432fca4b8 100644 --- a/dlls/win32u/dibdrv/primitives.c +++ b/dlls/win32u/dibdrv/primitives.c @@ -6354,15 +6354,9 @@ static inline BYTE blend_color_gamma( BYTE dst, BYTE text, BYTE alpha, static inline DWORD blend_subpixel( BYTE r, BYTE g, BYTE b, DWORD text, DWORD alpha, const struct font_gamma_ramp *gamma_ramp ) { - if (gamma_ramp != NULL && gamma_ramp->gamma != 1000) - { - return blend_color_gamma( r, text >> 16, (BYTE)(alpha >> 16), gamma_ramp ) << 16 | - blend_color_gamma( g, text >> 8, (BYTE)(alpha >> 8), gamma_ramp ) << 8 | - blend_color_gamma( b, text, (BYTE) alpha, gamma_ramp ); - } - return blend_color( r, text >> 16, (BYTE)(alpha >> 16) ) << 16 | - blend_color( g, text >> 8, (BYTE)(alpha >> 8) ) << 8 | - blend_color( b, text, (BYTE) alpha ); + return blend_color_gamma( r, text >> 16, alpha >> 16, gamma_ramp ) << 16 | + blend_color_gamma( g, text >> 8, alpha >> 8, gamma_ramp ) << 8 | + blend_color_gamma( b, text, alpha, gamma_ramp ); }
static void draw_subpixel_glyph_8888( const dib_info *dib, const RECT *rect, const dib_info *glyph, diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c index 0c14f90afa5..c7d2059da02 100644 --- a/dlls/win32u/font.c +++ b/dlls/win32u/font.c @@ -4356,13 +4356,11 @@ static UINT init_font_options(void) This looks roughly similar to Windows Native with the same registry value. MS GDI seems to be rasterizing the outline at a different rate than FreeType. */ gamma = 1000 * gamma / 1400; - if (gamma != 1000) + + for (i = 0; i < 256; i++) { - for (i = 0; i < 256; i++) - { - font_gamma_ramp.encode[i] = pow( i / 255., 1000. / gamma ) * 255. + .5; - font_gamma_ramp.decode[i] = pow( i / 255., gamma / 1000. ) * 255. + .5; - } + font_gamma_ramp.encode[i] = pow( i / 255., 1000. / gamma ) * 255. + .5; + font_gamma_ramp.decode[i] = pow( i / 255., gamma / 1000. ) * 255. + .5; }
if (!dpi && (key = reg_open_key( NULL, fonts_config_keyW, sizeof(fonts_config_keyW) )))
Signed-off-by: Byeongsik Jeon bsjeon@hanmail.net --- v2: no change.
Because text_pixel does not change, we can use pre-computed gamma_ramp->decode[text] value.
dlls/win32u/dibdrv/primitives.c | 53 ++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 17 deletions(-)
diff --git a/dlls/win32u/dibdrv/primitives.c b/dlls/win32u/dibdrv/primitives.c index c9432fca4b8..4687ead5585 100644 --- a/dlls/win32u/dibdrv/primitives.c +++ b/dlls/win32u/dibdrv/primitives.c @@ -6339,24 +6339,22 @@ static void draw_glyph_null( const dib_info *dib, const RECT *rect, const dib_in { return; } -static inline BYTE blend_color_gamma( BYTE dst, BYTE text, BYTE alpha, +static inline BYTE blend_color_gamma( BYTE dst, BYTE text, BYTE decoded_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 ) ]; + return gamma_ramp->encode[ blend_color( gamma_ramp->decode[dst], decoded_text, alpha ) ]; }
-static inline DWORD blend_subpixel( BYTE r, BYTE g, BYTE b, DWORD text, DWORD alpha, +static inline DWORD blend_subpixel( BYTE r, BYTE g, BYTE b, DWORD text, DWORD decoded_text, DWORD alpha, const struct font_gamma_ramp *gamma_ramp ) { - return blend_color_gamma( r, text >> 16, alpha >> 16, gamma_ramp ) << 16 | - blend_color_gamma( g, text >> 8, alpha >> 8, gamma_ramp ) << 8 | - blend_color_gamma( b, text, alpha, gamma_ramp ); + return blend_color_gamma( r, text >> 16, decoded_text >> 16, alpha >> 16, gamma_ramp ) << 16 | + blend_color_gamma( g, text >> 8, decoded_text >> 8, alpha >> 8, gamma_ramp ) << 8 | + blend_color_gamma( b, text, decoded_text, alpha, gamma_ramp ); }
static void draw_subpixel_glyph_8888( const dib_info *dib, const RECT *rect, const dib_info *glyph, @@ -6366,6 +6364,11 @@ static void draw_subpixel_glyph_8888( const dib_info *dib, const RECT *rect, con DWORD *dst_ptr = get_pixel_ptr_32( dib, rect->left, rect->top ); const DWORD *glyph_ptr = get_pixel_ptr_32( glyph, origin->x, origin->y ); int x, y; + DWORD decoded_text; + + decoded_text = gamma_ramp->decode[ (BYTE)(text_pixel >> 16) ] << 16 | + gamma_ramp->decode[ (BYTE)(text_pixel >> 8 ) ] << 8 | + gamma_ramp->decode[ (BYTE)(text_pixel ) ];
for (y = rect->top; y < rect->bottom; y++) { @@ -6373,7 +6376,7 @@ static void draw_subpixel_glyph_8888( const dib_info *dib, const RECT *rect, con { if (glyph_ptr[x] == 0) continue; dst_ptr[x] = blend_subpixel( dst_ptr[x] >> 16, dst_ptr[x] >> 8, dst_ptr[x], - text_pixel, glyph_ptr[x], gamma_ramp ); + text_pixel, decoded_text, glyph_ptr[x], gamma_ramp ); } dst_ptr += dib->stride / 4; glyph_ptr += glyph->stride / 4; @@ -6387,12 +6390,16 @@ static void draw_subpixel_glyph_32( const dib_info *dib, const RECT *rect, const DWORD *dst_ptr = get_pixel_ptr_32( dib, rect->left, rect->top ); const DWORD *glyph_ptr = get_pixel_ptr_32( glyph, origin->x, origin->y ); int x, y; - DWORD text, val; + DWORD text, decoded_text, val;
text = get_field( text_pixel, dib->red_shift, dib->red_len ) << 16 | get_field( text_pixel, dib->green_shift, dib->green_len ) << 8 | get_field( text_pixel, dib->blue_shift, dib->blue_len );
+ decoded_text = gamma_ramp->decode[ (BYTE)(text >> 16) ] << 16 | + gamma_ramp->decode[ (BYTE)(text >> 8 ) ] << 8 | + gamma_ramp->decode[ (BYTE)(text ) ]; + for (y = rect->top; y < rect->bottom; y++) { for (x = 0; x < rect->right - rect->left; x++) @@ -6401,7 +6408,7 @@ static void draw_subpixel_glyph_32( const dib_info *dib, const RECT *rect, const val = blend_subpixel( 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, glyph_ptr[x], gamma_ramp ); + text, decoded_text, glyph_ptr[x], gamma_ramp ); dst_ptr[x] = rgb_to_pixel_masks( dib, val >> 16, val >> 8, val ); } dst_ptr += dib->stride / 4; @@ -6416,7 +6423,11 @@ static void draw_subpixel_glyph_24( const dib_info *dib, const RECT *rect, const BYTE *dst_ptr = get_pixel_ptr_24( dib, rect->left, rect->top ); const DWORD *glyph_ptr = get_pixel_ptr_32( glyph, origin->x, origin->y ); int x, y; - DWORD val; + DWORD decoded_text, val; + + decoded_text = gamma_ramp->decode[ (BYTE)(text_pixel >> 16) ] << 16 | + gamma_ramp->decode[ (BYTE)(text_pixel >> 8 ) ] << 8 | + gamma_ramp->decode[ (BYTE)(text_pixel ) ];
for (y = rect->top; y < rect->bottom; y++) { @@ -6424,7 +6435,7 @@ static void draw_subpixel_glyph_24( const dib_info *dib, const RECT *rect, const { if (glyph_ptr[x] == 0) continue; val = blend_subpixel( dst_ptr[x * 3 + 2], dst_ptr[x * 3 + 1], dst_ptr[x * 3], - text_pixel, glyph_ptr[x], gamma_ramp ); + text_pixel, decoded_text, glyph_ptr[x], gamma_ramp ); dst_ptr[x * 3] = val; dst_ptr[x * 3 + 1] = val >> 8; dst_ptr[x * 3 + 2] = val >> 16; @@ -6441,12 +6452,16 @@ static void draw_subpixel_glyph_555( const dib_info *dib, const RECT *rect, cons WORD *dst_ptr = get_pixel_ptr_16( dib, rect->left, rect->top ); const DWORD *glyph_ptr = get_pixel_ptr_32( glyph, origin->x, origin->y ); int x, y; - DWORD text, val; + DWORD text, decoded_text, val;
text = ((text_pixel << 9) & 0xf80000) | ((text_pixel << 4) & 0x070000) | ((text_pixel << 6) & 0x00f800) | ((text_pixel << 1) & 0x000700) | ((text_pixel << 3) & 0x0000f8) | ((text_pixel >> 2) & 0x000007);
+ decoded_text = gamma_ramp->decode[ (BYTE)(text >> 16) ] << 16 | + gamma_ramp->decode[ (BYTE)(text >> 8 ) ] << 8 | + gamma_ramp->decode[ (BYTE)(text ) ]; + for (y = rect->top; y < rect->bottom; y++) { for (x = 0; x < rect->right - rect->left; x++) @@ -6455,7 +6470,7 @@ static void draw_subpixel_glyph_555( const dib_info *dib, const RECT *rect, cons val = blend_subpixel( ((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, glyph_ptr[x], NULL ); + text, decoded_text, glyph_ptr[x], NULL ); dst_ptr[x] = ((val >> 9) & 0x7c00) | ((val >> 6) & 0x03e0) | ((val >> 3) & 0x001f); } dst_ptr += dib->stride / 2; @@ -6470,12 +6485,16 @@ static void draw_subpixel_glyph_16( const dib_info *dib, const RECT *rect, const WORD *dst_ptr = get_pixel_ptr_16( dib, rect->left, rect->top ); const DWORD *glyph_ptr = get_pixel_ptr_32( glyph, origin->x, origin->y ); int x, y; - DWORD text, val; + DWORD text, decoded_text, val;
text = get_field( text_pixel, dib->red_shift, dib->red_len ) << 16 | get_field( text_pixel, dib->green_shift, dib->green_len ) << 8 | get_field( text_pixel, dib->blue_shift, dib->blue_len );
+ decoded_text = gamma_ramp->decode[ (BYTE)(text >> 16) ] << 16 | + gamma_ramp->decode[ (BYTE)(text >> 8 ) ] << 8 | + gamma_ramp->decode[ (BYTE)(text ) ]; + for (y = rect->top; y < rect->bottom; y++) { for (x = 0; x < rect->right - rect->left; x++) @@ -6484,7 +6503,7 @@ static void draw_subpixel_glyph_16( const dib_info *dib, const RECT *rect, const val = blend_subpixel( 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, glyph_ptr[x], NULL ); + text, decoded_text, glyph_ptr[x], NULL ); dst_ptr[x] = rgb_to_pixel_masks( dib, val >> 16, val >> 8, val ); } dst_ptr += dib->stride / 2;
Signed-off-by: Byeongsik Jeon bsjeon@hanmail.net --- v2: no change.
This problem is caused by the FreeType hinting engine. Here this code is unnecessary.
dlls/win32u/font.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c index c7d2059da02..12260881a1d 100644 --- a/dlls/win32u/font.c +++ b/dlls/win32u/font.c @@ -4312,7 +4312,7 @@ static UINT init_font_options(void) char value_buffer[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[20 * sizeof(WCHAR)])]; KEY_VALUE_PARTIAL_INFORMATION *info = (void *)value_buffer; HKEY key; - DWORD i, val, gamma = 1400; + DWORD i, val, gamma = 1000; UINT dpi = 0;
if (query_reg_ascii_value( wine_fonts_key, "AntialiasFakeBoldOrItalic", @@ -4352,11 +4352,6 @@ static UINT init_font_options(void) NtClose( key ); }
- /* Calibrating the difference between the registry value and the Wine gamma value. - This looks roughly similar to Windows Native with the same registry value. - MS GDI seems to be rasterizing the outline at a different rate than FreeType. */ - gamma = 1000 * gamma / 1400; - for (i = 0; i < 256; i++) { font_gamma_ramp.encode[i] = pow( i / 255., 1000. / gamma ) * 255. + .5;
Signed-off-by: Byeongsik Jeon bsjeon@hanmail.net --- v2: no change.
dlls/win32u/font.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c index 12260881a1d..8a6cda2f500 100644 --- a/dlls/win32u/font.c +++ b/dlls/win32u/font.c @@ -4312,7 +4312,7 @@ static UINT init_font_options(void) char value_buffer[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[20 * sizeof(WCHAR)])]; KEY_VALUE_PARTIAL_INFORMATION *info = (void *)value_buffer; HKEY key; - DWORD i, val, gamma = 1000; + DWORD i, val, gamma = 1400; UINT dpi = 0;
if (query_reg_ascii_value( wine_fonts_key, "AntialiasFakeBoldOrItalic",
Signed-off-by: Byeongsik Jeon bsjeon@hanmail.net --- v2: ~0u --> 0xffffff, and add 'commit 11d68d0' supplemental code.
Numerically, there is a difference in code behavior because it only processes the full pixel alpha value 0xFFFFFF.
For example, if the red subpixel alpha value is 0xFF, the dst red subpixel is calculated by:
gamma->encode[ blend_color( gamma->decode[dst.r], gamma->decode[text.r], alpha.r) ]
alpha.r == 0xFF, so, gamma->encode[ gamma->decode[text.r] ]
The original code will get text.r, but the changed code will cause little errors.
However, since the affected pixels have already been changed by the LCD Filter, I wonder if they require strict subpixel color accuracy.
dlls/win32u/dibdrv/primitives.c | 65 ++++++++++++++------------------- dlls/win32u/freetype.c | 4 +- 2 files changed, 29 insertions(+), 40 deletions(-)
diff --git a/dlls/win32u/dibdrv/primitives.c b/dlls/win32u/dibdrv/primitives.c index 4687ead5585..d9d54179b54 100644 --- a/dlls/win32u/dibdrv/primitives.c +++ b/dlls/win32u/dibdrv/primitives.c @@ -6339,22 +6339,18 @@ static void draw_glyph_null( const dib_info *dib, const RECT *rect, const dib_in { return; } -static inline BYTE blend_color_gamma( BYTE dst, BYTE text, BYTE decoded_text, BYTE alpha, +static inline BYTE blend_color_gamma( BYTE dst, BYTE decoded_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], decoded_text, alpha ) ]; }
-static inline DWORD blend_subpixel( BYTE r, BYTE g, BYTE b, DWORD text, DWORD decoded_text, DWORD alpha, +static inline DWORD blend_subpixel( BYTE r, BYTE g, BYTE b, DWORD decoded_text, DWORD alpha, const struct font_gamma_ramp *gamma_ramp ) { - return blend_color_gamma( r, text >> 16, decoded_text >> 16, alpha >> 16, gamma_ramp ) << 16 | - blend_color_gamma( g, text >> 8, decoded_text >> 8, alpha >> 8, gamma_ramp ) << 8 | - blend_color_gamma( b, text, decoded_text, alpha, gamma_ramp ); + return blend_color_gamma( r, decoded_text >> 16, alpha >> 16, gamma_ramp ) << 16 | + blend_color_gamma( g, decoded_text >> 8, alpha >> 8, gamma_ramp ) << 8 | + blend_color_gamma( b, decoded_text, alpha, gamma_ramp ); }
static void draw_subpixel_glyph_8888( const dib_info *dib, const RECT *rect, const dib_info *glyph, @@ -6375,8 +6371,9 @@ static void draw_subpixel_glyph_8888( const dib_info *dib, const RECT *rect, con for (x = 0; x < rect->right - rect->left; x++) { if (glyph_ptr[x] == 0) continue; + if (glyph_ptr[x] == 0xffffff) { dst_ptr[x] = text_pixel; continue; } dst_ptr[x] = blend_subpixel( dst_ptr[x] >> 16, dst_ptr[x] >> 8, dst_ptr[x], - text_pixel, decoded_text, glyph_ptr[x], gamma_ramp ); + decoded_text, glyph_ptr[x], gamma_ramp ); } dst_ptr += dib->stride / 4; glyph_ptr += glyph->stride / 4; @@ -6390,25 +6387,22 @@ static void draw_subpixel_glyph_32( const dib_info *dib, const RECT *rect, const DWORD *dst_ptr = get_pixel_ptr_32( dib, rect->left, rect->top ); const DWORD *glyph_ptr = get_pixel_ptr_32( glyph, origin->x, origin->y ); int x, y; - DWORD text, decoded_text, val; - - text = get_field( text_pixel, dib->red_shift, dib->red_len ) << 16 | - get_field( text_pixel, dib->green_shift, dib->green_len ) << 8 | - get_field( text_pixel, dib->blue_shift, dib->blue_len ); + DWORD decoded_text, val;
- decoded_text = gamma_ramp->decode[ (BYTE)(text >> 16) ] << 16 | - gamma_ramp->decode[ (BYTE)(text >> 8 ) ] << 8 | - gamma_ramp->decode[ (BYTE)(text ) ]; + decoded_text = gamma_ramp->decode[ get_field( text_pixel, dib->red_shift, dib->red_len ) ] << 16 | + gamma_ramp->decode[ get_field( text_pixel, dib->green_shift, dib->green_len ) ] << 8 | + gamma_ramp->decode[ get_field( text_pixel, dib->blue_shift, dib->blue_len ) ];
for (y = rect->top; y < rect->bottom; y++) { for (x = 0; x < rect->right - rect->left; x++) { if (glyph_ptr[x] == 0) continue; + if (glyph_ptr[x] == 0xffffff) { dst_ptr[x] = text_pixel; continue; } val = blend_subpixel( 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, decoded_text, glyph_ptr[x], gamma_ramp ); + decoded_text, glyph_ptr[x], gamma_ramp ); dst_ptr[x] = rgb_to_pixel_masks( dib, val >> 16, val >> 8, val ); } dst_ptr += dib->stride / 4; @@ -6434,8 +6428,9 @@ static void draw_subpixel_glyph_24( const dib_info *dib, const RECT *rect, const for (x = 0; x < rect->right - rect->left; x++) { if (glyph_ptr[x] == 0) continue; + if (glyph_ptr[x] == 0xffffff) { dst_ptr[x] = text_pixel; continue; } val = blend_subpixel( dst_ptr[x * 3 + 2], dst_ptr[x * 3 + 1], dst_ptr[x * 3], - text_pixel, decoded_text, glyph_ptr[x], gamma_ramp ); + decoded_text, glyph_ptr[x], gamma_ramp ); dst_ptr[x * 3] = val; dst_ptr[x * 3 + 1] = val >> 8; dst_ptr[x * 3 + 2] = val >> 16; @@ -6452,25 +6447,22 @@ static void draw_subpixel_glyph_555( const dib_info *dib, const RECT *rect, cons WORD *dst_ptr = get_pixel_ptr_16( dib, rect->left, rect->top ); const DWORD *glyph_ptr = get_pixel_ptr_32( glyph, origin->x, origin->y ); int x, y; - DWORD text, decoded_text, val; - - text = ((text_pixel << 9) & 0xf80000) | ((text_pixel << 4) & 0x070000) | - ((text_pixel << 6) & 0x00f800) | ((text_pixel << 1) & 0x000700) | - ((text_pixel << 3) & 0x0000f8) | ((text_pixel >> 2) & 0x000007); + DWORD decoded_text, val;
- decoded_text = gamma_ramp->decode[ (BYTE)(text >> 16) ] << 16 | - gamma_ramp->decode[ (BYTE)(text >> 8 ) ] << 8 | - gamma_ramp->decode[ (BYTE)(text ) ]; + decoded_text = gamma_ramp->decode[ ((text_pixel >> 7) & 0xf8) | ((text_pixel >> 12) & 0x07) ] << 16 | + gamma_ramp->decode[ ((text_pixel >> 2) & 0xf8) | ((text_pixel >> 7) & 0x07) ] << 8 | + gamma_ramp->decode[ ((text_pixel << 3) & 0xf8) | ((text_pixel >> 2) & 0x07) ];
for (y = rect->top; y < rect->bottom; y++) { for (x = 0; x < rect->right - rect->left; x++) { if (glyph_ptr[x] == 0) continue; + if (glyph_ptr[x] == 0xffffff) { dst_ptr[x] = text_pixel; continue; } val = blend_subpixel( ((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, decoded_text, glyph_ptr[x], NULL ); + decoded_text, glyph_ptr[x], NULL ); dst_ptr[x] = ((val >> 9) & 0x7c00) | ((val >> 6) & 0x03e0) | ((val >> 3) & 0x001f); } dst_ptr += dib->stride / 2; @@ -6485,25 +6477,22 @@ static void draw_subpixel_glyph_16( const dib_info *dib, const RECT *rect, const WORD *dst_ptr = get_pixel_ptr_16( dib, rect->left, rect->top ); const DWORD *glyph_ptr = get_pixel_ptr_32( glyph, origin->x, origin->y ); int x, y; - DWORD text, decoded_text, val; - - text = get_field( text_pixel, dib->red_shift, dib->red_len ) << 16 | - get_field( text_pixel, dib->green_shift, dib->green_len ) << 8 | - get_field( text_pixel, dib->blue_shift, dib->blue_len ); + DWORD decoded_text, val;
- decoded_text = gamma_ramp->decode[ (BYTE)(text >> 16) ] << 16 | - gamma_ramp->decode[ (BYTE)(text >> 8 ) ] << 8 | - gamma_ramp->decode[ (BYTE)(text ) ]; + decoded_text = gamma_ramp->decode[ get_field( text_pixel, dib->red_shift, dib->red_len ) ] << 16 | + gamma_ramp->decode[ get_field( text_pixel, dib->green_shift, dib->green_len ) ] << 8 | + gamma_ramp->decode[ get_field( text_pixel, dib->blue_shift, dib->blue_len ) ];
for (y = rect->top; y < rect->bottom; y++) { for (x = 0; x < rect->right - rect->left; x++) { if (glyph_ptr[x] == 0) continue; + if (glyph_ptr[x] == 0xffffff) { dst_ptr[x] = text_pixel; continue; } val = blend_subpixel( 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, decoded_text, glyph_ptr[x], NULL ); + decoded_text, glyph_ptr[x], NULL ); dst_ptr[x] = rgb_to_pixel_masks( dib, val >> 16, val >> 8, val ); } dst_ptr += dib->stride / 2; diff --git a/dlls/win32u/freetype.c b/dlls/win32u/freetype.c index f00df7ed86d..21dad3612a7 100644 --- a/dlls/win32u/freetype.c +++ b/dlls/win32u/freetype.c @@ -3082,8 +3082,8 @@ static DWORD get_subpixel_glyph_bitmap( FT_GlyphSlot glyph, FT_BBox bbox, UINT f { if ( src[x / 8] & masks[x % 8] ) { - ((unsigned int *)dst)[x] = ~0u; - if (fake_bold && x + 1 < width) ((unsigned int *)dst)[x + 1] = ~0u; + ((unsigned int *)dst)[x] = 0xffffff; + if (fake_bold && x + 1 < width) ((unsigned int *)dst)[x + 1] = 0xffffff; } } src += glyph->bitmap.pitch;