8#include "glyph_atlas_info.hpp"
9#include "../graphic_path.hpp"
10#include "../geometry/module.hpp"
11#include "../utility/module.hpp"
23hi_warning_ignore_msvc(26401);
26hi_warning_ignore_msvc(26409);
28namespace hi::inline
v1 {
49 _num_graphemes = (value >> 4) & 0xf;
50 std::get<0>(_glyphs) =
glyph_id{(value >> 16) & 0xffff};
51 std::get<1>(_glyphs) = new_id;
54 _num_graphemes = (value >> 4) & 0xf;
55 std::get<0>(_glyphs) =
glyph_id{(value >> 16) & 0xffff};
56 std::get<1>(_glyphs) =
glyph_id{(value >> 32) & 0xffff};
57 std::get<2>(_glyphs) =
glyph_id{(value >> 48) & 0xffff};
58 std::get<3>(_glyphs) = new_id;
62 [[nodiscard]]
constexpr std::size_t num_glyphs() const noexcept
67 [[nodiscard]]
constexpr std::size_t num_graphemes() const noexcept
69 return _num_graphemes;
72 constexpr void set_num_graphemes(
std::size_t num_graphemes)
noexcept
75 _num_graphemes = narrow_cast<uint8_t>(num_graphemes);
78 [[nodiscard]]
constexpr std::size_t hash() const noexcept
82 for (
auto i = 0_uz; i != _num_glyphs; ++i) {
84 r ^= std::rotl(r, 16);
90 constexpr glyph_ids_long& operator+=(glyph_id
id)
noexcept
93 if (_num_glyphs < _glyphs.size()) {
94 _glyphs[_num_glyphs++] = id;
99 [[nodiscard]]
constexpr glyph_id
const& operator[](
std::size_t i)
const noexcept
105 template<std::
size_t I>
106 [[nodiscard]]
constexpr friend glyph_id get(glyph_ids_long
const& rhs)
noexcept
109 return std::get<I>(rhs._glyphs);
112 [[nodiscard]]
constexpr friend bool operator==(glyph_ids_long
const&, glyph_ids_long
const&)
noexcept =
default;
116 uint8_t _num_graphemes;
144 constexpr glyph_ids(
glyph_ids const& other) noexcept : _font(other._font), _ptr(other._ptr)
153 hi_return_on_self_assignment(other);
166 constexpr glyph_ids(
glyph_ids&& other) noexcept : _font(other._font), _ptr(std::exchange(other._ptr, make_ptr(1))) {}
180 constexpr glyph_ids() noexcept : _font(
nullptr), _ptr(make_ptr(1)) {}
208 [[nodiscard]]
constexpr font const&
font() const noexcept
235 [[nodiscard]]
constexpr bool empty() const noexcept
237 return _ptr == make_ptr(1);
242 constexpr operator bool() const noexcept
254 template<std::
size_t N>
257 static_assert(N <= num_glyphs_mask);
259 constexpr std::size_t mask = (num_glyphs_mask << num_glyphs_shift) | 1;
260 constexpr std::size_t value = (N << num_glyphs_shift) | 1;
261 return (make_value(_ptr) & mask) == value;
276 return is_long() ? _ptr->num_glyphs() : (make_value(_ptr) >> 1) & num_glyphs_mask;
279 [[nodiscard]]
constexpr std::size_t num_graphemes() const noexcept
281 return is_long() ? _ptr->num_graphemes() : (make_value(_ptr) >> 4) & 0xf;
284 constexpr void set_num_graphemes(
std::size_t num_graphemes)
noexcept
287 _ptr->set_num_graphemes(num_graphemes);
289 hi_axiom(num_graphemes <= num_graphemes_mask);
291 (make_value(_ptr) & ~(num_graphemes_mask << num_graphemes_shift)) | (num_graphemes << num_graphemes_shift));
299 return is_long() ? _ptr->hash() : make_value(_ptr);
311 }
else if (
hilet index = short_num_glyphs(); index < num_glyphs_mask) {
312 increment_num_glyphs();
313 set_glyph(index,
id);
330 return (*_ptr)[index];
332 return get_glyph(index);
336 template<std::
size_t I>
340 return get<I>(*rhs._ptr);
343 return glyph_id{(make_value(rhs._ptr) >> shift) & 0xffff};
347 [[nodiscard]]
constexpr friend bool operator==(glyph_ids
const& lhs, glyph_ids
const& rhs)
noexcept
349 hilet lhs_value = make_value(lhs._ptr);
350 hilet rhs_value = make_value(rhs._ptr);
352 if (lhs._font != rhs._font) {
354 }
else if (lhs_value == rhs_value) {
357 return ((lhs_value | rhs_value) & 1) == 0 and *lhs._ptr == *rhs._ptr;
369 [[nodiscard]]
std::pair<
graphic_path, aarectangle> get_path_and_bounding_box() const noexcept;
375 [[nodiscard]] aarectangle get_bounding_box() const noexcept;
378 static_assert(sizeof(
std::
size_t) == sizeof(detail::glyph_ids_long *));
380 static constexpr
std::
size_t num_glyphs_shift = 1;
381 static constexpr
std::
size_t num_glyphs_mask = sizeof(
std::
size_t) == 4 ? 1 : 3;
382 static constexpr
std::
size_t num_graphemes_shift = 4;
383 static constexpr
std::
size_t num_graphemes_mask = 15;
398 detail::glyph_ids_long *_ptr;
400 constexpr
void increment_num_glyphs() noexcept
403 hi_axiom(short_num_glyphs() < num_glyphs_mask);
405 _ptr = make_ptr(make_value(_ptr) + (1 << num_glyphs_shift));
416 constexpr void set_glyph(
std::size_t i, glyph_id
id)
noexcept
422 _ptr = make_ptr((make_value(_ptr) & ~mask) | (
static_cast<std::size_t>(
id) << shift));
425 [[nodiscard]]
constexpr std::size_t short_num_glyphs() const noexcept
428 return (make_value(_ptr) >> num_glyphs_shift) & num_glyphs_mask;
431 [[nodiscard]]
constexpr bool is_short() const noexcept
433 return to_bool(make_value(_ptr) & 1);
436 [[nodiscard]]
constexpr bool is_long() const noexcept
438 return not is_short();
441 [[nodiscard]]
static constexpr detail::glyph_ids_long *make_ptr(
std::size_t value)
noexcept
443 return std::bit_cast<detail::glyph_ids_long *>(value);
446 [[nodiscard]]
static constexpr std::size_t make_value(detail::glyph_ids_long *ptr)
noexcept
448 return std::bit_cast<std::size_t>(ptr);
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:238
#define hi_assert_not_null(x,...)
Assert if an expression is not nullptr.
Definition assert.hpp:223
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
DOXYGEN BUG.
Definition algorithm.hpp:13
@ shift
The shift key is being held.
geometry/margins.hpp
Definition cache.hpp:11
Definition glyph_atlas_info.hpp:12
Definition glyph_ids.hpp:33
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:45
A set of glyph-ids of a font which composites into a single glyph.
Definition glyph_ids.hpp:135
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:266
constexpr std::size_t num_glyphs() const noexcept
Get the number of glyphs.
Definition glyph_ids.hpp:274
constexpr font const & font() const noexcept
Get the font for this glyph_ids object.
Definition glyph_ids.hpp:208
constexpr std::size_t hash() const noexcept
Get the hash value.
Definition glyph_ids.hpp:297
constexpr glyph_ids() noexcept
Create an empty glyph_ids object.
Definition glyph_ids.hpp:180
constexpr glyph_ids & operator+=(glyph_id id) noexcept
Add a glyph to this object.
Definition glyph_ids.hpp:306
constexpr bool has_num_glyphs() const noexcept
Check if this object contains a number of glyphs.
Definition glyph_ids.hpp:255
constexpr bool empty() const noexcept
Check if glyphs are attached.
Definition glyph_ids.hpp:235
constexpr glyph_ids(hi::font const &font, hi::glyph_id glyph_id) noexcept
Create a glyph_ids object from a font and a single glyph_id.
Definition glyph_ids.hpp:192
constexpr glyph_id operator[](std::size_t index) const noexcept
Get a glyph.
Definition glyph_ids.hpp:325
constexpr void clear() noexcept
Clear the glyphs in this glyph_ids object.
Definition glyph_ids.hpp:225
void set_font(hi::font const &font) noexcept
Set the font for this glyph_ids object.
Definition glyph_ids.hpp:216
glyph_ids(hi::font const &font, lean_vector< glyph_id > const &glyph_ids) noexcept
Create a glyph_ids object from a font and a list of glyph_ids.
Definition glyph_ids.hpp:199
constexpr glyph_ids(hi::font const &font) noexcept
Create an empty glyph_ids for a font.
Definition glyph_ids.hpp:188
A path is a vector graphics object.
Definition graphic_path.hpp:26
Definition tagged_id.hpp:17