unoplatform / uno

Open-source platform for building cross-platform native Mobile, Web, Desktop and Embedded apps quickly. Create rich, C#/XAML, single-codebase apps from any IDE. Hot Reload included! 90m+ NuGet Downloads!!
https://platform.uno
Apache License 2.0
9.09k stars 739 forks source link

[Fonts] FontWeights are not being respected for .ttf files containing multiple weights #13725

Open kazo0 opened 1 year ago

kazo0 commented 1 year ago

Current behavior

Using a font file that contains multiple font weights in a single file does not seem to work on Uno platforms.

Example, take the .ttf file from Roboto Flex (RobotoFlex.zip) and use it with the following XAML

AppResources.xaml

<Style TargetType="TextBlock">
    <Setter Property="FontFamily" Value="ms-appx:///UnoApp68/Assets/RobotoFlex.ttf" />
    <Setter Property="FontSize" Value="40" />
</Style>

MainPage.xaml

<StackPanel HorizontalAlignment="Center"
            VerticalAlignment="Center">
    <TextBlock Text="ExtraBlack"
               FontWeight="ExtraBlack"
               HorizontalAlignment="Center" />
    <TextBlock Text="Black"
               FontWeight="Black"
               HorizontalAlignment="Center" />
    <TextBlock Text="ExtraBold"
               FontWeight="ExtraBold"
               HorizontalAlignment="Center" />
    <TextBlock Text="Bold"
               FontWeight="Bold"
               HorizontalAlignment="Center" />
    <TextBlock Text="SemiBold"
               FontWeight="SemiBold"
               HorizontalAlignment="Center" />
    <TextBlock Text="Medium"
               FontWeight="Medium"
               HorizontalAlignment="Center" />
    <TextBlock Text="Normal"
               FontWeight="Normal"
               HorizontalAlignment="Center" />
    <TextBlock Text="SemiLight"
               FontWeight="SemiLight"
               HorizontalAlignment="Center" />
    <TextBlock Text="Light"
               FontWeight="Light"
               HorizontalAlignment="Center" />
    <TextBlock Text="ExtraLight"
               FontWeight="ExtraLight"
               HorizontalAlignment="Center" />
</StackPanel>

Results in the following comparison between Windows and WASM:

Screenshot 2023-09-20 155334

Expected behavior

Should look like this:

image

How to reproduce it (as minimally and precisely as possible)

UnoApp68.zip

Workaround

No response

Works on UWP/WinUI

Yes

Environment

Uno.WinUI / Uno.WinUI.WebAssembly / Uno.WinUI.Skia

NuGet package version(s)

Uno.WinUI 4.10.13

Affected platforms

WebAssembly, Android, iOS, macOS (AppKit), Mac Catalyst, Skia (WPF), Skia (GTK on Linux/macOS/Windows), Skia (Linux Framebuffer)

IDE

No response

IDE version

No response

Relevant plugins

No response

Anything else we need to know?

No response

ramezgerges commented 1 year ago

I've looked into this for skia a little bit, and I initially thought the problem would be in our HarfBuzz logic, but it seems to be at the SkiaSharp level. HarfBuzz doesn't seem to recognise different font faces in the same font file. For example,

new Font(new Face(Blob.FromFile(@"uno\src\SamplesApp\SamplesApp.Skia.Gtk\bin\Debug\net7.0\Assets\RobotoFlex.ttf"), 0)

and

new Font(new Face(Blob.FromFile(@"uno\src\SamplesApp\SamplesApp.Skia.Gtk\bin\Debug\net7.0\Assets\RobotoFlex.ttf"), 1)

will yield the exact same TextBlock Segment measurements (more on this in Run.skia.cs).

However, ignoring HarfBuzz for now, things seem to work when I provide a second parameter to https://github.com/unoplatform/uno/blob/0c1ece4ac0082e0b3ee9a5808205f7c92aec92ea/src/Uno.UI/UI/Xaml/Documents/TextFormatting/FontDetailsCache.skia.cs#L51

image

The second parameter is supposed to select a specific face, but it seems that any integer value other than the default 0 does the same thing. However, this breaks some glyphs like the hamburger menu glyph in SamplesApp.

I couldn't investigate any further after that.

ramezgerges commented 10 months ago

Relevant: https://github.com/mono/SkiaSharp/issues/2397