12#include FT_TRUETYPE_TABLES_H
21 mRenderResourceContext(rrc),
22 mTextRenderer(textRenderer),
24 mErrorResult(FT_Err_Ok),
27 mFontName = boost::filesystem::path(filepath).stem().string();
32 throw std::runtime_error{
"Failed to create new face!" };
38 throw std::runtime_error{
"Failed to set char size!" };
48 mRenderResourceContext(rrc),
49 mTextRenderer(textRenderer),
50 mErrorResult(FT_Err_Ok),
54 mFontFileBytes(fileBytes)
59 throw std::runtime_error{
"Failed to create new face!" };
65 throw std::runtime_error{
"Failed to set char size!" };
84 auto distance = end - begin;
85 std::uint32_t start = begin;
96 if (codePoints.empty())
99 std::vector<GlyphIndex> glyphs;
100 for (
auto codePoint : codePoints)
110 if (glyphIndexes.empty())
113 std::vector<GlyphIndex> lackingGlyphs;
114 for (
const auto& glyphIndex : glyphIndexes)
120 gi.
index = glyphIndex.index;
121 lackingGlyphs.push_back(gi);
124 if (!lackingGlyphs.empty())
140 throw std::runtime_error{
"Failed to load glyph!" };
146 throw std::runtime_error{
"Failed to render glyph!" };
151 const auto srcW =
mFace->glyph->bitmap.width;
152 const auto srcH =
mFace->glyph->bitmap.rows;
154 const auto dstW = srcW + padding * 2;
155 const auto dstH = srcH + padding * 2;
157 const auto bufferSize = dstW * dstH * 4;
158 std::vector<uint8_t> buffer(bufferSize, 0);
159 for (
int y = 0; y < srcH; ++y)
161 for (
int x = 0; x < srcW; ++x)
164 mFace->glyph->bitmap.buffer[y * srcW + x];
166 int dstX = x + padding;
167 int dstY = y + padding;
169 const size_t idx = (
static_cast<size_t>(dstY) *
static_cast<size_t>(dstW)
170 +
static_cast<size_t>(dstX)) * 4u;
172 buffer[idx + 0] = coverage;
173 buffer[idx + 1] = coverage;
174 buffer[idx + 2] = coverage;
175 buffer[idx + 3] = coverage;
179 glyphMetrics.
width = srcW;
180 glyphMetrics.
height = srcH;
188 glyphMetrics.
padding = padding;
190 return std::pair(glyphMetrics,
ImageData(dstW, dstH, buffer));
196 glyphIndex.
index =
static_cast<std::uint32_t
>(FT_Get_Char_Index(
mFace,
static_cast<FT_ULong
>(codePoint)));
210 std::unordered_map<std::uint32_t, std::pair<GlyphMetrics, ImageData>> glyphs;
211 for (
auto codePoint = begin; codePoint <= end; ++codePoint)
231 const std::string fileName = textureName +
".png";
233 fontAtlas.WritePngFile(fullPath.string().c_str());
235 textureCache->LoadTexture(textureName, fontAtlas);
239 const std::string materialName = textureName +
"_Mat";
248 materialCache->AddMaterial(materialSettings);
249 Material* material = materialCache->GetMaterial(materialName);
250 material->
SetVec4(
"FontColor", glm::vec4(1.0f, 1.0f, 1.0f, 1.0f));
251 material->
SetVec4(
"OutlineColor", glm::vec4(0, 0, 0, 1));
252 material->
SetFloat(
"OutlineThicknessPx", 0.0);
253 const float invW = 1.0f /
static_cast<float>(fontAtlas.GetWidth());
254 const float invH = 1.0f /
static_cast<float>(fontAtlas.GetHeight());
255 material->
SetFloat(
"InvAtlasSizeWidth", invW);
256 material->
SetFloat(
"InvAtlasSizeHeight", invH);
264 for (
auto& it : glyphs)
266 const std::uint32_t glyphIndex =
static_cast<std::uint32_t
>(FT_Get_Char_Index(
mFace,
static_cast<FT_ULong
>(it.first)));
267 mGlyphsByIndex[glyphIndex] = std::pair<GlyphMetrics, std::string>(it.second.first, materialName);
275 return FT_Get_Char_Index(
mFace, codePoint) != 0;
290 return search->second.first;
298 return std::string();
303 return std::string();
305 return search->second;
313 return std::string();
315 return search->second.second;
321 result.
index = FT_Get_Char_Index(
mFace, codePoint);
333 std::unordered_map<std::uint32_t, std::pair<GlyphMetrics, ImageData>> glyphs;
334 for (
auto glyphIndex : glyphIndexes)
353 const std::string fileName = textureName +
".png";
355 fontAtlas.WritePngFile(fullPath.string().c_str());
357 textureCache->LoadTexture(textureName, fontAtlas);
361 const std::string materialName = textureName +
"_Mat";
370 materialCache->AddMaterial(materialSettings);
371 Material* material = materialCache->GetMaterial(materialName);
372 material->
SetVec4(
"FontColor", glm::vec4(1.0f, 1.0f, 1.0f, 1.0f));
373 material->
SetVec4(
"OutlineColor", glm::vec4(0, 0, 0, 1));
374 material->
SetFloat(
"OutlineThicknessPx", 0.0f);
375 const float invW = 1.0f /
static_cast<float>(fontAtlas.GetWidth());
376 const float invH = 1.0f /
static_cast<float>(fontAtlas.GetHeight());
377 material->
SetFloat(
"InvAtlasSizeWidth", invW);
378 material->
SetFloat(
"InvAtlasSizeHeight", invH);
386 for (
auto& it : glyphs)
388 mGlyphsByIndex[it.first] = std::pair<GlyphMetrics, std::string>(it.second.first, materialName);
const FontMetrics & GetFontMetrics() const
Returns global font metrics.
FontResources(RenderResourceContext rrc, TextRenderer *textRenderer, std::string filepath, unsigned int const fontSize)
Constructs font resources from a font file.
GlyphMetrics GetGlyphMetrics(GlyphIndex glyphIndex) const
Returns metrics for a specific glyph.
static std::uint32_t sMaxGlyphsPerFontAtlas
Maximum number of glyphs per font atlas.
~FontResources()
Releases all font-related resources.
std::pair< GlyphMetrics, ImageData > CreateGlyphBitmapBy(GlyphIndex glyphIndex)
Creates a bitmap and metrics for a glyph by index.
void LoadGlyphsFromCodePointRange(std::uint32_t begin, std::uint32_t end)
Preloads glyphs for a continuous Unicode range.
void CreateFontAtlasFromRange(std::uint32_t begin, std::uint32_t end)
Creates a font atlas for a continuous code point range.
FT_Face GetFontFace()
Returns the internal font face handle.
const unsigned int mFontSize
void StoreFontAtlasesInFiles(bool in)
Enables or disables storing generated font atlases on disk.
TextRenderer * mTextRenderer
std::unordered_map< std::uint32_t, std::pair< GlyphMetrics, std::string > > mGlyphsByIndex
std::string GetFontAtlasTextureName(GlyphIndex glyphIndex) const
Returns the texture name of the atlas containing the glyph.
std::string GetFontAtlasMaterialName(GlyphIndex glyphIndex) const
Returns the material name associated with the glyph.
static unsigned int sFontAtlasPaddingPx
Padding in pixels around glyphs inside atlases.
std::vector< uint8_t > mFontFileBytes
RenderResourceContext mRenderResourceContext
void EnsureGlyphs(const std::vector< std::uint32_t > &codePoints)
Ensures glyphs for the given Unicode code points exist.
std::unordered_map< std::string, std::string > mFontAtlases
GlyphIndex GetIndexFromCodePoint(std::uint32_t codePoint) const
Resolves a Unicode code point to a glyph index.
bool HasGlyph(uint32_t codePoint) const
Checks whether a glyph exists for a code point.
bool bStoreFontAtlasesInFiles
void CreateFontAtlasFromList(const std::vector< GlyphIndex > &glyphIndexes)
Creates a font atlas for a list of glyphs.
Represents raw 2D image data stored in memory.
Represents a material instance with parameter values, texture bindings, and rendering configuration.
void InitializeRenderResources()
Initializes backend-specific GPU resources associated with this material.
void SetVec4(const std::string &name, glm::vec4 value)
Sets a vec4 parameter for the material.
void AddTexture(const std::string &textureName)
Adds a texture name to the material's list of used textures.
void SetFloat(const std::string &name, float value)
Sets a float parameter for the material.
Central text system manager and font resource registry.
FT_Library & GetFontLibrary()
Returns the internal FreeType library instance.
bool CreateTextureAtlas(std::map< char, std::pair< unsigned int, unsigned int > > &texAtlasData, ImageData &texAtlasImage)
Creates a texture atlas from the stored image collection.
static boost::filesystem::path GetContentFolderPath()
Returns absolute path to Content.
static const std::vector< MaterialParameterLayoutEntry > Font2DLayout
Global metrics describing font vertical layout.
Opaque glyph identifier within a font.
Metrics describing a single glyph and its atlas placement.
Settings required to define a material instance.
MaterialDomain materialDomain
ShadingModel shadingModel
std::string parentMaterialName
const std::vector< MaterialParameterLayoutEntry > * parameterLayout
Aggregates pointers to global rendering resource managers.
TextureCache * textureCache
MaterialCache * materialCache