diff --git a/src/font.rs b/src/font.rs index 60c40cb9f..ea59bd38c 100644 --- a/src/font.rs +++ b/src/font.rs @@ -51,7 +51,7 @@ pub struct FontMetrics { impl Font { /// Create a new font from a font program. - pub fn new(program: Vec) -> Result { + pub fn new(program: Vec) -> FontResult { // Create opentype reader to parse font tables let mut readable = Cursor::new(&program); let mut reader = OpenTypeReader::new(&mut readable); @@ -131,7 +131,7 @@ impl Font { chars: C, needed_tables: I1, optional_tables: I2 - ) -> Result + ) -> Result where C: IntoIterator, I1: IntoIterator, S1: AsRef, @@ -181,7 +181,7 @@ struct Subsetter<'p> { impl<'p> Subsetter<'p> { fn subset(mut self, needed_tables: I1, optional_tables: I2) - -> SubsetResult + -> FontResult where I1: IntoIterator, S1: AsRef, I2: IntoIterator, S2: AsRef @@ -194,12 +194,12 @@ impl<'p> Subsetter<'p> { for table in needed_tables.into_iter() { let table = table.as_ref(); let tag: Tag = table.parse() - .map_err(|_| SubsettingError::UnsupportedTable(table.to_string()))?; + .map_err(|_| FontError::UnsupportedTable(table.to_string()))?; if self.contains(tag) { self.write_table(tag)?; } else { - return Err(SubsettingError::MissingTable(tag.to_string())); + return Err(FontError::MissingTable(tag.to_string())); } } @@ -207,7 +207,7 @@ impl<'p> Subsetter<'p> { for table in optional_tables.into_iter() { let table = table.as_ref(); let tag: Tag = table.parse() - .map_err(|_| SubsettingError::UnsupportedTable(table.to_string()))?; + .map_err(|_| FontError::UnsupportedTable(table.to_string()))?; if self.contains(tag) { self.write_table(tag)?; @@ -219,7 +219,7 @@ impl<'p> Subsetter<'p> { let widths = self.glyphs.iter() .map(|&glyph| self.font.widths.get(glyph as usize).map(|&w| w) .take_invalid("missing glyph metrics")) - .collect::>>()?; + .collect::>>()?; let mapping = self.chars.into_iter().enumerate().map(|(i, c)| (c, i as u16)) .collect::>(); @@ -234,12 +234,12 @@ impl<'p> Subsetter<'p> { }) } - fn build_glyphs(&mut self) -> SubsetResult<()> { + fn build_glyphs(&mut self) -> FontResult<()> { self.read_cmap()?; let cmap = self.cmap.as_ref().unwrap(); for &c in &self.chars { - self.glyphs.push(cmap.get(c).ok_or_else(|| SubsettingError::MissingCharacter(c))?) + self.glyphs.push(cmap.get(c).ok_or_else(|| FontError::MissingCharacter(c))?) } self.glyphs.push(self.font.default_glyph); @@ -294,7 +294,7 @@ impl<'p> Subsetter<'p> { Ok(()) } - fn write_header(&mut self) -> SubsetResult<()> { + fn write_header(&mut self) -> FontResult<()> { // Create an output buffer let header_len = 12 + self.records.len() * 16; let mut header = Vec::with_capacity(header_len); @@ -336,7 +336,7 @@ impl<'p> Subsetter<'p> { Ok(()) } - fn write_table(&mut self, tag: Tag) -> SubsetResult<()> { + fn write_table(&mut self, tag: Tag) -> FontResult<()> { match tag.value() { b"head" | b"cvt " | b"prep" | b"fpgm" | b"name" | b"post" | b"OS/2" => { self.copy_table(tag) @@ -478,19 +478,19 @@ impl<'p> Subsetter<'p> { }) }, - _ => Err(SubsettingError::UnsupportedTable(tag.to_string())), + _ => Err(FontError::UnsupportedTable(tag.to_string())), } } - fn copy_table(&mut self, tag: Tag) -> SubsetResult<()> { + fn copy_table(&mut self, tag: Tag) -> FontResult<()> { self.write_table_body(tag, |this| { let table = this.get_table_data(tag)?; Ok(this.body.extend(table)) }) } - fn write_table_body(&mut self, tag: Tag, writer: F) -> SubsetResult<()> - where F: FnOnce(&mut Self) -> SubsetResult<()> { + fn write_table_body(&mut self, tag: Tag, writer: F) -> FontResult<()> + where F: FnOnce(&mut Self) -> FontResult<()> { let start = self.body.len(); writer(self)?; let end = self.body.len(); @@ -506,10 +506,10 @@ impl<'p> Subsetter<'p> { })) } - fn get_table_data(&self, tag: Tag) -> SubsetResult<&'p [u8]> { + fn get_table_data(&self, tag: Tag) -> FontResult<&'p [u8]> { let record = match self.tables.binary_search_by_key(&tag, |r| r.tag) { Ok(index) => &self.tables[index], - Err(_) => return Err(SubsettingError::MissingTable(tag.to_string())), + Err(_) => return Err(FontError::MissingTable(tag.to_string())), }; self.font.program @@ -521,19 +521,19 @@ impl<'p> Subsetter<'p> { self.tables.binary_search_by_key(&tag, |r| r.tag).is_ok() } - fn read_cmap(&mut self) -> SubsetResult<()> { + fn read_cmap(&mut self) -> FontResult<()> { Ok(if self.cmap.is_none() { self.cmap = Some(self.reader.read_table::()?); }) } - fn read_hmtx(&mut self) -> SubsetResult<()> { + fn read_hmtx(&mut self) -> FontResult<()> { Ok(if self.hmtx.is_none() { self.hmtx = Some(self.reader.read_table::()?); }) } - fn read_loca(&mut self) -> SubsetResult<()> { + fn read_loca(&mut self) -> FontResult<()> { Ok(if self.loca.is_none() { let mut table = self.get_table_data("loca".parse().unwrap())?; let format = self.reader.read_table::
()?.index_to_loc_format; @@ -571,72 +571,81 @@ fn calculate_check_sum(data: &[u8]) -> u32 { trait TakeInvalid: Sized { /// Pull the type out of the option, returning a subsetting error /// about an invalid font wrong. - fn take_invalid>(self, message: S) -> SubsetResult; + fn take_invalid>(self, message: S) -> FontResult; /// Pull the type out of the option, returning an error about missing /// bytes if it is nothing. - fn take_bytes(self) -> SubsetResult { + fn take_bytes(self) -> FontResult { self.take_invalid("expected more bytes") } } impl TakeInvalid for Option { - fn take_invalid>(self, message: S) -> SubsetResult { - self.ok_or(SubsettingError::Opentype(opentype::Error::InvalidFont(message.into()))) + fn take_invalid>(self, message: S) -> FontResult { + self.ok_or(FontError::InvalidFont(message.into())) } } -type SubsetResult = Result; +type FontResult = Result; /// The error type for font subsetting. #[derive(Debug)] -pub enum SubsettingError { +pub enum FontError { + /// The font file is incorrect. + InvalidFont(String), /// A requested table was not present in the source font. MissingTable(String), - /// The table is unknown to the engine (unimplemented or invalid). + /// The table is unknown to the subsetting engine (unimplemented or invalid). UnsupportedTable(String), /// A requested character was not present in the source font. MissingCharacter(char), - /// There was an error while parsing the font file. - Opentype(opentype::Error), + /// An I/O Error occured while reading the font program. + Io(io::Error), + + #[doc(hidden)] + __Extensible, } -impl error::Error for SubsettingError { +impl error::Error for FontError { #[inline] fn source(&self) -> Option<&(dyn error::Error + 'static)> { match self { - SubsettingError::Opentype(err) => Some(err), + FontError::Io(err) => Some(err), _ => None, } } } -impl fmt::Display for SubsettingError { +impl fmt::Display for FontError { #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use SubsettingError::*; + use FontError::*; match self { + InvalidFont(message) => write!(f, "invalid font: {}", message), MissingTable(table) => write!(f, "missing table: {}", table), UnsupportedTable(table) => write!(f, "unsupported table: {}", table), - MissingCharacter(c) => write!(f, "missing character: {}", c), - Opentype(err) => fmt::Display::fmt(err, f), + MissingCharacter(c) => write!(f, "missing character: '{}'", c), + Io(err) => fmt::Display::fmt(err, f), + __Extensible => panic!("tried to display extensible variant"), } } } -impl From for SubsettingError { +impl From for FontError { #[inline] - fn from(err: io::Error) -> SubsettingError { - SubsettingError::Opentype(err.into()) + fn from(err: io::Error) -> FontError { + FontError::Io(err) } } -impl From for SubsettingError { - #[inline] - fn from(err: opentype::Error) -> SubsettingError { +impl From for FontError { + fn from(err: opentype::Error) -> FontError { + use opentype::Error::*; match err { - opentype::Error::MissingTable(s) => SubsettingError::MissingTable(s), - err => SubsettingError::Opentype(err), + InvalidFont(message) => FontError::InvalidFont(message), + MissingTable(tag) => FontError::MissingTable(tag.to_string()), + Io(err) => FontError::Io(err), + _ => panic!("unexpected extensible variant"), } } } diff --git a/src/lib.rs b/src/lib.rs index dcd76a260..29daa8537 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,10 +15,10 @@ //! //! // Create a compiler and export a PDF. //! let src = "Hello World from Typeset!"; -//! let compiler = Compiler::new(src); +//! let compiler = Compiler::new(); //! //! // Write the document into a file as a PDF. -//! compiler.write_pdf(&mut file).unwrap(); +//! compiler.write_pdf(src, &mut file).unwrap(); //! ``` pub mod syntax; diff --git a/src/pdf.rs b/src/pdf.rs index e0c64c6f3..4cd78d0ae 100644 --- a/src/pdf.rs +++ b/src/pdf.rs @@ -297,9 +297,9 @@ impl From for PdfWritingError { } } -impl From for PdfWritingError { +impl From for PdfWritingError { #[inline] - fn from(err: crate::font::SubsettingError) -> PdfWritingError { + fn from(err: crate::font::FontError) -> PdfWritingError { PdfWritingError { message: format!("{}", err) } } }