7#include "otype_utilities.hpp"
8#include "../utility/module.hpp"
12namespace hi {
inline namespace v1 {
14[[nodiscard]]
inline std::optional<float>
15otype_kern_sub0_find(
size_t &offset, std::span<std::byte const> bytes, glyph_id first_glyph_id, glyph_id second_glyph_id,
float em_scale)
18 big_uint16_buf_t num_pairs;
19 big_uint16_buf_t search_range;
20 big_uint16_buf_t entry_selector;
21 big_uint16_buf_t range_shift;
25 big_uint16_buf_t
left;
26 big_uint16_buf_t
right;
27 otype_fword_buf_t value;
30 hilet& header = implicit_cast<header_type>(offset, bytes);
31 hilet entries = implicit_cast<entry_type>(offset, bytes, *header.num_pairs);
33 hilet key = (wide_cast<uint32_t>(*first_glyph_id) << 16) | wide_cast<uint32_t>(*second_glyph_id);
34 if (
hilet entry_ptr = fast_binary_search_eq<std::endian::big>(entries, key)) {
35 return entry_ptr->value * em_scale;
46[[nodiscard]]
inline vector2
47otype_kern_v0_find(std::span<std::byte const> bytes, glyph_id first_glyph_id, glyph_id second_glyph_id,
float em_scale)
50 big_uint16_buf_t version;
51 big_uint16_buf_t num_tables;
55 big_uint16_buf_t version;
56 big_uint16_buf_t length;
57 big_uint16_buf_t coverage;
61 hilet& header = implicit_cast<header_type>(offset, bytes);
62 hi_check(*header.version == 0,
"'kern' table expect version to be version 0.");
63 hilet num_tables = *header.num_tables;
67 for (
auto i = 0_uz; i != num_tables; ++i) {
68 hilet& entry = implicit_cast<entry_type>(offset, bytes);
69 hi_check(*entry.version == 0,
"'kern' expect sub-table version to be 0.");
79 hilet entry_coverage = *entry.coverage;
81 hilet cross_stream = to_bool(entry_coverage & 0x0004);
82 hi_check(not cross_stream,
"'kern' this font contains cross-stream kerning which is unsuported.");
84 hilet format = entry_coverage >> 8;
85 hi_check(format == 0,
"'kern' this font contains a unsuported subtable.");
87 hilet kerning = otype_kern_sub0_find(offset, bytes, first_glyph_id, second_glyph_id, em_scale);
89 hilet horizontal = to_bool(entry_coverage & 0x0001);
90 hilet minimum = to_bool(entry_coverage & 0x0002);
91 hilet overwrite = to_bool(entry_coverage & 0x0008);
94 r = horizontal ? vector2{*kerning, 0.0f} : vector2{0.0f, *kerning};
104 r += horizontal ? vector2{*kerning, 0.0f} : vector2{0.0f, *kerning};
111[[nodiscard]]
inline vector2
112otype_kern_v1_find(std::span<std::byte const> bytes, glyph_id first_glyph_id, glyph_id second_glyph_id,
float em_scale)
115 big_uint32_buf_t version;
116 big_uint32_buf_t num_tables;
120 big_uint32_buf_t length;
121 big_uint16_buf_t coverage;
122 big_uint16_buf_t tuple_index;
126 hilet& header = implicit_cast<header_type>(offset, bytes);
127 hi_check(*header.version == 0x00010000,
"'kern' table expect version to be version 0x00010000.");
128 hilet num_tables = *header.num_tables;
132 for (
auto i = 0_uz; i != num_tables; ++i) {
133 auto sub_table_offset = offset;
134 hilet& entry = implicit_cast<entry_type>(sub_table_offset, bytes);
136 hilet entry_length = *entry.length;
137 hi_check(entry_length >=
sizeof(entry_type),
"'kern' subtable length is invalid.");
141 offset += entry_length;
144 hilet entry_coverage = *entry.coverage;
146 hilet cross_stream = to_bool(entry_coverage & 0x4000);
155 hilet variation = to_bool(entry_coverage & 0x2000);
156 if (variation or *entry.tuple_index != 0) {
161 hilet format = entry_coverage & 0xff;
163 hilet kerning = [&]() -> std::optional<float> {
165 return otype_kern_sub0_find(sub_table_offset, bytes, first_glyph_id, second_glyph_id, em_scale);
172 hilet vertical = to_bool(entry_coverage & 0x8000);
174 hilet kerning_2D = vertical ? vector2{0.0f, *kerning} : vector2{*kerning, 0.0f};
181[[nodiscard]]
inline vector2
182otype_kern_find(std::span<std::byte const> bytes, glyph_id first_glyph_id, glyph_id second_glyph_id,
float em_scale)
189 hilet version = *implicit_cast<big_uint16_buf_t>(bytes);
193 return otype_kern_v1_find(bytes, first_glyph_id, second_glyph_id, em_scale);
#define hi_check(expression, message,...)
Check if the expression is valid, or throw a parse_error.
Definition assert.hpp:110
#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
vector2 otype_kern_v0_find(std::span< std::byte const > bytes, glyph_id first_glyph_id, glyph_id second_glyph_id, float em_scale)
'kern' version 0 find.
Definition otype_kern.hpp:47
constexpr value_type & x() noexcept
Access the x element from the vector.
Definition vector.hpp:112