1use std::iter;
7
8use font_types::{Int24, Tag, Uint24};
9
10use crate::{be_buffer, bebuffer::BeBuffer};
11
12pub static IFT_BASE: &[u8] = include_bytes!("../test_data/ttf/ift_base.ttf");
13
14pub static CFF_FONT: &[u8] = include_bytes!("../test_data/ttf/NotoSansJP-Regular.subset.otf");
15pub static CFF2_FONT: &[u8] = include_bytes!("../test_data/ttf/NotoSansJP-VF.subset.otf");
16
17pub const CFF_FONT_CHARSTRINGS_OFFSET: u32 = 0x1b9;
18pub const CFF2_FONT_CHARSTRINGS_OFFSET: u32 = 0x8f;
19
20pub const RELATIVE_URL_TEMPLATE: &[u8] = b"\x04foo/\x80";
22pub const ABSOLUTE_URL_TEMPLATE: &[u8] = b"\x0a//foo.bar/\x80";
23
24pub fn simple_format1() -> BeBuffer {
26 let mut buffer = be_buffer! {
27 {1u8: "format"}, 0u32, [1u32, 2, 3, 4], 2u16, {2u16: "max_glyph_map_entry_id"},
33 (Uint24::new(7)), {0u32: "glyph_map_offset"},
35 0u32, 0b00000010u8, 6u16, 4u8,
40 {b'f': "url_template[1]"},
41 {b'o': "url_template[2]"},
42 [b'o', b'/', 128u8], {3u8: "patch_format"}, {1u16: "glyph_map"}, {2u8: "entry_index[1]"},
49 [1u8, 0, 1, 0, 0] };
51
52 let offset = buffer.offset_for("glyph_map") as u32;
53 buffer.write_at("glyph_map_offset", offset);
54
55 buffer
56}
57
58pub fn format1_with_dup_urls() -> BeBuffer {
59 let mut buffer = be_buffer! {
60 1u8, 0u32, [1u32, 2, 3, 4], 4u16, {4u16: "max_glyph_map_entry_id"},
66 (Uint24::new(7)), {0u32: "glyph_map_offset"},
68 0u32, 0b00000010u8, 9u16, [8u8, b'f', b'o', b'o', b'/', b'b', b'a', b'a', b'r'], {3u8: "patch_format"}, {1u16: "glyph_map"}, {2u8: "entry_index[1]"},
79 [3u8, 4, 0, 0, 0] };
81
82 let offset = buffer.offset_for("glyph_map") as u32;
83 buffer.write_at("glyph_map_offset", offset);
84
85 buffer
86}
87
88pub fn simple_format1_with_one_charstrings_offset() -> BeBuffer {
89 let mut buffer = be_buffer! {
90 1u8, 0u8, 0u8, 0u8, 0b00000001u8, [1u32, 2, 3, 4], 2u16, {2u16: "max_glyph_map_entry_id"},
97 (Uint24::new(7)), {0u32: "glyph_map_offset"},
99 0u32, 0b00000010u8, 8u16, {b'A': "url_template[0]"},
104 {b'B': "url_template[1]"},
105 [b'C', b'D', b'E', b'F', 0xc9, 0xa4], {3u8: "patch_format"}, 456u32, {1u16: "glyph_map"}, {2u8: "entry_index[1]"},
114 [1u8, 0, 1, 0, 0] };
116
117 let offset = buffer.offset_for("glyph_map") as u32;
118 buffer.write_at("glyph_map_offset", offset);
119
120 buffer
121}
122
123pub fn simple_format1_with_two_charstrings_offsets() -> BeBuffer {
124 let mut buffer = be_buffer! {
125 1u8, 0u8, 0u8, 0u8, 0b00000011u8, [1u32, 2, 3, 4], 2u16, {2u16: "max_glyph_map_entry_id"},
132 (Uint24::new(7)), {0u32: "glyph_map_offset"},
134 0u32, 0b00000010u8, 8u16, {b'A': "url_template[0]"},
139 {b'B': "url_template[1]"},
140 [b'C', b'D', b'E', b'F', 0xc9, 0xa4], {3u8: "patch_format"}, 456u32, 789u32, {1u16: "glyph_map"}, {2u8: "entry_index[1]"},
150 [1u8, 0, 1, 0, 0] };
152
153 let offset = buffer.offset_for("glyph_map") as u32;
154 buffer.write_at("glyph_map_offset", offset);
155
156 buffer
157}
158
159pub fn u16_entries_format1() -> BeBuffer {
160 let mut buffer = be_buffer! {
161 1u8, 0u32, [1, 2, 3, 4u32], 300u16, 300u16, (Uint24::new(7)), {0u32: "glyph_map_offset"},
171 {0u32: "feature_map_offset"},
172
173 {0u8: "applied_entry_bitmap"},
175 [
176 0, 0, 0, 0, 0,
177 0, 0, 0, 0, 0, 0,
178 0, 0, 0, 0, 0, 0,
179 0, 0, 0, 0, 0, 0,
180 0, 0, 0, 0, 0, 0,
181 0, 0, 0, 0, 0, 0,
182 0, 0u8
183 ],
184
185 6u16, [4, b'f', b'o', b'o', b'/', 128u8], 3u8, {2u16: "glyph_map"}, [80, 81, 300, 300, 80u16]
195 };
196
197 let offset = buffer.offset_for("glyph_map") as u32;
198 buffer.write_at("glyph_map_offset", offset);
199
200 buffer
201}
202
203pub fn feature_map_format1() -> BeBuffer {
204 let mut buffer = be_buffer! {
205 1u8, 0u32, [1u32, 2u32, 3u32, 4u32], 400u16, 300u16, (Uint24::new(7)), {0u32: "glyph_map_offset"},
217 {0u32: "feature_map_offset"},
218
219 {0u8: "applied_entries"},
221 [
222 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0u8
227 ],
228 {0b00001000u8: "applied_entries_296"},
229 [
230 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0u8 ],
234
235 6u16, [4, b'f', b'o', b'o', b'/', 128u8], {3u8: "patch_format"}, {2u16: "glyph_map"}, [
245 80, 81, 300u16 ],
249 {299u16: "gid5_entry"}, {80u16: "gid6_entry"}, {3u16: "feature_map"}, {(Tag::new(b"dlig")): "FeatureRecord[0]"}, 400u16, 1u16, {(Tag::new(b"liga")): "FeatureRecord[1]"}, 384u16, 2u16, [b'n', b'u', b'l', b'l'], 301u16, 1u16, 81u16, 81u16, 80u16, 81u16, 299u16, 300u16, 0u16, 0u16 };
286
287 let offset = buffer.offset_for("glyph_map") as u32;
288 buffer.write_at("glyph_map_offset", offset);
289
290 let offset = buffer.offset_for("feature_map") as u32;
291 buffer.write_at("feature_map_offset", offset);
292
293 buffer
294}
295
296pub fn codepoints_only_format2() -> BeBuffer {
298 let mut buffer = be_buffer! {
299 {2u8: "format"}, 0u32, {1u32: "compat_id[0]"},
304 {2u32: "compat_id[1]"},
305 {3u32: "compat_id[2]"},
306 {4u32: "compat_id[3]"},
307
308 3u8, {(Uint24::new(4)): "entry_count"},
310 {0u32: "entries_offset"},
311 0u32, 6u16, [4, b'f', b'o', b'o', b'/', 128u8], {0b00010000u8: "entries[0]"}, [0b00001101, 0b00000011, 0b00110001u8], {0b01100000u8: "entries[1]"}, 5u16, [0b00001101, 0b00000011, 0b00110001u8], {0b00100000u8: "entries[2]"}, 5u16, [0b00001101, 0b00000011, 0b00110001u8], {0b00110000u8: "entries[3]"}, (Uint24::new(80_000)), [0b00001101, 0b00000011, 0b00110001u8] };
336
337 let offset = buffer.offset_for("entries[0]") as u32;
338 buffer.write_at("entries_offset", offset);
339
340 buffer
341}
342
343pub fn format2_with_one_charstrings_offset() -> BeBuffer {
344 let mut buffer = be_buffer! {
345 2u8, 0u8, 0u8, 0u8, {0b00000001u8: "field_flags"}, {1u32: "compat_id[0]"},
351 {2u32: "compat_id[1]"},
352 {3u32: "compat_id[2]"},
353 {4u32: "compat_id[3]"},
354
355 3u8, (Uint24::new(1)), {0u32: "entries_offset"},
358 0u32, 8u16, [b'A', b'B', b'C', b'D', b'E', b'F', 0xc9, 0xa4], {456u32: "charstrings_offset"}, {0b00010000u8: "entries[0]"}, [0b00001101, 0b00000011, 0b00110001u8] };
370
371 let offset = buffer.offset_for("entries[0]") as u32;
372 buffer.write_at("entries_offset", offset);
373
374 buffer
375}
376
377pub fn format2_with_two_charstrings_offset() -> BeBuffer {
378 let mut buffer = be_buffer! {
379 2u8, 0u8, 0u8, 0u8, 0b00000011u8, {1u32: "compat_id[0]"},
385 {2u32: "compat_id[1]"},
386 {3u32: "compat_id[2]"},
387 {4u32: "compat_id[3]"},
388
389 3u8, (Uint24::new(1)), {0u32: "entries_offset"},
392 0u32, 8u16, [b'A', b'B', b'C', b'D', b'E', b'F', 0xc9, 0xa4], 456u32, 789u32, {0b00010000u8: "entries[0]"}, [0b00001101, 0b00000011, 0b00110001u8] };
405
406 let offset = buffer.offset_for("entries[0]") as u32;
407 buffer.write_at("entries_offset", offset);
408
409 buffer
410}
411
412pub fn features_and_design_space_format2() -> BeBuffer {
413 let mut buffer = be_buffer! {
414 2u8, 0u32, [1, 2, 3, 4u32], {3u8: "patch_format"}, (Uint24::new(3)), {0u32: "entries_offset"},
423 0u32, 6u16, [4, b'f', b'o', b'o', b'/', 128u8], {0b00010001u8: "entries[0]"}, 2u8, (Tag::new(b"liga")), (Tag::new(b"smcp")), 1u16, (Tag::new(b"wdth")), {0x8000u32: "wdth start"}, 0x10000u32, [0b00001101, 0b00000011, 0b00110001u8], {0b00010001u8: "entries[1]"}, 1u8, (Tag::new(b"rlig")), 0u16, [0b00001101, 0b00000011, 0b00110001u8], {0b000100001u8: "entries[2]"}, 1u8, (Tag::new(b"smcp")), 3u16, (Tag::new(b"wght")), 0x00C8_0000u32, 0x02BC_0000u32, (Tag::new(b"wdth")), 0x0u32, 0x8000u32, (Tag::new(b"wdth")), 0x0002_0000u32, 0x0002_8000u32, 5u16, [0b00001101, 0b00000011, 0b00110001u8] };
475
476 let offset = buffer.offset_for("entries[0]") as u32;
477 buffer.write_at("entries_offset", offset);
478
479 buffer
480}
481
482pub fn child_indices_format2() -> BeBuffer {
483 let mut buffer = be_buffer! {
484 2u8, 0u32, [1, 2, 3, 4u32], {3u8: "encoding"}, (Uint24::new(9)), {0u32: "entries_offset"}, 0u32, 6u16, [4, b'f', b'o', b'o', b'/', 128u8], {0b01100000u8: "entries[0]"}, 5u16, [0b00001101, 0b00000011, 0b00110001u8], {0b00100000u8: "entries[1]"}, 50u16, [0b00001101, 0b00000011, 0b00110001u8], {0b00000001u8: "entries[2]"}, 1u8, (Tag::new(b"rlig")), 1u16, (Tag::new(b"wght")), 0x00C8_0000u32, 0x02BC_0000u32, {0b00000001u8: "entries[3]"}, 1u8, (Tag::new(b"liga")), 1u16, (Tag::new(b"wght")), 0x0032_0000, 0x0064_0000, {0b00000010u8: "entries[4]"}, 1u8, (Uint24::new(0)), {0b00000010u8: "entries[5]"}, 1u8, (Uint24::new(2)), {0b00000010u8: "entries[6]"}, {4u8: "entries[6]_child_count"}, (Uint24::new(3)), {(Uint24::new(2)): "entries[6]_child"}, (Uint24::new(1)), (Uint24::new(0)), {0b00000010u8: "entries[7]"}, 2u8, (Uint24::new(4)), (Uint24::new(5)), {0b00100010u8: "entries[8]"}, 1u8, (Uint24::new(0)), 100u16, [0b00001101, 0b00000011, 0b00110001u8] };
563
564 let offset = buffer.offset_for("entries[0]") as u32;
565 buffer.write_at("entries_offset", offset);
566
567 buffer
568}
569
570pub fn custom_ids_format2() -> BeBuffer {
572 let mut buffer = be_buffer! {
573 2u8, 0u32, {1u32: "compat_id[0]"},
578 {2u32: "compat_id[1]"},
579 {3u32: "compat_id[2]"},
580 {4u32: "compat_id[3]"},
581
582 3u8, {(Uint24::new(4)): "entry_count"}, {0u32: "entries_offset"}, 0u32, 6u16, [4, b'f', b'o', b'o', b'/', 128u8], {0b00010100u8: "entries[0]"}, {(Int24::new(-2)): "entries[0].id_delta"}, [0b00001101, 0b00000011, 0b00110001u8], {0b00100100u8: "entries[1]"}, {(Int24::new(10)): "entries[1].id_delta"}, 5u16, [0b00001101, 0b00000011, 0b00110001u8], {0b01000100u8: "entries[2]"}, {(Int24::new(14)): "id delta - ignored entry"}, {0b00101000u8: "entries[3]"}, {3u8: "entry[4] encoding"}, 10u16, [0b00001101, 0b00000011, 0b00110001u8] };
612
613 let offset = buffer.offset_for("entries[0]") as u32;
614 buffer.write_at("entries_offset", offset);
615
616 buffer
617}
618
619pub fn string_ids_format2() -> BeBuffer {
621 let mut buffer = be_buffer! {
622 2u8, 0u32, [1, 2, 3, 4u32], 3u8, (Uint24::new(6)), {0u32: "entries_offset"}, {0u32: "string_data_offset"}, 6u16, [4, b'f', b'o', b'o', b'/', 128u8], {0b00000000u8: "entries"}, 0b00000100u8, (Uint24::new(3)), 0b00000100u8, (Uint24::new(4)), 0b00000000u8, 0b00000100u8, {(Uint24::new(3)): "entry[4] id length"}, 0b00000100u8, (Uint24::new(0)), {b'a': "string_data"},
662 [b'b', b'c', b'd', b'e', b'f', b'g', b'h', b'i', b'j']
663 };
664
665 let offset = buffer.offset_for("string_data") as u32;
666 buffer.write_at("string_data_offset", offset);
667
668 let offset = buffer.offset_for("entries") as u32;
669 buffer.write_at("entries_offset", offset);
670
671 buffer
672}
673
674pub fn string_ids_format2_with_preloads() -> BeBuffer {
675 const CONTINUE_MASK: u32 = 1 << 23;
676 let mut buffer = be_buffer! {
677 2u8, 0u32, [1, 2, 3, 4u32], 3u8, (Uint24::new(5)), {0u32: "entries_offset"}, {0u32: "string_data_offset"}, 6u16, [4, b'f', b'o', b'o', b'/', 128u8], {0b00000000u8: "entries"}, 0b00000100u8, (Uint24::new(CONTINUE_MASK | 3)), (Uint24::new(CONTINUE_MASK)), (Uint24::new(4)), 0b00000000u8, 0b00000100u8, {(Uint24::new(3)): "entry[4] id length"}, 0b00000100u8, (Uint24::new(0)), {b'a': "string_data"},
715 [b'b', b'c', b'd', b'e', b'f', b'g', b'h', b'i', b'j']
716 };
717
718 let offset = buffer.offset_for("string_data") as u32;
719 buffer.write_at("string_data_offset", offset);
720
721 let offset = buffer.offset_for("entries") as u32;
722 buffer.write_at("entries_offset", offset);
723
724 buffer
725}
726
727pub fn table_keyed_format2() -> BeBuffer {
729 let mut buffer = be_buffer! {
730 2u8, 0u32, {1u32: "compat_id[0]"},
735 {2u32: "compat_id[1]"},
736 {3u32: "compat_id[2]"},
737 {4u32: "compat_id[3]"},
738
739 {1u8: "encoding"}, {(Uint24::new(1)): "entry_count"}, {0u32: "entries_offset"},
742 0u32, 6u16, [4u8, b'f', b'o', b'o', b'/'],
746 {128u8: "url_template_var_end"}, {0b00100100u8: "entries"}, {(Int24::new(0)): "id_delta"},
752 {0u16: "bias"}, [0b00001101, 0b00000011, 0b00110001u8] };
755
756 let offset = buffer.offset_for("entries") as u32;
757 buffer.write_at("entries_offset", offset);
758
759 buffer
760}
761
762pub fn table_keyed_format2_with_preload_urls() -> BeBuffer {
763 let mut buffer = be_buffer! {
764 2u8, 0u32, {1u32: "compat_id[0]"},
769 {2u32: "compat_id[1]"},
770 {3u32: "compat_id[2]"},
771 {4u32: "compat_id[3]"},
772
773 {3u8: "encoding"}, (Uint24::new(4)), {0u32: "entries_offset"},
776 0u32, 6u16, [4, b'f', b'o', b'o', b'/', 128u8], {0b00010000u8: "entries[0]"}, [0b00001101, 0b00000011, 0b00110001u8], {0b00010100u8: "entries[1]"}, (Int24::new(15)), (Int24::new(1)), (Int24::new(-10)), [0b00001101, 0b00000011, 0b00110001u8], {0b00010100u8: "entries[2]"}, (Int24::new(-11)), (Int24::new(0)), [0b00001101, 0b00000011, 0b00110001u8], {0b00010000u8: "entries[3]"}, [0b00001101, 0b00000011, 0b00110001u8] };
804
805 let offset = buffer.offset_for("entries[0]") as u32;
806 buffer.write_at("entries_offset", offset);
807
808 buffer
809}
810
811pub fn table_keyed_patch() -> BeBuffer {
813 let mut buffer = be_buffer! {
814 {(Tag::new(b"iftk")): "tag"},
815 0u32, {1u32: "compat_id"},
817 [2, 3, 4u32], 3u16, {0u32: "patch_off[0]"},
822 {0u32: "patch_off[1]"},
823 {0u32: "patch_off[2]"},
824 {0u32: "patch_off[3]"},
825
826 {(Tag::new(b"tab1")): "patch[0]"},
828 0u8, {29u32: "decompressed_len[0]"}, [0xa1, 0xe0, 0x00, 0xc0, 0x2f, 0x3a, 0x38, 0xf4, 0x01, 0xd1, 0xaf, 0x54, 0x84, 0x14, 0x71,
832 0x2a, 0x80, 0x04, 0xa2, 0x1c, 0xd3, 0xdd, 0x07u8],
833
834 {(Tag::new(b"tab2")): "patch[1]"},
836 {1u8: "flags[1]"}, 30u32, [0xa1, 0xe8, 0x00, 0xc0, 0xef, 0x48, 0x9d, 0xfa, 0xdc, 0xf1, 0xc2, 0xac, 0xc5, 0xde, 0xe4, 0xf4,
840 0xb4, 0x02, 0x48, 0x98, 0x98, 0x52, 0x64, 0xa8, 0x50, 0x20, 0x29, 0x75, 0x0bu8],
841
842 {(Tag::new(b"tab3")): "patch[2]"},
844 {2u8: "flags[2]"}, {0u32: "end"} };
847
848 let offset = buffer.offset_for("patch[0]") as u32;
849 buffer.write_at("patch_off[0]", offset);
850
851 let offset = buffer.offset_for("patch[1]") as u32;
852 buffer.write_at("patch_off[1]", offset);
853
854 let offset = buffer.offset_for("patch[2]") as u32;
855 buffer.write_at("patch_off[2]", offset);
856
857 let offset = (buffer.offset_for("end") + 4) as u32;
858 buffer.write_at("patch_off[3]", offset);
859
860 buffer
861}
862
863pub fn noop_table_keyed_patch() -> BeBuffer {
865 be_buffer! {
866 {(Tag::new(b"iftk")): "tag"},
867 0u32, [1, 2, 3, 4u32], 0u16, {0u32: "patch_off[0]"}
873 }
874}
875
876pub fn glyph_keyed_patch_header() -> BeBuffer {
878 be_buffer! {
879 {(Tag::new(b"ifgk")): "format"}, 0u32, 0u8, {6u32: "compatibility_id"},
883 [7, 8, 9u32], {0u32: "max_uncompressed_length"}
885 }
886}
887
888pub fn noop_glyf_glyph_patches() -> BeBuffer {
890 be_buffer! {
891 0u32, {1u8: "table_count"}, (Tag::new(b"glyf")), 0u32
898 }
899}
900
901pub fn glyf_u16_glyph_patches() -> BeBuffer {
903 let mut buffer = be_buffer! {
904 5u32, {1u8: "table_count"}, [2, 7u16],
909 {8u16: "gid_8"},
910 [9u16],
911 {13u16: "gid_13"},
912
913 (Tag::new(b"glyf")), {0u32: "gid_2_offset"},
917 {0u32: "gid_7_offset"},
918 {0u32: "gid_8_offset"},
919 {0u32: "gid_9_offset"},
920 {0u32: "gid_13_offset"},
921 {0u32: "end_offset"},
922
923 {b'a': "gid_2_data"},
925 [b'b', b'c'],
926
927 {b'd': "gid_7_data"},
928 [b'e', b'f', b'g'],
929
930 {b'h': "gid_8_and_9_data"},
931 [b'i', b'j', b'k', b'l'],
932
933 {b'm': "gid_13_data"},
934 [b'n']
935 };
936
937 let offset = buffer.offset_for("gid_2_data") as u32;
938 buffer.write_at("gid_2_offset", offset);
939
940 let offset = buffer.offset_for("gid_7_data") as u32;
941 buffer.write_at("gid_7_offset", offset);
942
943 let offset = buffer.offset_for("gid_8_and_9_data") as u32;
944 buffer.write_at("gid_8_offset", offset);
945
946 let offset = buffer.offset_for("gid_8_and_9_data") as u32;
947 buffer.write_at("gid_9_offset", offset);
948
949 let offset = buffer.offset_for("gid_13_data") as u32;
950 buffer.write_at("gid_13_offset", offset);
951 buffer.write_at("end_offset", offset + 2);
952
953 buffer
954}
955
956pub fn glyf_u16_glyph_patches_2() -> BeBuffer {
958 let mut buffer = be_buffer! {
959 3u32, {1u8: "table_count"}, 7u16,
964 12u16,
965 14u16,
966
967 (Tag::new(b"glyf")), {0u32: "gid_7_offset"},
971 {0u32: "gid_12_offset"},
972 {0u32: "gid_14_offset"},
973 {0u32: "end_offset"},
974
975 {b'q': "gid_7_data"},
977 [b'r'],
978
979 {b's': "gid_12_data"},
980 [b't', b'u'],
981
982 {b'v': "gid_14_data"}
983 };
984
985 let offset = buffer.offset_for("gid_7_data") as u32;
986 buffer.write_at("gid_7_offset", offset);
987
988 let offset = buffer.offset_for("gid_12_data") as u32;
989 buffer.write_at("gid_12_offset", offset);
990
991 let offset = buffer.offset_for("gid_14_data") as u32;
992 buffer.write_at("gid_14_offset", offset);
993 buffer.write_at("end_offset", offset + 1);
994
995 buffer
996}
997
998pub fn glyf_u24_glyph_patches() -> BeBuffer {
1000 let mut buffer = be_buffer! {
1001 5u32, 1u8, (Uint24::new(2)), (Uint24::new(7)), (Uint24::new(8)), (Uint24::new(9)), (Uint24::new(13)), (Tag::new(b"glyf")), {0u32: "gid_2_offset"},
1008 {0u32: "gid_7_offset"},
1009 {0u32: "gid_8_offset"},
1010 {0u32: "gid_9_offset"},
1011 {0u32: "gid_13_offset"},
1012 {0u32: "end_offset"},
1013
1014 {b'a': "gid_2_data"},
1016 [b'b', b'c'],
1017
1018 {b'd': "gid_7_data"},
1019 [b'e', b'f', b'g'],
1020
1021 {b'h': "gid_8_and_9_data"},
1022 [b'i', b'j', b'k', b'l'],
1023
1024 {b'm': "gid_13_data"},
1025 [b'n']
1026 };
1027
1028 let offset = buffer.offset_for("gid_2_data") as u32;
1029 buffer.write_at("gid_2_offset", offset);
1030
1031 let offset = buffer.offset_for("gid_7_data") as u32;
1032 buffer.write_at("gid_7_offset", offset);
1033
1034 let offset = buffer.offset_for("gid_8_and_9_data") as u32;
1035 buffer.write_at("gid_8_offset", offset);
1036
1037 let offset = buffer.offset_for("gid_8_and_9_data") as u32;
1038 buffer.write_at("gid_9_offset", offset);
1039
1040 let offset = buffer.offset_for("gid_13_data") as u32;
1041 buffer.write_at("gid_13_offset", offset);
1042 buffer.write_at("end_offset", offset + 2);
1043
1044 buffer
1045}
1046
1047pub fn glyf_and_gvar_u16_glyph_patches() -> BeBuffer {
1049 let mut buffer = be_buffer! {
1050 3u32, 2u8, [2, 7, 8u16], {(Tag::new(b"glyf")): "glyf_tag"}, {(Tag::new(b"gvar")): "gvar_tag"}, {0u32: "glyf_gid_2_offset"},
1058 {0u32: "glyf_gid_7_offset"},
1059 {0u32: "glyf_gid_8_offset"},
1060 {0u32: "gvar_gid_2_offset"},
1061 {0u32: "gvar_gid_7_offset"},
1062 {0u32: "gvar_gid_8_offset"},
1063 {0u32: "end_offset"},
1064
1065 {b'a': "glyf_gid_2_data"},
1067 [b'b', b'c'],
1068
1069 {b'd': "glyf_gid_7_data"},
1070 [b'e', b'f', b'g'],
1071
1072 {b'h': "glyf_gid_8_data"},
1073 [b'i', b'j', b'k', b'l'],
1074
1075 {b'm': "gvar_gid_2_data"},
1076 [b'n'],
1077
1078 {b'o': "gvar_gid_7_data"},
1079 [b'p', b'q'],
1080
1081 {b'r': "gvar_gid_8_data"}
1082 };
1083
1084 let offset = buffer.offset_for("glyf_gid_2_data") as u32;
1085 buffer.write_at("glyf_gid_2_offset", offset);
1086 let offset = buffer.offset_for("glyf_gid_7_data") as u32;
1087 buffer.write_at("glyf_gid_7_offset", offset);
1088 let offset = buffer.offset_for("glyf_gid_8_data") as u32;
1089 buffer.write_at("glyf_gid_8_offset", offset);
1090
1091 let offset = buffer.offset_for("gvar_gid_2_data") as u32;
1092 buffer.write_at("gvar_gid_2_offset", offset);
1093 let offset = buffer.offset_for("gvar_gid_7_data") as u32;
1094 buffer.write_at("gvar_gid_7_offset", offset);
1095 let offset = buffer.offset_for("gvar_gid_8_data") as u32;
1096 buffer.write_at("gvar_gid_8_offset", offset);
1097 buffer.write_at("end_offset", offset + 1);
1098
1099 buffer
1100}
1101
1102pub fn cff_u16_glyph_patches() -> BeBuffer {
1103 let mut buffer = be_buffer! {
1104 4u32, {1u8: "table_count"}, [1, 38,
1110 47,
1111 59u16], {(Tag::new(b"CFF ")): "tag"}, {0u32: "gid_1_offset"},
1117 {0u32: "gid_38_offset"},
1118 {0u32: "gid_47_offset"},
1119 {0u32: "gid_59_offset"},
1120 {0u32: "end_offset"},
1121
1122 {b'a': "gid_1_data"},
1124 [b'b', b'c'],
1125
1126 {b'd': "gid_38_data"},
1127 [b'e', b'f', b'g'],
1128
1129 {b'h': "gid_47_data"},
1130 [b'i', b'j', b'k', b'l'],
1131
1132 {b'm': "gid_59_data"},
1133 [b'n']
1134 };
1135
1136 let offset = buffer.offset_for("gid_1_data") as u32;
1137 buffer.write_at("gid_1_offset", offset);
1138
1139 let offset = buffer.offset_for("gid_38_data") as u32;
1140 buffer.write_at("gid_38_offset", offset);
1141
1142 let offset = buffer.offset_for("gid_47_data") as u32;
1143 buffer.write_at("gid_47_offset", offset);
1144
1145 let offset = buffer.offset_for("gid_59_data") as u32;
1146 buffer.write_at("gid_59_offset", offset);
1147 buffer.write_at("end_offset", offset + 2);
1148
1149 buffer
1150}
1151
1152pub fn short_gvar_with_shared_tuples() -> BeBuffer {
1154 let mut buffer = be_buffer! {
1157 1u16, 0u16, 1u16, 3u16, {0u32: "shared_tuples_offset"},
1163 15u16, 0u16, {0u32: "glyph_variation_data_offset"},
1166
1167 {0u16: "glyph_offset[0]"},
1169 {0u16: "glyph_offset[1]"},
1170 {0u16: "glyph_offset[2]"},
1171 {0u16: "glyph_offset[3]"},
1172 {0u16: "glyph_offset[4]"},
1173 {0u16: "glyph_offset[5]"},
1174 {0u16: "glyph_offset[6]"},
1175 {0u16: "glyph_offset[7]"},
1176 {0u16: "glyph_offset[8]"},
1177 {0u16: "glyph_offset[9]"},
1178 {0u16: "glyph_offset[10]"},
1179 {0u16: "glyph_offset[11]"},
1180 {0u16: "glyph_offset[12]"},
1181 {0u16: "glyph_offset[13]"},
1182 {0u16: "glyph_offset[14]"},
1183 {0u16: "glyph_offset[15]"},
1184
1185 {42u16: "sharedTuples[0]"},
1187 13u16,
1188 25u16,
1189
1190 {1u8: "glyph_0"}, [2, 3, 4u8],
1192 {5u8: "glyph_8"}, [6, 7, 8, 9u8], {10u8: "end"}
1193 };
1194
1195 let offset = buffer.offset_for("sharedTuples[0]") as u32;
1196 buffer.write_at("shared_tuples_offset", offset);
1197
1198 let data_offset = buffer.offset_for("glyph_0");
1199 buffer.write_at("glyph_variation_data_offset", data_offset as u32);
1200
1201 let glyph0_offset = ((buffer.offset_for("glyph_0") - data_offset) / 2) as u16;
1202 let glyph8_offset = ((buffer.offset_for("glyph_8") - data_offset) / 2) as u16;
1203 let end_offset = ((buffer.offset_for("end") + 1 - data_offset) / 2) as u16;
1204
1205 buffer.write_at("glyph_offset[0]", glyph0_offset);
1206 buffer.write_at("glyph_offset[1]", glyph8_offset);
1207 buffer.write_at("glyph_offset[2]", glyph8_offset);
1208 buffer.write_at("glyph_offset[3]", glyph8_offset);
1209 buffer.write_at("glyph_offset[4]", glyph8_offset);
1210 buffer.write_at("glyph_offset[5]", glyph8_offset);
1211 buffer.write_at("glyph_offset[6]", glyph8_offset);
1212 buffer.write_at("glyph_offset[7]", glyph8_offset);
1213 buffer.write_at("glyph_offset[8]", glyph8_offset);
1214 buffer.write_at("glyph_offset[9]", end_offset);
1215 buffer.write_at("glyph_offset[10]", end_offset);
1216 buffer.write_at("glyph_offset[11]", end_offset);
1217 buffer.write_at("glyph_offset[12]", end_offset);
1218 buffer.write_at("glyph_offset[13]", end_offset);
1219 buffer.write_at("glyph_offset[14]", end_offset);
1220 buffer.write_at("glyph_offset[15]", end_offset);
1221
1222 buffer
1223}
1224
1225pub fn long_gvar_with_shared_tuples() -> BeBuffer {
1227 let mut buffer = be_buffer! {
1230 1u16, 0u16, 1u16, 3u16, {0u32: "shared_tuples_offset"},
1236 15u16, 0b00000000_00000001u16, {0u32: "glyph_variation_data_offset"},
1239
1240 {0u32: "glyph_offset[0]"},
1242 {0u32: "glyph_offset[1]"},
1243 {0u32: "glyph_offset[2]"},
1244 {0u32: "glyph_offset[3]"},
1245 {0u32: "glyph_offset[4]"},
1246 {0u32: "glyph_offset[5]"},
1247 {0u32: "glyph_offset[6]"},
1248 {0u32: "glyph_offset[7]"},
1249 {0u32: "glyph_offset[8]"},
1250 {0u32: "glyph_offset[9]"},
1251 {0u32: "glyph_offset[10]"},
1252 {0u32: "glyph_offset[11]"},
1253 {0u32: "glyph_offset[12]"},
1254 {0u32: "glyph_offset[13]"},
1255 {0u32: "glyph_offset[14]"},
1256 {0u32: "glyph_offset[15]"},
1257
1258 {42u16: "sharedTuples[0]"},
1260 13u16,
1261 25u16,
1262
1263 {1u8: "glyph_0"}, [2, 3, 4u8],
1265 {5u8: "glyph_8"}, [6, 7, 8, 9u8], {10u8: "end"}
1266 };
1267
1268 let offset = buffer.offset_for("sharedTuples[0]") as u32;
1269 buffer.write_at("shared_tuples_offset", offset);
1270
1271 let data_offset = buffer.offset_for("glyph_0");
1272 buffer.write_at("glyph_variation_data_offset", data_offset as u32);
1273
1274 let glyph0_offset = (buffer.offset_for("glyph_0") - data_offset) as u32;
1275 let glyph8_offset = (buffer.offset_for("glyph_8") - data_offset) as u32;
1276 let end_offset = (buffer.offset_for("end") + 1 - data_offset) as u32;
1277
1278 buffer.write_at("glyph_offset[0]", glyph0_offset);
1279 buffer.write_at("glyph_offset[1]", glyph8_offset);
1280 buffer.write_at("glyph_offset[2]", glyph8_offset);
1281 buffer.write_at("glyph_offset[3]", glyph8_offset);
1282 buffer.write_at("glyph_offset[4]", glyph8_offset);
1283 buffer.write_at("glyph_offset[5]", glyph8_offset);
1284 buffer.write_at("glyph_offset[6]", glyph8_offset);
1285 buffer.write_at("glyph_offset[7]", glyph8_offset);
1286 buffer.write_at("glyph_offset[8]", glyph8_offset);
1287 buffer.write_at("glyph_offset[9]", end_offset);
1288 buffer.write_at("glyph_offset[10]", end_offset);
1289 buffer.write_at("glyph_offset[11]", end_offset);
1290 buffer.write_at("glyph_offset[12]", end_offset);
1291 buffer.write_at("glyph_offset[13]", end_offset);
1292 buffer.write_at("glyph_offset[14]", end_offset);
1293 buffer.write_at("glyph_offset[15]", end_offset);
1294
1295 buffer
1296}
1297
1298pub fn short_gvar_with_no_shared_tuples() -> BeBuffer {
1299 let mut buffer = be_buffer! {
1302 1u16, 0u16, 1u16, {0u16: "shared_tuple_count"},
1307 {0u32: "shared_tuples_offset"},
1308 15u16, 0u16, {0u32: "glyph_variation_data_offset"},
1311
1312 {0u16: "glyph_offset[0]"},
1314 {0u16: "glyph_offset[1]"},
1315 {0u16: "glyph_offset[2]"},
1316 {0u16: "glyph_offset[3]"},
1317 {0u16: "glyph_offset[4]"},
1318 {0u16: "glyph_offset[5]"},
1319 {0u16: "glyph_offset[6]"},
1320 {0u16: "glyph_offset[7]"},
1321 {0u16: "glyph_offset[8]"},
1322 {0u16: "glyph_offset[9]"},
1323 {0u16: "glyph_offset[10]"},
1324 {0u16: "glyph_offset[11]"},
1325 {0u16: "glyph_offset[12]"},
1326 {0u16: "glyph_offset[13]"},
1327 {0u16: "glyph_offset[14]"},
1328 {0u16: "glyph_offset[15]"},
1329
1330 {1u8: "glyph_0"}, [2, 3, 4u8],
1332 {5u8: "glyph_8"}, [6, 7, 8, 9u8], {10u8: "end"}
1333 };
1334
1335 let data_offset = buffer.offset_for("glyph_0");
1336 buffer.write_at("shared_tuples_offset", data_offset as u32);
1337 buffer.write_at("glyph_variation_data_offset", data_offset as u32);
1338
1339 let glyph0_offset = ((buffer.offset_for("glyph_0") - data_offset) / 2) as u16;
1340 let glyph8_offset = ((buffer.offset_for("glyph_8") - data_offset) / 2) as u16;
1341 let end_offset = ((buffer.offset_for("end") + 1 - data_offset) / 2) as u16;
1342
1343 buffer.write_at("glyph_offset[0]", glyph0_offset);
1344 buffer.write_at("glyph_offset[1]", glyph8_offset);
1345 buffer.write_at("glyph_offset[2]", glyph8_offset);
1346 buffer.write_at("glyph_offset[3]", glyph8_offset);
1347 buffer.write_at("glyph_offset[4]", glyph8_offset);
1348 buffer.write_at("glyph_offset[5]", glyph8_offset);
1349 buffer.write_at("glyph_offset[6]", glyph8_offset);
1350 buffer.write_at("glyph_offset[7]", glyph8_offset);
1351 buffer.write_at("glyph_offset[8]", glyph8_offset);
1352 buffer.write_at("glyph_offset[9]", end_offset);
1353 buffer.write_at("glyph_offset[10]", end_offset);
1354 buffer.write_at("glyph_offset[11]", end_offset);
1355 buffer.write_at("glyph_offset[12]", end_offset);
1356 buffer.write_at("glyph_offset[13]", end_offset);
1357 buffer.write_at("glyph_offset[14]", end_offset);
1358 buffer.write_at("glyph_offset[15]", end_offset);
1359
1360 buffer
1361}
1362
1363pub fn short_gvar_near_maximum_offset_size() -> BeBuffer {
1364 let buffer = be_buffer! {
1369 1u16, 0u16, 1u16, {0u16: "shared_tuple_count"},
1374 {0u32: "shared_tuples_offset"},
1375 15u16, 0u16, {0u32: "glyph_variation_data_offset"},
1378
1379 {0u16: "glyph_offset[0]"},
1381 {0u16: "glyph_offset[1]"},
1382 {0u16: "glyph_offset[2]"},
1383 {0u16: "glyph_offset[3]"},
1384 {0u16: "glyph_offset[4]"},
1385 {0u16: "glyph_offset[5]"},
1386 {0u16: "glyph_offset[6]"},
1387 {0u16: "glyph_offset[7]"},
1388 {0u16: "glyph_offset[8]"},
1389 {0u16: "glyph_offset[9]"},
1390 {0u16: "glyph_offset[10]"},
1391 {0u16: "glyph_offset[11]"},
1392 {0u16: "glyph_offset[12]"},
1393 {0u16: "glyph_offset[13]"},
1394 {0u16: "glyph_offset[14]"},
1395 {0u16: "glyph_offset[15]"},
1396
1397 {1u8: "glyph_0"}
1399 };
1400
1401 let mut buffer = buffer.extend(iter::repeat(1u8).take(131065));
1403
1404 let data_offset = buffer.offset_for("glyph_0");
1405 buffer.write_at("shared_tuples_offset", data_offset as u32);
1406 buffer.write_at("glyph_variation_data_offset", data_offset as u32);
1407
1408 buffer.write_at("glyph_offset[0]", 0u16);
1409 buffer.write_at("glyph_offset[1]", 65533u16);
1410 buffer.write_at("glyph_offset[2]", 65533u16);
1411 buffer.write_at("glyph_offset[3]", 65533u16);
1412 buffer.write_at("glyph_offset[4]", 65533u16);
1413 buffer.write_at("glyph_offset[5]", 65533u16);
1414 buffer.write_at("glyph_offset[6]", 65533u16);
1415 buffer.write_at("glyph_offset[7]", 65533u16);
1416 buffer.write_at("glyph_offset[8]", 65533u16);
1417 buffer.write_at("glyph_offset[9]", 65533u16);
1418 buffer.write_at("glyph_offset[10]", 65533u16);
1419 buffer.write_at("glyph_offset[11]", 65533u16);
1420 buffer.write_at("glyph_offset[12]", 65533u16);
1421 buffer.write_at("glyph_offset[13]", 65533u16);
1422 buffer.write_at("glyph_offset[14]", 65533u16);
1423 buffer.write_at("glyph_offset[15]", 65533u16);
1424
1425 buffer
1426}
1427
1428pub fn out_of_order_gvar_with_shared_tuples() -> BeBuffer {
1430 let mut buffer = be_buffer! {
1431 1u16, 0u16, 1u16, 3u16, {0u32: "shared_tuples_offset"},
1437 15u16, 0u16, {0u32: "glyph_variation_data_offset"},
1440
1441 {0u16: "glyph_offset[0]"},
1443 {0u16: "glyph_offset[1]"},
1444 {0u16: "glyph_offset[2]"},
1445 {0u16: "glyph_offset[3]"},
1446 {0u16: "glyph_offset[4]"},
1447 {0u16: "glyph_offset[5]"},
1448 {0u16: "glyph_offset[6]"},
1449 {0u16: "glyph_offset[7]"},
1450 {0u16: "glyph_offset[8]"},
1451 {0u16: "glyph_offset[9]"},
1452 {0u16: "glyph_offset[10]"},
1453 {0u16: "glyph_offset[11]"},
1454 {0u16: "glyph_offset[12]"},
1455 {0u16: "glyph_offset[13]"},
1456 {0u16: "glyph_offset[14]"},
1457 {0u16: "glyph_offset[15]"},
1458
1459 {1u8: "glyph_0"}, [2, 3, 4u8],
1461 {5u8: "glyph_8"}, [6, 7, 8, 9u8], {10u8: "end"},
1462
1463 {42u16: "sharedTuples[0]"},
1465 13u16,
1466 25u16
1467 };
1468
1469 let offset = buffer.offset_for("sharedTuples[0]") as u32;
1470 buffer.write_at("shared_tuples_offset", offset);
1471
1472 let data_offset = buffer.offset_for("glyph_0");
1473 buffer.write_at("glyph_variation_data_offset", data_offset as u32);
1474
1475 let glyph0_offset = ((buffer.offset_for("glyph_0") - data_offset) / 2) as u16;
1476 let glyph8_offset = ((buffer.offset_for("glyph_8") - data_offset) / 2) as u16;
1477 let end_offset = ((buffer.offset_for("end") + 1 - data_offset) / 2) as u16;
1478
1479 buffer.write_at("glyph_offset[0]", glyph0_offset);
1480 buffer.write_at("glyph_offset[1]", glyph8_offset);
1481 buffer.write_at("glyph_offset[2]", glyph8_offset);
1482 buffer.write_at("glyph_offset[3]", glyph8_offset);
1483 buffer.write_at("glyph_offset[4]", glyph8_offset);
1484 buffer.write_at("glyph_offset[5]", glyph8_offset);
1485 buffer.write_at("glyph_offset[6]", glyph8_offset);
1486 buffer.write_at("glyph_offset[7]", glyph8_offset);
1487 buffer.write_at("glyph_offset[8]", glyph8_offset);
1488 buffer.write_at("glyph_offset[9]", end_offset);
1489 buffer.write_at("glyph_offset[10]", end_offset);
1490 buffer.write_at("glyph_offset[11]", end_offset);
1491 buffer.write_at("glyph_offset[12]", end_offset);
1492 buffer.write_at("glyph_offset[13]", end_offset);
1493 buffer.write_at("glyph_offset[14]", end_offset);
1494 buffer.write_at("glyph_offset[15]", end_offset);
1495
1496 buffer
1497}