8#include "glyph_atlas_info.hpp"
9#include "../graphic_path.hpp"
10#include "../geometry/axis_aligned_rectangle.hpp"
20namespace hi::inline v1 {
41 _num_graphemes = (value >> 4) & 0xf;
42 std::get<0>(_glyphs) =
glyph_id{(value >> 16) & 0xffff};
43 std::get<1>(_glyphs) = new_id;
46 _num_graphemes = (value >> 4) & 0xf;
47 std::get<0>(_glyphs) =
glyph_id{(value >> 16) & 0xffff};
48 std::get<1>(_glyphs) =
glyph_id{(value >> 32) & 0xffff};
49 std::get<2>(_glyphs) =
glyph_id{(value >> 48) & 0xffff};
50 std::get<3>(_glyphs) = new_id;
54 [[nodiscard]]
constexpr std::size_t num_glyphs() const noexcept
59 [[nodiscard]]
constexpr std::size_t num_graphemes() const noexcept
61 return _num_graphemes;
64 constexpr void set_num_graphemes(
std::size_t num_graphemes)
noexcept
66 hi_axiom(num_graphemes <= 0xf);
67 _num_graphemes =
static_cast<uint8_t
>(num_graphemes);
70 [[nodiscard]]
constexpr std::size_t hash() const noexcept
74 for (
auto i = 0_uz; i != _num_glyphs; ++i) {
76 r ^= std::rotl(r, 16);
82 constexpr glyph_ids_long &operator+=(glyph_id
id)
noexcept
85 if (_num_glyphs < _glyphs.size()) {
86 _glyphs[_num_glyphs++] = id;
91 [[nodiscard]]
constexpr glyph_id
const &operator[](
std::size_t i)
const noexcept
93 hi_axiom(i < _num_glyphs);
97 template<std::
size_t I>
98 [[nodiscard]]
constexpr friend glyph_id get(glyph_ids_long
const &rhs)
noexcept
100 hi_axiom(I < rhs._num_glyphs);
101 return std::get<I>(rhs._glyphs);
104 [[nodiscard]]
constexpr friend bool operator==(glyph_ids_long
const &, glyph_ids_long
const &)
noexcept =
default;
108 uint8_t _num_graphemes;
136 constexpr glyph_ids(
glyph_ids const &other) noexcept : _font(other._font), _ptr(other._ptr)
145 hi_return_on_self_assignment(other);
158 constexpr glyph_ids(
glyph_ids &&other) noexcept : _font(other._font), _ptr(std::exchange(other._ptr, make_ptr(1))) {}
172 constexpr glyph_ids() noexcept : _font(
nullptr), _ptr(make_ptr(1)) {}
184 [[nodiscard]]
constexpr font const &
font() const noexcept
211 [[nodiscard]]
constexpr bool empty() const noexcept
213 return _ptr == make_ptr(1);
218 constexpr operator bool() const noexcept
230 template<std::
size_t N>
233 static_assert(N <= num_glyphs_mask);
235 constexpr std::size_t mask = (num_glyphs_mask << num_glyphs_shift) | 1;
236 constexpr std::size_t value = (N << num_glyphs_shift) | 1;
237 return (make_value(_ptr) & mask) == value;
244 hi_axiom(has_num_glyphs<1>());
252 return is_long() ? _ptr->num_glyphs() : (make_value(_ptr) >> 1) & num_glyphs_mask;
255 [[nodiscard]]
constexpr std::size_t num_graphemes() const noexcept
257 return is_long() ? _ptr->num_graphemes() : (make_value(_ptr) >> 4) & 0xf;
260 constexpr void set_num_graphemes(
std::size_t num_graphemes)
noexcept
263 _ptr->set_num_graphemes(num_graphemes);
265 hi_axiom(num_graphemes <= num_graphemes_mask);
267 (make_value(_ptr) & ~(num_graphemes_mask << num_graphemes_shift)) | (num_graphemes << num_graphemes_shift));
275 return is_long() ? _ptr->hash() : make_value(_ptr);
287 }
else if (
auto index = short_num_glyphs(); index < num_glyphs_mask) {
288 increment_num_glyphs();
289 set_glyph(index,
id);
303 hi_axiom(index < num_glyphs());
306 return (*_ptr)[index];
308 return get_glyph(index);
312 template<std::
size_t I>
316 return get<I>(*rhs._ptr);
319 return glyph_id{(make_value(rhs._ptr) >> shift) & 0xffff};
323 [[nodiscard]]
constexpr friend bool operator==(glyph_ids
const &lhs, glyph_ids
const &rhs)
noexcept
325 hilet lhs_value = make_value(lhs._ptr);
326 hilet rhs_value = make_value(rhs._ptr);
328 if (lhs._font != rhs._font) {
330 }
else if (lhs_value == rhs_value) {
333 return ((lhs_value | rhs_value) & 1) == 0 and *lhs._ptr == *rhs._ptr;
354 static_assert(sizeof(
std::
size_t) == sizeof(detail::glyph_ids_long *));
356 static constexpr
std::
size_t num_glyphs_shift = 1;
357 static constexpr
std::
size_t num_glyphs_mask = sizeof(
std::
size_t) == 4 ? 1 : 3;
358 static constexpr
std::
size_t num_graphemes_shift = 4;
359 static constexpr
std::
size_t num_graphemes_mask = 15;
361 hi::
font const *_font;
374 detail::glyph_ids_long *_ptr;
376 [[nodiscard]] constexpr
void increment_num_glyphs() noexcept
378 hi_axiom(is_short());
379 hi_axiom(short_num_glyphs() < num_glyphs_mask);
381 _ptr = make_ptr(make_value(_ptr) + (1 << num_glyphs_shift));
386 hi_axiom(is_short());
388 auto shift = (index + 1) * 16;
389 return glyph_id{(make_value(_ptr) >> shift) & 0xffff};
392 constexpr void set_glyph(
std::size_t i, glyph_id
id)
noexcept
394 hi_axiom(is_short());
396 auto shift = (i + 1) * 16;
398 _ptr = make_ptr((make_value(_ptr) & ~mask) | (
static_cast<std::size_t>(
id) << shift));
401 [[nodiscard]]
constexpr std::size_t short_num_glyphs() const noexcept
403 hi_axiom(is_short());
404 return (make_value(_ptr) >> num_glyphs_shift) & num_glyphs_mask;
407 [[nodiscard]]
constexpr bool is_short() const noexcept
409 return static_cast<bool>(make_value(_ptr) & 1);
412 [[nodiscard]]
constexpr bool is_long() const noexcept
414 return not is_short();
417 [[nodiscard]]
static constexpr detail::glyph_ids_long *make_ptr(
std::size_t value)
noexcept
419 return std::bit_cast<detail::glyph_ids_long *>(value);
422 [[nodiscard]]
static constexpr std::size_t make_value(detail::glyph_ids_long *ptr)
noexcept
424 return std::bit_cast<std::size_t>(ptr);
This file includes required definitions.
#define hilet
Invariant should be the default for variables.
Definition required.hpp:23
Class which represents an axis-aligned rectangle.
Definition axis_aligned_rectangle.hpp:20
A path is a vector graphics object.
Definition graphic_path.hpp:29
Definition glyph_atlas_info.hpp:12
Definition glyph_ids.hpp:25
constexpr glyph_ids_long(std::size_t value, glyph_id new_id) noexcept
Construct a list of glyphs starting with a packed set of glyphs.
Definition glyph_ids.hpp:37
A set of glyph-ids of a font which composites into a single glyph.
Definition glyph_ids.hpp:127
glyph_atlas_info & atlas_info() const noexcept
Get information where the glyph is drawn in the atlas.
constexpr glyph_id get_single() const noexcept
Get the value of the single glyph.
Definition glyph_ids.hpp:242
constexpr std::size_t num_glyphs() const noexcept
Get the number of glyphs.
Definition glyph_ids.hpp:250
constexpr font const & font() const noexcept
Get the font for this glyph_ids object.
Definition glyph_ids.hpp:184
constexpr std::size_t hash() const noexcept
Get the hash value.
Definition glyph_ids.hpp:273
constexpr glyph_ids() noexcept
Create an empty glyph_ids object.
Definition glyph_ids.hpp:172
constexpr glyph_ids & operator+=(glyph_id id) noexcept
Add a glyph to this object.
Definition glyph_ids.hpp:282
constexpr bool has_num_glyphs() const noexcept
Check if this object contains a number of glyphs.
Definition glyph_ids.hpp:231
constexpr bool empty() const noexcept
Check if glyphs are attached.
Definition glyph_ids.hpp:211
constexpr glyph_id operator[](std::size_t index) const noexcept
Get a glyph.
Definition glyph_ids.hpp:301
constexpr void clear() noexcept
Clear the glyphs in this glyph_ids object.
Definition glyph_ids.hpp:201
void set_font(hi::font const &font) noexcept
Set the font for this glyph_ids object.
Definition glyph_ids.hpp:192
constexpr glyph_ids(hi::font const &font) noexcept
Create an empty glyph_ids for a font.
Definition glyph_ids.hpp:180