winforms icon indicating copy to clipboard operation
winforms copied to clipboard

Default font scaling corrections and optimizations. Fix #11037.

Open kirsan31 opened this issue 1 year ago • 12 comments

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

kirsan31 avatar Apr 12 '24 10:04 kirsan31

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.

codecov[bot] avatar Apr 12 '24 10:04 codecov[bot]

@Olina-Zhang can your team please test this?

elachlan avatar Jun 22 '24 02:06 elachlan

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: image

Also it is different from the result with .NET framework 4.8.1, there is no fontCache found: image

So I want to check with you to make sure it's verified that way?

Olina-Zhang avatar Jun 24 '24 06:06 Olina-Zhang

@Olina-Zhang

So I want to check with you to make sure it's verified that way?

  1. In #11037 initially we are talking about gdi font leak. So when testing I've cheked GDI handles count in task manager.
  2. The problem is in FontCache that was introduced in .Net5. So before it everything was ok.
  3. FontCache is caching fonts references so it will grow - it's normal.
  4. 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.
  5. My PR also fix 2 bugs (appear in https://github.com/dotnet/winforms/commit/f36b0db2400247c3ed68b9538f92ab6914896b1d) explained here: you need to launch exe from SysFont and SysFontDef, 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 avatar Jun 25 '24 14:06 kirsan31

@kirsan31 based on your comment, re-tested it with following result, please take a look:

  1. 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 image
  2. Tested various configuration values with SysFont and SysFontDef when 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 avatar Jun 26 '24 08:06 Olina-Zhang

@Olina-Zhang

  1. 👍
  2. 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:

  1. This code from Program.cs was not executed:
#elif SYSFONT || SYSFONTDEF
            Application.SetDefaultFont(System.Drawing.SystemFonts.SmallCaptionFont);
  1. System.Drawing.SystemFonts.SmallCaptionFont then return IsSystemFont == false on your pc 🤷‍♂️

kirsan31 avatar Jun 26 '24 09:06 kirsan31

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

Olina-Zhang avatar Jun 26 '24 10:06 Olina-Zhang

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.

kirsan31 avatar Jun 26 '24 10:06 kirsan31

and check IsSystemFont for SmallCaptionFont?

It doesn't go into this method: ScaleHelper.ScaleToSystemTextSize image

Olina-Zhang avatar Jun 26 '24 11:06 Olina-Zhang

and check IsSystemFont for SmallCaptionFont?

It doesn't go into this method: ScaleHelper.ScaleToSystemTextSize image

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>

kirsan31 avatar Jun 26 '24 11:06 kirsan31

In Winforms main branch, the font is null: image

Olina-Zhang avatar Jun 27 '24 02:06 Olina-Zhang

In Winforms main branch, the font is null: image

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: image

  1. We check SYSFONTDEF version.
  2. SYSFONTDEF version must be compiled aginst clean .Net9 sdk.
  3. 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

  1. After text scale we call ScaleDefaultFont in this place (note that s_defaultFont here is different variable this is Control.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 🙄

kirsan31 avatar Jun 27 '24 07:06 kirsan31

@lonitra can you pull this one back to main?

JeremyKuhne avatar Jul 24 '24 23:07 JeremyKuhne

  • Rebased on main.
  • Suggestions implemented.

kirsan31 avatar Aug 03 '24 13:08 kirsan31