Files
another-boids-in-rust/vendor/ttf-parser/tests/tables/cmap.rs

556 lines
19 KiB
Rust

mod format0 {
use ttf_parser::{cmap, GlyphId};
use crate::{convert, Unit::*};
#[test]
fn maps_not_all_256_codepoints() {
let mut data = convert(&[
UInt16(0), // format
UInt16(262), // subtable size
UInt16(0), // language ID
]);
// Map (only) codepoint 0x40 to 100.
data.extend(std::iter::repeat(0).take(256));
data[6 + 0x40] = 100;
let subtable = cmap::Subtable0::parse(&data).unwrap();
assert_eq!(subtable.glyph_index(0), None);
assert_eq!(subtable.glyph_index(0x40), Some(GlyphId(100)));
assert_eq!(subtable.glyph_index(100), None);
let mut vec = vec![];
subtable.codepoints(|c| vec.push(c));
assert_eq!(vec, [0x40]);
}
}
mod format2 {
use ttf_parser::{cmap, GlyphId};
use crate::{convert, Unit::*};
const U16_SIZE: usize = std::mem::size_of::<u16>();
#[test]
fn collect_codepoints() {
let mut data = convert(&[
UInt16(2), // format
UInt16(534), // subtable size
UInt16(0), // language ID
]);
// Make only high byte 0x28 multi-byte.
data.extend(std::iter::repeat(0x00).take(256 * U16_SIZE));
data[6 + 0x28 * U16_SIZE + 1] = 0x08;
data.extend(convert(&[
// First sub header (for single byte mapping)
UInt16(254), // first code
UInt16(2), // entry count
UInt16(0), // id delta: uninteresting
UInt16(0), // id range offset: uninteresting
// Second sub header (for high byte 0x28)
UInt16(16), // first code: (0x28 << 8) + 0x10 = 10256
UInt16(3), // entry count
UInt16(0), // id delta: uninteresting
UInt16(0), // id range offset: uninteresting
]));
// Now only glyph ID's would follow. Not interesting for codepoints.
let subtable = cmap::Subtable2::parse(&data).unwrap();
let mut vec = vec![];
subtable.codepoints(|c| vec.push(c));
assert_eq!(vec, [10256, 10257, 10258, 254, 255]);
}
#[test]
fn codepoint_at_range_end() {
let mut data = convert(&[
UInt16(2), // format
UInt16(532), // subtable size
UInt16(0), // language ID
]);
// Only single bytes.
data.extend(std::iter::repeat(0x00).take(256 * U16_SIZE));
data.extend(convert(&[
// First sub header (for single byte mapping)
UInt16(40), // first code
UInt16(2), // entry count
UInt16(0), // id delta
UInt16(2), // id range offset
// Glyph index
UInt16(100), // glyph ID [0]
UInt16(1000), // glyph ID [1]
UInt16(10000), // glyph ID [2] (unused)
]));
let subtable = cmap::Subtable2::parse(&data).unwrap();
assert_eq!(subtable.glyph_index(39), None);
assert_eq!(subtable.glyph_index(40), Some(GlyphId(100)));
assert_eq!(subtable.glyph_index(41), Some(GlyphId(1000)));
assert_eq!(subtable.glyph_index(42), None);
}
}
mod format4 {
use ttf_parser::{cmap, GlyphId};
use crate::{convert, Unit::*};
#[test]
fn single_glyph() {
let data = convert(&[
UInt16(4), // format
UInt16(32), // subtable size
UInt16(0), // language ID
UInt16(4), // 2 x segCount
UInt16(2), // search range
UInt16(0), // entry selector
UInt16(2), // range shift
// End character codes
UInt16(65), // char code [0]
UInt16(65535), // char code [1]
UInt16(0), // reserved
// Start character codes
UInt16(65), // char code [0]
UInt16(65535), // char code [1]
// Deltas
Int16(-64), // delta [0]
Int16(1), // delta [1]
// Offsets into Glyph index array
UInt16(0), // offset [0]
UInt16(0), // offset [1]
]);
let subtable = cmap::Subtable4::parse(&data).unwrap();
assert_eq!(subtable.glyph_index(0x41), Some(GlyphId(1)));
assert_eq!(subtable.glyph_index(0x42), None);
}
#[test]
fn continuous_range() {
let data = convert(&[
UInt16(4), // format
UInt16(32), // subtable size
UInt16(0), // language ID
UInt16(4), // 2 x segCount
UInt16(2), // search range
UInt16(0), // entry selector
UInt16(2), // range shift
// End character codes
UInt16(73), // char code [0]
UInt16(65535), // char code [1]
UInt16(0), // reserved
// Start character codes
UInt16(65), // char code [0]
UInt16(65535), // char code [1]
// Deltas
Int16(-64), // delta [0]
Int16(1), // delta [1]
// Offsets into Glyph index array
UInt16(0), // offset [0]
UInt16(0), // offset [1]
]);
let subtable = cmap::Subtable4::parse(&data).unwrap();
assert_eq!(subtable.glyph_index(0x40), None);
assert_eq!(subtable.glyph_index(0x41), Some(GlyphId(1)));
assert_eq!(subtable.glyph_index(0x42), Some(GlyphId(2)));
assert_eq!(subtable.glyph_index(0x43), Some(GlyphId(3)));
assert_eq!(subtable.glyph_index(0x44), Some(GlyphId(4)));
assert_eq!(subtable.glyph_index(0x45), Some(GlyphId(5)));
assert_eq!(subtable.glyph_index(0x46), Some(GlyphId(6)));
assert_eq!(subtable.glyph_index(0x47), Some(GlyphId(7)));
assert_eq!(subtable.glyph_index(0x48), Some(GlyphId(8)));
assert_eq!(subtable.glyph_index(0x49), Some(GlyphId(9)));
assert_eq!(subtable.glyph_index(0x4A), None);
}
#[test]
fn multiple_ranges() {
let data = convert(&[
UInt16(4), // format
UInt16(48), // subtable size
UInt16(0), // language ID
UInt16(8), // 2 x segCount
UInt16(4), // search range
UInt16(1), // entry selector
UInt16(4), // range shift
// End character codes
UInt16(65), // char code [0]
UInt16(69), // char code [1]
UInt16(73), // char code [2]
UInt16(65535), // char code [3]
UInt16(0), // reserved
// Start character codes
UInt16(65), // char code [0]
UInt16(67), // char code [1]
UInt16(71), // char code [2]
UInt16(65535), // char code [3]
// Deltas
Int16(-64), // delta [0]
Int16(-65), // delta [1]
Int16(-66), // delta [2]
Int16(1), // delta [3]
// Offsets into Glyph index array
UInt16(0), // offset [0]
UInt16(0), // offset [1]
UInt16(0), // offset [2]
UInt16(0), // offset [3]
]);
let subtable = cmap::Subtable4::parse(&data).unwrap();
assert_eq!(subtable.glyph_index(0x40), None);
assert_eq!(subtable.glyph_index(0x41), Some(GlyphId(1)));
assert_eq!(subtable.glyph_index(0x42), None);
assert_eq!(subtable.glyph_index(0x43), Some(GlyphId(2)));
assert_eq!(subtable.glyph_index(0x44), Some(GlyphId(3)));
assert_eq!(subtable.glyph_index(0x45), Some(GlyphId(4)));
assert_eq!(subtable.glyph_index(0x46), None);
assert_eq!(subtable.glyph_index(0x47), Some(GlyphId(5)));
assert_eq!(subtable.glyph_index(0x48), Some(GlyphId(6)));
assert_eq!(subtable.glyph_index(0x49), Some(GlyphId(7)));
assert_eq!(subtable.glyph_index(0x4A), None);
}
#[test]
fn unordered_ids() {
let data = convert(&[
UInt16(4), // format
UInt16(42), // subtable size
UInt16(0), // language ID
UInt16(4), // 2 x segCount
UInt16(2), // search range
UInt16(0), // entry selector
UInt16(2), // range shift
// End character codes
UInt16(69), // char code [0]
UInt16(65535), // char code [1]
UInt16(0), // reserved
// Start character codes
UInt16(65), // char code [0]
UInt16(65535), // char code [1]
// Deltas
Int16(0), // delta [0]
Int16(1), // delta [1]
// Offsets into Glyph index array
UInt16(4), // offset [0]
UInt16(0), // offset [1]
// Glyph index array
UInt16(1), // glyph ID [0]
UInt16(10), // glyph ID [1]
UInt16(100), // glyph ID [2]
UInt16(1000), // glyph ID [3]
UInt16(10000), // glyph ID [4]
]);
let subtable = cmap::Subtable4::parse(&data).unwrap();
assert_eq!(subtable.glyph_index(0x40), None);
assert_eq!(subtable.glyph_index(0x41), Some(GlyphId(1)));
assert_eq!(subtable.glyph_index(0x42), Some(GlyphId(10)));
assert_eq!(subtable.glyph_index(0x43), Some(GlyphId(100)));
assert_eq!(subtable.glyph_index(0x44), Some(GlyphId(1000)));
assert_eq!(subtable.glyph_index(0x45), Some(GlyphId(10000)));
assert_eq!(subtable.glyph_index(0x46), None);
}
#[test]
fn unordered_chars_and_ids() {
let data = convert(&[
UInt16(4), // format
UInt16(64), // subtable size
UInt16(0), // language ID
UInt16(12), // 2 x segCount
UInt16(8), // search range
UInt16(2), // entry selector
UInt16(4), // range shift
// End character codes
UInt16(80), // char code [0]
UInt16(256), // char code [1]
UInt16(336), // char code [2]
UInt16(512), // char code [3]
UInt16(592), // char code [4]
UInt16(65535), // char code [5]
UInt16(0), // reserved
// Start character codes
UInt16(80), // char code [0]
UInt16(256), // char code [1]
UInt16(336), // char code [2]
UInt16(512), // char code [3]
UInt16(592), // char code [4]
UInt16(65535), // char code [5]
// Deltas
Int16(-79), // delta [0]
Int16(-246), // delta [1]
Int16(-236), // delta [2]
Int16(488), // delta [3]
Int16(9408), // delta [4]
Int16(1), // delta [5]
// Offsets into Glyph index array
UInt16(0), // offset [0]
UInt16(0), // offset [1]
UInt16(0), // offset [2]
UInt16(0), // offset [3]
UInt16(0), // offset [4]
UInt16(0), // offset [5]
]);
let subtable = cmap::Subtable4::parse(&data).unwrap();
assert_eq!(subtable.glyph_index(0x40), None);
assert_eq!(subtable.glyph_index(0x50), Some(GlyphId(1)));
assert_eq!(subtable.glyph_index(0x100), Some(GlyphId(10)));
assert_eq!(subtable.glyph_index(0x150), Some(GlyphId(100)));
assert_eq!(subtable.glyph_index(0x200), Some(GlyphId(1000)));
assert_eq!(subtable.glyph_index(0x250), Some(GlyphId(10000)));
assert_eq!(subtable.glyph_index(0x300), None);
}
#[test]
fn no_end_codes() {
let data = convert(&[
UInt16(4), // format
UInt16(28), // subtable size
UInt16(0), // language ID
UInt16(4), // 2 x segCount
UInt16(2), // search range
UInt16(0), // entry selector
UInt16(2), // range shift
// End character codes
UInt16(73), // char code [0]
// 0xFF, 0xFF, // char code [1] <-- removed
UInt16(0), // reserved
// Start character codes
UInt16(65), // char code [0]
// 0xFF, 0xFF, // char code [1] <-- removed
// Deltas
Int16(-64), // delta [0]
Int16(1), // delta [1]
// Offsets into Glyph index array
UInt16(0), // offset [0]
UInt16(0), // offset [1]
]);
assert!(cmap::Subtable4::parse(&data).is_none());
}
#[test]
fn invalid_segment_count() {
let data = convert(&[
UInt16(4), // format
UInt16(32), // subtable size
UInt16(0), // language ID
UInt16(1), // 2 x segCount <-- must be more than 1
UInt16(2), // search range
UInt16(0), // entry selector
UInt16(2), // range shift
// End character codes
UInt16(65), // char code [0]
UInt16(65535), // char code [1]
UInt16(0), // reserved
// Start character codes
UInt16(65), // char code [0]
UInt16(65535), // char code [1]
// Deltas
Int16(-64), // delta [0]
Int16(1), // delta [1]
// Offsets into Glyph index array
UInt16(0), // offset [0]
UInt16(0), // offset [1]
]);
assert!(cmap::Subtable4::parse(&data).is_none());
}
#[test]
fn only_end_segments() {
let data = convert(&[
UInt16(4), // format
UInt16(32), // subtable size
UInt16(0), // language ID
UInt16(2), // 2 x segCount
UInt16(2), // search range
UInt16(0), // entry selector
UInt16(2), // range shift
// End character codes
UInt16(65535), // char code [1]
UInt16(0), // reserved
// Start character codes
UInt16(65535), // char code [1]
// Deltas
Int16(-64), // delta [0]
Int16(1), // delta [1]
// Offsets into Glyph index array
UInt16(0), // offset [0]
UInt16(0), // offset [1]
]);
let subtable = cmap::Subtable4::parse(&data).unwrap();
// Should not loop forever.
assert_eq!(subtable.glyph_index(0x41), None);
}
#[test]
fn invalid_length() {
let data = convert(&[
UInt16(4), // format
UInt16(16), // subtable size <-- the size should be 32, but we don't check it anyway
UInt16(0), // language ID
UInt16(4), // 2 x segCount
UInt16(2), // search range
UInt16(0), // entry selector
UInt16(2), // range shift
// End character codes
UInt16(65), // char code [0]
UInt16(65535), // char code [1]
UInt16(0), // reserved
// Start character codes
UInt16(65), // char code [0]
UInt16(65535), // char code [1]
// Deltas
Int16(-64), // delta [0]
Int16(1), // delta [1]
// Offsets into Glyph index array
UInt16(0), // offset [0]
UInt16(0), // offset [1]
]);
let subtable = cmap::Subtable4::parse(&data).unwrap();
assert_eq!(subtable.glyph_index(0x41), Some(GlyphId(1)));
assert_eq!(subtable.glyph_index(0x42), None);
}
#[test]
fn codepoint_out_of_range() {
let data = convert(&[
UInt16(4), // format
UInt16(32), // subtable size
UInt16(0), // language ID
UInt16(4), // 2 x segCount
UInt16(2), // search range
UInt16(0), // entry selector
UInt16(2), // range shift
// End character codes
UInt16(65), // char code [0]
UInt16(65535), // char code [1]
UInt16(0), // reserved
// Start character codes
UInt16(65), // char code [0]
UInt16(65535), // char code [1]
// Deltas
Int16(-64), // delta [0]
Int16(1), // delta [1]
// Offsets into Glyph index array
UInt16(0), // offset [0]
UInt16(0), // offset [1]
]);
let subtable = cmap::Subtable4::parse(&data).unwrap();
// Format 4 support only u16 codepoints, so we have to bail immediately otherwise.
assert_eq!(subtable.glyph_index(0x1FFFF), None);
}
#[test]
fn zero() {
let data = convert(&[
UInt16(4), // format
UInt16(42), // subtable size
UInt16(0), // language ID
UInt16(4), // 2 x segCount
UInt16(2), // search range
UInt16(0), // entry selector
UInt16(2), // range shift
// End character codes
UInt16(69), // char code [0]
UInt16(65535), // char code [1]
UInt16(0), // reserved
// Start character codes
UInt16(65), // char code [0]
UInt16(65535), // char code [1]
// Deltas
Int16(0), // delta [0]
Int16(1), // delta [1]
// Offsets into Glyph index array
UInt16(4), // offset [0]
UInt16(0), // offset [1]
// Glyph index array
UInt16(0), // glyph ID [0] <-- indicates missing glyph
UInt16(10), // glyph ID [1]
UInt16(100), // glyph ID [2]
UInt16(1000), // glyph ID [3]
UInt16(10000), // glyph ID [4]
]);
let subtable = cmap::Subtable4::parse(&data).unwrap();
assert_eq!(subtable.glyph_index(0x41), None);
}
#[test]
fn invalid_offset() {
let data = convert(&[
UInt16(4), // format
UInt16(42), // subtable size
UInt16(0), // language ID
UInt16(4), // 2 x segCount
UInt16(2), // search range
UInt16(0), // entry selector
UInt16(2), // range shift
// End character codes
UInt16(69), // char code [0]
UInt16(65535), // char code [1]
UInt16(0), // reserved
// Start character codes
UInt16(65), // char code [0]
UInt16(65535), // char code [1]
// Deltas
Int16(0), // delta [0]
Int16(1), // delta [1]
// Offsets into Glyph index array
UInt16(4), // offset [0]
UInt16(65535), // offset [1]
// Glyph index array
UInt16(1), // glyph ID [0]
]);
let subtable = cmap::Subtable4::parse(&data).unwrap();
assert_eq!(subtable.glyph_index(65535), None);
}
#[test]
fn collect_codepoints() {
let data = convert(&[
UInt16(4), // format
UInt16(24), // subtable size
UInt16(0), // language ID
UInt16(4), // 2 x segCount
UInt16(2), // search range
UInt16(0), // entry selector
UInt16(2), // range shift
// End character codes
UInt16(34), // char code [0]
UInt16(65535), // char code [1]
UInt16(0), // reserved
// Start character codes
UInt16(27), // char code [0]
UInt16(65533), // char code [1]
// Deltas
Int16(0), // delta [0]
Int16(1), // delta [1]
// Offsets into Glyph index array
UInt16(4), // offset [0]
UInt16(0), // offset [1]
// Glyph index array
UInt16(0), // glyph ID [0]
UInt16(10), // glyph ID [1]
]);
let subtable = cmap::Subtable4::parse(&data).unwrap();
let mut vec = vec![];
subtable.codepoints(|c| vec.push(c));
assert_eq!(vec, [27, 28, 29, 30, 31, 32, 33, 34, 65533, 65534, 65535]);
}
}