postscript/compact1/font_set/
character_id_keyed.rs1use std::io::Cursor;
4
5use crate::compact1::index::{CharacterStrings, Dictionaries, Subroutines};
6use crate::compact1::{GlyphID, Number, Operations, Operator, StringID};
7use crate::Result;
8
9#[derive(Clone, Debug)]
11pub struct Record {
12 pub registry: StringID,
13 pub ordering: StringID,
14 pub supplement: Number,
15 pub encoding: Encoding,
16 pub operations: Vec<Operations>,
17 pub records: Vec<RecordInner>,
18}
19
20#[derive(Clone, Debug)]
22pub struct RecordInner {
23 pub operations: Operations,
24 pub subroutines: Subroutines,
25}
26
27#[derive(Clone, Debug)]
29pub enum Encoding {
30 Format0(Encoding0),
32 Format3(Encoding3),
34}
35
36#[derive(Clone, Debug)]
38pub struct Encoding0 {
39 pub format: u8, pub dictionary_ids: Vec<u8>, }
42
43table! {
44 pub Encoding3 {
46 format (u8 ) = { 3 }, range_count (u16), ranges (Vec<Range3>) |this, tape| { tape.take_given(this.range_count as usize)
51 },
52
53 glyph_count (u16), }
55}
56
57table! {
58 #[derive(Copy)]
60 pub Range3 {
61 first_glyph_id (GlyphID), dictionary_id (u8 ), }
64}
65
66impl<'l> crate::walue::Read<'l> for Record {
67 type Parameter = (u64, &'l Operations, &'l CharacterStrings);
68
69 fn read<T: crate::tape::Read>(
70 tape: &mut T,
71 (position, top_operations, character_strings): Self::Parameter,
72 ) -> Result<Self> {
73 let operands = match top_operations.get(Operator::ROS) {
74 Some(operands) if operands.len() == 3 => operands,
75 _ => raise!("found a malformed character-ID-keyed record"),
76 };
77 let offset = get!(@single top_operations, FDSelect);
78 let encoding = jump_take_given!(@unwrap tape, position, offset, character_strings);
79 let offset = get!(@single top_operations, FDArray);
80 let operations: Dictionaries = jump_take!(@unwrap tape, position, offset);
81 let operations: Vec<_> = (&operations).try_into()?;
82 let mut records = vec![];
83 for top_operations in operations.iter() {
84 records.push(tape.take_given((position, top_operations))?);
85 }
86 Ok(Self {
87 registry: operands[0].try_into()?,
88 ordering: operands[1].try_into()?,
89 supplement: operands[2],
90 encoding,
91 operations,
92 records,
93 })
94 }
95}
96
97impl<'l> crate::walue::Read<'l> for RecordInner {
98 type Parameter = (u64, &'l Operations);
99
100 fn read<T: crate::tape::Read>(
101 tape: &mut T,
102 (position, top_operations): Self::Parameter,
103 ) -> Result<Self> {
104 use crate::tape::Read;
105
106 let (size, offset) = get!(@double top_operations, Private);
107 let chunk: Vec<u8> = jump_take_given!(@unwrap tape, position, offset, size as usize);
108 let operations = Cursor::new(chunk).take::<Operations>()?;
109 let subroutines = match get!(@try @single operations, Subrs) {
110 Some(another_offset) => jump_take!(@unwrap tape, position, offset + another_offset),
111 _ => Default::default(),
112 };
113 Ok(Self {
114 operations,
115 subroutines,
116 })
117 }
118}
119
120impl<'l> crate::walue::Read<'l> for Encoding {
121 type Parameter = &'l CharacterStrings;
122
123 fn read<T: crate::tape::Read>(
124 tape: &mut T,
125 character_strings: Self::Parameter,
126 ) -> Result<Self> {
127 Ok(match tape.peek::<u8>()? {
128 0 => Encoding::Format0(tape.take_given(character_strings)?),
129 3 => Encoding::Format3(tape.take()?),
130 format => {
131 raise!("found an unknown format of the glyph-to-dictionary encoding ({format})")
132 }
133 })
134 }
135}
136
137impl<'l> crate::walue::Read<'l> for Encoding0 {
138 type Parameter = &'l CharacterStrings;
139
140 fn read<T: crate::tape::Read>(
141 tape: &mut T,
142 character_strings: Self::Parameter,
143 ) -> Result<Self> {
144 let format = tape.take()?;
145 debug_assert_eq!(format, 0);
146 Ok(Self {
147 format,
148 dictionary_ids: tape.take_given(character_strings.count as usize)?,
149 })
150 }
151}