HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
font_font.hpp
1// Copyright Take Vos 2019-2022.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "glyph_metrics.hpp"
8#include "glyph_atlas_info.hpp"
9#include "font_weight.hpp"
10#include "font_variant.hpp"
11#include "font_metrics.hpp"
12#include "font_char_map.hpp"
13#include "font_id.hpp"
14#include "../unicode/unicode.hpp"
15#include "../i18n/i18n.hpp"
16#include "../graphic_path/graphic_path.hpp"
17#include "../utility/utility.hpp"
18#include "../container/container.hpp"
19#include <span>
20#include <vector>
21#include <map>
22#include <string>
23
24hi_export_module(hikogui.font : font);
25
26hi_export namespace hi::inline v1 {
27
32hi_export class font {
33public:
39
45
46 bool monospace = false;
47 bool serif = false;
48 font_style style = font_style::normal;
49 bool condensed = false;
51 float optical_size = 12.0;
52
57 font_char_map char_map;
58
63
66 font_metrics_em metrics;
67
71
72 font() = default;
73 virtual ~font() = default;
74 font(font const&) = delete;
75 font& operator=(font const&) = delete;
76 font(font&&) = delete;
77 font& operator=(font&&) = delete;
78
83 [[nodiscard]] virtual bool loaded() const noexcept = 0;
84
88 [[nodiscard]] glyph_id find_glyph(char32_t c) const noexcept
89 {
90 return char_map.find(c);
91 }
92
96 [[nodiscard]] lean_vector<glyph_id> find_glyph(grapheme g) const
97 {
98 // Create a glyph_ids object for a single grapheme.
99 auto r = lean_vector<glyph_id>{};
100
101 // First try composed normalization
102 for (auto const c : g.composed()) {
103 if (auto const glyph_id = find_glyph(c)) {
104 r.push_back(glyph_id);
105 } else {
106 r.clear();
107 break;
108 }
109 }
110
111 if (r.empty()) {
112 // Now try decomposed normalization
113 for (auto const c : g.decomposed()) {
114 if (auto const glyph_id = find_glyph(c)) {
115 r.push_back(glyph_id);
116 } else {
117 r.clear();
118 break;
119 }
120 }
121 }
122
123 return r;
124 }
125
134 [[nodiscard]] virtual graphic_path get_path(hi::glyph_id glyph_id) const = 0;
135
142 [[nodiscard]] virtual float get_advance(hi::glyph_id glyph_id) const = 0;
143
152 [[nodiscard]] virtual glyph_metrics get_metrics(hi::glyph_id glyph_id) const = 0;
153
158
162
170
176
182
183 void reserve(size_t count) noexcept
184 {
185 advances.reserve(count);
186 glyph_count.reserve(count);
187 glyphs.reserve(count);
188 glyph_positions.reserve(count);
189 glyph_rectangles.reserve(count);
190 }
191
197 void scale_and_offset(float s) noexcept
198 {
199 auto S = scale2{s};
200
201 for (auto& tmp : advances) {
202 tmp = s * tmp;
203 }
204 for (auto& tmp : glyph_positions) {
205 tmp = S * tmp;
206 }
207 for (auto& tmp : glyph_rectangles) {
208 tmp = S * tmp;
209 }
210 }
211 };
212
230 [[nodiscard]] virtual shape_run_result_type shape_run(iso_639 language, iso_15924 script, gstring run) const = 0;
231
232 glyph_atlas_info& atlas_info(glyph_id glyph) const
233 {
234 if (*glyph >= _glyph_atlas_table.size()) [[unlikely]] {
235 _glyph_atlas_table.resize(*glyph + 1);
236 }
237
238 hi_axiom_bounds(*glyph, _glyph_atlas_table);
239 return _glyph_atlas_table[*glyph];
240 }
241
242 [[nodiscard]] font_variant font_variant() const noexcept
243 {
244 return {weight, style};
245 }
246
247 [[nodiscard]] friend std::string to_string(font const& rhs) noexcept
248 {
249 return std::format(
250 "{} - {}: style={}{}{}{}{}{}, features={}",
251 rhs.family_name,
252 rhs.sub_family_name,
253 rhs.monospace ? 'M' : '_',
254 rhs.serif ? 'S' : '_',
255 rhs.style == font_style::italic ? 'I' : '_',
256 rhs.condensed ? 'C' : '_',
257 to_char(rhs.weight),
258 rhs.optical_size,
259 rhs.features);
260 }
261
262private:
263 mutable std::vector<glyph_atlas_info> _glyph_atlas_table;
264};
265
266} // namespace hi::inline v1
267
268// XXX #617 MSVC bug does not handle partial specialization in modules.
269hi_export template<>
270struct std::formatter<hi::font, char> : formatter<std::string_view, char> {
271 auto format(hi::font const& t, auto& fc) const
272 {
273 return formatter<string_view, char>::format(to_string(t), fc);
274 }
275};
Defined font_char_map type.
The HikoGUI namespace.
Definition array_generic.hpp:21
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
font_weight
Definition font_weight.hpp:21
@ regular
400: Normal / Regular
Definition font_weight.hpp:25
virtual glyph_metrics get_metrics(hi::glyph_id glyph_id) const =0
Load a glyph into a path.
virtual bool loaded() const noexcept=0
Return if the font is loaded.
virtual shape_run_result_type shape_run(iso_639 language, iso_15924 script, gstring run) const =0
Shape a run of graphemes.
font_metrics_em metrics
The metrics of a font.
Definition font_font.hpp:66
std::string features
A string representing the features of a font.
Definition font_font.hpp:62
std::string family_name
The family name as parsed from the font file.
Definition font_font.hpp:38
std::string sub_family_name
The sub-family name as parsed from the font file.
Definition font_font.hpp:44
virtual graphic_path get_path(hi::glyph_id glyph_id) const =0
Load a glyph into a path.
virtual float get_advance(hi::glyph_id glyph_id) const =0
Get the advance for a glyph.
glyph_id find_glyph(char32_t c) const noexcept
Get the glyph for a code-point.
Definition font_font.hpp:88
lean_vector< glyph_id > find_glyph(grapheme g) const
Get the glyphs for a grapheme.
Definition font_font.hpp:96
font_char_map char_map
A optimized character map.
Definition font_font.hpp:57
std::vector< hi::font_id > fallback_chain
List of fonts to use as a fallback for this font.
Definition font_font.hpp:70
Definition font_font.hpp:154
std::vector< size_t > glyph_count
The number of glyphs used by each grapheme.
Definition font_font.hpp:161
std::vector< point2 > glyph_positions
Position of each glyph, relative to the grapheme.
Definition font_font.hpp:175
std::vector< float > advances
The horizontal advance of each grapheme.
Definition font_font.hpp:157
std::vector< glyph_id > glyphs
The glyphs representing all the graphemes.
Definition font_font.hpp:169
void scale_and_offset(float s) noexcept
Scale and position the result of the run.
Definition font_font.hpp:197
std::vector< aarectangle > glyph_rectangles
The bounding rectangle for each glyph, relative to glyph_position.
Definition font_font.hpp:181
A font variant is one of 16 different fonts that can be part of a family.
Definition font_variant.hpp:27
Definition glyph_atlas_info.hpp:16
The identifier of a glyph in a font-file.
Definition glyph_id.hpp:22
Definition glyph_metrics.hpp:20
ISO-639 language code.
Definition iso_639.hpp:29
A grapheme-cluster, what a user thinks a character is.
Definition grapheme.hpp:168
constexpr std::u32string decomposed(unicode_normalize_config config=unicode_normalize_config::NFD()) const noexcept
Get a list of code-point normalized to NFD.
Definition grapheme.hpp:472
constexpr std::u32string composed() const noexcept
Get a list of code-point normalized to NFC.
Definition grapheme.hpp:460
T to_string(T... args)