Antkeeper  0.0.1
fonts.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Christopher J. Howard
3  *
4  * This file is part of Antkeeper source code.
5  *
6  * Antkeeper source code is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Antkeeper source code is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "game/fonts.hpp"
21 #include <engine/type/type.hpp>
26 #include "game/strings.hpp"
27 #include <codecvt>
28 
29 static void build_bitmap_font(const type::typeface& typeface, float size, const std::unordered_set<char32_t>& charset, type::bitmap_font& font, render::material& material, std::shared_ptr<gl::shader_template> shader_template)
30 {
31  // Get font metrics for given size
32  if (type::font_metrics metrics; typeface.get_metrics(size, metrics))
33  {
34  font.set_font_metrics(metrics);
35  }
36 
37  // For each UTF-32 character code in the character set
38  for (char32_t code: charset)
39  {
40  // Skip missing glyphs
41  if (!typeface.get_charset().contains(code))
42  {
43  continue;
44  }
45 
46  // Add glyph to font
47  type::bitmap_glyph& glyph = font.insert(code);
48  typeface.get_metrics(size, code, glyph.metrics);
49  typeface.get_bitmap(size, code, glyph.bitmap, glyph.bitmap_width, glyph.bitmap_height);
50  }
51 
52  // Pack glyph bitmaps into the font bitmap
53  font.pack();
54 
55  // Create font material
57 
58  // Create font bitmap variable
59  material.set_variable("font_bitmap", std::make_shared<render::matvar_texture_2d>(1, font.get_texture()));
60 
61  material.set_shader_template(shader_template);
62 }
63 
64 void load_fonts(::game& ctx)
65 {
66  // Load dyslexia-friendly typeface (if enabled)
67  bool dyslexia_font_loaded = false;
68  if (ctx.dyslexia_font)
69  {
70  const auto dyslexia_font_path = get_string(ctx, "font_dyslexia");
71  ctx.typefaces["dyslexia"] = ctx.resource_manager->load<type::typeface>(dyslexia_font_path);
72  dyslexia_font_loaded = true;
73  }
74 
75  // Load typefaces
76  if (dyslexia_font_loaded)
77  {
78  // Override standard typefaces with dyslexia-friendly typeface
79  ctx.typefaces["serif"] = ctx.typefaces["dyslexia"];
80  ctx.typefaces["sans_serif"] = ctx.typefaces["dyslexia"];
81  ctx.typefaces["monospace"] = ctx.typefaces["dyslexia"];
82  }
83  else
84  {
85  // Load standard typefaces
86  const auto serif_font_path = get_string(ctx, "font_serif");
87  const auto sans_serif_font_path = get_string(ctx, "font_sans_serif");
88  const auto monospace_font_path = get_string(ctx, "font_monospace");
89 
90  ctx.typefaces["serif"] = ctx.resource_manager->load<type::typeface>(serif_font_path);
91  ctx.typefaces["sans_serif"] = ctx.resource_manager->load<type::typeface>(sans_serif_font_path);
92  ctx.typefaces["monospace"] = ctx.resource_manager->load<type::typeface>(monospace_font_path);
93  }
94 
95  // Build character set
96  /*
97  std::unordered_set<char32_t> charset;
98  {
99  // Add all character codes from the basic Latin unicode block
100  for (char32_t code = type::unicode::block::basic_latin.first; code <= type::unicode::block::basic_latin.last; ++code)
101  charset.insert(code);
102 
103  // Add all character codes from game strings
104  for (auto it = ctx.string_map->begin(); it != ctx.string_map->end(); ++it)
105  {
106  // Convert UTF-8 string to UTF-32
107  std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> convert;
108  std::u32string u32 = convert.from_bytes(it->second);
109 
111  for (char32_t code: u32)
112  charset.insert(code);
113  }
114  }
115  */
116 
117  // Load bitmap font shader
118  std::shared_ptr<gl::shader_template> font_shader_template = ctx.resource_manager->load<gl::shader_template>("bitmap-font.glsl");
119 
120  // Point size to pixel size conversion factor
121  const float dpi = ctx.window_manager->get_display(0).get_dpi();
122  const float pt_to_px = (dpi / 72.0f) * ctx.font_scale;
123 
124  // Build debug font
125  if (auto it = ctx.typefaces.find("monospace"); it != ctx.typefaces.end())
126  {
127  build_bitmap_font(*it->second, ctx.debug_font_size_pt * pt_to_px, it->second->get_charset(), ctx.debug_font, *ctx.debug_font_material, font_shader_template);
128  }
129 
130  // Build menu font
131  if (auto it = ctx.typefaces.find("sans_serif"); it != ctx.typefaces.end())
132  {
133  build_bitmap_font(*it->second, ctx.menu_font_size_pt * pt_to_px, it->second->get_charset(), ctx.menu_font, *ctx.menu_font_material, font_shader_template);
134  }
135 
136  // Build title font
137  if (auto it = ctx.typefaces.find("serif"); it != ctx.typefaces.end())
138  {
139  build_bitmap_font(*it->second, ctx.title_font_size_pt * pt_to_px, it->second->get_charset(), ctx.title_font, *ctx.title_font_material, font_shader_template);
140  }
141 }
142 
Definition: game.hpp:121
std::unique_ptr< app::window_manager > window_manager
Definition: game.hpp:165
float debug_font_size_pt
Definition: game.hpp:343
float title_font_size_pt
Definition: game.hpp:345
type::bitmap_font menu_font
Definition: game.hpp:188
float font_scale
Definition: game.hpp:341
float menu_font_size_pt
Definition: game.hpp:344
std::unique_ptr< resource_manager > resource_manager
Definition: game.hpp:152
type::bitmap_font title_font
Definition: game.hpp:189
std::shared_ptr< render::material > debug_font_material
Definition: game.hpp:190
type::bitmap_font debug_font
Definition: game.hpp:187
bool dyslexia_font
Definition: game.hpp:342
std::shared_ptr< render::material > menu_font_material
Definition: game.hpp:191
std::unordered_map< hash::fnv1a32_t, std::shared_ptr< type::typeface > > typefaces
Definition: game.hpp:186
std::shared_ptr< render::material > title_font_material
Definition: game.hpp:192
Template used to for generating one or more shader variants from a single source.
A material is associated with exactly one shader program and contains a set of material properties wh...
Definition: material.hpp:37
void set_variable(hash::fnv1a32_t key, std::shared_ptr< material_variable_base > value)
Sets the value of a material variable with the given name.
Definition: material.cpp:95
void set_blend_mode(material_blend_mode mode) noexcept
Sets the material blend mode.
Definition: material.cpp:67
void set_shader_template(std::shared_ptr< gl::shader_template > shader_template)
Sets the material's shader template.
Definition: material.cpp:88
Raster font in which glyphs are stored as arrays of pixels.
Definition: bitmap-font.hpp:39
bool pack(bool resize=true)
Packs all glyph bitmaps into the font bitmap.
Definition: bitmap-font.cpp:57
const std::shared_ptr< gl::texture_2d > & get_texture() const noexcept
Returns a pointer to the glyph corresponding to a UTF-32 character code, or nullptr if no such glyph ...
bitmap_glyph & insert(char32_t code)
Inserts a glyph into the font.
Definition: bitmap-font.cpp:39
void set_font_metrics(const font_metrics &metrics)
Sets the font metrics.
Definition: font.cpp:39
Abstract base class for a typeface, which corresponds to a single digital font file.
Definition: typeface.hpp:50
virtual bool get_metrics(float height, font_metrics &metrics) const =0
Gets metrics for a font of the specified size.
virtual bool get_bitmap(float height, char32_t code, std::vector< std::byte > &bitmap, std::uint32_t &bitmap_width, std::uint32_t &bitmap_height) const =0
Gets a bitmap of a glyph in a font of the specified size.
const std::unordered_set< char32_t > & get_charset() const noexcept
Returns the set of characters supported by the typeface.
Definition: typeface.hpp:136
void load_fonts(::game &ctx)
Definition: fonts.cpp:64
@ translucent
Material is translucent.
std::string get_string(const ::game &ctx, hash::fnv1a32_t key)
Returns a localized string.
Definition: strings.cpp:23
Single glyph in a bitmap font.
glyph_metrics metrics
Metrics describing the glyph.
std::uint32_t bitmap_height
Height of the glyph bitmap, in pixels.
std::vector< std::byte > bitmap
Bitmap representing the glyph.
std::uint32_t bitmap_width
Width of the glyph bitmap, in pixels.
Metrics describing properties of a font.