summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-08-24 17:18:50 +0200
committerLaurenz <laurmaedje@gmail.com>2021-08-24 17:18:50 +0200
commit7a2e3c80b5a6c0497ea062bce2714c0dfc300dd2 (patch)
tree8c1393fb7fac510a499571c3a6cccaf6aa39e039
parent148a06c070e6376e6f86b878d08dfd4f0aef8a73 (diff)
PDF bug fixes
- Write correct subtype for CID Font - Write CIDToGIDMap attribute - Deduplicate CMap pairings - Bump pdf-writer for string primitive fix
-rw-r--r--Cargo.toml2
-rw-r--r--src/export/pdf.rs50
2 files changed, 33 insertions, 19 deletions
diff --git a/Cargo.toml b/Cargo.toml
index f15d22d7..525a3eee 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -24,7 +24,7 @@ fxhash = "0.2.1"
image = { version = "0.23", default-features = false, features = ["png", "jpeg"] }
itertools = "0.10"
miniz_oxide = "0.4"
-pdf-writer = { git = "https://github.com/typst/pdf-writer", rev = "818659b" }
+pdf-writer = "0.3.2"
rand = "0.8"
rustybuzz = "0.4"
serde = { version = "1", features = ["derive", "rc"] }
diff --git a/src/export/pdf.rs b/src/export/pdf.rs
index ee2b026c..0f1480f3 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::HashMap;
+use std::collections::{BTreeSet, HashMap};
use std::hash::Hash;
use std::rc::Rc;
@@ -11,7 +11,7 @@ use pdf_writer::{
ActionType, AnnotationType, CidFontType, ColorSpace, Content, Filter, FontFlags,
Name, PdfWriter, Rect, Ref, Str, SystemInfo, UnicodeCmap,
};
-use ttf_parser::{name_id, GlyphId};
+use ttf_parser::{name_id, GlyphId, Tag};
use crate::color::Color;
use crate::font::{FaceId, FontStore};
@@ -318,6 +318,16 @@ impl<'a> PdfExporter<'a> {
let cap_height = face.cap_height.to_pdf();
let stem_v = 10.0 + 0.244 * (f32::from(ttf.weight().to_number()) - 50.0);
+ // Check for the presence of CFF outlines to select the correct
+ // CID-Font subtype.
+ let subtype = match ttf
+ .table_data(Tag::from_bytes(b"CFF "))
+ .or(ttf.table_data(Tag::from_bytes(b"CFF2")))
+ {
+ Some(_) => CidFontType::Type0,
+ None => CidFontType::Type2,
+ };
+
// Write the base font object referencing the CID font.
self.writer
.type0_font(refs.type0_font)
@@ -328,10 +338,11 @@ impl<'a> PdfExporter<'a> {
// Write the CID font referencing the font descriptor.
self.writer
- .cid_font(refs.cid_font, CidFontType::Type2)
+ .cid_font(refs.cid_font, subtype)
.base_font(base_font)
.system_info(system_info)
.font_descriptor(refs.font_descriptor)
+ .cid_to_gid_map_predefined(Name(b"Identity"))
.widths()
.individual(0, {
let num_glyphs = ttf.number_of_glyphs();
@@ -356,22 +367,25 @@ impl<'a> PdfExporter<'a> {
// Write the to-unicode character map, which maps glyph ids back to
// unicode codepoints to enable copying out of the PDF.
- self.writer
- .cmap(refs.cmap, &{
- let mut cmap = UnicodeCmap::new(cmap_name, system_info);
- 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) {
- cmap.pair(g.0, c);
- }
+ self.writer.cmap(refs.cmap, &{
+ // Deduplicate glyph-to-unicode mappings with a set.
+ let mut mapping = BTreeSet::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));
}
- })
- }
- cmap.finish()
- })
- .name(cmap_name)
- .system_info(system_info);
+ }
+ })
+ }
+
+ let mut cmap = UnicodeCmap::new(cmap_name, system_info);
+ for (g, c) in mapping {
+ cmap.pair(g, c);
+ }
+ cmap.finish()
+ });
// Write the face's bytes.
self.writer.stream(refs.data, face.buffer());