use core::cmp::Ordering;
include!("../../generated/generated_svg.rs");
impl<'a> Svg<'a> {
pub fn glyph_data(&self, glyph_id: GlyphId) -> Option<&'a [u8]> {
let document_list = self.svg_document_list().ok()?;
let svg_document = document_list
.document_records()
.binary_search_by(|r| {
if r.start_glyph_id.get() > glyph_id {
Ordering::Greater
} else if r.end_glyph_id.get() < glyph_id {
Ordering::Less
} else {
Ordering::Equal
}
})
.ok()
.and_then(|index| document_list.document_records().get(index))
.and_then(|r| {
let all_data = document_list.offset_data().as_bytes();
let start = r.svg_doc_offset();
let end = start.checked_add(r.svg_doc_length())?;
all_data.get(start as usize..end as usize)
});
svg_document
}
}
#[cfg(test)]
mod tests {
use font_test_data::bebuffer::BeBuffer;
use super::*;
#[test]
fn read_dummy_svg_file() {
let data: [u16; 32] = [
0, 0, 10, 0, 0, 3, 1, 3, 0, 38, 0, 10, 6, 7, 0, 48, 0, 6, 9, 9, 0, 38, 0, 10,
1, 0, 0, 0, 1, 2, 0, 0, ];
let mut buf = BeBuffer::new();
buf = buf.extend(data);
let table = Svg::read(buf.data().into()).unwrap();
let first_document = &[0, 1, 0, 0, 0, 0, 0, 0, 0, 1][..];
let second_document = &[0, 2, 0, 0, 0, 0][..];
assert_eq!(table.glyph_data(GlyphId::new(0)), None);
assert_eq!(table.glyph_data(GlyphId::new(1)), Some(first_document));
assert_eq!(table.glyph_data(GlyphId::new(2)), Some(first_document));
assert_eq!(table.glyph_data(GlyphId::new(3)), Some(first_document));
assert_eq!(table.glyph_data(GlyphId::new(4)), None);
assert_eq!(table.glyph_data(GlyphId::new(5)), None);
assert_eq!(table.glyph_data(GlyphId::new(6)), Some(second_document));
assert_eq!(table.glyph_data(GlyphId::new(7)), Some(second_document));
assert_eq!(table.glyph_data(GlyphId::new(8)), None);
assert_eq!(table.glyph_data(GlyphId::new(9)), Some(first_document));
assert_eq!(table.glyph_data(GlyphId::new(10)), None);
}
#[test]
fn test_svg_glyph_data_overflow_guard() {
let data: [u16; 12] = [
0, 0, 10, 0, 0, 1, 1, 3, 0xFFFF, 0xFFFF, 0, 10, ];
let mut buf = BeBuffer::new();
buf = buf.extend(data);
let table = Svg::read(buf.data().into()).unwrap();
let _ = table.glyph_data(GlyphId::new(1));
}
}