Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Skia GTK: Text block does not display #6441

Closed
3 of 24 tasks
dradtke opened this issue Jul 9, 2021 · 19 comments · Fixed by #9591
Closed
3 of 24 tasks

Skia GTK: Text block does not display #6441

dradtke opened this issue Jul 9, 2021 · 19 comments · Fixed by #9591
Assignees
Labels
area/skia ✏️ Categorizes an issue or PR as relevant to Skia difficulty/tbd Categorizes an issue for which the difficulty level needs to be defined. kind/bug Something isn't working project/core-tools 🛠️ Categorizes an issue or PR as relevant to core and tools

Comments

@dradtke
Copy link

dradtke commented Jul 9, 2021

Current behavior

When I create a new Uno project on Linux and run the GTK subproject, it just displays a white background with no text, and these errors in the console:

fail: Windows.UI.Xaml.Controls.CommandBarFlyout[0]
      The member CommandBarFlyout.CommandBarFlyout() is not implemented in Uno.
fail: Windows.UI.Xaml.Controls.TextCommandBarFlyout[0]
      The member TextCommandBarFlyout.TextCommandBarFlyout() is not implemented in Uno.
warn: Windows.UI.Composition.TextVisual[0]
      The font Segoe UI could not be found, using system default
fail: Windows.UI.Composition.CompositionObject[0]
      The member void CompositionObject.Dispose() is not implemented in Uno.

I asked about this in Discord, and was told that Uno was likely unable to find my system default font. They suggested running it with FC_DEBUG=1, which produced a bunch of additional output (see uno.log), but I am not able to see in that output anything helpful for fixing the issue.

Expected behavior

I see the text "Hello there, world!"

Minimal repro project is here: https://git.sr.ht/~damien/shopping-uno

Workaround

N/A

Works on UWP/WinUI

N/A

Environment

Nuget Package:

  • Uno.UI / Uno.UI.WebAssembly / Uno.UI.Skia
  • Uno.WinUI / Uno.WinUI.WebAssembly / Uno.WinUI.Skia
  • Uno.SourceGenerationTasks
  • Uno.UI.RemoteControl / Uno.WinUI.RemoteControl
  • Other:

This was tested on openSUSE Tumbleweed (snapshot 20210703) running GNOME 40.2.

Nuget Package Version(s):

Affected platform(s):

  • iOS
  • Android
  • WebAssembly
  • WebAssembly renderers for Xamarin.Forms
  • macOS
  • Skia
    • WPF
    • GTK (Linux)
    • Tizen
  • Windows
  • Build tasks
  • Solution Templates

IDE:

  • Visual Studio 2017 (version: )
  • Visual Studio 2019 (version: )
  • Visual Studio for Mac (version: )
  • Rider Windows (version: )
  • Rider macOS (version: )
  • Visual Studio Code (version: )

Relevant plugins:

  • Resharper (version: )

Anything else we need to know?

Related to #7121

@dradtke dradtke added difficulty/tbd Categorizes an issue for which the difficulty level needs to be defined. kind/bug Something isn't working triage/untriaged Indicates an issue requires triaging or verification labels Jul 9, 2021
@jeromelaban
Copy link
Member

@mterwoord This would be a similar issue. (If you've found what to do to enable default fonts on systems not providing it properly)

@jeromelaban jeromelaban added area/skia ✏️ Categorizes an issue or PR as relevant to Skia project/core-tools 🛠️ Categorizes an issue or PR as relevant to core and tools and removed triage/untriaged Indicates an issue requires triaging or verification labels Jul 10, 2021
@mterwoord
Copy link
Contributor

I'm working on an IOT project, which uses custom-built linux image. (using yocto)
Apparently the image doesn't have a default font.
What I did was put the following config in /etc/fonts/conf.d, named 99-something.conf:

<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
    <match>
        <test qual="all" name="family" compare="eq">
            <string></string>
        </test>
        <edit name="family" mode="assign">
            <string>Liberation Serif</string>
        </edit>
    </match>
</fontconfig>

This will rewrite all font families to be Liberation Serif. This works for me. I'm still working on getting a more fine-grained configuration setting, but that's a WIP.

@dradtke
Copy link
Author

dradtke commented Jul 10, 2021

Hmm, that didn't seem to have an effect for me.

From the FC_DEBUG=1 output, I do see this towards the bottom:

        fontversion: 137625(i)(w)
        capability: "otlayout:cyrl otlayout:grek otlayout:hebr otlayout:latn"(w)
        fontformat: "TrueType"(w)
        decorative: False(w)
        postscriptname: "LiberationSans"(w)

I have LiberationSans installed at /usr/share/fonts/truetype/LiberationSans-Regular.ttf, so maybe Skia isn't correctly locating it?

@dradtke
Copy link
Author

dradtke commented Jul 10, 2021

I was able to confirm that this is seen by .NET as the default font with this small program:

// Created with:
//
//  $ dotnet new <project>
//  $ dotnet add package System.Drawing.Common
//
using System;                                                                                                                                                                                                                                 
using System.Drawing;                                                                                                                                                                                                                         
                                                                                                                                                                                                                                              
namespace font_test                                                                                                                                                                                                                           
{                                                                                                                                                                                                                                             
    class Program                                                                                                                                                                                                                             
    {                                                                                                                                                                                                                                         
        static void Main(string[] args)                                                                                                                                                                                                       
        {                                                                                                                                                                                                                                     
            Console.WriteLine(SystemFonts.DefaultFont);                                                                                                                                                                                       
        }                                                                                                                                                                                                                                     
    }                                                                                                                                                                                                                                         
}

This outputs the following:

[Font: Name=Liberation Sans, Size=8.25, Units=3, GdiCharSet=1, GdiVerticalFont=False]

@mterwoord
Copy link
Contributor

Have you modified my config to read Liberation Sans instead of Liberation Serif?

@dradtke
Copy link
Author

dradtke commented Jul 11, 2021

That actually doesn't seem to be having any effect on my system. When I run the Uno program with FC_DEBUG=4, I see this towards the end:

FcConfigSubstitute donePattern has 46 elts (size 48)                                                                   
        family: "Liberation Sans"(s)                                                                                   
        familylang: "en"(s)                                                                                            
        style: "Regular"(s)                                                                                            
        stylelang: "en"(s)                                                                                             
        fullname: "Liberation Sans"(s)                                                                                 
        fullnamelang: "en"(s)                                                                                          
        slant: 0(i)(s)                                                                                                 
        weight: 80(f)(s)                                                                                               
        width: 100(f)(s)                                                                                               
        size: 12(f)(s)                                                                                                 
        pixelsize: 12.5(f)(s)                                                                                          
        foundry: "1ASC"(w)                                                                                             
        antialias: True(w)                                                                                             
        hintstyle: 1(i)(w)                                                                                             
        hinting: True(w)                                                                                               
        verticallayout: False(s)                                                                                       
        autohint: False(w)                                                                                             
        globaladvance: True(s)                                                                                         
        file: "/usr/share/fonts/truetype/LiberationSans-Regular.ttf"(w)                                                
        index: 0(i)(w)                                     
        outline: True(w)                                                                                                                                                                                                                              scalable: True(w)                                                                                                                                                                                                                             dpi: 75(f)(s)                                                                                                                                                                                                                         
        rgba: 1(i)(w)                                      
        scale: 1(f)(s)

This doesn't seem to change no matter what I put in the new config.

Based on this, it looks like it is finding the system font, but it's somehow not able to use it?

@dradtke
Copy link
Author

dradtke commented Jul 11, 2021

Okay, so I was finally able to get some text to display by using this configuration:

<?xml version="1.0"?>                                                                                                                   
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">                                                                                                
<fontconfig>                                                                                                                            
    <match>                                                                                                                             
        <edit name="family" mode="assign">                                                                                              
            <string>Liberation Sans</string>                                                                                            
        </edit>                                                                                                                         
    </match>                                                                                                                            
</fontconfig>

However, this also messes up the fonts in my terminal, because it's presumably replacing everything with Liberation Sans. This means that the assignment works, but the test is somehow failing.

@mterwoord
Copy link
Contributor

Correct, this replaces everything. I still need to dig deeper, but Won't be till next weekend (or even later)

@dradtke
Copy link
Author

dradtke commented Jul 11, 2021

A-ha, I found the test that works for me!

<!-- /etc/fonts/conf.d/99-uno.conf -->

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">

<fontconfig>
        <match>
                <test qual="any" name="family" compare="eq">
                        <string>Segoe UI</string>
                </test>
                <edit name="family" mode="assign">
                        <string>Liberation Sans</string>
                </edit>
        </match>
</fontconfig>

This seems to indicate that the family is never changed from Segoe UI, which is requested by Uno. This config ensures that it gets changed to Liberation Sans.

This works, but it also seems to indicate a bug in how .NET Core locates the default system font. For example, when I comment out the above config, I get this from fc-match:

$ fc-match "Segoe UI"
LiberationSans-Regular.ttf: "Liberation Sans" "Regular"

This seems to confirm that Liberation Sans is being treated as the system default when presented with an unknown font family. However, .NET isn't doing the same, resulting in the need to create an explicit rule against Segoe UI.

@jeromelaban
Copy link
Member

jeromelaban commented Jul 11, 2021

This is some very interesting digging into the issue. This is the location where we're trying to get the default font:

var typeFace = SKTypeface.FromFamilyName(name, weight, width, slant);
// FromFontFamilyName may return null: https://github.com/mono/SkiaSharp/issues/1058
if (typeFace == null)
{
if (typeof(TextVisual).Log().IsEnabled(LogLevel.Warning))
{
typeof(TextVisual).Log().LogWarning($"The font {name} could not be found, using system default");
}
typeFace = SKTypeface.FromFamilyName(null, weight, width, slant);
}
return typeFace;

We're relying on the way Skia resolves fonts (and not through System.Drawing), and in this case the flow should go to the fallback:

typeFace = SKTypeface.FromFamilyName(null, weight, width, slant);

If we really do go through that fallback, there should be a warning in the console. If we're not, this would mean that Skia returns a "blank" font, which does not make a lot of sense...

Are you both seeing this warning?

typeof(TextVisual).Log().LogWarning($"The font {name} could not be found, using system default");

@dradtke
Copy link
Author

dradtke commented Jul 11, 2021

Yeah, it's one of the errors listed in my original report.

@mterwoord
Copy link
Contributor

Same here. I verified with following code what's happening on my image:

var face1 = SKTypeface.FromFamilyName(null, 12, 12, SKFontStyleSlant.Upright);
                if (face1 == null)
                {
                    Console.WriteLine("Option1: Not found");
                }
                else
                {
                    Console.WriteLine("Option1: Found: " + face1.FamilyName);
                }

                var face2 = SKTypeface.FromFamilyName("", 12, 12, SKFontStyleSlant.Upright);
                if (face2 == null)
                {
                    Console.WriteLine("Option2: Not found");
                }
                else
                {
                    Console.WriteLine("Option2: Found: " + face2.FamilyName);
                }

                var face3 = SKTypeface.FromFamilyName("Liberation Mono", 12, 12, SKFontStyleSlant.Upright);
                if (face3 == null)
                {
                    Console.WriteLine("Option3: Not found");
                }
                else
                {
                    Console.WriteLine("Option3: Found: " + face3.FamilyName);
                }

This shows to me that, by default, only the third option finds a font.
With my redirection, all 3 options show same redirected font name.

@mterwoord
Copy link
Contributor

Just did a check, for me, Segoe UI isn't tried.

@dradtke
Copy link
Author

dradtke commented Jul 12, 2021

It definitely is looking like this is a bug in Skia rather than Uno, but I'm not able to find the method backing sk_typeface_create_from_name to confirm. I wasn't able to find it in Skia's main respository, and I'm not sure where else to look.

@mterwoord
Copy link
Contributor

mterwoord commented Jul 12, 2021 via email

@dradtke
Copy link
Author

dradtke commented Jul 12, 2021

Okay, after digging around a little bit in Skia's source, I believe here is where the null value is being passed back up to Uno. It seems to be calling fontconfig directly at that point, so the issue is either in that method call, or within the if statement that causes null to be returned at that point.

@brinko99
Copy link

brinko99 commented Sep 7, 2021

These comments have been helpful. We too are building a custom Linux image for use with Uno. I found that simply matching family eq with Segoe UI per @dradtke's comment is not enough in our case. Some text displays under that condition, but not all. As far as I can tell, under Windows our missing text is indeed straight Segoe UI.

The only solution I've found is to substitute everything, or match the program name: prgname eq with dotnet.

I'm struggling to interpret the output of FC_DEBUG=1 (attached here) to see what font family remains unmatched.

Any ideas for us?

@Youssef1313
Copy link
Member

I have no idea if it's possible that #6975 can fix this. Would be good to re-test when/if it gets merged.

@jeromelaban
Copy link
Member

From #9473 (reply in thread), it looks like installing ttf-mscorefonts-installer provides the default fonts to get uno working properly.

Could someone subscribed to this issue, and still has the issue, try out ? Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/skia ✏️ Categorizes an issue or PR as relevant to Skia difficulty/tbd Categorizes an issue for which the difficulty level needs to be defined. kind/bug Something isn't working project/core-tools 🛠️ Categorizes an issue or PR as relevant to core and tools
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants