extern crate sfnt;
use std::fs::{File};
use std::io::{Read};
use std::path::{Path};
use sfnt::{Fixed16_16, Sfnt, checksum};
macro_rules! assert_record_eq {
($record:expr, $tag:expr, $checksum:expr, $offset:expr, $length:expr) => {
let record = $record;
assert_eq!(record.tag, $tag);
assert_eq!(record.checksum, $checksum);
assert_eq!(record.offset, $offset);
assert_eq!(record.length, $length);
};
}
macro_rules! assert_find_eq {
($sfnt:expr, $tag:expr, $checksum:expr, $offset:expr, $length:expr) => {
let (record, bytes) = $sfnt.find($tag).unwrap();
assert_record_eq!(record, $tag, $checksum, $offset, $length);
let start = record.offset as usize;
let end = start + record.length as usize;
assert_eq!(bytes, &$sfnt.bytes[start..end])
};
}
fn with_bytes<P: AsRef<Path>, F: Fn(&[u8])>(path: P, f: F) {
let mut file = File::open(path).unwrap();
let mut bytes = vec![];
file.read_to_end(&mut bytes).unwrap();
f(&bytes);
}
#[test]
fn test_parse_sfnt() {
with_bytes("tests/resources/OpenSans-Italic.ttf", |bytes| {
let sfnt = Sfnt::parse(bytes).unwrap();
assert_eq!(sfnt.bytes, bytes);
assert_eq!(sfnt.header.version, Fixed16_16(65536));
assert_eq!(sfnt.header.num_tables, 19);
assert_eq!(sfnt.header.search_range, 256);
assert_eq!(sfnt.header.entry_selector, 4);
assert_eq!(sfnt.header.range_shift, 48);
let records = sfnt.records.iter().collect::<Vec<_>>();
assert_eq!(records.len(), sfnt.header.num_tables as usize);
assert_record_eq!(records[0], "DSIG", 0x5A77FD40, 207404, 5492);
assert_record_eq!(records[1], "GDEF", 0x002603AF, 206348, 30);
assert_record_eq!(records[2], "GPOS", 0x0B370F37, 206380, 56);
assert_record_eq!(records[3], "GSUB", 0x0E2B3DB7, 206436, 966);
assert_record_eq!(records[4], "OS/2", 0xA14D963D, 440, 96);
assert_record_eq!(records[5], "cmap", 0x29AB2F68, 4276, 1050);
assert_record_eq!(records[6], "cvt ", 0x0EC01719, 7568, 160);
assert_record_eq!(records[7], "fpgm", 0x7E61B611, 5328, 1972);
assert_record_eq!(records[8], "gasp", 0x00150023, 206332, 16);
assert_record_eq!(records[9], "glyf", 0x5058F254, 9608, 73246);
assert_record_eq!(records[10], "head", 0xF847F963, 316, 54);
assert_record_eq!(records[11], "hhea", 0x102010E0, 372, 36);
assert_record_eq!(records[12], "hmtx", 0xD907CDE3, 536, 3738);
assert_record_eq!(records[13], "kern", 0x542B097E, 82856, 112182);
assert_record_eq!(records[14], "loca", 0x4D8505A9, 7728, 1878);
assert_record_eq!(records[15], "maxp", 0x054301A0, 408, 32);
assert_record_eq!(records[16], "name", 0x537422CE, 195040, 1518);
assert_record_eq!(records[17], "post", 0x0237EF6C, 196560, 9771);
assert_record_eq!(records[18], "prep", 0x54819693, 7300, 265);
});
}
#[test]
fn test_find() {
with_bytes("tests/resources/OpenSans-Italic.ttf", |bytes| {
let sfnt = Sfnt::parse(bytes).unwrap();
assert_eq!(sfnt.find("AAAA"), None);
assert_find_eq!(sfnt, "DSIG", 0x5A77FD40, 207404, 5492);
assert_find_eq!(sfnt, "GDEF", 0x002603AF, 206348, 30);
assert_find_eq!(sfnt, "GPOS", 0x0B370F37, 206380, 56);
assert_find_eq!(sfnt, "GSUB", 0x0E2B3DB7, 206436, 966);
assert_find_eq!(sfnt, "OS/2", 0xA14D963D, 440, 96);
assert_find_eq!(sfnt, "cmap", 0x29AB2F68, 4276, 1050);
assert_find_eq!(sfnt, "cvt ", 0x0EC01719, 7568, 160);
assert_find_eq!(sfnt, "fpgm", 0x7E61B611, 5328, 1972);
assert_find_eq!(sfnt, "gasp", 0x00150023, 206332, 16);
assert_find_eq!(sfnt, "glyf", 0x5058F254, 9608, 73246);
assert_find_eq!(sfnt, "head", 0xF847F963, 316, 54);
assert_find_eq!(sfnt, "hhea", 0x102010E0, 372, 36);
assert_find_eq!(sfnt, "hmtx", 0xD907CDE3, 536, 3738);
assert_find_eq!(sfnt, "kern", 0x542B097E, 82856, 112182);
assert_find_eq!(sfnt, "loca", 0x4D8505A9, 7728, 1878);
assert_find_eq!(sfnt, "maxp", 0x054301A0, 408, 32);
assert_find_eq!(sfnt, "name", 0x537422CE, 195040, 1518);
assert_find_eq!(sfnt, "post", 0x0237EF6C, 196560, 9771);
assert_find_eq!(sfnt, "prep", 0x54819693, 7300, 265);
assert_eq!(sfnt.find("ZZZZ"), None);
});
}
#[test]
fn test_checksum() {
with_bytes("tests/resources/OpenSans-Italic.ttf", |bytes| {
let sfnt = Sfnt::parse(bytes).unwrap();
for (record, bytes) in sfnt.iter() {
if record.tag != "head" {
assert_eq!(checksum(bytes), record.checksum);
}
}
});
}