Rendering Engine 0.2.9
Modular Graphics Rendering Engine | v0.2.9
text_block_2d.hpp
Go to the documentation of this file.
1// This file is part of the Rendering Engine project.
2// Author: Alexander Obzherin <alexanderobzherin@gmail.com>
3// Copyright (c) 2026 Alexander Obzherin
4// Distributed under the terms of the zlib License. See LICENSE.md for details.
5#pragma once
6
7#include "drawable_2d.hpp"
10
11#include <cstdint>
12#include <string>
13#include <vector>
14#include <iostream>
15#include <unordered_map>
16#include <glm/glm.hpp>
17
18namespace rendering_engine
19{
20/*
21penX, penY - current cursor (baseline)
22x = penX + bearingX
23y = penY - bearingY
24width, height - quad size
25penX += advanceX
26*/
27class Scene;
28class TextRenderer;
29class FontResources;
30struct GlyphIndex;
31
32/**
33 * @enum TextAlign
34 * @brief Horizontal alignment mode for text layout.
35 */
36enum class TextAlign
37{
38 Left = 0,
39 Center,
40 Right
41};
42
43/**
44 * @class TextBlock2D
45 * @brief 2D drawable representing a block of rendered text.
46 *
47 * Converts UTF-8 text into glyph quads, performs layout and alignment,
48 * and submits render batches using font atlas materials.
49 *
50 * A TextBlock2D instance is bound to a single font and font size.
51 */
53{
54public:
55/**
56* @struct TextBlock2D::Properties
57* @brief Configuration parameters for a text block.
58*/
60{
61 /// Font family name.
62 std::string fontName;
63 /// Font size in pixels.
64 float fontSize = 10;
65 /// Horizontal text alignment.
67 /// Maximum line length for layout; zero disables wrapping.
68 float maxLineLength = 0.0f;
69 /// Enables text shaping during layout.
70 bool textShapeEnabled = false;
71 /// Outline thickness in pixels.
72 float outlineThicknessPx = 0.0f;
73 /// Line height multiplier.
74 float lineSpacingScale = 1.0f;
75
77 : fontName(TextBlock2D::sDefaultFontName)
78 {}
79};
80
81public:
82 /**
83 * @brief Constructs a 2D text block.
84 * @param textRenderer Owning text renderer.
85 * @param properties Text block configuration.
86 */
87 TextBlock2D(Scene& scene, std::shared_ptr<TextRenderer> textRenderer, Properties properties = Properties());
88
89 /**
90 * @copydoc DrawableComponent::Initialize
91 */
92 void Initialize() override;
93 /**
94 * @copydoc DrawableComponent::Update
95 */
96 void Update(float deltaTime) override;
97 /**
98 * @copydoc Drawable2D::Draw
99 */
100 void Draw(const Camera2D& camera) override;
101 /**
102 * @brief Sets the displayed text.
103 * @param text UTF-8 encoded text string.
104 */
105 virtual void SetText(std::string text);
106 /**
107 * @brief Sets the text color.
108 * @param color RGBA color.
109 */
110 void SetTextColor(glm::vec4 color);
111 /**
112 * @brief Sets the outline color.
113 * @param color RGBA color.
114 */
115 void SetOutlineColor(glm::vec4 color);
116 /**
117 * @brief Returns text block dimensions.
118 * @return Width and height in pixels.
119 */
120 glm::vec2 GetDimensions() const;
121
122protected:
123/**
124* @struct Mesh
125* @brief CPU-side mesh data for glyph quads.
126*/
127struct Mesh
128{
129 std::vector<glm::vec2> positions2D;
130 std::vector<glm::vec2> texCoords;
131 std::vector<glm::vec4> colors;
132 std::vector<std::uint32_t> indices;
133};
134/**
135 * @struct GlyphQuad
136 * @brief Renderable quad representing a single glyph.
137 */
139{
140 float x0;
141 float y0;
142 float x1;
143 float y1;
144
145 float u0;
146 float v0;
147 float u1;
148 float v1;
149
151 std::uint32_t advanceX;
152};
153/**
154 * @struct ShapedGlyph
155 * @brief Result of text shaping for a single glyph.
156 *
157 * Contains glyph index, pen offsets, and advance values.
158 */
160{
161 std::uint32_t glyphIndex; // FT glyph index (font-specific)
162 std::uint32_t cluster;
163 float xAdvance; // pen movement AFTER this glyph
164 float yAdvance;
165 float xOffset; // offset FROM current pen position
166 float yOffset;
167};
168protected:
169 /**
170 * @brief Decodes a UTF-8 string into Unicode code points.
171 * @param text UTF-8 encoded string.
172 * @return List of Unicode code points.
173 */
174 std::vector<std::uint32_t> DecodeUtf8(const std::string& text);
175
176 /**
177 * @brief Converts a Unicode code point to UTF-8.
178 * @param codePoint Unicode code point.
179 * @return UTF-8 encoded string.
180 */
181 std::string CodepointToUtf8(std::uint32_t codePoint);
182
183 /**
184 * @brief Shapes text and returns shaped glyphs.
185 * @param text UTF-8 encoded text.
186 * @return List of shaped glyphs.
187 */
188 std::vector<ShapedGlyph> ShapeText(const std::string& text);
189
190 // Deprecated
191 void ConstructMeshAutoLinebreak(const std::vector<std::uint32_t>& codePoints);
192
193 /**
194 * @brief Constructs glyph geometry without shaping.
195 */
196 void ConstructMesh();
197
198 /**
199 * @brief Shapes text and constructs glyph geometry.
200 */
201 void ShapeTextAndConstructMesh();
202 /**
203 * @brief Creates a glyph quad at the current pen position.
204 * @param glyphIndex Glyph identifier.
205 * @param penX Horizontal pen position.
206 * @param penY Vertical pen position.
207 * @return Glyph quad.
208 */
209 GlyphQuad MakeGlyphQuad(GlyphIndex glyphIndext, float penX, float penY);
210 /**
211 * @brief Appends a glyph quad to a mesh.
212 * @param meshName Target mesh name.
213 * @param meshes Mesh container.
214 * @param glyphQuad Glyph quad data.
215 * @param horizontalShift Alignment offset.
216 */
217 void PushQuad(std::string meshName,
218 std::unordered_map<std::string, TextBlock2D::Mesh>& meshes,
219 GlyphQuad glyphQuad,
220 float horizontalShift = 0.0f);
221 /**
222 * @brief Uploads prepared meshes to GPU resources.
223 * @param meshes CPU-side mesh data.
224 */
225 void UploadMeshes(const std::unordered_map<std::string, TextBlock2D::Mesh>& meshes);
226 /**
227 * @brief Sets outline thickness for all render batches.
228 * @param thicknessPx Thickness in pixels.
229 */
230 void SetOutlineThickness(float thicknessPx);
231 /**
232 * @brief Prepares mesh slots based on glyph usage.
233 * @param glyphs Glyph collection.
234 * @return Map of mesh names to mesh data.
235 */
236 template <typename T>
237 std::unordered_map<std::string, TextBlock2D::Mesh> PrepareMeshSlots(const std::vector<T>& glyphs);
238 /**
239 * @brief Splits a string by a separator.
240 * @param text Input string.
241 * @param separator Separator string.
242 * @return List of substrings.
243 */
244 std::vector<std::string> SplitString(const std::string& text, std::string separator);
245 /**
246 * @brief Checks whether shaping is required for a code point.
247 * @param codePoint Unicode code point.
248 * @return True if shaping is required.
249 */
250 bool IsTextShapingRequired(std::uint32_t codePoint) const;
251
252private:
253 static std::uint64_t sNumOfTextBlocks;
254 std::string mTextBlockID;
255
256protected:
257 /*Stores material used in string and corresponding name of created mesh*/
258 std::unordered_map<std::string, std::string> mMaterialMesh;
259
260 const std::shared_ptr<TextRenderer> mTextRenderer;
261 std::shared_ptr<FontResources> mFontResources;
262 glm::vec4 mColor;
263 static std::string sDefaultFontName;
264 const std::string mFontName;
265 const unsigned int mFontSize;
266 float mLineSpacingScale = 1.0f;
267 std::string mText;
268 float mMaxLineLength = 0.0f;
270 glm::vec2 mDimensions;
271
273
275};
276}
Represents a 2D camera with position, rotation, and zoom control.
Definition: camera_2d.hpp:36
2D drawable component for rendering objects in 2D space.
Definition: drawable_2d.hpp:27
Base class representing a renderable scene.
Definition: scene.hpp:44
2D drawable representing a block of rendered text.
static std::string sDefaultFontName
std::unordered_map< std::string, std::string > mMaterialMesh
std::shared_ptr< FontResources > mFontResources
const std::shared_ptr< TextRenderer > mTextRenderer
std::unordered_map< std::string, TextBlock2D::Mesh > PrepareMeshSlots(const std::vector< T > &glyphs)
Prepares mesh slots based on glyph usage.
TextAlign
Horizontal alignment mode for text layout.
#define RE_API
Configuration parameters for a text block.
Opaque glyph identifier within a font.
Renderable quad representing a single glyph.
CPU-side mesh data for glyph quads.
std::vector< std::uint32_t > indices
std::vector< glm::vec4 > colors
std::vector< glm::vec2 > texCoords
std::vector< glm::vec2 > positions2D
std::string fontName
Font family name.
Result of text shaping for a single glyph.