7#include "otype_utilities.hpp"
8#include "font_weight.hpp"
9#include "../utility/module.hpp"
13namespace hi {
inline namespace v1 {
15[[nodiscard]]
inline auto otype_parse_os2(std::span<std::byte const> bytes,
float em_scale)
23 uint8_t stroke_variation;
30 struct header_type_0 {
31 big_uint16_buf_t version;
32 big_int16_buf_t avg_char_width;
33 big_uint16_buf_t weight_class;
34 big_uint16_buf_t width_class;
35 big_uint16_buf_t type;
36 big_int16_buf_t subscript_x_size;
37 big_int16_buf_t subscript_y_size;
38 big_int16_buf_t subscript_x_offset;
39 big_int16_buf_t subscript_y_offset;
40 big_int16_buf_t superscript_x_size;
41 big_int16_buf_t superscript_y_size;
42 big_int16_buf_t superscript_x_offset;
43 big_int16_buf_t superscript_y_offset;
44 big_int16_buf_t strikeout_size;
45 big_int16_buf_t strikeout_position;
46 big_int16_buf_t family_class;
48 big_uint32_buf_t unicode_range_1;
49 big_uint32_buf_t unicode_range_2;
50 big_uint32_buf_t unicode_range_3;
51 big_uint32_buf_t unicode_range_4;
52 big_uint32_buf_t ach_vend_id;
53 big_uint16_buf_t selection;
54 big_uint16_buf_t first_char_index;
55 big_uint16_buf_t last_char_index;
58 struct header_type_2 : header_type_0 {
59 big_int16_buf_t typo_ascender;
60 big_int16_buf_t typo_descender;
61 big_int16_buf_t typo_line_gap;
62 big_uint16_buf_t win_ascent;
63 big_uint16_buf_t win_descent;
64 big_uint32_buf_t code_page_range_1;
65 big_uint32_buf_t code_page_range_2;
66 otype_fword_buf_t x_height;
67 otype_fword_buf_t cap_height;
68 big_uint16_buf_t default_char;
69 big_uint16_buf_t break_char;
70 big_uint16_buf_t max_context;
75 bool condensed =
false;
77 bool monospace =
false;
79 float x_height = 0.0f;
80 float cap_height = 0.0f;
83 hilet& header = implicit_cast<header_type_0>(bytes);
84 hi_check(*header.version <= 5,
"'OS/2' version must be between 0 and 5");
86 auto r = return_type{};
88 hilet weight_value = *header.weight_class;
89 if (weight_value >= 1 && weight_value <= 1000) {
93 hilet width_value = *header.width_class;
94 if (width_value >= 1 && width_value <= 4) {
96 }
else if (width_value >= 5 && width_value <= 9) {
100 hilet serif_value = header.panose.serif_style;
101 if ((serif_value >= 2 && serif_value <= 10) || (serif_value >= 14 && serif_value <= 15)) {
103 }
else if (serif_value >= 11 && serif_value <= 13) {
110 switch (header.panose.weight) {
112 r.weight = font_weight::thin;
115 r.weight = font_weight::extra_light;
118 r.weight = font_weight::light;
121 r.weight = font_weight::regular;
124 r.weight = font_weight::medium;
127 r.weight = font_weight::semi_bold;
130 r.weight = font_weight::bold;
133 r.weight = font_weight::extra_bold;
136 r.weight = font_weight::black;
139 r.weight = font_weight::extra_black;
145 switch (header.panose.proportion) {
165 hilet letterform_value = header.panose.letterform;
166 if (letterform_value >= 2 && letterform_value <= 8) {
168 }
else if (letterform_value >= 9 && letterform_value <= 15) {
172 if (*header.version >= 2) {
173 hilet &header_v2 = implicit_cast<header_type_2>(bytes);
175 r.x_height = header_v2.x_height * em_scale;
176 r.cap_height = header_v2.cap_height * 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
constexpr font_weight font_weight_from_int(numeric_integral auto rhs)
Convert a font weight value between 50 and 1000 to a font weight.
Definition font_weight.hpp:46
font_weight
Definition font_weight.hpp:16
geometry/margins.hpp
Definition cache.hpp:11
@ italic
A font that is italic.