Page 1 of 1

Android - Unable to load font

Posted: 18 Apr 2017, 19:09
by GabrielStranak
When I try to load xaml style that sets FontFamily I get:
Noesis.Error+NoesisException: Unable to load font 'Fonts/#Roboto'
Actually I'm using xaml and font files from the sample application included in the Managed SDK NoesisGUI-ManagedSDK-2.0.0f1\Src\Samples\GL\Data\. So the files are correct, and they are working in my UWP project.

My code looks like this:
Noesis.GUI.Init();
string path = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "AppData", "UI");
Noesis.GUI.SetResourceProvider(path);

var theme = (Noesis.ResourceDictionary)Noesis.GUI.LoadXaml("NoesisStyle.xaml");
Noesis.GUI.SetTheme(theme);
The path variable contains absolute path like this /data/data/XamarinNoesisSample.XamarinNoesisSample/files/AppData/UI
The files exists in the specified path location.

Why can't Noesis load this font? Do I have to do something extra compared to UWP to load the fonts?

Re: Android - Unable to load font

Posted: 25 Apr 2017, 02:48
by jsantos
So, the style is at
/data/data/XamarinNoesisSample.XamarinNoesisSample/files/AppData/UI/NoesisStyle.xaml
and the font is located inside
/data/data/XamarinNoesisSample.XamarinNoesisSample/files/AppData/UI/Fonts
right? It should work with those paths. Could you implement a custom resource provider and see which paths are you being asked to load?

Re: Android - Unable to load font

Posted: 25 Apr 2017, 09:20
by GabrielStranak
Yes the paths are like you described.

So I have implemented simple custom resource providers like you suggested.
The problem is that function OpenFont inside FontProvider is newer called.

The execution order looks like this:
1. Noesis.GUI.LoadXaml is executed
2. LoadXaml inside XamlProvider is called
3. ScanFolder inside FontProvider is called
4. application crash

There seems to be some bug.

Re: Android - Unable to load font

Posted: 25 Apr 2017, 20:46
by jsantos
How did you implement ScanFolder? Could you paste it here?

Re: Android - Unable to load font

Posted: 26 Apr 2017, 09:21
by GabrielStranak
I overlooked that I need to register the fonts with RegisterFont function.
Now my implementation looks like this:
public override void ScanFolder(string folder)
{
    DirectoryInfo dir = new DirectoryInfo(Path.Combine(assetsPath, folder));
    if (dir.Exists)
    {
        foreach (FileInfo file in dir.EnumerateFiles())
        {
            if (file.Extension.Equals(".ttf", StringComparison.OrdinalIgnoreCase) || file.Extension.Equals(".otf", StringComparison.OrdinalIgnoreCase))
                RegisterFont(folder, file.Name);
        }
    }
}
With this implementation it works and Noesis makes 6 calls to OpenFont:
/data/user/0/XamarinNoesisSample.Android/files/AppData/UI/Fonts/Roboto-Bold.ttf
/data/user/0/XamarinNoesisSample.Android/files/AppData/UI/Fonts/Roboto-BoldItalic.ttf
/data/user/0/XamarinNoesisSample.Android/files/AppData/UI/Fonts/Roboto-Italic.ttf
/data/user/0/XamarinNoesisSample.Android/files/AppData/UI/Fonts/Roboto-Regular.ttf
/data/user/0/XamarinNoesisSample.Android/files/AppData/UI/Fonts/Roboto-Regular.ttf
/data/user/0/XamarinNoesisSample.Android/files/AppData/UI/Fonts/Roboto-Regular.ttf
So with this we confirmed that the fonts are there and they can be loaded.

The question remains. Why can't Noesis LocalFontProvider load this font?

Re: Android - Unable to load font

Posted: 26 Apr 2017, 14:41
by sfernandez
The question remains. Why can't Noesis LocalFontProvider load this font?
Our implementation of ScanFolder in the default font provider uses opendir/readdir functions in Android, and I think they might be failing due to permission problems (I've read comments about it in some forums). Could you please try to place xaml files and its dependencies in external storage and add WRITE_EXTERNAL_STORAGE permission, and use our default provider?

Another option to implement custom providers in Android is to use AssetManager to access assets stored inside the .apk file.

Re: Android - Unable to load font

Posted: 26 Apr 2017, 16:13
by GabrielStranak
I have added the WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE permissions and then I have tried to place the files to "External Storage" /storage/emulated/0/Android/data/XamarinNoesisSample.Android/files/AppData/UI and also to "Removable Storage" /storage/2A21-095B/Android/data/XamarinNoesisSample.Android/files/AppData/UI and use the default resource provider.
But I got the same result Noesis.Error+NoesisException: Unable to load font 'Fonts/#Roboto'.

I will use custom resource provider, because I will need to read from both Assets and folders. But for everyone else it would be good if the default resource provider would work.

Re: Android - Unable to load font

Posted: 28 Apr 2017, 22:26
by jsantos
Yes, our default providers should work. Although probably we shouldn't implement default providers and just reference implementations for our users to pick up (like we are doing with renderer in c++). Could you please report this problem in the tracker?

Re: Android - Unable to load font

Posted: 30 Apr 2017, 11:01
by GabrielStranak
I have created new issue in the BugTracker,