11#include "glyph_id.hpp"
12#include "../algorithm.hpp"
13#include "../utility/module.hpp"
14#include "../unicode/unicode_mask.hpp"
20namespace hi {
inline namespace v1 {
38 [[nodiscard]]
constexpr bool empty()
const noexcept
57 [[nodiscard]]
constexpr void add(
char32_t start_code_point,
char32_t end_code_point, uint16_t start_glyph)
noexcept
62 hi_axiom(start_code_point <= end_code_point);
63 auto count = wide_cast<size_t>(end_code_point - start_code_point + 1);
64 hi_axiom(start_glyph + count < 0xffff,
"Only glyph_ids 0 through 0xfffe are valid");
70 _map.
emplace_back(start_code_point, char_cast<char32_t>(start_code_point + short_count - 1), start_glyph);
73 start_code_point += narrow_cast<char32_t>(short_count);
74 start_glyph += narrow_cast<uint16_t>(short_count);
91 return a.end_code_point < b.end_code_point;
94 auto it = _map.
begin();
96 while (it != _map.
end()) {
97 hi_axiom(prev_it->end_code_point < it->start_code_point());
99 if (mergable(*prev_it, *it)) {
100 hilet merged_count =
std::min(prev_it->count() + it->count(), entry_type::max_count);
101 hilet move_count = merged_count - prev_it->count();
102 hi_axiom(move_count <= entry_type::max_count);
104 prev_it->end_code_point += narrow_cast<char32_t>(move_count);
105 prev_it->set_count(prev_it->count() + move_count);
107 if (move_count == it->count()) {
114 it->start_glyph += narrow_cast<uint16_t>(move_count);
115 it->set_count(it->count() - move_count);
134 [[nodiscard]]
inline glyph_id
find(
char32_t code_point)
const noexcept
140 if (
hilet item_ptr = fast_lower_bound(std::span{_map}, char_cast<uint32_t>(code_point))) {
141 return item_ptr->get(code_point);
146 [[nodiscard]] unicode_mask make_mask() const noexcept
148 auto r = unicode_mask();
150 for (
hilet& entry : _map) {
151 r.add(entry.start_code_point(), entry.end_code_point + 1);
161 constexpr static size_t max_count = 0x1'0000;
163 char32_t end_code_point;
164 uint16_t start_glyph;
167 constexpr entry_type(
char32_t start_code_point,
char32_t end_code_point, uint16_t start_glyph) noexcept :
168 end_code_point(end_code_point),
169 start_glyph(start_glyph),
170 _count(narrow_cast<uint16_t>(end_code_point - start_code_point))
172 hi_axiom(start_code_point <= end_code_point);
175 [[nodiscard]]
constexpr size_t count() const noexcept
177 return wide_cast<size_t>(_count) + 1;
180 [[nodiscard]]
constexpr void set_count(
size_t new_count)
noexcept
184 _count = narrow_cast<uint16_t>(new_count - 1);
187 [[nodiscard]]
constexpr char32_t start_code_point() const noexcept
189 return end_code_point - _count;
192 [[nodiscard]]
constexpr uint16_t end_glyph() const noexcept
194 return narrow_cast<uint16_t>(start_glyph + _count);
197 [[nodiscard]]
constexpr friend bool mergable(entry_type
const& lhs, entry_type
const& rhs)
noexcept
199 return lhs.end_code_point + 1 == rhs.start_code_point() and lhs.end_glyph() + 1 == rhs.start_glyph;
202 [[nodiscard]]
constexpr glyph_id get(
char32_t code_point)
const noexcept
204 auto diff = wide_cast<ptrdiff_t>(code_point) - wide_cast<ptrdiff_t>(end_code_point);
213 return glyph_id{truncate<uint16_t>(diff)};
220 bool _prepared =
false;
#define hi_assert(expression,...)
Assert if expression is true.
Definition assert.hpp:184
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:238
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
DOXYGEN BUG.
Definition algorithm.hpp:13
geometry/margins.hpp
Definition cache.hpp:11
Character map of a font.
Definition font_char_map.hpp:30
constexpr void reserve(size_t n)
Reserve space for a set of ranges to be added.
Definition font_char_map.hpp:46
glyph_id find(char32_t code_point) const noexcept
Find a glyph for a code_point.
Definition font_char_map.hpp:134
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:57
void prepare() noexcept
Prepare the map for searching.
Definition font_char_map.hpp:83
T emplace_back(T... args)
T shrink_to_fit(T... args)