Add rudimentary support for TTC

This commit is contained in:
Patrick Walton 2017-01-27 13:01:21 -08:00
parent 8fbb875654
commit a927294790
3 changed files with 58 additions and 15 deletions

View File

@ -1,6 +1,9 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
#![feature(alloc_system)]
extern crate alloc_system;
extern crate compute_shader;
extern crate euclid;
extern crate gl;

View File

@ -52,20 +52,28 @@ impl<'a> CmapTable<'a> {
// Check platform ID and encoding.
// TODO(pcwalton): Handle more.
// TODO(pcwalton): Search for one that we can handle.
let mut table_found = false;
for _ in 0..num_tables {
let platform_id = try!(cmap_reader.read_u16::<BigEndian>().map_err(drop));
let encoding_id = try!(cmap_reader.read_u16::<BigEndian>().map_err(drop));
let offset = try!(cmap_reader.read_u32::<BigEndian>().map_err(drop));
match (platform_id, encoding_id) {
(PLATFORM_ID_UNICODE, _) |
(PLATFORM_ID_MICROSOFT, MICROSOFT_ENCODING_ID_UNICODE_BMP) |
(PLATFORM_ID_MICROSOFT, MICROSOFT_ENCODING_ID_UNICODE_UCS4) => {}
_ => return Err(())
}
(PLATFORM_ID_MICROSOFT, MICROSOFT_ENCODING_ID_UNICODE_UCS4) => {
// Move to the mapping table.
let offset = try!(cmap_reader.read_u32::<BigEndian>().map_err(drop));
cmap_reader = self.table.bytes;
try!(cmap_reader.jump(offset as usize));
table_found = true;
break
}
_ => {}
}
}
if !table_found {
return Err(())
}
// Check the mapping table format.
let format = try!(cmap_reader.read_u16::<BigEndian>().map_err(drop));

View File

@ -50,6 +50,15 @@ const LOCA: u32 = ((b'l' as u32) << 24) |
((b'o' as u32) << 16) |
((b'c' as u32) << 8) |
(b'a' as u32);
const TTCF: u32 = ((b't' as u32) << 24) |
((b't' as u32) << 16) |
((b'c' as u32) << 8) |
(b'f' as u32);
static SFNT_VERSIONS: [u32; 2] = [
0x10000,
((b't' as u32) << 24) | ((b'r' as u32) << 16) | ((b'u' as u32) << 8) | (b'e' as u32),
];
pub struct Font<'a> {
pub bytes: &'a [u8],
@ -71,10 +80,33 @@ pub struct FontTable<'a> {
impl<'a> Font<'a> {
#[inline]
pub fn new<'b>(bytes: &'b [u8]) -> Result<Font<'b>, ()> {
// Read the tables we care about.
// Check magic number.
let mut reader = bytes;
let sfnt_version = try!(reader.read_u32::<BigEndian>().map_err(drop));
if sfnt_version != 0x10000 {
let mut magic_number = try!(reader.read_u32::<BigEndian>().map_err(drop));
if magic_number == TTCF {
// This is a font collection. Read the first font.
//
// TODO(pcwalton): Provide a mechanism to read others.
let major_version = try!(reader.read_u16::<BigEndian>().map_err(drop));
let minor_version = try!(reader.read_u16::<BigEndian>().map_err(drop));
if (major_version != 1 && major_version != 2) || minor_version != 0 {
return Err(())
}
let num_fonts = try!(reader.read_u32::<BigEndian>().map_err(drop));
if num_fonts == 0 {
return Err(())
}
let table_offset = try!(reader.read_u32::<BigEndian>().map_err(drop));
reader = bytes;
try!(reader.jump(table_offset as usize));
magic_number = try!(reader.read_u32::<BigEndian>().map_err(drop));
}
// Check version.
if !SFNT_VERSIONS.contains(&magic_number) {
return Err(())
}