diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-08-25 01:45:17 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-08-25 12:12:47 +0200 |
| commit | 821536b253bed0753eb031d4cc7fbd407dce9f39 (patch) | |
| tree | e287c97718add518253f6f3de964fdf0fbbd81af /src/export/pdf.rs | |
| parent | 6f84cf3c225c80a131fc6b0ab46749331306bc9d (diff) | |
Subset glyf and loca tables
Diffstat (limited to 'src/export/pdf.rs')
| -rw-r--r-- | src/export/pdf.rs | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/src/export/pdf.rs b/src/export/pdf.rs index 433dc844..9b9d0e8e 100644 --- a/src/export/pdf.rs +++ b/src/export/pdf.rs @@ -1,7 +1,7 @@ //! Exporting into PDF documents. use std::cmp::Eq; -use std::collections::{BTreeSet, HashMap}; +use std::collections::{BTreeMap, HashMap, HashSet}; use std::hash::Hash; use std::rc::Rc; @@ -38,12 +38,14 @@ struct PdfExporter<'a> { frames: &'a [Rc<Frame>], fonts: &'a FontStore, images: &'a ImageStore, + glyphs: HashMap<FaceId, HashSet<u16>>, font_map: Remapper<FaceId>, image_map: Remapper<ImageId>, } impl<'a> PdfExporter<'a> { fn new(ctx: &'a Context, frames: &'a [Rc<Frame>]) -> Self { + let mut glyphs = HashMap::<FaceId, HashSet<u16>>::new(); let mut font_map = Remapper::new(); let mut image_map = Remapper::new(); let mut alpha_masks = 0; @@ -51,7 +53,11 @@ impl<'a> PdfExporter<'a> { for frame in frames { for (_, element) in frame.elements() { match *element { - Element::Text(ref text) => font_map.insert(text.face_id), + Element::Text(ref text) => { + font_map.insert(text.face_id); + let set = glyphs.entry(text.face_id).or_default(); + set.extend(text.glyphs.iter().map(|g| g.id)); + } Element::Geometry(_, _) => {} Element::Image(id, _) => { let img = ctx.images.get(id); @@ -74,6 +80,7 @@ impl<'a> PdfExporter<'a> { frames, fonts: &ctx.fonts, images: &ctx.images, + glyphs, font_map, image_map, } @@ -278,6 +285,7 @@ impl<'a> PdfExporter<'a> { fn write_fonts(&mut self) { for (refs, face_id) in self.refs.fonts().zip(self.font_map.layout_indices()) { + let glyphs = &self.glyphs[&face_id]; let face = self.fonts.get(face_id); let ttf = face.ttf(); @@ -370,15 +378,19 @@ impl<'a> PdfExporter<'a> { // unicode codepoints to enable copying out of the PDF. self.writer.cmap(refs.cmap, &{ // Deduplicate glyph-to-unicode mappings with a set. - let mut mapping = BTreeSet::new(); + let mut mapping = BTreeMap::new(); for subtable in ttf.character_mapping_subtables() { - subtable.codepoints(|n| { - if let Some(c) = std::char::from_u32(n) { - if let Some(g) = ttf.glyph_index(c) { - mapping.insert((g.0, c)); + if subtable.is_unicode() { + subtable.codepoints(|n| { + if let Some(c) = std::char::from_u32(n) { + if let Some(GlyphId(g)) = ttf.glyph_index(c) { + if glyphs.contains(&g) { + mapping.insert(g, c); + } + } } - } - }) + }); + } } let mut cmap = UnicodeCmap::new(cmap_name, system_info); @@ -388,9 +400,9 @@ impl<'a> PdfExporter<'a> { cmap.finish() }); - // Susbet and write the face's bytes. + // Subset and write the face's bytes. let original = face.buffer(); - let subsetted = subset(original, face.index()); + let subsetted = subset(original, face.index(), glyphs.iter().copied()); let data = subsetted.as_deref().unwrap_or(original); self.writer.stream(refs.data, data); } |
