Default font scaling corrections and optimizations. Fix #11037.
Fixes #11037
Proposed changes
- Сhange the default font only if it has really changed. Most of these problems already was solved in f36b0db2400247c3ed68b9538f92ab6914896b1d.
- Not use scaled default font for system fonts.
- Not dispose user (external) fonts.
Customer Impact
- Fewer font changing related actions and a bit less memory use.
- Bug fixes.
Regression?
- Yes
Risk
- Minimal.
Test methodology
- Existing unit tests.
- New unit tests.
- Manually with test app: DefFontTest.zip
Microsoft Reviewers: Open in CodeFlow
Codecov Report
Attention: Patch coverage is 61.53846% with 40 lines in your changes missing coverage. Please review.
Project coverage is 74.84486%. Comparing base (
bacb9f8) to head (10a2a9e). Report is 20 commits behind head on main.
Additional details and impacted files
@@ Coverage Diff @@
## main #11206 +/- ##
===================================================
+ Coverage 74.84172% 74.84486% +0.00314%
===================================================
Files 3012 3014 +2
Lines 629272 629414 +142
Branches 46693 46716 +23
===================================================
+ Hits 470958 471084 +126
- Misses 154952 154961 +9
- Partials 3362 3369 +7
| Flag | Coverage Δ | |
|---|---|---|
| Debug | 74.84486% <61.53846%> (+0.00314%) |
:arrow_up: |
| integration | 18.04056% <0.00000%> (-0.00817%) |
:arrow_down: |
| production | 47.84827% <39.13043%> (+0.00791%) |
:arrow_up: |
| test | 97.00904% <79.31034%> (-0.00352%) |
:arrow_down: |
| unit | 44.87828% <39.13043%> (+0.00979%) |
:arrow_up: |
Flags with carried forward coverage won't be shown. Click here to find out more.
@Olina-Zhang can your team please test this?
Hi @kirsan31 I tested this PR change using provided test app, it still see fontCache in memory leak, has the same behavior before.
Your PR change result:
Also it is different from the result with .NET framework 4.8.1, there is no fontCache found:
So I want to check with you to make sure it's verified that way?
@Olina-Zhang
So I want to check with you to make sure it's verified that way?
- In #11037 initially we are talking about gdi font leak. So when testing I've cheked GDI handles count in task manager.
- The problem is in
FontCachethat was introduced in .Net5. So before it everything was ok. FontCacheis caching fonts references so it will grow - it's normal.- The main problem of #11037 was implicitly fixed by Jeremy in .Net9 by this commit https://github.com/dotnet/winforms/commit/f36b0db2400247c3ed68b9538f92ab6914896b1d. But my PR fix this explicitly (this will prevent possible font leaks from other sources in the future) and make all related things clearer. So to see this difference you need to test it for example vs .net8 version and see gdi handles leak every rdp connect only in .net8.
- My PR also fix 2 bugs (appear in https://github.com/dotnet/winforms/commit/f36b0db2400247c3ed68b9538f92ab6914896b1d) explained here: you need to launch exe from
SysFontandSysFontDef, then change text size in windows (Settings-Accessibility-Text size) and see that def version is not scaled.
I hope I remembered everything correctly and not missed something...
@kirsan31 based on your comment, re-tested it with following result, please take a look:
- Check GDI objects for every rdp connection, found in .NET9.0 with your change and without your change, they are same, not increased, and in .NET 8.0, increased every time rdp connection
- Tested various configuration values with
SysFontandSysFontDefwhen changing text size in windows (Settings-Accessibility-Text size), results on .NET9 and .NET8 are same: .NET9:
https://github.com/dotnet/winforms/assets/26474449/43aa85c1-3ecd-4822-96e9-ae6a0b8583fb
.NET8:
https://github.com/dotnet/winforms/assets/26474449/9934c6c9-c860-4661-997e-a681cab22c6b
@Olina-Zhang
- 👍
- Very strange behavior of text scaling on your pc - I see no caption scaling 🤷♂️ My result:
https://github.com/dotnet/winforms/assets/17767561/0bc960e1-3471-43f0-8fed-d7a97809fbe5
As you can see on my pc window caption scaling too also text scaling apply going through blue Wait screen... As why button text also scaling in your test I really don't know - it's cant be :))) I see no changes in scale method (and other) since my PR: https://github.com/dotnet/winforms/blob/dd6025d972f902b83c1d15ba7cd1ff3e9eef3afd/src/System.Windows.Forms.Primitives/src/System/Windows/Forms/Internals/ScaleHelper.cs#L221-L226 The method done nothing if we have system font as default.
May be all problems are related to that caption not scaling (it must scale in any versions). Other of this I have only tow guess:
- This code from
Program.cswas not executed:
#elif SYSFONT || SYSFONTDEF
Application.SetDefaultFont(System.Drawing.SystemFonts.SmallCaptionFont);
System.Drawing.SystemFonts.SmallCaptionFontthen returnIsSystemFont == falseon your pc 🤷♂️
This is re-testing for your change on different configuration(You can see the execution of the code in program.cs ), same as last time we tested:
https://github.com/dotnet/winforms/assets/26474449/8acdb318-fcb4-4d98-a715-2a98ca127a9a
This is re-testing for your change on different configuration(You can see the execution of the code in program.cs ), same as last time we tested:
Then the problem in whole system as I said I see no window caption increase (must work in all version net/app) and this is not good 🤷♂️ Can you set breakpoint at this line:
https://github.com/dotnet/winforms/blob/dd6025d972f902b83c1d15ba7cd1ff3e9eef3afd/src/System.Windows.Forms.Primitives/src/System/Windows/Forms/Internals/ScaleHelper.cs#L223
and check IsSystemFont for SmallCaptionFont?
Also, I will test it too with latest .Net9 build when I have time.
and check
IsSystemFontforSmallCaptionFont?
It doesn't go into this method: ScaleHelper.ScaleToSystemTextSize
and check
IsSystemFontforSmallCaptionFont?It doesn't go into this method:
ScaleHelper.ScaleToSystemTextSize
This is my branch - but the problem in main without my changes it's must not scale system font...
The Def versions must compiled against clean 9 sdk installed:
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net9.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<Configurations>Debug;SysFont;Font;DebugDef;SysFontDef;FontDef</Configurations>
</PropertyGroup>
<ItemGroup Condition="'$(Configuration)' == 'Debug' or '$(Configuration)' == 'SysFont' or '$(Configuration)' == 'Font'">
<Reference Include="e:\Projects\Other\winforms\artifacts\bin\System.Windows.Forms\Debug\net9.0\System.Windows.Forms.dll" />
<Reference Include="e:\Projects\Other\winforms\artifacts\bin\System.Windows.Forms.Primitives\Debug\net9.0\System.Windows.Forms.Primitives.dll" />
<Reference Include="e:\Projects\Other\winforms\artifacts\bin\System.Private.Windows.Core\Debug\net9.0\System.Private.Windows.Core.dll" />
</ItemGroup>
</Project>
In Winforms main branch, the font is null:
In Winforms main branch, the font is null:
This can't be. I've checked current main code - no changes was made in executing path. Also tested with latest sdk - result the same:
- We check
SYSFONTDEFversion. SYSFONTDEFversion must be compiled aginst clean .Net9 sdk.- This code must be executed:
#elif SYSFONT || SYSFONTDEF
Application.SetDefaultFont(System.Drawing.SystemFonts.SmallCaptionFont);
System.Drawing.SystemFonts.SmallCaptionFont can't be null here because of:
https://github.com/dotnet/winforms/blob/6bf29db65a28bab6270ca7c7c16f2144f14cbc62/src/System.Windows.Forms/src/System/Windows/Forms/Application.cs#L1200-L1202
down a bit in SetDefaultFont we set Application.s_defaultFont:
https://github.com/dotnet/winforms/blob/6bf29db65a28bab6270ca7c7c16f2144f14cbc62/src/System.Windows.Forms/src/System/Windows/Forms/Application.cs#L1212-L1214
- After text scale we call
ScaleDefaultFontin this place (note thats_defaultFonthere is different variable this isControl.s_defaultFont):
https://github.com/dotnet/winforms/blob/6bf29db65a28bab6270ca7c7c16f2144f14cbc62/src/System.Windows.Forms/src/System/Windows/Forms/Control.cs#L12924-L12925
ScaleDefaultFont code:
https://github.com/dotnet/winforms/blob/6bf29db65a28bab6270ca7c7c16f2144f14cbc62/src/System.Windows.Forms/src/System/Windows/Forms/Application.cs#L1217-L1224
So font in ScaleToSystemTextSize cannot be null.
I think the problem must be in point 1 - 3. Or we found other intresting bug 🙄
@lonitra can you pull this one back to main?
- Rebased on main.
- Suggestions implemented.

