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
use std::io::Cursor;
use crate::compact1::index::{CharStrings, Dictionaries, Subroutines};
use crate::compact1::{GlyphID, Number, Operation, 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 CharStrings);
fn read<T: Tape>(
tape: &mut T,
(position, dictionary, char_strings): Self::Parameter,
) -> Result<Self> {
let operands = match <[_]>::get(dictionary, 0) {
Some(Operation(Operator::ROS, operands)) if operands.len() == 3 => operands,
_ => raise!("found a malformed character-ID-keyed record"),
};
let offset = get!(@single dictionary, FDSelect);
tape.jump(position + offset as u64)?;
let encoding = tape.take_given(char_strings)?;
let offset = get!(@single dictionary, FDArray);
tape.jump(position + offset as u64)?;
let operations = tape.take::<Dictionaries>()?.into()?;
let mut records = vec![];
for dictionary in operations.iter() {
records.push(tape.take_given((position, dictionary))?);
}
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, dictionary): Self::Parameter) -> Result<Self> {
let (size, offset) = get!(@double dictionary, 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 CharStrings;
fn read<T: Tape>(tape: &mut T, char_strings: Self::Parameter) -> Result<Self> {
Ok(match tape.peek::<u8>()? {
0 => Encoding::Format0(tape.take_given(char_strings)?),
3 => Encoding::Format3(tape.take()?),
_ => raise!("found an unknown format of the glyph-to-dictionary encoding"),
})
}
}
impl<'l> Walue<'l> for Encoding0 {
type Parameter = &'l CharStrings;
fn read<T: Tape>(tape: &mut T, char_strings: Self::Parameter) -> Result<Self> {
let format = tape.take()?;
debug_assert_eq!(format, 0);
Ok(Self {
format: format,
dictionary_ids: tape.take_given(char_strings.count as usize)?,
})
}
}