Skip to content

Commit

Permalink
Add the ability to select a font face from a font collection.
Browse files Browse the repository at this point in the history
  • Loading branch information
leduyquang753 committed Jan 13, 2025
1 parent f3d0d49 commit 51ad585
Show file tree
Hide file tree
Showing 21 changed files with 66 additions and 59 deletions.
6 changes: 4 additions & 2 deletions Include/RmlUi/Core/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,21 +131,23 @@ RMLUICORE_API int GetNumContexts();
/// Adds a new font face to the font engine. The face's family, style and weight will be determined from the face itself.
/// @param[in] file_path The path to the file to load the face from. The path is passed directly to the file interface which is used to load the file.
/// The default file interface accepts both absolute paths and paths relative to the working directory.
/// @param[in] face_index The index of the font face within a font collection.
/// @param[in] fallback_face True to use this font face for unknown characters in other font faces.
/// @param[in] weight The weight to load when the font face contains multiple weights, otherwise the weight to register the font as. By default, it
/// loads all found font weights.
/// @return True if the face was loaded successfully, false otherwise.
RMLUICORE_API bool LoadFontFace(const String& file_path, bool fallback_face = false, Style::FontWeight weight = Style::FontWeight::Auto);
RMLUICORE_API bool LoadFontFace(const String& file_path, int face_index = 0, bool fallback_face = false, Style::FontWeight weight = Style::FontWeight::Auto);
/// Adds a new font face from memory to the font engine. The face's family, style and weight is given by the parameters.
/// @param[in] data The font data.
/// @param[in] face_index The index of the font face within a font collection.
/// @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 load when the font face contains multiple weights, otherwise the weight to register the font as. By default, it
/// loads all found font weights.
/// @param[in] fallback_face True to use this font face for unknown characters in other font faces.
/// @return True if the face was loaded successfully, false otherwise.
/// @lifetime The pointed to 'data' must remain available until after the call to Rml::Shutdown.
RMLUICORE_API bool LoadFontFace(Span<const byte> data, const String& family, Style::FontStyle style,
RMLUICORE_API bool LoadFontFace(Span<const byte> data, int face_index, const String& family, Style::FontStyle style,
Style::FontWeight weight = Style::FontWeight::Auto, bool fallback_face = false);

/// Registers a generic RmlUi plugin.
Expand Down
8 changes: 5 additions & 3 deletions Include/RmlUi/Core/FontEngineInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,22 @@ class RMLUICORE_API FontEngineInterface {

/// Called by RmlUi when it wants to load a font face from file.
/// @param[in] file_name The file to load the face from.
/// @param[in] face_index The index of the font face within a font collection.
/// @param[in] fallback_face True to use this font face for unknown characters in other font faces.
/// @param[in] weight The weight to load when the font face contains multiple weights, otherwise the weight to register the font as.
/// @return True if the face was loaded successfully, false otherwise.
virtual bool LoadFontFace(const String& file_name, bool fallback_face, Style::FontWeight weight);
virtual bool LoadFontFace(const String& file_name, int face_index, bool fallback_face, Style::FontWeight weight);

/// Called by RmlUi when it wants to load a font face from memory, registered using the provided family, style, and weight.
/// @param[in] data The font data.
/// @param[in] face_index The index of the font face within a font collection.
/// @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 load when the font face contains multiple weights, otherwise the weight to register the font as.
/// @param[in] fallback_face True to use this font face for unknown characters in other font faces.
/// @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(Span<const byte> data, const String& family, Style::FontStyle style, Style::FontWeight weight, bool fallback_face);
virtual bool LoadFontFace(Span<const byte> data, int face_index, const String& family, Style::FontStyle style, Style::FontWeight weight, bool fallback_face);

/// Called by 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 string geometry to be rendered.
Expand Down Expand Up @@ -118,7 +120,7 @@ class RMLUICORE_API FontEngineInterface {

/// Called by RmlUi to determine if the text geometry is required to be re-generated. Whenever the returned version
/// is changed, all geometry belonging to the given face handle will be re-generated.
/// @param[in] handle The font handle.
/// @param[in] face_handle The font handle.
/// @return The version required for using any geometry generated with the face handle.
virtual int GetVersion(FontFaceHandle handle);

Expand Down
4 changes: 2 additions & 2 deletions Samples/basic/bitmap_font/src/FontEngineInterfaceBitmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ void FontEngineInterfaceBitmap::Shutdown()
FontProviderBitmap::Shutdown();
}

bool FontEngineInterfaceBitmap::LoadFontFace(const String& file_name, bool /*fallback_face*/, FontWeight /*weight*/)
bool FontEngineInterfaceBitmap::LoadFontFace(const String& file_name, int /*face_index*/, bool /*fallback_face*/, FontWeight /*weight*/)
{
return FontProviderBitmap::LoadFontFace(file_name);
}

bool FontEngineInterfaceBitmap::LoadFontFace(Span<const byte> /*data*/, const String& font_family, FontStyle /*style*/, FontWeight /*weight*/,
bool FontEngineInterfaceBitmap::LoadFontFace(Span<const byte> /*data*/, int /*face_index*/, const String& font_family, FontStyle /*style*/, FontWeight /*weight*/,
bool /*fallback_face*/)
{
// We return 'true' here to allow the debugger to continue loading, but we will use our own fonts when it asks for a handle.
Expand Down
4 changes: 2 additions & 2 deletions Samples/basic/bitmap_font/src/FontEngineInterfaceBitmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ class FontEngineInterfaceBitmap : public Rml::FontEngineInterface {
void Shutdown() override;

/// Called by RmlUi when it wants to load a font face from file.
bool LoadFontFace(const String& file_name, bool fallback_face, FontWeight weight) override;
bool LoadFontFace(const String& file_name, int face_index, bool fallback_face, FontWeight weight) override;

/// Called by 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.
bool LoadFontFace(Span<const byte> data, const String& family, FontStyle style, FontWeight weight, bool fallback_face) override;
bool LoadFontFace(Span<const byte> data, int face_index, const String& family, FontStyle style, FontWeight weight, bool fallback_face) override;

/// Called by 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 string geometry to be rendered.
Expand Down
8 changes: 4 additions & 4 deletions Samples/basic/harfbuzz/src/FontEngineInterfaceHarfBuzz.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ void FontEngineInterfaceHarfBuzz::Shutdown()
FontProvider::Shutdown();
}

bool FontEngineInterfaceHarfBuzz::LoadFontFace(const String& file_name, bool fallback_face, Style::FontWeight weight)
bool FontEngineInterfaceHarfBuzz::LoadFontFace(const String& file_name, int face_index, bool fallback_face, Style::FontWeight weight)
{
return FontProvider::LoadFontFace(file_name, fallback_face, weight);
return FontProvider::LoadFontFace(file_name, face_index, fallback_face, weight);
}

bool FontEngineInterfaceHarfBuzz::LoadFontFace(Span<const byte> data, const String& font_family, Style::FontStyle style, Style::FontWeight weight,
bool FontEngineInterfaceHarfBuzz::LoadFontFace(Span<const byte> data, int face_index, const String& font_family, Style::FontStyle style, Style::FontWeight weight,
bool fallback_face)
{
return FontProvider::LoadFontFace(data, font_family, style, weight, fallback_face);
return FontProvider::LoadFontFace(data, face_index, font_family, style, weight, fallback_face);
}

FontFaceHandle FontEngineInterfaceHarfBuzz::GetFontFaceHandle(const String& family, Style::FontStyle style, Style::FontWeight weight, int size)
Expand Down
4 changes: 2 additions & 2 deletions Samples/basic/harfbuzz/src/FontEngineInterfaceHarfBuzz.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ class FontEngineInterfaceHarfBuzz : public Rml::FontEngineInterface {
void Shutdown() override;

/// 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, Style::FontWeight weight) override;
bool LoadFontFace(const String& file_name, int face_index, bool fallback_face, Style::FontWeight weight) override;

/// Adds a new font face to the database using the provided family, style and weight.
bool LoadFontFace(Span<const byte> data, const String& font_family, Style::FontStyle style, Style::FontWeight weight,
bool LoadFontFace(Span<const byte> data, int face_index, 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
Expand Down
14 changes: 7 additions & 7 deletions Samples/basic/harfbuzz/src/FontProvider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ void FontProvider::ReleaseFontResources()
name_family.second->ReleaseFontResources();
}

bool FontProvider::LoadFontFace(const String& file_name, bool fallback_face, Style::FontWeight weight)
bool FontProvider::LoadFontFace(const String& file_name, int face_index, bool fallback_face, Style::FontWeight weight)
{
Rml::FileInterface* file_interface = Rml::GetFileInterface();
Rml::FileHandle handle = file_interface->Open(file_name);
Expand All @@ -122,28 +122,28 @@ bool FontProvider::LoadFontFace(const String& file_name, bool fallback_face, Sty
file_interface->Read(buffer, length, handle);
file_interface->Close(handle);

bool result = Get().LoadFontFace({buffer, length}, fallback_face, std::move(buffer_ptr), file_name, {}, Style::FontStyle::Normal, weight);
bool result = Get().LoadFontFace({buffer, length}, face_index, fallback_face, std::move(buffer_ptr), file_name, {}, Style::FontStyle::Normal, weight);

return result;
}

bool FontProvider::LoadFontFace(Span<const byte> data, const String& font_family, Style::FontStyle style, Style::FontWeight weight,
bool FontProvider::LoadFontFace(Span<const byte> data, int face_index, const String& font_family, Style::FontStyle style, Style::FontWeight weight,
bool fallback_face)
{
const String source = "memory";

bool result = Get().LoadFontFace(data, fallback_face, nullptr, source, font_family, style, weight);
bool result = Get().LoadFontFace(data, face_index, fallback_face, nullptr, source, font_family, style, weight);

return result;
}

bool FontProvider::LoadFontFace(Span<const byte> data, bool fallback_face, UniquePtr<byte[]> face_memory, const String& source, String font_family,
bool FontProvider::LoadFontFace(Span<const byte> data, int face_index, bool fallback_face, UniquePtr<byte[]> face_memory, const String& source, String font_family,
Style::FontStyle style, Style::FontWeight weight)
{
using Style::FontWeight;

Vector<Rml::FaceVariation> face_variations;
if (!Rml::FreeType::GetFaceVariations(data, face_variations))
if (!Rml::FreeType::GetFaceVariations(data, face_variations, face_index))
{
Rml::Log::Message(Rml::Log::LT_ERROR, "Failed to load font face from '%s': Invalid or unsupported font face file format.", source.c_str());
return false;
Expand Down Expand Up @@ -200,7 +200,7 @@ bool FontProvider::LoadFontFace(Span<const byte> data, bool fallback_face, Uniqu

for (const Rml::FaceVariation& variation : load_variations)
{
FontFaceHandleFreetype ft_face = Rml::FreeType::LoadFace(data, source, variation.named_instance_index);
FontFaceHandleFreetype ft_face = Rml::FreeType::LoadFace(data, source, face_index, variation.named_instance_index);
if (!ft_face)
return false;

Expand Down
6 changes: 3 additions & 3 deletions Samples/basic/harfbuzz/src/FontProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ class FontProvider {
static FontFaceHandleHarfBuzz* GetFontFaceHandle(const String& family, Style::FontStyle style, Style::FontWeight weight, int size);

/// Adds a new font face to the database. The face's family, style and weight will be determined from the face itself.
static bool LoadFontFace(const String& file_name, bool fallback_face, Style::FontWeight weight = Style::FontWeight::Auto);
static bool LoadFontFace(const String& file_name, int face_index, bool fallback_face, Style::FontWeight weight = Style::FontWeight::Auto);

/// Adds a new font face from memory.
static bool LoadFontFace(Span<const byte> data, const String& font_family, Style::FontStyle style, Style::FontWeight weight, bool fallback_face);
static bool LoadFontFace(Span<const byte> data, int face_index, const String& font_family, Style::FontStyle style, Style::FontWeight weight, bool fallback_face);

/// Return the number of fallback font faces.
static int CountFallbackFontFaces();
Expand All @@ -87,7 +87,7 @@ class FontProvider {

static FontProvider& Get();

bool LoadFontFace(Span<const byte> data, bool fallback_face, UniquePtr<byte[]> face_memory, const String& source, String font_family,
bool LoadFontFace(Span<const byte> data, int face_index, bool fallback_face, UniquePtr<byte[]> face_memory, const String& source, String font_family,
Style::FontStyle style,
Style::FontWeight weight);

Expand Down
2 changes: 1 addition & 1 deletion Samples/basic/ime/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ static void LoadFonts()
font_faces.push_back({path, true});

for (const FontFace& face : font_faces)
Rml::LoadFontFace(face.filename, face.fallback_face);
Rml::LoadFontFace(face.filename, 0, face.fallback_face);
}

int APIENTRY WinMain(HINSTANCE /*instance_handle*/, HINSTANCE /*previous_instance_handle*/, char* /*command_line*/, int /*command_show*/)
Expand Down
2 changes: 1 addition & 1 deletion Samples/shell/src/Shell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ void Shell::LoadFonts()
};

for (const FontFace& face : font_faces)
Rml::LoadFontFace(directory + face.filename, face.fallback_face);
Rml::LoadFontFace(directory + face.filename, 0, face.fallback_face);
}

bool Shell::ProcessKeyDownShortcuts(Rml::Context* context, Rml::Input::KeyIdentifier key, int key_modifier, float native_dp_ratio, bool priority)
Expand Down
8 changes: 4 additions & 4 deletions Source/Core/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -356,14 +356,14 @@ int GetNumContexts()
return (int)core_data->contexts.size();
}

bool LoadFontFace(const String& file_path, bool fallback_face, Style::FontWeight weight)
bool LoadFontFace(const String& file_path, int face_index, bool fallback_face, Style::FontWeight weight)
{
return font_interface->LoadFontFace(file_path, fallback_face, weight);
return font_interface->LoadFontFace(file_path, face_index, fallback_face, weight);
}

bool LoadFontFace(Span<const byte> data, const String& family, Style::FontStyle style, Style::FontWeight weight, bool fallback_face)
bool LoadFontFace(Span<const byte> data, int face_index, const String& family, Style::FontStyle style, Style::FontWeight weight, bool fallback_face)
{
return font_interface->LoadFontFace(data, family, style, weight, fallback_face);
return font_interface->LoadFontFace(data, face_index, family, style, weight, fallback_face);
}

void RegisterPlugin(Plugin* plugin)
Expand Down
8 changes: 4 additions & 4 deletions Source/Core/FontEngineDefault/FontEngineInterfaceDefault.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@ void FontEngineInterfaceDefault::Shutdown()
FontProvider::Shutdown();
}

bool FontEngineInterfaceDefault::LoadFontFace(const String& file_name, bool fallback_face, Style::FontWeight weight)
bool FontEngineInterfaceDefault::LoadFontFace(const String& file_name, int face_index, bool fallback_face, Style::FontWeight weight)
{
return FontProvider::LoadFontFace(file_name, fallback_face, weight);
return FontProvider::LoadFontFace(file_name, face_index, fallback_face, weight);
}

bool FontEngineInterfaceDefault::LoadFontFace(Span<const byte> data, const String& font_family, Style::FontStyle style, Style::FontWeight weight,
bool FontEngineInterfaceDefault::LoadFontFace(Span<const byte> data, int face_index, const String& font_family, Style::FontStyle style, Style::FontWeight weight,
bool fallback_face)
{
return FontProvider::LoadFontFace(data, font_family, style, weight, fallback_face);
return FontProvider::LoadFontFace(data, face_index, font_family, style, weight, fallback_face);
}

FontFaceHandle FontEngineInterfaceDefault::GetFontFaceHandle(const String& family, Style::FontStyle style, Style::FontWeight weight, int size)
Expand Down
4 changes: 2 additions & 2 deletions Source/Core/FontEngineDefault/FontEngineInterfaceDefault.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ class RMLUICORE_API FontEngineInterfaceDefault : public FontEngineInterface {
void Shutdown() override;

/// 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, Style::FontWeight weight) override;
bool LoadFontFace(const String& file_name, int face_index, bool fallback_face, Style::FontWeight weight) override;

/// Adds a new font face to the database using the provided family, style and weight.
bool LoadFontFace(Span<const byte> data, const String& font_family, Style::FontStyle style, Style::FontWeight weight,
bool LoadFontFace(Span<const byte> data, int face_index, 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
Expand Down
14 changes: 7 additions & 7 deletions Source/Core/FontEngineDefault/FontProvider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ void FontProvider::ReleaseFontResources()
name_family.second->ReleaseFontResources();
}

bool FontProvider::LoadFontFace(const String& file_name, bool fallback_face, Style::FontWeight weight)
bool FontProvider::LoadFontFace(const String& file_name, int face_index, bool fallback_face, Style::FontWeight weight)
{
FileInterface* file_interface = GetFileInterface();
FileHandle handle = file_interface->Open(file_name);
Expand All @@ -128,28 +128,28 @@ bool FontProvider::LoadFontFace(const String& file_name, bool fallback_face, Sty
file_interface->Read(buffer, length, handle);
file_interface->Close(handle);

bool result = Get().LoadFontFace({buffer, length}, fallback_face, std::move(buffer_ptr), file_name, {}, Style::FontStyle::Normal, weight);
bool result = Get().LoadFontFace({buffer, length}, face_index, fallback_face, std::move(buffer_ptr), file_name, {}, Style::FontStyle::Normal, weight);

return result;
}

bool FontProvider::LoadFontFace(Span<const byte> data, const String& font_family, Style::FontStyle style, Style::FontWeight weight,
bool FontProvider::LoadFontFace(Span<const byte> data, int face_index, const String& font_family, Style::FontStyle style, Style::FontWeight weight,
bool fallback_face)
{
const String source = "memory";

bool result = Get().LoadFontFace(data, fallback_face, nullptr, source, font_family, style, weight);
bool result = Get().LoadFontFace(data, face_index, fallback_face, nullptr, source, font_family, style, weight);

return result;
}

bool FontProvider::LoadFontFace(Span<const byte> data, bool fallback_face, UniquePtr<byte[]> face_memory, const String& source, String font_family,
bool FontProvider::LoadFontFace(Span<const byte> data, int face_index, bool fallback_face, UniquePtr<byte[]> face_memory, const String& source, String font_family,
Style::FontStyle style, Style::FontWeight weight)
{
using Style::FontWeight;

Vector<FaceVariation> face_variations;
if (!FreeType::GetFaceVariations(data, face_variations))
if (!FreeType::GetFaceVariations(data, face_variations, face_index))
{
Log::Message(Log::LT_ERROR, "Failed to load font face from '%s': Invalid or unsupported font face file format.", source.c_str());
return false;
Expand Down Expand Up @@ -205,7 +205,7 @@ bool FontProvider::LoadFontFace(Span<const byte> data, bool fallback_face, Uniqu

for (const FaceVariation& variation : load_variations)
{
FontFaceHandleFreetype ft_face = FreeType::LoadFace(data, source, variation.named_instance_index);
FontFaceHandleFreetype ft_face = FreeType::LoadFace(data, source, face_index, variation.named_instance_index);
if (!ft_face)
return false;

Expand Down
Loading

0 comments on commit 51ad585

Please sign in to comment.