nikobarli
Topic Author
Posts: 178
Joined: 26 Apr 2017, 06:23

How to make NoesisGUI recognizes system-installed font (C++ SDK 2.0.2f2, Windows platform)

20 Jun 2017, 02:57

Hi,

Is there any way to make NoesisGUI recognizes system-installed font ?

Currently, I have to copy the *.ttf files into a resource directory and set the directory to be searchable from the path given to Noesis::GUI::SetResourceProvider(resourcePath).

Do I need to implement FontProvider ?
Is there any sample or reference code for that ?

Assume that I have implemented FontProvider, and I want to call Noesis::GUI::SetResourceProvider(provider) to set it, should I also set the xamlProvider and textureProvider inside Provider struct ? How can I make NoesisGUI to use the default implementation for those two providers.
struct Provider
{
    Gui::XamlProvider* xamlProvider;
    Drawing::TextureProvider* textureProvider;
    Drawing::FontProvider* fontProvider;
};
 
User avatar
jsantos
Site Admin
Posts: 2905
Joined: 20 Jan 2012, 17:18
Contact:

Re: How to make NoesisGUI recognizes system-installed font (C++ SDK 2.0.2f2, Windows platform)

20 Jun 2017, 18:39

The only way to achieve that is by implementing a custom provider. You have to set them at the same time, but default implementations are available in LocalXamlProvider, LocalTextureProvider and LocalFontProvider implementation classes respectively.

We plan to include all the sources in the new application framework we are working on. For now, here you can find the default implementation for the font provider:

////////////////////////////////////////////////////////////////////////////////////////////////////
// Noesis Engine - http://www.noesisengine.com
// Copyright (c) 2009-2010 Noesis Technologies S.L. All Rights Reserved.
////////////////////////////////////////////////////////////////////////////////////////////////////


#ifndef __DRAWING_LOCALFONTPROVIDER_H__
#define __DRAWING_LOCALFONTPROVIDER_H__


#include <Noesis.h>
#include <NsDrawing/CachedFontProvider.h>
#include <NsDrawing/LocalFontProviderApi.h>


namespace Noesis
{
namespace Drawing
{

////////////////////////////////////////////////////////////////////////////////////////////////////
/// A font provider that searches fonts in local directories
////////////////////////////////////////////////////////////////////////////////////////////////////
class NS_DRAWING_LOCALFONTPROVIDER_API LocalFontProvider: public CachedFontProvider
{
public:
    LocalFontProvider(const NsChar* rootPath);

private:
    /// From CachedFontProvider
    //@{
    void ScanFolder(const NsChar* folder) override;
    Ptr<Core::Stream> OpenFont(const NsChar* folder, const NsChar* filename) const override;
    //@}

    void ScanFolder(const NsChar* path, const NsChar* folder, const NsChar* ext);

private:
    NsChar mRootPath[PATH_MAX];
};

}
}

#endif

////////////////////////////////////////////////////////////////////////////////////////////////////
// Noesis Engine - http://www.noesisengine.com
// Copyright (c) 2009-2010 Noesis Technologies S.L. All Rights Reserved.
////////////////////////////////////////////////////////////////////////////////////////////////////


#include <NsDrawing/LocalFontProvider.h>
#include <NsCore/File.h>
#include <NsCore/Find.h>
#include <NsCore/Stream.h>
#include <NsCore/LoggerMacros.h>


using namespace Noesis;
using namespace Noesis::Core;
using namespace Noesis::Drawing;


////////////////////////////////////////////////////////////////////////////////////////////////////
LocalFontProvider::LocalFontProvider(const NsChar* rootPath)
{
    String::Copy(mRootPath, sizeof(mRootPath), rootPath);
}

////////////////////////////////////////////////////////////////////////////////////////////////////
void LocalFontProvider::ScanFolder(const NsChar* folder)
{
    NsChar uri[PATH_MAX] = "";

    if (!String::IsNullOrEmpty(mRootPath))
    {
        String::Copy(uri, sizeof(uri), mRootPath);
        String::Append(uri, sizeof(uri), "/");
    }

    String::Append(uri, sizeof(uri), folder);

    ScanFolder(uri, folder, ".ttf");
    ScanFolder(uri, folder, ".otf");
}

////////////////////////////////////////////////////////////////////////////////////////////////////
Ptr<Stream> LocalFontProvider::OpenFont(const NsChar* folder, const NsChar* filename) const
{
    NsChar uri[PATH_MAX] = "";

    if (!String::IsNullOrEmpty(mRootPath))
    {
        String::Copy(uri, sizeof(uri), mRootPath);
        String::Append(uri, sizeof(uri), "/");
    }

    String::Append(uri, sizeof(uri), folder);
    String::Append(uri, sizeof(uri), "/");
    String::Append(uri, sizeof(uri), filename);

    if (File::IsFile(uri))
    {
        return File::OpenStream(uri);
    }

    return 0;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
void LocalFontProvider::ScanFolder(const NsChar* path, const NsChar* folder, const NsChar* ext)
{
    FindData findData;

    if (FindFirst(path, ext, findData))
    {
        do
        {
            RegisterFont(folder, findData.filename);
        }
        while (FindNext(findData));

        Core::FindClose(findData);
    }
}
 
nikobarli
Topic Author
Posts: 178
Joined: 26 Apr 2017, 06:23

Re: How to make NoesisGUI recognizes system-installed font (C++ SDK 2.0.2f2, Windows platform)

21 Jun 2017, 07:48

Great. Thank you. Will try this.
 
nikobarli
Topic Author
Posts: 178
Joined: 26 Apr 2017, 06:23

Re: How to make NoesisGUI recognizes system-installed font (C++ SDK 2.0.2f2, Windows platform)

27 Jul 2017, 09:51

An additional question.

When I passed Provider struct to SetResourceProvider as follows:
        Noesis::Provider provider;
        provider.fontProvider = new Noesis::LocalFontProvider(path);
        provider.textureProvider = new Noesis::LocalTextureProvider(path);
        provider.xamlProvider = new Noesis::LocalXamlProvider(path);
        Noesis::GUI::SetResourceProvider(provider);
It seems that during shutdown sequence, I don't need to call "delete" for the three providers myself, because Noesis::GUI::Shutdown seems to deallocate the memory for me. Is that correct ?
 
User avatar
jsantos
Site Admin
Posts: 2905
Joined: 20 Jan 2012, 17:18
Contact:

Re: How to make NoesisGUI recognizes system-installed font (C++ SDK 2.0.2f2, Windows platform)

28 Jul 2017, 12:52

Providers base classes (XamlProvider, FontProvider and TextureProvider) are reference counted. So, yes, you don't need to take care of deleting those objects. The correct code would be:
Ptr<LocalFontProvider> fontProvider = *new Noesis::LocalFontProvider(path);
Ptr<LocalTextureProvider> textureProvider = *new Noesis::LocalTextureProvider(path);
Ptr<LocalXamlProvider> xamlProvider = *new Noesis::LocalXamlProvider(path);

Provider provider = { xamlProvider.GetPtr(), textureProvider.GetPtr(), fontProvider.GetPtr() };
Noesis::GUI::SetResourceProvider(provider);
 
nikobarli
Topic Author
Posts: 178
Joined: 26 Apr 2017, 06:23

Re: How to make NoesisGUI recognizes system-installed font (C++ SDK 2.0.2f2, Windows platform)

31 Jul 2017, 03:44

I missed that. I did try to follow the inheritance tree and somehow I came to conclusion that the provider classes is not ref counted. Thanks.

Another question:

Suppose that I have a text box filled with a mix of English and Japanese characters. If I want to use Meiryo as default font for Japanese characters, and Arial for other characters, how can I achieve that ?
 
User avatar
jsantos
Site Admin
Posts: 2905
Joined: 20 Jan 2012, 17:18
Contact:

Re: How to make NoesisGUI recognizes system-installed font (C++ SDK 2.0.2f2, Windows platform)

31 Jul 2017, 15:55

Suppose that I have a text box filled with a mix of English and Japanese characters. If I want to use Meiryo as default font for Japanese characters, and Arial for other characters, how can I achieve that ?
For TextBlock you can use Runs, but for TextBoxes that is not supported, even in WPF. The WPF way is using a RichTextBox, but that class is yet not implemented in Noesis.

Are you using a TextBlock or a TextBox?
 
nikobarli
Topic Author
Posts: 178
Joined: 26 Apr 2017, 06:23

01 Aug 2017, 09:10

Are you using a TextBlock or a TextBox?
Actually I want to apply the settings to all of the control (button's text, tab headers, menus, etc). I am thinking to set a default font family for all the UI and only override wherever necessary. Ideally, we can set a unicode font family that can cover all possible languages. However, there is no such font installed by default in Windows OSes we want to support. Even if there is, very often the font is not optimal for all the cases.

According to https://msdn.microsoft.com/en-us/librar ... .110).aspx internally WPF fallback to a default font family "Global User Interface" which is a 'composite font'. And we can also set the fallback sequence in code/xaml as follows:
<TextBox FontFamily="Consolas, Yu Gothic" FontSize="40">日本語 English</TextBox>
In this example, English characters will use font Consolas while Japanese characters will use Yu Gothic.

Is it possible to do the same using noesisgui ?
 
User avatar
jsantos
Site Admin
Posts: 2905
Joined: 20 Jan 2012, 17:18
Contact:

Re:

02 Aug 2017, 15:27

However, there is no such font installed by default in Windows OSes we want to support. Even if there is, very often the font is not optimal for all the cases.
Remember that by default we don't read default OS fonts. You need to do that in your custom provider.
In this example, English characters will use font Consolas while Japanese characters will use Yu Gothic.

Is it possible to do the same using noesisgui ?
Not for now, the fallback mechanism is not implemented. If this is something important for you, please report it athough the workaround would be manually packaging all the needed glyphs in a custom font.
 
nikobarli
Topic Author
Posts: 178
Joined: 26 Apr 2017, 06:23

Re: How to make NoesisGUI recognizes system-installed font (C++ SDK 2.0.2f2, Windows platform)

08 Aug 2017, 04:24

Remember that by default we don't read default OS fonts. You need to do that in your custom provider.
Currently we plan to set the font directory to C:\Windows\Fonts where Windows put their default fonts. If necessary, it is also OK for us to create a custom provider.
Not for now, the fallback mechanism is not implemented. If this is something important for you, please report it athough the workaround would be manually packaging all the needed glyphs in a custom font.
I don't think it is possible to repackage Windows fonts due to their licensing terms...

Is it possible to create a custom provider that for example when asked for a font family "MyFamily", will return a font stream combining "Arial" family and "Yu Gothic" family ?

Who is online

Users browsing this forum: No registered users and 0 guests