use std::iter;
use font_types::{Int24, Tag, Uint24};
use crate::{be_buffer, bebuffer::BeBuffer};
pub static IFT_BASE: &[u8] = include_bytes!("../test_data/ttf/ift_base.ttf");
pub static CFF_FONT: &[u8] = include_bytes!("../test_data/ttf/NotoSansJP-Regular.subset.otf");
pub static CFF2_FONT: &[u8] = include_bytes!("../test_data/ttf/NotoSansJP-VF.subset.otf");
pub const CFF_FONT_CHARSTRINGS_OFFSET: u32 = 0x1b9;
pub const CFF2_FONT_CHARSTRINGS_OFFSET: u32 = 0x8f;
pub const RELATIVE_URL_TEMPLATE: &[u8] = b"\x04foo/\x80";
pub const ABSOLUTE_URL_TEMPLATE: &[u8] = b"\x0a//foo.bar/\x80";
pub fn simple_format1() -> BeBuffer {
let mut buffer = be_buffer! {
{1u8: "format"}, 0u32, [1u32, 2, 3, 4], 2u16, {2u16: "max_glyph_map_entry_id"},
(Uint24::new(7)), {0u32: "glyph_map_offset"},
0u32, 0b00000010u8,
6u16, 4u8,
{b'f': "url_template[1]"},
{b'o': "url_template[2]"},
[b'o', b'/', 128u8],
{3u8: "patch_format"},
{1u16: "glyph_map"}, {2u8: "entry_index[1]"},
[1u8, 0, 1, 0, 0] };
let offset = buffer.offset_for("glyph_map") as u32;
buffer.write_at("glyph_map_offset", offset);
buffer
}
pub fn format1_with_dup_urls() -> BeBuffer {
let mut buffer = be_buffer! {
1u8, 0u32, [1u32, 2, 3, 4], 4u16, {4u16: "max_glyph_map_entry_id"},
(Uint24::new(7)), {0u32: "glyph_map_offset"},
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]"},
[3u8, 4, 0, 0, 0] };
let offset = buffer.offset_for("glyph_map") as u32;
buffer.write_at("glyph_map_offset", offset);
buffer
}
pub fn simple_format1_with_one_charstrings_offset() -> BeBuffer {
let mut buffer = be_buffer! {
1u8, 0u8, 0u8, 0u8, 0b00000001u8, [1u32, 2, 3, 4], 2u16, {2u16: "max_glyph_map_entry_id"},
(Uint24::new(7)), {0u32: "glyph_map_offset"},
0u32, 0b00000010u8,
8u16, {b'A': "url_template[0]"},
{b'B': "url_template[1]"},
[b'C', b'D', b'E', b'F', 0xc9, 0xa4],
{3u8: "patch_format"},
456u32,
{1u16: "glyph_map"}, {2u8: "entry_index[1]"},
[1u8, 0, 1, 0, 0] };
let offset = buffer.offset_for("glyph_map") as u32;
buffer.write_at("glyph_map_offset", offset);
buffer
}
pub fn simple_format1_with_two_charstrings_offsets() -> BeBuffer {
let mut buffer = be_buffer! {
1u8, 0u8, 0u8, 0u8, 0b00000011u8, [1u32, 2, 3, 4], 2u16, {2u16: "max_glyph_map_entry_id"},
(Uint24::new(7)), {0u32: "glyph_map_offset"},
0u32, 0b00000010u8,
8u16, {b'A': "url_template[0]"},
{b'B': "url_template[1]"},
[b'C', b'D', b'E', b'F', 0xc9, 0xa4],
{3u8: "patch_format"},
456u32, 789u32,
{1u16: "glyph_map"}, {2u8: "entry_index[1]"},
[1u8, 0, 1, 0, 0] };
let offset = buffer.offset_for("glyph_map") as u32;
buffer.write_at("glyph_map_offset", offset);
buffer
}
pub fn u16_entries_format1() -> BeBuffer {
let mut buffer = be_buffer! {
1u8, 0u32, [1, 2, 3, 4u32],
300u16, 300u16,
(Uint24::new(7)),
{0u32: "glyph_map_offset"},
{0u32: "feature_map_offset"},
{0u8: "applied_entry_bitmap"},
[
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,
0, 0u8
],
6u16, [4, b'f', b'o', b'o', b'/', 128u8],
3u8,
{2u16: "glyph_map"},
[80, 81, 300, 300, 80u16]
};
let offset = buffer.offset_for("glyph_map") as u32;
buffer.write_at("glyph_map_offset", offset);
buffer
}
pub fn feature_map_format1() -> BeBuffer {
let mut buffer = be_buffer! {
1u8,
0u32,
[1u32, 2u32, 3u32, 4u32],
400u16, 300u16, (Uint24::new(7)),
{0u32: "glyph_map_offset"},
{0u32: "feature_map_offset"},
{0u8: "applied_entries"},
[
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
],
{0b00001000u8: "applied_entries_296"},
[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0u8 ],
6u16, [4, b'f', b'o', b'o', b'/', 128u8],
{3u8: "patch_format"},
{2u16: "glyph_map"},
[
80, 81, 300u16 ],
{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 };
let offset = buffer.offset_for("glyph_map") as u32;
buffer.write_at("glyph_map_offset", offset);
let offset = buffer.offset_for("feature_map") as u32;
buffer.write_at("feature_map_offset", offset);
buffer
}
pub fn codepoints_only_format2() -> BeBuffer {
let mut buffer = be_buffer! {
{2u8: "format"},
0u32,
{1u32: "compat_id[0]"},
{2u32: "compat_id[1]"},
{3u32: "compat_id[2]"},
{4u32: "compat_id[3]"},
3u8, {(Uint24::new(4)): "entry_count"},
{0u32: "entries_offset"},
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] };
let offset = buffer.offset_for("entries[0]") as u32;
buffer.write_at("entries_offset", offset);
buffer
}
pub fn format2_with_one_charstrings_offset() -> BeBuffer {
let mut buffer = be_buffer! {
2u8,
0u8, 0u8, 0u8, {0b00000001u8: "field_flags"},
{1u32: "compat_id[0]"},
{2u32: "compat_id[1]"},
{3u32: "compat_id[2]"},
{4u32: "compat_id[3]"},
3u8, (Uint24::new(1)), {0u32: "entries_offset"},
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] };
let offset = buffer.offset_for("entries[0]") as u32;
buffer.write_at("entries_offset", offset);
buffer
}
pub fn format2_with_two_charstrings_offset() -> BeBuffer {
let mut buffer = be_buffer! {
2u8,
0u8, 0u8, 0u8, 0b00000011u8,
{1u32: "compat_id[0]"},
{2u32: "compat_id[1]"},
{3u32: "compat_id[2]"},
{4u32: "compat_id[3]"},
3u8, (Uint24::new(1)), {0u32: "entries_offset"},
0u32,
8u16, [b'A', b'B', b'C', b'D', b'E', b'F', 0xc9, 0xa4],
456u32, 789u32,
{0b00010000u8: "entries[0]"}, [0b00001101, 0b00000011, 0b00110001u8] };
let offset = buffer.offset_for("entries[0]") as u32;
buffer.write_at("entries_offset", offset);
buffer
}
pub fn features_and_design_space_format2() -> BeBuffer {
let mut buffer = be_buffer! {
2u8,
0u32,
[1, 2, 3, 4u32],
{3u8: "patch_format"}, (Uint24::new(3)), {0u32: "entries_offset"},
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] };
let offset = buffer.offset_for("entries[0]") as u32;
buffer.write_at("entries_offset", offset);
buffer
}
pub fn child_indices_format2() -> BeBuffer {
let mut buffer = be_buffer! {
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] };
let offset = buffer.offset_for("entries[0]") as u32;
buffer.write_at("entries_offset", offset);
buffer
}
pub fn custom_ids_format2() -> BeBuffer {
let mut buffer = be_buffer! {
2u8,
0u32,
{1u32: "compat_id[0]"},
{2u32: "compat_id[1]"},
{3u32: "compat_id[2]"},
{4u32: "compat_id[3]"},
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] };
let offset = buffer.offset_for("entries[0]") as u32;
buffer.write_at("entries_offset", offset);
buffer
}
pub fn string_ids_format2() -> BeBuffer {
let mut buffer = be_buffer! {
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"},
[b'b', b'c', b'd', b'e', b'f', b'g', b'h', b'i', b'j']
};
let offset = buffer.offset_for("string_data") as u32;
buffer.write_at("string_data_offset", offset);
let offset = buffer.offset_for("entries") as u32;
buffer.write_at("entries_offset", offset);
buffer
}
pub fn string_ids_format2_with_preloads() -> BeBuffer {
const CONTINUE_MASK: u32 = 1 << 23;
let mut buffer = be_buffer! {
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"},
[b'b', b'c', b'd', b'e', b'f', b'g', b'h', b'i', b'j']
};
let offset = buffer.offset_for("string_data") as u32;
buffer.write_at("string_data_offset", offset);
let offset = buffer.offset_for("entries") as u32;
buffer.write_at("entries_offset", offset);
buffer
}
pub fn table_keyed_format2() -> BeBuffer {
let mut buffer = be_buffer! {
2u8,
0u32,
{1u32: "compat_id[0]"},
{2u32: "compat_id[1]"},
{3u32: "compat_id[2]"},
{4u32: "compat_id[3]"},
{1u8: "encoding"}, {(Uint24::new(1)): "entry_count"}, {0u32: "entries_offset"},
0u32,
6u16, [4u8, b'f', b'o', b'o', b'/'],
{128u8: "url_template_var_end"},
{0b00100100u8: "entries"}, {(Int24::new(0)): "id_delta"},
{0u16: "bias"}, [0b00001101, 0b00000011, 0b00110001u8] };
let offset = buffer.offset_for("entries") as u32;
buffer.write_at("entries_offset", offset);
buffer
}
pub fn table_keyed_format2_with_preload_urls() -> BeBuffer {
let mut buffer = be_buffer! {
2u8,
0u32,
{1u32: "compat_id[0]"},
{2u32: "compat_id[1]"},
{3u32: "compat_id[2]"},
{4u32: "compat_id[3]"},
{3u8: "encoding"}, (Uint24::new(4)), {0u32: "entries_offset"},
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] };
let offset = buffer.offset_for("entries[0]") as u32;
buffer.write_at("entries_offset", offset);
buffer
}
pub fn table_keyed_patch() -> BeBuffer {
let mut buffer = be_buffer! {
{(Tag::new(b"iftk")): "tag"},
0u32, {1u32: "compat_id"},
[2, 3, 4u32], 3u16,
{0u32: "patch_off[0]"},
{0u32: "patch_off[1]"},
{0u32: "patch_off[2]"},
{0u32: "patch_off[3]"},
{(Tag::new(b"tab1")): "patch[0]"},
0u8, {29u32: "decompressed_len[0]"}, [0xa1, 0xe0, 0x00, 0xc0, 0x2f, 0x3a, 0x38, 0xf4, 0x01, 0xd1, 0xaf, 0x54, 0x84, 0x14, 0x71,
0x2a, 0x80, 0x04, 0xa2, 0x1c, 0xd3, 0xdd, 0x07u8],
{(Tag::new(b"tab2")): "patch[1]"},
{1u8: "flags[1]"}, 30u32, [0xa1, 0xe8, 0x00, 0xc0, 0xef, 0x48, 0x9d, 0xfa, 0xdc, 0xf1, 0xc2, 0xac, 0xc5, 0xde, 0xe4, 0xf4,
0xb4, 0x02, 0x48, 0x98, 0x98, 0x52, 0x64, 0xa8, 0x50, 0x20, 0x29, 0x75, 0x0bu8],
{(Tag::new(b"tab3")): "patch[2]"},
{2u8: "flags[2]"}, {0u32: "end"} };
let offset = buffer.offset_for("patch[0]") as u32;
buffer.write_at("patch_off[0]", offset);
let offset = buffer.offset_for("patch[1]") as u32;
buffer.write_at("patch_off[1]", offset);
let offset = buffer.offset_for("patch[2]") as u32;
buffer.write_at("patch_off[2]", offset);
let offset = (buffer.offset_for("end") + 4) as u32;
buffer.write_at("patch_off[3]", offset);
buffer
}
pub fn noop_table_keyed_patch() -> BeBuffer {
be_buffer! {
{(Tag::new(b"iftk")): "tag"},
0u32, [1, 2, 3, 4u32], 0u16,
{0u32: "patch_off[0]"}
}
}
pub fn glyph_keyed_patch_header() -> BeBuffer {
be_buffer! {
{(Tag::new(b"ifgk")): "format"}, 0u32, 0u8, {6u32: "compatibility_id"},
[7, 8, 9u32], {0u32: "max_uncompressed_length"}
}
}
pub fn noop_glyf_glyph_patches() -> BeBuffer {
be_buffer! {
0u32, {1u8: "table_count"},
(Tag::new(b"glyf")),
0u32
}
}
pub fn glyf_u16_glyph_patches() -> BeBuffer {
let mut buffer = be_buffer! {
5u32, {1u8: "table_count"},
[2, 7u16],
{8u16: "gid_8"},
[9u16],
{13u16: "gid_13"},
(Tag::new(b"glyf")),
{0u32: "gid_2_offset"},
{0u32: "gid_7_offset"},
{0u32: "gid_8_offset"},
{0u32: "gid_9_offset"},
{0u32: "gid_13_offset"},
{0u32: "end_offset"},
{b'a': "gid_2_data"},
[b'b', b'c'],
{b'd': "gid_7_data"},
[b'e', b'f', b'g'],
{b'h': "gid_8_and_9_data"},
[b'i', b'j', b'k', b'l'],
{b'm': "gid_13_data"},
[b'n']
};
let offset = buffer.offset_for("gid_2_data") as u32;
buffer.write_at("gid_2_offset", offset);
let offset = buffer.offset_for("gid_7_data") as u32;
buffer.write_at("gid_7_offset", offset);
let offset = buffer.offset_for("gid_8_and_9_data") as u32;
buffer.write_at("gid_8_offset", offset);
let offset = buffer.offset_for("gid_8_and_9_data") as u32;
buffer.write_at("gid_9_offset", offset);
let offset = buffer.offset_for("gid_13_data") as u32;
buffer.write_at("gid_13_offset", offset);
buffer.write_at("end_offset", offset + 2);
buffer
}
pub fn glyf_u16_glyph_patches_2() -> BeBuffer {
let mut buffer = be_buffer! {
3u32, {1u8: "table_count"},
7u16,
12u16,
14u16,
(Tag::new(b"glyf")),
{0u32: "gid_7_offset"},
{0u32: "gid_12_offset"},
{0u32: "gid_14_offset"},
{0u32: "end_offset"},
{b'q': "gid_7_data"},
[b'r'],
{b's': "gid_12_data"},
[b't', b'u'],
{b'v': "gid_14_data"}
};
let offset = buffer.offset_for("gid_7_data") as u32;
buffer.write_at("gid_7_offset", offset);
let offset = buffer.offset_for("gid_12_data") as u32;
buffer.write_at("gid_12_offset", offset);
let offset = buffer.offset_for("gid_14_data") as u32;
buffer.write_at("gid_14_offset", offset);
buffer.write_at("end_offset", offset + 1);
buffer
}
pub fn glyf_u24_glyph_patches() -> BeBuffer {
let mut buffer = be_buffer! {
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"},
{0u32: "gid_7_offset"},
{0u32: "gid_8_offset"},
{0u32: "gid_9_offset"},
{0u32: "gid_13_offset"},
{0u32: "end_offset"},
{b'a': "gid_2_data"},
[b'b', b'c'],
{b'd': "gid_7_data"},
[b'e', b'f', b'g'],
{b'h': "gid_8_and_9_data"},
[b'i', b'j', b'k', b'l'],
{b'm': "gid_13_data"},
[b'n']
};
let offset = buffer.offset_for("gid_2_data") as u32;
buffer.write_at("gid_2_offset", offset);
let offset = buffer.offset_for("gid_7_data") as u32;
buffer.write_at("gid_7_offset", offset);
let offset = buffer.offset_for("gid_8_and_9_data") as u32;
buffer.write_at("gid_8_offset", offset);
let offset = buffer.offset_for("gid_8_and_9_data") as u32;
buffer.write_at("gid_9_offset", offset);
let offset = buffer.offset_for("gid_13_data") as u32;
buffer.write_at("gid_13_offset", offset);
buffer.write_at("end_offset", offset + 2);
buffer
}
pub fn glyf_and_gvar_u16_glyph_patches() -> BeBuffer {
let mut buffer = be_buffer! {
3u32, 2u8, [2, 7, 8u16], {(Tag::new(b"glyf")): "glyf_tag"}, {(Tag::new(b"gvar")): "gvar_tag"},
{0u32: "glyf_gid_2_offset"},
{0u32: "glyf_gid_7_offset"},
{0u32: "glyf_gid_8_offset"},
{0u32: "gvar_gid_2_offset"},
{0u32: "gvar_gid_7_offset"},
{0u32: "gvar_gid_8_offset"},
{0u32: "end_offset"},
{b'a': "glyf_gid_2_data"},
[b'b', b'c'],
{b'd': "glyf_gid_7_data"},
[b'e', b'f', b'g'],
{b'h': "glyf_gid_8_data"},
[b'i', b'j', b'k', b'l'],
{b'm': "gvar_gid_2_data"},
[b'n'],
{b'o': "gvar_gid_7_data"},
[b'p', b'q'],
{b'r': "gvar_gid_8_data"}
};
let offset = buffer.offset_for("glyf_gid_2_data") as u32;
buffer.write_at("glyf_gid_2_offset", offset);
let offset = buffer.offset_for("glyf_gid_7_data") as u32;
buffer.write_at("glyf_gid_7_offset", offset);
let offset = buffer.offset_for("glyf_gid_8_data") as u32;
buffer.write_at("glyf_gid_8_offset", offset);
let offset = buffer.offset_for("gvar_gid_2_data") as u32;
buffer.write_at("gvar_gid_2_offset", offset);
let offset = buffer.offset_for("gvar_gid_7_data") as u32;
buffer.write_at("gvar_gid_7_offset", offset);
let offset = buffer.offset_for("gvar_gid_8_data") as u32;
buffer.write_at("gvar_gid_8_offset", offset);
buffer.write_at("end_offset", offset + 1);
buffer
}
pub fn cff_u16_glyph_patches() -> BeBuffer {
let mut buffer = be_buffer! {
4u32, {1u8: "table_count"},
[1, 38,
47,
59u16],
{(Tag::new(b"CFF ")): "tag"},
{0u32: "gid_1_offset"},
{0u32: "gid_38_offset"},
{0u32: "gid_47_offset"},
{0u32: "gid_59_offset"},
{0u32: "end_offset"},
{b'a': "gid_1_data"},
[b'b', b'c'],
{b'd': "gid_38_data"},
[b'e', b'f', b'g'],
{b'h': "gid_47_data"},
[b'i', b'j', b'k', b'l'],
{b'm': "gid_59_data"},
[b'n']
};
let offset = buffer.offset_for("gid_1_data") as u32;
buffer.write_at("gid_1_offset", offset);
let offset = buffer.offset_for("gid_38_data") as u32;
buffer.write_at("gid_38_offset", offset);
let offset = buffer.offset_for("gid_47_data") as u32;
buffer.write_at("gid_47_offset", offset);
let offset = buffer.offset_for("gid_59_data") as u32;
buffer.write_at("gid_59_offset", offset);
buffer.write_at("end_offset", offset + 2);
buffer
}
pub fn short_gvar_with_shared_tuples() -> BeBuffer {
let mut buffer = be_buffer! {
1u16, 0u16, 1u16, 3u16, {0u32: "shared_tuples_offset"},
15u16, 0u16, {0u32: "glyph_variation_data_offset"},
{0u16: "glyph_offset[0]"},
{0u16: "glyph_offset[1]"},
{0u16: "glyph_offset[2]"},
{0u16: "glyph_offset[3]"},
{0u16: "glyph_offset[4]"},
{0u16: "glyph_offset[5]"},
{0u16: "glyph_offset[6]"},
{0u16: "glyph_offset[7]"},
{0u16: "glyph_offset[8]"},
{0u16: "glyph_offset[9]"},
{0u16: "glyph_offset[10]"},
{0u16: "glyph_offset[11]"},
{0u16: "glyph_offset[12]"},
{0u16: "glyph_offset[13]"},
{0u16: "glyph_offset[14]"},
{0u16: "glyph_offset[15]"},
{42u16: "sharedTuples[0]"},
13u16,
25u16,
{1u8: "glyph_0"}, [2, 3, 4u8],
{5u8: "glyph_8"}, [6, 7, 8, 9u8], {10u8: "end"}
};
let offset = buffer.offset_for("sharedTuples[0]") as u32;
buffer.write_at("shared_tuples_offset", offset);
let data_offset = buffer.offset_for("glyph_0");
buffer.write_at("glyph_variation_data_offset", data_offset as u32);
let glyph0_offset = ((buffer.offset_for("glyph_0") - data_offset) / 2) as u16;
let glyph8_offset = ((buffer.offset_for("glyph_8") - data_offset) / 2) as u16;
let end_offset = ((buffer.offset_for("end") + 1 - data_offset) / 2) as u16;
buffer.write_at("glyph_offset[0]", glyph0_offset);
buffer.write_at("glyph_offset[1]", glyph8_offset);
buffer.write_at("glyph_offset[2]", glyph8_offset);
buffer.write_at("glyph_offset[3]", glyph8_offset);
buffer.write_at("glyph_offset[4]", glyph8_offset);
buffer.write_at("glyph_offset[5]", glyph8_offset);
buffer.write_at("glyph_offset[6]", glyph8_offset);
buffer.write_at("glyph_offset[7]", glyph8_offset);
buffer.write_at("glyph_offset[8]", glyph8_offset);
buffer.write_at("glyph_offset[9]", end_offset);
buffer.write_at("glyph_offset[10]", end_offset);
buffer.write_at("glyph_offset[11]", end_offset);
buffer.write_at("glyph_offset[12]", end_offset);
buffer.write_at("glyph_offset[13]", end_offset);
buffer.write_at("glyph_offset[14]", end_offset);
buffer.write_at("glyph_offset[15]", end_offset);
buffer
}
pub fn long_gvar_with_shared_tuples() -> BeBuffer {
let mut buffer = be_buffer! {
1u16, 0u16, 1u16, 3u16, {0u32: "shared_tuples_offset"},
15u16, 0b00000000_00000001u16, {0u32: "glyph_variation_data_offset"},
{0u32: "glyph_offset[0]"},
{0u32: "glyph_offset[1]"},
{0u32: "glyph_offset[2]"},
{0u32: "glyph_offset[3]"},
{0u32: "glyph_offset[4]"},
{0u32: "glyph_offset[5]"},
{0u32: "glyph_offset[6]"},
{0u32: "glyph_offset[7]"},
{0u32: "glyph_offset[8]"},
{0u32: "glyph_offset[9]"},
{0u32: "glyph_offset[10]"},
{0u32: "glyph_offset[11]"},
{0u32: "glyph_offset[12]"},
{0u32: "glyph_offset[13]"},
{0u32: "glyph_offset[14]"},
{0u32: "glyph_offset[15]"},
{42u16: "sharedTuples[0]"},
13u16,
25u16,
{1u8: "glyph_0"}, [2, 3, 4u8],
{5u8: "glyph_8"}, [6, 7, 8, 9u8], {10u8: "end"}
};
let offset = buffer.offset_for("sharedTuples[0]") as u32;
buffer.write_at("shared_tuples_offset", offset);
let data_offset = buffer.offset_for("glyph_0");
buffer.write_at("glyph_variation_data_offset", data_offset as u32);
let glyph0_offset = (buffer.offset_for("glyph_0") - data_offset) as u32;
let glyph8_offset = (buffer.offset_for("glyph_8") - data_offset) as u32;
let end_offset = (buffer.offset_for("end") + 1 - data_offset) as u32;
buffer.write_at("glyph_offset[0]", glyph0_offset);
buffer.write_at("glyph_offset[1]", glyph8_offset);
buffer.write_at("glyph_offset[2]", glyph8_offset);
buffer.write_at("glyph_offset[3]", glyph8_offset);
buffer.write_at("glyph_offset[4]", glyph8_offset);
buffer.write_at("glyph_offset[5]", glyph8_offset);
buffer.write_at("glyph_offset[6]", glyph8_offset);
buffer.write_at("glyph_offset[7]", glyph8_offset);
buffer.write_at("glyph_offset[8]", glyph8_offset);
buffer.write_at("glyph_offset[9]", end_offset);
buffer.write_at("glyph_offset[10]", end_offset);
buffer.write_at("glyph_offset[11]", end_offset);
buffer.write_at("glyph_offset[12]", end_offset);
buffer.write_at("glyph_offset[13]", end_offset);
buffer.write_at("glyph_offset[14]", end_offset);
buffer.write_at("glyph_offset[15]", end_offset);
buffer
}
pub fn short_gvar_with_no_shared_tuples() -> BeBuffer {
let mut buffer = be_buffer! {
1u16, 0u16, 1u16, {0u16: "shared_tuple_count"},
{0u32: "shared_tuples_offset"},
15u16, 0u16, {0u32: "glyph_variation_data_offset"},
{0u16: "glyph_offset[0]"},
{0u16: "glyph_offset[1]"},
{0u16: "glyph_offset[2]"},
{0u16: "glyph_offset[3]"},
{0u16: "glyph_offset[4]"},
{0u16: "glyph_offset[5]"},
{0u16: "glyph_offset[6]"},
{0u16: "glyph_offset[7]"},
{0u16: "glyph_offset[8]"},
{0u16: "glyph_offset[9]"},
{0u16: "glyph_offset[10]"},
{0u16: "glyph_offset[11]"},
{0u16: "glyph_offset[12]"},
{0u16: "glyph_offset[13]"},
{0u16: "glyph_offset[14]"},
{0u16: "glyph_offset[15]"},
{1u8: "glyph_0"}, [2, 3, 4u8],
{5u8: "glyph_8"}, [6, 7, 8, 9u8], {10u8: "end"}
};
let data_offset = buffer.offset_for("glyph_0");
buffer.write_at("shared_tuples_offset", data_offset as u32);
buffer.write_at("glyph_variation_data_offset", data_offset as u32);
let glyph0_offset = ((buffer.offset_for("glyph_0") - data_offset) / 2) as u16;
let glyph8_offset = ((buffer.offset_for("glyph_8") - data_offset) / 2) as u16;
let end_offset = ((buffer.offset_for("end") + 1 - data_offset) / 2) as u16;
buffer.write_at("glyph_offset[0]", glyph0_offset);
buffer.write_at("glyph_offset[1]", glyph8_offset);
buffer.write_at("glyph_offset[2]", glyph8_offset);
buffer.write_at("glyph_offset[3]", glyph8_offset);
buffer.write_at("glyph_offset[4]", glyph8_offset);
buffer.write_at("glyph_offset[5]", glyph8_offset);
buffer.write_at("glyph_offset[6]", glyph8_offset);
buffer.write_at("glyph_offset[7]", glyph8_offset);
buffer.write_at("glyph_offset[8]", glyph8_offset);
buffer.write_at("glyph_offset[9]", end_offset);
buffer.write_at("glyph_offset[10]", end_offset);
buffer.write_at("glyph_offset[11]", end_offset);
buffer.write_at("glyph_offset[12]", end_offset);
buffer.write_at("glyph_offset[13]", end_offset);
buffer.write_at("glyph_offset[14]", end_offset);
buffer.write_at("glyph_offset[15]", end_offset);
buffer
}
pub fn short_gvar_near_maximum_offset_size() -> BeBuffer {
let buffer = be_buffer! {
1u16, 0u16, 1u16, {0u16: "shared_tuple_count"},
{0u32: "shared_tuples_offset"},
15u16, 0u16, {0u32: "glyph_variation_data_offset"},
{0u16: "glyph_offset[0]"},
{0u16: "glyph_offset[1]"},
{0u16: "glyph_offset[2]"},
{0u16: "glyph_offset[3]"},
{0u16: "glyph_offset[4]"},
{0u16: "glyph_offset[5]"},
{0u16: "glyph_offset[6]"},
{0u16: "glyph_offset[7]"},
{0u16: "glyph_offset[8]"},
{0u16: "glyph_offset[9]"},
{0u16: "glyph_offset[10]"},
{0u16: "glyph_offset[11]"},
{0u16: "glyph_offset[12]"},
{0u16: "glyph_offset[13]"},
{0u16: "glyph_offset[14]"},
{0u16: "glyph_offset[15]"},
{1u8: "glyph_0"}
};
let mut buffer = buffer.extend(iter::repeat(1u8).take(131065));
let data_offset = buffer.offset_for("glyph_0");
buffer.write_at("shared_tuples_offset", data_offset as u32);
buffer.write_at("glyph_variation_data_offset", data_offset as u32);
buffer.write_at("glyph_offset[0]", 0u16);
buffer.write_at("glyph_offset[1]", 65533u16);
buffer.write_at("glyph_offset[2]", 65533u16);
buffer.write_at("glyph_offset[3]", 65533u16);
buffer.write_at("glyph_offset[4]", 65533u16);
buffer.write_at("glyph_offset[5]", 65533u16);
buffer.write_at("glyph_offset[6]", 65533u16);
buffer.write_at("glyph_offset[7]", 65533u16);
buffer.write_at("glyph_offset[8]", 65533u16);
buffer.write_at("glyph_offset[9]", 65533u16);
buffer.write_at("glyph_offset[10]", 65533u16);
buffer.write_at("glyph_offset[11]", 65533u16);
buffer.write_at("glyph_offset[12]", 65533u16);
buffer.write_at("glyph_offset[13]", 65533u16);
buffer.write_at("glyph_offset[14]", 65533u16);
buffer.write_at("glyph_offset[15]", 65533u16);
buffer
}
pub fn out_of_order_gvar_with_shared_tuples() -> BeBuffer {
let mut buffer = be_buffer! {
1u16, 0u16, 1u16, 3u16, {0u32: "shared_tuples_offset"},
15u16, 0u16, {0u32: "glyph_variation_data_offset"},
{0u16: "glyph_offset[0]"},
{0u16: "glyph_offset[1]"},
{0u16: "glyph_offset[2]"},
{0u16: "glyph_offset[3]"},
{0u16: "glyph_offset[4]"},
{0u16: "glyph_offset[5]"},
{0u16: "glyph_offset[6]"},
{0u16: "glyph_offset[7]"},
{0u16: "glyph_offset[8]"},
{0u16: "glyph_offset[9]"},
{0u16: "glyph_offset[10]"},
{0u16: "glyph_offset[11]"},
{0u16: "glyph_offset[12]"},
{0u16: "glyph_offset[13]"},
{0u16: "glyph_offset[14]"},
{0u16: "glyph_offset[15]"},
{1u8: "glyph_0"}, [2, 3, 4u8],
{5u8: "glyph_8"}, [6, 7, 8, 9u8], {10u8: "end"},
{42u16: "sharedTuples[0]"},
13u16,
25u16
};
let offset = buffer.offset_for("sharedTuples[0]") as u32;
buffer.write_at("shared_tuples_offset", offset);
let data_offset = buffer.offset_for("glyph_0");
buffer.write_at("glyph_variation_data_offset", data_offset as u32);
let glyph0_offset = ((buffer.offset_for("glyph_0") - data_offset) / 2) as u16;
let glyph8_offset = ((buffer.offset_for("glyph_8") - data_offset) / 2) as u16;
let end_offset = ((buffer.offset_for("end") + 1 - data_offset) / 2) as u16;
buffer.write_at("glyph_offset[0]", glyph0_offset);
buffer.write_at("glyph_offset[1]", glyph8_offset);
buffer.write_at("glyph_offset[2]", glyph8_offset);
buffer.write_at("glyph_offset[3]", glyph8_offset);
buffer.write_at("glyph_offset[4]", glyph8_offset);
buffer.write_at("glyph_offset[5]", glyph8_offset);
buffer.write_at("glyph_offset[6]", glyph8_offset);
buffer.write_at("glyph_offset[7]", glyph8_offset);
buffer.write_at("glyph_offset[8]", glyph8_offset);
buffer.write_at("glyph_offset[9]", end_offset);
buffer.write_at("glyph_offset[10]", end_offset);
buffer.write_at("glyph_offset[11]", end_offset);
buffer.write_at("glyph_offset[12]", end_offset);
buffer.write_at("glyph_offset[13]", end_offset);
buffer.write_at("glyph_offset[14]", end_offset);
buffer.write_at("glyph_offset[15]", end_offset);
buffer
}