Alexandre Julliard : gdi32: Scale stock fonts based on the DPI awareness.

Alexandre Julliard julliard at winehq.org
Thu Apr 12 15:28:14 CDT 2018


Module: wine
Branch: master
Commit: 60085f4e36d97938a1e7365161eb8f8b09140824
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=60085f4e36d97938a1e7365161eb8f8b09140824

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Apr 12 13:50:01 2018 +0200

gdi32: Scale stock fonts based on the DPI awareness.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/gdi32/gdiobj.c           | 41 +++++++++++++++++++++------------------
 dlls/user32/tests/sysparams.c | 45 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+), 19 deletions(-)

diff --git a/dlls/gdi32/gdiobj.c b/dlls/gdi32/gdiobj.c
index db03f49..819d24a 100644
--- a/dlls/gdi32/gdiobj.c
+++ b/dlls/gdi32/gdiobj.c
@@ -108,6 +108,7 @@ static const LOGPEN DCPen     = { PS_SOLID, { 0, 0 }, RGB(0,0,0) };
 #define NB_STOCK_OBJECTS (STOCK_LAST+2)
 
 static HGDIOBJ stock_objects[NB_STOCK_OBJECTS];
+static HGDIOBJ scaled_stock_objects[NB_STOCK_OBJECTS];
 
 static CRITICAL_SECTION gdi_section;
 static CRITICAL_SECTION_DEBUG critsect_debug =
@@ -662,7 +663,6 @@ DWORD get_system_dpi(void)
 static HFONT create_scaled_font( const LOGFONTW *deffont )
 {
     LOGFONTW lf;
-    LONG height;
     static DWORD dpi;
 
     if (!dpi)
@@ -672,9 +672,7 @@ static HFONT create_scaled_font( const LOGFONTW *deffont )
     }
 
     lf = *deffont;
-    height = abs(lf.lfHeight) * dpi / 96;
-    lf.lfHeight = deffont->lfHeight < 0 ? -height : height;
-
+    lf.lfHeight = MulDiv( lf.lfHeight, dpi, 96 );
     return CreateFontIndirectW( &lf );
 }
 
@@ -716,10 +714,15 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
 
     /* language-dependent stock fonts */
     deffonts = get_default_fonts(get_default_charset());
-    stock_objects[SYSTEM_FONT]         = create_scaled_font( &deffonts->SystemFont );
-    stock_objects[DEVICE_DEFAULT_FONT] = create_scaled_font( &deffonts->DeviceDefaultFont );
+    stock_objects[SYSTEM_FONT]         = CreateFontIndirectW( &deffonts->SystemFont );
+    stock_objects[DEVICE_DEFAULT_FONT] = CreateFontIndirectW( &deffonts->DeviceDefaultFont );
     stock_objects[SYSTEM_FIXED_FONT]   = CreateFontIndirectW( &deffonts->SystemFixedFont );
-    stock_objects[DEFAULT_GUI_FONT]    = create_scaled_font( &deffonts->DefaultGuiFont );
+    stock_objects[DEFAULT_GUI_FONT]    = CreateFontIndirectW( &deffonts->DefaultGuiFont );
+
+    scaled_stock_objects[OEM_FIXED_FONT]    = create_scaled_font( &OEMFixedFont );
+    scaled_stock_objects[SYSTEM_FONT]       = create_scaled_font( &deffonts->SystemFont );
+    scaled_stock_objects[SYSTEM_FIXED_FONT] = create_scaled_font( &deffonts->SystemFixedFont );
+    scaled_stock_objects[DEFAULT_GUI_FONT]  = create_scaled_font( &deffonts->DefaultGuiFont );
 
     stock_objects[DC_BRUSH]     = CreateBrushIndirect( &DCBrush );
     stock_objects[DC_PEN]       = CreatePenIndirect( &DCPen );
@@ -727,15 +730,9 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
     /* clear the NOSYSTEM bit on all stock objects*/
     for (i = 0; i < NB_STOCK_OBJECTS; i++)
     {
-        if (!stock_objects[i])
-        {
-            if (i == 9) continue;  /* there's no stock object 9 */
-            ERR( "could not create stock object %d\n", i );
-            return FALSE;
-        }
-        __wine_make_gdi_object_system( stock_objects[i], TRUE );
+        if (stock_objects[i]) __wine_make_gdi_object_system( stock_objects[i], TRUE );
+        if (scaled_stock_objects[i]) __wine_make_gdi_object_system( scaled_stock_objects[i], TRUE );
     }
-
     return TRUE;
 }
 
@@ -1061,11 +1058,17 @@ void GDI_hdc_not_using_object(HGDIOBJ obj, HDC hdc)
  */
 HGDIOBJ WINAPI GetStockObject( INT obj )
 {
-    HGDIOBJ ret;
     if ((obj < 0) || (obj >= NB_STOCK_OBJECTS)) return 0;
-    ret = stock_objects[obj];
-    TRACE("returning %p\n", ret );
-    return ret;
+    switch (obj)
+    {
+    case OEM_FIXED_FONT:
+    case SYSTEM_FONT:
+    case SYSTEM_FIXED_FONT:
+    case DEFAULT_GUI_FONT:
+        if (get_system_dpi() != 96) return scaled_stock_objects[obj];
+        break;
+    }
+    return stock_objects[obj];
 }
 
 
diff --git a/dlls/user32/tests/sysparams.c b/dlls/user32/tests/sysparams.c
index 4d60ea5..780cfbb 100644
--- a/dlls/user32/tests/sysparams.c
+++ b/dlls/user32/tests/sysparams.c
@@ -3001,6 +3001,50 @@ static void test_GetSysColorBrush(void)
         win_skip("COLOR_MENUBAR unsupported\n");
 }
 
+static void test_dpi_stock_objects( HDC hdc )
+{
+    DPI_AWARENESS_CONTEXT context;
+    HGDIOBJ obj[STOCK_LAST + 1], obj2[STOCK_LAST + 1];
+    LOGFONTW lf, lf2;
+    UINT i, dpi;
+
+    context = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
+    dpi = GetDeviceCaps( hdc, LOGPIXELSX );
+    ok( dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", dpi );
+    ok( !pIsProcessDPIAware(), "not aware\n" );
+    for (i = 0; i <= STOCK_LAST; i++) obj[i] = GetStockObject( i );
+
+    pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
+    dpi = GetDeviceCaps( hdc, LOGPIXELSX );
+    ok( dpi == real_dpi, "wrong dpi %u\n", dpi );
+    ok( pIsProcessDPIAware(), "not aware\n" );
+    for (i = 0; i <= STOCK_LAST; i++) obj2[i] = GetStockObject( i );
+
+    for (i = 0; i <= STOCK_LAST; i++)
+    {
+        switch (i)
+        {
+        case OEM_FIXED_FONT:
+        case SYSTEM_FIXED_FONT:
+            ok( obj[i] != obj2[i], "%u: same object\n", i );
+            break;
+        case SYSTEM_FONT:
+        case DEFAULT_GUI_FONT:
+            ok( obj[i] != obj2[i], "%u: same object\n", i );
+            GetObjectW( obj[i], sizeof(lf), &lf );
+            GetObjectW( obj2[i], sizeof(lf2), &lf2 );
+            ok( lf.lfHeight == MulDiv( lf2.lfHeight, USER_DEFAULT_SCREEN_DPI, real_dpi ),
+                "%u: wrong height %d / %d\n", i, lf.lfHeight, lf2.lfHeight );
+            break;
+        default:
+            ok( obj[i] == obj2[i], "%u: different object\n", i );
+            break;
+        }
+    }
+
+    pSetThreadDpiAwarenessContext( context );
+}
+
 static void test_dpi_aware(void)
 {
     BOOL ret;
@@ -3181,6 +3225,7 @@ static void test_dpi_aware(void)
                 break;
             }
         }
+        if (real_dpi != USER_DEFAULT_SCREEN_DPI) test_dpi_stock_objects( hdc );
         ReleaseDC( 0, hdc );
     }
     else win_skip( "SetProcessDpiAwarenessContext not supported\n" );




More information about the wine-cvs mailing list