Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgraded font-weight #296

Merged
merged 3 commits into from
May 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Include/RmlUi/Core/ComputedValues.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ struct Clip {
enum class Visibility : uint8_t { Visible, Hidden };

enum class FontStyle : uint8_t { Normal, Italic };
enum class FontWeight : uint8_t { Normal, Bold };
enum class FontWeight : uint16_t { Auto = 0, Normal = 400, Bold = 700 }; // Any definite value in the range [1,1000] is valid.

enum class TextAlign : uint8_t { Left, Right, Center, Justify };
enum class TextDecoration : uint8_t { None, Underline, Overline, LineThrough };
Expand Down
10 changes: 7 additions & 3 deletions Include/RmlUi/Core/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,18 +119,22 @@ 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_name The file to load the face from.
/// @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_name, bool fallback_face = false);
RMLUICORE_API bool LoadFontFace(const String& file_name, 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 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.
/// @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(const byte* data, int data_size, const String& font_family, Style::FontStyle style, Style::FontWeight weight, bool fallback_face = false);
RMLUICORE_API bool LoadFontFace(const byte* data, int data_size, const String& font_family, Style::FontStyle style,
Style::FontWeight weight = Style::FontWeight::Auto, bool fallback_face = false);

/// Registers a generic RmlUi plugin.
RMLUICORE_API void RegisterPlugin(Plugin* plugin);
Expand Down
5 changes: 3 additions & 2 deletions Include/RmlUi/Core/FontEngineInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,16 @@ 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] 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);
virtual bool LoadFontFace(const String& file_name, 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 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.
/// @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'.
Expand Down
4 changes: 4 additions & 0 deletions Include/RmlUi/Core/Math.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ RMLUICORE_API bool AreEqual(float value_0, float value_1);
/// @param[in] value The number of get the absolute value of.
/// @return The absolute value of the number.
RMLUICORE_API float AbsoluteValue(float value);
/// Calculates the absolute value of a number.
/// @param[in] value The number of get the absolute value of.
/// @return The absolute value of the number.
RMLUICORE_API int AbsoluteValue(int value);

/// Calculates the cosine of an angle.
/// @param[in] angle The angle to calculate the cosine of, in radians.
Expand Down
2 changes: 1 addition & 1 deletion Samples/basic/bitmapfont/src/FontEngineInterfaceBitmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ FontEngineInterfaceBitmap::~FontEngineInterfaceBitmap()
FontProviderBitmap::Shutdown();
}

bool FontEngineInterfaceBitmap::LoadFontFace(const String& file_name, bool /*fallback_face*/)
bool FontEngineInterfaceBitmap::LoadFontFace(const String& file_name, bool /*fallback_face*/, FontWeight /*weight*/)
{
return FontProviderBitmap::LoadFontFace(file_name);
}
Expand Down
2 changes: 1 addition & 1 deletion Samples/basic/bitmapfont/src/FontEngineInterfaceBitmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class FontEngineInterfaceBitmap : public Rml::FontEngineInterface
virtual ~FontEngineInterfaceBitmap();

/// Called by RmlUi when it wants to load a font face from file.
bool LoadFontFace(const String& file_name, bool fallback_face) override;
bool LoadFontFace(const String& file_name, 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.
Expand Down
4 changes: 2 additions & 2 deletions Source/Core/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,9 +331,9 @@ int GetNumContexts()
return (int) contexts.size();
}

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

bool LoadFontFace(const byte* data, int data_size, const String& font_family, Style::FontStyle style, Style::FontWeight weight, bool fallback_face)
Expand Down
4 changes: 2 additions & 2 deletions Source/Core/FontEngineDefault/FontEngineInterfaceDefault.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ FontEngineInterfaceDefault::~FontEngineInterfaceDefault()
FontProvider::Shutdown();
}

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

bool FontEngineInterfaceDefault::LoadFontFace(const byte* data, int data_size, const String& font_family, Style::FontStyle style, Style::FontWeight weight, bool fallback_face)
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/FontEngineDefault/FontEngineInterfaceDefault.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class RMLUICORE_API FontEngineInterfaceDefault : public FontEngineInterface
virtual ~FontEngineInterfaceDefault();

/// 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;
bool LoadFontFace(const String& file_name, bool fallback_face, Style::FontWeight weight) 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;
Expand Down
9 changes: 1 addition & 8 deletions Source/Core/FontEngineDefault/FontFace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,17 @@

namespace Rml {

FontFace::FontFace(FontFaceHandleFreetype _face, Style::FontStyle _style, Style::FontWeight _weight, UniquePtr<byte[]> _face_memory)
FontFace::FontFace(FontFaceHandleFreetype _face, Style::FontStyle _style, Style::FontWeight _weight)
{
style = _style;
weight = _weight;
face = _face;

face_memory = std::move(_face_memory);
}

FontFace::~FontFace()
{
if (face)
{
FreeType::ReleaseFace(face);
face_memory.reset();
face = 0;
}
handles.clear();
}

// Returns the style of the font face.
Expand Down
5 changes: 1 addition & 4 deletions Source/Core/FontEngineDefault/FontFace.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class FontFaceHandleDefault;
class FontFace
{
public:
FontFace(FontFaceHandleFreetype face, Style::FontStyle style, Style::FontWeight weight, UniquePtr<byte[]> face_memory);
FontFace(FontFaceHandleFreetype face, Style::FontStyle style, Style::FontWeight weight);
~FontFace();

Style::FontStyle GetStyle() const;
Expand All @@ -59,9 +59,6 @@ class FontFace
Style::FontStyle style;
Style::FontWeight weight;

// Only filled if we own the memory used by the FreeType face handle.
UniquePtr<byte[]> face_memory;

// Key is font size
using HandleMap = UnorderedMap< int, UniquePtr<FontFaceHandleDefault> >;
HandleMap handles;
Expand Down
39 changes: 28 additions & 11 deletions Source/Core/FontEngineDefault/FontFamily.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,46 +27,63 @@
*/

#include "FontFamily.h"
#include "../../../Include/RmlUi/Core/Math.h"
#include "FontFace.h"
#include <limits.h>

namespace Rml {

FontFamily::FontFamily(const String& name) : name(name)
{}

FontFamily::~FontFamily()
{
// Multiple face entries may share memory within a single font family, although only one of them owns it. Here we make sure that all the face
// destructors are run before all the memory is released. This way we don't leave any hanging references to invalidated memory.
for (FontFaceEntry& entry : font_faces)
entry.face.reset();
}

// Returns a handle to the most appropriate font in the family, at the correct size.
FontFaceHandleDefault* FontFamily::GetFaceHandle(Style::FontStyle style, Style::FontWeight weight, int size)
{
// Search for a face of the same style, and match the weight as closely as we can.
int best_dist = INT_MAX;
FontFace* matching_face = nullptr;
for (size_t i = 0; i < font_faces.size(); i++)
{
// If we've found a face matching the style, then ... great! We'll match it regardless of the weight. However,
// if it's a perfect match, then we'll stop looking altogether.
if (font_faces[i]->GetStyle() == style)
{
matching_face = font_faces[i].get();
FontFace* face = font_faces[i].face.get();

if (font_faces[i]->GetWeight() == weight)
if (face->GetStyle() == style)
{
const int dist = Math::AbsoluteValue((int)face->GetWeight() - (int)weight);
if (dist == 0)
{
// Direct match for weight, break the loop early.
matching_face = face;
break;
}
else if (dist < best_dist)
{
// Best match so far for weight, store the face and dist.
matching_face = face;
best_dist = dist;
}
}
}

if (matching_face == nullptr)
if (!matching_face)
return nullptr;

return matching_face->GetHandle(size, false);
}


// Adds a new face to the family.
FontFace* FontFamily::AddFace(FontFaceHandleFreetype ft_face, Style::FontStyle style, Style::FontWeight weight, UniquePtr<byte[]> face_memory)
{
auto face = MakeUnique<FontFace>(ft_face, style, weight, std::move(face_memory));
auto face = MakeUnique<FontFace>(ft_face, style, weight);
FontFace* result = face.get();

font_faces.push_back(std::move(face));
font_faces.push_back(FontFaceEntry{std::move(face), std::move(face_memory)});

return result;
}
Expand Down
9 changes: 8 additions & 1 deletion Source/Core/FontEngineDefault/FontFamily.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class FontFamily
{
public:
FontFamily(const String& name);
~FontFamily();

/// Returns a handle to the most appropriate font in the family, at the correct size.
/// @param[in] style The style of the desired handle.
Expand All @@ -64,7 +65,13 @@ class FontFamily
protected:
String name;

using FontFaceList = Vector< UniquePtr<FontFace> >;
struct FontFaceEntry {
UniquePtr<FontFace> face;
// Only filled if we own the memory used by the face's FreeType handle. May be shared with other faces in this family.
UniquePtr<byte[]> face_memory;
};

using FontFaceList = Vector<FontFaceEntry>;
FontFaceList font_faces;
};

Expand Down
Loading