diff options
| author | Laurenz <laurmaedje@gmail.com> | 2019-10-13 13:10:21 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2019-10-13 13:10:21 +0200 |
| commit | 7c0899b5373cdc4f1083a0a8515856207c431423 (patch) | |
| tree | ee1ecade4022f1fa3f666feb55097f7bdcae69ed /src/export/pdf.rs | |
| parent | 5c04185892947969005ffcf6412d7190dafb3a79 (diff) | |
Run rustfmt 🚿
Diffstat (limited to 'src/export/pdf.rs')
| -rw-r--r-- | src/export/pdf.rs | 149 |
1 files changed, 97 insertions, 52 deletions
diff --git a/src/export/pdf.rs b/src/export/pdf.rs index 78e48e81..b7ad21c7 100644 --- a/src/export/pdf.rs +++ b/src/export/pdf.rs @@ -3,21 +3,22 @@ use std::collections::{HashMap, HashSet}; use std::io::{self, Write}; -use tide::{PdfWriter, Ref, Rect, Version, Trailer}; use tide::content::Content; -use tide::doc::{Catalog, PageTree, Page, Resource, Text}; -use tide::font::{Type0Font, CIDFont, CIDFontType, CIDSystemInfo, FontDescriptor, FontFlags}; -use tide::font::{GlyphUnit, CMap, CMapEncoding, WidthRecord, FontStream}; +use tide::doc::{Catalog, Page, PageTree, Resource, Text}; +use tide::font::{CIDFont, CIDFontType, CIDSystemInfo, FontDescriptor, FontFlags, Type0Font}; +use tide::font::{CMap, CMapEncoding, FontStream, GlyphUnit, WidthRecord}; +use tide::{PdfWriter, Rect, Ref, Trailer, Version}; -use toddle::tables::{Header, Post, OS2, HorizontalMetrics, CharMap, Name, NameEntry, MacStyleFlags}; use toddle::font::OwnedFont; use toddle::query::SharedFontLoader; +use toddle::tables::{ + CharMap, Header, HorizontalMetrics, MacStyleFlags, Name, NameEntry, Post, OS2, +}; use toddle::Error as FontError; -use crate::layout::{MultiLayout, Layout, LayoutAction}; +use crate::layout::{Layout, LayoutAction, MultiLayout}; use crate::size::{Size, Size2D}; - /// Exports layouts into _PDFs_. #[derive(Debug)] pub struct PdfExporter {} @@ -29,10 +30,16 @@ impl PdfExporter { PdfExporter {} } - /// Export a finished layouts into a writer. Returns how many bytes were written. + /// Export a finished layouts into a writer. Returns how many bytes were + /// written. #[inline] - pub fn export<W: Write>(&self, layout: &MultiLayout, loader: &SharedFontLoader, target: W) - -> PdfResult<usize> { + pub fn export<W: Write>( + &self, + layout: &MultiLayout, + loader: &SharedFontLoader, + target: W, + ) -> PdfResult<usize> + { let mut engine = PdfEngine::new(layout, loader, target)?; engine.write() } @@ -59,8 +66,12 @@ struct Offsets { impl<'d, W: Write> PdfEngine<'d, W> { /// Create a new _PDF_ engine. - fn new(layout: &'d MultiLayout, loader: &SharedFontLoader, target: W) - -> PdfResult<PdfEngine<'d, W>> { + fn new( + layout: &'d MultiLayout, + loader: &SharedFontLoader, + target: W, + ) -> PdfResult<PdfEngine<'d, W>> + { // Create a subsetted PDF font for each font in the layout. let mut font_remap = HashMap::new(); let fonts = { @@ -71,24 +82,26 @@ impl<'d, W: Write> PdfEngine<'d, W> { for boxed in &layout.layouts { for action in &boxed.actions { match action { - LayoutAction::WriteText(string) => { - chars.entry(font) - .or_insert_with(HashSet::new) - .extend(string.chars()) - }, + LayoutAction::WriteText(string) => chars + .entry(font) + .or_insert_with(HashSet::new) + .extend(string.chars()), LayoutAction::SetFont(id, _) => { font = *id; let new_id = font_remap.len(); font_remap.entry(font).or_insert(new_id); - }, - _ => {}, + } + _ => {} } } } // Collect the fonts into a vector in the order of the values in the remapping. let mut loader = loader.borrow_mut(); - let mut order = font_remap.iter().map(|(&old, &new)| (old, new)).collect::<Vec<_>>(); + let mut order = font_remap + .iter() + .map(|(&old, &new)| (old, new)) + .collect::<Vec<_>>(); order.sort_by_key(|&(_, new)| new); let mut fonts = vec![]; @@ -96,8 +109,10 @@ impl<'d, W: Write> PdfEngine<'d, W> { let font = loader.get_with_index(index); let subsetted = font.subsetted( chars[&index].iter().cloned(), - &["name", "OS/2", "post", "head", "hhea", "hmtx", "maxp", - "cmap", "cvt ", "fpgm", "prep", "loca", "glyf"][..] + &[ + "name", "OS/2", "post", "head", "hhea", "hmtx", "maxp", "cmap", "cvt ", + "fpgm", "prep", "loca", "glyf", + ][..], )?; fonts.push(OwnedFont::from_bytes(subsetted)?); } @@ -111,7 +126,13 @@ impl<'d, W: Write> PdfEngine<'d, W> { let pages = (page_tree + 1, page_tree + layout.layouts.len() as Ref); let contents = (pages.1 + 1, pages.1 + layout.layouts.len() as Ref); let font_offsets = (contents.1 + 1, contents.1 + 5 * fonts.len() as Ref); - let offsets = Offsets { catalog, page_tree, pages, contents, fonts: font_offsets }; + let offsets = Offsets { + catalog, + page_tree, + pages, + contents, + fonts: font_offsets, + }; Ok(PdfEngine { writer: PdfWriter::new(target), @@ -129,32 +150,43 @@ impl<'d, W: Write> PdfEngine<'d, W> { self.write_pages()?; self.write_fonts()?; self.writer.write_xref_table()?; - self.writer.write_trailer(Trailer::new(self.offsets.catalog))?; + self.writer + .write_trailer(Trailer::new(self.offsets.catalog))?; Ok(self.writer.written()) } /// Write the document catalog and page tree. fn write_page_tree(&mut self) -> PdfResult<()> { // The document catalog - self.writer.write_obj(self.offsets.catalog, &Catalog::new(self.offsets.page_tree))?; + self.writer + .write_obj(self.offsets.catalog, &Catalog::new(self.offsets.page_tree))?; // The font resources let offset = self.offsets.fonts.0; - let fonts = (0 .. self.fonts.len()) - .map(|i| Resource::Font((i + 1) as u32, offset + 5 * i as u32)); + let fonts = + (0..self.fonts.len()).map(|i| Resource::Font((i + 1) as u32, offset + 5 * i as u32)); // The root page tree - self.writer.write_obj(self.offsets.page_tree, PageTree::new() - .kids(ids(self.offsets.pages)) - .resources(fonts) + self.writer.write_obj( + self.offsets.page_tree, + PageTree::new() + .kids(ids(self.offsets.pages)) + .resources(fonts), )?; // The page objects for (id, page) in ids(self.offsets.pages).zip(&self.layout.layouts) { - let rect = Rect::new(0.0, 0.0, page.dimensions.x.to_pt(), page.dimensions.y.to_pt()); - self.writer.write_obj(id, Page::new(self.offsets.page_tree) - .media_box(rect) - .contents(ids(self.offsets.contents)) + let rect = Rect::new( + 0.0, + 0.0, + page.dimensions.x.to_pt(), + page.dimensions.y.to_pt(), + ); + self.writer.write_obj( + id, + Page::new(self.offsets.page_tree) + .media_box(rect) + .contents(ids(self.offsets.contents)), )?; } @@ -202,8 +234,8 @@ impl<'d, W: Write> PdfEngine<'d, W> { // Write the text. text.tj(self.fonts[active_font.0].encode_text(&string)?); - }, - LayoutAction::DebugBox(_, _) => {}, + } + LayoutAction::DebugBox(_, _) => {} } } @@ -217,18 +249,21 @@ impl<'d, W: Write> PdfEngine<'d, W> { let mut id = self.offsets.fonts.0; for font in &mut self.fonts { - let name = font.read_table::<Name>()? + let name = font + .read_table::<Name>()? .get_decoded(NameEntry::PostScriptName) .unwrap_or_else(|| "unknown".to_string()); let base_font = format!("ABCDEF+{}", name); // Write the base font object referencing the CID font. - self.writer.write_obj(id, + self.writer.write_obj( + id, Type0Font::new( base_font.clone(), CMapEncoding::Predefined("Identity-H".to_owned()), - id + 1 - ).to_unicode(id + 3) + id + 1, + ) + .to_unicode(id + 3), )?; // Extract information from the head table. @@ -252,19 +287,22 @@ impl<'d, W: Write> PdfEngine<'d, W> { // Transform the width into PDF units. let widths: Vec<_> = font .read_table::<HorizontalMetrics>()? - .metrics.iter() + .metrics + .iter() .map(|m| font_unit_to_glyph_unit(m.advance_width as f32)) .collect(); // Write the CID font referencing the font descriptor. let system_info = CIDSystemInfo::new("Adobe", "Identity", 0); - self.writer.write_obj(id + 1, + self.writer.write_obj( + id + 1, CIDFont::new( CIDFontType::Type2, base_font.clone(), system_info.clone(), id + 2, - ).widths(vec![WidthRecord::start(0, widths)]) + ) + .widths(vec![WidthRecord::start(0, widths)]), )?; // Extract information from the post table. @@ -284,24 +322,31 @@ impl<'d, W: Write> PdfEngine<'d, W> { let os2 = font.read_table::<OS2>()?; // Write the font descriptor (contains the global information about the font). - self.writer.write_obj(id + 2, + self.writer.write_obj( + id + 2, FontDescriptor::new(base_font, flags, italic_angle) .font_bbox(bounding_box) .ascent(font_unit_to_glyph_unit(os2.s_typo_ascender as f32)) .descent(font_unit_to_glyph_unit(os2.s_typo_descender as f32)) - .cap_height(font_unit_to_glyph_unit(os2.s_cap_height.unwrap_or(os2.s_typo_ascender) as f32)) + .cap_height(font_unit_to_glyph_unit( + os2.s_cap_height.unwrap_or(os2.s_typo_ascender) as f32, + )) .stem_v((10.0 + 0.244 * (os2.us_weight_class as f32 - 50.0)) as GlyphUnit) - .font_file_2(id + 4) + .font_file_2(id + 4), )?; // Write the CMap, which maps glyphs to unicode codepoints. - let mapping = font.read_table::<CharMap>()? - .mapping.iter() + let mapping = font + .read_table::<CharMap>()? + .mapping + .iter() .map(|(&c, &cid)| (cid, c)); - self.writer.write_obj(id + 3, &CMap::new("Custom", system_info, mapping))?; + self.writer + .write_obj(id + 3, &CMap::new("Custom", system_info, mapping))?; // Finally write the subsetted font program. - self.writer.write_obj(id + 4, &FontStream::new(font.data().get_ref()))?; + self.writer + .write_obj(id + 4, &FontStream::new(font.data().get_ref()))?; id += 5; } @@ -311,8 +356,8 @@ impl<'d, W: Write> PdfEngine<'d, W> { } /// Create an iterator from a reference pair. -fn ids((start, end): (Ref, Ref)) -> impl Iterator<Item=Ref> { - start ..= end +fn ids((start, end): (Ref, Ref)) -> impl Iterator<Item = Ref> { + start..=end } /// The error type for _PDF_ creation. |
