libdonut  2.3.2
Application framework for cross-platform game development in C++20
Font.hpp
Go to the documentation of this file.
1 #ifndef DONUT_GRAPHICS_FONT_HPP
2 #define DONUT_GRAPHICS_FONT_HPP
3 
4 #include <donut/AtlasPacker.hpp>
5 #include <donut/Filesystem.hpp>
6 #include <donut/UniqueHandle.hpp>
8 #include <donut/math.hpp>
9 
10 #include <cstddef> // std::size_t, std::byte
11 #include <utility> // std::pair
12 #include <vector> // std::vector
13 
14 namespace donut::graphics {
15 
16 class Renderer; // Forward declaration, to avoid including Renderer.hpp.
17 
21 struct FontOptions {
35  bool useLinearFiltering = false;
36 };
37 
42 class Font {
43 public:
47  struct Glyph {
49  vec2 sizeInAtlas;
50  bool rendered;
51  };
52 
56  struct GlyphMetrics {
57  vec2 size;
58  vec2 bearing;
59  float advance;
60  };
61 
65  struct LineMetrics {
66  float ascender;
67  float descender;
68  float height;
69  };
70 
90  Font(const Filesystem& filesystem, const char* filepath, const FontOptions& options = {});
91 
93  ~Font() = default;
94 
99  Font(const Font&) = delete;
100 
102  Font(Font&& other) noexcept = default;
103 
108  Font& operator=(const Font& other) = delete;
109 
111  Font& operator=(Font&& other) noexcept = default;
112 
125  [[nodiscard]] Glyph findGlyph(u32 characterSize, char32_t codePoint) const noexcept;
126 
154  std::pair<Glyph, bool> renderGlyph(Renderer& renderer, u32 characterSize, char32_t codePoint);
155 
168  [[nodiscard]] GlyphMetrics getGlyphMetrics(u32 characterSize, char32_t codePoint) const noexcept;
169 
177  [[nodiscard]] LineMetrics getLineMetrics(u32 characterSize) const noexcept;
178 
192  [[nodiscard]] vec2 getKerning(u32 characterSize, char32_t left, char32_t right) const noexcept;
193 
206  void markGlyphForRendering(u32 characterSize, char32_t codePoint);
207 
224  bool renderMarkedGlyphs(Renderer& renderer);
225 
232  [[nodiscard]] bool containsGlyphsMarkedForRendering() const noexcept;
233 
243  [[nodiscard]] const Texture& getAtlasTexture() const noexcept {
244  return atlasTexture;
245  }
246 
247 private:
248  struct FontDeleter {
249  void operator()(void* handle) const noexcept;
250  };
251 
252  struct GlyphKey {
253  u32 characterSize;
254  char32_t codePoint;
255 
256  [[nodiscard]] constexpr auto operator<=>(const GlyphKey&) const = default;
257  };
258 
259  static constexpr std::size_t INITIAL_RESOLUTION = 128;
260  static constexpr std::size_t PADDING = 6;
261 
262  void prepareAtlasTexture(Renderer& renderer, bool resized);
263 
264  std::vector<std::byte> fontFileContents;
265  UniqueHandle<void*, FontDeleter> font;
266  AtlasPacker<INITIAL_RESOLUTION, PADDING> atlasPacker{};
267  Texture atlasTexture{};
268  std::vector<GlyphKey> sortedGlyphKeys{};
269  std::vector<Glyph> glyphsSortedByKey{};
270  std::vector<GlyphKey> glyphKeysMarkedForRendering{};
271  FontOptions options;
272 };
273 
274 } // namespace donut::graphics
275 
276 #endif
Persistent system for managing the virtual filesystem.
Definition: Filesystem.hpp:185
Typeface describing an assortment of character glyphs that may be rendered on-demand into an expandin...
Definition: Font.hpp:42
Font & operator=(const Font &other)=delete
Copying a font is not allowed, since the memory location of the file contents must remain stable.
vec2 getKerning(u32 characterSize, char32_t left, char32_t right) const noexcept
Get the kerning offset to use between a pair of adjacent character glyphs while shaping text.
Font & operator=(Font &&other) noexcept=default
Move assignment.
Font(const Filesystem &filesystem, const char *filepath, const FontOptions &options={})
Load a font from a virtual file.
bool renderMarkedGlyphs(Renderer &renderer)
Render all glyphs marked using markGlyphForRendering() that have not already been rendered.
Font(const Font &)=delete
Copying a font is not allowed, since the memory location of the file contents must remain stable.
Glyph findGlyph(u32 characterSize, char32_t codePoint) const noexcept
Look up the information about a glyph's entry in the texture atlas for a specific code point.
Font(Font &&other) noexcept=default
Move constructor.
~Font()=default
Destructor.
GlyphMetrics getGlyphMetrics(u32 characterSize, char32_t codePoint) const noexcept
Get the dimensions of a single glyph in this font, for shaping text.
std::pair< Glyph, bool > renderGlyph(Renderer &renderer, u32 characterSize, char32_t codePoint)
Render the glyph for a specific character and store it in the texture atlas, if it has not already be...
void markGlyphForRendering(u32 characterSize, char32_t codePoint)
Enqueue a glyph for rendering on the next call to renderMarkedGlyphs() if it has not already been ren...
const Texture & getAtlasTexture() const noexcept
Get the texture atlas to use when rendering glyphs from this font.
Definition: Font.hpp:243
LineMetrics getLineMetrics(u32 characterSize) const noexcept
Get the vertical dimensions for shaping lines of text with this font.
bool containsGlyphsMarkedForRendering() const noexcept
Check if any unrendered glyphs have been marked for rendering.
Persistent system for rendering the batched draw commands of a RenderPass onto a Framebuffer,...
Definition: Renderer.hpp:38
Storage for multidimensional data, such as 2D images, on the GPU, combined with a sampler configurati...
Definition: Texture.hpp:75
Definition: Buffer.hpp:7
constexpr std::strong_ordering operator<=>(Monostate, Monostate) noexcept
Compare two monostates.
Definition: Variant.hpp:258
Configuration options for a Font.
Definition: Font.hpp:21
bool useLinearFiltering
Use bilinear filtering rather than nearest-neighbor interpolation when rendering text at a non-1:1 sc...
Definition: Font.hpp:35
Dimensions of a single glyph in this font, for shaping text.
Definition: Font.hpp:56
float advance
Horizontal offset to apply in order to advance to the next glyph position, excluding any kerning.
Definition: Font.hpp:59
vec2 size
Size of this glyph's rectangle when rendered, in pixels.
Definition: Font.hpp:57
vec2 bearing
Offset from the baseline to apply to the glyph's rectangle position when rendering this glyph.
Definition: Font.hpp:58
Information about a single glyph's entry in the texture atlas.
Definition: Font.hpp:47
vec2 sizeInAtlas
Size of this glyph's rectangle in the texture atlas, in texels. Invalid if Glyph::rendered is false.
Definition: Font.hpp:49
bool rendered
True if the glyph has been rendered and has a valid rectangle in the texture atlas,...
Definition: Font.hpp:50
vec2 positionInAtlas
Position of this glyph's rectangle in the texture atlas, in texels. Invalid if Glyph::rendered is fal...
Definition: Font.hpp:48
Vertical dimensions for shaping lines of text with this font.
Definition: Font.hpp:65
float ascender
Vertical offset from the baseline to the visual top of the text.
Definition: Font.hpp:66
float height
Vertical offset to apply in order to advance to the next line.
Definition: Font.hpp:68
float descender
Vertical offset from the baseline to the visual bottom of the text.
Definition: Font.hpp:67