1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//! The faces an ingested SVG's `<text>` is set in.
//!
//! An SVG
//! names fonts by *family* — `font-family: Inter, sans-serif` — and a PDF
//! carries font *programs*. Nothing bridges those two without a font
//! database, so the caller supplies one: [`SvgFonts`] is a set of face
//! programs, each registered under the family its own name table declares.
//!
//! # Why the caller supplies them
//!
//! `usvg`'s own defaults would scan the host — `system-fonts` and
//! `memmap-fonts` — and pdfrum does not take a dependency's defaults.
//! More to the point, a document whose appearance depends on which
//! fonts a build machine happens to have installed is not reproducible, and
//! reproducibility is the whole reason `SaveOptions::id_source` exists. A
//! caller who *wants* the host's fonts reads them and registers them, and
//! that is then a decision in their code rather than an accident in ours.
//!
//! # What text becomes
//!
//! **Outlines.** `usvg` lays the text out and flattens each span to filled
//! paths, and the ingestion walk draws those paths like any others — so text
//! goes into the page as vectors with no font embedded and no encoding to get
//! wrong, and it renders identically everywhere. Outlines are the default
//! because embedding would need a font program and an encoding this pass
//! does not carry.
//!
//! An SVG whose `<text>` names a family this set does not carry draws
//! nothing, and that is reported as [`Unsupported::Text`](crate::Unsupported)
//! — a missing face is a reported gap, never a silent one.
use Arc;
/// The font faces an ingested SVG's `<text>` may be set in.
///
/// Each face is registered under the family names its own `name` table
/// declares, which is how an SVG's `font-family` finds it. Empty by default:
/// a session that registers nothing renders no text, and says so in the
/// report.
///
/// Cheap to clone — the registered faces are shared, not copied — so one set
/// built at start-up serves every document.
///
/// ```no_run
/// use pdfrum::{Document, SvgFonts};
///
/// let mut fonts = SvgFonts::new();
/// fonts.register(std::fs::read("Inter.ttf")?);
/// assert_eq!(fonts.families(), ["Inter"]);
///
/// let doc = Document::open("in.pdf")?;
/// let mut edit = doc.edit();
/// edit.set_svg_fonts(fonts);
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```