diff --git a/Cargo.toml b/Cargo.toml index 101970af8..df49e0e7e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" build = "build.rs" [dependencies] -toddle = { path = "../toddle", default-features = false } +toddle = { path = "../toddle", features = ["query"], default-features = false } tide = { path = "../tide" } byteorder = "1" smallvec = "1" diff --git a/src/bin/main.rs b/src/bin/main.rs index 8cb7c0554..11f308803 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -3,9 +3,9 @@ use std::io::BufWriter; use std::path::{Path, PathBuf}; use futures_executor::block_on; -use typstc::Typesetter; -use typstc::toddle::query::FileSystemFontProvider; -use typstc::export::pdf::PdfExporter; +use typstc::{Typesetter, DynErrorProvider}; +use typstc::toddle::query::fs::EagerFsProvider; +use typstc::export::pdf; fn main() { @@ -37,15 +37,14 @@ fn run() -> Result<(), Box> { let src = read_to_string(source) .map_err(|_| "failed to read from source file")?; - let mut typesetter = Typesetter::new(); - let provider = FileSystemFontProvider::from_index("../fonts/index.json").unwrap(); - typesetter.add_font_provider(provider); + let (fs, entries) = EagerFsProvider::from_index("../fonts", "index.json")?; + let provider = DynErrorProvider::new(fs); + let typesetter = Typesetter::new((Box::new(provider), entries)); let layouts = block_on(typesetter.typeset(&src)); - let exporter = PdfExporter::new(); let writer = BufWriter::new(File::create(&dest)?); - exporter.export(&layouts, typesetter.loader(), writer)?; + pdf::export(&layouts, typesetter.loader(), writer)?; Ok(()) } diff --git a/src/export/pdf.rs b/src/export/pdf.rs index 48aa2510c..f877d4584 100644 --- a/src/export/pdf.rs +++ b/src/export/pdf.rs @@ -11,45 +11,35 @@ use tide::font::{ CMap, CMapEncoding, FontStream, GlyphUnit, WidthRecord, }; -use toddle::Error as FontError; -use toddle::font::OwnedFont; -use toddle::query::{SharedFontLoader, FontIndex}; +use toddle::{Font, OwnedFont, LoadError}; +use toddle::types::Tag; +use toddle::query::FontIndex; use toddle::tables::{ CharMap, Header, HorizontalMetrics, MacStyleFlags, Name, NameEntry, Post, OS2, }; +use crate::GlobalFontLoader; use crate::layout::{MultiLayout, Layout, LayoutAction}; use crate::size::Size; -/// Exports layouts into _PDFs_. -pub struct PdfExporter {} - -impl PdfExporter { - /// Create a new exporter. - pub fn new() -> PdfExporter { - PdfExporter {} - } - - /// Export a layouted list of boxes. The same font loader as used for - /// layouting needs to be passed in here since the layout only contains - /// indices referencing the loaded fonts. The raw PDF ist written into the - /// target writable, returning the number of bytes written. - pub fn export( - &self, - layout: &MultiLayout, - loader: &SharedFontLoader, - target: W, - ) -> PdfResult { - ExportProcess::new(layout, loader, target)?.write() - } +/// Export a layouted list of boxes. The same font loader as used for +/// layouting needs to be passed in here since the layout only contains +/// indices referencing the loaded fonts. The raw PDF ist written into the +/// target writable, returning the number of bytes written. +pub fn export( + layout: &MultiLayout, + loader: &GlobalFontLoader, + target: W, +) -> PdfResult { + PdfExporter::new(layout, loader, target)?.write() } /// The data relevant to the export of one document. -struct ExportProcess<'d, W: Write> { +struct PdfExporter<'a, W: Write> { writer: PdfWriter, - layouts: &'d MultiLayout, + layouts: &'a MultiLayout, /// Since we cross-reference pages and fonts with their IDs already in the document /// catalog, we need to know exactly which ID is used for what from the beginning. @@ -76,18 +66,18 @@ struct Offsets { fonts: (Ref, Ref), } -impl<'d, W: Write> ExportProcess<'d, W> { +impl<'a, W: Write> PdfExporter<'a, W> { /// Prepare the export. Only once [`ExportProcess::write`] is called the /// writing really happens. fn new( - layouts: &'d MultiLayout, - font_loader: &SharedFontLoader, + layouts: &'a MultiLayout, + font_loader: &GlobalFontLoader, target: W, - ) -> PdfResult> { + ) -> PdfResult> { let (fonts, font_remap) = Self::subset_fonts(layouts, font_loader)?; let offsets = Self::calculate_offsets(layouts.len(), fonts.len()); - Ok(ExportProcess { + Ok(PdfExporter { writer: PdfWriter::new(target), layouts, offsets, @@ -101,8 +91,8 @@ impl<'d, W: Write> ExportProcess<'d, W> { /// one used in the PDF. The new ones index into the returned vector of /// owned fonts. fn subset_fonts( - layouts: &'d MultiLayout, - font_loader: &SharedFontLoader + layouts: &'a MultiLayout, + font_loader: &GlobalFontLoader, ) -> PdfResult<(Vec, HashMap)> { let mut fonts = Vec::new(); let mut font_chars: HashMap> = HashMap::new(); @@ -144,18 +134,22 @@ impl<'d, W: Write> ExportProcess<'d, W> { let mut font_loader = font_loader.borrow_mut(); // All tables not listed here are dropped. - const SUBSET_TABLES: [&str; 13] = [ - "name", "OS/2", "post", "head", "hhea", "hmtx", "maxp", - "cmap", "cvt ", "fpgm", "prep", "loca", "glyf", - ]; + let tables: Vec<_> = [ + b"name", b"OS/2", b"post", b"head", b"hhea", b"hmtx", b"maxp", + b"cmap", b"cvt ", b"fpgm", b"prep", b"loca", b"glyf", + ].iter().map(|&s| Tag(*s)).collect(); // Do the subsetting. for index in 0 .. num_fonts { let old_index = new_to_old[&index]; let font = font_loader.get_with_index(old_index); - let subsetted = font.subsetted(font_chars[&old_index].iter().cloned(), &SUBSET_TABLES) - .map(|bytes| OwnedFont::from_bytes(bytes)) - .unwrap_or_else(|_| font.to_owned())?; + + let chars = font_chars[&old_index].iter().cloned(); + let subsetted = match font.subsetted(chars, tables.iter().copied()) { + Ok(data) => Font::from_bytes(data)?, + Err(_) => font.clone(), + }; + fonts.push(subsetted); } @@ -302,7 +296,7 @@ impl<'d, W: Write> ExportProcess<'d, W> { id, Type0Font::new( base_font.clone(), - CMapEncoding::Predefined("Identity-H".to_owned()), + CMapEncoding::Predefined("Identity-H".to_string()), id + 1, ) .to_unicode(id + 3), @@ -409,7 +403,7 @@ fn ids((start, end): (Ref, Ref)) -> impl Iterator { /// The error type for _PDF_ exporting. pub enum PdfExportError { /// An error occured while subsetting the font for the _PDF_. - Font(FontError), + Font(LoadError), /// An I/O Error on the underlying writable. Io(io::Error), } @@ -418,13 +412,13 @@ error_type! { self: PdfExportError, res: PdfResult, show: f => match self { - PdfExportError::Font(err) => write!(f, "font error: {}", err), - PdfExportError::Io(err) => write!(f, "io error: {}", err), + PdfExportError::Font(err) => err.fmt(f), + PdfExportError::Io(err) => err.fmt(f), }, source: match self { PdfExportError::Font(err) => Some(err), PdfExportError::Io(err) => Some(err), }, from: (err: io::Error, PdfExportError::Io(err)), - from: (err: FontError, PdfExportError::Font(err)), + from: (err: LoadError, PdfExportError::Font(err)), } diff --git a/src/func.rs b/src/func.rs index ce67034f2..63d7e8efe 100644 --- a/src/func.rs +++ b/src/func.rs @@ -145,15 +145,14 @@ macro_rules! function { (@layout($name:ident) layout($this:ident, $ctx:ident, $errors:ident) $code:block) => { impl $crate::syntax::Model for $name { - fn layout<'a, 'b, 'c, 't>( + fn layout<'a, 'b, 't>( #[allow(unused)] &'a $this, - #[allow(unused)] mut $ctx: $crate::layout::LayoutContext<'b, 'c>, + #[allow(unused)] mut $ctx: $crate::layout::LayoutContext<'b>, ) -> $crate::layout::DynFuture<'t, $crate::layout::Layouted< $crate::layout::Commands<'a>> > where 'a: 't, 'b: 't, - 'c: 't, Self: 't, { Box::pin(async move { diff --git a/src/layout/model.rs b/src/layout/model.rs index 1d635f5c7..2eac9a8c9 100644 --- a/src/layout/model.rs +++ b/src/layout/model.rs @@ -5,8 +5,9 @@ use std::future::Future; use std::pin::Pin; use smallvec::smallvec; -use toddle::query::SharedFontLoader; +use toddle::query::{SharedFontLoader, FontProvider}; +use crate::GlobalFontLoader; use crate::error::Errors; use crate::style::{LayoutStyle, PageStyle, TextStyle}; use crate::size::{Size, Size2D}; @@ -18,8 +19,8 @@ use super::*; /// Performs the model layouting. -pub struct ModelLayouter<'a, 'p> { - ctx: LayoutContext<'a, 'p>, +pub struct ModelLayouter<'a> { + ctx: LayoutContext<'a>, layouter: LineLayouter, style: LayoutStyle, errors: Errors, @@ -27,10 +28,10 @@ pub struct ModelLayouter<'a, 'p> { /// The context for layouting. #[derive(Debug, Clone)] -pub struct LayoutContext<'a, 'p> { +pub struct LayoutContext<'a> { /// The font loader to retrieve fonts from when typesetting text /// using [`layout_text`]. - pub loader: &'a SharedFontLoader<'p>, + pub loader: &'a GlobalFontLoader, /// The style for pages and text. pub style: &'a LayoutStyle, /// The base unpadded dimensions of this container (for relative sizing). @@ -105,7 +106,7 @@ pub enum Command<'a> { } /// Layout a syntax model into a list of boxes. -pub async fn layout(model: &SyntaxModel, ctx: LayoutContext<'_, '_>) -> Layouted { +pub async fn layout(model: &SyntaxModel, ctx: LayoutContext<'_>) -> Layouted { let mut layouter = ModelLayouter::new(ctx); layouter.layout_syntax_model(model).await; layouter.finish() @@ -116,9 +117,9 @@ pub async fn layout(model: &SyntaxModel, ctx: LayoutContext<'_, '_>) -> Layouted /// work internally. pub type DynFuture<'a, T> = Pin + 'a>>; -impl<'a, 'p> ModelLayouter<'a, 'p> { +impl<'a> ModelLayouter<'a> { /// Create a new model layouter. - pub fn new(ctx: LayoutContext<'a, 'p>) -> ModelLayouter<'a, 'p> { + pub fn new(ctx: LayoutContext<'a>) -> ModelLayouter<'a> { ModelLayouter { layouter: LineLayouter::new(LineContext { spaces: ctx.spaces.clone(), @@ -182,6 +183,7 @@ impl<'a, 'p> ModelLayouter<'a, 'p> { Some("monospace") => { list.remove(0); }, _ => list.insert(0, "monospace".to_string()), } + self.style.text.fallback.flatten(); } Node::Model(model) => { diff --git a/src/layout/text.rs b/src/layout/text.rs index a0f476431..6b512a07e 100644 --- a/src/layout/text.rs +++ b/src/layout/text.rs @@ -4,17 +4,18 @@ //! When the primary layouting axis horizontally inversed, the word is spelled //! backwards. Vertical word layout is not yet supported. -use toddle::query::{SharedFontLoader, FontQuery, FontIndex}; +use toddle::query::{FontQuery, FontIndex}; use toddle::tables::{CharMap, Header, HorizontalMetrics}; +use crate::GlobalFontLoader; use crate::size::{Size, Size2D}; use crate::style::TextStyle; use super::*; /// Performs the text layouting. -struct TextLayouter<'a, 'p> { - ctx: TextContext<'a, 'p>, +struct TextLayouter<'a> { + ctx: TextContext<'a>, text: &'a str, actions: LayoutActions, buffer: String, @@ -24,10 +25,10 @@ struct TextLayouter<'a, 'p> { /// The context for text layouting. #[derive(Copy, Clone)] -pub struct TextContext<'a, 'p> { +pub struct TextContext<'a> { /// The font loader to retrieve fonts from when typesetting text /// using [`layout_text`]. - pub loader: &'a SharedFontLoader<'p>, + pub loader: &'a GlobalFontLoader, /// The style for text: Font selection with classes, weights and variants, /// font sizes, spacing and so on. pub style: &'a TextStyle, @@ -39,13 +40,13 @@ pub struct TextContext<'a, 'p> { } /// Layouts text into a box. -pub async fn layout_text(text: &str, ctx: TextContext<'_, '_>) -> Layout { +pub async fn layout_text(text: &str, ctx: TextContext<'_>) -> Layout { TextLayouter::new(text, ctx).layout().await } -impl<'a, 'p> TextLayouter<'a, 'p> { +impl<'a> TextLayouter<'a> { /// Create a new text layouter. - fn new(text: &'a str, ctx: TextContext<'a, 'p>) -> TextLayouter<'a, 'p> { + fn new(text: &'a str, ctx: TextContext<'a>) -> TextLayouter<'a> { TextLayouter { ctx, text, diff --git a/src/lib.rs b/src/lib.rs index a36b5cda5..07a60e356 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,8 +21,14 @@ pub use toddle; use std::cell::RefCell; +use std::error::Error; +use std::fmt::{self, Debug, Formatter}; +use std::io::Cursor; +use async_trait::async_trait; use smallvec::smallvec; -use toddle::query::{FontLoader, FontProvider, SharedFontLoader}; + +use toddle::{Font, OwnedData}; +use toddle::query::{FontLoader, FontProvider, SharedFontLoader, FontDescriptor}; use crate::layout::{Layouted, MultiLayout}; use crate::style::{LayoutStyle, PageStyle, TextStyle}; @@ -45,20 +51,29 @@ pub mod syntax; /// Transforms source code into typesetted layouts. /// /// A typesetter can be configured through various methods. -pub struct Typesetter<'p> { +pub struct Typesetter { /// The font loader shared by all typesetting processes. - loader: SharedFontLoader<'p>, + loader: GlobalFontLoader, /// The base layouting style. style: LayoutStyle, /// The standard library scope. scope: Scope, } -impl<'p> Typesetter<'p> { +/// The font loader type used in the [`Typesetter`]. +/// +/// This font loader is ref-cell protected and backed by a dynamic font +/// provider. +pub type GlobalFontLoader = SharedFontLoader; + +/// The provider type of font loaders used in the [`Typesetter`]. +pub type GlobalProvider = Box>>; + +impl Typesetter { /// Create a new typesetter. - pub fn new() -> Typesetter<'p> { + pub fn new(provider: (GlobalProvider, Vec)) -> Typesetter { Typesetter { - loader: RefCell::new(FontLoader::new()), + loader: RefCell::new(FontLoader::new(provider)), style: LayoutStyle::default(), scope: Scope::with_std(), } @@ -74,14 +89,8 @@ impl<'p> Typesetter<'p> { self.style.text = style; } - /// Add a font provider to the context of this typesetter. - pub fn add_font_provider(&mut self, provider: P) - where P: FontProvider { - self.loader.get_mut().add_provider(provider); - } - /// A reference to the backing font loader. - pub fn loader(&self) -> &SharedFontLoader<'p> { + pub fn loader(&self) -> &GlobalFontLoader { &self.loader } @@ -121,3 +130,29 @@ impl<'p> Typesetter<'p> { self.layout(&tree).await.output } } + +/// Wraps a font provider and transforms its errors into boxed trait objects. +/// This enables font providers that do not return boxed errors to be used with +/// the typesetter. +pub struct DynErrorProvider

{ + provider: P, +} + +impl

DynErrorProvider

+where P: FontProvider, P::Error: Error + 'static { + /// Create a new dynamic error provider from any provider. + pub fn new(provider: P) -> DynErrorProvider

{ + DynErrorProvider { provider } + } +} + +#[async_trait(?Send)] +impl

FontProvider for DynErrorProvider

+where P: FontProvider, P::Error: Error + 'static { + type Data = P::Data; + type Error = Box; + + async fn load(&self, index: usize, variant: usize) -> Result, Self::Error> { + Ok(self.provider.load(index, variant).await?) + } +} diff --git a/src/library/font.rs b/src/library/font.rs index 07707e907..8e62563e8 100644 --- a/src/library/font.rs +++ b/src/library/font.rs @@ -20,7 +20,10 @@ function! { layout(self, ctx, errors) { styled(&self.body, ctx, Some(&self.list), - |s, l| s.fallback.list = l.clone()) + |s, list| { + s.fallback.list = list.clone(); + s.fallback.flatten(); + }) } } diff --git a/src/library/mod.rs b/src/library/mod.rs index 02311c0da..1a36fcc72 100644 --- a/src/library/mod.rs +++ b/src/library/mod.rs @@ -1,5 +1,6 @@ //! The _Typst_ standard library. +use toddle::query::FontProvider; use crate::syntax::Scope; use crate::func::prelude::*; @@ -68,7 +69,7 @@ function! { /// Layout an optional body with a change of the text style. fn styled<'a, T, F>( body: &'a Option, - ctx: LayoutContext, + ctx: LayoutContext<'_>, data: Option, f: F, ) -> Commands<'a> where F: FnOnce(&mut TextStyle, T) { diff --git a/src/style.rs b/src/style.rs index 643dc03a1..e49e9680c 100644 --- a/src/style.rs +++ b/src/style.rs @@ -1,6 +1,7 @@ //! Styles for text and pages. -use toddle::query::{FontFallbackTree, FontVariant, FontStyle, FontWeight}; +use toddle::fallback; +use toddle::query::{FallbackTree, FontVariant, FontStyle, FontWeight}; use crate::size::{Size, Size2D, SizeBox, ValueBox, PSize}; @@ -17,7 +18,7 @@ pub struct LayoutStyle { #[derive(Debug, Clone)] pub struct TextStyle { /// A tree of font names and generic family names. - pub fallback: FontFallbackTree, + pub fallback: FallbackTree, /// The selected font variant. pub variant: FontVariant, /// Whether the bolder toggle is active or inactive. This determines @@ -57,38 +58,19 @@ impl TextStyle { } } -macro_rules! fallback { - ( - list: ($($f:expr),*), - classes: { $($c:expr => ($($cf:expr),*),)* }, - base: ($($b:expr),*), - ) => ({ - let mut fallback = FontFallbackTree::new( - vec![$($f.to_string()),*], - vec![$($b.to_string()),*], - ); - $( - fallback.set_class_list($c.to_string(), vec![$($cf.to_string()),*]) - .expect("TextStyle::default: unexpected error \ - when setting class list"); - )* - fallback - }); -} - impl Default for TextStyle { fn default() -> TextStyle { TextStyle { fallback: fallback! { - list: ("sans-serif"), + list: ["sans-serif"], classes: { - "serif" => ("source serif pro", "noto serif"), - "sans-serif" => ("source sans pro", "noto sans"), - "monospace" => ("source code pro", "noto sans mono"), - "math" => ("latin modern math", "serif"), + "serif" => ["source serif pro", "noto serif"], + "sans-serif" => ["source sans pro", "noto sans"], + "monospace" => ["source code pro", "noto sans mono"], + "math" => ["latin modern math", "serif"], }, - base: ("source sans pro", "noto sans", - "noto emoji", "latin modern math"), + base: ["source sans pro", "noto sans", + "noto emoji", "latin modern math"], }, variant: FontVariant { style: FontStyle::Normal, @@ -157,7 +139,7 @@ pub struct Paper { impl Paper { /// The paper with the given name. - pub fn from_str(name: &str) -> Option { + pub fn from_name(name: &str) -> Option { parse_paper(name) } } diff --git a/src/syntax/func/values.rs b/src/syntax/func/values.rs index 515d6a43d..e4a0b2ad1 100644 --- a/src/syntax/func/values.rs +++ b/src/syntax/func/values.rs @@ -145,7 +145,7 @@ impl Value for FontStyle { type Output = Self; fn parse(expr: Spanned) -> Result { - FontStyle::from_str(Ident::parse(expr)?.as_str()) + FontStyle::from_name(Ident::parse(expr)?.as_str()) .ok_or_else(|| err!("invalid font style")) } } @@ -166,7 +166,7 @@ impl Value for FontWeight { } } Expr::Ident(id) => { - FontWeight::from_str(id.as_str()) + FontWeight::from_name(id.as_str()) .ok_or_else(|| err!("invalid font weight")) .map(|weight| (weight, false)) } @@ -180,7 +180,7 @@ impl Value for Paper { type Output = Self; fn parse(expr: Spanned) -> Result { - Paper::from_str(Ident::parse(expr)?.as_str()) + Paper::from_name(Ident::parse(expr)?.as_str()) .ok_or_else(|| err!("invalid paper type")) } } diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs index 4430f6e8f..9d83e5468 100644 --- a/src/syntax/mod.rs +++ b/src/syntax/mod.rs @@ -23,7 +23,10 @@ pub_use_mod!(tokens); pub trait Model: Debug + ModelBounds { /// Layout the model into a sequence of commands processed by a /// [`ModelLayouter`](crate::layout::ModelLayouter). - async fn layout<'a>(&'a self, ctx: LayoutContext<'_, '_>) -> Layouted>; + async fn layout<'a>( + &'a self, + ctx: LayoutContext<'_>, + ) -> Layouted>; } /// A tree representation of source code. @@ -47,7 +50,10 @@ impl SyntaxModel { #[async_trait(?Send)] impl Model for SyntaxModel { - async fn layout<'a>(&'a self, _: LayoutContext<'_, '_>) -> Layouted> { + async fn layout<'a>( + &'a self, + _: LayoutContext<'_>, + ) -> Layouted> { Layouted { output: vec![Command::LayoutSyntaxModel(self)], errors: vec![], diff --git a/src/syntax/parsing.rs b/src/syntax/parsing.rs index 9d128a46e..1e8cc74f0 100644 --- a/src/syntax/parsing.rs +++ b/src/syntax/parsing.rs @@ -81,7 +81,7 @@ pub fn parse(start: Position, src: &str, ctx: ParseContext) -> Parsed Node::ToggleBolder, Token::Underscore => Node::ToggleItalic, Token::Backtick => Node::ToggleMonospace, - Token::Text(text) => Node::Text(text.to_owned()), + Token::Text(text) => Node::Text(text.to_string()), Token::LineComment(_) | Token::BlockComment(_) => continue, diff --git a/src/syntax/scope.rs b/src/syntax/scope.rs index 895ee4982..a6d27c1ec 100644 --- a/src/syntax/scope.rs +++ b/src/syntax/scope.rs @@ -43,7 +43,7 @@ impl Scope { pub fn add_with_meta(&mut self, name: &str, metadata: ::Meta) where F: ParseFunc + Model + 'static { self.parsers.insert( - name.to_owned(), + name.to_string(), parser::(metadata), ); } diff --git a/tests/src/layouter.rs b/tests/src/layouter.rs index 95eea204d..ab95224cf 100644 --- a/tests/src/layouter.rs +++ b/tests/src/layouter.rs @@ -8,12 +8,12 @@ use std::process::Command; use futures_executor::block_on; -use typstc::Typesetter; +use typstc::{Typesetter, DynErrorProvider}; use typstc::layout::{MultiLayout, Serialize}; use typstc::size::{Size, Size2D, ValueBox}; use typstc::style::{PageStyle, PaperClass}; -use typstc::toddle::query::FileSystemFontProvider; -use typstc::export::pdf::PdfExporter; +use typstc::export::pdf; +use typstc::toddle::query::fs::EagerFsProvider; type DynResult = Result>; @@ -66,17 +66,17 @@ fn main() -> DynResult<()> { fn test(name: &str, src: &str) -> DynResult<()> { println!("Testing: {}.", name); - let mut typesetter = Typesetter::new(); + let (fs, entries) = EagerFsProvider::from_index("../fonts", "index.json")?; + let paths = fs.paths(); + let provider = DynErrorProvider::new(fs); + let mut typesetter = Typesetter::new((Box::new(provider), entries)); + typesetter.set_page_style(PageStyle { class: PaperClass::Custom, dimensions: Size2D::with_all(Size::pt(250.0)), margins: ValueBox::with_all(None), }); - let provider = FileSystemFontProvider::from_index("../fonts/index.json")?; - let font_paths = provider.paths(); - typesetter.add_font_provider(provider); - let layouts = compile(&typesetter, src); // Compute the font's paths. @@ -84,10 +84,8 @@ fn test(name: &str, src: &str) -> DynResult<()> { let loader = typesetter.loader().borrow(); for layout in &layouts { for index in layout.find_used_fonts() { - fonts.entry(index).or_insert_with(|| { - let p = loader.get_provider_and_index(index.id).1; - &font_paths[p][index.variant] - }); + fonts.entry(index) + .or_insert_with(|| &paths[index.id][index.variant]); } } drop(loader); @@ -113,8 +111,7 @@ fn test(name: &str, src: &str) -> DynResult<()> { // Write the PDF file. let path = format!("tests/cache/pdf/{}.pdf", name); let file = BufWriter::new(File::create(path)?); - let exporter = PdfExporter::new(); - exporter.export(&layouts, typesetter.loader(), file)?; + pdf::export(&layouts, typesetter.loader(), file)?; Ok(()) }