Browse Source

Load debugger font from memory.

Michael Ragazzon 6 years ago
parent
commit
7b67c88967

+ 6 - 3
Include/RmlUi/Core/Core.h

@@ -123,9 +123,12 @@ RMLUICORE_API void SetFileInterface(FileInterface* file_interface);
 /// Returns RmlUi's file interface.
 RMLUICORE_API FileInterface* GetFileInterface();
 
-// Sets the interface through which all font requests are made.
-RMLUICORE_API void SetFontEngineInterface(FontEngineInterface* _font_interface);
-// Returns RmlUi's file interface.
+/// Sets the interface through which all font requests are made. This is not required to be called, but if it is
+/// it must be called before Initialise().
+/// @param[in] font_interface A non-owning pointer to the application-specified font engine interface.
+/// @lifetime The interface must be kept alive until after the call to Core::Shutdown.
+RMLUICORE_API void SetFontEngineInterface(FontEngineInterface* font_interface);
+/// Returns RmlUi's font interface.
 RMLUICORE_API FontEngineInterface* GetFontEngineInterface();
 	
 /// Creates a new element context.

+ 10 - 0
Include/RmlUi/Core/FontEngineInterface.h

@@ -47,6 +47,16 @@ public:
 	/// @return True if the face was loaded successfully, false otherwise.
 	virtual bool LoadFontFace(const String& file_name, bool fallback_face = false);
 
+	/// Called by the RmlUi when it wants to load a font face from memory, registered using the provided family, style, and weight.
+	/// @param[in] data A pointer to the data.
+	/// @param[in] data_size Size of the data in bytes.
+	/// @param[in] family The family to register the font as.
+	/// @param[in] style The style to register the font as.
+	/// @param[in] weight The weight to register the font as.
+	/// @return True if the face was loaded successfully, false otherwise.
+	/// Note: The debugger plugin will load its embedded font faces through this method using the family name 'rmlui-debugger-font'.
+	virtual bool LoadFontFace(const byte* data, int data_size, const String& family, Style::FontStyle style, Style::FontWeight weight, bool fallback_face = false);
+
 	/// Called by the RmlUi when a font configuration is resolved for an element. Should return a handle that 
 	/// can later be used to resolve properties of the face, and generate strings which can later be rendered.
 	/// @param[in] family The family of the desired font handle.

+ 5 - 0
Source/Core/FontDatabaseDefault.cpp

@@ -82,6 +82,11 @@ bool FontDatabaseDefault::LoadFontFace(const String& file_name, bool fallback_fa
 	return FontProvider_FreeType::LoadFontFace(file_name, fallback_face);
 }
 
+bool FontDatabaseDefault::LoadFontFace(const byte* data, int data_size, const String& font_family, Style::FontStyle style, Style::FontWeight weight, bool fallback_face)
+{
+	return FontProvider_FreeType::LoadFontFace(data, data_size, font_family, style, weight, fallback_face);
+}
+
 // Returns a handle to a font face that can be used to position and render text.
 SharedPtr<FontFaceHandleDefault> FontDatabaseDefault::GetFontFaceHandle(const String& family, Style::FontStyle style, Style::FontWeight weight, int size)
 {

+ 3 - 0
Source/Core/FontDatabaseDefault.h

@@ -61,6 +61,9 @@ public:
 	/// @return True if the face was loaded successfully, false otherwise.
 	static bool LoadFontFace(const String& file_name, bool fallback_face);
 
+	/// Adds a new font face from memory.
+	static bool LoadFontFace(const byte* data, int data_size, const String& font_family, Style::FontStyle style, Style::FontWeight weight, bool fallback_face);
+
 	/// Returns a handle to a font face that can be used to position and render text. This will return the closest match
 	/// it can find, but in the event a font family is requested that does not exist, nullptr will be returned instead of a
 	/// valid handle.

+ 5 - 0
Source/Core/FontEngineInterface.cpp

@@ -44,6 +44,11 @@ bool FontEngineInterface::LoadFontFace(const String& file_name, bool fallback_fa
 	return false;
 }
 
+bool FontEngineInterface::LoadFontFace(const byte* data, int data_size, const String& font_family, Style::FontStyle style, Style::FontWeight weight, bool fallback_face)
+{
+	return false;
+}
+
 FontFaceHandle FontEngineInterface::GetFontFaceHandle(const String& RMLUI_UNUSED_PARAMETER(family), Style::FontStyle RMLUI_UNUSED_PARAMETER(style),
 	Style::FontWeight RMLUI_UNUSED_PARAMETER(weight), int RMLUI_UNUSED_PARAMETER(size))
 {

+ 5 - 0
Source/Core/FontEngineInterfaceDefault.cpp

@@ -51,6 +51,11 @@ bool FontEngineInterfaceDefault::LoadFontFace(const String& file_name, bool fall
 	return FontDatabaseDefault::LoadFontFace(file_name, fallback_face);
 }
 
+bool FontEngineInterfaceDefault::LoadFontFace(const byte* data, int data_size, const String& font_family, Style::FontStyle style, Style::FontWeight weight, bool fallback_face)
+{
+	return FontDatabaseDefault::LoadFontFace(data, data_size, font_family, style, weight, fallback_face);
+}
+
 FontFaceHandle FontEngineInterfaceDefault::GetFontFaceHandle(const String& family, Style::FontStyle style, Style::FontWeight weight, int size)
 {
 	auto handle = FontDatabaseDefault::GetFontFaceHandle(family, style, weight, size);

+ 3 - 0
Source/Core/FontEngineInterfaceDefault.h

@@ -42,6 +42,9 @@ public:
 	/// Adds a new font face to the database. The face's family, style and weight will be determined from the face itself.
 	bool LoadFontFace(const String& file_name, bool fallback_face) override;
 
+	/// Adds a new font face to the database using the provided family, style and weight.
+	bool LoadFontFace(const byte* data, int data_size, const String& font_family, Style::FontStyle style, Style::FontWeight weight, bool fallback_face) override;
+
 	/// Returns a handle to a font face that can be used to position and render text. This will return the closest match
 	/// it can find, but in the event a font family is requested that does not exist, NULL will be returned instead of a
 	/// valid handle.

+ 3 - 11
Source/Core/FontProvider.cpp

@@ -35,24 +35,16 @@ namespace Core {
 
 #ifndef RMLUI_NO_FONT_INTERFACE_DEFAULT
 
-const String FontProvider::debugger_font_family_name = "rmlui-debugger-font";
-
 // Returns a handle to a font face that can be used to position and render text.
 SharedPtr<FontFaceHandleDefault> FontProvider::GetFontFaceHandle(const String& family, Style::FontStyle style, Style::FontWeight weight, int size)
 {
 	RMLUI_ASSERTMSG(family == StringUtilities::ToLower(family), "Font family name must be converted to lowercase before entering here.");
 
-	FontFamilyMap::iterator iterator;
-
-	if (family == debugger_font_family_name)
-		iterator = font_families.begin();
-	else
-		iterator = font_families.find(family);
-
-	if (iterator == font_families.end())
+	auto it = font_families.find(family);
+	if (it == font_families.end())
 		return nullptr;
 
-	return (*iterator).second->GetFaceHandle(style, weight, size);
+	return it->second->GetFaceHandle(style, weight, size);
 }
 
 const FontFaceList& FontProvider::GetFallbackFontFaces() const

+ 21 - 0
Source/Core/FreeType/FontProvider.cpp

@@ -118,6 +118,27 @@ bool FontProvider_FreeType::LoadFontFace(const String& file_name, bool fallback_
 	return true;
 }
 
+bool FontProvider_FreeType::LoadFontFace(const byte* data, int data_size, const String& font_family, Style::FontStyle style, Style::FontWeight weight, bool fallback_face)
+{
+	const String source = "memory";
+
+	FT_Face ft_face = (FT_Face)instance->LoadFace(data, data_size, source, false);
+	if (ft_face == nullptr)
+	{
+		Log::Message(Log::LT_ERROR, "Failed to load font face %s from memory.", font_family.c_str());
+		return false;
+	}
+
+	if (!instance->AddFace(ft_face, font_family, style, weight, fallback_face, false))
+	{
+		Log::Message(Log::LT_ERROR, "Failed to load font face %s %s (from memory).", ft_face->family_name, ft_face->style_name);
+		return false;
+	}
+
+	Log::Message(Log::LT_INFO, "Loaded font face %s %s (from memory).", ft_face->family_name, ft_face->style_name);
+	return true;
+}
+
 // Adds a loaded face to the appropriate font family.
 bool FontProvider_FreeType::AddFace(void* face, const String& family, Style::FontStyle style, Style::FontWeight weight, bool fallback_face, bool release_stream)
 {

+ 3 - 0
Source/Core/FreeType/FontProvider.h

@@ -53,6 +53,9 @@ public:
 	/// @return True if the face was loaded successfully, false otherwise.
 	static bool LoadFontFace(const String& file_name, bool fallback_face);
 
+	/// Adds a new font face from memory.
+	static bool LoadFontFace(const byte* data, int data_size, const String& font_family, Style::FontStyle style, Style::FontWeight weight, bool fallback_face);
+
 private:
 	FontProvider_FreeType(void);
 	~FontProvider_FreeType(void);

+ 14 - 0
Source/Debugger/Plugin.cpp

@@ -72,6 +72,12 @@ bool Plugin::Initialise(Core::Context* context)
 	host_context = context;
 	Geometry::SetContext(context);
 
+	if (!LoadFont())
+	{
+		Core::Log::Message(Core::Log::LT_ERROR, "Failed to initialise debugger, unable to load font.");
+		return false;
+	}
+
 	if (!LoadMenuElement() ||
 		!LoadInfoElement() ||
 		!LoadLogElement())
@@ -269,6 +275,14 @@ Plugin* Plugin::GetInstance()
 	return instance;
 }
 
+bool Plugin::LoadFont()
+{
+	const Core::String font_family_name = "rmlui-debugger-font";
+
+	return (Core::GetFontEngineInterface()->LoadFontFace(lacuna_regular, sizeof(lacuna_regular) / sizeof(unsigned char), font_family_name, Core::Style::FontStyle::Normal, Core::Style::FontWeight::Normal) &&
+	        Core::GetFontEngineInterface()->LoadFontFace(lacuna_italic, sizeof(lacuna_italic) / sizeof(unsigned char), font_family_name, Core::Style::FontStyle::Italic, Core::Style::FontWeight::Normal));
+}
+
 bool Plugin::LoadMenuElement()
 {
 	menu_element = host_context->CreateDocument();

+ 1 - 0
Source/Debugger/Plugin.h

@@ -100,6 +100,7 @@ public:
 	static Plugin* GetInstance();
 
 private:
+	bool LoadFont();
 	bool LoadMenuElement();
 	bool LoadInfoElement();
 	bool LoadLogElement();