mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-02 11:10:31 +03:00
migrate fonts to scoped resource ownership
- replace FontManager with per-ResourceScope FontService instances - publish font factories into explicit or default resource scopes - import default resources into UI scene scopes unless explicitly disabled - keep related font faces strongly owned without hot-path weak_ptr locking - add cached glyph advance queries without creating texture pages - fix font picker preview ownership, cleanup, and rapid switching - selectively evict TextLayout cache entries when referenced fonts unload - document FontService, ResourceCatalog, and cache invalidation semantics - migrate examples, tools, benchmarks, and tests to the scoped font API - expand coverage for font ownership, texture release, and layout caching
This commit is contained in:
@@ -233,9 +233,11 @@ Frozen lookup rules:
|
||||
- Never search the live registry.
|
||||
- Never implicitly search a parent, host scene, sibling scene, or every live resource.
|
||||
- The default Graphics scope imports the global catalog explicitly.
|
||||
- A UI/application scene receives only the catalogs deliberately imported into it.
|
||||
- A Web document does not inherit host/global resources unless the host exports and imports them
|
||||
intentionally.
|
||||
- A UI/application scene imports the default resource catalog automatically for the common case;
|
||||
callers can disable this at construction for strict isolation and then import only the catalogs
|
||||
they deliberately expose.
|
||||
- A Web document receives the same default-catalog baseline unless created with automatic import
|
||||
disabled. It never implicitly inherits host, sibling, or other document-local catalogs.
|
||||
- Scopes import catalogs, not arbitrary scopes. This avoids recursive lookup and import cycles.
|
||||
|
||||
Pure `EE::Graphics` users may use TextureFactory for unpinned creation or Engine's default Graphics
|
||||
@@ -566,7 +568,7 @@ focused regression coverage while preserving current raw factory ownership:
|
||||
- Externally executed HTTP tasks cannot retain a dangling raw Http after Pool destruction.
|
||||
- TextureAtlasLoader joins/stops ResourceLoader work before callback-visible loader state is
|
||||
destroyed.
|
||||
- Engine destroys ShaderProgramManager before Renderer and clears TextLayout before FontManager.
|
||||
- Engine clears TextLayout before destroying the default ResourceScope and its FontService.
|
||||
- Engine stops asynchronous resource producers before resource consumers and GPU managers.
|
||||
- UISceneNode's static async delivery queue has an explicit shutdown purge/rejection boundary.
|
||||
- Obsolete FrameBuffer context-loss reload APIs were removed.
|
||||
@@ -808,6 +810,17 @@ raw-owning ResourceManager subclass one family at a time. Their self-contained G
|
||||
the established graphics-thread destruction contract unless a concrete migration requires
|
||||
otherwise.
|
||||
|
||||
For fonts, ownership is separate from rendering policy. Font handles and semantic lookup live in
|
||||
naturally owned catalogs: application defaults use the default scope, while author `@font-face`
|
||||
resources are owned by their document scene. Every `ResourceScope` owns an inline `FontService` for
|
||||
its rendering configuration, emoji fonts, configured fallbacks, and system fallback cache. Fonts
|
||||
retain only a borrowed service pointer while published in that scope and are detached when removed
|
||||
or when the scope is destroyed. Raw `Font*` values in text/layout/style structures remain borrowed
|
||||
views whose enclosing application, scene, theme, or fallback service retains the corresponding
|
||||
handle. The former process-wide `FontManager` singleton and compatibility namespace were removed.
|
||||
Publishing a font with an existing local key replaces that catalog binding; the legacy manager
|
||||
behavior that silently suffixed duplicate font names is intentionally not preserved.
|
||||
|
||||
Remove raw-owning `ResourceManager<T>` only when no subclass or consumer depends on it.
|
||||
|
||||
## 11. Required validation matrix
|
||||
@@ -873,8 +886,8 @@ Remove raw-owning `ResourceManager<T>` only when no subclass or consumer depends
|
||||
|
||||
## 12. Next implementation deliverable
|
||||
|
||||
Stage 7 continues with the remaining ResourceManager families one at a time: fonts and font caches,
|
||||
themes/icons, shaders/programs, and any remaining raw-owning manager. Each singleton semantic
|
||||
namespace is replaced by naturally owned catalogs plus explicit scope imports, following the
|
||||
completed nine-patch and texture-atlas migrations. The raw-owning ResourceManager template is
|
||||
removed only after its final consumer is migrated.
|
||||
Stage 7 continues with the remaining ResourceManager families one at a time. Fonts and font caches
|
||||
now use scope catalogs plus `FontService`; the next families are themes/icons, shaders/programs, and
|
||||
any remaining raw-owning manager. Each singleton semantic namespace is replaced by naturally owned
|
||||
catalogs plus explicit scope imports. The raw-owning ResourceManager template is removed only after
|
||||
its final consumer is migrated.
|
||||
|
||||
@@ -68,6 +68,17 @@ class DynamicLRU {
|
||||
mCacheMap.clear();
|
||||
}
|
||||
|
||||
template <typename Predicate> void eraseIf( Predicate predicate ) {
|
||||
for ( auto it = mCacheList.begin(); it != mCacheList.end(); ) {
|
||||
if ( predicate( it->first, it->second ) ) {
|
||||
mCacheMap.erase( it->first );
|
||||
it = mCacheList.erase( it );
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] std::size_t size() const { return mCacheList.size(); }
|
||||
};
|
||||
|
||||
@@ -166,6 +177,19 @@ class StaticLRU {
|
||||
used_ = 0;
|
||||
}
|
||||
|
||||
template <typename Predicate> void eraseIf( Predicate predicate ) {
|
||||
std::vector<std::pair<KeyT, ValueT>> retained;
|
||||
retained.reserve( used_ );
|
||||
for ( std::uint16_t idx = head_; idx < N; idx = next_[idx] ) {
|
||||
if ( !predicate( keys_[idx], vals_[idx] ) )
|
||||
retained.emplace_back( std::move( keys_[idx] ), std::move( vals_[idx] ) );
|
||||
}
|
||||
|
||||
clear();
|
||||
for ( auto it = retained.rbegin(); it != retained.rend(); ++it )
|
||||
put( std::move( it->first ), std::move( it->second ) );
|
||||
}
|
||||
|
||||
[[nodiscard]] std::size_t size() const noexcept { return used_; }
|
||||
|
||||
private:
|
||||
@@ -283,6 +307,9 @@ class LRUCache {
|
||||
std::optional<ValueT> get( KeyParamT key ) { return impl_.get( key ); }
|
||||
void put( KeyT key, ValueT value ) { impl_.put( std::move( key ), std::move( value ) ); }
|
||||
void clear() { impl_.clear(); }
|
||||
template <typename Predicate> void eraseIf( Predicate predicate ) {
|
||||
impl_.eraseIf( std::move( predicate ) );
|
||||
}
|
||||
|
||||
static constexpr std::size_t capacity() { return Capacity; }
|
||||
[[nodiscard]] std::size_t size() const { return impl_.size(); }
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <eepp/graphics/font.hpp>
|
||||
#include <eepp/graphics/fontbmfont.hpp>
|
||||
#include <eepp/graphics/fontfamily.hpp>
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/fontservice.hpp>
|
||||
#include <eepp/graphics/fontsprite.hpp>
|
||||
#include <eepp/graphics/fontstyleconfig.hpp>
|
||||
#include <eepp/graphics/fonttruetype.hpp>
|
||||
@@ -43,9 +43,9 @@
|
||||
#include <eepp/graphics/renderer/rendererglshader.hpp>
|
||||
#include <eepp/graphics/renderer/rendererhelper.hpp>
|
||||
#include <eepp/graphics/rendermode.hpp>
|
||||
#include <eepp/graphics/richtext.hpp>
|
||||
#include <eepp/graphics/resourcecatalog.hpp>
|
||||
#include <eepp/graphics/resourcescope.hpp>
|
||||
#include <eepp/graphics/richtext.hpp>
|
||||
#include <eepp/graphics/scopedtexture.hpp>
|
||||
#include <eepp/graphics/scrollparallax.hpp>
|
||||
#include <eepp/graphics/shader.hpp>
|
||||
@@ -62,9 +62,9 @@
|
||||
#include <eepp/graphics/textshaperun.hpp>
|
||||
#include <eepp/graphics/texttransform.hpp>
|
||||
#include <eepp/graphics/texture.hpp>
|
||||
#include <eepp/graphics/texturedrawable.hpp>
|
||||
#include <eepp/graphics/textureatlas.hpp>
|
||||
#include <eepp/graphics/textureatlasloader.hpp>
|
||||
#include <eepp/graphics/texturedrawable.hpp>
|
||||
#include <eepp/graphics/texturefactory.hpp>
|
||||
#include <eepp/graphics/textureloader.hpp>
|
||||
#include <eepp/graphics/texturepacker.hpp>
|
||||
|
||||
@@ -11,6 +11,8 @@ using namespace std::literals;
|
||||
namespace EE { namespace Graphics {
|
||||
|
||||
class Font;
|
||||
using FontPtr = ResourcePtr<Font>;
|
||||
using FontWeakPtr = ResourceWeakPtr<Font>;
|
||||
|
||||
struct EE_API Glyph {
|
||||
Float advance{ 0 }; ///< Offset to move horizontally to the next character
|
||||
@@ -135,6 +137,10 @@ class EE_API Font {
|
||||
virtual Glyph getGlyph( Uint32 codePoint, unsigned int characterSize, bool bold, bool italic,
|
||||
Float outlineThickness = 0 ) const = 0;
|
||||
|
||||
/** Returns the horizontal advance without requiring a renderable glyph texture. */
|
||||
virtual Float getGlyphAdvance( Uint32 codePoint, unsigned int characterSize, bool bold = false,
|
||||
bool italic = false, Float outlineThickness = 0 ) const;
|
||||
|
||||
/** @return The glyph drawable that represents the glyph in a texture. The glyph drawable
|
||||
* allocation is managed by the font. */
|
||||
virtual GlyphDrawable* getGlyphDrawable( Uint32 codePoint, unsigned int characterSize,
|
||||
|
||||
@@ -12,12 +12,20 @@ class IOStream;
|
||||
|
||||
namespace EE { namespace Graphics {
|
||||
|
||||
class FontBMFont;
|
||||
class ResourceScope;
|
||||
using FontBMFontPtr = ResourcePtr<FontBMFont>;
|
||||
using FontBMFontWeakPtr = ResourceWeakPtr<FontBMFont>;
|
||||
|
||||
/** @brief Implementation of AngelCode BMFont fonts. */
|
||||
class EE_API FontBMFont : public Font {
|
||||
public:
|
||||
static FontBMFont* New( const std::string fontName );
|
||||
static FontBMFontPtr New( const std::string fontName );
|
||||
static FontBMFontPtr New( const std::string fontName, ResourceScope& resourceScope );
|
||||
|
||||
static FontBMFont* New( const std::string fontName, const std::string& filename );
|
||||
static FontBMFontPtr New( const std::string fontName, const std::string& filename );
|
||||
static FontBMFontPtr New( const std::string fontName, const std::string& filename,
|
||||
ResourceScope& resourceScope );
|
||||
|
||||
~FontBMFont();
|
||||
|
||||
@@ -39,6 +47,9 @@ class EE_API FontBMFont : public Font {
|
||||
Glyph getGlyph( Uint32 codePoint, unsigned int characterSize, bool bold, bool italic,
|
||||
Float outlineThickness = 0 ) const;
|
||||
|
||||
Float getGlyphAdvance( Uint32 codePoint, unsigned int characterSize, bool bold = false,
|
||||
bool italic = false, Float outlineThickness = 0 ) const;
|
||||
|
||||
GlyphDrawable* getGlyphDrawable( Uint32 codePoint, unsigned int characterSize,
|
||||
bool bold = false, bool italic = false,
|
||||
Float outlineThickness = 0 ) const;
|
||||
|
||||
@@ -14,8 +14,8 @@ class EE_API FontFamily {
|
||||
const std::string& ext,
|
||||
const std::vector<std::string_view>& names );
|
||||
|
||||
static FontTrueType* setFont( FontTrueType* font, const std::string& fontpath,
|
||||
const std::string_view& fontType );
|
||||
static void setFont( FontTrueType* font, const std::string& fontpath,
|
||||
const std::string_view& fontType );
|
||||
};
|
||||
|
||||
}} // namespace EE::Graphics
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
#ifndef EE_GRAPHICSCFONTMANAGER_HPP
|
||||
#define EE_GRAPHICSCFONTMANAGER_HPP
|
||||
|
||||
#include <eepp/graphics/base.hpp>
|
||||
#include <eepp/graphics/font.hpp>
|
||||
|
||||
#include <eepp/system/resourcemanager.hpp>
|
||||
#include <eepp/system/singleton.hpp>
|
||||
using namespace EE::System;
|
||||
|
||||
namespace EE { namespace Graphics {
|
||||
|
||||
class FontTrueType;
|
||||
struct FontDesc;
|
||||
|
||||
/** @brief The Font Manager is a singleton class that manages all the instance of fonts
|
||||
instantiated. And releases the font instances automatically. So the user doesn't need to release
|
||||
any font instance.
|
||||
*/
|
||||
class EE_API FontManager : public ResourceManager<Font> {
|
||||
SINGLETON_DECLARE_HEADERS( FontManager )
|
||||
|
||||
public:
|
||||
virtual ~FontManager();
|
||||
|
||||
/** @brief Adds a new font to the manager */
|
||||
Graphics::Font* add( Graphics::Font* Font );
|
||||
|
||||
Font* getColorEmojiFont() const;
|
||||
|
||||
void setColorEmojiFont( Graphics::Font* font );
|
||||
|
||||
Font* getEmojiFont() const;
|
||||
|
||||
void setEmojiFont( Font* newEmojiFont );
|
||||
|
||||
const std::vector<Font*>& getFallbackFonts() const;
|
||||
|
||||
bool hasFallbackFonts() const;
|
||||
|
||||
bool addFallbackFont( Font* fallbackFont );
|
||||
|
||||
bool removeFallbackFont( Font* fallbackFont );
|
||||
|
||||
FontHinting getHinting() const;
|
||||
|
||||
void setHinting( FontHinting hinting );
|
||||
|
||||
FontAntialiasing getAntialiasing() const;
|
||||
|
||||
void setAntialiasing( FontAntialiasing antialiasing );
|
||||
|
||||
Font* getByInternalId( Uint32 internalId ) const;
|
||||
|
||||
FontTrueType* getOrLoadSystemFallbackFont( const FontDesc& desc );
|
||||
|
||||
protected:
|
||||
Font* mColorEmojiFont{ nullptr };
|
||||
Font* mEmojiFont{ nullptr };
|
||||
std::vector<Font*> mFallbackFonts;
|
||||
std::vector<Font*> mSystemFallbackFonts;
|
||||
FontHinting mHinting{ FontHinting::Full };
|
||||
FontAntialiasing mAntialiasing{ FontAntialiasing::Grayscale };
|
||||
|
||||
FontManager();
|
||||
};
|
||||
|
||||
}} // namespace EE::Graphics
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,135 @@
|
||||
#ifndef EE_GRAPHICS_FONTSERVICE_HPP
|
||||
#define EE_GRAPHICS_FONTSERVICE_HPP
|
||||
|
||||
#include <eepp/graphics/base.hpp>
|
||||
#include <eepp/graphics/font.hpp>
|
||||
|
||||
namespace EE { namespace Graphics {
|
||||
|
||||
class FontTrueType;
|
||||
class ResourceScope;
|
||||
struct FontDesc;
|
||||
|
||||
/**
|
||||
* @brief Owns font fallback state and rendering policy for a ResourceScope.
|
||||
*
|
||||
* Every ResourceScope has one FontService. Fonts published locally by that scope are associated
|
||||
* with its service, allowing glyph lookup to resolve configured emoji, explicit fallback, and
|
||||
* system fallback fonts without consulting global state.
|
||||
*
|
||||
* The service strongly owns configured emoji and fallback fonts. Raw-pointer setters only accept
|
||||
* fonts that can be resolved through the associated scope; passing an unrelated pointer clears or
|
||||
* ignores the corresponding configuration. Removing a locally published font from the scope also
|
||||
* removes any service references to it.
|
||||
*
|
||||
* Rendering policy changes are applied to TrueType fonts associated with this service. Imported
|
||||
* fonts remain associated with the service of their owning scope and are therefore not mutated.
|
||||
*
|
||||
* System fonts can be loaded with two different lifetime contracts:
|
||||
* - loadSystemFont() returns an independently owned, uncached font.
|
||||
* - getOrLoadSystemFallbackFont() retains the font in this service for repeated fallback lookup.
|
||||
*/
|
||||
class EE_API FontService {
|
||||
friend class ResourceScope;
|
||||
|
||||
public:
|
||||
/** Creates a service associated with @p resourceScope. ResourceScope owns its service. */
|
||||
explicit FontService( ResourceScope& resourceScope );
|
||||
|
||||
/** @return The resource scope whose fonts and policy are managed by this service. */
|
||||
ResourceScope& getResourceScope() const;
|
||||
|
||||
/** @return The configured color emoji font, or nullptr when none is configured. */
|
||||
Font* getColorEmojiFont() const;
|
||||
|
||||
/**
|
||||
* Sets the color emoji font. The font must be resolvable through the associated scope. Passing
|
||||
* nullptr or an unrelated font clears the current value.
|
||||
*/
|
||||
void setColorEmojiFont( Font* font );
|
||||
|
||||
/** @return The configured monochrome emoji font, or nullptr when none is configured. */
|
||||
Font* getEmojiFont() const;
|
||||
|
||||
/**
|
||||
* Sets the monochrome emoji font. The font must be resolvable through the associated scope.
|
||||
* Passing nullptr or an unrelated font clears the current value.
|
||||
*/
|
||||
void setEmojiFont( Font* font );
|
||||
|
||||
/** @return The strongly owned explicit fallback fonts in lookup order. */
|
||||
const std::vector<FontPtr>& getFallbackFonts() const;
|
||||
|
||||
/** @return Whether at least one explicit fallback font is configured. */
|
||||
bool hasFallbackFonts() const;
|
||||
|
||||
/** Adds an owning fallback handle unless the same font is already configured. */
|
||||
bool addFallbackFont( FontPtr fallbackFont );
|
||||
|
||||
/**
|
||||
* Adds a fallback font resolved through the associated scope.
|
||||
* @return True when the font was found and added; false otherwise.
|
||||
*/
|
||||
bool addFallbackFont( Font* fallbackFont );
|
||||
|
||||
/** Removes the matching explicit fallback font without removing it from its resource scope. */
|
||||
bool removeFallbackFont( Font* fallbackFont );
|
||||
|
||||
/** @return The policy used when loading and updating associated TrueType fonts. */
|
||||
FontHinting getHinting() const;
|
||||
|
||||
/** Updates the hinting policy and applies it to associated non-emoji TrueType fonts. */
|
||||
void setHinting( FontHinting hinting );
|
||||
|
||||
/** @return The antialiasing policy used by associated TrueType fonts. */
|
||||
FontAntialiasing getAntialiasing() const;
|
||||
|
||||
/** Updates the antialiasing policy and applies it to associated non-emoji TrueType fonts. */
|
||||
void setAntialiasing( FontAntialiasing antialiasing );
|
||||
|
||||
/**
|
||||
* Finds a TrueType font visible through the associated scope by its runtime internal ID.
|
||||
* @return A borrowed pointer, or nullptr when no matching font is visible.
|
||||
*/
|
||||
Font* getByInternalId( Uint32 internalId ) const;
|
||||
|
||||
/**
|
||||
* Loads a standalone system font described by @p desc.
|
||||
*
|
||||
* The font is not published into the associated scope and is not retained by this service. The
|
||||
* returned handle is its sole owner and can be released independently, immediately freeing its
|
||||
* glyph pages when no other handle exists. Current hinting and antialiasing policy is applied
|
||||
* at load time. The standalone font does not use this service for subsequent fallback
|
||||
* resolution.
|
||||
*
|
||||
* @return An owning handle, or an empty handle when the descriptor cannot be loaded.
|
||||
*/
|
||||
ResourcePtr<FontTrueType> loadSystemFont( const FontDesc& desc );
|
||||
|
||||
/**
|
||||
* Finds or loads a system fallback font described by @p desc.
|
||||
*
|
||||
* Successfully loaded fonts are published into the associated scope and strongly retained by
|
||||
* the service for future glyph fallback requests. The returned pointer is borrowed and remains
|
||||
* valid until the font is removed from the scope or the service is destroyed.
|
||||
*
|
||||
* @return A borrowed pointer to the cached font, or nullptr when loading fails.
|
||||
*/
|
||||
FontTrueType* getOrLoadSystemFallbackFont( const FontDesc& desc );
|
||||
|
||||
private:
|
||||
FontPtr findHandle( Font* font ) const;
|
||||
void onFontRemoved( Font* font );
|
||||
|
||||
ResourceScope& mResourceScope;
|
||||
FontPtr mColorEmojiFont;
|
||||
FontPtr mEmojiFont;
|
||||
std::vector<FontPtr> mFallbackFonts;
|
||||
std::vector<FontPtr> mSystemFallbackFonts;
|
||||
FontHinting mHinting{ FontHinting::Full };
|
||||
FontAntialiasing mAntialiasing{ FontAntialiasing::Grayscale };
|
||||
};
|
||||
|
||||
}} // namespace EE::Graphics
|
||||
|
||||
#endif
|
||||
@@ -13,12 +13,20 @@ class IOStream;
|
||||
|
||||
namespace EE { namespace Graphics {
|
||||
|
||||
class FontSprite;
|
||||
class ResourceScope;
|
||||
using FontSpritePtr = ResourcePtr<FontSprite>;
|
||||
using FontSpriteWeakPtr = ResourceWeakPtr<FontSprite>;
|
||||
|
||||
/** @brief Implementation of XNA Font Sprites */
|
||||
class EE_API FontSprite : public Font {
|
||||
public:
|
||||
static FontSprite* New( const std::string fontName );
|
||||
static FontSpritePtr New( const std::string fontName );
|
||||
static FontSpritePtr New( const std::string fontName, ResourceScope& resourceScope );
|
||||
|
||||
static FontSprite* New( const std::string fontName, const std::string& filename );
|
||||
static FontSpritePtr New( const std::string fontName, const std::string& filename );
|
||||
static FontSpritePtr New( const std::string fontName, const std::string& filename,
|
||||
ResourceScope& resourceScope );
|
||||
|
||||
~FontSprite();
|
||||
|
||||
|
||||
@@ -15,15 +15,26 @@ namespace EE { namespace Graphics {
|
||||
|
||||
enum class FontWeight : Uint16;
|
||||
struct FontDesc;
|
||||
class ResourceScope;
|
||||
|
||||
class FontTrueType;
|
||||
class FontService;
|
||||
using FontTrueTypePtr = ResourcePtr<FontTrueType>;
|
||||
using FontTrueTypeWeakPtr = ResourceWeakPtr<FontTrueType>;
|
||||
|
||||
class EE_API FontTrueType : public Font {
|
||||
public:
|
||||
static FontTrueType* New( const std::string& FontName );
|
||||
static FontTrueTypePtr New( const std::string& FontName );
|
||||
static FontTrueTypePtr New( const std::string& FontName, ResourceScope& resourceScope );
|
||||
|
||||
static FontTrueType* New( const std::string& FontName, const std::string& filename );
|
||||
static FontTrueTypePtr New( const std::string& FontName, const std::string& filename );
|
||||
static FontTrueTypePtr New( const std::string& FontName, const std::string& filename,
|
||||
ResourceScope& resourceScope );
|
||||
|
||||
static FontTrueType* New( const std::string& FontName, const std::string& filename,
|
||||
Uint32 faceIndex );
|
||||
static FontTrueTypePtr New( const std::string& FontName, const std::string& filename,
|
||||
Uint32 faceIndex );
|
||||
static FontTrueTypePtr New( const std::string& FontName, const std::string& filename,
|
||||
Uint32 faceIndex, ResourceScope& resourceScope );
|
||||
|
||||
~FontTrueType();
|
||||
|
||||
@@ -48,6 +59,9 @@ class EE_API FontTrueType : public Font {
|
||||
Glyph getGlyph( Uint32 codePoint, unsigned int characterSize, bool bold, bool italic,
|
||||
Float outlineThickness = 0 ) const;
|
||||
|
||||
Float getGlyphAdvance( Uint32 codePoint, unsigned int characterSize, bool bold = false,
|
||||
bool italic = false, Float outlineThickness = 0 ) const;
|
||||
|
||||
Glyph getGlyphByIndex( Uint32 index, unsigned int characterSize, bool bold, bool italic,
|
||||
Float outlineThickness = 0 ) const;
|
||||
|
||||
@@ -80,6 +94,7 @@ class EE_API FontTrueType : public Font {
|
||||
const TexturePtr& getTexture( unsigned int characterSize ) const;
|
||||
|
||||
bool loaded() const;
|
||||
FontService* getFontService() const;
|
||||
|
||||
FontTrueType( const FontTrueType& ) = delete;
|
||||
FontTrueType& operator=( const FontTrueType& ) = delete;
|
||||
@@ -151,19 +166,19 @@ class EE_API FontTrueType : public Font {
|
||||
|
||||
virtual bool hasItalic() const { return mIsItalic || mFontItalic != nullptr; }
|
||||
|
||||
virtual bool hasBoldItalic() const { return isBoldItalic() || mFontBoldItalic; }
|
||||
virtual bool hasBoldItalic() const { return isBoldItalic() || mFontBoldItalic != nullptr; }
|
||||
|
||||
FontTrueType* getBoldFont() const { return mFontBold; }
|
||||
const FontTrueTypePtr& getBoldFont() const { return mFontBold; }
|
||||
|
||||
FontTrueType* getItalicFont() const { return mFontItalic; }
|
||||
const FontTrueTypePtr& getItalicFont() const { return mFontItalic; }
|
||||
|
||||
FontTrueType* getBoldItalicFont() const { return mFontBoldItalic; }
|
||||
const FontTrueTypePtr& getBoldItalicFont() const { return mFontBoldItalic; }
|
||||
|
||||
void setBoldFont( FontTrueType* fontBold );
|
||||
void setBoldFont( const FontTrueTypePtr& fontBold );
|
||||
|
||||
void setItalicFont( FontTrueType* fontItalic );
|
||||
void setItalicFont( const FontTrueTypePtr& fontItalic );
|
||||
|
||||
void setBoldItalicFont( FontTrueType* fontBoldItalic );
|
||||
void setBoldItalicFont( const FontTrueTypePtr& fontBoldItalic );
|
||||
|
||||
void* face() const { return mFace; }
|
||||
|
||||
@@ -178,8 +193,11 @@ class EE_API FontTrueType : public Font {
|
||||
protected:
|
||||
friend class Text;
|
||||
friend class TextLayout;
|
||||
friend class FontService;
|
||||
friend class ResourceScope;
|
||||
|
||||
explicit FontTrueType( const std::string& FontName );
|
||||
explicit FontTrueType( const std::string& FontName, FontService& fontService );
|
||||
void setFontService( FontService* fontService );
|
||||
|
||||
struct Row {
|
||||
Row( unsigned int rowTop, unsigned int rowHeight ) :
|
||||
@@ -267,15 +285,14 @@ class EE_API FontTrueType : public Font {
|
||||
mutable UnorderedMap<Uint32, std::tuple<Uint32, Uint32, bool>> mKeyCache;
|
||||
mutable UnorderedMap<Uint64, Float> mKerningCache; // For codepoints (getKerning)
|
||||
mutable UnorderedMap<Uint64, Float> mKerningGlyphCache; // For glyph indices
|
||||
mutable UnorderedMap<unsigned int, UnorderedMap<Uint64, Float>> mGlyphAdvanceCache;
|
||||
FontHinting mHinting{ FontHinting::Full };
|
||||
FontAntialiasing mAntialiasing{ FontAntialiasing::Grayscale };
|
||||
FontService* mFontService{ nullptr };
|
||||
Uint32 mFaceIndex{ 0 };
|
||||
FontTrueType* mFontBold{ nullptr };
|
||||
FontTrueType* mFontItalic{ nullptr };
|
||||
FontTrueType* mFontBoldItalic{ nullptr };
|
||||
Uint32 mFontBoldCb{ 0 };
|
||||
Uint32 mFontItalicCb{ 0 };
|
||||
Uint32 mFontBoldItalicCb{ 0 };
|
||||
FontTrueTypePtr mFontBold;
|
||||
FontTrueTypePtr mFontItalic;
|
||||
FontTrueTypePtr mFontBoldItalic;
|
||||
|
||||
Float getGlyphTopOffset( unsigned int characterSize ) const;
|
||||
|
||||
@@ -284,12 +301,6 @@ class EE_API FontTrueType : public Font {
|
||||
bool setFontFace( void* face );
|
||||
|
||||
void updateMonospaceState() const;
|
||||
|
||||
void disconnectBoldFont();
|
||||
|
||||
void disconnectItalicFont();
|
||||
|
||||
void disconnectBoldItalicFont();
|
||||
};
|
||||
|
||||
}} // namespace EE::Graphics
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef EE_GRAPHICS_RESOURCE_HPP
|
||||
#define EE_GRAPHICS_RESOURCE_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
@@ -57,4 +58,14 @@ template <typename T, typename... Args> ResourcePtr<T> makeResource( Args&&... a
|
||||
|
||||
}} // namespace EE::Graphics
|
||||
|
||||
namespace std {
|
||||
|
||||
template <> struct hash<EE::Graphics::ResourceId> {
|
||||
std::size_t operator()( const EE::Graphics::ResourceId& id ) const noexcept {
|
||||
return std::hash<EE::Uint64>{}( id.value() );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <eepp/core/containers.hpp>
|
||||
#include <eepp/graphics/drawable.hpp>
|
||||
#include <eepp/graphics/font.hpp>
|
||||
#include <eepp/graphics/resource.hpp>
|
||||
#include <eepp/graphics/texture.hpp>
|
||||
#include <eepp/graphics/textureatlas.hpp>
|
||||
@@ -13,34 +14,123 @@ namespace EE { namespace Graphics {
|
||||
class ResourceCatalog;
|
||||
using ResourceCatalogPtr = ResourcePtr<ResourceCatalog>;
|
||||
|
||||
/** Strong, named ownership for Graphics resources. The live registry is never searched here. */
|
||||
/**
|
||||
* @brief Thread-safe, strongly owning collection of named graphics resources.
|
||||
*
|
||||
* A catalog maps semantic string keys to textures, drawable sources, texture atlases, and fonts.
|
||||
* Publishing a resource gives the catalog shared ownership of it. Publishing another resource of
|
||||
* the same kind under the same key replaces that binding; the key and resource name are never
|
||||
* changed automatically. Publishing a null handle is equivalent to erasing the corresponding key,
|
||||
* while an empty key is ignored.
|
||||
*
|
||||
* Lookups return owning handles. A resource obtained from a catalog therefore remains alive even
|
||||
* if its binding is subsequently replaced, erased, or the catalog is cleared. Final handles are
|
||||
* released after dropping the catalog mutex so resource destruction and callbacks never execute
|
||||
* while the catalog is locked.
|
||||
*
|
||||
* Drawable and font hash lookups use String::hash() of the semantic key as a weak secondary index.
|
||||
* They are compatibility/convenience lookups and do not replace full-key lookup when collision-safe
|
||||
* identity is required. Textures use ResourceId for process-wide object identity elsewhere; the
|
||||
* hash accepted by findDrawable() and findFont() is not a ResourceId.
|
||||
*
|
||||
* ResourceCatalog performs no parent, scene, live-registry, filesystem, or fallback search. A
|
||||
* ResourceScope defines lookup precedence by searching its local catalog and then explicitly
|
||||
* imported catalogs. Importing a catalog shares this object and its live contents; it does not copy
|
||||
* any resource.
|
||||
*
|
||||
* All public operations are safe to call concurrently. Enumeration methods return snapshots and
|
||||
* allocate vectors containing owning handles.
|
||||
*/
|
||||
class EE_API ResourceCatalog {
|
||||
public:
|
||||
/** @return A new empty catalog using eepp resource allocation and deletion. */
|
||||
static ResourceCatalogPtr New();
|
||||
|
||||
/** @brief Publishes or replaces a texture binding. A null texture erases @p key. */
|
||||
void publish( ResourceKey key, TexturePtr texture );
|
||||
/** @copydoc publish(ResourceKey,TexturePtr) */
|
||||
void publish( std::string key, TexturePtr texture );
|
||||
|
||||
/** @brief Publishes or replaces a drawable-source binding. A null drawable erases @p key. */
|
||||
void publishDrawable( ResourceKey key, DrawablePtr drawable );
|
||||
/** @copydoc publishDrawable(ResourceKey,DrawablePtr) */
|
||||
void publishDrawable( std::string key, DrawablePtr drawable );
|
||||
|
||||
/** @brief Publishes or replaces a texture-atlas binding. A null atlas erases @p key. */
|
||||
void publishAtlas( ResourceKey key, TextureAtlasPtr atlas );
|
||||
/** @copydoc publishAtlas(ResourceKey,TextureAtlasPtr) */
|
||||
void publishAtlas( std::string key, TextureAtlasPtr atlas );
|
||||
|
||||
/** @brief Publishes or replaces a font binding. A null font erases @p key. */
|
||||
void publishFont( ResourceKey key, FontPtr font );
|
||||
/** @copydoc publishFont(ResourceKey,FontPtr) */
|
||||
void publishFont( std::string key, FontPtr font );
|
||||
|
||||
/** @return The texture bound to @p key, or an empty handle when it is not present. */
|
||||
TexturePtr findTexture( const ResourceKey& key ) const;
|
||||
/** @copydoc findTexture(const ResourceKey&)const */
|
||||
TexturePtr findTexture( const std::string& key ) const;
|
||||
|
||||
/** @return The drawable source bound to @p key, or an empty handle when it is not present. */
|
||||
DrawablePtr findDrawable( const ResourceKey& key ) const;
|
||||
/** @copydoc findDrawable(const ResourceKey&)const */
|
||||
DrawablePtr findDrawable( const std::string& key ) const;
|
||||
/**
|
||||
* @brief Looks up a drawable through the weak String::hash(key) secondary index.
|
||||
* @return An owning handle when the indexed drawable is still present, otherwise an empty
|
||||
* handle.
|
||||
*/
|
||||
DrawablePtr findDrawable( const String::HashType& id ) const;
|
||||
|
||||
/** @return The texture atlas bound to @p key, or an empty handle when it is not present. */
|
||||
TextureAtlasPtr findAtlas( const ResourceKey& key ) const;
|
||||
/** @copydoc findAtlas(const ResourceKey&)const */
|
||||
TextureAtlasPtr findAtlas( const std::string& key ) const;
|
||||
/** @return An owning snapshot of all texture atlases currently published in this catalog. */
|
||||
std::vector<TextureAtlasPtr> getAtlases() const;
|
||||
|
||||
/** @return The font bound to @p key, or an empty handle when it is not present. */
|
||||
FontPtr findFont( const ResourceKey& key ) const;
|
||||
/** @copydoc findFont(const ResourceKey&)const */
|
||||
FontPtr findFont( const std::string& key ) const;
|
||||
/**
|
||||
* @brief Looks up a font through the weak String::hash(key) secondary index.
|
||||
* @return An owning handle when the indexed font is still present, otherwise an empty handle.
|
||||
*/
|
||||
FontPtr findFont( const String::HashType& id ) const;
|
||||
/** @return An owning snapshot of all fonts currently published in this catalog. */
|
||||
std::vector<FontPtr> getFonts() const;
|
||||
|
||||
/** @brief Removes the texture binding for @p key. @return Whether a binding was removed. */
|
||||
bool erase( const ResourceKey& key );
|
||||
/** @copydoc erase(const ResourceKey&) */
|
||||
bool erase( const std::string& key );
|
||||
|
||||
/** @brief Removes the drawable binding for @p key. @return Whether a binding was removed. */
|
||||
bool eraseDrawable( const ResourceKey& key );
|
||||
/** @copydoc eraseDrawable(const ResourceKey&) */
|
||||
bool eraseDrawable( const std::string& key );
|
||||
|
||||
/** @brief Removes the texture-atlas binding for @p key. @return Whether a binding was removed.
|
||||
*/
|
||||
bool eraseAtlas( const ResourceKey& key );
|
||||
/** @copydoc eraseAtlas(const ResourceKey&) */
|
||||
bool eraseAtlas( const std::string& key );
|
||||
|
||||
/** @brief Removes the font binding for @p key. @return Whether a binding was removed. */
|
||||
bool eraseFont( const ResourceKey& key );
|
||||
/** @copydoc eraseFont(const ResourceKey&) */
|
||||
bool eraseFont( const std::string& key );
|
||||
/**
|
||||
* @brief Removes @p font only when its current name maps to that exact font in this catalog.
|
||||
* @return Whether the matching binding was removed.
|
||||
*/
|
||||
bool eraseFont( Font* font );
|
||||
|
||||
/** @brief Removes every binding while allowing previously returned handles to remain valid. */
|
||||
void clear();
|
||||
|
||||
/** @return The total number of texture, drawable, atlas, and font bindings. */
|
||||
std::size_t size() const;
|
||||
|
||||
private:
|
||||
@@ -49,6 +139,8 @@ class EE_API ResourceCatalog {
|
||||
UnorderedMap<std::string, DrawablePtr> mDrawables;
|
||||
UnorderedMap<String::HashType, DrawableWeakPtr> mDrawablesById;
|
||||
UnorderedMap<std::string, TextureAtlasPtr> mAtlases;
|
||||
UnorderedMap<std::string, FontPtr> mFonts;
|
||||
UnorderedMap<String::HashType, FontWeakPtr> mFontsById;
|
||||
};
|
||||
|
||||
}} // namespace EE::Graphics
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define EE_GRAPHICS_RESOURCESCOPE_HPP
|
||||
|
||||
#include <eepp/graphics/drawable.hpp>
|
||||
#include <eepp/graphics/fontservice.hpp>
|
||||
#include <eepp/graphics/resourcecatalog.hpp>
|
||||
#include <eepp/graphics/textureregion.hpp>
|
||||
|
||||
@@ -10,12 +11,30 @@ namespace EE { namespace Graphics {
|
||||
class ResourceScope;
|
||||
using ResourceScopePtr = ResourcePtr<ResourceScope>;
|
||||
|
||||
/** Graphics-only semantic lookup boundary with a local catalog and explicit catalog imports. */
|
||||
/**
|
||||
* @brief Graphics resource lookup boundary with local ownership and explicit catalog visibility.
|
||||
*
|
||||
* A scope owns resources published into its local catalog. Lookups search that local catalog first,
|
||||
* followed by imported catalogs in import order. Importing a catalog retains the catalog and makes
|
||||
* its resources visible; it does not copy resources and does not transfer them into the local
|
||||
* catalog. Consequently, removing an import only removes lookup visibility and releases the
|
||||
* scope's catalog reference.
|
||||
*
|
||||
* Use importCatalog() when resources owned by another lifetime boundary must be visible in this
|
||||
* scope, such as application assets shared with a scene or a theme catalog used by UI widgets.
|
||||
* Avoid importing unrelated scene or document catalogs: keeping imports explicit prevents name
|
||||
* collisions and resource leakage between independent documents. UISceneNode imports the default
|
||||
* resource catalog automatically unless that behavior is disabled at construction time.
|
||||
*/
|
||||
class EE_API ResourceScope {
|
||||
public:
|
||||
static ResourceScopePtr New();
|
||||
|
||||
ResourceScope();
|
||||
~ResourceScope();
|
||||
|
||||
FontService& getFontService();
|
||||
const FontService& getFontService() const;
|
||||
|
||||
TexturePtr findTexture( const ResourceKey& key ) const;
|
||||
TexturePtr findTexture( const std::string& key ) const;
|
||||
@@ -26,6 +45,10 @@ class EE_API ResourceScope {
|
||||
TextureAtlasPtr findAtlas( const ResourceKey& key ) const;
|
||||
TextureAtlasPtr findAtlas( const std::string& key ) const;
|
||||
std::vector<TextureAtlasPtr> getAtlases() const;
|
||||
FontPtr findFont( const ResourceKey& key ) const;
|
||||
FontPtr findFont( const std::string& key ) const;
|
||||
FontPtr findFont( const String::HashType& id ) const;
|
||||
std::vector<FontPtr> getFonts() const;
|
||||
std::vector<TextureRegionPtr>
|
||||
findTextureRegionsByPattern( const std::string& name, const std::string& extension = "",
|
||||
TextureAtlas* searchInTextureAtlas = nullptr ) const;
|
||||
@@ -39,27 +62,52 @@ class EE_API ResourceScope {
|
||||
void publishLocalDrawable( std::string key, DrawablePtr drawable );
|
||||
void publishLocalAtlas( ResourceKey key, TextureAtlasPtr atlas );
|
||||
void publishLocalAtlas( std::string key, TextureAtlasPtr atlas );
|
||||
/**
|
||||
* @brief Publishes a font under @p key, replacing any existing local binding for that key.
|
||||
*
|
||||
* The requested semantic key is preserved. Fonts are never renamed to avoid a collision.
|
||||
*/
|
||||
void publishLocalFont( ResourceKey key, FontPtr font );
|
||||
void publishLocalFont( std::string key, FontPtr font );
|
||||
bool eraseLocal( const ResourceKey& key );
|
||||
bool eraseLocal( const std::string& key );
|
||||
bool eraseLocalDrawable( const ResourceKey& key );
|
||||
bool eraseLocalDrawable( const std::string& key );
|
||||
bool eraseLocalAtlas( const ResourceKey& key );
|
||||
bool eraseLocalAtlas( const std::string& key );
|
||||
bool eraseLocalFont( const ResourceKey& key );
|
||||
bool eraseLocalFont( const std::string& key );
|
||||
bool eraseLocalFont( Font* font );
|
||||
void clearLocal();
|
||||
|
||||
/**
|
||||
* @brief Makes resources from @p catalog visible after this scope's local resources.
|
||||
*
|
||||
* Importing the same catalog more than once has no effect. The catalog is retained strongly for
|
||||
* as long as it remains imported. Catalog contents stay live: resources published after this
|
||||
* call become visible without importing the catalog again.
|
||||
*/
|
||||
void importCatalog( ResourceCatalogPtr catalog );
|
||||
|
||||
/** @brief Removes an imported catalog without modifying the catalog or its resources. */
|
||||
bool removeCatalog( const ResourceCatalogPtr& catalog );
|
||||
|
||||
/** @brief Removes every imported catalog while preserving this scope's local resources. */
|
||||
void clearImports();
|
||||
|
||||
ResourceCatalogPtr getLocalCatalog() const;
|
||||
|
||||
private:
|
||||
void attachFontService( const FontPtr& font );
|
||||
void detachFontService( const FontPtr& font );
|
||||
|
||||
ResourceCatalogPtr mLocalCatalog;
|
||||
FontService mFontService;
|
||||
std::vector<ResourceCatalogPtr> mImports;
|
||||
mutable System::Mutex mMutex;
|
||||
};
|
||||
|
||||
/** Engine-owned process defaults for pure Graphics and legacy application-wide resolution. */
|
||||
/** Engine-owned process defaults for pure Graphics and application-wide resolution. */
|
||||
EE_API ResourceCatalog& globalResourceCatalog();
|
||||
EE_API ResourceScope& defaultResourceScope();
|
||||
|
||||
|
||||
@@ -48,7 +48,16 @@ class EE_API TextLayout {
|
||||
LineWrapMode lineWrapMode = LineWrapMode::NoWrap, Uint32 wrapWidth = 0,
|
||||
bool keepIndentation = false, Float initialXOffset = 0 );
|
||||
|
||||
static void clearLayoutCache();
|
||||
/**
|
||||
* Removes entries from the shared text-layout LRU cache.
|
||||
*
|
||||
* @param font Optional borrowed font identity. When provided, only layouts requested with this
|
||||
* font or containing shaped glyphs produced by this font are evicted. Passing nullptr clears
|
||||
* the entire cache. Font destruction uses selective eviction before its borrowed pointers
|
||||
* become invalid.
|
||||
*/
|
||||
static void clearLayoutCache( Font* font = nullptr );
|
||||
|
||||
protected:
|
||||
static void wrapLayout( const String::View& string, TextLayout&, LineWrapMode lineWrapMode,
|
||||
Float wrapWidth, Float vspace, bool keepIndentation, Font* font,
|
||||
|
||||
@@ -118,6 +118,9 @@ class EE_API UIFontPickerDialog : public UIWindow {
|
||||
std::vector<Uint32> mSizes;
|
||||
UnorderedSet<std::string> mLoadedFontKeys;
|
||||
UnorderedMap<std::string, std::string> mFontTags;
|
||||
Graphics::FontTrueTypePtr mPreviewFont;
|
||||
Graphics::Font* mPreviewTextDefaultFont{ nullptr };
|
||||
Graphics::Font* mPreviewInputDefaultFont{ nullptr };
|
||||
std::shared_ptr<Models::Model> mFamilyModel;
|
||||
std::shared_ptr<Models::Model> mStyleModel;
|
||||
std::shared_ptr<Models::Model> mSizeModel;
|
||||
@@ -171,7 +174,7 @@ class EE_API UIFontPickerDialog : public UIWindow {
|
||||
|
||||
void sortFonts();
|
||||
|
||||
void mergeFontManagerFonts( std::vector<FontDesc>& fonts );
|
||||
void mergeLoadedFonts( std::vector<FontDesc>& fonts );
|
||||
|
||||
void updateFontTags();
|
||||
|
||||
@@ -189,6 +192,8 @@ class EE_API UIFontPickerDialog : public UIWindow {
|
||||
|
||||
void updatePreview();
|
||||
|
||||
void clearPreviewFont();
|
||||
|
||||
void selectInitialRows();
|
||||
|
||||
void selectFamily( const std::string& family );
|
||||
|
||||
@@ -23,6 +23,7 @@ using namespace EE::Network;
|
||||
|
||||
namespace EE { namespace Graphics {
|
||||
class Font;
|
||||
using FontPtr = ResourcePtr<Font>;
|
||||
}} // namespace EE::Graphics
|
||||
|
||||
namespace EE { namespace Window {
|
||||
@@ -57,9 +58,14 @@ class EE_API UISceneNode : public SceneNode {
|
||||
*
|
||||
* @param window Pointer to the window to associate with this UI scene node.
|
||||
* If NULL, uses the current window from Engine.
|
||||
* @param importDefaultResources Whether the scene scope automatically imports the catalog from
|
||||
* Graphics::defaultResourceScope(). Keep this enabled for normal
|
||||
* application scenes. Disable it for intentionally isolated
|
||||
* scenes that must only resolve local or explicitly imported resources.
|
||||
* @return Pointer to the newly created UISceneNode instance.
|
||||
*/
|
||||
static UISceneNode* New( EE::Window::Window* window = NULL );
|
||||
static UISceneNode* New( EE::Window::Window* window = NULL,
|
||||
bool importDefaultResources = true );
|
||||
|
||||
/**
|
||||
* @brief Destroys the UISceneNode and cleans up resources.
|
||||
@@ -782,7 +788,12 @@ class EE_API UISceneNode : public SceneNode {
|
||||
/** @return The Graphics resource lookup and ownership boundary of this scene. */
|
||||
const Graphics::ResourceScopePtr& getResourceScope() const;
|
||||
|
||||
/** Replaces this scene's resource boundary, allowing intentional sharing between scenes. */
|
||||
/**
|
||||
* @brief Replaces this scene's resource boundary, allowing intentional sharing between scenes.
|
||||
*
|
||||
* Scenes created with default-resource importing enabled also import the default catalog into
|
||||
* the replacement scope. Scenes created with it disabled leave the replacement scope unchanged.
|
||||
*/
|
||||
UISceneNode* setResourceScope( Graphics::ResourceScopePtr resourceScope );
|
||||
|
||||
/**
|
||||
@@ -928,10 +939,11 @@ class EE_API UISceneNode : public SceneNode {
|
||||
bool mStyleDuringLoad{ false };
|
||||
UIThemeManager* mUIThemeManager{ nullptr };
|
||||
UIIconThemeManager* mUIIconThemeManager{ nullptr };
|
||||
std::vector<Font*> mFontFaces;
|
||||
std::vector<Graphics::FontPtr> mFontFaces;
|
||||
UnorderedMap<std::string, Font*> mFontFaceAliases;
|
||||
UnorderedMap<Font*, std::string> mFontFaceFamilies;
|
||||
std::shared_ptr<AsyncResourceLoadState> mAsyncResourceLoadState;
|
||||
bool mImportDefaultResources{ true };
|
||||
Graphics::ResourceScopePtr mResourceScope;
|
||||
DrawableResolver mDrawableResolver;
|
||||
WebResourceCachePtr mWebResourceCache;
|
||||
@@ -971,8 +983,9 @@ class EE_API UISceneNode : public SceneNode {
|
||||
* Creates a UISceneNode with optional window association.
|
||||
*
|
||||
* @param window Pointer to the window, or NULL for default.
|
||||
* @param importDefaultResources Whether the scene scope imports the default resource catalog.
|
||||
*/
|
||||
explicit UISceneNode( EE::Window::Window* window = NULL );
|
||||
explicit UISceneNode( EE::Window::Window* window = NULL, bool importDefaultResources = true );
|
||||
|
||||
/**
|
||||
* @brief Handles node resize.
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
../../include/eepp/graphics/fontbmfont.hpp
|
||||
../../include/eepp/graphics/font.hpp
|
||||
../../include/eepp/graphics/fontfamily.hpp
|
||||
../../include/eepp/graphics/fontmanager.hpp
|
||||
../../include/eepp/graphics/fontservice.hpp
|
||||
../../include/eepp/graphics/fontsprite.hpp
|
||||
../../include/eepp/graphics/fontstyleconfig.hpp
|
||||
../../include/eepp/graphics/fonttruetype.hpp
|
||||
@@ -560,7 +560,7 @@
|
||||
../../src/eepp/graphics/fontbmfont.cpp
|
||||
../../src/eepp/graphics/font.cpp
|
||||
../../src/eepp/graphics/fontfamily.cpp
|
||||
../../src/eepp/graphics/fontmanager.cpp
|
||||
../../src/eepp/graphics/fontservice.cpp
|
||||
../../src/eepp/graphics/fontsprite.cpp
|
||||
../../src/eepp/graphics/fonttruetype.cpp
|
||||
../../src/eepp/graphics/framebuffer.cpp
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
../../include/eepp/graphics/fontbmfont.hpp
|
||||
../../include/eepp/graphics/font.hpp
|
||||
../../include/eepp/graphics/fontfamily.hpp
|
||||
../../include/eepp/graphics/fontmanager.hpp
|
||||
../../include/eepp/graphics/fontservice.hpp
|
||||
../../include/eepp/graphics/fontsprite.hpp
|
||||
../../include/eepp/graphics/fontstyleconfig.hpp
|
||||
../../include/eepp/graphics/fonttruetype.hpp
|
||||
@@ -551,7 +551,7 @@
|
||||
../../src/eepp/graphics/fontbmfont.cpp
|
||||
../../src/eepp/graphics/font.cpp
|
||||
../../src/eepp/graphics/fontfamily.cpp
|
||||
../../src/eepp/graphics/fontmanager.cpp
|
||||
../../src/eepp/graphics/fontservice.cpp
|
||||
../../src/eepp/graphics/fontsprite.cpp
|
||||
../../src/eepp/graphics/fonttruetype.cpp
|
||||
../../src/eepp/graphics/framebuffer.cpp
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
../../include/eepp/ui/webresourcecache.hpp
|
||||
../../include/eepp/graphics/fontbmfont.hpp
|
||||
../../include/eepp/graphics/font.hpp
|
||||
../../include/eepp/graphics/fontmanager.hpp
|
||||
../../include/eepp/graphics/fontservice.hpp
|
||||
../../include/eepp/graphics/fontsprite.hpp
|
||||
../../include/eepp/graphics/fontstyleconfig.hpp
|
||||
../../include/eepp/graphics/fonttruetype.hpp
|
||||
@@ -542,7 +542,7 @@
|
||||
../../src/eepp/ui/webresourcecache.cpp
|
||||
../../src/eepp/graphics/fontbmfont.cpp
|
||||
../../src/eepp/graphics/font.cpp
|
||||
../../src/eepp/graphics/fontmanager.cpp
|
||||
../../src/eepp/graphics/fontservice.cpp
|
||||
../../src/eepp/graphics/fontsprite.cpp
|
||||
../../src/eepp/graphics/fonttruetype.cpp
|
||||
../../src/eepp/graphics/framebuffer.cpp
|
||||
|
||||
@@ -236,7 +236,7 @@ UTEST( Benchmark, InlineLayout ) {
|
||||
800, 600, "bench", WindowStyle::Default, WindowBackend::Default, 32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
if ( !font->loaded() ) {
|
||||
Engine::destroySingleton();
|
||||
@@ -323,9 +323,9 @@ UTEST( Benchmark, MarkdownReadme ) {
|
||||
UISceneNode* ui = UISceneNode::New( window );
|
||||
SceneManager::instance()->add( ui );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
FontTrueType* monoFont = FontTrueType::New( "monospace" );
|
||||
FontTrueType* monoFont = FontTrueType::New( "monospace" ).get();
|
||||
monoFont->loadFromFile( "../assets/fonts/DejaVuSansMono.ttf" );
|
||||
if ( !font->loaded() || !monoFont->loaded() ) {
|
||||
Engine::destroySingleton();
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include <eepp/graphics/font.hpp>
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/globalbatchrenderer.hpp>
|
||||
#include <eepp/graphics/text.hpp>
|
||||
#include <eepp/window/engine.hpp>
|
||||
@@ -80,19 +79,19 @@ std::vector<std::size_t> Font::emojiCodePointsPositions( const String& string )
|
||||
|
||||
Font::Font( const FontType& Type, const std::string& Name ) : mType( Type ), mNumCallBacks( 0 ) {
|
||||
this->setName( Name );
|
||||
FontManager::instance()->add( this );
|
||||
}
|
||||
|
||||
Font::~Font() {
|
||||
if ( !FontManager::instance()->isDestroying() ) {
|
||||
FontManager::instance()->remove( this, false );
|
||||
}
|
||||
}
|
||||
Font::~Font() {}
|
||||
|
||||
const FontType& Font::getType() const {
|
||||
return mType;
|
||||
}
|
||||
|
||||
Float Font::getGlyphAdvance( Uint32 codePoint, unsigned int characterSize, bool bold, bool italic,
|
||||
Float outlineThickness ) const {
|
||||
return getGlyph( codePoint, characterSize, bold, italic, outlineThickness ).advance;
|
||||
}
|
||||
|
||||
const std::string& Font::getName() const {
|
||||
return mFontName;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <eepp/graphics/fontbmfont.hpp>
|
||||
#include <eepp/graphics/resourcescope.hpp>
|
||||
#include <eepp/graphics/texturefactory.hpp>
|
||||
#include <eepp/system/filesystem.hpp>
|
||||
#include <eepp/system/iostream.hpp>
|
||||
@@ -10,12 +11,27 @@
|
||||
|
||||
namespace EE { namespace Graphics {
|
||||
|
||||
FontBMFont* FontBMFont::New( const std::string fontName ) {
|
||||
return eeNew( FontBMFont, ( fontName ) );
|
||||
FontBMFontPtr FontBMFont::New( const std::string fontName ) {
|
||||
FontBMFontPtr font( eeNew( FontBMFont, ( fontName ) ), ResourceDeleter<FontBMFont>() );
|
||||
defaultResourceScope().publishLocalFont( fontName, font );
|
||||
return font;
|
||||
}
|
||||
|
||||
FontBMFont* FontBMFont::New( const std::string fontName, const std::string& filename ) {
|
||||
FontBMFont* fontBMFont = New( fontName );
|
||||
FontBMFontPtr FontBMFont::New( const std::string fontName, ResourceScope& resourceScope ) {
|
||||
FontBMFontPtr font( eeNew( FontBMFont, ( fontName ) ), ResourceDeleter<FontBMFont>() );
|
||||
resourceScope.publishLocalFont( fontName, font );
|
||||
return font;
|
||||
}
|
||||
|
||||
FontBMFontPtr FontBMFont::New( const std::string fontName, const std::string& filename ) {
|
||||
FontBMFontPtr fontBMFont = New( fontName );
|
||||
fontBMFont->loadFromFile( filename );
|
||||
return fontBMFont;
|
||||
}
|
||||
|
||||
FontBMFontPtr FontBMFont::New( const std::string fontName, const std::string& filename,
|
||||
ResourceScope& resourceScope ) {
|
||||
FontBMFontPtr fontBMFont = New( fontName, resourceScope );
|
||||
fontBMFont->loadFromFile( filename );
|
||||
return fontBMFont;
|
||||
}
|
||||
@@ -194,6 +210,11 @@ Glyph FontBMFont::getGlyph( Uint32 codePoint, unsigned int characterSize, bool b
|
||||
}
|
||||
}
|
||||
|
||||
Float FontBMFont::getGlyphAdvance( Uint32 codePoint, unsigned int characterSize, bool bold,
|
||||
bool italic, Float outlineThickness ) const {
|
||||
return getGlyph( codePoint, characterSize, bold, italic, outlineThickness ).advance;
|
||||
}
|
||||
|
||||
GlyphDrawable* FontBMFont::getGlyphDrawable( Uint32 codePoint, unsigned int characterSize,
|
||||
bool bold, bool italic,
|
||||
Float outlineThickness ) const {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <eepp/graphics/fontfamily.hpp>
|
||||
#include <eepp/graphics/fontservice.hpp>
|
||||
#include <eepp/system/filesystem.hpp>
|
||||
|
||||
using namespace std::literals;
|
||||
@@ -53,11 +54,15 @@ std::string FontFamily::findType( const std::string& fontpath, const std::string
|
||||
return "";
|
||||
}
|
||||
|
||||
FontTrueType* FontFamily::setFont( FontTrueType* font, const std::string& fontpath,
|
||||
const std::string_view& fontType ) {
|
||||
void FontFamily::setFont( FontTrueType* font, const std::string& fontpath,
|
||||
const std::string_view& fontType ) {
|
||||
if ( fontpath.empty() )
|
||||
return nullptr;
|
||||
FontTrueType* loadedFont = FontTrueType::New( font->getName() + "-" + fontType, fontpath );
|
||||
return;
|
||||
FontService* fontService = font->getFontService();
|
||||
FontTrueTypePtr loadedFont =
|
||||
fontService ? FontTrueType::New( font->getName() + "-" + fontType, fontpath,
|
||||
fontService->getResourceScope() )
|
||||
: FontTrueType::New( font->getName() + "-" + fontType, fontpath );
|
||||
if ( fontType == "bold"sv )
|
||||
font->setBoldFont( loadedFont );
|
||||
else if ( fontType == "italic"sv )
|
||||
@@ -66,7 +71,6 @@ FontTrueType* FontFamily::setFont( FontTrueType* font, const std::string& fontpa
|
||||
font->setBoldItalicFont( loadedFont );
|
||||
loadedFont->setBoldAdvanceSameAsRegular( font->getBoldAdvanceSameAsRegular() );
|
||||
loadedFont->setEnableDynamicMonospace( font->getEnableDynamicMonospace() );
|
||||
return loadedFont;
|
||||
}
|
||||
|
||||
}} // namespace EE::Graphics
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/fonttruetype.hpp>
|
||||
#include <eepp/graphics/systemfontresolver.hpp>
|
||||
#include <eepp/system/filesystem.hpp>
|
||||
|
||||
namespace EE { namespace Graphics {
|
||||
|
||||
SINGLETON_DECLARE_IMPLEMENTATION( FontManager )
|
||||
|
||||
FontManager::FontManager() {}
|
||||
|
||||
FontManager::~FontManager() {
|
||||
mEmojiFont = nullptr;
|
||||
mColorEmojiFont = nullptr;
|
||||
mFallbackFonts.clear();
|
||||
mSystemFallbackFonts.clear();
|
||||
}
|
||||
|
||||
Graphics::Font* FontManager::add( Graphics::Font* font ) {
|
||||
eeASSERT( NULL != font );
|
||||
return ResourceManager<Graphics::Font>::add( font );
|
||||
}
|
||||
|
||||
void FontManager::setColorEmojiFont( Font* font ) {
|
||||
mColorEmojiFont = font;
|
||||
}
|
||||
|
||||
Graphics::Font* FontManager::getColorEmojiFont() const {
|
||||
return mColorEmojiFont;
|
||||
}
|
||||
|
||||
Graphics::Font* FontManager::getEmojiFont() const {
|
||||
return mEmojiFont;
|
||||
}
|
||||
|
||||
void FontManager::setEmojiFont( Graphics::Font* newEmojiFont ) {
|
||||
mEmojiFont = newEmojiFont;
|
||||
}
|
||||
|
||||
const std::vector<Font*>& FontManager::getFallbackFonts() const {
|
||||
return mFallbackFonts;
|
||||
}
|
||||
|
||||
bool FontManager::hasFallbackFonts() const {
|
||||
return !mFallbackFonts.empty();
|
||||
}
|
||||
|
||||
bool FontManager::addFallbackFont( Font* fallbackFont ) {
|
||||
if ( fallbackFont && std::find( mFallbackFonts.begin(), mFallbackFonts.end(), fallbackFont ) ==
|
||||
mFallbackFonts.end() ) {
|
||||
mFallbackFonts.emplace_back( fallbackFont );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FontManager::removeFallbackFont( Font* fallbackFont ) {
|
||||
auto fallbackFontIt = std::find( mFallbackFonts.begin(), mFallbackFonts.end(), fallbackFont );
|
||||
if ( fallbackFontIt != mFallbackFonts.end() ) {
|
||||
mFallbackFonts.erase( fallbackFontIt );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
FontHinting FontManager::getHinting() const {
|
||||
return mHinting;
|
||||
}
|
||||
|
||||
void FontManager::setHinting( FontHinting hinting ) {
|
||||
mHinting = hinting;
|
||||
|
||||
for ( auto [_, font] : mResources ) {
|
||||
if ( font->getType() == FontType::TTF ) {
|
||||
auto ttf = static_cast<FontTrueType*>( font );
|
||||
if ( !ttf->isEmojiFont() )
|
||||
ttf->setHinting( hinting );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FontAntialiasing FontManager::getAntialiasing() const {
|
||||
return mAntialiasing;
|
||||
}
|
||||
|
||||
void FontManager::setAntialiasing( FontAntialiasing antialiasing ) {
|
||||
mAntialiasing = antialiasing;
|
||||
|
||||
for ( auto [_, font] : mResources ) {
|
||||
if ( font->getType() == FontType::TTF ) {
|
||||
auto ttf = static_cast<FontTrueType*>( font );
|
||||
if ( !ttf->isEmojiFont() )
|
||||
ttf->setAntialiasing( antialiasing );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Font* FontManager::getByInternalId( Uint32 internalId ) const {
|
||||
for ( auto [_, font] : mResources ) {
|
||||
if ( font->getType() == FontType::TTF &&
|
||||
static_cast<FontTrueType*>( font )->getFontInternalId() == internalId )
|
||||
return font;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FontTrueType* FontManager::getOrLoadSystemFallbackFont( const FontDesc& desc ) {
|
||||
if ( desc.path.empty() )
|
||||
return nullptr;
|
||||
|
||||
for ( auto* font : mSystemFallbackFonts ) {
|
||||
if ( font->getType() == FontType::TTF ) {
|
||||
auto* ttf = static_cast<FontTrueType*>( font );
|
||||
if ( ttf->getInfo().fontpath + ttf->getInfo().filename == desc.path &&
|
||||
ttf->getFaceIndex() == desc.faceIndex )
|
||||
return ttf;
|
||||
}
|
||||
}
|
||||
|
||||
FontTrueType* ttf = FontTrueType::New( desc.family, desc.path, desc.faceIndex );
|
||||
if ( !ttf || !ttf->loaded() ) {
|
||||
eeSAFE_DELETE( ttf );
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mSystemFallbackFonts.push_back( ttf );
|
||||
|
||||
return ttf;
|
||||
}
|
||||
|
||||
}} // namespace EE::Graphics
|
||||
@@ -0,0 +1,162 @@
|
||||
#include <algorithm>
|
||||
#include <eepp/graphics/fontservice.hpp>
|
||||
#include <eepp/graphics/fonttruetype.hpp>
|
||||
#include <eepp/graphics/resourcescope.hpp>
|
||||
#include <eepp/graphics/systemfontresolver.hpp>
|
||||
|
||||
namespace EE { namespace Graphics {
|
||||
|
||||
FontService::FontService( ResourceScope& resourceScope ) : mResourceScope( resourceScope ) {}
|
||||
|
||||
ResourceScope& FontService::getResourceScope() const {
|
||||
return mResourceScope;
|
||||
}
|
||||
|
||||
FontPtr FontService::findHandle( Font* font ) const {
|
||||
if ( !font )
|
||||
return {};
|
||||
FontPtr handle = mResourceScope.findFont( font->getId() );
|
||||
return handle.get() == font ? handle : FontPtr{};
|
||||
}
|
||||
|
||||
void FontService::onFontRemoved( Font* font ) {
|
||||
if ( mColorEmojiFont.get() == font )
|
||||
mColorEmojiFont.reset();
|
||||
if ( mEmojiFont.get() == font )
|
||||
mEmojiFont.reset();
|
||||
removeFallbackFont( font );
|
||||
mSystemFallbackFonts.erase(
|
||||
std::remove_if( mSystemFallbackFonts.begin(), mSystemFallbackFonts.end(),
|
||||
[font]( const FontPtr& systemFont ) { return systemFont.get() == font; } ),
|
||||
mSystemFallbackFonts.end() );
|
||||
}
|
||||
|
||||
void FontService::setColorEmojiFont( Font* font ) {
|
||||
mColorEmojiFont = findHandle( font );
|
||||
}
|
||||
|
||||
Font* FontService::getColorEmojiFont() const {
|
||||
return mColorEmojiFont.get();
|
||||
}
|
||||
|
||||
Font* FontService::getEmojiFont() const {
|
||||
return mEmojiFont.get();
|
||||
}
|
||||
|
||||
void FontService::setEmojiFont( Font* font ) {
|
||||
mEmojiFont = findHandle( font );
|
||||
}
|
||||
|
||||
const std::vector<FontPtr>& FontService::getFallbackFonts() const {
|
||||
return mFallbackFonts;
|
||||
}
|
||||
|
||||
bool FontService::hasFallbackFonts() const {
|
||||
return !mFallbackFonts.empty();
|
||||
}
|
||||
|
||||
bool FontService::addFallbackFont( FontPtr fallbackFont ) {
|
||||
if ( fallbackFont && std::find( mFallbackFonts.begin(), mFallbackFonts.end(), fallbackFont ) ==
|
||||
mFallbackFonts.end() ) {
|
||||
mFallbackFonts.emplace_back( std::move( fallbackFont ) );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FontService::addFallbackFont( Font* fallbackFont ) {
|
||||
return addFallbackFont( findHandle( fallbackFont ) );
|
||||
}
|
||||
|
||||
bool FontService::removeFallbackFont( Font* fallbackFont ) {
|
||||
auto it = std::find_if(
|
||||
mFallbackFonts.begin(), mFallbackFonts.end(),
|
||||
[fallbackFont]( const FontPtr& font ) { return font.get() == fallbackFont; } );
|
||||
if ( it == mFallbackFonts.end() )
|
||||
return false;
|
||||
mFallbackFonts.erase( it );
|
||||
return true;
|
||||
}
|
||||
|
||||
FontHinting FontService::getHinting() const {
|
||||
return mHinting;
|
||||
}
|
||||
|
||||
void FontService::setHinting( FontHinting hinting ) {
|
||||
mHinting = hinting;
|
||||
for ( const FontPtr& fontHandle : mResourceScope.getFonts() ) {
|
||||
Font* font = fontHandle.get();
|
||||
if ( font->getType() == FontType::TTF ) {
|
||||
auto ttf = static_cast<FontTrueType*>( font );
|
||||
if ( ttf->getFontService() == this && !ttf->isEmojiFont() )
|
||||
ttf->setHinting( hinting );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FontAntialiasing FontService::getAntialiasing() const {
|
||||
return mAntialiasing;
|
||||
}
|
||||
|
||||
void FontService::setAntialiasing( FontAntialiasing antialiasing ) {
|
||||
mAntialiasing = antialiasing;
|
||||
for ( const FontPtr& fontHandle : mResourceScope.getFonts() ) {
|
||||
Font* font = fontHandle.get();
|
||||
if ( font->getType() == FontType::TTF ) {
|
||||
auto ttf = static_cast<FontTrueType*>( font );
|
||||
if ( ttf->getFontService() == this && !ttf->isEmojiFont() )
|
||||
ttf->setAntialiasing( antialiasing );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Font* FontService::getByInternalId( Uint32 internalId ) const {
|
||||
for ( const FontPtr& fontHandle : mResourceScope.getFonts() ) {
|
||||
Font* font = fontHandle.get();
|
||||
if ( font->getType() == FontType::TTF &&
|
||||
static_cast<FontTrueType*>( font )->getFontInternalId() == internalId )
|
||||
return font;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ResourcePtr<FontTrueType> FontService::loadSystemFont( const FontDesc& desc ) {
|
||||
if ( desc.path.empty() )
|
||||
return {};
|
||||
|
||||
FontTrueTypePtr ttf( eeNew( FontTrueType, ( desc.family, *this ) ),
|
||||
ResourceDeleter<FontTrueType>() );
|
||||
if ( !ttf->loadFromFile( desc.path, desc.faceIndex ) )
|
||||
return {};
|
||||
|
||||
ttf->setHinting( mHinting );
|
||||
ttf->setAntialiasing( mAntialiasing );
|
||||
// A standalone font can outlive this service, so it must not retain a borrowed service pointer.
|
||||
ttf->setFontService( nullptr );
|
||||
return ttf;
|
||||
}
|
||||
|
||||
FontTrueType* FontService::getOrLoadSystemFallbackFont( const FontDesc& desc ) {
|
||||
if ( desc.path.empty() )
|
||||
return nullptr;
|
||||
|
||||
for ( const FontPtr& fontHandle : mSystemFallbackFonts ) {
|
||||
auto* ttf = static_cast<FontTrueType*>( fontHandle.get() );
|
||||
if ( ttf->getInfo().fontpath + ttf->getInfo().filename == desc.path &&
|
||||
ttf->getFaceIndex() == desc.faceIndex )
|
||||
return ttf;
|
||||
}
|
||||
|
||||
FontTrueTypePtr ttf =
|
||||
FontTrueType::New( desc.family, desc.path, desc.faceIndex, mResourceScope );
|
||||
if ( !ttf || !ttf->loaded() ) {
|
||||
if ( ttf )
|
||||
mResourceScope.eraseLocalFont( ttf.get() );
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mSystemFallbackFonts.emplace_back( ttf );
|
||||
return ttf.get();
|
||||
}
|
||||
|
||||
}} // namespace EE::Graphics
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <eepp/graphics/fontsprite.hpp>
|
||||
#include <eepp/graphics/resourcescope.hpp>
|
||||
#include <eepp/graphics/texturefactory.hpp>
|
||||
#include <eepp/system/filesystem.hpp>
|
||||
#include <eepp/system/iostream.hpp>
|
||||
@@ -10,12 +11,27 @@
|
||||
|
||||
namespace EE { namespace Graphics {
|
||||
|
||||
FontSprite* FontSprite::New( const std::string fontName ) {
|
||||
return eeNew( FontSprite, ( fontName ) );
|
||||
FontSpritePtr FontSprite::New( const std::string fontName ) {
|
||||
FontSpritePtr font( eeNew( FontSprite, ( fontName ) ), ResourceDeleter<FontSprite>() );
|
||||
defaultResourceScope().publishLocalFont( fontName, font );
|
||||
return font;
|
||||
}
|
||||
|
||||
FontSprite* FontSprite::New( const std::string fontName, const std::string& filename ) {
|
||||
FontSprite* fontSprite = New( fontName );
|
||||
FontSpritePtr FontSprite::New( const std::string fontName, ResourceScope& resourceScope ) {
|
||||
FontSpritePtr font( eeNew( FontSprite, ( fontName ) ), ResourceDeleter<FontSprite>() );
|
||||
resourceScope.publishLocalFont( fontName, font );
|
||||
return font;
|
||||
}
|
||||
|
||||
FontSpritePtr FontSprite::New( const std::string fontName, const std::string& filename ) {
|
||||
FontSpritePtr fontSprite = New( fontName );
|
||||
fontSprite->loadFromFile( filename );
|
||||
return fontSprite;
|
||||
}
|
||||
|
||||
FontSpritePtr FontSprite::New( const std::string fontName, const std::string& filename,
|
||||
ResourceScope& resourceScope ) {
|
||||
FontSpritePtr fontSprite = New( fontName, resourceScope );
|
||||
fontSprite->loadFromFile( filename );
|
||||
return fontSprite;
|
||||
}
|
||||
|
||||
+200
-139
@@ -1,8 +1,10 @@
|
||||
#include <eepp/core/retainsymbol.hpp>
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/fontservice.hpp>
|
||||
#include <eepp/graphics/fonttruetype.hpp>
|
||||
#include <eepp/graphics/resourcescope.hpp>
|
||||
#include <eepp/graphics/systemfontresolver.hpp>
|
||||
#include <eepp/graphics/text.hpp>
|
||||
#include <eepp/graphics/textlayout.hpp>
|
||||
#include <eepp/graphics/texturefactory.hpp>
|
||||
#include <eepp/system/filesystem.hpp>
|
||||
#include <eepp/system/iostream.hpp>
|
||||
@@ -266,24 +268,49 @@ static inline Uint64 getKerningKey( Uint32 first, Uint32 second, unsigned int ch
|
||||
( static_cast<Uint64>( static_cast<Uint32>( outlineThickness * 100.f ) & 0xFF ) );
|
||||
}
|
||||
|
||||
FontTrueType* FontTrueType::New( const std::string& FontName ) {
|
||||
return eeNew( FontTrueType, ( FontName ) );
|
||||
FontTrueTypePtr FontTrueType::New( const std::string& FontName ) {
|
||||
FontTrueTypePtr font(
|
||||
eeNew( FontTrueType, ( FontName, defaultResourceScope().getFontService() ) ),
|
||||
ResourceDeleter<FontTrueType>() );
|
||||
defaultResourceScope().publishLocalFont( FontName, font );
|
||||
return font;
|
||||
}
|
||||
|
||||
FontTrueType* FontTrueType::New( const std::string& FontName, const std::string& filename ) {
|
||||
FontTrueType* fontTrueType = New( FontName );
|
||||
FontTrueTypePtr FontTrueType::New( const std::string& FontName, ResourceScope& resourceScope ) {
|
||||
FontTrueTypePtr font( eeNew( FontTrueType, ( FontName, resourceScope.getFontService() ) ),
|
||||
ResourceDeleter<FontTrueType>() );
|
||||
resourceScope.publishLocalFont( FontName, font );
|
||||
return font;
|
||||
}
|
||||
|
||||
FontTrueTypePtr FontTrueType::New( const std::string& FontName, const std::string& filename ) {
|
||||
FontTrueTypePtr fontTrueType = New( FontName );
|
||||
fontTrueType->loadFromFile( filename );
|
||||
return fontTrueType;
|
||||
}
|
||||
|
||||
FontTrueType* FontTrueType::New( const std::string& FontName, const std::string& filename,
|
||||
Uint32 faceIndex ) {
|
||||
FontTrueType* fontTrueType = New( FontName );
|
||||
FontTrueTypePtr FontTrueType::New( const std::string& FontName, const std::string& filename,
|
||||
ResourceScope& resourceScope ) {
|
||||
FontTrueTypePtr fontTrueType = New( FontName, resourceScope );
|
||||
fontTrueType->loadFromFile( filename );
|
||||
return fontTrueType;
|
||||
}
|
||||
|
||||
FontTrueTypePtr FontTrueType::New( const std::string& FontName, const std::string& filename,
|
||||
Uint32 faceIndex ) {
|
||||
FontTrueTypePtr fontTrueType = New( FontName );
|
||||
fontTrueType->loadFromFile( filename, faceIndex );
|
||||
return fontTrueType;
|
||||
}
|
||||
|
||||
FontTrueType::FontTrueType( const std::string& FontName ) :
|
||||
FontTrueTypePtr FontTrueType::New( const std::string& FontName, const std::string& filename,
|
||||
Uint32 faceIndex, ResourceScope& resourceScope ) {
|
||||
FontTrueTypePtr fontTrueType = New( FontName, resourceScope );
|
||||
fontTrueType->loadFromFile( filename, faceIndex );
|
||||
return fontTrueType;
|
||||
}
|
||||
|
||||
FontTrueType::FontTrueType( const std::string& FontName, FontService& fontService ) :
|
||||
Font( FontType::TTF, FontName ),
|
||||
mLibrary( NULL ),
|
||||
mFace( NULL ),
|
||||
@@ -307,17 +334,19 @@ FontTrueType::FontTrueType( const std::string& FontName ) :
|
||||
mIsBold( false ),
|
||||
mIsItalic( false ),
|
||||
mIsMonospaceCompletePending( false ),
|
||||
mHinting( FontManager::instance()->getHinting() ),
|
||||
mAntialiasing( FontManager::instance()->getAntialiasing() ),
|
||||
mFaceIndex( 0 ),
|
||||
mFontBold( nullptr ),
|
||||
mFontItalic( nullptr ),
|
||||
mFontBoldItalic( nullptr ),
|
||||
mFontBoldCb( 0 ),
|
||||
mFontItalicCb( 0 ),
|
||||
mFontBoldItalicCb( 0 ) {}
|
||||
mHinting( fontService.getHinting() ),
|
||||
mAntialiasing( fontService.getAntialiasing() ),
|
||||
mFontService( &fontService ),
|
||||
mFaceIndex( 0 ) {}
|
||||
|
||||
void FontTrueType::setFontService( FontService* fontService ) {
|
||||
mFontService = fontService;
|
||||
}
|
||||
|
||||
FontTrueType::~FontTrueType() {
|
||||
// Cached shaped glyphs borrow FontTrueType pointers. Drop layouts referencing this font before
|
||||
// it dies, while preserving unrelated entries in the shared cache.
|
||||
TextLayout::clearLayoutCache( this );
|
||||
cleanup();
|
||||
}
|
||||
|
||||
@@ -516,12 +545,12 @@ bool FontTrueType::setFontFace( void* _face ) {
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( ( mIsColorEmojiFont || mHasColrGlyphs ) &&
|
||||
FontManager::instance()->getColorEmojiFont() == nullptr )
|
||||
FontManager::instance()->setColorEmojiFont( this );
|
||||
if ( mFontService && ( mIsColorEmojiFont || mHasColrGlyphs ) &&
|
||||
mFontService->getColorEmojiFont() == nullptr )
|
||||
mFontService->setColorEmojiFont( this );
|
||||
|
||||
if ( mIsEmojiFont && !mHasSvgGlyphs && FontManager::instance()->getEmojiFont() == nullptr )
|
||||
FontManager::instance()->setEmojiFont( this );
|
||||
if ( mFontService && mIsEmojiFont && !mHasSvgGlyphs && mFontService->getEmojiFont() == nullptr )
|
||||
mFontService->setEmojiFont( this );
|
||||
|
||||
// Load the stroker that will be used to outline the font
|
||||
FT_Stroker stroker = nullptr;
|
||||
@@ -611,6 +640,7 @@ bool FontTrueType::setVariableFontWeight( FontWeight weight ) {
|
||||
mKeyCache.clear();
|
||||
mKerningCache.clear();
|
||||
mKerningGlyphCache.clear();
|
||||
mGlyphAdvanceCache.clear();
|
||||
#ifdef EE_TEXT_SHAPER_ENABLED
|
||||
if ( mHBFont )
|
||||
hb_ft_font_changed( static_cast<hb_font_t*>( mHBFont ) );
|
||||
@@ -649,11 +679,11 @@ Glyph FontTrueType::getGlyph( Uint32 codePoint, unsigned int characterSize, bool
|
||||
Uint32 idx = 0;
|
||||
if ( mEnableEmojiFallback && !mIsColorEmojiFont && !mHasSvgGlyphs && !mHasColrGlyphs &&
|
||||
!mIsEmojiFont && Font::isEmojiCodePoint( codePoint ) ) {
|
||||
if ( !mIsColorEmojiFont && FontManager::instance()->getColorEmojiFont() != nullptr &&
|
||||
FontManager::instance()->getColorEmojiFont()->getType() == FontType::TTF ) {
|
||||
if ( mFontService && !mIsColorEmojiFont && mFontService->getColorEmojiFont() != nullptr &&
|
||||
mFontService->getColorEmojiFont()->getType() == FontType::TTF ) {
|
||||
|
||||
FontTrueType* fontEmoji =
|
||||
static_cast<FontTrueType*>( FontManager::instance()->getColorEmojiFont() );
|
||||
static_cast<FontTrueType*>( mFontService->getColorEmojiFont() );
|
||||
if ( ( idx = fontEmoji->getGlyphIndex( codePoint ) ) ) {
|
||||
if ( mIsMonospace && mEnableDynamicMonospace ) {
|
||||
mIsMonospaceComplete = false;
|
||||
@@ -662,11 +692,10 @@ Glyph FontTrueType::getGlyph( Uint32 codePoint, unsigned int characterSize, bool
|
||||
return fontEmoji->getGlyphByIndex( idx, characterSize, bold, italic,
|
||||
outlineThickness, getPage( characterSize ) );
|
||||
}
|
||||
} else if ( !mIsEmojiFont && FontManager::instance()->getEmojiFont() != nullptr &&
|
||||
FontManager::instance()->getEmojiFont()->getType() == FontType::TTF ) {
|
||||
} else if ( mFontService && !mIsEmojiFont && mFontService->getEmojiFont() != nullptr &&
|
||||
mFontService->getEmojiFont()->getType() == FontType::TTF ) {
|
||||
|
||||
FontTrueType* fontEmoji =
|
||||
static_cast<FontTrueType*>( FontManager::instance()->getEmojiFont() );
|
||||
FontTrueType* fontEmoji = static_cast<FontTrueType*>( mFontService->getEmojiFont() );
|
||||
if ( ( idx = fontEmoji->getGlyphIndex( codePoint ) ) ) {
|
||||
if ( mIsMonospace && mEnableDynamicMonospace ) {
|
||||
mIsMonospaceComplete = false;
|
||||
@@ -678,27 +707,26 @@ Glyph FontTrueType::getGlyph( Uint32 codePoint, unsigned int characterSize, bool
|
||||
}
|
||||
}
|
||||
|
||||
if ( bold && italic && mFontBoldItalic != nullptr &&
|
||||
if ( bold && italic && mFontBoldItalic &&
|
||||
( idx = mFontBoldItalic->getGlyphIndex( codePoint ) ) ) {
|
||||
return mFontBoldItalic->getGlyphByIndex( idx, characterSize, true, true, outlineThickness,
|
||||
getPage( characterSize ) );
|
||||
}
|
||||
|
||||
if ( bold && !italic && mFontBold != nullptr &&
|
||||
( idx = mFontBold->getGlyphIndex( codePoint ) ) ) {
|
||||
if ( bold && !italic && mFontBold && ( idx = mFontBold->getGlyphIndex( codePoint ) ) ) {
|
||||
return mFontBold->getGlyphByIndex( idx, characterSize, true, false, outlineThickness,
|
||||
getPage( characterSize ) );
|
||||
}
|
||||
|
||||
if ( italic && !bold && mFontItalic != nullptr &&
|
||||
( idx = mFontItalic->getGlyphIndex( codePoint ) ) ) {
|
||||
if ( italic && !bold && mFontItalic && ( idx = mFontItalic->getGlyphIndex( codePoint ) ) ) {
|
||||
return mFontItalic->getGlyphByIndex( idx, characterSize, false, true, outlineThickness,
|
||||
getPage( characterSize ) );
|
||||
}
|
||||
|
||||
idx = getGlyphIndex( codePoint );
|
||||
if ( 0 == idx && mEnableFallbackFont && FontManager::instance()->hasFallbackFonts() ) {
|
||||
for ( Font* fallbackFontPtr : FontManager::instance()->getFallbackFonts() ) {
|
||||
if ( 0 == idx && mEnableFallbackFont && mFontService && mFontService->hasFallbackFonts() ) {
|
||||
for ( const FontPtr& fallbackFontHandle : mFontService->getFallbackFonts() ) {
|
||||
Font* fallbackFontPtr = fallbackFontHandle.get();
|
||||
if ( fallbackFontPtr->getType() != FontType::TTF )
|
||||
continue;
|
||||
FontTrueType* fallbackFont = static_cast<FontTrueType*>( fallbackFontPtr );
|
||||
@@ -718,7 +746,7 @@ Glyph FontTrueType::getGlyph( Uint32 codePoint, unsigned int characterSize, bool
|
||||
codePoint, FontWeight::Normal, false );
|
||||
if ( !fallbackDesc.path.empty() ) {
|
||||
FontTrueType* systemFallback =
|
||||
FontManager::instance()->getOrLoadSystemFallbackFont( fallbackDesc );
|
||||
mFontService ? mFontService->getOrLoadSystemFallbackFont( fallbackDesc ) : nullptr;
|
||||
if ( systemFallback && ( idx = systemFallback->getGlyphIndex( codePoint ) ) ) {
|
||||
if ( mIsMonospace && mEnableDynamicMonospace ) {
|
||||
mIsMonospaceComplete = false;
|
||||
@@ -791,10 +819,11 @@ GlyphDrawable* FontTrueType::getGlyphDrawable( Uint32 codePoint, unsigned int ch
|
||||
|
||||
if ( mEnableEmojiFallback && Font::isEmojiCodePoint( codePoint ) && !mIsColorEmojiFont &&
|
||||
!mIsEmojiFont ) {
|
||||
if ( !mIsColorEmojiFont && FontManager::instance()->getColorEmojiFont() != nullptr &&
|
||||
FontManager::instance()->getColorEmojiFont()->getType() == FontType::TTF ) {
|
||||
if ( mFontService && !mIsColorEmojiFont &&
|
||||
mFontService->getColorEmojiFont() != nullptr &&
|
||||
mFontService->getColorEmojiFont()->getType() == FontType::TTF ) {
|
||||
FontTrueType* fontEmoji =
|
||||
static_cast<FontTrueType*>( FontManager::instance()->getColorEmojiFont() );
|
||||
static_cast<FontTrueType*>( mFontService->getColorEmojiFont() );
|
||||
tGlyphIndex = fontEmoji->getGlyphIndex( codePoint );
|
||||
if ( 0 != tGlyphIndex ) {
|
||||
glyphIndex = tGlyphIndex;
|
||||
@@ -802,10 +831,10 @@ GlyphDrawable* FontTrueType::getGlyphDrawable( Uint32 codePoint, unsigned int ch
|
||||
} else {
|
||||
glyphIndex = getGlyphIndex( codePoint );
|
||||
}
|
||||
} else if ( !mIsEmojiFont && FontManager::instance()->getEmojiFont() != nullptr &&
|
||||
FontManager::instance()->getEmojiFont()->getType() == FontType::TTF ) {
|
||||
} else if ( mFontService && !mIsEmojiFont && mFontService->getEmojiFont() != nullptr &&
|
||||
mFontService->getEmojiFont()->getType() == FontType::TTF ) {
|
||||
FontTrueType* fontEmoji =
|
||||
static_cast<FontTrueType*>( FontManager::instance()->getEmojiFont() );
|
||||
static_cast<FontTrueType*>( mFontService->getEmojiFont() );
|
||||
tGlyphIndex = fontEmoji->getGlyphIndex( codePoint );
|
||||
if ( 0 != tGlyphIndex ) {
|
||||
glyphIndex = tGlyphIndex;
|
||||
@@ -820,29 +849,30 @@ GlyphDrawable* FontTrueType::getGlyphDrawable( Uint32 codePoint, unsigned int ch
|
||||
glyphIndex = getGlyphIndex( codePoint );
|
||||
}
|
||||
|
||||
if ( bold && italic && mFontBoldItalic != nullptr &&
|
||||
if ( bold && italic && mFontBoldItalic &&
|
||||
( tGlyphIndex = mFontBoldItalic->getGlyphIndex( codePoint ) ) ) {
|
||||
glyphIndex = tGlyphIndex;
|
||||
fontInternalId = mFontBoldItalic->getFontInternalId();
|
||||
isItalic = true;
|
||||
}
|
||||
|
||||
if ( bold && !italic && mFontBold != nullptr &&
|
||||
if ( bold && !italic && mFontBold &&
|
||||
( tGlyphIndex = mFontBold->getGlyphIndex( codePoint ) ) ) {
|
||||
glyphIndex = tGlyphIndex;
|
||||
fontInternalId = mFontBold->getFontInternalId();
|
||||
}
|
||||
|
||||
if ( italic && !bold && mFontItalic != nullptr &&
|
||||
if ( italic && !bold && mFontItalic &&
|
||||
( tGlyphIndex = mFontItalic->getGlyphIndex( codePoint ) ) ) {
|
||||
glyphIndex = tGlyphIndex;
|
||||
fontInternalId = mFontItalic->getFontInternalId();
|
||||
isItalic = true;
|
||||
}
|
||||
|
||||
if ( 0 == glyphIndex && mEnableFallbackFont &&
|
||||
FontManager::instance()->hasFallbackFonts() ) {
|
||||
for ( Font* fontFallbackPtr : FontManager::instance()->getFallbackFonts() ) {
|
||||
if ( 0 == glyphIndex && mEnableFallbackFont && mFontService &&
|
||||
mFontService->hasFallbackFonts() ) {
|
||||
for ( const FontPtr& fontFallbackHandle : mFontService->getFallbackFonts() ) {
|
||||
Font* fontFallbackPtr = fontFallbackHandle.get();
|
||||
if ( fontFallbackPtr->getType() != FontType::TTF )
|
||||
continue;
|
||||
FontTrueType* fontFallback = static_cast<FontTrueType*>( fontFallbackPtr );
|
||||
@@ -866,7 +896,8 @@ GlyphDrawable* FontTrueType::getGlyphDrawable( Uint32 codePoint, unsigned int ch
|
||||
codePoint, FontWeight::Normal, false );
|
||||
if ( !fallbackDesc.path.empty() ) {
|
||||
FontTrueType* systemFallback =
|
||||
FontManager::instance()->getOrLoadSystemFallbackFont( fallbackDesc );
|
||||
mFontService ? mFontService->getOrLoadSystemFallbackFont( fallbackDesc )
|
||||
: nullptr;
|
||||
if ( systemFallback &&
|
||||
( tGlyphIndex = systemFallback->getGlyphIndex( codePoint ) ) ) {
|
||||
glyphIndex = tGlyphIndex;
|
||||
@@ -1143,15 +1174,15 @@ bool FontTrueType::loaded() const {
|
||||
return NULL != mFace;
|
||||
}
|
||||
|
||||
FontService* FontTrueType::getFontService() const {
|
||||
return mFontService;
|
||||
}
|
||||
|
||||
void FontTrueType::cleanup() {
|
||||
sendEvent( Event::Unload );
|
||||
|
||||
if ( FontManager::existsSingleton() && FontManager::instance()->getColorEmojiFont() == this )
|
||||
FontManager::instance()->setColorEmojiFont( nullptr );
|
||||
|
||||
disconnectBoldItalicFont();
|
||||
disconnectBoldFont();
|
||||
disconnectItalicFont();
|
||||
if ( mFontService && mFontService->getColorEmojiFont() == this )
|
||||
mFontService->setColorEmojiFont( nullptr );
|
||||
|
||||
mCallbacks.clear();
|
||||
mNumCallBacks = 0;
|
||||
@@ -1202,16 +1233,14 @@ void FontTrueType::cleanup() {
|
||||
mIsBold = false;
|
||||
mIsItalic = false;
|
||||
mIsMonospaceCompletePending = false;
|
||||
mFontBold = nullptr;
|
||||
mFontItalic = nullptr;
|
||||
mFontBoldItalic = nullptr;
|
||||
mFontBoldCb = 0;
|
||||
mFontItalicCb = 0;
|
||||
mFontBoldItalicCb = 0;
|
||||
mFontBold.reset();
|
||||
mFontItalic.reset();
|
||||
mFontBoldItalic.reset();
|
||||
mPages.clear();
|
||||
std::vector<Uint8>().swap( mPixelBuffer );
|
||||
mKerningCache.clear();
|
||||
mKerningGlyphCache.clear();
|
||||
mGlyphAdvanceCache.clear();
|
||||
mCodePointIndexCache.clear();
|
||||
mKeyCache.clear();
|
||||
mClosestCharacterSize.clear();
|
||||
@@ -1226,6 +1255,81 @@ static int fontSetLoadOptions( FontAntialiasing antialiasing, FontHinting hintin
|
||||
return load_target | hint;
|
||||
}
|
||||
|
||||
Float FontTrueType::getGlyphAdvance( Uint32 codePoint, unsigned int characterSize, bool bold,
|
||||
bool italic, Float outlineThickness ) const {
|
||||
Uint32 index = 0;
|
||||
if ( mEnableEmojiFallback && !mIsColorEmojiFont && !mHasSvgGlyphs && !mHasColrGlyphs &&
|
||||
!mIsEmojiFont && mFontService && Font::isEmojiCodePoint( codePoint ) ) {
|
||||
Font* emojiFont = mFontService->getColorEmojiFont();
|
||||
if ( !emojiFont )
|
||||
emojiFont = mFontService->getEmojiFont();
|
||||
if ( emojiFont && emojiFont->getType() == FontType::TTF ) {
|
||||
auto emojiTrueType = static_cast<FontTrueType*>( emojiFont );
|
||||
if ( emojiTrueType->getGlyphIndex( codePoint ) )
|
||||
return emojiTrueType->getGlyphAdvance( codePoint, characterSize, bold, italic,
|
||||
outlineThickness );
|
||||
}
|
||||
}
|
||||
|
||||
if ( bold && italic ) {
|
||||
if ( mFontBoldItalic && ( index = mFontBoldItalic->getGlyphIndex( codePoint ) ) )
|
||||
return mFontBoldItalic->getGlyphAdvance( codePoint, characterSize, true, true,
|
||||
outlineThickness );
|
||||
} else if ( bold ) {
|
||||
if ( mFontBold && ( index = mFontBold->getGlyphIndex( codePoint ) ) )
|
||||
return mFontBold->getGlyphAdvance( codePoint, characterSize, true, false,
|
||||
outlineThickness );
|
||||
} else if ( italic ) {
|
||||
if ( mFontItalic && ( index = mFontItalic->getGlyphIndex( codePoint ) ) )
|
||||
return mFontItalic->getGlyphAdvance( codePoint, characterSize, false, true,
|
||||
outlineThickness );
|
||||
}
|
||||
|
||||
const FontTrueType* advanceFont = this;
|
||||
index = getGlyphIndex( codePoint );
|
||||
if ( index == 0 && mEnableFallbackFont && mFontService && mFontService->hasFallbackFonts() ) {
|
||||
for ( const FontPtr& fallbackHandle : mFontService->getFallbackFonts() ) {
|
||||
if ( !fallbackHandle || fallbackHandle->getType() != FontType::TTF )
|
||||
continue;
|
||||
auto fallbackFont = static_cast<FontTrueType*>( fallbackHandle.get() );
|
||||
if ( ( index = fallbackFont->getGlyphIndex( codePoint ) ) ) {
|
||||
advanceFont = fallbackFont;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( index == 0 && mEnableSystemFallback && mFontService &&
|
||||
SystemFontResolver::existsSingleton() ) {
|
||||
FontDesc fallbackDesc = SystemFontResolver::instance()->getFallbackForCodepoint(
|
||||
codePoint, FontWeight::Normal, false );
|
||||
FontTrueType* fallbackFont =
|
||||
fallbackDesc.path.empty() ? nullptr
|
||||
: mFontService->getOrLoadSystemFallbackFont( fallbackDesc );
|
||||
if ( fallbackFont && ( index = fallbackFont->getGlyphIndex( codePoint ) ) )
|
||||
advanceFont = fallbackFont;
|
||||
}
|
||||
|
||||
Uint64 key = getIndexKey( advanceFont->mFontInternalId, index, bold, italic, outlineThickness );
|
||||
auto& advances = advanceFont->mGlyphAdvanceCache[characterSize];
|
||||
auto advanceIt = advances.find( key );
|
||||
if ( advanceIt != advances.end() )
|
||||
return advanceIt->second;
|
||||
FT_Face face = static_cast<FT_Face>( advanceFont->mFace );
|
||||
if ( !face || !advanceFont->setCurrentSize( characterSize ) )
|
||||
return 0.f;
|
||||
FT_Int32 flags =
|
||||
fontSetLoadOptions( advanceFont->mAntialiasing, advanceFont->mHinting ) | FT_LOAD_COLOR;
|
||||
if ( FT_Load_Glyph( face, index, flags ) != 0 )
|
||||
return 0.f;
|
||||
|
||||
Float advance =
|
||||
static_cast<Float>( face->glyph->metrics.horiAdvance ) / static_cast<Float>( 1 << 6 );
|
||||
if ( bold && !advanceFont->mIsBold && !advanceFont->mBoldAdvanceSameAsRegular )
|
||||
advance += 1.f;
|
||||
advances[key] = advance;
|
||||
return advance;
|
||||
}
|
||||
|
||||
static constexpr FT_Render_Mode fontSetRenderOptions( FT_Library library,
|
||||
FontAntialiasing antialiasing,
|
||||
FontHinting hinting,
|
||||
@@ -1786,7 +1890,10 @@ bool FontTrueType::isFallbackFontEnabled() const {
|
||||
}
|
||||
|
||||
void FontTrueType::setEnableFallbackFont( bool enableFallbackFont ) {
|
||||
mEnableFallbackFont = enableFallbackFont;
|
||||
if ( mEnableFallbackFont != enableFallbackFont ) {
|
||||
mEnableFallbackFont = enableFallbackFont;
|
||||
mGlyphAdvanceCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool FontTrueType::isSystemFallbackEnabled() const {
|
||||
@@ -1794,7 +1901,10 @@ bool FontTrueType::isSystemFallbackEnabled() const {
|
||||
}
|
||||
|
||||
void FontTrueType::setEnableSystemFallback( bool enableSystemFallback ) {
|
||||
mEnableSystemFallback = enableSystemFallback;
|
||||
if ( mEnableSystemFallback != enableSystemFallback ) {
|
||||
mEnableSystemFallback = enableSystemFallback;
|
||||
mGlyphAdvanceCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool FontTrueType::isEmojiFallbackEnabled() const {
|
||||
@@ -1802,7 +1912,10 @@ bool FontTrueType::isEmojiFallbackEnabled() const {
|
||||
}
|
||||
|
||||
void FontTrueType::setEnableEmojiFallback( bool enableEmojiFallback ) {
|
||||
mEnableEmojiFallback = enableEmojiFallback;
|
||||
if ( mEnableEmojiFallback != enableEmojiFallback ) {
|
||||
mEnableEmojiFallback = enableEmojiFallback;
|
||||
mGlyphAdvanceCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
const Uint32& FontTrueType::getFontInternalId() const {
|
||||
@@ -1848,7 +1961,10 @@ bool FontTrueType::getBoldAdvanceSameAsRegular() const {
|
||||
}
|
||||
|
||||
void FontTrueType::setBoldAdvanceSameAsRegular( bool boldAdvanceSameAsRegular ) {
|
||||
mBoldAdvanceSameAsRegular = boldAdvanceSameAsRegular;
|
||||
if ( mBoldAdvanceSameAsRegular != boldAdvanceSameAsRegular ) {
|
||||
mBoldAdvanceSameAsRegular = boldAdvanceSameAsRegular;
|
||||
mGlyphAdvanceCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void FontTrueType::updateMonospaceState() const {
|
||||
@@ -1858,96 +1974,40 @@ void FontTrueType::updateMonospaceState() const {
|
||||
return;
|
||||
}
|
||||
mIsMonospaceCompletePending = false;
|
||||
if ( mIsMonospaceComplete && mFontBold != nullptr ) {
|
||||
if ( mIsMonospaceComplete && mFontBold ) {
|
||||
mIsMonospaceComplete = mIsMonospaceComplete && mFontBold->isMonospace() &&
|
||||
getGlyph( ' ', 10, false, false ).advance ==
|
||||
mFontBold->getGlyph( ' ', 10, false, false ).advance;
|
||||
getGlyphAdvance( ' ', 10 ) == mFontBold->getGlyphAdvance( ' ', 10 );
|
||||
}
|
||||
if ( mIsMonospaceComplete && mFontItalic != nullptr ) {
|
||||
mIsMonospaceComplete = mIsMonospaceComplete && mFontItalic->isMonospace() &&
|
||||
getGlyph( ' ', 10, false, false ).advance ==
|
||||
mFontItalic->getGlyph( ' ', 10, false, false ).advance;
|
||||
if ( mIsMonospaceComplete && mFontItalic ) {
|
||||
mIsMonospaceComplete =
|
||||
mIsMonospaceComplete && mFontItalic->isMonospace() &&
|
||||
getGlyphAdvance( ' ', 10 ) == mFontItalic->getGlyphAdvance( ' ', 10 );
|
||||
}
|
||||
if ( mIsMonospaceComplete && mFontBoldItalic != nullptr ) {
|
||||
mIsMonospaceComplete = mIsMonospaceComplete && mFontBoldItalic->isMonospace() &&
|
||||
getGlyph( ' ', 10, false, false ).advance ==
|
||||
mFontBoldItalic->getGlyph( ' ', 10, false, false ).advance;
|
||||
if ( mIsMonospaceComplete && mFontBoldItalic ) {
|
||||
mIsMonospaceComplete =
|
||||
mIsMonospaceComplete && mFontBoldItalic->isMonospace() &&
|
||||
getGlyphAdvance( ' ', 10 ) == mFontBoldItalic->getGlyphAdvance( ' ', 10 );
|
||||
}
|
||||
}
|
||||
|
||||
void FontTrueType::setBoldFont( FontTrueType* fontBold ) {
|
||||
if ( fontBold == mFontBold )
|
||||
return;
|
||||
disconnectBoldFont();
|
||||
void FontTrueType::setBoldFont( const FontTrueTypePtr& fontBold ) {
|
||||
mFontBold = fontBold;
|
||||
if ( mFontBold != nullptr ) {
|
||||
mFontBoldCb = mFontBold->pushFontEventCallback( [this]( Uint32, Event event, Font* ) {
|
||||
if ( event == Font::Event::Unload ) {
|
||||
// Maybe we should recreate the page table
|
||||
mFontBold = nullptr;
|
||||
mFontBoldCb = 0;
|
||||
}
|
||||
} );
|
||||
}
|
||||
mGlyphAdvanceCache.clear();
|
||||
updateMonospaceState();
|
||||
}
|
||||
|
||||
void FontTrueType::setItalicFont( FontTrueType* fontItalic ) {
|
||||
if ( fontItalic == mFontItalic )
|
||||
return;
|
||||
disconnectItalicFont();
|
||||
void FontTrueType::setItalicFont( const FontTrueTypePtr& fontItalic ) {
|
||||
mFontItalic = fontItalic;
|
||||
if ( mFontItalic != nullptr ) {
|
||||
mFontItalicCb = mFontItalic->pushFontEventCallback( [this]( Uint32, Event event, Font* ) {
|
||||
if ( event == Font::Event::Unload ) {
|
||||
// Maybe we should recreate the page table
|
||||
mFontItalic = nullptr;
|
||||
mFontItalicCb = 0;
|
||||
}
|
||||
} );
|
||||
}
|
||||
mGlyphAdvanceCache.clear();
|
||||
updateMonospaceState();
|
||||
}
|
||||
|
||||
void FontTrueType::setBoldItalicFont( FontTrueType* fontBoldItalic ) {
|
||||
if ( fontBoldItalic == mFontBoldItalic )
|
||||
return;
|
||||
disconnectBoldItalicFont();
|
||||
void FontTrueType::setBoldItalicFont( const FontTrueTypePtr& fontBoldItalic ) {
|
||||
mFontBoldItalic = fontBoldItalic;
|
||||
if ( mFontBoldItalic != nullptr ) {
|
||||
mFontBoldItalicCb =
|
||||
mFontBoldItalic->pushFontEventCallback( [this]( Uint32, Event event, Font* ) {
|
||||
if ( event == Font::Event::Unload ) {
|
||||
// Maybe we should recreate the page table
|
||||
mFontBoldItalic = nullptr;
|
||||
mFontBoldItalicCb = 0;
|
||||
}
|
||||
} );
|
||||
}
|
||||
mGlyphAdvanceCache.clear();
|
||||
updateMonospaceState();
|
||||
}
|
||||
|
||||
void FontTrueType::disconnectBoldFont() {
|
||||
if ( mFontBoldCb != 0 && mFontBold != nullptr )
|
||||
mFontBold->popFontEventCallback( mFontBoldCb );
|
||||
mFontBold = nullptr;
|
||||
mFontBoldCb = 0;
|
||||
}
|
||||
|
||||
void FontTrueType::disconnectItalicFont() {
|
||||
if ( mFontItalicCb != 0 && mFontItalic != nullptr )
|
||||
mFontItalic->popFontEventCallback( mFontItalicCb );
|
||||
mFontItalic = nullptr;
|
||||
mFontItalicCb = 0;
|
||||
}
|
||||
|
||||
void FontTrueType::disconnectBoldItalicFont() {
|
||||
if ( mFontBoldItalicCb != 0 && mFontBoldItalic != nullptr )
|
||||
mFontBoldItalic->popFontEventCallback( mFontBoldItalicCb );
|
||||
mFontBoldItalic = nullptr;
|
||||
mFontBoldItalicCb = 0;
|
||||
}
|
||||
|
||||
bool FontTrueType::hasSvgGlyphs() const {
|
||||
return mHasSvgGlyphs;
|
||||
}
|
||||
@@ -1988,6 +2048,7 @@ void FontTrueType::clearCache() {
|
||||
mKeyCache.clear();
|
||||
mKerningCache.clear();
|
||||
mKerningGlyphCache.clear();
|
||||
mGlyphAdvanceCache.clear();
|
||||
Text::GlobalInvalidationId++;
|
||||
}
|
||||
|
||||
|
||||
@@ -98,6 +98,35 @@ void ResourceCatalog::publishAtlas( std::string key, TextureAtlasPtr atlas ) {
|
||||
previous.reset();
|
||||
}
|
||||
|
||||
void ResourceCatalog::publishFont( ResourceKey key, FontPtr font ) {
|
||||
publishFont( key.value(), std::move( font ) );
|
||||
}
|
||||
|
||||
void ResourceCatalog::publishFont( std::string key, FontPtr font ) {
|
||||
if ( key.empty() )
|
||||
return;
|
||||
if ( !font ) {
|
||||
eraseFont( key );
|
||||
return;
|
||||
}
|
||||
|
||||
FontPtr previous;
|
||||
String::HashType id = String::hash( key );
|
||||
{
|
||||
Lock lock( mMutex );
|
||||
auto it = mFonts.find( key );
|
||||
if ( it == mFonts.end() ) {
|
||||
mFonts.emplace( std::move( key ), font );
|
||||
mFontsById[id] = font;
|
||||
return;
|
||||
}
|
||||
previous = std::move( it->second );
|
||||
it->second = font;
|
||||
mFontsById[id] = font;
|
||||
}
|
||||
previous.reset();
|
||||
}
|
||||
|
||||
TexturePtr ResourceCatalog::findTexture( const ResourceKey& key ) const {
|
||||
return findTexture( key.value() );
|
||||
}
|
||||
@@ -143,6 +172,31 @@ std::vector<TextureAtlasPtr> ResourceCatalog::getAtlases() const {
|
||||
return atlases;
|
||||
}
|
||||
|
||||
FontPtr ResourceCatalog::findFont( const ResourceKey& key ) const {
|
||||
return findFont( key.value() );
|
||||
}
|
||||
|
||||
FontPtr ResourceCatalog::findFont( const std::string& key ) const {
|
||||
Lock lock( mMutex );
|
||||
auto it = mFonts.find( key );
|
||||
return it != mFonts.end() ? it->second : FontPtr{};
|
||||
}
|
||||
|
||||
FontPtr ResourceCatalog::findFont( const String::HashType& id ) const {
|
||||
Lock lock( mMutex );
|
||||
auto it = mFontsById.find( id );
|
||||
return it != mFontsById.end() ? it->second.lock() : FontPtr{};
|
||||
}
|
||||
|
||||
std::vector<FontPtr> ResourceCatalog::getFonts() const {
|
||||
std::vector<FontPtr> fonts;
|
||||
Lock lock( mMutex );
|
||||
fonts.reserve( mFonts.size() );
|
||||
for ( const auto& font : mFonts )
|
||||
fonts.emplace_back( font.second );
|
||||
return fonts;
|
||||
}
|
||||
|
||||
bool ResourceCatalog::erase( const ResourceKey& key ) {
|
||||
return erase( key.value() );
|
||||
}
|
||||
@@ -204,28 +258,74 @@ bool ResourceCatalog::eraseAtlas( const std::string& key ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ResourceCatalog::eraseFont( const ResourceKey& key ) {
|
||||
return eraseFont( key.value() );
|
||||
}
|
||||
|
||||
bool ResourceCatalog::eraseFont( const std::string& key ) {
|
||||
FontPtr font;
|
||||
{
|
||||
Lock lock( mMutex );
|
||||
auto it = mFonts.find( key );
|
||||
if ( it == mFonts.end() )
|
||||
return false;
|
||||
font = std::move( it->second );
|
||||
mFonts.erase( it );
|
||||
auto idIt = mFontsById.find( String::hash( key ) );
|
||||
if ( idIt != mFontsById.end() )
|
||||
mFontsById.erase( idIt );
|
||||
}
|
||||
font.reset();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ResourceCatalog::eraseFont( Font* font ) {
|
||||
if ( !font )
|
||||
return false;
|
||||
FontPtr removed;
|
||||
{
|
||||
Lock lock( mMutex );
|
||||
auto it = mFonts.find( font->getName() );
|
||||
if ( it == mFonts.end() || it->second.get() != font )
|
||||
return false;
|
||||
removed = std::move( it->second );
|
||||
mFonts.erase( it );
|
||||
auto idIt = mFontsById.find( font->getId() );
|
||||
if ( idIt != mFontsById.end() )
|
||||
mFontsById.erase( idIt );
|
||||
}
|
||||
removed.reset();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ResourceCatalog::clear() {
|
||||
UnorderedMap<std::string, TexturePtr> textures;
|
||||
UnorderedMap<std::string, DrawablePtr> drawables;
|
||||
UnorderedMap<String::HashType, DrawableWeakPtr> drawablesById;
|
||||
UnorderedMap<std::string, TextureAtlasPtr> atlases;
|
||||
UnorderedMap<std::string, FontPtr> fonts;
|
||||
UnorderedMap<String::HashType, FontWeakPtr> fontsById;
|
||||
{
|
||||
Lock lock( mMutex );
|
||||
textures = std::move( mTextures );
|
||||
drawables = std::move( mDrawables );
|
||||
drawablesById = std::move( mDrawablesById );
|
||||
atlases = std::move( mAtlases );
|
||||
fonts = std::move( mFonts );
|
||||
fontsById = std::move( mFontsById );
|
||||
}
|
||||
|
||||
textures.clear();
|
||||
drawables.clear();
|
||||
drawablesById.clear();
|
||||
atlases.clear();
|
||||
fonts.clear();
|
||||
fontsById.clear();
|
||||
}
|
||||
|
||||
std::size_t ResourceCatalog::size() const {
|
||||
Lock lock( mMutex );
|
||||
return mTextures.size() + mDrawables.size() + mAtlases.size();
|
||||
return mTextures.size() + mDrawables.size() + mAtlases.size() + mFonts.size();
|
||||
}
|
||||
|
||||
}} // namespace EE::Graphics
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <algorithm>
|
||||
#include <eepp/core/string.hpp>
|
||||
#include <eepp/graphics/fonttruetype.hpp>
|
||||
#include <eepp/graphics/resourcescope.hpp>
|
||||
#include <eepp/graphics/sprite.hpp>
|
||||
#include <eepp/system/filesystem.hpp>
|
||||
@@ -15,7 +16,37 @@ ResourceScopePtr ResourceScope::New() {
|
||||
return ResourceScopePtr( eeNew( ResourceScope, () ), ResourceDeleter<ResourceScope>() );
|
||||
}
|
||||
|
||||
ResourceScope::ResourceScope() : mLocalCatalog( ResourceCatalog::New() ) {}
|
||||
ResourceScope::ResourceScope() : mLocalCatalog( ResourceCatalog::New() ), mFontService( *this ) {}
|
||||
|
||||
ResourceScope::~ResourceScope() {
|
||||
for ( const FontPtr& font : mLocalCatalog->getFonts() )
|
||||
detachFontService( font );
|
||||
}
|
||||
|
||||
void ResourceScope::attachFontService( const FontPtr& font ) {
|
||||
if ( font && font->getType() == FontType::TTF )
|
||||
static_cast<FontTrueType*>( font.get() )->setFontService( &mFontService );
|
||||
}
|
||||
|
||||
void ResourceScope::detachFontService( const FontPtr& font ) {
|
||||
if ( font ) {
|
||||
mFontService.onFontRemoved( font.get() );
|
||||
if ( font->getType() != FontType::TTF )
|
||||
return;
|
||||
auto* ttf = static_cast<FontTrueType*>( font.get() );
|
||||
if ( ttf->getFontService() == &mFontService ) {
|
||||
ttf->setFontService( nullptr );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FontService& ResourceScope::getFontService() {
|
||||
return mFontService;
|
||||
}
|
||||
|
||||
const FontService& ResourceScope::getFontService() const {
|
||||
return mFontService;
|
||||
}
|
||||
|
||||
TexturePtr ResourceScope::findTexture( const ResourceKey& key ) const {
|
||||
return findTexture( key.value() );
|
||||
@@ -75,6 +106,42 @@ std::vector<TextureAtlasPtr> ResourceScope::getAtlases() const {
|
||||
return atlases;
|
||||
}
|
||||
|
||||
FontPtr ResourceScope::findFont( const ResourceKey& key ) const {
|
||||
return findFont( key.value() );
|
||||
}
|
||||
|
||||
FontPtr ResourceScope::findFont( const std::string& key ) const {
|
||||
if ( FontPtr font = mLocalCatalog->findFont( key ) )
|
||||
return font;
|
||||
Lock lock( mMutex );
|
||||
for ( const ResourceCatalogPtr& catalog : mImports ) {
|
||||
if ( FontPtr font = catalog->findFont( key ) )
|
||||
return font;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
FontPtr ResourceScope::findFont( const String::HashType& id ) const {
|
||||
if ( FontPtr font = mLocalCatalog->findFont( id ) )
|
||||
return font;
|
||||
Lock lock( mMutex );
|
||||
for ( const ResourceCatalogPtr& catalog : mImports ) {
|
||||
if ( FontPtr font = catalog->findFont( id ) )
|
||||
return font;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<FontPtr> ResourceScope::getFonts() const {
|
||||
std::vector<FontPtr> fonts = mLocalCatalog->getFonts();
|
||||
Lock lock( mMutex );
|
||||
for ( const ResourceCatalogPtr& catalog : mImports ) {
|
||||
std::vector<FontPtr> imported = catalog->getFonts();
|
||||
fonts.insert( fonts.end(), imported.begin(), imported.end() );
|
||||
}
|
||||
return fonts;
|
||||
}
|
||||
|
||||
std::vector<TextureRegionPtr>
|
||||
ResourceScope::findTextureRegionsByPattern( const std::string& name, const std::string& extension,
|
||||
TextureAtlas* searchInTextureAtlas ) const {
|
||||
@@ -232,6 +299,18 @@ void ResourceScope::publishLocalAtlas( std::string key, TextureAtlasPtr atlas )
|
||||
mLocalCatalog->publishAtlas( std::move( key ), std::move( atlas ) );
|
||||
}
|
||||
|
||||
void ResourceScope::publishLocalFont( ResourceKey key, FontPtr font ) {
|
||||
publishLocalFont( key.value(), std::move( font ) );
|
||||
}
|
||||
|
||||
void ResourceScope::publishLocalFont( std::string key, FontPtr font ) {
|
||||
FontPtr replaced = mLocalCatalog->findFont( key );
|
||||
if ( replaced && replaced != font )
|
||||
detachFontService( replaced );
|
||||
attachFontService( font );
|
||||
mLocalCatalog->publishFont( std::move( key ), std::move( font ) );
|
||||
}
|
||||
|
||||
bool ResourceScope::eraseLocal( const ResourceKey& key ) {
|
||||
return mLocalCatalog->erase( key );
|
||||
}
|
||||
@@ -256,7 +335,33 @@ bool ResourceScope::eraseLocalAtlas( const std::string& key ) {
|
||||
return mLocalCatalog->eraseAtlas( key );
|
||||
}
|
||||
|
||||
bool ResourceScope::eraseLocalFont( const ResourceKey& key ) {
|
||||
return eraseLocalFont( key.value() );
|
||||
}
|
||||
|
||||
bool ResourceScope::eraseLocalFont( const std::string& key ) {
|
||||
FontPtr font = mLocalCatalog->findFont( key );
|
||||
if ( !font )
|
||||
return false;
|
||||
detachFontService( font );
|
||||
return mLocalCatalog->eraseFont( key );
|
||||
}
|
||||
|
||||
bool ResourceScope::eraseLocalFont( Font* font ) {
|
||||
if ( !font )
|
||||
return false;
|
||||
FontPtr handle = mLocalCatalog->findFont( font->getId() );
|
||||
if ( handle.get() != font )
|
||||
return false;
|
||||
if ( !mLocalCatalog->eraseFont( font ) )
|
||||
return false;
|
||||
detachFontService( handle );
|
||||
return true;
|
||||
}
|
||||
|
||||
void ResourceScope::clearLocal() {
|
||||
for ( const FontPtr& font : mLocalCatalog->getFonts() )
|
||||
detachFontService( font );
|
||||
mLocalCatalog->clear();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include <algorithm>
|
||||
#include <eepp/graphics/font.hpp>
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/linewrap.hpp>
|
||||
#include <eepp/graphics/primitives.hpp>
|
||||
#include <eepp/graphics/resourcescope.hpp>
|
||||
#include <eepp/graphics/richtext.hpp>
|
||||
|
||||
namespace EE { namespace Graphics {
|
||||
|
||||
+17
-15
@@ -1,6 +1,6 @@
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/fontservice.hpp>
|
||||
#include <eepp/graphics/fonttruetype.hpp>
|
||||
#include <eepp/graphics/globalbatchrenderer.hpp>
|
||||
#include <eepp/graphics/pixeldensity.hpp>
|
||||
@@ -341,11 +341,12 @@ Sizef Text::draw( const StringType& string, const Vector2f& pos, Font* font, Flo
|
||||
String::StringBaseType prevChar = 0;
|
||||
bool isBold = ( style & Text::Bold ) != 0;
|
||||
bool isItalic = ( style & Text::Italic ) != 0;
|
||||
bool fallbacksToColorEmoji =
|
||||
font && font->getType() == FontType::TTF &&
|
||||
!static_cast<FontTrueType*>( font )->isColorEmojiFont() &&
|
||||
FontManager::instance()->getColorEmojiFont() != nullptr &&
|
||||
FontManager::instance()->getColorEmojiFont()->getType() == FontType::TTF;
|
||||
FontTrueType* trueTypeFont =
|
||||
font && font->getType() == FontType::TTF ? static_cast<FontTrueType*>( font ) : nullptr;
|
||||
FontService* fontService = trueTypeFont ? trueTypeFont->getFontService() : nullptr;
|
||||
bool fallbacksToColorEmoji = trueTypeFont && !trueTypeFont->isColorEmojiFont() && fontService &&
|
||||
fontService->getColorEmojiFont() != nullptr &&
|
||||
fontService->getColorEmojiFont()->getType() == FontType::TTF;
|
||||
bool isMonospace = font && ( font->isMonospace() ||
|
||||
( font->getType() == FontType::TTF &&
|
||||
static_cast<FontTrueType*>( font )->isIdentifiedAsMonospace() &&
|
||||
@@ -355,12 +356,14 @@ Sizef Text::draw( const StringType& string, const Vector2f& pos, Font* font, Flo
|
||||
Float height = font->getLineSpacing( fontSize );
|
||||
Sizef size{ 0, height };
|
||||
size_t ssize = string.size();
|
||||
if ( ssize == 0 )
|
||||
return size;
|
||||
BatchRenderer* BR = GlobalBatchRenderer::instance();
|
||||
const TexturePtr& fontTexture = font->getTexture( fontSize );
|
||||
Float tabAlign = 0;
|
||||
GlyphDrawable* spaceGlyph = nullptr;
|
||||
GlyphDrawable* tabGlyph = nullptr;
|
||||
Float hspace = font->getGlyph( ' ', fontSize, isBold, isItalic ).advance;
|
||||
Float hspace = font->getGlyphAdvance( ' ', fontSize, isBold, isItalic );
|
||||
std::optional<Float> tabOffset{ whitespaceDisplayConfig.tabOffset };
|
||||
if ( whitespaceDisplayConfig.tabDisplayCharacter )
|
||||
tabGlyph = font->getGlyphDrawable( whitespaceDisplayConfig.tabDisplayCharacter, fontSize );
|
||||
@@ -640,9 +643,10 @@ void Text::create( Font* font, const String& text, Color FontColor, Color FontSh
|
||||
|
||||
void Text::checkColorEmojis() {
|
||||
mContainsColorEmoji = false;
|
||||
if ( mFontStyleConfig.Font && FontManager::instance()->getColorEmojiFont() != nullptr ) {
|
||||
if ( mFontStyleConfig.Font->getType() == FontType::TTF ) {
|
||||
FontTrueType* fontTrueType = static_cast<FontTrueType*>( mFontStyleConfig.Font );
|
||||
if ( mFontStyleConfig.Font && mFontStyleConfig.Font->getType() == FontType::TTF ) {
|
||||
FontTrueType* fontTrueType = static_cast<FontTrueType*>( mFontStyleConfig.Font );
|
||||
FontService* fontService = fontTrueType->getFontService();
|
||||
if ( fontService && fontService->getColorEmojiFont() != nullptr ) {
|
||||
if ( fontTrueType->isColorEmojiFont() || !fontTrueType->isEmojiFont() )
|
||||
mContainsColorEmoji = Font::containsEmojiCodePoint( mString );
|
||||
}
|
||||
@@ -2963,11 +2967,9 @@ SmallVector<Rectf> Text::getSelectionRects( TextSelectionRange range ) {
|
||||
|
||||
size_t startLine = findVisualLineFromCharIndex( range.start );
|
||||
size_t endLine = findVisualLineFromCharIndex( range.end );
|
||||
Float hspace =
|
||||
mFontStyleConfig.Font
|
||||
->getGlyph( ' ', mFontStyleConfig.CharacterSize, mFontStyleConfig.Style & Text::Bold,
|
||||
mFontStyleConfig.Style & Text::Italic )
|
||||
.advance;
|
||||
Float hspace = mFontStyleConfig.Font->getGlyphAdvance( ' ', mFontStyleConfig.CharacterSize,
|
||||
mFontStyleConfig.Style & Text::Bold,
|
||||
mFontStyleConfig.Style & Text::Italic );
|
||||
Float vspace = getLineSpacing();
|
||||
|
||||
for ( size_t i = startLine; i <= endLine; ++i ) {
|
||||
|
||||
@@ -13,7 +13,12 @@
|
||||
|
||||
namespace EE::Graphics {
|
||||
|
||||
using LRULayoutCache = LRUCache<8192, Uint64, TextLayout::Cache>;
|
||||
struct LayoutCacheEntry {
|
||||
Font* sourceFont{ nullptr };
|
||||
TextLayout::Cache layout;
|
||||
};
|
||||
|
||||
using LRULayoutCache = LRUCache<8192, Uint64, LayoutCacheEntry>;
|
||||
|
||||
#ifdef EE_TEXT_SHAPER_ENABLED
|
||||
|
||||
@@ -236,15 +241,30 @@ static inline Uint64 textLayoutHash( const String::View& string, Font* font,
|
||||
std::hash<Float>()( initialXOffset ) );
|
||||
}
|
||||
|
||||
static LRULayoutCache& getLayoutCache( bool invalidate = false ) {
|
||||
static LRULayoutCache& getLayoutCache( bool invalidate = false, Font* font = nullptr ) {
|
||||
static LRULayoutCache sLayoutCache;
|
||||
if ( invalidate )
|
||||
sLayoutCache.clear();
|
||||
if ( invalidate ) {
|
||||
if ( !font ) {
|
||||
sLayoutCache.clear();
|
||||
} else {
|
||||
sLayoutCache.eraseIf( [font]( Uint64, const LayoutCacheEntry& entry ) {
|
||||
if ( !entry.layout || entry.sourceFont == font )
|
||||
return true;
|
||||
for ( const ShapedTextParagraph& paragraph : entry.layout->paragraphs ) {
|
||||
for ( const ShapedGlyph& glyph : paragraph.shapedGlyphs ) {
|
||||
if ( glyph.font == font )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} );
|
||||
}
|
||||
}
|
||||
return sLayoutCache;
|
||||
}
|
||||
|
||||
void TextLayout::clearLayoutCache() {
|
||||
getLayoutCache( true );
|
||||
void TextLayout::clearLayoutCache( Font* font ) {
|
||||
getLayoutCache( true, font );
|
||||
}
|
||||
|
||||
TextLayout::Cache TextLayout::layout( const String::View& string, Font* font,
|
||||
@@ -270,13 +290,13 @@ TextLayout::Cache TextLayout::layout( const String::View& string, Font* font,
|
||||
|
||||
auto cacheHit = getLayoutCache().get( hash );
|
||||
if ( cacheHit.has_value() )
|
||||
return *cacheHit;
|
||||
return cacheHit->layout;
|
||||
}
|
||||
|
||||
bool bold = ( style & Text::Bold ) != 0;
|
||||
bool italic = ( style & Text::Italic ) != 0;
|
||||
Uint32 spaceGlyphIndex = 0;
|
||||
Float hspace = font->getGlyph( ' ', characterSize, bold, italic, outlineThickness ).advance;
|
||||
Float hspace = font->getGlyphAdvance( ' ', characterSize, bold, italic, outlineThickness );
|
||||
Float vspace = font->getLineSpacing( characterSize );
|
||||
Vector2f pen{ initialXOffset, 0 };
|
||||
Float maxWidth = 0;
|
||||
@@ -523,7 +543,7 @@ TextLayout::Cache TextLayout::layout( const String::View& string, Font* font,
|
||||
characterSize, style, tabWidth, outlineThickness, hspace );
|
||||
}
|
||||
|
||||
getLayoutCache().put( hash, resultPtr );
|
||||
getLayoutCache().put( hash, { font, resultPtr } );
|
||||
return resultPtr;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <SOIL2/src/SOIL2/SOIL2.h>
|
||||
#include <SOIL2/src/SOIL2/stb_image.h>
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <eepp/graphics/renderer/openglext.hpp>
|
||||
#include <eepp/graphics/renderer/renderer.hpp>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include <eepp/graphics/circledrawable.hpp>
|
||||
#include <eepp/graphics/convexshapedrawable.hpp>
|
||||
#include <eepp/graphics/drawable.hpp>
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/rectangledrawable.hpp>
|
||||
#include <eepp/graphics/resourcescope.hpp>
|
||||
#include <eepp/graphics/triangledrawable.hpp>
|
||||
#include <eepp/system/log.hpp>
|
||||
#include <eepp/system/luapattern.hpp>
|
||||
@@ -151,7 +151,7 @@ bool DrawableImageParser::exists( const std::string& name ) const {
|
||||
}
|
||||
|
||||
DrawablePtr DrawableImageParser::createDrawable( const std::string& value, const Sizef& size,
|
||||
UINode* node ) {
|
||||
UINode* node ) {
|
||||
FunctionString functionType = FunctionString::parse( value );
|
||||
|
||||
if ( "none" == value )
|
||||
@@ -183,7 +183,7 @@ void DrawableImageParser::addParser( const std::string& name,
|
||||
void DrawableImageParser::registerBaseParsers() {
|
||||
// Shared parsing logic for linear-gradient and repeating-linear-gradient
|
||||
auto parseGradient = []( const FunctionString& functionType, UINode* node,
|
||||
bool repeating ) -> DrawablePtr {
|
||||
bool repeating ) -> DrawablePtr {
|
||||
const auto& params( functionType.getParameters() );
|
||||
if ( params.size() < 2 )
|
||||
return {};
|
||||
@@ -459,14 +459,14 @@ void DrawableImageParser::registerBaseParsers() {
|
||||
};
|
||||
|
||||
mFuncs["repeating-linear-gradient"] = [parseGradient]( const FunctionString& functionType,
|
||||
const Sizef& /*size*/,
|
||||
UINode* node ) -> DrawablePtr {
|
||||
const Sizef& /*size*/,
|
||||
UINode* node ) -> DrawablePtr {
|
||||
return parseGradient( functionType, node, true );
|
||||
};
|
||||
|
||||
// Shared parsing logic for radial-gradient and repeating-radial-gradient
|
||||
auto parseRadialGradient = []( const FunctionString& functionType, UINode* node,
|
||||
bool repeating ) -> DrawablePtr {
|
||||
bool repeating ) -> DrawablePtr {
|
||||
const auto& params( functionType.getParameters() );
|
||||
if ( params.size() < 2 )
|
||||
return {};
|
||||
@@ -681,13 +681,13 @@ void DrawableImageParser::registerBaseParsers() {
|
||||
};
|
||||
|
||||
mFuncs["repeating-radial-gradient"] = [parseRadialGradient]( const FunctionString& functionType,
|
||||
const Sizef& /*size*/,
|
||||
UINode* node ) -> DrawablePtr {
|
||||
const Sizef& /*size*/,
|
||||
UINode* node ) -> DrawablePtr {
|
||||
return parseRadialGradient( functionType, node, true );
|
||||
};
|
||||
|
||||
mFuncs["circle"] = []( const FunctionString& functionType, const Sizef& size,
|
||||
UINode* node ) -> DrawablePtr {
|
||||
UINode* node ) -> DrawablePtr {
|
||||
if ( functionType.getParameters().size() < 1 ) {
|
||||
return {};
|
||||
}
|
||||
@@ -717,7 +717,7 @@ void DrawableImageParser::registerBaseParsers() {
|
||||
};
|
||||
|
||||
mFuncs["rectangle"] = []( const FunctionString& functionType, const Sizef& size,
|
||||
UINode* node ) -> DrawablePtr {
|
||||
UINode* node ) -> DrawablePtr {
|
||||
if ( functionType.getParameters().size() < 1 ) {
|
||||
return {};
|
||||
}
|
||||
@@ -776,7 +776,7 @@ void DrawableImageParser::registerBaseParsers() {
|
||||
};
|
||||
|
||||
mFuncs["triangle"] = []( const FunctionString& functionType, const Sizef& size,
|
||||
UINode* node ) -> DrawablePtr {
|
||||
UINode* node ) -> DrawablePtr {
|
||||
if ( functionType.getParameters().size() < 2 ) {
|
||||
return {};
|
||||
}
|
||||
@@ -843,7 +843,7 @@ void DrawableImageParser::registerBaseParsers() {
|
||||
};
|
||||
|
||||
mFuncs["poly"] = []( const FunctionString& functionType, const Sizef& size,
|
||||
UINode* node ) -> DrawablePtr {
|
||||
UINode* node ) -> DrawablePtr {
|
||||
if ( functionType.getParameters().size() < 2 ) {
|
||||
return {};
|
||||
}
|
||||
@@ -899,7 +899,7 @@ void DrawableImageParser::registerBaseParsers() {
|
||||
};
|
||||
|
||||
mFuncs["url"] = []( const FunctionString& functionType, const Sizef& /*size*/,
|
||||
UINode* node ) -> DrawablePtr {
|
||||
UINode* node ) -> DrawablePtr {
|
||||
if ( functionType.getParameters().size() < 1 )
|
||||
return {};
|
||||
const auto& param = functionType.getParameters().at( 0 );
|
||||
@@ -915,8 +915,7 @@ void DrawableImageParser::registerBaseParsers() {
|
||||
cparam += ',';
|
||||
cparam += functionType.getParameters().at( i );
|
||||
}
|
||||
DrawablePtr drawable =
|
||||
node->getUISceneNode()->getDrawableResolver().resolve( cparam );
|
||||
DrawablePtr drawable = node->getUISceneNode()->getDrawableResolver().resolve( cparam );
|
||||
return drawable;
|
||||
}
|
||||
DrawablePtr drawable = node->getUISceneNode()->getDrawableResolver().resolve( param );
|
||||
@@ -924,7 +923,7 @@ void DrawableImageParser::registerBaseParsers() {
|
||||
};
|
||||
|
||||
mFuncs["icon"] = []( const FunctionString& functionType, const Sizef& size,
|
||||
UINode* node ) -> DrawablePtr {
|
||||
UINode* node ) -> DrawablePtr {
|
||||
auto* uiScene = node->getUISceneNode();
|
||||
const auto& params = functionType.getParameters();
|
||||
if ( params.size() < 2 )
|
||||
@@ -935,11 +934,11 @@ void DrawableImageParser::registerBaseParsers() {
|
||||
};
|
||||
|
||||
mFuncs["glyph"] = []( const FunctionString& functionType, const Sizef& size,
|
||||
UINode* node ) -> DrawablePtr {
|
||||
UINode* node ) -> DrawablePtr {
|
||||
const auto& params = functionType.getParameters();
|
||||
if ( params.size() < 3 )
|
||||
return nullptr;
|
||||
Font* font = FontManager::instance()->getByName( params[0] );
|
||||
Font* font = node->getUISceneNode()->getResourceScope()->findFont( params[0] ).get();
|
||||
if ( font == nullptr )
|
||||
return nullptr;
|
||||
Uint32 codePoint = 0;
|
||||
@@ -955,8 +954,8 @@ void DrawableImageParser::registerBaseParsers() {
|
||||
} else if ( String::fromString( value, buffer ) ) {
|
||||
codePoint = value;
|
||||
}
|
||||
Drawable* drawable = font->getGlyphDrawable(
|
||||
codePoint, node->convertLength( params[1], size.getWidth() ) );
|
||||
Drawable* drawable =
|
||||
font->getGlyphDrawable( codePoint, node->convertLength( params[1], size.getWidth() ) );
|
||||
return drawable ? drawable->clone() : DrawablePtr{};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/fonttruetype.hpp>
|
||||
#include <eepp/graphics/resourcescope.hpp>
|
||||
#include <eepp/graphics/text.hpp>
|
||||
#include <eepp/scene/scenemanager.hpp>
|
||||
#include <eepp/system/filesystem.hpp>
|
||||
@@ -267,6 +267,7 @@ UIFontPickerDialog::~UIFontPickerDialog() {
|
||||
mColorPicker = nullptr;
|
||||
mColorPickerCloseCb = 0;
|
||||
clearBrowseDialog();
|
||||
clearPreviewFont();
|
||||
}
|
||||
|
||||
Uint32 UIFontPickerDialog::getType() const {
|
||||
@@ -294,7 +295,7 @@ void UIFontPickerDialog::setTheme( UITheme* theme ) {
|
||||
|
||||
if ( mButtonBrowse ) {
|
||||
if ( DrawablePtr icon = getUISceneNode()->findIconDrawable( "document-open",
|
||||
PixelDensity::dpToPxI( 16 ) ) )
|
||||
PixelDensity::dpToPxI( 16 ) ) )
|
||||
mButtonBrowse->setIcon( std::move( icon ) );
|
||||
}
|
||||
|
||||
@@ -438,7 +439,7 @@ void UIFontPickerDialog::loadFonts() {
|
||||
|
||||
void UIFontPickerDialog::setFonts( std::vector<FontDesc> fonts ) {
|
||||
FontDesc selectedFont = mSelection.font;
|
||||
mergeFontManagerFonts( fonts );
|
||||
mergeLoadedFonts( fonts );
|
||||
for ( const auto& font : mFonts ) {
|
||||
if ( std::find_if( fonts.begin(), fonts.end(), [&]( const FontDesc& desc ) {
|
||||
return desc.sameFile( font );
|
||||
@@ -471,21 +472,23 @@ void UIFontPickerDialog::sortFonts() {
|
||||
} );
|
||||
}
|
||||
|
||||
void UIFontPickerDialog::mergeFontManagerFonts( std::vector<FontDesc>& fonts ) {
|
||||
FontManager::instance()->each( [&]( const auto& res ) {
|
||||
if ( res.second == nullptr || res.second->getType() != FontType::TTF )
|
||||
return;
|
||||
void UIFontPickerDialog::mergeLoadedFonts( std::vector<FontDesc>& fonts ) {
|
||||
if ( !getUISceneNode() )
|
||||
return;
|
||||
for ( const FontPtr& font : getUISceneNode()->getResourceScope()->getFonts() ) {
|
||||
if ( font == nullptr || font->getType() != FontType::TTF )
|
||||
continue;
|
||||
|
||||
FontDesc desc;
|
||||
if ( !static_cast<FontTrueType*>( res.second )->getFontDesc( desc ) )
|
||||
return;
|
||||
if ( !static_cast<FontTrueType*>( font.get() )->getFontDesc( desc ) )
|
||||
continue;
|
||||
|
||||
mLoadedFontKeys.insert( desc.getFileKey() );
|
||||
if ( std::find_if( fonts.begin(), fonts.end(), [&]( const FontDesc& font ) {
|
||||
return font.sameFile( desc );
|
||||
} ) == fonts.end() )
|
||||
fonts.push_back( desc );
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
void UIFontPickerDialog::updateFontTags() {
|
||||
@@ -628,10 +631,24 @@ void UIFontPickerDialog::updatePreview() {
|
||||
if ( !mPreviewText )
|
||||
return;
|
||||
|
||||
FontTrueType* font = FontManager::instance()->getOrLoadSystemFallbackFont( mSelection.font );
|
||||
if ( font ) {
|
||||
mPreviewText->setFont( font );
|
||||
mPreviewInput->setFont( font );
|
||||
if ( !mPreviewTextDefaultFont )
|
||||
mPreviewTextDefaultFont = mPreviewText->getFont();
|
||||
if ( !mPreviewInputDefaultFont )
|
||||
mPreviewInputDefaultFont = mPreviewInput->getFont();
|
||||
|
||||
FontDesc previewDesc;
|
||||
const bool previewMatchesSelection = mPreviewFont && mPreviewFont->getFontDesc( previewDesc ) &&
|
||||
previewDesc.sameFile( mSelection.font );
|
||||
if ( !previewMatchesSelection && !mSelection.font.path.empty() && getUISceneNode() ) {
|
||||
FontTrueTypePtr font =
|
||||
getUISceneNode()->getResourceScope()->getFontService().loadSystemFont(
|
||||
mSelection.font );
|
||||
if ( font ) {
|
||||
mPreviewText->setFont( font.get() );
|
||||
mPreviewInput->setFont( font.get() );
|
||||
clearPreviewFont();
|
||||
mPreviewFont = std::move( font );
|
||||
}
|
||||
}
|
||||
|
||||
mPreviewText->setFontSize( PixelDensity::dpToPxI( mSelection.size * 2 ) );
|
||||
@@ -657,6 +674,17 @@ void UIFontPickerDialog::updatePreview() {
|
||||
}
|
||||
}
|
||||
|
||||
void UIFontPickerDialog::clearPreviewFont() {
|
||||
if ( !mPreviewFont )
|
||||
return;
|
||||
if ( mPreviewText && mPreviewTextDefaultFont && mPreviewText->getFont() == mPreviewFont.get() )
|
||||
mPreviewText->setFont( mPreviewTextDefaultFont );
|
||||
if ( mPreviewInput && mPreviewInputDefaultFont &&
|
||||
mPreviewInput->getFont() == mPreviewFont.get() )
|
||||
mPreviewInput->setFont( mPreviewInputDefaultFont );
|
||||
mPreviewFont.reset();
|
||||
}
|
||||
|
||||
void UIFontPickerDialog::selectInitialRows() {
|
||||
mSizeModel = ItemListModel<Uint32>::create( mSizes );
|
||||
mSizeList->setModel( mSizeModel );
|
||||
@@ -782,18 +810,21 @@ bool UIFontPickerDialog::addExternalFont( const std::string& path, Uint32 faceIn
|
||||
|
||||
const std::string fontName(
|
||||
FileSystem::fileRemoveExtension( FileSystem::fileNameFromPath( path ) ) );
|
||||
FontTrueType* font = FontTrueType::New( fontName );
|
||||
if ( !getUISceneNode() )
|
||||
return false;
|
||||
ResourceScope& resourceScope = *getUISceneNode()->getResourceScope();
|
||||
FontTrueTypePtr font = FontTrueType::New( fontName, resourceScope );
|
||||
if ( !font || !font->loadFromFile( path, faceIndex ) ) {
|
||||
eeSAFE_DELETE( font );
|
||||
resourceScope.eraseLocalFont( font.get() );
|
||||
return false;
|
||||
}
|
||||
|
||||
FontDesc desc;
|
||||
if ( !font->getFontDesc( desc ) ) {
|
||||
eeSAFE_DELETE( font );
|
||||
resourceScope.eraseLocalFont( font.get() );
|
||||
return false;
|
||||
}
|
||||
eeSAFE_DELETE( font );
|
||||
resourceScope.eraseLocalFont( font.get() );
|
||||
|
||||
mLoadedFontKeys.insert( desc.getFileKey() );
|
||||
mFonts.push_back( desc );
|
||||
|
||||
@@ -59,17 +59,20 @@ UIApplication::UIApplication( const WindowSettings& windowSettings, const Settin
|
||||
|
||||
if ( !appSettings.loadBaseResources )
|
||||
return;
|
||||
|
||||
Font* font = appSettings.baseFont
|
||||
? appSettings.baseFont
|
||||
: FontTrueType::New( "NotoSans-Regular", "assets/fonts/NotoSans-Regular.ttf" );
|
||||
FontTrueTypePtr loadedBaseFont;
|
||||
if ( !appSettings.baseFont )
|
||||
loadedBaseFont =
|
||||
FontTrueType::New( "NotoSans-Regular", "assets/fonts/NotoSans-Regular.ttf" );
|
||||
Font* font = appSettings.baseFont ? appSettings.baseFont : loadedBaseFont.get();
|
||||
|
||||
if ( font && font->getType() == FontType::TTF )
|
||||
FontFamily::loadFromRegular( static_cast<FontTrueType*>( font ) );
|
||||
|
||||
Font* monospaceFont = appSettings.monospaceFont
|
||||
? appSettings.monospaceFont
|
||||
: FontTrueType::New( "monospace", "assets/fonts/DejaVuSansMono.ttf" );
|
||||
FontTrueTypePtr loadedMonospaceFont;
|
||||
if ( !appSettings.monospaceFont )
|
||||
loadedMonospaceFont = FontTrueType::New( "monospace", "assets/fonts/DejaVuSansMono.ttf" );
|
||||
Font* monospaceFont =
|
||||
appSettings.monospaceFont ? appSettings.monospaceFont : loadedMonospaceFont.get();
|
||||
|
||||
if ( monospaceFont && monospaceFont->getType() == FontType::TTF ) {
|
||||
static_cast<FontTrueType*>( monospaceFont )->setEnableDynamicMonospace( true );
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#include "eepp/ui/uistyle.hpp"
|
||||
#include <algorithm>
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/fonttruetype.hpp>
|
||||
#include <eepp/graphics/globalbatchrenderer.hpp>
|
||||
#include <eepp/graphics/primitives.hpp>
|
||||
#include <eepp/graphics/renderer/renderer.hpp>
|
||||
#include <eepp/graphics/resourcescope.hpp>
|
||||
#include <eepp/scene/actions/close.hpp>
|
||||
#include <eepp/scene/actions/scale.hpp>
|
||||
#include <eepp/scene/actions/sequence.hpp>
|
||||
@@ -138,7 +138,7 @@ const MouseBindings::ShortcutMap UICodeEditor::getDefaultMousebindings() {
|
||||
UICodeEditor::UICodeEditor( const std::string& elementTag, const bool& autoRegisterBaseCommands,
|
||||
const bool& autoRegisterBaseKeybindings ) :
|
||||
UIWidget( elementTag ),
|
||||
mFont( FontManager::instance()->getByName( "monospace" ) ),
|
||||
mFont( getUISceneNode()->getResourceScope()->findFont( "monospace" ).get() ),
|
||||
mDoc( std::make_shared<TextDocument>() ),
|
||||
mDocView( mDoc, mFontStyleConfig, { .tabStops = mTabStops } ),
|
||||
mBlinkTime( Seconds( 0.5f ) ),
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include <algorithm>
|
||||
#include <eepp/audio/listener.hpp>
|
||||
#include <eepp/graphics/font.hpp>
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/primitives.hpp>
|
||||
#include <eepp/graphics/renderer/renderer.hpp>
|
||||
#include <eepp/graphics/resourcescope.hpp>
|
||||
#include <eepp/graphics/text.hpp>
|
||||
#include <eepp/scene/action.hpp>
|
||||
#include <eepp/scene/actions/actions.hpp>
|
||||
@@ -52,7 +52,7 @@ UIConsole::UIConsole( Font* font, const bool& makeDefaultCommands, const bool& a
|
||||
|
||||
mFontStyleConfig.Font = font;
|
||||
if ( nullptr == font )
|
||||
mFontStyleConfig.Font = FontManager::instance()->getByName( "monospace" );
|
||||
mFontStyleConfig.Font = getUISceneNode()->getResourceScope()->findFont( "monospace" ).get();
|
||||
|
||||
mMaxLogLines = maxLogLines;
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <algorithm>
|
||||
#include <eepp/graphics/font.hpp>
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/text.hpp>
|
||||
#include <eepp/ui/css/propertydefinition.hpp>
|
||||
#include <eepp/ui/uiitemcontainer.hpp>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <eepp/core/debug.hpp>
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/primitives.hpp>
|
||||
#include <eepp/graphics/text.hpp>
|
||||
#include <eepp/scene/scenemanager.hpp>
|
||||
|
||||
+47
-37
@@ -1,6 +1,6 @@
|
||||
#include <algorithm>
|
||||
#include <eepp/core/string.hpp>
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/fontservice.hpp>
|
||||
#include <eepp/graphics/fonttruetype.hpp>
|
||||
#include <eepp/graphics/systemfontresolver.hpp>
|
||||
#include <eepp/graphics/text.hpp>
|
||||
@@ -129,11 +129,11 @@ static void refreshWebViewDocumentLayoutAfterStyleChange( UIWidget* root ) {
|
||||
}
|
||||
}
|
||||
|
||||
UISceneNode* UISceneNode::New( EE::Window::Window* window ) {
|
||||
return eeNew( UISceneNode, ( window ) );
|
||||
UISceneNode* UISceneNode::New( EE::Window::Window* window, bool importDefaultResources ) {
|
||||
return eeNew( UISceneNode, ( window, importDefaultResources ) );
|
||||
}
|
||||
|
||||
UISceneNode::UISceneNode( EE::Window::Window* window ) :
|
||||
UISceneNode::UISceneNode( EE::Window::Window* window, bool importDefaultResources ) :
|
||||
SceneNode( window ),
|
||||
mRoot( NULL ),
|
||||
mIsLoading( false ),
|
||||
@@ -141,10 +141,14 @@ UISceneNode::UISceneNode( EE::Window::Window* window ) :
|
||||
mUIThemeManager( UIThemeManager::New() ),
|
||||
mUIIconThemeManager( UIIconThemeManager::New()->setFallbackThemeManager( mUIThemeManager ) ),
|
||||
mAsyncResourceLoadState( std::make_shared<AsyncResourceLoadState>() ),
|
||||
mImportDefaultResources( importDefaultResources ),
|
||||
mResourceScope( ResourceScope::New() ),
|
||||
mDrawableResolver( *this ),
|
||||
mWebResourceCache( WebResourceCache::New() ),
|
||||
mKeyBindings( mWindow->getInput() ) {
|
||||
if ( mImportDefaultResources )
|
||||
mResourceScope->importCatalog( defaultResourceScope().getLocalCatalog() );
|
||||
|
||||
// Reset size since the SceneNode already set it but needs to set the size from zero to emit
|
||||
// the required events to its children.
|
||||
mSize = Sizef();
|
||||
@@ -764,6 +768,8 @@ const ResourceScopePtr& UISceneNode::getResourceScope() const {
|
||||
|
||||
UISceneNode* UISceneNode::setResourceScope( ResourceScopePtr resourceScope ) {
|
||||
mResourceScope = resourceScope ? std::move( resourceScope ) : ResourceScope::New();
|
||||
if ( mImportDefaultResources )
|
||||
mResourceScope->importCatalog( defaultResourceScope().getLocalCatalog() );
|
||||
mUIThemeManager->setResourceScope( mResourceScope );
|
||||
return this;
|
||||
}
|
||||
@@ -1455,7 +1461,7 @@ UIIcon* UISceneNode::findIcon( const std::string& iconName ) {
|
||||
}
|
||||
|
||||
DrawablePtr UISceneNode::findIconDrawable( const std::string& iconName,
|
||||
const size_t& drawableSize ) {
|
||||
const size_t& drawableSize ) {
|
||||
UIIcon* icon = findIcon( iconName );
|
||||
return icon ? icon->createDrawable( drawableSize ) : DrawablePtr{};
|
||||
}
|
||||
@@ -1530,7 +1536,7 @@ void UISceneNode::loadGlyphIcon( const StyleSheetStyleVector& styles ) {
|
||||
CSS::StyleSheetProperty glyphProp( *glyph );
|
||||
|
||||
if ( !familyProp.isEmpty() && !nameProp.isEmpty() && !glyphProp.isEmpty() ) {
|
||||
Font* fontSearch = FontManager::instance()->getByName( familyProp.getValue() );
|
||||
Font* fontSearch = mResourceScope->findFont( familyProp.getValue() ).get();
|
||||
|
||||
if ( nullptr == fontSearch )
|
||||
continue;
|
||||
@@ -1675,11 +1681,11 @@ void UISceneNode::loadFontFaces( const StyleSheetStyleVector& styles, URI baseUR
|
||||
fontStyle, static_cast<Uint32>( fontWeight ) );
|
||||
};
|
||||
auto registerLoadedFont = [this, authorFamily, fontStyle,
|
||||
fontWeight]( FontTrueType* font ) {
|
||||
fontWeight]( FontTrueTypePtr font ) {
|
||||
if ( font == nullptr || !font->loaded() )
|
||||
return false;
|
||||
font->setVariableFontWeight( fontWeight );
|
||||
registerFontFaceAlias( authorFamily, fontStyle, fontWeight, font );
|
||||
registerFontFaceAlias( authorFamily, fontStyle, fontWeight, font.get() );
|
||||
mFontFaces.push_back( font );
|
||||
mRoot->reloadFontFamily();
|
||||
return true;
|
||||
@@ -1706,12 +1712,13 @@ void UISceneNode::loadFontFaces( const StyleSheetStyleVector& styles, URI baseUR
|
||||
if ( isBase64 && !data.empty() ) {
|
||||
std::string decoded;
|
||||
Base64::decode( data, decoded );
|
||||
FontTrueType* font = FontTrueType::New(
|
||||
makeInternalFontName( authorFamily, fontStyle, fontWeight ) );
|
||||
FontTrueTypePtr font = FontTrueType::New(
|
||||
makeInternalFontName( authorFamily, fontStyle, fontWeight ),
|
||||
*mResourceScope );
|
||||
if ( font->loadFromMemory( &decoded[0], decoded.size() ) ) {
|
||||
registerLoadedFont( font );
|
||||
} else
|
||||
eeSAFE_DELETE( font );
|
||||
mResourceScope->eraseLocalFont( font.get() );
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -1723,14 +1730,14 @@ void UISceneNode::loadFontFaces( const StyleSheetStyleVector& styles, URI baseUR
|
||||
if ( String::startsWith( path, "file://" ) ) {
|
||||
std::string filePath( resolvedURI.getFSPath() );
|
||||
|
||||
FontTrueType* font =
|
||||
FontTrueType::New( makeInternalFontName( authorFamily, fontStyle, fontWeight ) );
|
||||
FontTrueTypePtr font = FontTrueType::New(
|
||||
makeInternalFontName( authorFamily, fontStyle, fontWeight ), *mResourceScope );
|
||||
|
||||
if ( font->loadFromFile( filePath ) ) {
|
||||
registerLoadedFont( font );
|
||||
runOnMainThread( [this] { mRoot->reloadFontFamily(); } );
|
||||
} else
|
||||
eeSAFE_DELETE( font );
|
||||
mResourceScope->eraseLocalFont( font.get() );
|
||||
} else if ( String::startsWith( path, "http://" ) ||
|
||||
String::startsWith( path, "https://" ) ) {
|
||||
std::string internalFontName(
|
||||
@@ -1755,17 +1762,18 @@ void UISceneNode::loadFontFaces( const StyleSheetStyleVector& styles, URI baseUR
|
||||
resourceState, resourceGeneration,
|
||||
[fontData = std::move( fontData ), internalFontName, authorFamily,
|
||||
fontStyle, fontWeight]( UISceneNode* scene ) mutable {
|
||||
FontTrueType* font = FontTrueType::New( internalFontName );
|
||||
FontTrueTypePtr font =
|
||||
FontTrueType::New( internalFontName, *scene->mResourceScope );
|
||||
if ( font->loadFromMemory( &fontData[0], fontData.size() ) &&
|
||||
font->loaded() ) {
|
||||
font->setVariableFontWeight( fontWeight );
|
||||
scene->registerFontFaceAlias( authorFamily, fontStyle, fontWeight,
|
||||
font );
|
||||
font.get() );
|
||||
scene->mFontFaces.push_back( font );
|
||||
if ( scene->mRoot )
|
||||
scene->mRoot->reloadFontFamily();
|
||||
} else {
|
||||
eeSAFE_DELETE( font );
|
||||
scene->mResourceScope->eraseLocalFont( font.get() );
|
||||
}
|
||||
} );
|
||||
} else {
|
||||
@@ -1781,14 +1789,14 @@ void UISceneNode::loadFontFaces( const StyleSheetStyleVector& styles, URI baseUR
|
||||
}
|
||||
} );
|
||||
} else if ( VFS::instance()->fileExists( path ) ) {
|
||||
FontTrueType* font =
|
||||
FontTrueType::New( makeInternalFontName( authorFamily, fontStyle, fontWeight ) );
|
||||
FontTrueTypePtr font = FontTrueType::New(
|
||||
makeInternalFontName( authorFamily, fontStyle, fontWeight ), *mResourceScope );
|
||||
|
||||
IOStream* stream = VFS::instance()->getFileFromPath( path );
|
||||
if ( font->loadFromStream( *stream ) ) {
|
||||
registerLoadedFont( font );
|
||||
} else
|
||||
eeSAFE_DELETE( font );
|
||||
mResourceScope->eraseLocalFont( font.get() );
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2204,7 +2212,6 @@ void UISceneNode::invalidate( Node* invalidator ) {
|
||||
|
||||
Font* UISceneNode::getFontFromNamesList( std::string_view names, Uint32 fontStyle,
|
||||
FontWeight weight ) const {
|
||||
FontManager* fm = FontManager::instance();
|
||||
Font* font = nullptr;
|
||||
String::readBySeparatorStoppable(
|
||||
names,
|
||||
@@ -2222,7 +2229,7 @@ Font* UISceneNode::getFontFromNamesList( std::string_view names, Uint32 fontStyl
|
||||
if ( fontStyle )
|
||||
fontFamily += "#" + Text::styleFlagToString( fontStyle );
|
||||
|
||||
font = fm->getByName( fontFamily );
|
||||
font = mResourceScope->findFont( fontFamily ).get();
|
||||
|
||||
// Remove the font style part (ex: `Arial#bold` to `Arial`)
|
||||
// We need this for SystemFontResolver::genericFamilyFromName
|
||||
@@ -2243,7 +2250,7 @@ Font* UISceneNode::getFontFromNamesList( std::string_view names, Uint32 fontStyl
|
||||
if ( fontStyle )
|
||||
fontFamily += "#" + Text::styleFlagToString( fontStyle );
|
||||
|
||||
font = fm->getByName( fontFamily );
|
||||
font = mResourceScope->findFont( fontFamily ).get();
|
||||
}
|
||||
|
||||
if ( font == nullptr && SystemFontResolver::isEnabled() ) {
|
||||
@@ -2258,15 +2265,16 @@ Font* UISceneNode::getFontFromNamesList( std::string_view names, Uint32 fontStyl
|
||||
if ( fontStyle )
|
||||
family += "#" + Text::styleFlagToString( fontStyle );
|
||||
|
||||
if ( ( font = fm->getByName( family ) ) )
|
||||
if ( ( font = mResourceScope->findFont( family ).get() ) )
|
||||
return true;
|
||||
|
||||
FontTrueType* ttf = FontTrueType::New( family, desc.path, desc.faceIndex );
|
||||
FontTrueTypePtr ttf =
|
||||
FontTrueType::New( family, desc.path, desc.faceIndex, *mResourceScope );
|
||||
if ( ttf && ttf->loaded() ) {
|
||||
font = ttf;
|
||||
font = ttf.get();
|
||||
Uint32 weightStyle = fontStyle & ( Text::Bold | Text::Italic );
|
||||
if ( weightStyle ) {
|
||||
Font* regular = fm->getByName( desc.family );
|
||||
Font* regular = mResourceScope->findFont( desc.family ).get();
|
||||
if ( regular && regular != font &&
|
||||
regular->getType() == FontType::TTF ) {
|
||||
auto* regularFT = static_cast<FontTrueType*>( regular );
|
||||
@@ -2309,8 +2317,8 @@ void UISceneNode::clearFontFaces() {
|
||||
if ( mRoot )
|
||||
mRoot->reloadFontFamily();
|
||||
|
||||
for ( auto& font : mFontFaces )
|
||||
FontManager::instance()->remove( font );
|
||||
for ( const FontPtr& font : mFontFaces )
|
||||
mResourceScope->eraseLocalFont( font.get() );
|
||||
|
||||
mFontFaces.clear();
|
||||
}
|
||||
@@ -2348,7 +2356,7 @@ void UISceneNode::loadFontStyleVariants( Font* font, const std::string& family )
|
||||
return;
|
||||
auto* ft = static_cast<FontTrueType*>( font );
|
||||
|
||||
auto loadVariant = [family]( FontWeight weight, bool italic ) -> FontTrueType* {
|
||||
auto loadVariant = [this, family]( FontWeight weight, bool italic ) -> FontTrueTypePtr {
|
||||
Uint32 style = 0;
|
||||
if ( italic )
|
||||
style |= Text::Italic;
|
||||
@@ -2357,9 +2365,10 @@ void UISceneNode::loadFontStyleVariants( Font* font, const std::string& family )
|
||||
std::string queryFamily = family;
|
||||
if ( style )
|
||||
queryFamily += "#" + Text::styleFlagToString( style );
|
||||
Font* existing = FontManager::instance()->getByName( queryFamily );
|
||||
FontPtr existingHandle = mResourceScope->findFont( queryFamily );
|
||||
Font* existing = existingHandle.get();
|
||||
if ( existing && existing->getType() == FontType::TTF )
|
||||
return static_cast<FontTrueType*>( existing );
|
||||
return std::static_pointer_cast<FontTrueType>( existingHandle );
|
||||
|
||||
FontDesc desc = SystemFontResolver::instance()->resolveGeneric(
|
||||
SystemFontResolver::genericFamilyFromName( family ), weight, italic );
|
||||
@@ -2373,23 +2382,24 @@ void UISceneNode::loadFontStyleVariants( Font* font, const std::string& family )
|
||||
if ( desc.path.empty() )
|
||||
return nullptr;
|
||||
|
||||
auto* ttf = FontTrueType::New( queryFamily, desc.path, desc.faceIndex );
|
||||
FontTrueTypePtr ttf =
|
||||
FontTrueType::New( queryFamily, desc.path, desc.faceIndex, *mResourceScope );
|
||||
if ( !ttf || !ttf->loaded() ) {
|
||||
eeSAFE_DELETE( ttf );
|
||||
mResourceScope->eraseLocalFont( ttf.get() );
|
||||
return nullptr;
|
||||
}
|
||||
return ttf;
|
||||
};
|
||||
|
||||
FontTrueType* boldFont = loadVariant( FontWeight::Bold, false );
|
||||
FontTrueTypePtr boldFont = loadVariant( FontWeight::Bold, false );
|
||||
if ( boldFont )
|
||||
ft->setBoldFont( boldFont );
|
||||
|
||||
FontTrueType* italicFont = loadVariant( FontWeight::Normal, true );
|
||||
FontTrueTypePtr italicFont = loadVariant( FontWeight::Normal, true );
|
||||
if ( italicFont )
|
||||
ft->setItalicFont( italicFont );
|
||||
|
||||
FontTrueType* boldItalicFont = loadVariant( FontWeight::Bold, true );
|
||||
FontTrueTypePtr boldItalicFont = loadVariant( FontWeight::Bold, true );
|
||||
if ( boldItalicFont )
|
||||
ft->setBoldItalicFont( boldItalicFont );
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/scene/actions/actions.hpp>
|
||||
#include <eepp/system/functionstring.hpp>
|
||||
#include <eepp/ui/css/stylesheetpropertyanimation.hpp>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/primitives.hpp>
|
||||
#include <eepp/graphics/renderer/renderer.hpp>
|
||||
#include <eepp/ui/css/propertydefinition.hpp>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include <eepp/graphics/font.hpp>
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/fonttruetype.hpp>
|
||||
#include <eepp/graphics/primitives.hpp>
|
||||
#include <eepp/graphics/renderer/renderer.hpp>
|
||||
#include <eepp/graphics/resourcescope.hpp>
|
||||
#include <eepp/graphics/text.hpp>
|
||||
#include <eepp/ui/css/propertydefinition.hpp>
|
||||
#include <eepp/ui/uiicon.hpp>
|
||||
@@ -649,7 +649,10 @@ bool UITextInput::applyProperty( const StyleSheetProperty& attribute ) {
|
||||
setHintFontSize( lengthFromValue( attribute ) );
|
||||
break;
|
||||
case PropertyId::HintFontFamily:
|
||||
setHintFont( FontManager::instance()->getByName( attribute.value() ) );
|
||||
setHintFont(
|
||||
getUISceneNode()
|
||||
? getUISceneNode()->getResourceScope()->findFont( attribute.value() ).get()
|
||||
: nullptr );
|
||||
break;
|
||||
case PropertyId::HintFontStyle:
|
||||
setHintFontStyle( attribute.asFontStyle() );
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include <eepp/core/debug.hpp>
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/text.hpp>
|
||||
#include <eepp/scene/scenemanager.hpp>
|
||||
#include <eepp/ui/css/propertydefinition.hpp>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include <eepp/graphics/font.hpp>
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/primitives.hpp>
|
||||
#include <eepp/graphics/text.hpp>
|
||||
#include <eepp/scene/actions/actions.hpp>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/text.hpp>
|
||||
#include <eepp/scene/actions/actions.hpp>
|
||||
#include <eepp/system/log.hpp>
|
||||
|
||||
@@ -2,12 +2,10 @@
|
||||
|
||||
#ifdef EE_BACKEND_SDL2
|
||||
|
||||
#include <eepp/graphics/framebuffermanager.hpp>
|
||||
#include <eepp/graphics/globalbatchrenderer.hpp>
|
||||
#include <eepp/graphics/renderer/renderer.hpp>
|
||||
#include <eepp/graphics/shaderprogrammanager.hpp>
|
||||
#include <eepp/graphics/texturefactory.hpp>
|
||||
#include <eepp/graphics/vertexbuffermanager.hpp>
|
||||
#include <eepp/system/filesystem.hpp>
|
||||
#include <eepp/system/log.hpp>
|
||||
#include <eepp/window/backend/SDL2/clipboardsdl2.hpp>
|
||||
|
||||
@@ -2,12 +2,10 @@
|
||||
|
||||
#ifdef EE_BACKEND_SDL3
|
||||
|
||||
#include <eepp/graphics/framebuffermanager.hpp>
|
||||
#include <eepp/graphics/globalbatchrenderer.hpp>
|
||||
#include <eepp/graphics/renderer/renderer.hpp>
|
||||
#include <eepp/graphics/shaderprogrammanager.hpp>
|
||||
#include <eepp/graphics/texturefactory.hpp>
|
||||
#include <eepp/graphics/vertexbuffermanager.hpp>
|
||||
#include <eepp/system/filesystem.hpp>
|
||||
#include <eepp/system/log.hpp>
|
||||
#include <eepp/window/backend/SDL3/clipboardsdl3.hpp>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/framebuffermanager.hpp>
|
||||
#include <eepp/graphics/globalbatchrenderer.hpp>
|
||||
#include <eepp/graphics/renderer/renderer.hpp>
|
||||
@@ -105,8 +104,6 @@ Engine::~Engine() {
|
||||
|
||||
Doc::SyntaxDefinitionManager::destroySingleton();
|
||||
|
||||
FontManager::destroySingleton();
|
||||
|
||||
Graphics::Private::FrameBufferManager::destroySingleton();
|
||||
|
||||
Graphics::Private::VertexBufferManager::destroySingleton();
|
||||
|
||||
@@ -25,23 +25,24 @@ EE_MAIN_FUNC int main( int, char*[] ) {
|
||||
"cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non "
|
||||
"proident, sunt in culpa qui officia deserunt mollit anim id est laborum." );
|
||||
|
||||
FontTrueType* fontTest = FontTrueType::New( "DejaVuSansMono" );
|
||||
FontTrueType* fontTest = FontTrueType::New( "DejaVuSansMono" ).get();
|
||||
fontTest->loadFromFile( "assets/fonts/DejaVuSansMono.ttf" );
|
||||
|
||||
FontTrueType* fontTest2 = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* fontTest2 = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
fontTest2->loadFromFile( "assets/fonts/NotoSans-Regular.ttf" );
|
||||
|
||||
FontTrueType* fontEmoji = FontTrueType::New( "NotoEmoji-Regular" );
|
||||
FontTrueType* fontEmoji = FontTrueType::New( "NotoEmoji-Regular" ).get();
|
||||
fontEmoji->loadFromFile( "assets/fonts/NotoEmoji-Regular.ttf" );
|
||||
|
||||
FontTrueType* fontEmojiColor = FontTrueType::New( "NotoColorEmoji" );
|
||||
FontTrueType* fontEmojiColor = FontTrueType::New( "NotoColorEmoji" ).get();
|
||||
fontEmojiColor->loadFromFile( "assets/fonts/NotoColorEmoji.ttf" );
|
||||
|
||||
FontBMFont* fontBMFont = FontBMFont::New( "bmfont" );
|
||||
FontBMFont* fontBMFont = FontBMFont::New( "bmfont" ).get();
|
||||
fontBMFont->loadFromFile( "assets/fonts/bmfont.fnt" );
|
||||
|
||||
FontSprite* fontSprite = FontSprite::New(
|
||||
"alagard" ); // Alagard - Hewett Tsoi ( https://www.dafont.com/alagard.font )
|
||||
FontSprite* fontSprite =
|
||||
FontSprite::New( "alagard" )
|
||||
.get(); // Alagard - Hewett Tsoi ( https://www.dafont.com/alagard.font )
|
||||
fontSprite->loadFromFile( "assets/fonts/custom_alagard.png", Color::Fuchsia, 32, -4 );
|
||||
|
||||
Text text;
|
||||
|
||||
@@ -9,7 +9,7 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) {
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font =
|
||||
FontTrueType::New( "NotoSans-Regular", "assets/fonts/NotoSans-Regular.ttf" );
|
||||
FontTrueType::New( "NotoSans-Regular", "assets/fonts/NotoSans-Regular.ttf" ).get();
|
||||
|
||||
if ( !font || !font->loaded() )
|
||||
return EXIT_FAILURE;
|
||||
|
||||
@@ -10,10 +10,15 @@ EE_MAIN_FUNC int main( int, char** ) {
|
||||
return EXIT_FAILURE;
|
||||
|
||||
app.getUI()->setThreadPool( threadPool );
|
||||
ResourceScope& resourceScope = *app.getUI()->getResourceScope();
|
||||
FontTrueTypePtr remixIconFont =
|
||||
FontTrueType::New( "icon", "assets/fonts/remixicon.ttf", resourceScope );
|
||||
FontTrueTypePtr noniconsFont =
|
||||
FontTrueType::New( "nonicons", "assets/fonts/nonicons.ttf", resourceScope );
|
||||
FontTrueTypePtr codIconFont =
|
||||
FontTrueType::New( "codicon", "assets/fonts/codicon.ttf", resourceScope );
|
||||
app.getUI()->getUIIconThemeManager()->setCurrentTheme(
|
||||
IconManager::init( "icons", FontTrueType::New( "icon", "assets/fonts/remixicon.ttf" ),
|
||||
FontTrueType::New( "nonicons", "assets/fonts/nonicons.ttf" ),
|
||||
FontTrueType::New( "codicon", "assets/fonts/codicon.ttf" ) ) );
|
||||
IconManager::init( "icons", remixIconFont.get(), noniconsFont.get(), codIconFont.get() ) );
|
||||
|
||||
UIFontPickerDialog* dialog = UIFontPickerDialog::New();
|
||||
dialog->setCloseShortcut( KEY_ESCAPE );
|
||||
|
||||
@@ -13,13 +13,12 @@ EE_MAIN_FUNC int main( int, char** ) {
|
||||
// is always correct even if we load the application from other directory than the binary
|
||||
// path.
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
// Load a font to use as the default font in our UI.
|
||||
FontTrueType* font =
|
||||
FontTrueType::New( "NotoSans-Regular", "assets/fonts/NotoSans-Regular.ttf" );
|
||||
|
||||
// Create a new scene node to add our widgets.
|
||||
UISceneNode* uiSceneNode = UISceneNode::New();
|
||||
// Load a font to use as the default font in our UI.
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular", "assets/fonts/NotoSans-Regular.ttf",
|
||||
*uiSceneNode->getResourceScope() )
|
||||
.get();
|
||||
|
||||
// Set the default font used in the scene node (otherwise we won't have any font to create
|
||||
// text views.
|
||||
|
||||
@@ -63,11 +63,15 @@ EE_MAIN_FUNC int main( int argc, char** argv ) {
|
||||
auto ui = app.getUI();
|
||||
ui->setThreadPool( threadPool );
|
||||
|
||||
FontTrueType* remixIconFont = FontTrueType::New( "icon", "assets/fonts/remixicon.ttf" );
|
||||
FontTrueType* noniconsFont = FontTrueType::New( "nonicons", "assets/fonts/nonicons.ttf" );
|
||||
FontTrueType* codIconFont = FontTrueType::New( "codicon", "assets/fonts/codicon.ttf" );
|
||||
ResourceScope& resourceScope = *ui->getResourceScope();
|
||||
FontTrueTypePtr remixIconFont =
|
||||
FontTrueType::New( "icon", "assets/fonts/remixicon.ttf", resourceScope );
|
||||
FontTrueTypePtr noniconsFont =
|
||||
FontTrueType::New( "nonicons", "assets/fonts/nonicons.ttf", resourceScope );
|
||||
FontTrueTypePtr codIconFont =
|
||||
FontTrueType::New( "codicon", "assets/fonts/codicon.ttf", resourceScope );
|
||||
ui->getUIIconThemeManager()->setCurrentTheme(
|
||||
IconManager::init( "icons", remixIconFont, noniconsFont, codIconFont ) );
|
||||
IconManager::init( "icons", remixIconFont.get(), noniconsFont.get(), codIconFont.get() ) );
|
||||
|
||||
ui->setColorSchemePreference(
|
||||
!prefersColorScheme.Get().empty()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/fontservice.hpp>
|
||||
#include <eepp/graphics/fonttruetype.hpp>
|
||||
#include <eepp/graphics/renderer/renderer.hpp>
|
||||
#include <eepp/graphics/text.hpp>
|
||||
@@ -1391,7 +1391,12 @@ void TerminalDisplay::drawGrid( const Vector2f& pos ) {
|
||||
auto* gd = mFont->getGlyphDrawable( glyph.u, mFontSize, glyph.mode & ATTR_BOLD,
|
||||
glyph.mode & ATTR_ITALIC, 0 );
|
||||
|
||||
if ( ( glyph.mode & ATTR_EMOJI ) && FontManager::instance()->getColorEmojiFont() ) {
|
||||
FontService* fontService =
|
||||
mFont->getType() == FontType::TTF
|
||||
? static_cast<FontTrueType*>( mFont )->getFontService()
|
||||
: nullptr;
|
||||
if ( ( glyph.mode & ATTR_EMOJI ) && fontService &&
|
||||
fontService->getColorEmojiFont() ) {
|
||||
gd->setColor( Color::White );
|
||||
} else {
|
||||
gd->setColor( fg );
|
||||
|
||||
@@ -256,8 +256,8 @@ void EETest::loadFonts() {
|
||||
}
|
||||
|
||||
void EETest::onFontLoaded() {
|
||||
TTF = FontManager::instance()->getByName( "NotoSans-Regular" );
|
||||
Font* monospace = FontManager::instance()->getByName( "monospace" );
|
||||
TTF = defaultResourceScope().findFont( "NotoSans-Regular" ).get();
|
||||
Font* monospace = defaultResourceScope().findFont( "monospace" ).get();
|
||||
|
||||
Log::info( "Fonts loading time: %4.3f ms.", mFTE.getElapsedTimeAndReset().asMilliseconds() );
|
||||
|
||||
|
||||
@@ -168,13 +168,13 @@ int testTextRendering() {
|
||||
editor->setLayoutSizePolicy( SizePolicy::MatchParent, SizePolicy::MatchParent );
|
||||
editor->setParent( ll );
|
||||
// editor->setFontSize( PixelDensity::dpToPx( 12 ) );
|
||||
FontManager::instance()->addFallbackFont(
|
||||
defaultResourceScope().getFontService().addFallbackFont(
|
||||
FontTrueType::New( "arabic", "unit_tests/assets/fonts/NotoNaskhArabic-Regular.ttf" ) );
|
||||
FontManager::instance()->addFallbackFont( FontTrueType::New(
|
||||
defaultResourceScope().getFontService().addFallbackFont( FontTrueType::New(
|
||||
"NotoSerifBengali-Regular", "unit_tests/assets/fonts/NotoSansBengali-Regular.ttf" ) );
|
||||
editor->setWordWrap( true );
|
||||
// editor->setLineWrapMode( LineWrapMode::Word );
|
||||
// editor->setFont( FontManager::instance()->getByName( "monospace" ) );
|
||||
// editor->setFont( defaultResourceScope().findFont( "monospace" ).get() );
|
||||
// editor->loadFromFile( "unit_tests/assets/textfiles/test-arabic-simple.uext" );
|
||||
// editor->loadFromFile( "unit_tests/assets/textfiles/test-arabic.uext" );
|
||||
// editor->loadFromFile( "unit_tests/assets/textfiles/test-bengali.uext" );
|
||||
@@ -212,8 +212,8 @@ EE_MAIN_FUNC int main( int, char*[] ) {
|
||||
PixelDensity::setPixelDensity(
|
||||
Engine::instance()->getDisplayManager()->getDisplayIndex( 0 )->getPixelDensity() );
|
||||
FontTrueType* font =
|
||||
FontTrueType::New( "NotoSans-Regular", "assets/fonts/NotoSans-Regular.ttf" );
|
||||
FontTrueType* iconFont = FontTrueType::New( "icon", "assets/fonts/remixicon.ttf" );
|
||||
FontTrueType::New( "NotoSans-Regular", "assets/fonts/NotoSans-Regular.ttf" ).get();
|
||||
FontTrueType* iconFont = FontTrueType::New( "icon", "assets/fonts/remixicon.ttf" ).get();
|
||||
UIIconTheme* iconTheme = UIIconTheme::New( "remixicon" );
|
||||
auto addIcon = [iconTheme, iconFont]( const std::string& name,
|
||||
const Uint32& codePoint ) -> UIIcon* {
|
||||
|
||||
@@ -25,7 +25,7 @@ using namespace EE::UI::CSS;
|
||||
static UISceneNode* initDrawableParserTest() {
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
FontFamily::loadFromRegular( font );
|
||||
|
||||
@@ -54,7 +54,7 @@ UTEST( DrawableImageParser, TwoStopsWithPosition ) {
|
||||
|
||||
auto& parser = StyleSheetSpecification::instance()->getDrawableImageParser();
|
||||
DrawablePtr drawable = parser.createDrawable( "linear-gradient(#f5eedd 0%, #ebe0c2 100%)",
|
||||
Sizef( 100, 100 ), node );
|
||||
Sizef( 100, 100 ), node );
|
||||
|
||||
ASSERT_TRUE( drawable != NULL );
|
||||
ASSERT_EQ( drawable->getDrawableType(), Drawable::LINEARGRADIENT );
|
||||
@@ -82,8 +82,8 @@ UTEST( DrawableImageParser, DirectionToRight ) {
|
||||
UINode* node = createTestNode( sceneNode );
|
||||
|
||||
auto& parser = StyleSheetSpecification::instance()->getDrawableImageParser();
|
||||
DrawablePtr drawable = parser.createDrawable( "linear-gradient(to right, red, blue)",
|
||||
Sizef( 100, 100 ), node );
|
||||
DrawablePtr drawable =
|
||||
parser.createDrawable( "linear-gradient(to right, red, blue)", Sizef( 100, 100 ), node );
|
||||
|
||||
ASSERT_TRUE( drawable != NULL );
|
||||
auto* grad = static_cast<LinearGradientDrawable*>( drawable.get() );
|
||||
@@ -105,7 +105,7 @@ UTEST( DrawableImageParser, AngleDegrees ) {
|
||||
|
||||
auto& parser = StyleSheetSpecification::instance()->getDrawableImageParser();
|
||||
DrawablePtr drawable = parser.createDrawable( "linear-gradient(45deg, red 0%, blue 100%)",
|
||||
Sizef( 100, 100 ), node );
|
||||
Sizef( 100, 100 ), node );
|
||||
|
||||
ASSERT_TRUE( drawable != NULL );
|
||||
auto* grad = static_cast<LinearGradientDrawable*>( drawable.get() );
|
||||
@@ -124,8 +124,8 @@ UTEST( DrawableImageParser, AngleTurn ) {
|
||||
UINode* node = createTestNode( sceneNode );
|
||||
|
||||
auto& parser = StyleSheetSpecification::instance()->getDrawableImageParser();
|
||||
DrawablePtr drawable = parser.createDrawable( "linear-gradient(0.25turn, red, blue)",
|
||||
Sizef( 100, 100 ), node );
|
||||
DrawablePtr drawable =
|
||||
parser.createDrawable( "linear-gradient(0.25turn, red, blue)", Sizef( 100, 100 ), node );
|
||||
|
||||
ASSERT_TRUE( drawable != NULL );
|
||||
auto* grad = static_cast<LinearGradientDrawable*>( drawable.get() );
|
||||
@@ -145,7 +145,7 @@ UTEST( DrawableImageParser, ThreeStops ) {
|
||||
|
||||
auto& parser = StyleSheetSpecification::instance()->getDrawableImageParser();
|
||||
DrawablePtr drawable = parser.createDrawable( "linear-gradient(red 0%, green 50%, blue 100%)",
|
||||
Sizef( 100, 100 ), node );
|
||||
Sizef( 100, 100 ), node );
|
||||
|
||||
ASSERT_TRUE( drawable != NULL );
|
||||
auto* grad = static_cast<LinearGradientDrawable*>( drawable.get() );
|
||||
@@ -168,8 +168,8 @@ UTEST( DrawableImageParser, ColorHint ) {
|
||||
UINode* node = createTestNode( sceneNode );
|
||||
|
||||
auto& parser = StyleSheetSpecification::instance()->getDrawableImageParser();
|
||||
DrawablePtr drawable = parser.createDrawable( "linear-gradient(red 0%, 25%, blue 100%)",
|
||||
Sizef( 100, 100 ), node );
|
||||
DrawablePtr drawable =
|
||||
parser.createDrawable( "linear-gradient(red 0%, 25%, blue 100%)", Sizef( 100, 100 ), node );
|
||||
|
||||
ASSERT_TRUE( drawable != NULL );
|
||||
auto* grad = static_cast<LinearGradientDrawable*>( drawable.get() );
|
||||
@@ -209,8 +209,8 @@ UTEST( DrawableImageParser, StopsWithoutPositions ) {
|
||||
UINode* node = createTestNode( sceneNode );
|
||||
|
||||
auto& parser = StyleSheetSpecification::instance()->getDrawableImageParser();
|
||||
DrawablePtr drawable = parser.createDrawable( "linear-gradient(red, green, blue)",
|
||||
Sizef( 100, 100 ), node );
|
||||
DrawablePtr drawable =
|
||||
parser.createDrawable( "linear-gradient(red, green, blue)", Sizef( 100, 100 ), node );
|
||||
|
||||
ASSERT_TRUE( drawable != NULL );
|
||||
auto* grad = static_cast<LinearGradientDrawable*>( drawable.get() );
|
||||
@@ -254,8 +254,8 @@ UTEST( DrawableImageParser, RepeatingTwoStops ) {
|
||||
UINode* node = createTestNode( sceneNode );
|
||||
|
||||
auto& parser = StyleSheetSpecification::instance()->getDrawableImageParser();
|
||||
DrawablePtr drawable = parser.createDrawable( "repeating-linear-gradient(red, blue)",
|
||||
Sizef( 100, 100 ), node );
|
||||
DrawablePtr drawable =
|
||||
parser.createDrawable( "repeating-linear-gradient(red, blue)", Sizef( 100, 100 ), node );
|
||||
|
||||
ASSERT_TRUE( drawable != NULL );
|
||||
ASSERT_TRUE( drawable->getDrawableType() == Drawable::REPEATINGLINEARGRADIENT );
|
||||
@@ -301,7 +301,7 @@ UTEST( DrawableImageParser, RepeatingWithPositions ) {
|
||||
|
||||
auto& parser = StyleSheetSpecification::instance()->getDrawableImageParser();
|
||||
DrawablePtr drawable = parser.createDrawable( "repeating-linear-gradient(red 10%, blue 40%)",
|
||||
Sizef( 100, 100 ), node );
|
||||
Sizef( 100, 100 ), node );
|
||||
|
||||
ASSERT_TRUE( drawable != NULL );
|
||||
auto* grad = static_cast<LinearGradientDrawable*>( drawable.get() );
|
||||
@@ -347,8 +347,8 @@ UTEST( DrawableImageParser, RadialCircleKeyword ) {
|
||||
UINode* node = createTestNode( sceneNode );
|
||||
|
||||
auto& parser = StyleSheetSpecification::instance()->getDrawableImageParser();
|
||||
DrawablePtr drawable = parser.createDrawable( "radial-gradient(circle, #f00, #00f)",
|
||||
Sizef( 100, 100 ), node );
|
||||
DrawablePtr drawable =
|
||||
parser.createDrawable( "radial-gradient(circle, #f00, #00f)", Sizef( 100, 100 ), node );
|
||||
|
||||
ASSERT_TRUE( drawable != NULL );
|
||||
auto* grad = static_cast<RadialGradientDrawable*>( drawable.get() );
|
||||
@@ -367,8 +367,8 @@ UTEST( DrawableImageParser, RadialWithPositions ) {
|
||||
UINode* node = createTestNode( sceneNode );
|
||||
|
||||
auto& parser = StyleSheetSpecification::instance()->getDrawableImageParser();
|
||||
DrawablePtr drawable = parser.createDrawable( "radial-gradient(red 10%, blue 80%)",
|
||||
Sizef( 100, 100 ), node );
|
||||
DrawablePtr drawable =
|
||||
parser.createDrawable( "radial-gradient(red 10%, blue 80%)", Sizef( 100, 100 ), node );
|
||||
|
||||
ASSERT_TRUE( drawable != NULL );
|
||||
auto* grad = static_cast<RadialGradientDrawable*>( drawable.get() );
|
||||
@@ -390,7 +390,7 @@ UTEST( DrawableImageParser, RepeatingRadial ) {
|
||||
|
||||
auto& parser = StyleSheetSpecification::instance()->getDrawableImageParser();
|
||||
DrawablePtr drawable = parser.createDrawable( "repeating-radial-gradient(red 10%, blue 40%)",
|
||||
Sizef( 100, 100 ), node );
|
||||
Sizef( 100, 100 ), node );
|
||||
|
||||
ASSERT_TRUE( drawable != NULL );
|
||||
ASSERT_TRUE( drawable->getDrawableType() == Drawable::REPEATINGRADIALGRADIENT );
|
||||
|
||||
@@ -4,15 +4,16 @@
|
||||
#include <eepp/graphics/batchrenderer.hpp>
|
||||
#include <eepp/graphics/fontbmfont.hpp>
|
||||
#include <eepp/graphics/fontfamily.hpp>
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/fontsprite.hpp>
|
||||
#include <eepp/graphics/fonttruetype.hpp>
|
||||
#include <eepp/graphics/globalbatchrenderer.hpp>
|
||||
#include <eepp/graphics/image.hpp>
|
||||
#include <eepp/graphics/primitives.hpp>
|
||||
#include <eepp/graphics/renderer/renderergl.hpp>
|
||||
#include <eepp/graphics/resourcescope.hpp>
|
||||
#include <eepp/graphics/richtext.hpp>
|
||||
#include <eepp/graphics/text.hpp>
|
||||
#include <eepp/graphics/texturefactory.hpp>
|
||||
#include <eepp/scene/scenemanager.hpp>
|
||||
#include <eepp/system/base64.hpp>
|
||||
#include <eepp/system/filesystem.hpp>
|
||||
@@ -35,34 +36,127 @@ using namespace EE::Window;
|
||||
using namespace EE::UI;
|
||||
using namespace EE::UI::CSS;
|
||||
|
||||
UTEST( FontRendering, relatedFontsDisconnectReplacedCallbacks ) {
|
||||
FontTrueType* font = FontTrueType::New( "RelatedFontsDisconnect-Regular" );
|
||||
FontTrueType* oldBold = FontTrueType::New( "RelatedFontsDisconnect-OldBold" );
|
||||
FontTrueType* newBold = FontTrueType::New( "RelatedFontsDisconnect-NewBold" );
|
||||
FontTrueType* oldItalic = FontTrueType::New( "RelatedFontsDisconnect-OldItalic" );
|
||||
FontTrueType* newItalic = FontTrueType::New( "RelatedFontsDisconnect-NewItalic" );
|
||||
FontTrueType* oldBoldItalic = FontTrueType::New( "RelatedFontsDisconnect-OldBoldItalic" );
|
||||
FontTrueType* newBoldItalic = FontTrueType::New( "RelatedFontsDisconnect-NewBoldItalic" );
|
||||
UTEST( FontRendering, drawingEmptyTextDoesNotCreateFontPage ) {
|
||||
UIApplication app(
|
||||
WindowSettings( 320, 240, "eepp - Empty Text Test", WindowStyle::Default,
|
||||
WindowBackend::Default, 32 ),
|
||||
UIApplication::Settings( Sys::getProcessPath() + ".." + FileSystem::getOSSlash(), 1 ) );
|
||||
|
||||
font->setBoldFont( oldBold );
|
||||
font->setBoldFont( newBold );
|
||||
eeDelete( oldBold );
|
||||
EXPECT_EQ( newBold, font->getBoldFont() );
|
||||
FontDesc desc;
|
||||
desc.family = "Empty Text Test";
|
||||
desc.path = Sys::getProcessPath() + "assets/fonts/NotoSansKR-Regular.ttf";
|
||||
FontTrueTypePtr font = app.getUI()->getResourceScope()->getFontService().loadSystemFont( desc );
|
||||
ASSERT_TRUE( font );
|
||||
|
||||
font->setItalicFont( oldItalic );
|
||||
font->setItalicFont( newItalic );
|
||||
eeDelete( oldItalic );
|
||||
EXPECT_EQ( newItalic, font->getItalicFont() );
|
||||
TextureFactory* textureFactory = TextureFactory::instance();
|
||||
const Uint32 textureCount = textureFactory->getTextureCount();
|
||||
Text::draw( String{}, Vector2f::Zero, font.get(), 10, Color::White );
|
||||
|
||||
font->setBoldItalicFont( oldBoldItalic );
|
||||
font->setBoldItalicFont( newBoldItalic );
|
||||
eeDelete( oldBoldItalic );
|
||||
EXPECT_EQ( newBoldItalic, font->getBoldItalicFont() );
|
||||
EXPECT_EQ( textureCount, textureFactory->getTextureCount() );
|
||||
}
|
||||
|
||||
eeDelete( font );
|
||||
eeDelete( newBold );
|
||||
eeDelete( newItalic );
|
||||
eeDelete( newBoldItalic );
|
||||
UTEST( FontRendering, glyphAdvanceDoesNotCreateTexturePages ) {
|
||||
UIApplication app(
|
||||
WindowSettings( 320, 240, "eepp - Glyph Advance Test", WindowStyle::Default,
|
||||
WindowBackend::Default, 32 ),
|
||||
UIApplication::Settings( Sys::getProcessPath() + ".." + FileSystem::getOSSlash(), 1 ) );
|
||||
ResourceScope& scope = *app.getUI()->getResourceScope();
|
||||
FontTrueTypePtr font = FontTrueType::New( "GlyphAdvance-Regular", scope );
|
||||
ASSERT_TRUE(
|
||||
font->loadFromFile( Sys::getProcessPath() + "../assets/fonts/NotoSans-Regular.ttf" ) );
|
||||
|
||||
TextureFactory* textureFactory = TextureFactory::instance();
|
||||
const Uint32 textureCount = textureFactory->getTextureCount();
|
||||
const Float advance = font->getGlyphAdvance( ' ', 10 );
|
||||
const Float outlinedAdvance = font->getGlyphAdvance( ' ', 10, false, false, 2.f );
|
||||
EXPECT_TRUE( advance > 0 );
|
||||
EXPECT_EQ( advance, outlinedAdvance );
|
||||
EXPECT_EQ( textureCount, textureFactory->getTextureCount() );
|
||||
}
|
||||
|
||||
UTEST( FontRendering, loadingFontFamilyDoesNotCreateTexturePages ) {
|
||||
UIApplication app(
|
||||
WindowSettings( 320, 240, "eepp - Font Family Metrics Test", WindowStyle::Default,
|
||||
WindowBackend::Default, 32 ),
|
||||
UIApplication::Settings( Sys::getProcessPath() + ".." + FileSystem::getOSSlash(), 1 ) );
|
||||
ResourceScope& scope = *app.getUI()->getResourceScope();
|
||||
FontTrueTypePtr font = FontTrueType::New( "FontFamilyMetrics-Regular", scope );
|
||||
ASSERT_TRUE(
|
||||
font->loadFromFile( Sys::getProcessPath() + "../assets/fonts/NotoSans-Regular.ttf" ) );
|
||||
|
||||
TextureFactory* textureFactory = TextureFactory::instance();
|
||||
const Uint32 textureCount = textureFactory->getTextureCount();
|
||||
|
||||
FontFamily::loadFromRegular( font.get() );
|
||||
EXPECT_TRUE( font->hasBold() );
|
||||
EXPECT_TRUE( font->hasItalic() );
|
||||
EXPECT_EQ( textureCount, textureFactory->getTextureCount() );
|
||||
}
|
||||
|
||||
UTEST( FontRendering, regularFontOwnsRelatedFonts ) {
|
||||
FontTrueTypePtr font = FontTrueType::New( "RelatedFonts-Regular" );
|
||||
FontTrueTypePtr bold = FontTrueType::New( "RelatedFonts-Bold" );
|
||||
FontTrueTypePtr italic = FontTrueType::New( "RelatedFonts-Italic" );
|
||||
FontTrueTypePtr boldItalic = FontTrueType::New( "RelatedFonts-BoldItalic" );
|
||||
FontTrueTypeWeakPtr weakBold = bold;
|
||||
FontTrueTypeWeakPtr weakItalic = italic;
|
||||
FontTrueTypeWeakPtr weakBoldItalic = boldItalic;
|
||||
|
||||
font->setBoldFont( bold );
|
||||
font->setItalicFont( italic );
|
||||
font->setBoldItalicFont( boldItalic );
|
||||
|
||||
defaultResourceScope().eraseLocalFont( bold.get() );
|
||||
defaultResourceScope().eraseLocalFont( italic.get() );
|
||||
defaultResourceScope().eraseLocalFont( boldItalic.get() );
|
||||
bold.reset();
|
||||
italic.reset();
|
||||
boldItalic.reset();
|
||||
|
||||
EXPECT_TRUE( font->getBoldFont() );
|
||||
EXPECT_TRUE( font->getItalicFont() );
|
||||
EXPECT_TRUE( font->getBoldItalicFont() );
|
||||
EXPECT_FALSE( weakBold.expired() );
|
||||
EXPECT_FALSE( weakItalic.expired() );
|
||||
EXPECT_FALSE( weakBoldItalic.expired() );
|
||||
|
||||
defaultResourceScope().eraseLocalFont( font.get() );
|
||||
font.reset();
|
||||
|
||||
EXPECT_TRUE( weakBold.expired() );
|
||||
EXPECT_TRUE( weakItalic.expired() );
|
||||
EXPECT_TRUE( weakBoldItalic.expired() );
|
||||
}
|
||||
|
||||
UTEST( FontRendering, destroyingFontInvalidatesTextLayoutCache ) {
|
||||
UIApplication app(
|
||||
WindowSettings( 320, 240, "eepp - Text Layout Cache Test", WindowStyle::Default,
|
||||
WindowBackend::Default, 32 ),
|
||||
UIApplication::Settings( Sys::getProcessPath() + ".." + FileSystem::getOSSlash(), 1 ) );
|
||||
ResourceScope& scope = *app.getUI()->getResourceScope();
|
||||
FontTrueTypePtr font = FontTrueType::New( "TextLayoutCache-Regular", scope );
|
||||
FontTrueTypePtr retainedFont = FontTrueType::New( "TextLayoutCache-Retained", scope );
|
||||
ASSERT_TRUE(
|
||||
font->loadFromFile( Sys::getProcessPath() + "../assets/fonts/NotoSans-Regular.ttf" ) );
|
||||
ASSERT_TRUE( retainedFont->loadFromFile( Sys::getProcessPath() +
|
||||
"../assets/fonts/NotoSans-Regular.ttf" ) );
|
||||
|
||||
TextLayout::Cache layout =
|
||||
TextLayout::layout( String( "cached shaped text" ), font.get(), 14, Text::Regular );
|
||||
TextLayout::Cache retainedLayout = TextLayout::layout( String( "unrelated cached text" ),
|
||||
retainedFont.get(), 14, Text::Regular );
|
||||
std::weak_ptr<const TextLayout> layoutWeak = layout;
|
||||
std::weak_ptr<const TextLayout> retainedLayoutWeak = retainedLayout;
|
||||
layout.reset();
|
||||
retainedLayout.reset();
|
||||
EXPECT_FALSE( layoutWeak.expired() );
|
||||
EXPECT_FALSE( retainedLayoutWeak.expired() );
|
||||
|
||||
EXPECT_TRUE( scope.eraseLocalFont( font.get() ) );
|
||||
font.reset();
|
||||
|
||||
EXPECT_TRUE( layoutWeak.expired() );
|
||||
EXPECT_FALSE( retainedLayoutWeak.expired() );
|
||||
}
|
||||
|
||||
UTEST( FontRendering, fontsTest ) {
|
||||
@@ -85,22 +179,22 @@ UTEST( FontRendering, fontsTest ) {
|
||||
"cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non "
|
||||
"proident, sunt in culpa qui officia deserunt mollit anim id est laborum." );
|
||||
|
||||
FontTrueType* fontTest = FontTrueType::New( "DejaVuSansMono" );
|
||||
FontTrueType* fontTest = FontTrueType::New( "DejaVuSansMono" ).get();
|
||||
fontTest->loadFromFile( "../assets/fonts/DejaVuSansMono.ttf" );
|
||||
|
||||
FontTrueType* fontTest2 = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* fontTest2 = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
fontTest2->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
|
||||
FontTrueType* fontEmoji = FontTrueType::New( "NotoEmoji-Regular" );
|
||||
FontTrueType* fontEmoji = FontTrueType::New( "NotoEmoji-Regular" ).get();
|
||||
fontEmoji->loadFromFile( "../assets/fonts/NotoEmoji-Regular.ttf" );
|
||||
|
||||
FontTrueType* fontEmojiColor = FontTrueType::New( "NotoColorEmoji" );
|
||||
FontTrueType* fontEmojiColor = FontTrueType::New( "NotoColorEmoji" ).get();
|
||||
fontEmojiColor->loadFromFile( "../assets/fonts/NotoColorEmoji.ttf" );
|
||||
|
||||
FontBMFont* fontBMFont = FontBMFont::New( "bmfont" );
|
||||
FontBMFont* fontBMFont = FontBMFont::New( "bmfont" ).get();
|
||||
fontBMFont->loadFromFile( "../assets/fonts/bmfont.fnt" );
|
||||
|
||||
FontSprite* fontSprite = FontSprite::New( "alagard" );
|
||||
FontSprite* fontSprite = FontSprite::New( "alagard" ).get();
|
||||
fontSprite->loadFromFile( "../assets/fonts/custom_alagard.png", Color::Fuchsia, 32, -4 );
|
||||
|
||||
Text text;
|
||||
@@ -288,7 +382,7 @@ UTEST( FontRendering, loadFontFaceDataURI ) {
|
||||
SceneManager::instance()->add( sceneNode );
|
||||
UI::UIThemeManager* themeManager = sceneNode->getUIThemeManager();
|
||||
|
||||
FontTrueType* baseFont = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* baseFont = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
baseFont->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
themeManager->setDefaultFont( baseFont );
|
||||
|
||||
@@ -315,7 +409,7 @@ UTEST( FontRendering, loadFontFaceDataURI ) {
|
||||
Font* loadedFont = sceneNode->getFontFromNamesList( "DataURIFont" );
|
||||
ASSERT_NE( loadedFont, nullptr );
|
||||
ASSERT_TRUE_MSG( loadedFont->loaded(), "Font loaded via data URI is not loaded" );
|
||||
EXPECT_EQ( nullptr, FontManager::instance()->getByName( "DataURIFont" ) );
|
||||
EXPECT_EQ( nullptr, defaultResourceScope().findFont( "DataURIFont" ).get() );
|
||||
|
||||
Engine::destroySingleton();
|
||||
}
|
||||
@@ -353,7 +447,7 @@ UTEST( FontRendering, fontFaceAuthorFamilyIsSceneScoped ) {
|
||||
EXPECT_TRUE( fontB->loaded() );
|
||||
EXPECT_NE( fontA, fontB );
|
||||
EXPECT_TRUE( fontA->getName() != fontB->getName() );
|
||||
EXPECT_EQ( nullptr, FontManager::instance()->getByName( "ScopedAuthorFace" ) );
|
||||
EXPECT_EQ( nullptr, defaultResourceScope().findFont( "ScopedAuthorFace" ).get() );
|
||||
|
||||
Engine::destroySingleton();
|
||||
}
|
||||
@@ -631,8 +725,9 @@ UTEST( FontRendering, textEditBengaliTest ) {
|
||||
UIApplication::Settings( Sys::getProcessPath() + ".." + FileSystem::getOSSlash(), 1.5f ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
FontTrueType* bengaliFont =
|
||||
FontTrueType::New( "NotoSansBengali-Regular", "assets/fonts/NotoSansBengali-Regular.ttf" );
|
||||
FontManager::instance()->addFallbackFont( bengaliFont );
|
||||
FontTrueType::New( "NotoSansBengali-Regular", "assets/fonts/NotoSansBengali-Regular.ttf" )
|
||||
.get();
|
||||
defaultResourceScope().getFontService().addFallbackFont( bengaliFont );
|
||||
UTEST_PRINT_STEP( "Text Shaper enabled" );
|
||||
auto* editor = UITextEdit::New();
|
||||
// editor->setFontSize( PixelDensity::dpToPx( 12 ) );
|
||||
@@ -651,8 +746,9 @@ UTEST( FontRendering, textEditArabicTest ) {
|
||||
UIApplication::Settings( Sys::getProcessPath() + ".." + FileSystem::getOSSlash(), 1.5f ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
FontTrueType* arabicFont =
|
||||
FontTrueType::New( "NotoNaskhArabic-Regular", "assets/fonts/NotoNaskhArabic-Regular.ttf" );
|
||||
FontManager::instance()->addFallbackFont( arabicFont );
|
||||
FontTrueType::New( "NotoNaskhArabic-Regular", "assets/fonts/NotoNaskhArabic-Regular.ttf" )
|
||||
.get();
|
||||
defaultResourceScope().getFontService().addFallbackFont( arabicFont );
|
||||
UTEST_PRINT_STEP( "Text Shaper enabled" );
|
||||
auto* editor = UITextEdit::New();
|
||||
// editor->setFontSize( PixelDensity::dpToPx( 12 ) );
|
||||
@@ -671,8 +767,9 @@ UTEST( FontRendering, textEditHebrewTest ) {
|
||||
UIApplication::Settings( Sys::getProcessPath() + ".." + FileSystem::getOSSlash(), 1.5f ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
FontTrueType* hebrewFont =
|
||||
FontTrueType::New( "NotoSansHebrew-Regular", "assets/fonts/NotoSansHebrew-Regular.ttf" );
|
||||
FontManager::instance()->addFallbackFont( hebrewFont );
|
||||
FontTrueType::New( "NotoSansHebrew-Regular", "assets/fonts/NotoSansHebrew-Regular.ttf" )
|
||||
.get();
|
||||
defaultResourceScope().getFontService().addFallbackFont( hebrewFont );
|
||||
UTEST_PRINT_STEP( "Text Shaper enabled" );
|
||||
auto* editor = UITextEdit::New();
|
||||
// editor->setFontSize( PixelDensity::dpToPx( 12 ) );
|
||||
@@ -692,7 +789,7 @@ UTEST( FontRendering, textSizes ) {
|
||||
|
||||
Text::TextShaperEnabled = false;
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
|
||||
FontStyleConfig config;
|
||||
@@ -793,7 +890,7 @@ UTEST( FontRendering, textStyles ) {
|
||||
|
||||
Text::TextShaperEnabled = false;
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
FontFamily::loadFromRegular( font );
|
||||
|
||||
@@ -876,11 +973,11 @@ UTEST( FontRendering, emojisWithText ) {
|
||||
|
||||
Text::TextShaperEnabled = false;
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
FontFamily::loadFromRegular( font );
|
||||
|
||||
FontTrueType* fontEmojiColor = FontTrueType::New( "NotoColorEmoji" );
|
||||
FontTrueType* fontEmojiColor = FontTrueType::New( "NotoColorEmoji" ).get();
|
||||
fontEmojiColor->loadFromFile( "../assets/fonts/NotoColorEmoji.ttf" );
|
||||
|
||||
win->setClearColor( RGB( 255, 255, 255 ) );
|
||||
@@ -934,7 +1031,8 @@ UTEST( FontRendering, textSetFillColor ) {
|
||||
win->setClearColor( RGB( 230, 230, 230 ) );
|
||||
|
||||
FontTrueType* arabicFont =
|
||||
FontTrueType::New( "NotoNaskhArabic-Regular", "assets/fonts/NotoNaskhArabic-Regular.ttf" );
|
||||
FontTrueType::New( "NotoNaskhArabic-Regular", "assets/fonts/NotoNaskhArabic-Regular.ttf" )
|
||||
.get();
|
||||
|
||||
Text text;
|
||||
text.setFont( arabicFont );
|
||||
@@ -1364,7 +1462,7 @@ UTEST( FontRendering, TextSoftWrapPos ) {
|
||||
UIApplication::Settings( Sys::getProcessPath() + ".." + FileSystem::getOSSlash(), 1 ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "DejaVuSansMono" );
|
||||
FontTrueType* font = FontTrueType::New( "DejaVuSansMono" ).get();
|
||||
font->loadFromFile( "../assets/fonts/DejaVuSansMono.ttf" );
|
||||
|
||||
Text text;
|
||||
@@ -1414,7 +1512,7 @@ UTEST( FontRendering, TextSelection ) {
|
||||
|
||||
Text::TextShaperEnabled = false;
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
bool loaded = font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( loaded );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -1501,7 +1599,7 @@ UTEST( FontRendering, TextInitialOffset ) {
|
||||
win->setClearColor( RGB( 255, 255, 255 ) );
|
||||
win->clear();
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
|
||||
Primitives p;
|
||||
@@ -1568,7 +1666,7 @@ UTEST( FontRendering, TextContiguousOffset ) {
|
||||
win->setClearColor( RGB( 255, 255, 255 ) );
|
||||
win->clear();
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
|
||||
Float maxWidth = 450.f;
|
||||
@@ -1681,7 +1779,7 @@ UTEST( FontRendering, TextBackgroundColor ) {
|
||||
win->setClearColor( RGB( 255, 255, 255 ) );
|
||||
win->clear();
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
|
||||
Vector2f pos{ 20, 20 };
|
||||
|
||||
@@ -26,7 +26,7 @@ static UISceneNode* createScene() {
|
||||
true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
if ( !font->loaded() ) {
|
||||
Engine::destroySingleton();
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
#include <condition_variable>
|
||||
#include <eepp/core/lrucache.hpp>
|
||||
#include <eepp/graphics/drawablegroup.hpp>
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/fontbmfont.hpp>
|
||||
#include <eepp/graphics/fontsprite.hpp>
|
||||
#include <eepp/graphics/fonttruetype.hpp>
|
||||
#include <eepp/graphics/framebuffermanager.hpp>
|
||||
#include <eepp/graphics/globalbatchrenderer.hpp>
|
||||
@@ -199,6 +200,18 @@ EE::Window::Window* createLifecycleTestWindow( const std::string& title ) {
|
||||
|
||||
static_assert( !std::is_copy_constructible<Texture>::value, "Texture must not be copyable" );
|
||||
static_assert( !std::is_copy_assignable<Texture>::value, "Texture must not be copy-assignable" );
|
||||
static_assert( std::is_invocable_r_v<std::size_t, std::hash<ResourceId>, const ResourceId&>,
|
||||
"ResourceId must support standard unordered containers" );
|
||||
|
||||
UTEST( ResourcePrerequisites, resourceIdSupportsUnorderedContainers ) {
|
||||
UnorderedMap<ResourceId, int> resources;
|
||||
resources[ResourceId( 1 )] = 10;
|
||||
resources[ResourceId( 2 )] = 20;
|
||||
|
||||
EXPECT_EQ( 10, resources[ResourceId( 1 )] );
|
||||
EXPECT_EQ( 20, resources[ResourceId( 2 )] );
|
||||
EXPECT_EQ( (size_t)2, resources.size() );
|
||||
}
|
||||
|
||||
UTEST( ResourcePrerequisites, lruCacheEvictsOnlyLeastRecentlyUsedAndReleasesKeys ) {
|
||||
LRUCache<2, int, bool> recencyCache;
|
||||
@@ -221,6 +234,21 @@ UTEST( ResourcePrerequisites, lruCacheEvictsOnlyLeastRecentlyUsedAndReleasesKeys
|
||||
|
||||
owningKeyCache.clear();
|
||||
EXPECT_TRUE( weakKey.expired() );
|
||||
|
||||
LRUCache<3, int, int> selectiveCache;
|
||||
selectiveCache.put( 1, 10 );
|
||||
selectiveCache.put( 2, 20 );
|
||||
selectiveCache.put( 3, 30 );
|
||||
ASSERT_TRUE( selectiveCache.get( 1 ).has_value() );
|
||||
selectiveCache.eraseIf( []( int key, int ) { return key == 2; } );
|
||||
EXPECT_TRUE( !selectiveCache.get( 2 ).has_value() );
|
||||
EXPECT_EQ( (size_t)2, selectiveCache.size() );
|
||||
selectiveCache.put( 4, 40 );
|
||||
selectiveCache.put( 5, 50 );
|
||||
EXPECT_TRUE( !selectiveCache.get( 3 ).has_value() );
|
||||
EXPECT_TRUE( selectiveCache.get( 1 ).has_value() );
|
||||
EXPECT_TRUE( selectiveCache.get( 4 ).has_value() );
|
||||
EXPECT_TRUE( selectiveCache.get( 5 ).has_value() );
|
||||
}
|
||||
|
||||
UTEST( ResourcePrerequisites, textureAtlasLoaderAppliesFilterToEveryTexture ) {
|
||||
@@ -495,6 +523,92 @@ UTEST( ResourcePrerequisites, defaultResourceScopeImportsGlobalCatalog ) {
|
||||
Engine::destroySingleton();
|
||||
}
|
||||
|
||||
UTEST( ResourcePrerequisites, uiScenesImportDefaultResourcesUnlessDisabled ) {
|
||||
EE::Window::Window* window = createLifecycleTestWindow( "UI scene default resources test" );
|
||||
TexturePtr texture = TextureFactory::instance()->createEmptyTexture( 1, 1 );
|
||||
ASSERT_TRUE( texture != nullptr );
|
||||
defaultResourceScope().publishLocal( "ui-scene-default-texture", texture );
|
||||
|
||||
UISceneNode* defaultScene = UISceneNode::New( window );
|
||||
UISceneNode* isolatedScene = UISceneNode::New( window, false );
|
||||
EXPECT_EQ( texture.get(),
|
||||
defaultScene->getResourceScope()->findTexture( "ui-scene-default-texture" ).get() );
|
||||
EXPECT_TRUE( isolatedScene->getResourceScope()->findTexture( "ui-scene-default-texture" ) ==
|
||||
nullptr );
|
||||
|
||||
defaultScene->setResourceScope( ResourceScope::New() );
|
||||
EXPECT_EQ( texture.get(),
|
||||
defaultScene->getResourceScope()->findTexture( "ui-scene-default-texture" ).get() );
|
||||
|
||||
eeDelete( isolatedScene );
|
||||
eeDelete( defaultScene );
|
||||
defaultResourceScope().eraseLocal( "ui-scene-default-texture" );
|
||||
texture.reset();
|
||||
window->display( false );
|
||||
Engine::destroySingleton();
|
||||
}
|
||||
|
||||
UTEST( ResourcePrerequisites, fontServiceFollowsScopeOwnershipAndDetachesRetainedFonts ) {
|
||||
EE::Window::Window* window = createLifecycleTestWindow( "Font service scope test" );
|
||||
ResourceScopePtr scope = ResourceScope::New();
|
||||
FontTrueTypePtr font = FontTrueType::New( "scoped-font-service", *scope );
|
||||
ASSERT_TRUE( font != nullptr );
|
||||
|
||||
EXPECT_EQ( &scope->getFontService(), font->getFontService() );
|
||||
EXPECT_EQ( font.get(), scope->findFont( "scoped-font-service" ).get() );
|
||||
EXPECT_TRUE( scope->getFontService().addFallbackFont( font ) );
|
||||
EXPECT_TRUE( scope->getFontService().hasFallbackFonts() );
|
||||
|
||||
EXPECT_TRUE( scope->eraseLocalFont( font.get() ) );
|
||||
EXPECT_EQ( nullptr, font->getFontService() );
|
||||
EXPECT_FALSE( scope->getFontService().hasFallbackFonts() );
|
||||
EXPECT_TRUE( scope->findFont( "scoped-font-service" ) == nullptr );
|
||||
|
||||
font.reset();
|
||||
scope.reset();
|
||||
window->display( false );
|
||||
Engine::destroySingleton();
|
||||
}
|
||||
|
||||
UTEST( ResourcePrerequisites, fontFactoriesPublishIntoExplicitScope ) {
|
||||
EE::Window::Window* window = createLifecycleTestWindow( "Scoped font factories test" );
|
||||
auto scope = ResourceScope::New();
|
||||
auto bmFont = FontBMFont::New( "scoped-bm-font", *scope );
|
||||
auto spriteFont = FontSprite::New( "scoped-sprite-font", *scope );
|
||||
|
||||
EXPECT_EQ( bmFont.get(), scope->findFont( "scoped-bm-font" ).get() );
|
||||
EXPECT_EQ( spriteFont.get(), scope->findFont( "scoped-sprite-font" ).get() );
|
||||
EXPECT_EQ( nullptr, defaultResourceScope().findFont( "scoped-bm-font" ).get() );
|
||||
EXPECT_EQ( nullptr, defaultResourceScope().findFont( "scoped-sprite-font" ).get() );
|
||||
|
||||
bmFont.reset();
|
||||
spriteFont.reset();
|
||||
scope.reset();
|
||||
window->display( false );
|
||||
Engine::destroySingleton();
|
||||
}
|
||||
|
||||
UTEST( ResourcePrerequisites, duplicateFontNamesReplaceCatalogBinding ) {
|
||||
EE::Window::Window* window = createLifecycleTestWindow( "Font replacement semantics test" );
|
||||
auto scope = ResourceScope::New();
|
||||
FontTrueTypePtr first = FontTrueType::New( "replaceable-font", *scope );
|
||||
FontTrueTypePtr second = FontTrueType::New( "replaceable-font", *scope );
|
||||
FontTrueTypeWeakPtr firstWeak = first;
|
||||
|
||||
EXPECT_STRINGEQ( "replaceable-font", first->getName() );
|
||||
EXPECT_STRINGEQ( "replaceable-font", second->getName() );
|
||||
EXPECT_EQ( second.get(), scope->findFont( "replaceable-font" ).get() );
|
||||
EXPECT_EQ( nullptr, first->getFontService() );
|
||||
EXPECT_EQ( &scope->getFontService(), second->getFontService() );
|
||||
|
||||
first.reset();
|
||||
EXPECT_TRUE( firstWeak.expired() );
|
||||
second.reset();
|
||||
scope.reset();
|
||||
window->display( false );
|
||||
Engine::destroySingleton();
|
||||
}
|
||||
|
||||
UTEST( ResourcePrerequisites, uiScenesOwnIsolatedScopesThatCanBeSharedExplicitly ) {
|
||||
EE::Window::Window* window = createLifecycleTestWindow( "UI scene resource scope test" );
|
||||
UISceneNode* firstScene = UISceneNode::New( window );
|
||||
@@ -1049,10 +1163,11 @@ UTEST( ResourcePrerequisites, engineTeardownReleasesGraphicsBeforeContextsAcross
|
||||
scene->enableFrameBuffer();
|
||||
UIImage::New()->setDrawable( ninePatch->clone() )->setParent( scene->getRoot() );
|
||||
|
||||
auto* font = FontTrueType::New( "engine-teardown-font" );
|
||||
FontTrueTypePtr font = FontTrueType::New( "engine-teardown-font" );
|
||||
ASSERT_TRUE(
|
||||
font->loadFromFile( Sys::getProcessPath() + "../assets/fonts/NotoSans-Regular.ttf" ) );
|
||||
auto layout = TextLayout::layout( String( "cached before Engine teardown" ), font, 14, 0 );
|
||||
auto layout =
|
||||
TextLayout::layout( String( "cached before Engine teardown" ), font.get(), 14, 0 );
|
||||
std::weak_ptr<const TextLayout> layoutWeak = layout;
|
||||
layout.reset();
|
||||
|
||||
@@ -1061,6 +1176,7 @@ UTEST( ResourcePrerequisites, engineTeardownReleasesGraphicsBeforeContextsAcross
|
||||
batch->batchQuad( 0, 0, 4, 4 );
|
||||
ninePatch.reset();
|
||||
texture.reset();
|
||||
font.reset();
|
||||
|
||||
Engine::destroySingleton();
|
||||
|
||||
@@ -1068,7 +1184,6 @@ UTEST( ResourcePrerequisites, engineTeardownReleasesGraphicsBeforeContextsAcross
|
||||
EXPECT_TRUE( Engine::existsSingleton() == nullptr );
|
||||
EXPECT_TRUE( SceneManager::existsSingleton() == nullptr );
|
||||
EXPECT_TRUE( GlobalBatchRenderer::existsSingleton() == nullptr );
|
||||
EXPECT_TRUE( FontManager::existsSingleton() == nullptr );
|
||||
EXPECT_TRUE( TextureFactory::existsSingleton() == nullptr );
|
||||
EXPECT_TRUE( ShaderProgramManager::existsSingleton() == nullptr );
|
||||
EXPECT_TRUE( Graphics::Private::FrameBufferManager::existsSingleton() == nullptr );
|
||||
|
||||
@@ -40,7 +40,7 @@ static UISceneNode* createRichTextScene() {
|
||||
32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
if ( !font->loaded() ) {
|
||||
Engine::destroySingleton();
|
||||
@@ -94,7 +94,7 @@ UTEST( RichText, basicFunctionality ) {
|
||||
32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
|
||||
ASSERT_TRUE( font->loaded() );
|
||||
@@ -141,7 +141,7 @@ UTEST( RichText, selection ) {
|
||||
32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font->loaded() );
|
||||
|
||||
@@ -222,7 +222,7 @@ UTEST( RichText, BaselineAlignment ) {
|
||||
32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font->loaded() );
|
||||
|
||||
@@ -260,7 +260,7 @@ UTEST( RichText, VerticalAlignAtomicBoxes ) {
|
||||
32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font->loaded() );
|
||||
|
||||
@@ -355,7 +355,7 @@ UTEST( RichText, InlineTextUsesActiveInlineBoxAlignment ) {
|
||||
32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font->loaded() );
|
||||
|
||||
@@ -403,7 +403,7 @@ UTEST( RichText, InlineAncestorLineHeightContributesToLineHeight ) {
|
||||
32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font->loaded() );
|
||||
|
||||
@@ -452,7 +452,7 @@ UTEST( RichText, FloatAwareInlineLayoutUsesTreeOrder ) {
|
||||
32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font->loaded() );
|
||||
|
||||
@@ -487,7 +487,7 @@ UTEST( RichText, RenderSpanPayloadSupportsDrawableAndAtomicSelection ) {
|
||||
32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font->loaded() );
|
||||
|
||||
@@ -545,7 +545,7 @@ UTEST( RichText, InlineBoxHorizontalEdgesContributeToAdvance ) {
|
||||
32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font->loaded() );
|
||||
|
||||
@@ -607,7 +607,7 @@ UTEST( RichText, HitTestingSnapsAcrossInlineBoxSpacing ) {
|
||||
32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font->loaded() );
|
||||
|
||||
@@ -653,7 +653,7 @@ UTEST( RichText, SelectionRectsUseInlineFragments ) {
|
||||
WindowBackend::Default, 32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font->loaded() );
|
||||
|
||||
@@ -699,7 +699,7 @@ UTEST( RichText, InlineParentTextDecorationReachesFragments ) {
|
||||
32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font->loaded() );
|
||||
|
||||
@@ -748,7 +748,7 @@ UTEST( RichText, AtomicInlineBoxBaselineAlignment ) {
|
||||
32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font->loaded() );
|
||||
|
||||
@@ -778,7 +778,7 @@ UTEST( LineWrap, SoftWrapPreventsWordSplitWithOffset ) {
|
||||
WindowStyle::Default, WindowBackend::Default,
|
||||
32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font->loaded() );
|
||||
|
||||
@@ -798,8 +798,6 @@ UTEST( LineWrap, SoftWrapPreventsWordSplitWithOffset ) {
|
||||
ASSERT_GE( info.wraps.size(), (size_t)2 );
|
||||
EXPECT_EQ( info.wraps[1], 1 );
|
||||
|
||||
delete font;
|
||||
|
||||
Engine::destroySingleton();
|
||||
}
|
||||
|
||||
@@ -840,7 +838,7 @@ UTEST( RichText, RichTextTest ) {
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font =
|
||||
FontTrueType::New( "NotoSans-Regular", "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
FontTrueType::New( "NotoSans-Regular", "../assets/fonts/NotoSans-Regular.ttf" ).get();
|
||||
|
||||
ASSERT_TRUE( font && font->loaded() );
|
||||
|
||||
@@ -1738,7 +1736,7 @@ UTEST( RichText, BreakSpacesWrapsAfterPreservedSpacesAndTabs ) {
|
||||
32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "utest.hpp"
|
||||
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/fonttruetype.hpp>
|
||||
#include <eepp/graphics/resourcescope.hpp>
|
||||
#include <eepp/graphics/systemfontresolver.hpp>
|
||||
#include <eepp/system/filesystem.hpp>
|
||||
#include <eepp/system/sys.hpp>
|
||||
@@ -548,12 +548,12 @@ UTEST( FontTrueType_faceIndex, loadWithDefaultFaceIndex ) {
|
||||
std::string fontPath = getFontsDir() + "DejaVuSansMono.ttf";
|
||||
ASSERT_TRUE( FileSystem::fileExists( fontPath ) );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "Test-faceIndex-default" );
|
||||
FontTrueType* font = FontTrueType::New( "Test-faceIndex-default" ).get();
|
||||
bool loaded = font->loadFromFile( fontPath );
|
||||
ASSERT_TRUE( loaded );
|
||||
EXPECT_TRUE( font->loaded() );
|
||||
|
||||
eeDelete( font );
|
||||
defaultResourceScope().eraseLocalFont( font );
|
||||
}
|
||||
|
||||
UTEST( FontTrueType_faceIndex, newWithFaceIndex ) {
|
||||
@@ -562,11 +562,11 @@ UTEST( FontTrueType_faceIndex, newWithFaceIndex ) {
|
||||
std::string fontPath = getFontsDir() + "DejaVuSansMono.ttf";
|
||||
ASSERT_TRUE( FileSystem::fileExists( fontPath ) );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "Test-faceIndex-explicit", fontPath, 0 );
|
||||
FontTrueType* font = FontTrueType::New( "Test-faceIndex-explicit", fontPath, 0 ).get();
|
||||
ASSERT_TRUE( font != nullptr );
|
||||
EXPECT_TRUE( font->loaded() );
|
||||
|
||||
eeDelete( font );
|
||||
defaultResourceScope().eraseLocalFont( font );
|
||||
}
|
||||
|
||||
UTEST( FontTrueType_faceIndex, loadFromMemoryFaceIndex ) {
|
||||
@@ -578,10 +578,10 @@ UTEST( FontTrueType_faceIndex, loadFromMemoryFaceIndex ) {
|
||||
ScopedBuffer buf;
|
||||
FileSystem::fileGet( fontPath, buf );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "Test-faceIndex-memory" );
|
||||
FontTrueType* font = FontTrueType::New( "Test-faceIndex-memory" ).get();
|
||||
bool loaded = font->loadFromMemory( buf.get(), buf.length(), true, 0 );
|
||||
ASSERT_TRUE( loaded );
|
||||
EXPECT_TRUE( font->loaded() );
|
||||
|
||||
eeDelete( font );
|
||||
defaultResourceScope().eraseLocalFont( font );
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "utest.hpp"
|
||||
#include <eepp/graphics/font.hpp>
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/pixeldensity.hpp>
|
||||
#include <eepp/graphics/resourcescope.hpp>
|
||||
#include <eepp/scene/node.hpp>
|
||||
#include <eepp/system/filesystem.hpp>
|
||||
#include <eepp/ui/css/stylesheet.hpp>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#include "utest.hpp"
|
||||
#include <algorithm>
|
||||
#include <eepp/graphics/fonttruetype.hpp>
|
||||
#include <eepp/graphics/globalbatchrenderer.hpp>
|
||||
#include <eepp/graphics/systemfontresolver.hpp>
|
||||
#include <eepp/graphics/texturefactory.hpp>
|
||||
#include <eepp/system/filesystem.hpp>
|
||||
#include <eepp/system/threadpool.hpp>
|
||||
#include <eepp/ui/abstract/uiabstractview.hpp>
|
||||
@@ -47,6 +49,16 @@ template <typename Predicate> static void pumpUntil( UISceneNode* sceneNode, Pre
|
||||
}
|
||||
}
|
||||
|
||||
class TestFontPickerDialog : public UIFontPickerDialog {
|
||||
public:
|
||||
static TestFontPickerDialog* New() { return eeNew( TestFontPickerDialog, () ); }
|
||||
|
||||
FontTrueTypeWeakPtr getPreviewFontHandle() const { return mPreviewFont; }
|
||||
|
||||
protected:
|
||||
TestFontPickerDialog() : UIFontPickerDialog() {}
|
||||
};
|
||||
|
||||
UTEST( UIFontPickerDialog, PreselectsExternalFontPath ) {
|
||||
UIApplication app(
|
||||
WindowSettings( 320, 240, "eepp - UIFontPickerDialog Test", WindowStyle::Default,
|
||||
@@ -55,7 +67,6 @@ UTEST( UIFontPickerDialog, PreselectsExternalFontPath ) {
|
||||
|
||||
const std::string fontPath = Sys::getProcessPath() + "assets/fonts/NotoSansKR-Regular.ttf";
|
||||
ASSERT_TRUE( FileSystem::fileExists( fontPath ) );
|
||||
|
||||
UIFontPickerDialog* dialog = UIFontPickerDialog::New();
|
||||
dialog->setSelectedFont( fontPath );
|
||||
|
||||
@@ -73,6 +84,150 @@ UTEST( UIFontPickerDialog, PreselectsExternalFontPath ) {
|
||||
EXPECT_FALSE( selectionDialog->getSelection().font.family.empty() );
|
||||
}
|
||||
|
||||
UTEST( UIFontPickerDialog, PreviewFontsDoNotPopulateSceneFontCatalog ) {
|
||||
UIApplication app(
|
||||
WindowSettings( 320, 240, "eepp - UIFontPickerDialog Test", WindowStyle::Default,
|
||||
WindowBackend::Default, 32 ),
|
||||
UIApplication::Settings( Sys::getProcessPath() + ".." + FileSystem::getOSSlash(), 1 ) );
|
||||
|
||||
const std::string koreanFontPath =
|
||||
Sys::getProcessPath() + "assets/fonts/NotoSansKR-Regular.ttf";
|
||||
const std::string hebrewFontPath =
|
||||
Sys::getProcessPath() + "assets/fonts/NotoSansHebrew-Regular.ttf";
|
||||
ASSERT_TRUE( FileSystem::fileExists( koreanFontPath ) );
|
||||
ASSERT_TRUE( FileSystem::fileExists( hebrewFontPath ) );
|
||||
|
||||
UIFontPickerDialog* dialog = UIFontPickerDialog::New();
|
||||
ResourceScope& sceneScope = *app.getUI()->getResourceScope();
|
||||
const size_t sceneFontCount = sceneScope.getFonts().size();
|
||||
|
||||
dialog->setSelectedFont( koreanFontPath );
|
||||
dialog->setSelectedFont( hebrewFontPath );
|
||||
|
||||
EXPECT_EQ( sceneFontCount, sceneScope.getFonts().size() );
|
||||
}
|
||||
|
||||
UTEST( UIFontPickerDialog, SelectingFontDoesNotCreateMetricOnlyPage ) {
|
||||
UIApplication app(
|
||||
WindowSettings( 320, 240, "eepp - UIFontPickerDialog Test", WindowStyle::Default,
|
||||
WindowBackend::Default, 32 ),
|
||||
UIApplication::Settings( Sys::getProcessPath() + ".." + FileSystem::getOSSlash(), 1 ) );
|
||||
|
||||
const std::string fontPath = Sys::getProcessPath() + "assets/fonts/NotoSansKR-Regular.ttf";
|
||||
ASSERT_TRUE( FileSystem::fileExists( fontPath ) );
|
||||
UIFontPickerDialog* dialog = UIFontPickerDialog::New();
|
||||
dialog->setSelectedFont( fontPath );
|
||||
app.getUI()->draw();
|
||||
GlobalBatchRenderer::instance()->draw();
|
||||
|
||||
bool foundPreviewPage = false;
|
||||
for ( const auto& texture : TextureFactory::instance()->snapshotTextures() ) {
|
||||
if ( String::startsWith( texture.displayName, "@font:TrueType:Noto Sans KR:" ) ) {
|
||||
foundPreviewPage = true;
|
||||
EXPECT_FALSE( String::endsWith( texture.displayName, ":10" ) );
|
||||
}
|
||||
}
|
||||
EXPECT_TRUE( foundPreviewPage );
|
||||
}
|
||||
|
||||
UTEST( UIFontPickerDialog, ReleasesPreviewFontTexturesOnClose ) {
|
||||
UIApplication app(
|
||||
WindowSettings( 320, 240, "eepp - UIFontPickerDialog Test", WindowStyle::Default,
|
||||
WindowBackend::Default, 32 ),
|
||||
UIApplication::Settings( Sys::getProcessPath() + ".." + FileSystem::getOSSlash(), 1 ) );
|
||||
|
||||
const std::string koreanFontPath =
|
||||
Sys::getProcessPath() + "assets/fonts/NotoSansKR-Regular.ttf";
|
||||
const std::string hebrewFontPath =
|
||||
Sys::getProcessPath() + "assets/fonts/NotoSansHebrew-Regular.ttf";
|
||||
ASSERT_TRUE( FileSystem::fileExists( koreanFontPath ) );
|
||||
ASSERT_TRUE( FileSystem::fileExists( hebrewFontPath ) );
|
||||
|
||||
TextureFactory* textureFactory = TextureFactory::instance();
|
||||
UnorderedSet<ResourceId> baselineIds;
|
||||
for ( const auto& texture : textureFactory->snapshotTextures() )
|
||||
baselineIds.insert( texture.id );
|
||||
|
||||
UIFontPickerDialog* dialog = UIFontPickerDialog::New();
|
||||
dialog->setSelectedFont( koreanFontPath );
|
||||
app.getUI()->draw();
|
||||
dialog->setSelectedFont( hebrewFontPath );
|
||||
app.getUI()->draw();
|
||||
GlobalBatchRenderer::instance()->draw();
|
||||
|
||||
std::vector<std::pair<std::string, TextureWeakPtr>> previewTextures;
|
||||
for ( const auto& texture : textureFactory->snapshotTextures() ) {
|
||||
if ( baselineIds.find( texture.id ) == baselineIds.end() &&
|
||||
( String::contains( texture.displayName, "Noto Sans KR" ) ||
|
||||
String::contains( texture.displayName, "Noto Sans Hebrew" ) ) )
|
||||
previewTextures.emplace_back( texture.displayName, texture.texture );
|
||||
}
|
||||
ASSERT_FALSE( previewTextures.empty() );
|
||||
|
||||
dialog->close();
|
||||
app.getUI()->update( Time::Zero );
|
||||
GlobalBatchRenderer::instance()->draw();
|
||||
textureFactory->collectReleasedTextures();
|
||||
|
||||
for ( const auto& texture : previewTextures )
|
||||
EXPECT_TRUE( texture.second.expired() );
|
||||
}
|
||||
|
||||
UTEST( UIFontPickerDialog, ReleasesEnumeratedSystemFontTexturesOnClose ) {
|
||||
UIApplication app(
|
||||
WindowSettings( 320, 240, "eepp - UIFontPickerDialog Test", WindowStyle::Default,
|
||||
WindowBackend::Default, 32 ),
|
||||
UIApplication::Settings( Sys::getProcessPath() + ".." + FileSystem::getOSSlash(), 1 ) );
|
||||
app.getUI()->getResourceScope()->clearImports();
|
||||
|
||||
std::vector<FontDesc> systemFonts;
|
||||
UnorderedSet<std::string> families;
|
||||
for ( const FontDesc& font : SystemFontResolver::instance()->enumerate() ) {
|
||||
if ( font.path.empty() || font.family.empty() || !families.insert( font.family ).second )
|
||||
continue;
|
||||
systemFonts.emplace_back( font );
|
||||
if ( systemFonts.size() == 3 )
|
||||
break;
|
||||
}
|
||||
if ( systemFonts.size() < 2 )
|
||||
UTEST_SKIP( "fewer than two distinct system font families available" );
|
||||
|
||||
TextureFactory* textureFactory = TextureFactory::instance();
|
||||
TestFontPickerDialog* dialog = TestFontPickerDialog::New();
|
||||
app.getUI()->draw();
|
||||
GlobalBatchRenderer::instance()->draw();
|
||||
std::vector<FontTrueTypeWeakPtr> previewFonts;
|
||||
std::vector<TextureWeakPtr> previewTextures;
|
||||
|
||||
for ( const FontDesc& font : systemFonts ) {
|
||||
dialog->setSelectedFont( font );
|
||||
app.getUI()->draw();
|
||||
GlobalBatchRenderer::instance()->draw();
|
||||
FontTrueTypePtr previewFont = dialog->getPreviewFontHandle().lock();
|
||||
ASSERT_TRUE( previewFont );
|
||||
previewFonts.emplace_back( previewFont );
|
||||
previewTextures.emplace_back(
|
||||
previewFont->getTexture( PixelDensity::dpToPxI( dialog->getSelection().size * 2 ) ) );
|
||||
previewTextures.emplace_back( previewFont->getTexture( PixelDensity::dpToPxI( 12 ) ) );
|
||||
}
|
||||
|
||||
dialog->close();
|
||||
GlobalBatchRenderer::instance()->draw();
|
||||
pumpUntil( app.getUI(), [&] {
|
||||
textureFactory->collectReleasedTextures();
|
||||
textureFactory->purgeExpiredTextures();
|
||||
return std::all_of( previewFonts.begin(), previewFonts.end(),
|
||||
[]( const FontTrueTypeWeakPtr& font ) { return font.expired(); } ) &&
|
||||
std::all_of( previewTextures.begin(), previewTextures.end(),
|
||||
[]( const TextureWeakPtr& texture ) { return texture.expired(); } );
|
||||
} );
|
||||
|
||||
for ( const auto& font : previewFonts )
|
||||
EXPECT_TRUE( font.expired() );
|
||||
for ( const auto& texture : previewTextures )
|
||||
EXPECT_TRUE( texture.expired() );
|
||||
}
|
||||
|
||||
UTEST( UIFontPickerDialog, AsyncLoadPreservesExternalFontPreselection ) {
|
||||
UIApplication app(
|
||||
WindowSettings( 320, 240, "eepp - UIFontPickerDialog Test", WindowStyle::Default,
|
||||
@@ -108,7 +263,7 @@ UTEST( UIFontPickerDialog, DefaultColorComesFromTheme ) {
|
||||
EXPECT_TRUE( dialog->getSelection().color.a != 0 );
|
||||
}
|
||||
|
||||
UTEST( UIFontPickerDialog, IncludesDiskFontsLoadedInFontManager ) {
|
||||
UTEST( UIFontPickerDialog, IncludesDiskFontsLoadedInDefaultScope ) {
|
||||
UIApplication app(
|
||||
WindowSettings( 320, 240, "eepp - UIFontPickerDialog Test", WindowStyle::Default,
|
||||
WindowBackend::Default, 32 ),
|
||||
@@ -117,7 +272,9 @@ UTEST( UIFontPickerDialog, IncludesDiskFontsLoadedInFontManager ) {
|
||||
const std::string fontPath = Sys::getProcessPath() + "assets/fonts/NotoSansKR-Regular.ttf";
|
||||
ASSERT_TRUE( FileSystem::fileExists( fontPath ) );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "UIFontPickerDialogManagedNotoSansKR", fontPath );
|
||||
FontTrueTypePtr fontHandle =
|
||||
FontTrueType::New( "UIFontPickerDialogManagedNotoSansKR", fontPath );
|
||||
FontTrueType* font = fontHandle.get();
|
||||
ASSERT_TRUE( font != nullptr );
|
||||
ASSERT_TRUE( font->loaded() );
|
||||
ASSERT_FALSE( font->getInfo().family.empty() );
|
||||
|
||||
@@ -24,7 +24,7 @@ using namespace EE::Graphics;
|
||||
|
||||
static void init_flex_test() {
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
FontFamily::loadFromRegular( font );
|
||||
UISceneNode* sceneNode = UISceneNode::New();
|
||||
|
||||
@@ -26,7 +26,7 @@ static void init_float_test() {
|
||||
32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
FontFamily::loadFromRegular( font );
|
||||
|
||||
@@ -1161,7 +1161,7 @@ UTEST( UIHTMLFloat, floatNotAffectedByTextAlignCenter ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
FontFamily::loadFromRegular( font );
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ using namespace EE::Graphics;
|
||||
|
||||
static void init_grid_test() {
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
FontFamily::loadFromRegular( font );
|
||||
UISceneNode* sceneNode = UISceneNode::New();
|
||||
|
||||
@@ -25,7 +25,7 @@ static void init_ui_test() {
|
||||
WindowBackend::Default, 32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
FontFamily::loadFromRegular( font );
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
#include "utest.hpp"
|
||||
|
||||
#include <eepp/graphics/fontfamily.hpp>
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/fonttruetype.hpp>
|
||||
#include <eepp/graphics/image.hpp>
|
||||
#include <eepp/graphics/renderer/renderer.hpp>
|
||||
#include <eepp/graphics/resourcescope.hpp>
|
||||
#include <eepp/graphics/texturedrawable.hpp>
|
||||
#include <eepp/graphics/texturefactory.hpp>
|
||||
#include <eepp/graphics/textureregion.hpp>
|
||||
@@ -80,10 +80,10 @@ static void init_ui_test() {
|
||||
32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
FontFamily::loadFromRegular( font );
|
||||
FontTrueType* monospace = FontTrueType::New( "monospace" );
|
||||
FontTrueType* monospace = FontTrueType::New( "monospace" ).get();
|
||||
monospace->loadFromFile( "../assets/fonts/DejaVuSansMono.ttf" );
|
||||
FontFamily::loadFromRegular( monospace );
|
||||
|
||||
@@ -131,7 +131,7 @@ UTEST( UIHTMLTable, complexLayout ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -192,7 +192,7 @@ UTEST( UIHTMLTable, complexLayout2 ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -251,7 +251,7 @@ UTEST( UIHTML, redditOldThreadWebViewSmoke ) {
|
||||
UTEST_SKIP( "old Reddit fixture CSS asset is not readable" );
|
||||
}
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -1048,7 +1048,7 @@ UTEST( UIRichText, anchorMargins ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -1090,7 +1090,7 @@ UTEST( UIRichText, spanPadding ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -1124,7 +1124,7 @@ UTEST( UIRichText, anchorPadding ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -1164,7 +1164,7 @@ UTEST( UIRichText, anchorPaddingLineHeight ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -1204,7 +1204,7 @@ UTEST( UIHTML, InlineBaselineAlignmentProperties ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -1257,7 +1257,7 @@ UTEST( UIHTML, InlineBlockVerticalAlignDoesNotInflateOwnTextLine ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -1306,7 +1306,7 @@ UTEST( UIHTMLTable, complexLayout3 ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -1339,7 +1339,7 @@ UTEST( UIHTMLTable, nestedPerformance ) {
|
||||
32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -1390,7 +1390,7 @@ UTEST( UIHTMLTable, specifiedWidth ) {
|
||||
32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -1430,7 +1430,7 @@ UTEST( UIHTMLTable, nestedSpecifiedWidth ) {
|
||||
32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -1975,7 +1975,7 @@ UTEST( UIHTMLTable, tableLayoutFixed ) {
|
||||
32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -2023,7 +2023,7 @@ UTEST( UIHTMLBody, backgroundColorPropagation ) {
|
||||
32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -2100,7 +2100,7 @@ UTEST( UILayout, marginAuto ) {
|
||||
32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -2368,7 +2368,7 @@ UTEST( UIHTMLDetails, lobstersInlineBlockCachesWidth ) {
|
||||
32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
FontFamily::loadFromRegular( font );
|
||||
|
||||
@@ -2548,7 +2548,7 @@ UTEST( UIBorder, renderingVariations ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -2582,7 +2582,7 @@ UTEST( UIBorder, renderingVariations2 ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -2610,12 +2610,11 @@ UTEST( UIBorder, renderingVariations2 ) {
|
||||
}
|
||||
|
||||
static UISceneNode* init_test_inline_block() {
|
||||
FontTrueType* font = nullptr;
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
FontFamily::loadFromRegular( font );
|
||||
FontTrueType* monoFont = FontTrueType::New( "monospace" );
|
||||
FontTrueType* monoFont = FontTrueType::New( "monospace" ).get();
|
||||
monoFont->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
UISceneNode* sceneNode = UISceneNode::New();
|
||||
SceneManager::instance()->add( sceneNode );
|
||||
@@ -4379,7 +4378,7 @@ static UISceneNode* createWinAndLoadHTML( std::string winName, std::string htmlP
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
if ( font == nullptr || !font->loaded() )
|
||||
return nullptr;
|
||||
@@ -4447,7 +4446,7 @@ UTEST( FontTrueType, glyphScaleZeroDimensionsNoCrash ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -5326,7 +5325,7 @@ UTEST( UIHTML, RonStonerDeferredImagesUpdateDocumentHeight ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -5416,7 +5415,7 @@ UTEST( UIHTML, NewsBlurStoryArchiveLayoutStabilizes ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
|
||||
@@ -31,7 +31,7 @@ static UISceneNode* initFormTest( const std::string& title ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
FontFamily::loadFromRegular( font );
|
||||
|
||||
|
||||
@@ -20,12 +20,11 @@ using namespace EE::Scene;
|
||||
using namespace EE::UI;
|
||||
|
||||
static UISceneNode* init_test_scene_node() {
|
||||
FontTrueType* font = nullptr;
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
FontFamily::loadFromRegular( font );
|
||||
FontTrueType* monoFont = FontTrueType::New( "monospace" );
|
||||
FontTrueType* monoFont = FontTrueType::New( "monospace" ).get();
|
||||
monoFont->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
UISceneNode* sceneNode = UISceneNode::New();
|
||||
SceneManager::instance()->add( sceneNode );
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include "utest.hpp"
|
||||
|
||||
#include <eepp/graphics/fontfamily.hpp>
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/fonttruetype.hpp>
|
||||
#include <eepp/graphics/primitives.hpp>
|
||||
#include <eepp/graphics/resourcescope.hpp>
|
||||
#include <eepp/graphics/richtext.hpp>
|
||||
#include <eepp/scene/node.hpp>
|
||||
#include <eepp/scene/scenemanager.hpp>
|
||||
@@ -39,7 +39,7 @@ static UISceneNode* createRichTextScene() {
|
||||
32, {}, 1, false, true ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
if ( !font->loaded() ) {
|
||||
Engine::destroySingleton();
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
#include <vector>
|
||||
|
||||
#include <eepp/graphics/fontfamily.hpp>
|
||||
#include <eepp/graphics/fontmanager.hpp>
|
||||
#include <eepp/graphics/fonttruetype.hpp>
|
||||
#include <eepp/graphics/image.hpp>
|
||||
#include <eepp/graphics/resourcescope.hpp>
|
||||
#include <eepp/network/http.hpp>
|
||||
#include <eepp/network/tcplistener.hpp>
|
||||
#include <eepp/network/tcpsocket.hpp>
|
||||
@@ -65,7 +65,7 @@ UTEST( UIWebView, OwnedDocumentSceneScrollTarget ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -136,7 +136,7 @@ UTEST( UIWebView, DocumentRootHitTestingTraversesScrollableExtent ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -215,7 +215,7 @@ UTEST( UIWebView, FontSizeEmDoesNotCompoundOnViewportRelayout ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -287,7 +287,7 @@ UTEST( UIWebView, FontFaceWeightSurvivesViewportRelayout ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -369,7 +369,7 @@ UTEST( UIWebView, AbsoluteTextareaPercentageHeightDoesNotRecurse ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -436,7 +436,7 @@ UTEST( UIWebView, RedditLoggedOutCommentSignupTextareaDoesNotGrowWithDocument )
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -575,7 +575,7 @@ UTEST( UIWebView, VerticalScrollbarViewportDoesNotCreateHorizontalScroll ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -660,7 +660,7 @@ UTEST( UIWebView, ExplicitWideDocumentStillCreatesHorizontalScroll ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -713,7 +713,7 @@ UTEST( UIWebView, ExplicitWideDocumentHorizontalScrollReachesRightEdgeAtPixelDen
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -777,7 +777,7 @@ UTEST( UIWebView, ResponsiveDocumentShrinksAfterGrowResize ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -867,7 +867,7 @@ UTEST( UIWebView, HorizontalScrollDisappearsAfterResponsiveShrink ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -951,7 +951,7 @@ UTEST( UIWebView, HiddenAndClippedWideDescendantsDoNotCreateHorizontalScroll ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -1019,7 +1019,7 @@ UTEST( UIWebView, VerticalScrollbarDisappearsWithoutViewportWidthOscillation ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -1090,7 +1090,7 @@ UTEST( UIWebView, HackerNewsGrowUntilVerticalScrollbarDisappearsSettlesViewport
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -1147,7 +1147,7 @@ UTEST( UIWebView, HackerNewsFrontPageBottomIsReachable ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -1282,7 +1282,7 @@ UTEST( UIWebView, NavigationAfterGrowDoesNotKeepMaximizedWidthOnShrink ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -1350,7 +1350,7 @@ UTEST( UIWebView, NavigationFromTallToShortShrinksDocumentExtent ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -1414,7 +1414,7 @@ UTEST( UIWebView, AsyncCSSCanShrinkDocumentExtent ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -1470,7 +1470,7 @@ UTEST( UIWebView, FixedPositionStaysPinnedToViewportWhenScrolled ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -1537,7 +1537,7 @@ UTEST( UIWebView, StickyPositionUsesWebViewViewportWhenScrolled ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -1607,7 +1607,7 @@ UTEST( UIWebView, DeferredLocalCSSIgnoredAfterNavigation ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -1686,7 +1686,7 @@ UTEST( UIWebView, RemoteCSSIgnoredAfterNavigation ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -1793,7 +1793,7 @@ UTEST( UIWebView, RemoteImageIgnoredAfterNavigation ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -1903,7 +1903,7 @@ UTEST( UIWebView, RemoteBackgroundImageIgnoredAfterNavigation ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -2025,7 +2025,7 @@ UTEST( UIWebView, LinearGradientRendersToFramebuffer ) {
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
win->setClearColor( Color::Black );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -2101,7 +2101,7 @@ UTEST( UIWebView, CoalescesViewportResizeDocumentMetrics ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -2152,7 +2152,7 @@ UTEST( UIWebView, HackerNewsSingleStepRestoreSettlesViewportInOneFrame ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -2228,7 +2228,7 @@ UTEST( UIWebView, LayoutDrivenResizeKeepsDocumentRootAtViewport ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -2468,7 +2468,7 @@ UTEST( UIWebView, DocumentScenesIsolateStylesUriAndLookup ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -2574,7 +2574,7 @@ UTEST( UIWebView, DocumentScenesIsolateAuthorFontFaces ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -2647,9 +2647,9 @@ UTEST( UIWebView, DocumentScenesIsolateAuthorFontFaces ) {
|
||||
EXPECT_TRUE( fontA->loaded() );
|
||||
EXPECT_TRUE( fontB->loaded() );
|
||||
EXPECT_NE( fontA, fontB );
|
||||
EXPECT_EQ( nullptr, FontManager::instance()->getByName( "SharedDocFace" ) );
|
||||
EXPECT_EQ( nullptr, defaultResourceScope().findFont( "SharedDocFace" ).get() );
|
||||
const std::string fontAResourceName = fontA->getName();
|
||||
EXPECT_EQ( fontA, FontManager::instance()->getByName( fontAResourceName ) );
|
||||
EXPECT_EQ( fontA, docA->getResourceScope()->findFont( fontAResourceName ).get() );
|
||||
|
||||
webViewA->loadURI( URI( "file://" + pathAWithoutFont ) );
|
||||
pump();
|
||||
@@ -2657,7 +2657,7 @@ UTEST( UIWebView, DocumentScenesIsolateAuthorFontFaces ) {
|
||||
auto targetAWithoutFont = docA->getRoot()->find( "target-a-empty" );
|
||||
ASSERT_TRUE( targetAWithoutFont != nullptr );
|
||||
EXPECT_EQ( nullptr, docA->getFontFromNamesList( "SharedDocFace" ) );
|
||||
EXPECT_EQ( nullptr, FontManager::instance()->getByName( fontAResourceName ) );
|
||||
EXPECT_EQ( nullptr, docA->getResourceScope()->findFont( fontAResourceName ).get() );
|
||||
|
||||
webViewA->loadURI( URI( "file://" + pathA2 ) );
|
||||
pump();
|
||||
@@ -2679,7 +2679,7 @@ UTEST( UIWebView, DocumentSceneAuthorFontFacesCleanUpOnDestruction ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -2739,14 +2739,15 @@ UTEST( UIWebView, DocumentSceneAuthorFontFacesCleanUpOnDestruction ) {
|
||||
EXPECT_NE( loadedFontA, loadedFontB );
|
||||
const std::string loadedFontAName = loadedFontA->getName();
|
||||
const std::string loadedFontBName = loadedFontB->getName();
|
||||
EXPECT_EQ( loadedFontA, FontManager::instance()->getByName( loadedFontAName ) );
|
||||
EXPECT_EQ( loadedFontB, FontManager::instance()->getByName( loadedFontBName ) );
|
||||
FontWeakPtr loadedFontAWeak = docA->getResourceScope()->findFont( loadedFontAName );
|
||||
EXPECT_EQ( loadedFontA, docA->getResourceScope()->findFont( loadedFontAName ).get() );
|
||||
EXPECT_EQ( loadedFontB, docB->getResourceScope()->findFont( loadedFontBName ).get() );
|
||||
|
||||
webViewA->close();
|
||||
pump();
|
||||
|
||||
EXPECT_EQ( nullptr, FontManager::instance()->getByName( loadedFontAName ) );
|
||||
EXPECT_EQ( loadedFontB, FontManager::instance()->getByName( loadedFontBName ) );
|
||||
EXPECT_TRUE( loadedFontAWeak.expired() );
|
||||
EXPECT_EQ( loadedFontB, docB->getResourceScope()->findFont( loadedFontBName ).get() );
|
||||
EXPECT_EQ( loadedFontB, docB->getFontFromNamesList( "DestroyDocFace" ) );
|
||||
|
||||
Engine::destroySingleton();
|
||||
@@ -2759,7 +2760,7 @@ UTEST( UIWebView, RemoteFontFaceIgnoredAfterNavigation ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
const std::string fontPath = Sys::getProcessPath() + "../assets/fonts/NotoSans-Regular.ttf";
|
||||
font->loadFromFile( fontPath );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
@@ -2873,7 +2874,7 @@ UTEST( UIWebView, StaleRedirectCookieIgnoredAfterNavigation ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -2965,7 +2966,7 @@ UTEST( UIWebView, DestroyWithPendingSubresourcesIsSafe ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
const std::string fontPath = Sys::getProcessPath() + "../assets/fonts/NotoSans-Regular.ttf";
|
||||
font->loadFromFile( fontPath );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
@@ -3065,7 +3066,7 @@ UTEST( UIWebView, NewerNavigationSupersedesStartedLoad ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -3114,7 +3115,7 @@ UTEST( UIWebView, CacheGenerationAdvancesWhenReplacementDocumentIsInstalled ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
@@ -3194,7 +3195,7 @@ UTEST( UIWebView, RepeatedRemoteNavigationHandlesSubresourceFanOut ) {
|
||||
ContextSettings( false, 0, 0, GLv_default, true, false ) );
|
||||
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" );
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ).get();
|
||||
font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" );
|
||||
ASSERT_TRUE( font != nullptr && font->loaded() );
|
||||
FontFamily::loadFromRegular( font );
|
||||
|
||||
@@ -4261,24 +4261,25 @@ FontTrueType* App::loadFont( const std::string& name, std::string fontPath,
|
||||
}
|
||||
if ( fontPath.empty() )
|
||||
return nullptr;
|
||||
FontTrueType* font = FontTrueType::New( name );
|
||||
ResourceScope& resourceScope = defaultResourceScope();
|
||||
FontTrueTypePtr font = FontTrueType::New( name, resourceScope );
|
||||
if ( font->loadFromFile( fontPath ) ) {
|
||||
font->setHinting( mConfig.ui.fontHinting );
|
||||
font->setAntialiasing( mConfig.ui.fontAntialiasing );
|
||||
return font;
|
||||
return font.get();
|
||||
}
|
||||
eeSAFE_DELETE( font );
|
||||
resourceScope.eraseLocalFont( font.get() );
|
||||
// Failed to load original font? Try to fallback
|
||||
if ( !fallback.empty() && !wasFallback ) {
|
||||
if ( !fontPath.empty() && FileSystem::isRelativePath( fontPath ) )
|
||||
fontPath = mResPath + fontPath;
|
||||
font = FontTrueType::New( name );
|
||||
font = FontTrueType::New( name, resourceScope );
|
||||
if ( font->loadFromFile( fontPath ) ) {
|
||||
font->setHinting( mConfig.ui.fontHinting );
|
||||
font->setAntialiasing( mConfig.ui.fontAntialiasing );
|
||||
return font;
|
||||
return font.get();
|
||||
}
|
||||
eeSAFE_DELETE( font );
|
||||
resourceScope.eraseLocalFont( font.get() );
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -4533,12 +4534,12 @@ void App::init( InitParameters& params ) {
|
||||
|
||||
mFallbackFont = loadFont( "fallback-font", "fonts/DroidSansFallbackFull.ttf" );
|
||||
if ( mFallbackFont )
|
||||
FontManager::instance()->addFallbackFont( mFallbackFont );
|
||||
defaultResourceScope().getFontService().addFallbackFont( mFallbackFont );
|
||||
|
||||
if ( mConfig.ui.fallbackFont != "fonts/DroidSansFallbackFull.ttf" ) {
|
||||
mUserFallbackFont = loadFont( "fallback-font", mConfig.ui.fallbackFont );
|
||||
if ( mUserFallbackFont )
|
||||
FontManager::instance()->addFallbackFont( mUserFallbackFont );
|
||||
defaultResourceScope().getFontService().addFallbackFont( mUserFallbackFont );
|
||||
}
|
||||
|
||||
Log::info( "Fonts loaded in: %s", fontsClock.getElapsedTime().toString() );
|
||||
@@ -4812,7 +4813,6 @@ void App::init( InitParameters& params ) {
|
||||
mAsyncResourcesLoadCond.wait( syntaxLanguagesLock,
|
||||
[this]() { return mAsyncResourcesLoaded; } );
|
||||
}
|
||||
|
||||
if ( !mFont || !mFontMono || !mRemixIconFont || !mNoniconsFont || !mCodIconFont ) {
|
||||
printf( "Font not found!" );
|
||||
Log::error( "Font not found!" );
|
||||
|
||||
@@ -14,7 +14,7 @@ struct MonospaceFontPreview {
|
||||
std::string previewPath;
|
||||
FontTrueType* originalFont{ nullptr };
|
||||
bool confirmed{ false };
|
||||
UnorderedMap<std::string, FontTrueType*> loadedFonts;
|
||||
UnorderedMap<std::string, FontTrueTypePtr> loadedFonts;
|
||||
};
|
||||
|
||||
void FontPickerController::openFontDialog( std::string& fontPath, bool loadingMonoFont,
|
||||
@@ -29,7 +29,8 @@ void FontPickerController::openFontDialog( std::string& fontPath, bool loadingMo
|
||||
return path;
|
||||
};
|
||||
|
||||
const auto applyMonospaceFont = [this, terminalFont]( FontTrueType* fontMono ) {
|
||||
const auto applyMonospaceFont = [this, terminalFont]( FontTrueType* fontMono,
|
||||
bool loadFamily = false ) {
|
||||
if ( !fontMono )
|
||||
return;
|
||||
|
||||
@@ -40,7 +41,10 @@ void FontPickerController::openFontDialog( std::string& fontPath, bool loadingMo
|
||||
|
||||
fontMono->setEnableDynamicMonospace( true );
|
||||
fontMono->setBoldAdvanceSameAsRegular( true );
|
||||
FontFamily::loadFromRegular( fontMono );
|
||||
// Related faces are published by FontFamily. Keep transient previews isolated and only
|
||||
// publish/load their family after the user confirms the selection.
|
||||
if ( loadFamily )
|
||||
FontFamily::loadFromRegular( fontMono );
|
||||
|
||||
if ( !mApp->getSplitter() )
|
||||
return;
|
||||
@@ -75,21 +79,30 @@ void FontPickerController::openFontDialog( std::string& fontPath, bool loadingMo
|
||||
: mApp->getFontMono() );
|
||||
}
|
||||
|
||||
const auto loadPreviewFont = [this, preview]( const std::string& newPath ) -> FontTrueType* {
|
||||
const auto loadPreviewFont = [this, preview]( const FontDesc& desc ) -> FontTrueTypePtr {
|
||||
if ( !preview )
|
||||
return nullptr;
|
||||
return {};
|
||||
|
||||
auto found = preview->loadedFonts.find( newPath );
|
||||
auto found = preview->loadedFonts.find( desc.path );
|
||||
if ( found != preview->loadedFonts.end() )
|
||||
return found->second;
|
||||
|
||||
auto fontName = FileSystem::fileRemoveExtension( FileSystem::fileNameFromPath( newPath ) );
|
||||
FontTrueType* fontMono = mApp->loadFont( fontName, newPath );
|
||||
if ( fontMono )
|
||||
preview->loadedFonts[newPath] = fontMono;
|
||||
FontTrueTypePtr fontMono = defaultResourceScope().getFontService().loadSystemFont( desc );
|
||||
if ( fontMono ) {
|
||||
fontMono->setHinting( mApp->getConfig().ui.fontHinting );
|
||||
fontMono->setAntialiasing( mApp->getConfig().ui.fontAntialiasing );
|
||||
preview->loadedFonts[desc.path] = fontMono;
|
||||
}
|
||||
return fontMono;
|
||||
};
|
||||
|
||||
const auto publishPreviewFont = []( const std::string& path, const FontTrueTypePtr& font ) {
|
||||
if ( !font )
|
||||
return;
|
||||
auto fontName = FileSystem::fileRemoveExtension( FileSystem::fileNameFromPath( path ) );
|
||||
defaultResourceScope().publishLocalFont( std::move( fontName ), font );
|
||||
};
|
||||
|
||||
const Uint32 flags = UIFontPickerDialog::DefaultFlags |
|
||||
( loadingMonoFont ? UIFontPickerDialog::MonospaceOnly : 0 );
|
||||
UIFontPickerDialog* dialog = UIFontPickerDialog::New( flags );
|
||||
@@ -97,7 +110,7 @@ void FontPickerController::openFontDialog( std::string& fontPath, bool loadingMo
|
||||
dialog->setCloseShortcut( KEY_ESCAPE );
|
||||
dialog->on( Event::OnWindowClose, [this, preview, applyMonospaceFont]( const Event* ) {
|
||||
if ( preview && !preview->confirmed )
|
||||
applyMonospaceFont( preview->originalFont );
|
||||
applyMonospaceFont( preview->originalFont, false );
|
||||
|
||||
if ( App::instance() && mApp->getSplitter() && mApp->getSplitter()->getCurWidget() &&
|
||||
!SceneManager::instance()->isShuttingDown() ) {
|
||||
@@ -113,20 +126,20 @@ void FontPickerController::openFontDialog( std::string& fontPath, bool loadingMo
|
||||
return;
|
||||
|
||||
if ( newPath == preview->originalPath ) {
|
||||
applyMonospaceFont( preview->originalFont );
|
||||
applyMonospaceFont( preview->originalFont, false );
|
||||
preview->previewPath = newPath;
|
||||
return;
|
||||
}
|
||||
|
||||
FontTrueType* fontMono = loadPreviewFont( newPath );
|
||||
FontTrueTypePtr fontMono = loadPreviewFont( selection.font );
|
||||
if ( fontMono ) {
|
||||
applyMonospaceFont( fontMono );
|
||||
applyMonospaceFont( fontMono.get(), false );
|
||||
preview->previewPath = newPath;
|
||||
}
|
||||
} );
|
||||
}
|
||||
dialog->setOnFontPicked( [&fontPath, loadingMonoFont, onFinish, preview, normalizedFontPath,
|
||||
loadPreviewFont,
|
||||
loadPreviewFont, publishPreviewFont,
|
||||
applyMonospaceFont]( const UIFontSelection& selection ) {
|
||||
auto newPath = normalizedFontPath( selection.font.path );
|
||||
if ( newPath.empty() )
|
||||
@@ -139,18 +152,20 @@ void FontPickerController::openFontDialog( std::string& fontPath, bool loadingMo
|
||||
return;
|
||||
}
|
||||
|
||||
FontTrueType* fontMono = preview && newPath == preview->originalPath
|
||||
? preview->originalFont
|
||||
: loadPreviewFont( newPath );
|
||||
FontTrueTypePtr previewFont = preview && newPath != preview->originalPath
|
||||
? loadPreviewFont( selection.font )
|
||||
: FontTrueTypePtr{};
|
||||
FontTrueType* fontMono = previewFont ? previewFont.get() : preview->originalFont;
|
||||
if ( fontMono ) {
|
||||
fontPath = newPath;
|
||||
if ( preview )
|
||||
preview->confirmed = true;
|
||||
applyMonospaceFont( fontMono );
|
||||
publishPreviewFont( newPath, previewFont );
|
||||
applyMonospaceFont( fontMono, previewFont != nullptr );
|
||||
}
|
||||
} else if ( preview ) {
|
||||
preview->confirmed = true;
|
||||
applyMonospaceFont( preview->originalFont );
|
||||
applyMonospaceFont( preview->originalFont, false );
|
||||
}
|
||||
} );
|
||||
dialog->setSelectedFont( absoluteFontPath );
|
||||
|
||||
@@ -3163,7 +3163,7 @@ UIMenu* SettingsMenu::createFontHintMenu() {
|
||||
if ( String::startsWith( id, "hint_" ) ) {
|
||||
auto hint = id.substr( 5 ).toUtf8();
|
||||
mApp->getConfig().ui.fontHinting = FontTrueType::fontHintingFromString( hint );
|
||||
FontManager::instance()->setHinting( mApp->getConfig().ui.fontHinting );
|
||||
defaultResourceScope().getFontService().setHinting( mApp->getConfig().ui.fontHinting );
|
||||
}
|
||||
} );
|
||||
|
||||
@@ -3204,7 +3204,8 @@ UIMenu* SettingsMenu::createFontAntiAliasingMenu() {
|
||||
auto hint = id.substr( 3 ).toUtf8();
|
||||
mApp->getConfig().ui.fontAntialiasing =
|
||||
FontTrueType::fontAntialiasingFromString( hint );
|
||||
FontManager::instance()->setAntialiasing( mApp->getConfig().ui.fontAntialiasing );
|
||||
defaultResourceScope().getFontService().setAntialiasing(
|
||||
mApp->getConfig().ui.fontAntialiasing );
|
||||
}
|
||||
} );
|
||||
|
||||
|
||||
@@ -276,7 +276,7 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) {
|
||||
FontTrueType* fontMono = nullptr;
|
||||
if ( fontPath && FileSystem::fileExists( fontPath.Get() ) ) {
|
||||
FileInfo file( fontPath.Get() );
|
||||
fontMono = FontTrueType::New( "monospace" );
|
||||
fontMono = FontTrueType::New( "monospace" ).get();
|
||||
if ( fontMono->loadFromFile( file.getFilepath() ) ) {
|
||||
FontFamily::loadFromRegular( fontMono );
|
||||
} else {
|
||||
@@ -284,7 +284,7 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) {
|
||||
}
|
||||
}
|
||||
if ( fontMono == nullptr ) {
|
||||
fontMono = FontTrueType::New( "monospace" );
|
||||
fontMono = FontTrueType::New( "monospace" ).get();
|
||||
fontMono->loadFromFile( resPath + "fonts/DejaVuSansMonoNerdFontComplete.ttf" );
|
||||
FontFamily::loadFromRegular( fontMono, "DejaVuSansMono" );
|
||||
}
|
||||
@@ -301,9 +301,9 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) {
|
||||
? fallbackFontPathF.Get()
|
||||
: resPath + "fonts/DroidSansFallbackFull.ttf" );
|
||||
if ( FileSystem::fileExists( fallbackFontPath ) ) {
|
||||
FontTrueType* fallbackFont = FontTrueType::New( "fallback-font" );
|
||||
FontTrueType* fallbackFont = FontTrueType::New( "fallback-font" ).get();
|
||||
if ( fallbackFont->loadFromFile( fallbackFontPath ) )
|
||||
FontManager::instance()->addFallbackFont( fallbackFont );
|
||||
defaultResourceScope().getFontService().addFallbackFont( fallbackFont );
|
||||
}
|
||||
|
||||
Float realMaxFPS = maxFPS.Get() ? maxFPS.Get() : currentDisplay->getRefreshRate();
|
||||
|
||||
@@ -105,11 +105,12 @@ EE_MAIN_FUNC int main( int, char*[] ) {
|
||||
else if ( PixelDensity::getPixelDensity() >= 2.f )
|
||||
pd = "2x";
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular",
|
||||
resPath + "assets/fonts/NotoSans-Regular.ttf" );
|
||||
FontTrueTypePtr font = FontTrueType::New( "NotoSans-Regular",
|
||||
resPath + "assets/fonts/NotoSans-Regular.ttf",
|
||||
*uiSceneNode->getResourceScope() );
|
||||
|
||||
UITheme* theme = UITheme::load( "uitheme" + pd, "uitheme" + pd,
|
||||
resPath + "assets/ui/uitheme" + pd + ".eta", font,
|
||||
resPath + "assets/ui/uitheme" + pd + ".eta", font.get(),
|
||||
resPath + "assets/ui/uitheme.css" );
|
||||
|
||||
/*UITheme* theme =
|
||||
@@ -120,7 +121,7 @@ EE_MAIN_FUNC int main( int, char*[] ) {
|
||||
uiSceneNode->getUIThemeManager()
|
||||
->setDefaultEffectsEnabled( true )
|
||||
->setDefaultTheme( theme )
|
||||
->setDefaultFont( font )
|
||||
->setDefaultFont( font.get() )
|
||||
->add( theme );
|
||||
}
|
||||
|
||||
|
||||
@@ -109,21 +109,22 @@ EE_MAIN_FUNC int main( int, char*[] ) {
|
||||
else if ( PixelDensity::getPixelDensity() >= 2.f )
|
||||
pd = "2x";
|
||||
|
||||
FontTrueType* font = FontTrueType::New( "NotoSans-Regular",
|
||||
resPath + "assets/fonts/NotoSans-Regular.ttf" );
|
||||
FontTrueTypePtr font = FontTrueType::New( "NotoSans-Regular",
|
||||
resPath + "assets/fonts/NotoSans-Regular.ttf",
|
||||
*uiSceneNode->getResourceScope() );
|
||||
|
||||
/*UITheme* theme = UITheme::load( "uitheme" + pd, "uitheme" + pd, resPath +
|
||||
* "assets/ui/uitheme" + pd + ".eta", font, resPath + "assets/ui/uitheme.css" );*/
|
||||
|
||||
UITheme* theme =
|
||||
UITheme::load( "uitheme", "uitheme", "", font, resPath + "assets/ui/breeze.css" );
|
||||
UITheme* theme = UITheme::load( "uitheme", "uitheme", "", font.get(),
|
||||
resPath + "assets/ui/breeze.css" );
|
||||
|
||||
uiSceneNode->combineStyleSheet( theme->getStyleSheet() );
|
||||
|
||||
uiSceneNode->getUIThemeManager()
|
||||
->setDefaultEffectsEnabled( true )
|
||||
->setDefaultTheme( theme )
|
||||
->setDefaultFont( font )
|
||||
->setDefaultFont( font.get() )
|
||||
->add( theme );
|
||||
}
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ void App::unloadImages() {
|
||||
|
||||
void App::unloadFonts() {
|
||||
for ( auto it = mFontsLoaded.begin(); it != mFontsLoaded.end(); ++it )
|
||||
FontManager::instance()->remove( it->first );
|
||||
mUISceneNode->getResourceScope()->eraseLocalFont( it->first.get() );
|
||||
mFontsLoaded.clear();
|
||||
}
|
||||
|
||||
@@ -168,7 +168,9 @@ FontTrueType* App::loadFont( const std::string& name, std::string fontPath,
|
||||
}
|
||||
if ( fontPath.empty() )
|
||||
return nullptr;
|
||||
return FontTrueType::New( name, fontPath );
|
||||
FontTrueTypePtr font = FontTrueType::New( name, fontPath, *mUISceneNode->getResourceScope() );
|
||||
mFontsLoaded[font] = name;
|
||||
return font.get();
|
||||
}
|
||||
|
||||
void App::createWidgetInspector() {
|
||||
@@ -179,7 +181,7 @@ void App::createWidgetInspector() {
|
||||
|
||||
void App::loadFont( std::string path ) {
|
||||
std::string filename( FileSystem::fileRemoveExtension( FileSystem::fileNameFromPath( path ) ) );
|
||||
FontTrueType* font = FontTrueType::New( filename );
|
||||
FontTrueTypePtr font = FontTrueType::New( filename, *mUISceneNode->getResourceScope() );
|
||||
font->loadFromFile( path );
|
||||
mFontsLoaded[font] = filename;
|
||||
}
|
||||
@@ -614,7 +616,7 @@ void App::onLayoutSelected( const Event* event ) {
|
||||
UIMenuCheckBox* chk = static_cast<UIMenuCheckBox*>( event->getNode() );
|
||||
chk->setActive( true );
|
||||
|
||||
std::map<std::string, std::string>::iterator it;
|
||||
UnorderedMap<std::string, std::string>::iterator it;
|
||||
|
||||
if ( ( it = mLayouts.find( txt.toUtf8() ) ) != mLayouts.end() )
|
||||
loadLayout( it->second );
|
||||
@@ -1271,16 +1273,16 @@ void App::init( const Float& pixelDensityConf, const bool& useAppTheme, const st
|
||||
mResPath += "assets";
|
||||
FileSystem::dirAddSlashAtEnd( mResPath );
|
||||
|
||||
FontTrueType* font =
|
||||
FontTrueTypePtr font =
|
||||
FontTrueType::New( "NotoSans-Regular", mResPath + "fonts/NotoSans-Regular.ttf" );
|
||||
FontTrueType* fontMono =
|
||||
FontTrueTypePtr fontMono =
|
||||
FontTrueType::New( "monospace", mResPath + "fonts/DejaVuSansMono.ttf" );
|
||||
|
||||
FontFamily::loadFromRegular( font );
|
||||
FontFamily::loadFromRegular( fontMono );
|
||||
FontFamily::loadFromRegular( font.get() );
|
||||
FontFamily::loadFromRegular( fontMono.get() );
|
||||
|
||||
mBaseStyleSheet = mResPath + "ui/breeze.css";
|
||||
mTheme = UITheme::load( "uitheme", "uitheme", "", font, mBaseStyleSheet );
|
||||
mTheme = UITheme::load( "uitheme", "uitheme", "", font.get(), mBaseStyleSheet );
|
||||
|
||||
mUISceneNode = UISceneNode::New();
|
||||
mUISceneNode->setId( "uiSceneNode" );
|
||||
@@ -1311,10 +1313,12 @@ void App::init( const Float& pixelDensityConf, const bool& useAppTheme, const st
|
||||
mAppUISceneNode->getUIThemeManager()
|
||||
->setDefaultEffectsEnabled( true )
|
||||
->setDefaultTheme( mTheme )
|
||||
->setDefaultFont( font )
|
||||
->setDefaultFont( font.get() )
|
||||
->add( mTheme );
|
||||
|
||||
mUISceneNode->getUIThemeManager()->setDefaultFont( font )->setDefaultEffectsEnabled( true );
|
||||
mUISceneNode->getUIThemeManager()
|
||||
->setDefaultFont( font.get() )
|
||||
->setDefaultEffectsEnabled( true );
|
||||
|
||||
mAppUISceneNode->getUIIconThemeManager()->setCurrentTheme( iconTheme );
|
||||
|
||||
|
||||
@@ -184,18 +184,18 @@ class App : public UICodeEditorSplitter::Client {
|
||||
efsw::WatchID mWatch{ 0 };
|
||||
efsw::WatchID mStyleSheetWatch{ 0 };
|
||||
efsw::WatchID mBaseStyleSheetWatch{ 0 };
|
||||
std::map<std::string, std::string> mWidgetRegistered;
|
||||
UnorderedMap<std::string, std::string> mWidgetRegistered;
|
||||
std::string mResPath;
|
||||
std::string mBasePath;
|
||||
UIConsole* mConsole{ nullptr };
|
||||
std::map<std::string, std::string> mLayouts;
|
||||
UnorderedMap<std::string, std::string> mLayouts;
|
||||
std::vector<std::string> mRecentProjects;
|
||||
std::vector<std::string> mRecentFiles;
|
||||
IniFile mIni;
|
||||
Uint32 mRecentProjectEventClickId{ 0xFFFFFFFF };
|
||||
Uint32 mRecentFilesEventClickId{ 0xFFFFFFFF };
|
||||
std::map<ResourceId, TextureRegionPtr> mImagesLoaded;
|
||||
std::map<Font*, std::string> mFontsLoaded;
|
||||
UnorderedMap<ResourceId, TextureRegionPtr> mImagesLoaded;
|
||||
UnorderedMap<FontPtr, std::string> mFontsLoaded;
|
||||
UpdateListener* mListener{ nullptr };
|
||||
std::string mConfigPath;
|
||||
std::string mColorSchemesPath;
|
||||
|
||||
Reference in New Issue
Block a user