11#include "glyph_id.hpp"
12#include "../algorithm/algorithm.hpp"
13#include "../utility/utility.hpp"
14#include "../macros.hpp"
22hi_export_module(hikogui.font.font_char_map);
24hi_export
namespace hi {
inline namespace v1 {
42 [[nodiscard]]
constexpr bool empty()
const noexcept
57 constexpr size_t count() const noexcept
70 for (
auto const& entry : _map) {
72 for (
auto cp = entry.start_code_point(); cp <= entry.end_code_point; ++cp) {
73 if (not mask.test(cp)) {
88 constexpr void add(
char32_t start_code_point,
char32_t end_code_point, uint16_t start_glyph)
noexcept
93 hi_axiom(start_code_point <= end_code_point);
94 auto todo = wide_cast<size_t>(end_code_point - start_code_point + 1);
96 hi_axiom(start_glyph + todo < 0xffff,
"Only glyph-ids 0 through 0xfffe are valid");
99 auto const doing =
std::min(todo, entry_type::max_count);
100 hi_axiom(doing != 0);
102 _map.
emplace_back(start_code_point, char_cast<char32_t>(start_code_point + doing - 1), start_glyph);
105 start_code_point += narrow_cast<char32_t>(doing);
106 start_glyph += narrow_cast<uint16_t>(doing);
123 return a.end_code_point < b.end_code_point;
126 auto it = _map.
begin();
128 while (it != _map.
end()) {
129 hi_axiom(prev_it->end_code_point < it->start_code_point());
131 if (mergable(*prev_it, *it)) {
132 auto const merged_count =
std::min(prev_it->count() + it->count(), entry_type::max_count);
133 auto const move_count = merged_count - prev_it->count();
134 hi_axiom(move_count <= entry_type::max_count);
136 prev_it->end_code_point += narrow_cast<char32_t>(move_count);
137 prev_it->set_count(prev_it->count() + move_count);
139 if (move_count == it->count()) {
145 hi_axiom(move_count < it->
count());
146 it->start_glyph += narrow_cast<uint16_t>(move_count);
147 it->set_count(it->count() - move_count);
166 [[nodiscard]]
inline glyph_id
find(
char32_t code_point)
const noexcept
169 hi_assert(_prepared);
172 if (
auto const item_ptr = fast_lower_bound(std::span{_map}, char_cast<uint32_t>(code_point))) {
173 return item_ptr->get(code_point);
180 constexpr static size_t max_count = 0x1'0000;
182 char32_t end_code_point;
183 uint16_t start_glyph;
186 constexpr entry_type(
char32_t start_code_point,
char32_t end_code_point, uint16_t start_glyph) noexcept :
187 end_code_point(end_code_point),
188 start_glyph(start_glyph),
189 _count(narrow_cast<uint16_t>(end_code_point - start_code_point))
191 hi_axiom(start_code_point <= end_code_point);
194 [[nodiscard]]
constexpr size_t count() const noexcept
196 return wide_cast<size_t>(_count) + 1;
199 constexpr void set_count(
size_t new_count)
noexcept
201 hi_axiom(new_count > 0);
202 hi_axiom(new_count <= max_count);
203 _count = narrow_cast<uint16_t>(new_count - 1);
206 [[nodiscard]]
constexpr char32_t start_code_point() const noexcept
208 return end_code_point - _count;
211 [[nodiscard]]
constexpr uint16_t end_glyph() const noexcept
213 return narrow_cast<uint16_t>(start_glyph + _count);
216 [[nodiscard]]
constexpr friend bool mergable(entry_type
const& lhs, entry_type
const& rhs)
noexcept
218 return lhs.end_code_point + 1 == rhs.start_code_point() and lhs.end_glyph() + 1 == rhs.start_glyph;
221 [[nodiscard]]
constexpr glyph_id get(
char32_t code_point)
const noexcept
223 auto diff = wide_cast<ptrdiff_t>(code_point) - wide_cast<ptrdiff_t>(end_code_point);
232 return glyph_id{truncate<uint16_t>(diff)};
243 bool _prepared =
false;
The HikoGUI namespace.
Definition array_generic.hpp:20
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
Character map of a font.
Definition font_char_map.hpp:34
constexpr void reserve(size_t n)
Reserve space for a set of ranges to be added.
Definition font_char_map.hpp:50
glyph_id find(char32_t code_point) const noexcept
Find a glyph for a code_point.
Definition font_char_map.hpp:166
constexpr size_t count() const noexcept
Get the number of code-points supported by the char-map.
Definition font_char_map.hpp:57
constexpr void add(char32_t start_code_point, char32_t end_code_point, uint16_t start_glyph) noexcept
Add a range of code points.
Definition font_char_map.hpp:88
constexpr size_t update_mask(std::bitset< 0x11 '0000 > &mask) const noexcept
Update a code-point mask.
Definition font_char_map.hpp:67
void prepare() noexcept
Prepare the map for searching.
Definition font_char_map.hpp:115
T emplace_back(T... args)
T shrink_to_fit(T... args)