Skip to main content

font_test_data/
lib.rs

1//! test data shared between various fontations crates.
2
3pub mod bebuffer;
4pub mod cmap;
5pub mod gdef;
6pub mod gpos;
7pub mod gsub;
8pub mod ift;
9pub mod layout;
10pub mod type1;
11
12pub static CMAP12_FONT1: &[u8] = include_bytes!("../test_data/ttf/cmap12_font1.ttf");
13
14pub static CMAP14_FONT1: &[u8] = include_bytes!("../test_data/ttf/cmap14_font1.ttf");
15
16pub static CMAP4_SYMBOL_PUA: &[u8] = include_bytes!("../test_data/ttf/cmap4_symbol_pua.ttf");
17
18pub static CMAP6: &[u8] = include_bytes!("../test_data/ttf/cmap6.ttf");
19
20pub static CMAP10: &[u8] = include_bytes!("../test_data/ttf/cmap10.ttf");
21
22pub static TOFU: &[u8] = include_bytes!("../test_data/ttf/tofu.ttf");
23
24pub static COLR_GRADIENT_RECT: &[u8] =
25    include_bytes!("../test_data/ttf/linear_gradient_rect_colr_1.ttf");
26
27pub static VAZIRMATN_VAR: &[u8] = include_bytes!("../test_data/ttf/vazirmatn_var_trimmed.ttf");
28
29pub static NAMES_ONLY: &[u8] = include_bytes!("../test_data/ttf/names_only.ttf");
30
31pub static VAZIRMATN_VAR_GLYPHS: &str =
32    include_str!("../test_data/extracted/vazirmatn_var_trimmed-glyphs.txt");
33
34pub static SIMPLE_GLYF: &[u8] = include_bytes!("../test_data/ttf/simple_glyf.ttf");
35
36pub static CUBIC_GLYF: &[u8] = include_bytes!("../test_data/ttf/cubic_glyf.ttf");
37
38pub static NOTO_SERIF_DISPLAY_TRIMMED: &[u8] =
39    include_bytes!("../test_data/ttf/noto_serif_display_trimmed.ttf");
40
41pub static NOTO_SERIF_DISPLAY_TRIMMED_GLYPHS: &str =
42    include_str!("../test_data/extracted/noto_serif_display_trimmed-glyphs.txt");
43
44pub static NOTO_SANS_JP_CFF: &[u8] =
45    include_bytes!("../test_data/ttf/NotoSansJP-Regular.subset.otf");
46
47pub static CANTARELL_VF_TRIMMED: &[u8] =
48    include_bytes!("../test_data/ttf/cantarell_vf_trimmed.ttf");
49
50pub static CANTARELL_VF_TRIMMED_GLYPHS: &str =
51    include_str!("../test_data/extracted/cantarell_vf_trimmed-glyphs.txt");
52
53pub static CHARSTRING_PATH_OPS: &[u8] = include_bytes!("../test_data/ttf/charstring_path_ops.ttf");
54
55pub static EMBEDDED_BITMAPS: &[u8] = include_bytes!("../test_data/ttf/embedded_bitmaps.ttf");
56pub static CBDT: &[u8] = include_bytes!("../test_data/ttf/cbdt.ttf");
57
58pub static HVAR_WITH_TRUNCATED_ADVANCE_INDEX_MAP: &[u8] =
59    include_bytes!("../test_data/ttf/hvar_with_truncated_adv_index_map.ttf");
60
61pub static COLRV0V1: &[u8] = include_bytes!("../test_data/ttf/test_glyphs-glyf_colr_1.ttf");
62
63pub static COLRV0V1_VARIABLE: &[u8] =
64    include_bytes!("../test_data/ttf/test_glyphs-glyf_colr_1_variable.ttf");
65
66/// Subset of Noto Color Emoji containing the flags with the most complex
67/// COLRv1 paint graphs (Ecuador and El Salvador).
68pub static NOTO_COLOR_EMOJI_FLAGS: &[u8] =
69    include_bytes!("../test_data/ttf/noto_color_emoji_flags.ttf");
70
71pub static COLRV1_NO_CLIPLIST: &[u8] =
72    include_bytes!("../test_data/ttf/test_glyphs-glyf_colr_1_no_cliplist.subset.ttf");
73
74pub static CVAR: &[u8] = include_bytes!("../test_data/ttf/cvar.ttf");
75
76pub static STARTING_OFF_CURVE: &[u8] = include_bytes!("../test_data/ttf/starts_off_curve.ttf");
77
78pub static MOSTLY_OFF_CURVE: &[u8] = include_bytes!("../test_data/ttf/mostly_off_curve.ttf");
79
80pub static INTERPOLATE_THIS: &[u8] = include_bytes!("../test_data/ttf/interpolate_this.ttf");
81
82pub static MATERIAL_SYMBOLS_SUBSET: &[u8] =
83    include_bytes!("../test_data/ttf/material_symbols_subset.ttf");
84
85pub static GLYF_COMPONENTS: &[u8] = include_bytes!("../test_data/ttf/glyf_components.ttf");
86
87pub static AUTOHINT_CMAP: &[u8] = include_bytes!("../test_data/ttf/autohint_cmap.ttf");
88
89pub static NOTOSERIFHEBREW_AUTOHINT_METRICS: &[u8] =
90    include_bytes!("../test_data/ttf/notoserifhebrew_autohint_metrics.ttf");
91
92pub static NOTOSERIFTC_AUTOHINT_METRICS: &[u8] =
93    include_bytes!("../test_data/ttf/notoseriftc_autohint_metrics.ttf");
94
95pub static NOTOSERIF_AUTOHINT_SHAPING: &[u8] =
96    include_bytes!("../test_data/ttf/notoserif_autohint_shaping.ttf");
97
98pub static TTHINT_SUBSET: &[u8] = include_bytes!("../test_data/ttf/tthint_subset.ttf");
99
100pub static VORG: &[u8] = include_bytes!("../test_data/ttf/vorg.ttf");
101
102pub static AHEM: &[u8] = include_bytes!("../test_data/ttf/ahem.ttf");
103
104pub static AVAR2_CHECKER: &[u8] = include_bytes!("../test_data/ttf/avar2checker.ttf");
105pub static AMSTELVAR_AVAR2_A: &[u8] = include_bytes!("../test_data/ttf/Amstelvar-avar2.A.ttf");
106
107pub static MATERIAL_ICONS_SUBSET: &[u8] =
108    include_bytes!("../test_data/ttf/material_icons_subset.ttf");
109
110pub static MATERIAL_ICONS_SUBSET_MATRIX: &[u8] =
111    include_bytes!("../test_data/ttf/material_icons_subset_matrix.ttf");
112
113pub static TINOS_SUBSET: &[u8] = include_bytes!("../test_data/ttf/tinos_subset.ttf");
114
115pub static NOTO_HANDWRITING_SBIX: &[u8] =
116    include_bytes!("../test_data/ttf/noto_handwriting-sbix.ttf");
117
118pub static COUSINE_HINT_SUBSET: &[u8] = include_bytes!("../test_data/ttf/cousine_hint_subset.ttf");
119
120pub mod morx {
121    // The following taken from the Unicode text rendering test fonts:
122    // <https://github.com/unicode-org/text-rendering-tests/tree/main/fonts>
123    pub static ONE: &[u8] = include_bytes!("../test_data/ttf/TestMORXOne.ttf");
124    pub static FOUR: &[u8] = include_bytes!("../test_data/ttf/TestMORXFour.ttf");
125    pub static EIGHTEEN: &[u8] = include_bytes!("../test_data/ttf/TestMORXEighteen.ttf");
126    pub static THIRTY_FOUR: &[u8] = include_bytes!("../test_data/ttf/TestMORXThirtyfour.ttf");
127    pub static FORTY_ONE: &[u8] = include_bytes!("../test_data/ttf/TestMORXFourtyone.ttf");
128}
129
130pub mod varc {
131    pub static CJK_6868: &[u8] = include_bytes!("../test_data/ttf/varc-6868.ttf");
132    pub static CONDITIONALS: &[u8] = include_bytes!("../test_data/ttf/varc-ac01-conditional.ttf");
133}
134
135pub mod closure {
136    pub static SIMPLE: &[u8] = include_bytes!("../test_data/ttf/simple_closure.ttf");
137    pub static SIMPLE_GLYPHS: &str = include_str!("../test_data/fea/simple_closure_glyphs.txt");
138    pub static RECURSIVE: &[u8] = include_bytes!("../test_data/ttf/recursive_closure.ttf");
139    pub static RECURSIVE_GLYPHS: &str =
140        include_str!("../test_data/fea/recursive_closure_glyphs.txt");
141    pub static CONTEXTUAL: &[u8] = include_bytes!("../test_data/ttf/context_closure.ttf");
142    pub static CONTEXTUAL_GLYPHS: &str =
143        include_str!("../test_data/fea/context_closure_glyphs.txt");
144    pub static RECURSIVE_CONTEXTUAL: &[u8] =
145        include_bytes!("../test_data/ttf/recursive_context_closure.ttf");
146    pub static RECURSIVE_CONTEXTUAL_GLYPHS: &str =
147        include_str!("../test_data/fea/recursive_context_closure_glyphs.txt");
148    // reuses glyph set from above
149    pub static CYCLIC_CONTEXTUAL: &[u8] =
150        include_bytes!("../test_data/ttf/cyclic_context_closure.ttf");
151    pub static CHAIN_CONTEXT_FORMAT3_BITS: &[u8] =
152        include_bytes!("../test_data/ttf/context_closure_unreachable_rule.ttf");
153    pub static CHAIN_CONTEXT_FORMAT3_BITS_GLYPHS: &str =
154        include_str!("../test_data/fea/context_closure_unreachable_rule_glyphs.txt");
155    pub static VARIATIONS_CLOSURE: &[u8] =
156        include_bytes!("../test_data/ttf/variations_closure.ttf");
157    pub static VARIATIONS_GLYPHS: &str =
158        include_str!("../test_data/fea/variations_closure_glyphs.txt");
159    pub static CONTEXT_ONLY_REACHABLE: &[u8] =
160        include_bytes!("../test_data/ttf/context_only_reachable.ttf");
161    pub static CONTEXT_ONLY_REACHABLE_GLYPHS: &str =
162        include_str!("../test_data/fea/context_only_reachable_glyphs.txt");
163}
164
165pub mod post {
166    use crate::bebuffer::BeBuffer;
167
168    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
169    pub enum GlyphNameOrder {
170        /// Glyph name indices in strictly increasing order.
171        Monotonic,
172        /// Glyph name indices in mostly increasing order, with some back
173        /// references to previous names.
174        ///
175        /// This likely matches most sane font data with duplicate glyph names.
176        MostlyMonotonicWithBackrefs,
177        /// All glyph name indices point to the last glyph name.
178        ///
179        /// This is the patholical case, requiring a full scan for each glyph
180        /// during iteration.
181        AllPointToLast,
182    }
183
184    /// Build a synthetic post v2 table with custom names for each glyph.
185    ///
186    /// Returns the table bytes and the generated glyph names in glyph id order.
187    pub fn v2_with_varied_glyph_names(
188        num_glyphs: u16,
189        base_name_len: u8,
190        order: GlyphNameOrder,
191    ) -> (Vec<u8>, Vec<String>) {
192        let custom_start = 258u16;
193        let mut buf = BeBuffer::new()
194            .push(0x0002_0000u32) // version 2.0
195            .push(0u32) // italicAngle
196            .push(0i16) // underlinePosition
197            .push(0i16) // underlineThickness
198            .push(0u32) // isFixedPitch
199            .push(0u32) // minMemType42
200            .push(0u32) // maxMemType42
201            .push(0u32) // minMemType1
202            .push(0u32) // maxMemType1
203            .push(num_glyphs);
204        let mapped_indices = mapped_custom_indices(num_glyphs as usize, order);
205        for mapped_idx in mapped_indices.iter().copied() {
206            let mapped_idx_u16 = u16::try_from(mapped_idx).unwrap();
207            buf = buf.push(custom_start.saturating_add(mapped_idx_u16));
208        }
209        let mut custom_names = Vec::with_capacity(num_glyphs as usize);
210        for custom_idx in 0..num_glyphs as usize {
211            let name = varied_name(custom_idx, base_name_len);
212            let len = u8::try_from(name.len()).unwrap();
213            buf = buf.push(len).extend(name.as_bytes().iter().copied());
214            custom_names.push(name);
215        }
216        let names = mapped_indices
217            .iter()
218            .map(|idx| custom_names[*idx].clone())
219            .collect();
220        (buf.data().to_vec(), names)
221    }
222
223    fn mapped_custom_indices(num_glyphs: usize, order: GlyphNameOrder) -> Vec<usize> {
224        match order {
225            GlyphNameOrder::Monotonic => (0..num_glyphs).collect(),
226            GlyphNameOrder::MostlyMonotonicWithBackrefs => (0..num_glyphs)
227                .map(|gid| {
228                    if gid > 0 && gid % 97 == 0 {
229                        gid - 1
230                    } else if gid > 3 && gid % 251 == 0 {
231                        gid - 3
232                    } else if gid > 7 && gid % 509 == 0 {
233                        gid - 7
234                    } else {
235                        gid
236                    }
237                })
238                .collect(),
239            GlyphNameOrder::AllPointToLast => {
240                if num_glyphs == 0 {
241                    Vec::new()
242                } else {
243                    vec![num_glyphs - 1; num_glyphs]
244                }
245            }
246        }
247    }
248
249    fn varied_name(custom_idx: usize, base_name_len: u8) -> String {
250        let base_name_len = usize::from(base_name_len.clamp(8, 220));
251        let len = (base_name_len + (custom_idx % 27)).min(255);
252        let mut name = format!("glyph_{custom_idx:05}_");
253        let pattern = match custom_idx % 4 {
254            0 => "abcdefghijklmnopqrstuvwxyz0123456789",
255            1 => "zyxwvutsrqponmlkjihgfedcba9876543210",
256            2 => "aabccddeeffgghhiijjkkllmmnnooppqqrrss",
257            _ => "n0nlinear_name_pattern_block_",
258        };
259        while name.len() < len {
260            name.push_str(pattern);
261        }
262        name.truncate(len);
263        name
264    }
265
266    #[rustfmt::skip]
267    pub static SIMPLE: &[u8] = &[
268        0x00, 0x02, 0x00, 0x00, // version 2.0
269        0x00, 0x00, 0x00, 0x00, // italic angle
270        0xFF, 0xb5,             // underlinePosition -75
271        0x00, 0x32,             // underlineThickness 50
272        0x00, 0x00, 0x00, 0x00, // fixedpitch
273        0x00, 0x00, 0x00, 0x00, // min/max mem:
274        0x00, 0x00, 0x00, 0x00,
275        0x00, 0x00, 0x00, 0x00,
276        0x00, 0x00, 0x00, 0x00,
277        0x00, 0x0A,             // numGlyphs 10
278                                // glyph name index:
279        0x00, 0x00,              // glyph 0 -> name 0
280        0x00, 0x00,             // glyph 1 -> name 0
281        0x00, 0x03,              // glyph 2 -> name 3 ('space')
282        0x00, 0x04,              // glyph 3 -> name 4 ('exclam')
283        0x00, 0x06,
284        0x00, 0x07,
285        0x00, 0x08,
286        0x01, 0x02,             // glyph 7 -> name 258 first custom
287        0x01, 0x03,             // glyph 8 -> name 258 first custom
288        0x01, 0x04,             // glyph 9 -> name 258 first custom
289        0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, // 5, h e l l o
290        0x02, 0x68, 0x69, // 2, h i
291        0x4, 0x68, 0x6f, 0x6c, 0x61, // 4, h o l a
292    ];
293}
294
295pub mod cff2 {
296    /// CFF2 example table
297    /// <https://learn.microsoft.com/en-us/typography/opentype/spec/cff2#appendix-a-example-cff2-font>
298    pub static EXAMPLE: &[u8] = &[
299        0x02, 0x00, 0x05, 0x00, 0x07, 0xCF, 0x0C, 0x24, 0xC3, 0x11, 0x9B, 0x18, 0x00, 0x00, 0x00,
300        0x00, 0x00, 0x26, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1C,
301        0x00, 0x01, 0x00, 0x02, 0xC0, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xE0,
302        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
303        0x01, 0x01, 0x03, 0x05, 0x20, 0x0A, 0x20, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x05,
304        0xF7, 0x06, 0xDA, 0x12, 0x77, 0x9F, 0xF8, 0x6C, 0x9D, 0xAE, 0x9A, 0xF4, 0x9A, 0x95, 0x9F,
305        0xB3, 0x9F, 0x8B, 0x8B, 0x8B, 0x8B, 0x85, 0x9A, 0x8B, 0x8B, 0x97, 0x73, 0x8B, 0x8B, 0x8C,
306        0x80, 0x8B, 0x8B, 0x8B, 0x8D, 0x8B, 0x8B, 0x8C, 0x8A, 0x8B, 0x8B, 0x97, 0x17, 0x06, 0xFB,
307        0x8E, 0x95, 0x86, 0x9D, 0x8B, 0x8B, 0x8D, 0x17, 0x07, 0x77, 0x9F, 0xF8, 0x6D, 0x9D, 0xAD,
308        0x9A, 0xF3, 0x9A, 0x95, 0x9F, 0xB3, 0x9F, 0x08, 0xFB, 0x8D, 0x95, 0x09, 0x1E, 0xA0, 0x37,
309        0x5F, 0x0C, 0x09, 0x8B, 0x0C, 0x0B, 0xC2, 0x6E, 0x9E, 0x8C, 0x17, 0x0A, 0xDB, 0x57, 0xF7,
310        0x02, 0x8C, 0x17, 0x0B, 0xB3, 0x9A, 0x77, 0x9F, 0x82, 0x8A, 0x8D, 0x17, 0x0C, 0x0C, 0xDB,
311        0x95, 0x57, 0xF7, 0x02, 0x85, 0x8B, 0x8D, 0x17, 0x0C, 0x0D, 0xF7, 0x06, 0x13, 0x00, 0x00,
312        0x00, 0x01, 0x01, 0x01, 0x1B, 0xBD, 0xBD, 0xEF, 0x8C, 0x10, 0x8B, 0x15, 0xF8, 0x88, 0x27,
313        0xFB, 0x5C, 0x8C, 0x10, 0x06, 0xF8, 0x88, 0x07, 0xFC, 0x88, 0xEF, 0xF7, 0x5C, 0x8C, 0x10,
314        0x06,
315    ];
316}
317
318/// This setup to avoid cross-crate path construction and build.rs because both caused problems for google3
319pub mod colrv1_json {
320    /// Gets the expected value for a colrv1 json test
321    pub fn expected(set_name: &str, settings: &[(&str, f32)]) -> &'static str {
322        let mut key = Vec::with_capacity(1 + settings.len());
323        key.push("colrv1_".to_string() + &set_name.to_ascii_lowercase());
324        key.extend(settings.iter().map(|(t, v)| format!("{t}_{v}")));
325        let key = key.join("_");
326        // you could generate the cases in bash using something like:
327        // for f in $(ls font-test-data/test_data/colrv1_json); do echo "\"$f\" => include_str!(\"../test_data/colrv1_json/$f\"),"; done
328        match key.as_str() {
329            "colrv1_clipbox" => include_str!("../test_data/colrv1_json/colrv1_clipbox"),
330            "colrv1_clipbox_CLIO_200" => include_str!("../test_data/colrv1_json/colrv1_clipbox_CLIO_200"),
331            "colrv1_colored_circles_v0" => include_str!("../test_data/colrv1_json/colrv1_colored_circles_v0"),
332            "colrv1_composite_mode" => include_str!("../test_data/colrv1_json/colrv1_composite_mode"),
333            "colrv1_extend_mode" => include_str!("../test_data/colrv1_json/colrv1_extend_mode"),
334            "colrv1_extend_mode_COL1_-0.25_COL3_0.25" => include_str!("../test_data/colrv1_json/colrv1_extend_mode_COL1_-0.25_COL3_0.25"),
335            "colrv1_extend_mode_COL1_0.5_COL3_-0.5" => include_str!("../test_data/colrv1_json/colrv1_extend_mode_COL1_0.5_COL3_-0.5"),
336            "colrv1_extend_mode_COL1_-1.5" => include_str!("../test_data/colrv1_json/colrv1_extend_mode_COL1_-1.5"),
337            "colrv1_extend_mode_COL2_-0.3" => include_str!("../test_data/colrv1_json/colrv1_extend_mode_COL2_-0.3"),
338            "colrv1_extend_mode_COL3_0.5" => include_str!("../test_data/colrv1_json/colrv1_extend_mode_COL3_0.5"),
339            "colrv1_extend_mode_COL3_1" => include_str!("../test_data/colrv1_json/colrv1_extend_mode_COL3_1"),
340            "colrv1_extend_mode_COL3_1_COL2_1.5_COL1_2" => include_str!("../test_data/colrv1_json/colrv1_extend_mode_COL3_1_COL2_1.5_COL1_2"),
341            "colrv1_extend_mode_GRR0_-200_GRR1_-300" => include_str!("../test_data/colrv1_json/colrv1_extend_mode_GRR0_-200_GRR1_-300"),
342            "colrv1_extend_mode_GRR0_430_GRR1_40" => include_str!("../test_data/colrv1_json/colrv1_extend_mode_GRR0_430_GRR1_40"),
343            "colrv1_extend_mode_GRR0_-50_COL3_-2_COL2_-2_COL1_-0.9" => include_str!("../test_data/colrv1_json/colrv1_extend_mode_GRR0_-50_COL3_-2_COL2_-2_COL1_-0.9"),
344            "colrv1_extend_mode_GRR0_-50_COL3_-2_COL2_-2_COL1_-1.1" => include_str!("../test_data/colrv1_json/colrv1_extend_mode_GRR0_-50_COL3_-2_COL2_-2_COL1_-1.1"),
345            "colrv1_extend_mode_GRX0_1000_GRX1_-1000_GRR0_-1000_GRR1_200" => include_str!("../test_data/colrv1_json/colrv1_extend_mode_GRX0_1000_GRX1_-1000_GRR0_-1000_GRR1_200"),
346            "colrv1_extend_mode_GRX0_-1000_GRX1_-1000_GRR0_-1000_GRR1_-900" => include_str!("../test_data/colrv1_json/colrv1_extend_mode_GRX0_-1000_GRX1_-1000_GRR0_-1000_GRR1_-900"),
347            "colrv1_foreground_color" => include_str!("../test_data/colrv1_json/colrv1_foreground_color"),
348            "colrv1_gradient_p2_skewed" => include_str!("../test_data/colrv1_json/colrv1_gradient_p2_skewed"),
349            "colrv1_gradient_stops_repeat" => include_str!("../test_data/colrv1_json/colrv1_gradient_stops_repeat"),
350            "colrv1_no_cycle_multi_colrglyph" => include_str!("../test_data/colrv1_json/colrv1_no_cycle_multi_colrglyph"),
351            "colrv1_paint_glyph_nested" => include_str!("../test_data/colrv1_json/colrv1_paint_glyph_nested"),
352            "colrv1_paint_rotate" => include_str!("../test_data/colrv1_json/colrv1_paint_rotate"),
353            "colrv1_paint_rotate_ROTA_40" => include_str!("../test_data/colrv1_json/colrv1_paint_rotate_ROTA_40"),
354            "colrv1_paint_rotate_ROTX_-250_ROTY_-250" => include_str!("../test_data/colrv1_json/colrv1_paint_rotate_ROTX_-250_ROTY_-250"),
355            "colrv1_paint_scale" => include_str!("../test_data/colrv1_json/colrv1_paint_scale"),
356            "colrv1_paint_scale_SCOX_200_SCOY_200" => include_str!("../test_data/colrv1_json/colrv1_paint_scale_SCOX_200_SCOY_200"),
357            "colrv1_paint_scale_SCSX_0.25_SCOY_0.25" => include_str!("../test_data/colrv1_json/colrv1_paint_scale_SCSX_0.25_SCOY_0.25"),
358            "colrv1_paint_scale_SCSX_-1_SCOY_-1" => include_str!("../test_data/colrv1_json/colrv1_paint_scale_SCSX_-1_SCOY_-1"),
359            "colrv1_paint_skew" => include_str!("../test_data/colrv1_json/colrv1_paint_skew"),
360            "colrv1_paint_skew_SKCX_200_SKCY_200" => include_str!("../test_data/colrv1_json/colrv1_paint_skew_SKCX_200_SKCY_200"),
361            "colrv1_paint_skew_SKXA_20" => include_str!("../test_data/colrv1_json/colrv1_paint_skew_SKXA_20"),
362            "colrv1_paint_skew_SKYA_20" => include_str!("../test_data/colrv1_json/colrv1_paint_skew_SKYA_20"),
363            "colrv1_paint_transform" => include_str!("../test_data/colrv1_json/colrv1_paint_transform"),
364            "colrv1_paint_translate" => include_str!("../test_data/colrv1_json/colrv1_paint_translate"),
365            "colrv1_paint_translate_TLDX_100_TLDY_100" => include_str!("../test_data/colrv1_json/colrv1_paint_translate_TLDX_100_TLDY_100"),
366            "colrv1_sweep_coincident" => include_str!("../test_data/colrv1_json/colrv1_sweep_coincident"),
367            "colrv1_sweep_varsweep" => include_str!("../test_data/colrv1_json/colrv1_sweep_varsweep"),
368            "colrv1_sweep_varsweep_SWC1_-0.25_SWC2_0.083333336_SWC3_0.083333336_SWC4_0.25" => include_str!("../test_data/colrv1_json/colrv1_sweep_varsweep_SWC1_-0.25_SWC2_0.083333336_SWC3_0.083333336_SWC4_0.25"),
369            "colrv1_sweep_varsweep_SWPE_-45" => include_str!("../test_data/colrv1_json/colrv1_sweep_varsweep_SWPE_-45"),
370            "colrv1_sweep_varsweep_SWPE_-90" => include_str!("../test_data/colrv1_json/colrv1_sweep_varsweep_SWPE_-90"),
371            "colrv1_sweep_varsweep_SWPS_0" => include_str!("../test_data/colrv1_json/colrv1_sweep_varsweep_SWPS_0"),
372            "colrv1_sweep_varsweep_SWPS_-45_SWPE_45" => include_str!("../test_data/colrv1_json/colrv1_sweep_varsweep_SWPS_-45_SWPE_45"),
373            "colrv1_sweep_varsweep_SWPS_45_SWPE_-45_SWC1_-0.25_SWC2_-0.416687_SWC3_-0.583313_SWC4_-0.75" => include_str!("../test_data/colrv1_json/colrv1_sweep_varsweep_SWPS_45_SWPE_-45_SWC1_-0.25_SWC2_-0.416687_SWC3_-0.583313_SWC4_-0.75"),
374            "colrv1_sweep_varsweep_SWPS_90" => include_str!("../test_data/colrv1_json/colrv1_sweep_varsweep_SWPS_90"),
375            "colrv1_variable_alpha" => include_str!("../test_data/colrv1_json/colrv1_variable_alpha"),
376            "colrv1_variable_alpha_APH1_-0.7" => include_str!("../test_data/colrv1_json/colrv1_variable_alpha_APH1_-0.7"),
377            "colrv1_variable_alpha_APH2_-0.7_APH3_-0.2" => include_str!("../test_data/colrv1_json/colrv1_variable_alpha_APH2_-0.7_APH3_-0.2"),
378            _ => panic!("No entry for {key}, if this is a new test you might need to add a case"),
379        }
380    }
381}
382
383pub mod ttc {
384    pub static TTC: &[u8] = include_bytes!("../test_data/ttc/TTC.ttc");
385}
386
387pub mod meta {
388    // the table from the binary for 'Sankofa'
389    #[rustfmt::skip]
390    pub static SIMPLE_META_TABLE: &[u8] = &[
391        0x00, 0x00, 0x00, 0x01, // version 1
392        0x00, 0x00, 0x00, 0x00, // flags 0
393        0x00, 0x00, 0x00, 0x28, // reserved (?)
394        0x00, 0x00, 0x00, 0x02, // data_maps_count 2
395        0x64, 0x6c, 0x6e, 0x67, // tag: dlng
396        0x00, 0x00, 0x00, 0x28, // data offset
397        0x00, 0x00, 0x00, 0x0d, // data length
398        0x73, 0x6c, 0x6e, 0x67, // tag: slng
399        0x00, 0x00, 0x00, 0x35, // data offset
400        0x00, 0x00, 0x00, 0x04, // length
401        0x65, 0x6e, 0x2d, 0x6c,
402        0x61, 0x74, 0x6e, 0x2c,
403        0x20, 0x6c, 0x61, 0x74,
404        0x6e, 0x6c, 0x61, 0x74,
405        0x6e, 0x00, 0x00, 0x00,
406    ];
407}
408
409pub mod gvar {
410    pub static USE_MY_METRICS: &[u8] = include_bytes!("../test_data/ttf/gvar_use_my_metrics.ttf");
411}