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
use crate::number::q32;
use crate::{Result, Tape, Value};
#[derive(Clone, Debug)]
pub enum PostScript {
Version1(PostScript1),
Version2(PostScript2),
Version3(PostScript3),
}
table! {
#[doc = "PostScript information of version 1."]
#[derive(Copy)]
pub PostScript1 {
version (q32), italic_angle (q32), underline_position (i16), underline_thickness (i16), is_fixed_pitch (u32), min_memory_type42 (u32), max_memory_type42 (u32), min_memory_type1 (u32), max_memory_type1 (u32), }
}
table! {
#[doc = "PostScript information of version 2."]
pub PostScript2 {
version (q32), italic_angle (q32), underline_position (i16), underline_thickness (i16), is_fixed_pitch (u32), min_memory_type42 (u32), max_memory_type42 (u32), min_memory_type1 (u32), max_memory_type1 (u32), glyph_count (u16), glyph_name_indices (Vec<u16>) |this, tape| { tape.take_given(this.glyph_count as usize)
},
glyph_names (Vec<String>) |this, tape| { read_pascal_strings(tape, &this.glyph_name_indices)
},
}
}
pub type PostScript3 = PostScript1;
impl Value for PostScript {
fn read<T: Tape>(tape: &mut T) -> Result<Self> {
Ok(match tape.peek::<q32>()? {
q32(0x00010000) => PostScript::Version1(tape.take()?),
q32(0x00020000) => PostScript::Version2(tape.take()?),
q32(0x00030000) => PostScript::Version3(tape.take()?),
_ => raise!("found an unknown format of the PostScript information"),
})
}
}
fn read_pascal_strings<T: Tape>(tape: &mut T, indices: &[u16]) -> Result<Vec<String>> {
let count = indices
.iter()
.fold(0, |n, &i| if 258 <= i && i <= 32767 { n + 1 } else { n });
let mut names = Vec::with_capacity(count);
for _ in 0..count {
let length = tape.take::<u8>()? as usize;
match String::from_utf8(tape.take_bytes(length)?) {
Ok(name) => names.push(name),
_ => names.push("<malformed>".into()),
}
}
Ok(names)
}