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.
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
#![feature(alloc_system)]
|
||||||
|
|
||||||
|
extern crate alloc_system;
|
||||||
extern crate compute_shader;
|
extern crate compute_shader;
|
||||||
extern crate euclid;
|
extern crate euclid;
|
||||||
extern crate gl;
|
extern crate gl;
|
||||||
|
|
|
@ -52,20 +52,28 @@ impl<'a> CmapTable<'a> {
|
||||||
|
|
||||||
// Check platform ID and encoding.
|
// Check platform ID and encoding.
|
||||||
// TODO(pcwalton): Handle more.
|
// 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 platform_id = try!(cmap_reader.read_u16::<BigEndian>().map_err(drop));
|
||||||
let encoding_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) {
|
match (platform_id, encoding_id) {
|
||||||
(PLATFORM_ID_UNICODE, _) |
|
(PLATFORM_ID_UNICODE, _) |
|
||||||
(PLATFORM_ID_MICROSOFT, MICROSOFT_ENCODING_ID_UNICODE_BMP) |
|
(PLATFORM_ID_MICROSOFT, MICROSOFT_ENCODING_ID_UNICODE_BMP) |
|
||||||
(PLATFORM_ID_MICROSOFT, MICROSOFT_ENCODING_ID_UNICODE_UCS4) => {}
|
(PLATFORM_ID_MICROSOFT, MICROSOFT_ENCODING_ID_UNICODE_UCS4) => {
|
||||||
_ => return Err(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move to the mapping table.
|
// Move to the mapping table.
|
||||||
let offset = try!(cmap_reader.read_u32::<BigEndian>().map_err(drop));
|
|
||||||
cmap_reader = self.table.bytes;
|
cmap_reader = self.table.bytes;
|
||||||
try!(cmap_reader.jump(offset as usize));
|
try!(cmap_reader.jump(offset as usize));
|
||||||
|
table_found = true;
|
||||||
|
break
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !table_found {
|
||||||
|
return Err(())
|
||||||
|
}
|
||||||
|
|
||||||
// Check the mapping table format.
|
// Check the mapping table format.
|
||||||
let format = try!(cmap_reader.read_u16::<BigEndian>().map_err(drop));
|
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'o' as u32) << 16) |
|
||||||
((b'c' as u32) << 8) |
|
((b'c' as u32) << 8) |
|
||||||
(b'a' as u32);
|
(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 struct Font<'a> {
|
||||||
pub bytes: &'a [u8],
|
pub bytes: &'a [u8],
|
||||||
|
@ -71,10 +80,33 @@ pub struct FontTable<'a> {
|
||||||
impl<'a> Font<'a> {
|
impl<'a> Font<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new<'b>(bytes: &'b [u8]) -> Result<Font<'b>, ()> {
|
pub fn new<'b>(bytes: &'b [u8]) -> Result<Font<'b>, ()> {
|
||||||
// Read the tables we care about.
|
// Check magic number.
|
||||||
let mut reader = bytes;
|
let mut reader = bytes;
|
||||||
let sfnt_version = try!(reader.read_u32::<BigEndian>().map_err(drop));
|
let mut magic_number = try!(reader.read_u32::<BigEndian>().map_err(drop));
|
||||||
if sfnt_version != 0x10000 {
|
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(())
|
return Err(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue