From a522a15a66f737035cead527dc0eca14c3605deb Mon Sep 17 00:00:00 2001 From: Laurenz Date: Sun, 31 Mar 2019 15:47:57 +0200 Subject: [PATCH] =?UTF-8?q?Insert=20default=20glyph=20when=20subsetting=20?= =?UTF-8?q?=E2=9A=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/engine/mod.rs | 2 +- src/export/pdf.rs | 26 ++++++++++++++------------ src/font.rs | 22 ++++++++++++++-------- 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/engine/mod.rs b/src/engine/mod.rs index daec2fbb7..c588e5c32 100644 --- a/src/engine/mod.rs +++ b/src/engine/mod.rs @@ -187,7 +187,7 @@ impl Default for Style { // Default font family, font size and line spacing. font_families: vec![SansSerif, Serif, Monospace], - font_size: 12.0, + font_size: 11.0, line_spacing: 1.25, } } diff --git a/src/export/pdf.rs b/src/export/pdf.rs index 2611f4ef5..b466f225d 100644 --- a/src/export/pdf.rs +++ b/src/export/pdf.rs @@ -164,35 +164,33 @@ impl<'d, W: Write> PdfEngine<'d, W> { let mut id = self.offsets.fonts.0; for font in &self.fonts { + let base_font = format!("ABCDEF+{}", font.name); + // Write the base font object referencing the CID font. self.writer.write_obj(id, Type0Font::new( - font.name.clone(), + base_font.clone(), CMapEncoding::Predefined("Identity-H".to_owned()), id + 1 - ).to_unicode(id + 2) + ).to_unicode(id + 3) )?; - let system_info = CIDSystemInfo::new("(Adobe)", "(Identity)", 0); + let system_info = CIDSystemInfo::new("Adobe", "Identity", 0); // Write the CID font referencing the font descriptor. self.writer.write_obj(id + 1, CIDFont::new( CIDFontType::Type2, - font.name.clone(), + base_font.clone(), system_info.clone(), - id + 3, + id + 2, ).widths(vec![WidthRecord::start(0, font.widths.clone())]) )?; - // The CMap, which maps glyphs to unicode codepoints. - let mapping = font.font.mapping.iter().map(|(&c, &cid)| (cid, c)); - self.writer.write_obj(id + 2, &CMap::new("Custom", system_info, mapping))?; - // Write the font descriptor (contains the global information about the font). - self.writer.write_obj(id + 3, + self.writer.write_obj(id + 2, FontDescriptor::new( - font.name.clone(), + base_font, font.flags, font.italic_angle, ) @@ -204,6 +202,10 @@ impl<'d, W: Write> PdfEngine<'d, W> { .font_file_3(id + 4) )?; + // The CMap, which maps glyphs to unicode codepoints. + let mapping = font.font.mapping.iter().map(|(&c, &cid)| (cid, c)); + 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.program, @@ -249,7 +251,7 @@ impl PdfFont { let subsetted = font.subsetted( chars.iter().cloned(), &["head", "hhea", "maxp", "hmtx", "loca", "glyf"][..], - &["cvt ", "prep", "fpgm"][..], + &["cvt ", "prep", "fpgm", /* "OS/2", "cmap", "name", "post" */][..], )?; // Specify flags for the font diff --git a/src/font.rs b/src/font.rs index 2f9db3bb0..f2aa1c281 100644 --- a/src/font.rs +++ b/src/font.rs @@ -141,7 +141,7 @@ impl Font { cmap: None, hmtx: None, loca: None, - glyphs: Vec::with_capacity(chars.len()), + glyphs: Vec::with_capacity(1 + chars.len()), chars, records: vec![], body: vec![], @@ -445,12 +445,15 @@ impl<'d> Subsetter<'d> { self.write_header()?; + // Build the new widths. let widths = self.glyphs.iter() - .map(|&glyph| self.font.widths.get(glyph as usize).map(|&w| w) - .take_invalid("missing glyph metrics")) - .collect::>>()?; + .map(|&glyph| { + self.font.widths.get(glyph as usize).map(|&w| w) + .take_invalid("missing glyph metrics") + }).collect::>>()?; - let mapping = self.chars.into_iter().enumerate().map(|(i, c)| (c, i as u16)) + // We add one to the index here because we added the default glyph to the front. + let mapping = self.chars.into_iter().enumerate().map(|(i, c)| (c, 1 + i as u16)) .collect::>(); Ok(Font { @@ -467,12 +470,12 @@ impl<'d> Subsetter<'d> { self.read_cmap()?; let cmap = self.cmap.as_ref().unwrap(); + // The default glyph should be always present. + self.glyphs.push(self.font.default_glyph); for &c in &self.chars { self.glyphs.push(cmap.get(c).ok_or_else(|| FontError::MissingCharacter(c))?) } - self.glyphs.push(self.font.default_glyph); - // Composite glyphs may need additional glyphs we have not yet in our list. // So now we have a look at the glyf table to check that and add glyphs // we need additionally. @@ -678,7 +681,10 @@ impl<'d> Subsetter<'d> { while i + 1 < len && this.chars[i+1] as u32 == this.chars[i] as u32 + 1 { i += 1; } - groups.push((this.chars[start], this.chars[i], start)); + + // Add one to the start because we inserted the default glyph in front. + let glyph = 1 + start; + groups.push((this.chars[start], this.chars[i], glyph)); i += 1; }