HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
true_type_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 "font.hpp"
8#include "otype_sfnt.hpp"
9#include "otype_kern.hpp"
10#include "font_char_map.hpp"
11#include "../file/file_view.hpp"
12#include "../graphic_path.hpp"
13#include "../counters.hpp"
14#include "../utility/module.hpp"
15#include <memory>
16#include <filesystem>
17
18namespace hi::inline v1 {
19
20class true_type_font final : public font {
21public:
22 true_type_font(std::filesystem::path const& path) : _path(path), _view(file_view{path})
23 {
24 ++global_counter<"ttf:map">;
25 try {
26 _bytes = as_span<std::byte const>(_view);
27 parse_font_directory(_bytes);
28
29 // Clear the view to reclaim resources.
30 _view = {};
31 _bytes = {};
32 ++global_counter<"ttf:unmap">;
33
34 } catch (std::exception const &e) {
35 throw parse_error(std::format("{}: Could not parse font directory.\n{}", path.string(), e.what()));
36 }
37 }
38
39 true_type_font() = delete;
40 true_type_font(true_type_font const &other) = delete;
41 true_type_font &operator=(true_type_font const &other) = delete;
42 true_type_font(true_type_font &&other) = delete;
43 true_type_font &operator=(true_type_font &&other) = delete;
44 ~true_type_font() = default;
45
46 [[nodiscard]] bool loaded() const noexcept override
47 {
48 return to_bool(_view);
49 }
50
54 [[nodiscard]] hi::glyph_id find_glyph(char32_t c) const override;
55
63 std::optional<hi::glyph_id> load_glyph(hi::glyph_id glyph_id, graphic_path &path) const override;
64
73 bool load_glyph_metrics(hi::glyph_id glyph_id, glyph_metrics &metrics, hi::glyph_id lookahead_glyph_id = hi::glyph_id{})
74 const override;
75
76 [[nodiscard]] vector2 get_kerning(hi::glyph_id current_glyph, hi::glyph_id next_glyph) const override
77 {
78 load_view();
79 return otype_kern_find(_kern_table_bytes, current_glyph, next_glyph, _em_scale);
80 }
81
86
87private:
90 std::filesystem::path _path;
91
96 mutable file_view _view;
97
98 float OS2_x_height = 0;
99 float OS2_cap_height = 0;
100
101 float _em_scale;
102
103 uint16_t numberOfHMetrics;
104
105 int num_glyphs;
106 mutable std::span<std::byte const> _bytes;
107 mutable std::span<std::byte const> _loca_table_bytes;
108 mutable std::span<std::byte const> _glyf_table_bytes;
109 mutable std::span<std::byte const> _hmtx_table_bytes;
110 mutable std::span<std::byte const> _kern_table_bytes;
111 mutable std::span<std::byte const> _GSUB_table_bytes;
112 bool _loca_is_offset32;
113 font_char_map _char_map;
114
115 void cache_tables(std::span<std::byte const> bytes) const
116 {
117 _loca_table_bytes = otype_sfnt_search<"loca">(bytes);
118 _glyf_table_bytes = otype_sfnt_search<"glyf">(bytes);
119 _hmtx_table_bytes = otype_sfnt_search<"hmtx">(bytes);
120
121 // Optional tables.
122 _kern_table_bytes = otype_sfnt_search<"kern">(bytes);
123 _GSUB_table_bytes = otype_sfnt_search<"GSUB">(bytes);
124 }
125
126 void load_view() const noexcept
127 {
128 if (_view) {
129 [[likely]] return;
130 }
131
132 _view = file_view{_path};
133 _bytes = as_span<std::byte const>(_view);
134 ++global_counter<"ttf:map">;
135 cache_tables(_bytes);
136 }
137
143 void parse_font_directory(std::span<std::byte const> bytes);
144
147 [[nodiscard]] hi::unicode_mask parse_cmap_table_mask() const;
148
152 bool update_glyph_metrics(
153 hi::glyph_id glyph_id,
154 glyph_metrics &metrics,
155 hi::glyph_id kern_glyph1_id = hi::glyph_id{},
156 hi::glyph_id kern_glyph2_id = hi::glyph_id{}) const;
157
158 bool load_simple_glyph(std::span<std::byte const> bytes, graphic_path &glyph) const;
159
168 bool
169 load_compound_glyph(std::span<std::byte const> bytes, graphic_path &glyph, hi::glyph_id &metrics_glyph_id) const;
170
178 bool load_compound_glyph_metrics(std::span<std::byte const> bytes, hi::glyph_id &metrics_glyph_id) const;
179
186 [[nodiscard]] std::ptrdiff_t get_coverage_index(std::span<std::byte const> bytes, hi::glyph_id glyph);
187};
188
189} // namespace hi::inline v1
Defines the file_view class.
Defined font_char_map type.
DOXYGEN BUG.
Definition algorithm.hpp:13
Definition font.hpp:31
Definition glyph_metrics.hpp:16
Definition true_type_font.hpp:20
void substitution_and_kerning(iso_639 language, iso_15924 script, std::vector< substitution_and_kerning_type > &word) const override
Substitute and kern a run of glyphs.
Definition true_type_font.hpp:82
vector2 get_kerning(hi::glyph_id current_glyph, hi::glyph_id next_glyph) const override
Get the kerning between two glyphs.
Definition true_type_font.hpp:76
bool loaded() const noexcept override
Return if the font is loaded.
Definition true_type_font.hpp:46
std::optional< hi::glyph_id > load_glyph(hi::glyph_id glyph_id, graphic_path &path) const override
Load a glyph into a path.
hi::glyph_id find_glyph(char32_t c) const override
Get the glyph for a code-point.
bool load_glyph_metrics(hi::glyph_id glyph_id, glyph_metrics &metrics, hi::glyph_id lookahead_glyph_id=hi::glyph_id{}) const override
Load a glyphMetrics into a path.
A path is a vector graphics object.
Definition graphic_path.hpp:26
ISO-15924 script code.
Definition iso_15924.hpp:19
ISO-639 language code.
Definition iso_639.hpp:24
Definition language.hpp:17
T what(T... args)