Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/gdi32/font.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-)
diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c index db87a283b13..cb170c0b862 100644 --- a/dlls/gdi32/font.c +++ b/dlls/gdi32/font.c @@ -3891,23 +3891,24 @@ const struct gdi_dc_funcs font_driver = GDI_PRIORITY_FONT_DRV /* priority */ };
-static DWORD get_key_value( HKEY key, const WCHAR *name, DWORD *value ) +static DWORD get_key_value( HKEY key1, HKEY key2, const WCHAR *name, DWORD *value ) { WCHAR buf[12]; DWORD count = sizeof(buf), type, err;
- err = RegQueryValueExW( key, name, NULL, &type, (BYTE *)buf, &count ); - if (!err) - { - if (type == REG_DWORD) memcpy( value, buf, sizeof(*value) ); - else *value = wcstol( buf, NULL, 10 ); - } - return err; + if ((err = RegQueryValueExW( key1, name, NULL, &type, (BYTE *)buf, &count )) + && (err = RegQueryValueExW( key2, name, NULL, &type, (BYTE *)buf, &count ))) + return err; + + if (type == REG_DWORD) memcpy( value, buf, sizeof(*value) ); + else *value = wcstol( buf, NULL, 10 ); + + return 0; }
static void init_font_options(void) { - HKEY key; + HKEY key, volatile_key = NULL; DWORD i, type, size, val, gamma = 1400; WCHAR buffer[20];
@@ -3920,8 +3921,10 @@ static void init_font_options(void)
if (!RegOpenKeyW( HKEY_CURRENT_USER, L"Control Panel\Desktop", &key )) { + RegOpenKeyW( HKEY_CURRENT_USER, L"Software\Wine\Temporary System Parameters\Control Panel\Desktop", + &volatile_key ); /* FIXME: handle vertical orientations even though Windows doesn't */ - if (!get_key_value( key, L"FontSmoothingOrientation", &val )) + if (!get_key_value( volatile_key, key, L"FontSmoothingOrientation", &val )) { switch (val) { @@ -3933,18 +3936,20 @@ static void init_font_options(void) break; } } - if (!get_key_value( key, L"FontSmoothing", &val ) && val /* enabled */) + if (!get_key_value( volatile_key, key, L"FontSmoothing", &val ) && val /* enabled */) { - if (!get_key_value( key, L"FontSmoothingType", &val ) && val == 2 /* FE_FONTSMOOTHINGCLEARTYPE */) + if (!get_key_value( volatile_key, key, L"FontSmoothingType", &val ) && val == 2 /* FE_FONTSMOOTHINGCLEARTYPE */) font_smoothing = subpixel_orientation; else font_smoothing = GGO_GRAY4_BITMAP; } - if (!get_key_value( key, L"FontSmoothingGamma", &val ) && val) + if (!get_key_value( volatile_key, key, L"FontSmoothingGamma", &val ) && val) { gamma = min( max( val, 1000 ), 2200 ); } RegCloseKey( key ); + if (volatile_key) + RegCloseKey( volatile_key ); }
/* Calibrating the difference between the registry value and the Wine gamma value.
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/winex11.drv/xrender.c | 61 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+)
diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c index 3376cee517d..14ce9e73975 100644 --- a/dlls/winex11.drv/xrender.c +++ b/dlls/winex11.drv/xrender.c @@ -32,6 +32,7 @@
#include "windef.h" #include "winbase.h" +#include "winreg.h" #include "x11drv.h" #include "winternl.h" #include "wine/unicode.h" @@ -314,6 +315,64 @@ static int load_xrender_formats(void) return count; }
+static void set_default_font_smoothing(void) +{ + DWORD smoothing_type, orientation, vertical; + BOOL smoothing; + HKEY sysparam_key; + char *value; + + if ((value = XGetDefault( gdi_display, "Xft", "antialias" ))) + { + TRACE( "got antialias '%s'.\n", value ); + smoothing = !(tolower(value[0]) == 'f' || tolower(value[0]) == 'n' || + value[0] == '0' || !_strnicmp( value, "off", -1 )); + SystemParametersInfoA(SPI_SETFONTSMOOTHING, smoothing, NULL, 0); + } + else + { + if (!SystemParametersInfoA(SPI_GETFONTSMOOTHING, 0, &smoothing, 0)) + smoothing = FALSE; + } + + if ((value = XGetDefault( gdi_display, "Xft", "rgba" ))) + { + TRACE( "got rgba '%s'.\n", value ); + + vertical = 0; + orientation = smoothing_type = ~0u; + if (!strcmp( value, "rgb" ) || (vertical = !strcmp( value, "vrgb" ))) + { + smoothing_type = FE_FONTSMOOTHINGCLEARTYPE; + orientation = FE_FONTSMOOTHINGORIENTATIONRGB; + } + else if (!strcmp( value, "bgr" ) || (vertical = !strcmp( value, "vbgr" ))) + { + smoothing_type = FE_FONTSMOOTHINGCLEARTYPE; + orientation = FE_FONTSMOOTHINGORIENTATIONBGR; + } + else if (!strcmp( value, "none" )) + { + smoothing_type = FE_FONTSMOOTHINGSTANDARD; + } + + if (smoothing) + { + if (smoothing_type != ~0u) + SystemParametersInfoA(SPI_SETFONTSMOOTHINGTYPE, 0, (void *)(ULONG_PTR)smoothing_type, 0); + if (orientation != ~0u) + SystemParametersInfoA(SPI_SETFONTSMOOTHINGORIENTATION, 0, (void *)(ULONG_PTR)orientation, 0); + } + + if (smoothing_type != ~0u && !RegOpenKeyA( HKEY_CURRENT_USER, + "Software\Wine\Temporary System Parameters\Control Panel\Desktop", &sysparam_key )) + { + RegSetValueExA( sysparam_key, "FontSmoothingVertical", 0, REG_DWORD, (BYTE *)&vertical, sizeof(vertical) ); + RegCloseKey( sysparam_key ); + } + } +} + /*********************************************************************** * X11DRV_XRender_Init * @@ -379,6 +438,8 @@ const struct gdi_dc_funcs *X11DRV_XRender_Init(void) } glyphsetCache[i-1].next = -1;
+ set_default_font_smoothing(); + return &xrender_funcs; }
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/gdi32/font.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c index cb170c0b862..c545274c46e 100644 --- a/dlls/gdi32/font.c +++ b/dlls/gdi32/font.c @@ -3909,7 +3909,7 @@ static DWORD get_key_value( HKEY key1, HKEY key2, const WCHAR *name, DWORD *valu static void init_font_options(void) { HKEY key, volatile_key = NULL; - DWORD i, type, size, val, gamma = 1400; + DWORD i, type, size, val, gamma = 1400, vertical = 0; WCHAR buffer[20];
size = sizeof(buffer); @@ -3923,16 +3923,18 @@ static void init_font_options(void) { RegOpenKeyW( HKEY_CURRENT_USER, L"Software\Wine\Temporary System Parameters\Control Panel\Desktop", &volatile_key ); - /* FIXME: handle vertical orientations even though Windows doesn't */ + + get_key_value( volatile_key, key, L"FontSmoothingVertical", &vertical ); + if (!get_key_value( volatile_key, key, L"FontSmoothingOrientation", &val )) { switch (val) { case 0: /* FE_FONTSMOOTHINGORIENTATIONBGR */ - subpixel_orientation = WINE_GGO_HBGR_BITMAP; + subpixel_orientation = vertical ? WINE_GGO_VBGR_BITMAP : WINE_GGO_HBGR_BITMAP; break; case 1: /* FE_FONTSMOOTHINGORIENTATIONRGB */ - subpixel_orientation = WINE_GGO_HRGB_BITMAP; + subpixel_orientation = vertical ? WINE_GGO_VRGB_BITMAP : WINE_GGO_HRGB_BITMAP; break; } }
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/winex11.drv/xrender.c | 11 ----------- 1 file changed, 11 deletions(-)
diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c index 14ce9e73975..f4f1ab64401 100644 --- a/dlls/winex11.drv/xrender.c +++ b/dlls/winex11.drv/xrender.c @@ -856,17 +856,6 @@ static UINT get_xft_aa_flags( const LOGFONTW *lf ) case NONANTIALIASED_QUALITY: case ANTIALIASED_QUALITY: break; - default: - if (!(value = XGetDefault( gdi_display, "Xft", "antialias" ))) break; - TRACE( "got antialias '%s'\n", value ); - if (tolower(value[0]) == 'f' || tolower(value[0]) == 'n' || - value[0] == '0' || !_strnicmp( value, "off", -1 )) - { - ret = GGO_BITMAP; - break; - } - ret = GGO_GRAY4_BITMAP; - /* fall through */ case CLEARTYPE_QUALITY: case CLEARTYPE_NATURAL_QUALITY: if (!(value = XGetDefault( gdi_display, "Xft", "rgba" ))) break;
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45857 Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/gdi32/font.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+)
diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c index c545274c46e..c393599eeed 100644 --- a/dlls/gdi32/font.c +++ b/dlls/gdi32/font.c @@ -42,6 +42,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(font);
static HKEY wine_fonts_key; static HKEY wine_fonts_cache_key; +static HKEY volatile_parameters_key; +static HANDLE volatile_parameters_changed_event;
struct font_physdev { @@ -97,6 +99,8 @@ static struct font_gamma_ramp font_gamma_ramp; static void add_face_to_cache( struct gdi_font_face *face ); static void remove_face_from_cache( struct gdi_font_face *face );
+static void update_font_options(void); + static inline WCHAR facename_tolower( WCHAR c ) { if (c >= 'A' && c <= 'Z') return c - 'A' + 'a'; @@ -3739,6 +3743,8 @@ static HFONT CDECL font_SelectFont( PHYSDEV dev, HFONT hfont, UINT *aa_flags ) *aa_flags = font->aa_flags; if (!*aa_flags) { + update_font_options(); + if (lf.lfQuality == CLEARTYPE_QUALITY || lf.lfQuality == CLEARTYPE_NATURAL_QUALITY) *aa_flags = subpixel_orientation; else @@ -3919,6 +3925,9 @@ static void init_font_options(void) antialias_fakes = (wcschr(L"yYtT1", buffer[0]) != NULL); }
+ font_smoothing = 0; + subpixel_orientation = 0; + if (!RegOpenKeyW( HKEY_CURRENT_USER, L"Control Panel\Desktop", &key )) { RegOpenKeyW( HKEY_CURRENT_USER, L"Software\Wine\Temporary System Parameters\Control Panel\Desktop", @@ -3967,6 +3976,30 @@ static void init_font_options(void) TRACE("gamma %d\n", font_gamma_ramp.gamma); }
+static void update_font_options(void) +{ + EnterCriticalSection( &font_cs ); + if (!volatile_parameters_key) + { + if (RegOpenKeyW( HKEY_CURRENT_USER, L"Software\Wine\Temporary System Parameters\Control Panel\Desktop", + &volatile_parameters_key )) + goto done; + volatile_parameters_changed_event = CreateEventA( NULL, FALSE, TRUE, NULL ); + } + if (WaitForSingleObject( volatile_parameters_changed_event, 0 ) == WAIT_OBJECT_0) + { + if (RegNotifyChangeKeyValue( volatile_parameters_key, FALSE, + REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_THREAD_AGNOSTIC, + volatile_parameters_changed_event, TRUE)) + ERR("Error registering registry change notification.\n"); + + init_font_options(); + } + +done: + LeaveCriticalSection( &font_cs ); +} +
static void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW ) {
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/gdi32/tests/dib.c | 45 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-)
diff --git a/dlls/gdi32/tests/dib.c b/dlls/gdi32/tests/dib.c index d16cb0df5c0..8cd054f7183 100644 --- a/dlls/gdi32/tests/dib.c +++ b/dlls/gdi32/tests/dib.c @@ -3007,7 +3007,7 @@ static inline COLORREF aa_colorref( COLORREF dst, COLORREF text, BYTE glyph )
static const BYTE masks[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
-static void draw_text_2( HDC hdc, const BITMAPINFO *bmi, BYTE *bits, BOOL aa ) +static void draw_text_2( HDC hdc, const BITMAPINFO *bmi, BYTE *bits, BYTE quality, BOOL expected_aa ) { DWORD dib_size = get_dib_size(bmi), ret; LOGFONTA lf; @@ -3029,7 +3029,7 @@ static void draw_text_2( HDC hdc, const BITMAPINFO *bmi, BYTE *bits, BOOL aa ) memset( &lf, 0, sizeof(lf) ); strcpy( lf.lfFaceName, "Tahoma" ); lf.lfHeight = 24; - lf.lfQuality = aa ? ANTIALIASED_QUALITY : NONANTIALIASED_QUALITY; + lf.lfQuality = quality;
font = CreateFontIndirectA( &lf ); font = SelectObject( hdc, font ); @@ -3054,12 +3054,12 @@ static void draw_text_2( HDC hdc, const BITMAPINFO *bmi, BYTE *bits, BOOL aa ) for(i = 0; i < dib_size; i++) bits[i] = vals[i % 4];
- if (bmi->bmiHeader.biBitCount <= 8) aa = FALSE; + if (bmi->bmiHeader.biBitCount <= 8) expected_aa = FALSE;
text_color = GetTextColor( hdc ); for (i = 0; i < strlen(str); i++) { - DWORD ggo_flags = aa ? GGO_GRAY4_BITMAP : GGO_BITMAP; + DWORD ggo_flags = expected_aa ? GGO_GRAY4_BITMAP : GGO_BITMAP;
ret = GetGlyphOutlineA( hdc, str[i], ggo_flags, &gm, 0, NULL, &identity );
@@ -3075,7 +3075,7 @@ static void draw_text_2( HDC hdc, const BITMAPINFO *bmi, BYTE *bits, BOOL aa )
if (!ret) continue;
- if (aa) + if (expected_aa) { stride = (gm.gmBlackBoxX + 3) & ~3;
@@ -3114,7 +3114,7 @@ static void draw_text_2( HDC hdc, const BITMAPINFO *bmi, BYTE *bits, BOOL aa ) }
diy_hash = hash_dib( hdc, bmi, bits ); - ok( !strcmp( eto_hash, diy_hash ), "hash mismatch - aa %d\n", aa ); + ok( !strcmp( eto_hash, diy_hash ), "hash mismatch - quality %#x, expected_aa %d\n", quality, expected_aa );
HeapFree( GetProcessHeap(), 0, diy_hash ); HeapFree( GetProcessHeap(), 0, eto_hash ); @@ -3125,14 +3125,43 @@ static void draw_text_2( HDC hdc, const BITMAPINFO *bmi, BYTE *bits, BOOL aa )
static void draw_text( HDC hdc, const BITMAPINFO *bmi, BYTE *bits ) { - draw_text_2( hdc, bmi, bits, FALSE ); + UINT smoothing, type; + BOOL ret; + + draw_text_2( hdc, bmi, bits, NONANTIALIASED_QUALITY, FALSE ); + + ret = SystemParametersInfoA(SPI_GETFONTSMOOTHING, 0, &smoothing, 0); + ok(ret, "SystemParametersInfoA failed, GetLastError() %u.\n", GetLastError()); + + ret = SystemParametersInfoA(SPI_SETFONTSMOOTHING, 0, NULL, 0); + ok(ret, "SystemParametersInfoA failed, GetLastError() %u.\n", GetLastError()); + draw_text_2( hdc, bmi, bits, DEFAULT_QUALITY, FALSE );
/* Rounding errors make these cases hard to test */ if ((bmi->bmiHeader.biCompression == BI_BITFIELDS && ((DWORD*)bmi->bmiColors)[0] == 0x3f000) || (bmi->bmiHeader.biBitCount == 16)) + { + ret = SystemParametersInfoA(SPI_SETFONTSMOOTHING, smoothing, NULL, 0); + ok(ret, "SystemParametersInfoA failed, GetLastError() %u.\n", GetLastError()); return; + } + + ret = SystemParametersInfoA(SPI_SETFONTSMOOTHING, 1, NULL, 0); + ok(ret, "SystemParametersInfoA failed, GetLastError() %u.\n", GetLastError()); + ret = SystemParametersInfoA(SPI_GETFONTSMOOTHINGTYPE, 0, &type, 0); + ok(ret, "SystemParametersInfoA failed, GetLastError() %u.\n", GetLastError()); + ret = SystemParametersInfoA(SPI_SETFONTSMOOTHINGTYPE, 0, (void *)FE_FONTSMOOTHINGSTANDARD, 0); + ok(ret, "SystemParametersInfoA failed, GetLastError() %u.\n", GetLastError()); + + draw_text_2( hdc, bmi, bits, DEFAULT_QUALITY, TRUE ); + + ret = SystemParametersInfoA(SPI_SETFONTSMOOTHINGTYPE, 0, (void *)(ULONG_PTR)type, 0); + ok(ret, "SystemParametersInfoA failed, GetLastError() %u.\n", GetLastError()); + + ret = SystemParametersInfoA(SPI_SETFONTSMOOTHING, smoothing, NULL, 0); + ok(ret, "SystemParametersInfoA failed, GetLastError() %u.\n", GetLastError());
- draw_text_2( hdc, bmi, bits, TRUE ); + draw_text_2( hdc, bmi, bits, ANTIALIASED_QUALITY, TRUE ); }
static void test_simple_graphics(void)