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
136
137
138
139
140
141
142
143
144
145
146
use std::io::Cursor;
use crate::compact1::index::{CharacterStrings, Dictionaries, Subroutines};
use crate::compact1::{GlyphID, Number, Operations, Operator, StringID};
use crate::{Result, Tape, Walue};
#[derive(Clone, Debug)]
pub struct Record {
pub registry: StringID,
pub ordering: StringID,
pub supplement: Number,
pub encoding: Encoding,
pub operations: Vec<Operations>,
pub records: Vec<RecordInner>,
}
#[derive(Clone, Debug)]
pub struct RecordInner {
pub operations: Operations,
pub subroutines: Subroutines,
}
#[derive(Clone, Debug)]
pub enum Encoding {
Format0(Encoding0),
Format3(Encoding3),
}
#[derive(Clone, Debug)]
pub struct Encoding0 {
pub format: u8, pub dictionary_ids: Vec<u8>, }
table! {
#[doc = "A glyph-to-dictionary encoding in format 3."]
pub Encoding3 {
format (u8 ) = { 3 }, range_count (u16), ranges (Vec<Range3>) |this, tape| { tape.take_given(this.range_count as usize)
},
glyph_count (u16), }
}
table! {
#[doc = "A range of a glyph-to-dictionary encoding in format 3."]
#[derive(Copy)]
pub Range3 {
first_glyph_id (GlyphID), dictionary_id (u8 ), }
}
impl<'l> Walue<'l> for Record {
type Parameter = (u64, &'l Operations, &'l CharacterStrings);
fn read<T: Tape>(
tape: &mut T,
(position, top_operations, character_strings): Self::Parameter,
) -> Result<Self> {
let operands = match top_operations.get(Operator::ROS) {
Some(operands) if operands.len() == 3 => operands,
_ => raise!("found a malformed character-ID-keyed record"),
};
let offset = get!(@single top_operations, FDSelect);
tape.jump(position + offset as u64)?;
let encoding = tape.take_given(character_strings)?;
let offset = get!(@single top_operations, FDArray);
tape.jump(position + offset as u64)?;
let operations: Vec<_> = (&tape.take::<Dictionaries>()?).try_into()?;
let mut records = vec![];
for top_operations in operations.iter() {
records.push(tape.take_given((position, top_operations))?);
}
Ok(Self {
registry: operands[0].try_into()?,
ordering: operands[1].try_into()?,
supplement: operands[2],
encoding: encoding,
operations: operations,
records: records,
})
}
}
impl<'l> Walue<'l> for RecordInner {
type Parameter = (u64, &'l Operations);
fn read<T: Tape>(tape: &mut T, (position, top_operations): Self::Parameter) -> Result<Self> {
let (size, offset) = get!(@double top_operations, Private);
tape.jump(position + offset as u64)?;
let chunk = tape.take_given::<Vec<u8>>(size as usize)?;
let operations = Cursor::new(chunk).take::<Operations>()?;
let subroutines = match get!(@try @single operations, Subrs) {
Some(another_offset) => {
tape.jump(position + offset as u64 + another_offset as u64)?;
tape.take()?
}
_ => Default::default(),
};
Ok(Self {
operations,
subroutines,
})
}
}
impl<'l> Walue<'l> for Encoding {
type Parameter = &'l CharacterStrings;
fn read<T: Tape>(tape: &mut T, character_strings: Self::Parameter) -> Result<Self> {
Ok(match tape.peek::<u8>()? {
0 => Encoding::Format0(tape.take_given(character_strings)?),
3 => Encoding::Format3(tape.take()?),
format => raise!(
"found an unsupported format of the glyph-to-dictionary encoding ({})",
format,
),
})
}
}
impl<'l> Walue<'l> for Encoding0 {
type Parameter = &'l CharacterStrings;
fn read<T: Tape>(tape: &mut T, character_strings: Self::Parameter) -> Result<Self> {
let format = tape.take()?;
debug_assert_eq!(format, 0);
Ok(Self {
format: format,
dictionary_ids: tape.take_given(character_strings.count as usize)?,
})
}
}