Description
- .NET Version: 6.0
- Windows version: Windows 10 21H2 (19044.1526)
- Does the bug reproduce also in WPF for .NET Framework 4.8?: Yes
Problem description:
When using a font that is embedded as a <Resource>
(see fonts as resource items), the performance of rendering text can be extremely poor.
This was first noted in a production .NET 4.8 WPF Application; a detailed writeup of the problem and a solution that was found is at https://faithlife.codes/blog/2019/06/improving-wpf-text-display-performance/.
Actual behavior:
dotTrace shows that very large amounts of time are spent in MS.Internal.Text.TextInterface.FontFileStream.ReadFileFragment
. Additionally, large amounts of memory are allocated and the program spends a lot of time in GC.
Expected behavior:
Rendering a <Resource>
font is extremely efficient because the resource is already mmap'ed into memory and returning its data could be as simple as a pointer addition.
Minimal repro:
An example repro is at https://github.com/bgrainger/EmbeddedFontPerformance. Clone the repo, build the code, and scroll the text box. You'll notice that it can take several seconds to draw the next screen of text (depending on how large the window is).
The following text complements that repo and describes how it reproduces the problem:
This reproduces most easily with the Noto Sans CJK font (perhaps because of the large number of glyphs that have to be read?).
Embed the font:
<ItemGroup>
<Resource Include="NotoSansCJKtc-Regular.otf" />
</ItemGroup>
Then create a text box that references the font and contains a large amount of Chinese text:
<Grid>
<ScrollViewer>
<TextBlock FontFamily="./#Noto Sans CJK TC" TextWrapping="Wrap">
<!-- place Chinese text here -->
</TextBlock>
</ScrollViewer>
</Grid>
Run the app and scroll the ScrollViewer.