Noesis Gui

教程19:资源提供者

2020-03-14  本文已影响0人  YottaYuan

资源提供者

在Noesis中,可以使用资源提供程序自定义加载资源的过程。每种资源都有一个提供程序:XamlTextureFont。通常在Noesis初始化后设置每个提供程序。

Noesis::GUI::SetXamlProvider(xamlProvider);
Noesis::GUI::SetTextureProvider(textureProvider);
Noesis::GUI::SetFontProvider(fontProvider);

这三种提供程序共享相同的文件抽象,即Stream接口。

class Stream: public BaseComponent
{
public:
    /// Set the current position within the stream
    virtual void SetPosition(uint32_t pos) = 0;

    /// Returns the current position within the stream
    virtual uint32_t GetPosition() const = 0;

    /// Returns the length of the stream in bytes
    virtual uint32_t GetLength() const = 0;

    /// Reads data at the current position and advances it by the number of bytes read
    /// Returns the total number of bytes read. This can be less than the number of bytes requested
    virtual uint32_t Read(void* buffer, uint32_t size) = 0;
};

XAML提供者

实现xamls提供程序的基类是XamlProvider

class XamlProvider: public BaseComponent
{
public:
    // Loads the specified XAML file. Returns null if no xaml found
    virtual Ptr<Stream> LoadXaml(const char* uri) = 0;
};

实现很简单。您基本上必须为所请求的每个uri提供一个流。您可以在应用程序框架中找到两个XamlProvider实现,LocalXamlProvider用于从磁盘加载XAML,EmbeddedXamlProvider用于加载嵌入在可执行文件中的XAML。

纹理提供者

纹理提供程序有点复杂,因为您需要实现两个不同的功能。在主线程中,布局过程需要有关纹理尺寸的信息。您可以通过GetTextureInfo函数提供该信息。真正加载纹理的函数是LoadTexture,它总是从渲染线程调用。

class TextureProvider: public BaseComponent
{
public:
    /// Returns metadata for the given texture. 0 x 0 is returned if no texture found
    virtual TextureInfo GetTextureInfo(const char* uri) = 0;

    /// Returns a texture compatible with the given device. Null is returned if no texture found
    virtual Ptr<Texture> LoadTexture(const char* uri, RenderDevice* device) = 0;
};

应用程序框架提供了一个辅助类,FileTextureProvider,将从图像为您创建纹理。它公开了一个虚拟函数,您必须实现该虚拟函数来加载请求的文件名。

class FileTextureProvider: public Noesis::TextureProvider
{
protected:
    virtual Ptr<Stream> OpenStream(const char* uri) const = 0;
};

XamlProvider相似,您可以在应用程序框架中找到LocalTextureProviderEmbeddedTextureProvider实现。

字体提供者

字体提供程序的实现更为复杂。负责加载字体的基类是FontProvider

class FontProvider: public BaseComponent
{
public:
    /// Finds the font in the given folder that best matches the specified properties
    /// BaseUri is the directory where the search is performed or nullptr for system fonts
    /// Returns a null stream if no matching found
    virtual FontSource MatchFont(const char* baseUri, const char* familyName, FontWeight weight,
        FontStretch stretch, FontStyle style) = 0;

    /// Returns true if the requested font family exists in given directory
    /// BaseUri is the directory where the search is performed or nullptr for system fonts
    virtual bool FamilyExists(const char* baseUri, const char* familyName) = 0;
};

为了帮助实现此提供程序,有一个中间类CachedFontProvider可以扫描文件夹并从.ttf.otf文件中提取家族信息。它还基于W3C规范实现字体匹配算法。

CachedFontProvider公开了两个虚拟函数ScanFolderOpenFont

class CachedFontProvider: public FontProvider
{
protected:
    /// Registers a font filename in the given folder. Each time this function is invoked, the
    /// given filename is opened and scanned (through OpenFont). It is recommened deferring
    /// this call as much as possible (for example, until ScanFolder is invoked)
    void RegisterFont(const char* folder, const char* filename);

    /// First time a font is requested from a folder, this function is invoked to give inheritors
    /// the opportunity to register faces found in that folder
    virtual void ScanFolder(const char* folder);

    /// Returns a stream to a previously registered filename
    virtual Ptr<Stream> OpenFont(const char* folder, const char* filename) const = 0;
};

注意

默认情况下,CachedFontProvider也将扫描系统字体。可以通过执行“ SetUseSystemFonts(false)”来禁用它。

与其他提供程序类似,LocalFontProviderEmbeddedFontProvider应用程序框架中可用的示例实现。

上一篇下一篇

猜你喜欢

热点阅读