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 "../unicode/unicode.hpp"
14#include "../i18n/i18n.hpp"
15#include "../graphic_path/graphic_path.hpp"
16#include "../utility/utility.hpp"
17#include "../container/container.hpp"
18#include <span>
19#include <vector>
20#include <map>
21#include <string>
22
23hi_export_module(hikogui.font.font);
24
25hi_export namespace hi::inline v1 {
26
31hi_export class font {
32public:
38
44
45 bool monospace = false;
46 bool serif = false;
47 font_style style = font_style::normal;
48 bool condensed = false;
49 font_weight weight = font_weight::regular;
50 float optical_size = 12.0;
51
56 font_char_map char_map;
57
62
67 hi::font_metrics metrics;
68
72
73 font() = default;
74 virtual ~font() = default;
75 font(font const&) = delete;
76 font& operator=(font const&) = delete;
77 font(font&&) = delete;
78 font& operator=(font&&) = delete;
79
84 [[nodiscard]] virtual bool loaded() const noexcept = 0;
85
89 [[nodiscard]] glyph_id find_glyph(char32_t c) const noexcept
90 {
91 return char_map.find(c);
92 }
93
97 [[nodiscard]] lean_vector<glyph_id> find_glyph(grapheme g) const
98 {
99 // Create a glyph_ids object for a single grapheme.
100 auto r = lean_vector<glyph_id>{};
101
102 // First try composed normalization
103 for (auto const c : g.composed()) {
104 if (auto const glyph_id = find_glyph(c)) {
105 r.push_back(glyph_id);
106 } else {
107 r.clear();
108 break;
109 }
110 }
111
112 if (r.empty()) {
113 // Now try decomposed normalization
114 for (auto const c : g.decomposed()) {
115 if (auto const glyph_id = find_glyph(c)) {
116 r.push_back(glyph_id);
117 } else {
118 r.clear();
119 break;
120 }
121 }
122 }
123
124 return r;
125 }
126
135 [[nodiscard]] virtual graphic_path get_path(hi::glyph_id glyph_id) const = 0;
136
143 [[nodiscard]] virtual float get_advance(hi::glyph_id glyph_id) const = 0;
144
153 [[nodiscard]] virtual glyph_metrics get_metrics(hi::glyph_id glyph_id) const = 0;
154
159
163
171
177
183
184 void reserve(size_t count) noexcept
185 {
186 advances.reserve(count);
187 glyph_count.reserve(count);
188 glyphs.reserve(count);
189 glyph_positions.reserve(count);
190 glyph_rectangles.reserve(count);
191 }
192
198 void scale_and_offset(float s) noexcept
199 {
200 auto S = scale2{s};
201
202 for (auto& tmp : advances) {
203 tmp = s * tmp;
204 }
205 for (auto& tmp : glyph_positions) {
206 tmp = S * tmp;
207 }
208 for (auto& tmp : glyph_rectangles) {
209 tmp = S * tmp;
210 }
211 }
212 };
213
231 [[nodiscard]] virtual shape_run_result_type shape_run(iso_639 language, iso_15924 script, gstring run) const = 0;
232
233 glyph_atlas_info& atlas_info(glyph_id glyph) const
234 {
235 if (*glyph >= _glyph_atlas_table.size()) [[unlikely]] {
236 _glyph_atlas_table.resize(*glyph + 1);
237 }
238
239 hi_axiom_bounds(*glyph, _glyph_atlas_table);
240 return _glyph_atlas_table[*glyph];
241 }
242
243 [[nodiscard]] font_variant font_variant() const noexcept
244 {
245 return {weight, style};
246 }
247
248 [[nodiscard]] friend std::string to_string(font const& rhs) noexcept
249 {
250 return std::format(
251 "{} - {}: style={}{}{}{}{}{}, features={}",
252 rhs.family_name,
253 rhs.sub_family_name,
254 rhs.monospace ? 'M' : '_',
255 rhs.serif ? 'S' : '_',
256 rhs.style == font_style::italic ? 'I' : '_',
257 rhs.condensed ? 'C' : '_',
258 to_char(rhs.weight),
259 rhs.optical_size,
260 rhs.features);
261 }
262
263private:
264 mutable std::vector<glyph_atlas_info> _glyph_atlas_table;
265};
266
267} // namespace hi::inline v1
268
269// XXX #617 MSVC bug does not handle partial specialization in modules.
270hi_export template<>
271struct std::formatter<hi::font, char> : formatter<std::string_view, char> {
272 auto format(hi::font const& t, auto& fc) const
273 {
274 return formatter<string_view, char>::format(to_string(t), fc);
275 }
276};
Defined font_char_map type.
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
font_weight
Definition font_weight.hpp:21
hi_export hi_inline auto find_glyph(font const &font, grapheme grapheme) noexcept
Find a glyph using the given code-point.
Definition font_book.hpp:440
The HikoGUI namespace.
Definition recursive_iterator.hpp:15
font_style
The different styles a font-family comes with.
Definition font_style.hpp:27
@ italic
A font that is italic.
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:378
Definition font_font.hpp:31
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.
hi::font_metrics metrics
The metrics of a font.
Definition font_font.hpp:67
std::string features
A string representing the features of a font.
Definition font_font.hpp:61
std::string family_name
The family name as parsed from the font file.
Definition font_font.hpp:37
std::string sub_family_name
The sub-family name as parsed from the font file.
Definition font_font.hpp:43
std::vector< hi::font * > fallback_chain
List of fonts to use as a fallback for this font.
Definition font_font.hpp:71
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.
lean_vector< glyph_id > find_glyph(grapheme g) const
Get the glyphs for a grapheme.
Definition font_font.hpp:97
font_char_map char_map
A optimized character map.
Definition font_font.hpp:56
Definition font_font.hpp:155
std::vector< size_t > glyph_count
The number of glyphs used by each grapheme.
Definition font_font.hpp:162
std::vector< point2 > glyph_positions
Position of each glyph, relative to the grapheme.
Definition font_font.hpp:176
std::vector< float > advances
The horizontal advance of each grapheme.
Definition font_font.hpp:158
std::vector< glyph_id > glyphs
The glyphs representing all the graphemes.
Definition font_font.hpp:170
void scale_and_offset(float s) noexcept
Scale and position the result of the run.
Definition font_font.hpp:198
std::vector< aarectangle > glyph_rectangles
The bounding rectangle for each glyph, relative to glyph_position.
Definition font_font.hpp:182
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
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:167
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:455
constexpr std::u32string composed() const noexcept
Get a list of code-point normalized to NFC.
Definition grapheme.hpp:443
Definition tagged_id.hpp:26
T reserve(T... args)
T to_string(T... args)