39 tt_axiom(nr_glyphs >= 0);
40 tt_axiom(nr_glyphs < std::ssize(glyph_ids));
41 glyph_ids[nr_glyphs++] = rhs;
45 [[nodiscard]]
size_t hash()
const noexcept
47 tt_axiom(nr_glyphs > 3);
48 tt_axiom(nr_glyphs < std::ssize(glyph_ids));
51 for (int8_t i = 0; i != nr_glyphs; ++i) {
60 tt_axiom(lhs.nr_glyphs > 3);
61 tt_axiom(rhs.nr_glyphs > 3);
62 tt_axiom(lhs.nr_glyphs < std::ssize(lhs.glyph_ids));
63 tt_axiom(rhs.nr_glyphs < std::ssize(rhs.glyph_ids));
65 if (lhs.nr_glyphs == rhs.nr_glyphs) {
66 for (int8_t i = 0; i != lhs.nr_glyphs; ++i) {
67 if (lhs.glyph_ids[i] != rhs.glyph_ids[i]) {
84 _glyphs.ids_short = ids_short_empty;
89 _glyphs.ids_short = ids_short_empty;
94 if (other.is_long()) {
97 _glyphs.ids_short = other._glyphs.ids_short;
103 other._glyphs.ids_short = ids_short_empty;
108 tt_return_on_self_assignment(other);
111 delete _glyphs.ids_long;
115 if (other.is_long()) {
118 _glyphs.ids_short = other._glyphs.ids_short;
128 swap(_font, other._font);
129 swap(_glyphs, other._glyphs);
136 delete _glyphs.ids_long;
140 void clear()
noexcept
143 delete _glyphs.ids_long;
145 _glyphs.ids_short = ids_short_empty;
148 operator bool()
const noexcept
153 [[nodiscard]]
font const &
font()
const noexcept
167 case 0: _glyphs.ids_short = (_glyphs.ids_short & 0xffff'ffff'0000'0000) | (uint64_t{rhs} << 16) | 1;
break;
168 case 1: _glyphs.ids_short = (_glyphs.ids_short & 0xffff'0000'ffff'0000) | (uint64_t{rhs} << 32) | 2;
break;
169 case 2: _glyphs.ids_short = (_glyphs.ids_short & 0x0000'ffff'ffff'0000) | (uint64_t{rhs} << 48) | 3;
break;
170 case 3: _glyphs.ids_long =
new font_glyph_ids_long((*
this)[0], (*
this)[1], (*
this)[2]); [[fallthrough]];
171 default: *_glyphs.ids_long += rhs;
176 [[nodiscard]]
glyph_id front()
const noexcept
185 [[nodiscard]]
glyph_id operator[](
size_t index)
const noexcept
187 tt_axiom(index < size());
189 tt_axiom(index < 18);
190 return _glyphs.ids_long->glyph_ids[index];
193 case 0:
return glyph_id{(_glyphs.ids_short >> 16) & glyph_id::mask};
194 case 1:
return glyph_id{(_glyphs.ids_short >> 32) & glyph_id::mask};
195 case 2:
return glyph_id{(_glyphs.ids_short >> 48) & glyph_id::mask};
196 default: tt_no_default();
201 [[nodiscard]]
size_t size()
const noexcept
204 return _glyphs.ids_long->nr_glyphs;
205 }
else if ((_glyphs.ids_short & 7) == 3) {
207 }
else if ((_glyphs.ids_short & 7) == 2) {
209 }
else if ((_glyphs.ids_short & 7) == 1) {
216 [[nodiscard]]
size_t hash()
const noexcept
219 return _glyphs.ids_long->hash();
226 [[nodiscard]]
aarectangle get_bounding_box()
const noexcept;
230 if (lhs._font == rhs._font and lhs.is_long() == rhs.is_long()) {
232 return *lhs._glyphs.ids_long == *rhs._glyphs.ids_long;
234 return lhs._glyphs.
ids_short == rhs._glyphs.ids_short;
242 static constexpr uint64_t ids_short_empty = 4;
249 static_assert(
sizeof(ids_long) == 8);
261 [[nodiscard]]
bool is_long() const noexcept
263 uint64_t tmp = std::bit_cast<uint64_t>(_glyphs);
265 return (tmp & 0x7) == 0;