Rendering Engine 0.2.9
Modular Graphics Rendering Engine | v0.2.9
rendering_engine::TextRenderer Class Reference

Central text system manager and font resource registry. More...

#include <text_renderer.hpp>

Public Member Functions

 TextRenderer (RenderResourceContext rrc)
 Constructs the text renderer and initializes internal font systems. More...
 
 ~TextRenderer ()
 Shuts down the text system and releases font backend resources. More...
 
void LoadFontsFromFolder (std::string pathToFolder)
 Loads fonts from a filesystem folder. More...
 
void LoadFontsFromPackage ()
 Loads fonts bundled inside an application package. More...
 
const RenderResourceContextGetRenderResourceContext () const
 Returns the rendering resource context. More...
 
std::shared_ptr< FontResourcesGetFontResources (const std::string &fontName, int fontSize)
 Retrieves or creates font resources for a font and size. More...
 
void StoreFontAtlasesInFiles (bool in)
 Enables or disables storing generated font atlases to files. More...
 
const std::vector< std::string > & GetScriptsRequiredShaping () const
 Returns scripts that require shaping before rendering. More...
 
std::pair< std::uint32_t, std::uint32_t > GetScriptRange (std::string script)
 Returns the Unicode codepoint range for a script. More...
 
FT_Library & GetFontLibrary ()
 Returns the internal FreeType library instance. More...
 
void Shutdown ()
 

Protected Member Functions

void LoadFontsAvailableInFolder (std::string pathToFolder)
 Discovers fonts available in a filesystem folder. More...
 
void LoadPreloadableFontAtlasesFromFolder (const std::unordered_map< std::string, std::string > &availableFontsInFolder)
 Loads preloadable font atlases from a folder. More...
 
void LoadFontsAvailableInPackage ()
 Discovers fonts available in the application package. More...
 
void LoadPreloadableFontAtlasesFromPackage (const std::unordered_map< std::string, std::string > &availableFontsInPackage)
 Loads preloadable font atlases from the application package. More...
 

Detailed Description

Central text system manager and font resource registry.

Owns the font backend instance, manages font discovery and caching, defines script metadata, and coordinates font atlas preloading based on application configuration.

Definition at line 36 of file text_renderer.hpp.

Constructor & Destructor Documentation

◆ TextRenderer()

rendering_engine::TextRenderer::TextRenderer ( RenderResourceContext  rrc)

Constructs the text renderer and initializes internal font systems.

Parameters
rrcRendering resource context.

This object owns the lifetime of the font backend and must outlive all font resources created through it.

Definition at line 95 of file text_renderer.cpp.

96 :
97 mRenderResourceContext(rrc)
98{
99 LOG_INFO("Initializing TextRenderer...");
100 auto start = std::chrono::steady_clock::now();
101
102 mErrorResult = FT_Init_FreeType(&mLibrary);
103 if (mErrorResult)
104 {
105 LOG_ERROR("Failed to initialize FreeType library!");
106 throw std::runtime_error{ "Failed to initialize FreeType library!" };
107 }
108
109 auto end = std::chrono::steady_clock::now();
110 float ms = std::chrono::duration<float, std::milli>(end - start).count();
111
112 LOG_INFO("FreeType initialized in " + std::to_string(ms) + " ms.");
113}
#define LOG_ERROR(msg)
Definition: logger.hpp:41
#define LOG_INFO(msg)
Definition: logger.hpp:39

◆ ~TextRenderer()

rendering_engine::TextRenderer::~TextRenderer ( )

Shuts down the text system and releases font backend resources.

All FontResources obtained from this renderer must be destroyed before the renderer itself.

Definition at line 115 of file text_renderer.cpp.

116{
117}

Member Function Documentation

◆ GetFontLibrary()

FT_Library & rendering_engine::TextRenderer::GetFontLibrary ( )
inline

Returns the internal FreeType library instance.

Returns
Reference to FT_Library.

Definition at line 99 of file text_renderer.hpp.

100 {
101 return mLibrary;
102 }

◆ GetFontResources()

std::shared_ptr< FontResources > rendering_engine::TextRenderer::GetFontResources ( const std::string &  fontName,
int  fontSize 
)

Retrieves or creates font resources for a font and size.

If the requested font resources are not yet loaded, they will be created on demand from available font sources.

Parameters
fontNameFont family name.
fontSizeFont size in pixels.
Returns
Shared pointer to font resources, or nullptr if unavailable.

Definition at line 159 of file text_renderer.cpp.

160{
161 auto key = std::make_pair(fontName, fontSize);
162 if (auto search = mFontResources.find(key); search != mFontResources.end())
163 {
164 return search->second;
165 }
166 else
167 {
168 if (!mAvailableFontsInPackage.empty())
169 {
170 if (!mAvailableFontsInPackage.empty())
171 {
172 auto foundInPackage = mAvailableFontsInPackage.find(fontName);
173 if (foundInPackage != mAvailableFontsInPackage.end())
174 {
175 const std::string virtualFilePath = mAvailableFontsInPackage[fontName];
176 std::vector<uint8_t> binaryFileData = Utility::ReadPackedFile(virtualFilePath);
177
178 mFontResources[key] = std::make_shared<FontResources>(mRenderResourceContext, this, fontName, binaryFileData, fontSize);
179 mFontResources[key]->StoreFontAtlasesInFiles(bStoreFontAtlasesInFiles);
180
181 return mFontResources[key];
182 }
183 else
184 {
185 // Log Font {fontName} is not avalable in asset package
186 }
187 }
188 }
189 else
190 {
191 if (!mAvailableFontsInFolder.empty())
192 {
193 auto foundInFolder = mAvailableFontsInFolder.find(fontName);
194 if (foundInFolder != mAvailableFontsInFolder.end())
195 {
196 auto key = std::make_pair(fontName, fontSize);
197 mFontResources[key] = std::make_shared<FontResources>(mRenderResourceContext, this, mAvailableFontsInFolder[fontName], fontSize);
198
199 return mFontResources[key];
200 }
201 else
202 {
203 // Log Font {fontName} is not avalable in asset folder
204 }
205 }
206 }
207 }
208
209 return nullptr;
210}
static std::vector< uint8_t > ReadPackedFile(const std::string &entryPath)
Reads raw bytes of a file stored inside Pack.bin.
Definition: utility.cpp:322

◆ GetRenderResourceContext()

const RenderResourceContext & rendering_engine::TextRenderer::GetRenderResourceContext ( ) const

Returns the rendering resource context.

Returns
Reference to the rendering resource context.

Definition at line 154 of file text_renderer.cpp.

155{
156 return mRenderResourceContext;
157}

◆ GetScriptRange()

std::pair< std::uint32_t, std::uint32_t > rendering_engine::TextRenderer::GetScriptRange ( std::string  script)

Returns the Unicode codepoint range for a script.

Parameters
scriptScript identifier.
Returns
Pair of <begin, end> Unicode codepoints.

Definition at line 222 of file text_renderer.cpp.

223{
224 std::pair<std::uint32_t, std::uint32_t> result{0, 0};
225
226 auto search = sScriptRanges.find(script);
227 {
228 if (search != sScriptRanges.end())
229 return sScriptRanges[script];
230 }
231 return result;
232}

◆ GetScriptsRequiredShaping()

const std::vector< std::string > & rendering_engine::TextRenderer::GetScriptsRequiredShaping ( ) const

Returns scripts that require shaping before rendering.

Returns
List of script identifiers.

Definition at line 217 of file text_renderer.cpp.

218{
219 return sScriptsRequiresShaping;
220}

◆ LoadFontsAvailableInFolder()

void rendering_engine::TextRenderer::LoadFontsAvailableInFolder ( std::string  pathToFolder)
protected

Discovers fonts available in a filesystem folder.

Parameters
pathToFolderPath to the font folder.

Definition at line 234 of file text_renderer.cpp.

235{
236 LOG_INFO("Scanning font folder: " + pathToFolder);
237 // 1. Check if path is valid and exist
238 boost::filesystem::path pathToDirectory = boost::filesystem::path(pathToFolder);
239 const bool isValidFolderPath = boost::filesystem::exists(boost::filesystem::path(pathToFolder)) && boost::filesystem::is_directory(boost::filesystem::path(pathToFolder));
240 if (!isValidFolderPath)
241 {
242 return;
243 }
244 // 2. Iterate through files in the folder.
245 // if file is in the list of supported extensions
246 for (boost::filesystem::recursive_directory_iterator it(pathToDirectory), end;
247 it != end;
248 ++it)
249 {
250 const boost::filesystem::path& filePath = it->path();
251
252 if (!boost::filesystem::is_regular_file(filePath))
253 continue;
254
255 const std::string ext = filePath.extension().string();
256 if (ext != ".ttf" && ext != ".otf")
257 continue;
258
259 // Fonts name and file path stored for future runtime loading
260 std::string fontName = filePath.stem().string();
261 mAvailableFontsInFolder[fontName] = filePath.string();
262 }
263 LOG_INFO("Discovered " +
264 std::to_string(mAvailableFontsInFolder.size()) +
265 " fonts in folder.");
266}

◆ LoadFontsAvailableInPackage()

void rendering_engine::TextRenderer::LoadFontsAvailableInPackage ( )
protected

Discovers fonts available in the application package.

Definition at line 309 of file text_renderer.cpp.

310{
311 LOG_INFO("Scanning fonts in package...");
312 const auto& entries = Utility::GetPackEntries();
313
314 std::string folderEntry = { "Fonts/" };
315 for (auto& entry : entries)
316 {
317 const std::string& virtualPath = entry.first;
318 if (virtualPath.rfind(folderEntry, 0) == 0) // starts with Fonts/
319 {
320 auto fontFilePath = boost::filesystem::path(virtualPath);
321 const std::string ext = fontFilePath.extension().string();
322 if (ext != ".ttf" && ext != ".otf")
323 continue;
324
325 // Fonts name and virtual path stored for future runtime loading
326 std::string fontName = fontFilePath.stem().string();
327 mAvailableFontsInPackage[fontName] = fontFilePath.string();
328 }
329 }
330 LOG_INFO("Discovered " +
331 std::to_string(mAvailableFontsInPackage.size()) +
332 " fonts in package.");
333}
static const PackEntries & GetPackEntries()
Returns the manifest of packed files.
Definition: utility.cpp:281

◆ LoadFontsFromFolder()

void rendering_engine::TextRenderer::LoadFontsFromFolder ( std::string  pathToFolder)

Loads fonts from a filesystem folder.

Parameters
pathToFolderPath to the folder containing font files.

Definition at line 135 of file text_renderer.cpp.

136{
137 LOG_INFO("Loading fonts from folder: " + pathToFolder);
138 auto start = std::chrono::steady_clock::now();
139 LoadFontsAvailableInFolder(pathToFolder);
140 LoadPreloadableFontAtlasesFromFolder(mAvailableFontsInFolder);
141 auto end = std::chrono::steady_clock::now();
142 float ms = std::chrono::duration<float, std::milli>(end - start).count();
143
144 LOG_INFO("Font discovery and preload complete in " +
145 std::to_string(ms) + " ms.");
146}
void LoadFontsAvailableInFolder(std::string pathToFolder)
Discovers fonts available in a filesystem folder.
void LoadPreloadableFontAtlasesFromFolder(const std::unordered_map< std::string, std::string > &availableFontsInFolder)
Loads preloadable font atlases from a folder.

◆ LoadFontsFromPackage()

void rendering_engine::TextRenderer::LoadFontsFromPackage ( )

Loads fonts bundled inside an application package.

Definition at line 148 of file text_renderer.cpp.

149{
151 LoadPreloadableFontAtlasesFromPackage(mAvailableFontsInPackage);
152}
void LoadFontsAvailableInPackage()
Discovers fonts available in the application package.
void LoadPreloadableFontAtlasesFromPackage(const std::unordered_map< std::string, std::string > &availableFontsInPackage)
Loads preloadable font atlases from the application package.

◆ LoadPreloadableFontAtlasesFromFolder()

void rendering_engine::TextRenderer::LoadPreloadableFontAtlasesFromFolder ( const std::unordered_map< std::string, std::string > &  availableFontsInFolder)
protected

Loads preloadable font atlases from a folder.

Parameters
availableFontsInFolderMap of font names to file paths.

Definition at line 268 of file text_renderer.cpp.

269{
270 LOG_INFO("Preloading font atlases from folder...");
271 auto start = std::chrono::steady_clock::now();
272 AppConfig appConfig = Utility::ReadConfigFile();
273
274 for (const auto& [fontName, filePath] : availableFontsInFolder)
275 {
276 for (auto requestedScript : appConfig.textScripts)
277 {
278 auto preloadableScriptIt = std::find(sFontAtlasPreloadableScripts.begin(), sFontAtlasPreloadableScripts.end(), requestedScript);
279 if (preloadableScriptIt != sFontAtlasPreloadableScripts.end())
280 {
281 for (auto fontSize : appConfig.fontSizePreload)
282 {
283 auto key = std::make_pair(fontName, fontSize);
284 if (mFontResources.find(key) == mFontResources.end())
285 {
286 LOG_DEBUG("Creating font resource: " + fontName +
287 " size " + std::to_string(fontSize));
288 mFontResources[key] = std::make_shared<FontResources>(mRenderResourceContext, this, filePath, fontSize);
289 mFontResources[key]->StoreFontAtlasesInFiles(bStoreFontAtlasesInFiles);
290 }
291 LOG_DEBUG("Preloading script '" + requestedScript +
292 "' for font " + fontName +
293 " size " + std::to_string(fontSize));
294 const std::uint32_t rangeBegin = sScriptRanges[requestedScript].first;
295 const std::uint32_t rangeEnd = sScriptRanges[requestedScript].second;
296 mFontResources[key]->LoadGlyphsFromCodePointRange(rangeBegin, rangeEnd);
297 }
298 }
299 }
300 }
301
302 auto end = std::chrono::steady_clock::now();
303 float ms = std::chrono::duration<float, std::milli>(end - start).count();
304
305 LOG_INFO("Font atlas preloading (folder) completed in " +
306 std::to_string(ms) + " ms.");
307}
static AppConfig ReadConfigFile()
Reads application settings from the JSON config file.
Definition: utility.cpp:34
#define LOG_DEBUG(msg)
Definition: logger.hpp:38

◆ LoadPreloadableFontAtlasesFromPackage()

void rendering_engine::TextRenderer::LoadPreloadableFontAtlasesFromPackage ( const std::unordered_map< std::string, std::string > &  availableFontsInPackage)
protected

Loads preloadable font atlases from the application package.

Parameters
availableFontsInPackageMap of font names to package paths.

Definition at line 335 of file text_renderer.cpp.

336{
337 LOG_INFO("Preloading font atlases from package...");
338 auto start = std::chrono::steady_clock::now();
339 AppConfig appConfig = Utility::ReadConfigFile();
340
341 for (const auto& [fontName, virtualFilePath] : availableFontsInPackage)
342 {
343 for (auto requestedScript : appConfig.textScripts)
344 {
345 auto preloadableScriptIt = std::find(sFontAtlasPreloadableScripts.begin(), sFontAtlasPreloadableScripts.end(), requestedScript);
346 if (preloadableScriptIt != sFontAtlasPreloadableScripts.end())
347 {
348 for (auto fontSize : appConfig.fontSizePreload)
349 {
350 auto key = std::make_pair(fontName, fontSize);
351 if (mFontResources.find(key) == mFontResources.end())
352 {
353 std::vector<uint8_t> binaryFileData = Utility::ReadPackedFile(virtualFilePath);
354 LOG_DEBUG("Creating font resource: " + fontName +
355 " size " + std::to_string(fontSize));
356 mFontResources[key] = std::make_shared<FontResources>(mRenderResourceContext, this, fontName, binaryFileData, fontSize);
357 mFontResources[key]->StoreFontAtlasesInFiles(bStoreFontAtlasesInFiles);
358 }
359 LOG_DEBUG("Preloading script '" + requestedScript +
360 "' for font " + fontName +
361 " size " + std::to_string(fontSize));
362 const std::uint32_t rangeBegin = sScriptRanges[requestedScript].first;
363 const std::uint32_t rangeEnd = sScriptRanges[requestedScript].second;
364 mFontResources[key]->LoadGlyphsFromCodePointRange(rangeBegin, rangeEnd);
365 }
366 }
367 }
368 }
369
370 auto end = std::chrono::steady_clock::now();
371 float ms = std::chrono::duration<float, std::milli>(end - start).count();
372
373 LOG_INFO("Font atlas preloading (package) completed in " +
374 std::to_string(ms) + " ms.");
375}

◆ Shutdown()

void rendering_engine::TextRenderer::Shutdown ( )

Definition at line 119 of file text_renderer.cpp.

120{
121 LOG_INFO("Shutting down TextRenderer...");
122 if (!mLibrary)
123 return;
124
125 for (auto& fontResource : mFontResources)
126 fontResource.second.reset();
127
128 mFontResources.clear();
129
130 FT_Done_FreeType(mLibrary);
131 mLibrary = nullptr;
132 LOG_INFO("TextRenderer shutdown complete.");
133}

◆ StoreFontAtlasesInFiles()

void rendering_engine::TextRenderer::StoreFontAtlasesInFiles ( bool  in)

Enables or disables storing generated font atlases to files.

Parameters
inTrue to store atlases on disk.

Definition at line 212 of file text_renderer.cpp.

213{
214 bStoreFontAtlasesInFiles = in;
215}

The documentation for this class was generated from the following files: