summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2019-02-27 18:42:33 +0100
committerLaurenz Mädje <laurmaedje@gmail.com>2019-02-27 18:45:55 +0100
commitda602613769cc73aad3fbaf8aa3c83d5d0fb85dc (patch)
tree0b4b030fecc244f59c334d4130e2b527c434c726 /src
parent6b8da16be817378920cf3ee0fc1a1e40e5afc076 (diff)
Enhance PDF crate API 🚀
Diffstat (limited to 'src')
-rw-r--r--src/pdf.rs137
1 files changed, 55 insertions, 82 deletions
diff --git a/src/pdf.rs b/src/pdf.rs
index d18d6fc4..7cc8e6da 100644
--- a/src/pdf.rs
+++ b/src/pdf.rs
@@ -4,10 +4,12 @@ use std::fmt;
use std::io::{self, Write, Cursor};
use crate::doc::Document;
use pdf::{PdfWriter, Id, Rect, Version, Trailer};
-use pdf::doc::{DocumentCatalog, PageTree, Page, PageData, Resource, Content};
+use pdf::doc::{Catalog, PageTree, Page, Resource, Content};
use pdf::text::Text;
-use pdf::font::{Type0Font, CMapEncoding, CIDFont, CIDFontType, CIDSystemInfo,
- WidthRecord, FontDescriptor, EmbeddedFont, GlyphUnit};
+use pdf::font::{
+ Type0Font, CMapEncoding, CIDFont, CIDFontType, CIDSystemInfo,
+ WidthRecord, FontDescriptor, FontFlags, EmbeddedFont, GlyphUnit
+};
use opentype::{OpenTypeReader, tables};
@@ -52,18 +54,6 @@ impl fmt::Display for PdfWritingError {
}
-/// Shortcut macro to create bitflags from bools.
-macro_rules! flags {
- ($($bit:expr => $value:expr),*) => {{
- let mut flags = 0;
- $(
- flags |= if $value { 1 << ($bit - 1) } else { 0 };
- )*
- flags
- }};
- ($($bit:expr => $value:expr,)*) => (flags!($($bit => $value),*));
-}
-
/// Keeps track of the document while letting the pdf writer
/// generate the _PDF_.
struct PdfCreator<'a, W: Write> {
@@ -140,9 +130,7 @@ impl<'a, W: Write> PdfCreator<'a, W> {
self.writer.write_xref_table()?;
// Trailer
- self.writer.write_trailer(&Trailer {
- root: self.offsets.catalog,
- })?;
+ self.writer.write_trailer(&Trailer::new(self.offsets.catalog))?;
Ok(self.writer.written())
}
@@ -150,19 +138,13 @@ impl<'a, W: Write> PdfCreator<'a, W> {
/// Write the document catalog, page tree and pages.
fn write_pages(&mut self) -> PdfResult<()> {
// The document catalog
- self.writer.write_obj(self.offsets.catalog, &DocumentCatalog {
- page_tree: self.offsets.page_tree,
- })?;
+ self.writer.write_obj(self.offsets.catalog, &Catalog::new(self.offsets.page_tree))?;
// Root page tree
- self.writer.write_obj(self.offsets.page_tree, &PageTree {
- parent: None,
- kids: (self.offsets.pages.0 ..= self.offsets.pages.1).collect(),
- data: PageData {
- resources: Some(vec![Resource::Font { nr: 1, id: self.offsets.fonts.0 }]),
- .. PageData::none()
- },
- })?;
+ self.writer.write_obj(self.offsets.page_tree, PageTree::new()
+ .kids(self.offsets.pages.0 ..= self.offsets.pages.1)
+ .resource(Resource::Font { nr: 1, id: self.offsets.fonts.0 })
+ )?;
// The page objects
let mut id = self.offsets.pages.0;
@@ -170,15 +152,10 @@ impl<'a, W: Write> PdfCreator<'a, W> {
let width = page.size[0].to_points();
let height = page.size[1].to_points();
- let contents = (self.offsets.contents.0 ..= self.offsets.contents.1).collect();
- self.writer.write_obj(id, &Page {
- parent: self.offsets.page_tree,
- data: PageData {
- media_box: Some(Rect::new(0.0, 0.0, width, height)),
- contents: Some(contents),
- .. PageData::none()
- },
- })?;
+ self.writer.write_obj(id, Page::new(self.offsets.page_tree)
+ .media_box(Rect::new(0.0, 0.0, width, height))
+ .contents(self.offsets.contents.0 ..= self.offsets.contents.1)
+ )?;
id += 1;
}
@@ -216,54 +193,50 @@ impl<'a, W: Write> PdfCreator<'a, W> {
let base_font = font_data.name.post_script_name.as_ref()
.unwrap_or(&self.doc.font);
- self.writer.write_obj(id, &Type0Font {
- base_font: base_font.clone(),
- encoding: CMapEncoding::Predefined("Identity-H".to_owned()),
- descendant_font: id + 1,
- to_unicode: None,
- }).unwrap();
-
- self.writer.write_obj(id + 1, &CIDFont {
- subtype: CIDFontType::Type2,
- base_font: base_font.clone(),
- cid_system_info: CIDSystemInfo {
- registry: "(Adobe)".to_owned(),
- ordering: "(Identity)".to_owned(),
- supplement: 0,
- },
- font_descriptor: id + 2,
- widths: Some(vec![WidthRecord::Start(0,
- font_data.hmtx.metrics.iter()
- .map(|m| convert(m.advance_width))
- .collect::<Vec<_>>()
- )]),
- cid_to_gid_map: Some(CMapEncoding::Predefined("Identity".to_owned())),
- }).unwrap();
-
- self.writer.write_obj(id + 2, &FontDescriptor {
- font_name: base_font.clone(),
- flags: flags!(
- 1 => font_data.post.is_fixed_pitch,
- 2 => base_font.contains("Serif"),
- 3 => true, 4 => false, 6 => false,
- 7 => (font_data.head.mac_style & 1) != 0,
- 17 => false, 18 => true, 19 => false,
- ),
- found_bbox: Rect::new(
+ self.writer.write_obj(id, &Type0Font::new(
+ base_font.clone(),
+ CMapEncoding::Predefined("Identity-H".to_owned()),
+ id + 1
+ )).unwrap();
+
+ self.writer.write_obj(id + 1,
+ CIDFont::new(
+ CIDFontType::Type2,
+ base_font.clone(),
+ CIDSystemInfo::new("(Adobe)", "(Identity)", 0),
+ id + 2,
+ ).widths(vec![
+ WidthRecord::start(0, font_data.hmtx.metrics.iter().map(|m| convert(m.advance_width))
+ )])
+ ).unwrap();
+
+ let mut flags = FontFlags::empty();
+ flags.set(FontFlags::FIXED_PITCH, font_data.post.is_fixed_pitch);
+ flags.set(FontFlags::SERIF, base_font.contains("Serif"));
+ flags.insert(FontFlags::SYMBOLIC);
+ flags.set(FontFlags::ITALIC, (font_data.head.mac_style & 1) != 0);
+ flags.insert(FontFlags::SMALL_CAP);
+
+ self.writer.write_obj(id + 2,
+ FontDescriptor::new(
+ base_font.clone(),
+ flags,
+ font_data.post.italic_angle.to_f32(),
+ )
+ .font_bbox(Rect::new(
convert(font_data.head.x_min),
convert(font_data.head.y_min),
convert(font_data.head.x_max),
convert(font_data.head.y_max)
- ),
- italic_angle: font_data.post.italic_angle.to_f32(),
- ascent: convert(font_data.os2.s_typo_ascender),
- descent: convert(font_data.os2.s_typo_descender),
- cap_height: convert(font_data.os2.s_cap_height
- .unwrap_or(font_data.os2.s_typo_ascender)),
- stem_v: (10.0 + 220.0 *
- (font_data.os2.us_weight_class as f32 - 50.0) / 900.0) as GlyphUnit,
- font_file_3: Some(id + 3),
- }).unwrap();
+ ))
+ .ascent(convert(font_data.os2.s_typo_ascender))
+ .descent(convert(font_data.os2.s_typo_descender))
+ .cap_height(convert(font_data.os2.s_cap_height
+ .unwrap_or(font_data.os2.s_typo_ascender)))
+ .stem_v((10.0 + 220.0 * (font_data.os2.us_weight_class as f32
+ - 50.0) / 900.0) as GlyphUnit)
+ .font_file_3(id + 3)
+ ).unwrap();
self.writer.write_obj(id + 3, &EmbeddedFont::OpenType(&font_data.data)).unwrap();