Skip to content

Commit 1dd5691

Browse files
committed
More efficient name encoding
Totally spec compliant
1 parent 1902e7b commit 1dd5691

2 files changed

Lines changed: 16 additions & 4 deletions

File tree

src/object.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,10 @@ impl Primitive for Name<'_> {
124124
fn write(self, buf: &mut Vec<u8>) {
125125
buf.push(b'/');
126126
for &byte in self.0 {
127-
// Quite a few characters must be escaped in names, so we take the
128-
// safe route and allow only ASCII letters and numbers.
129-
if byte.is_ascii_alphanumeric() {
127+
// - Number sign shall use hexadecimal escape
128+
// - Regular characters within the range exlacamation mark .. tilde
129+
// can be written directly
130+
if byte != b'#' && matches!(byte, b'!'..=b'~') && is_regular_character(byte) {
130131
buf.push(byte);
131132
} else {
132133
buf.push(b'#');
@@ -136,6 +137,15 @@ impl Primitive for Name<'_> {
136137
}
137138
}
138139

140+
/// Regular characters are a PDF concept.
141+
fn is_regular_character(byte: u8) -> bool {
142+
![
143+
b'\0', b'\t', b'\n', b'\x0C', b'\r', b' ', b'(', b')', b'<', b'>', b'[', b']',
144+
b'{', b'}', b'/', b'%',
145+
]
146+
.contains(&byte)
147+
}
148+
139149
/// The null object.
140150
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
141151
pub struct Null;

tests/tests.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,9 @@ fn test_primitive_objects() {
152152
// Test names.
153153
test_primitive!(Name(b"Filter"), b"/Filter");
154154
test_primitive!(Name(b"A B"), br"/A#20B");
155-
test_primitive!(Name(b"~+c"), br"/#7E#2Bc");
155+
test_primitive!(Name(b"~+c"), br"/~+c");
156+
test_primitive!(Name(b"/A-B"), br"/#2FA-B");
157+
test_primitive!(Name(b"<A>"), br"/#3CA#3E");
156158
test_primitive!(Name(b"#"), br"/#23");
157159
test_primitive!(Name(b"\n"), br"/#0A");
158160
}

0 commit comments

Comments
 (0)