Add rudimentary support for TTC
This commit is contained in:
parent
8fbb875654
commit
a927294790
|
@ -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;
|
||||
|
|
|
@ -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 platform_id = try!(cmap_reader.read_u16::<BigEndian>().map_err(drop));
|
||||
let encoding_id = try!(cmap_reader.read_u16::<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(())
|
||||
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) => {
|
||||
// Move to the mapping table.
|
||||
cmap_reader = self.table.bytes;
|
||||
try!(cmap_reader.jump(offset as usize));
|
||||
table_found = true;
|
||||
break
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
// 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));
|
||||
if !table_found {
|
||||
return Err(())
|
||||
}
|
||||
|
||||
// Check the mapping table format.
|
||||
let format = try!(cmap_reader.read_u16::<BigEndian>().map_err(drop));
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue