1use crate::compact1::{GlyphID, StringID};
4use crate::Result;
5
6#[derive(Clone, Debug)]
8pub enum CharacterSet {
9 ISOAdobe,
10 Expert,
11 ExpertSubset,
12 Format0(CharacterSet0),
13 Format1(CharacterSet1),
14 Format2(CharacterSet2),
15}
16
17#[derive(Clone, Debug)]
19pub struct CharacterSet0 {
20 pub format: u8, pub glyphs: Vec<StringID>, }
23
24#[derive(Clone, Debug)]
26pub struct CharacterSet1 {
27 pub format: u8, pub ranges: Vec<Range1>, }
30
31#[derive(Clone, Debug)]
33pub struct CharacterSet2 {
34 pub format: u8, pub ranges: Vec<Range2>, }
37
38table! {
39 #[derive(Copy)]
41 pub Range1 {
42 first_string_id (StringID), left_count (u8 ), }
45}
46
47table! {
48 #[derive(Copy)]
50 pub Range2 {
51 first_string_id (StringID), left_count (u16 ), }
54}
55
56impl CharacterSet {
57 #[inline]
59 pub fn get(&self, glyph_id: GlyphID) -> Option<&'static str> {
60 match self {
61 CharacterSet::ISOAdobe => get_iso_adobe(glyph_id),
62 CharacterSet::Expert => get_expert(glyph_id),
63 CharacterSet::ExpertSubset => get_expert_subset(glyph_id),
64 CharacterSet::Format0(ref char_set) => char_set.get(glyph_id),
65 CharacterSet::Format1(ref char_set) => char_set.get(glyph_id),
66 CharacterSet::Format2(ref char_set) => char_set.get(glyph_id),
67 }
68 }
69}
70
71impl crate::walue::Read<'static> for CharacterSet {
72 type Parameter = usize;
73
74 fn read<T: crate::tape::Read>(tape: &mut T, glyph_count: usize) -> Result<Self> {
75 Ok(match tape.peek::<u8>()? {
76 0 => CharacterSet::Format0(tape.take_given(glyph_count)?),
77 1 => CharacterSet::Format1(tape.take_given(glyph_count)?),
78 2 => CharacterSet::Format2(tape.take_given(glyph_count)?),
79 format => raise!("found an unknown format of character sets ({format})"),
80 })
81 }
82}
83
84impl CharacterSet0 {
85 #[inline]
86 fn get(&self, _: GlyphID) -> Option<&'static str> {
87 None
88 }
89}
90
91impl crate::walue::Read<'static> for CharacterSet0 {
92 type Parameter = usize;
93
94 fn read<T: crate::tape::Read>(tape: &mut T, glyph_count: usize) -> Result<Self> {
95 let format = tape.take::<u8>()?;
96 if format != 0 {
97 raise!("found a malformed character set");
98 }
99 Ok(CharacterSet0 {
100 format,
101 glyphs: tape.take_given(glyph_count - 1)?,
102 })
103 }
104}
105
106impl CharacterSet1 {
107 #[inline]
108 fn get(&self, _: GlyphID) -> Option<&'static str> {
109 None
110 }
111}
112
113impl crate::walue::Read<'static> for CharacterSet1 {
114 type Parameter = usize;
115
116 fn read<T: crate::tape::Read>(tape: &mut T, glyph_count: usize) -> Result<Self> {
117 let format = tape.take::<u8>()?;
118 if format != 1 {
119 raise!("found a malformed character set");
120 }
121 let mut ranges = vec![];
122 #[allow(clippy::identity_op)]
123 let mut found_count = 0 + 1;
124 while found_count < glyph_count {
125 let range = tape.take::<Range1>()?;
126 found_count += 1 + range.left_count as usize;
127 ranges.push(range);
128 }
129 if found_count != glyph_count {
130 raise!("found a malformed character set");
131 }
132 Ok(CharacterSet1 { format, ranges })
133 }
134}
135
136impl CharacterSet2 {
137 #[inline]
138 fn get(&self, _: GlyphID) -> Option<&'static str> {
139 None
140 }
141}
142
143impl crate::walue::Read<'static> for CharacterSet2 {
144 type Parameter = usize;
145
146 fn read<T: crate::tape::Read>(tape: &mut T, glyph_count: usize) -> Result<Self> {
147 macro_rules! reject(() => (raise!("found a malformed character set")));
148 let format = tape.take::<u8>()?;
149 if format != 2 {
150 reject!();
151 }
152 let mut ranges = vec![];
153 #[allow(clippy::identity_op)]
154 let mut found_count = 0 + 1;
155 while found_count < glyph_count {
156 let range = tape.take::<Range2>()?;
157 found_count += 1 + range.left_count as usize;
158 ranges.push(range);
159 }
160 if found_count != glyph_count {
161 reject!();
162 }
163 Ok(CharacterSet2 { format, ranges })
164 }
165}
166
167fn get_iso_adobe(glyph_id: GlyphID) -> Option<&'static str> {
168 Some(match glyph_id {
169 1 => "space",
170 2 => "exclam",
171 3 => "quotedbl",
172 4 => "numbersign",
173 5 => "dollar",
174 6 => "percent",
175 7 => "ampersand",
176 8 => "quoteright",
177 9 => "parenleft",
178 10 => "parenright",
179 11 => "asterisk",
180 12 => "plus",
181 13 => "comma",
182 14 => "hyphen",
183 15 => "period",
184 16 => "slash",
185 17 => "zero",
186 18 => "one",
187 19 => "two",
188 20 => "three",
189 21 => "four",
190 22 => "five",
191 23 => "six",
192 24 => "seven",
193 25 => "eight",
194 26 => "nine",
195 27 => "colon",
196 28 => "semicolon",
197 29 => "less",
198 30 => "equal",
199 31 => "greater",
200 32 => "question",
201 33 => "at",
202 34 => "A",
203 35 => "B",
204 36 => "C",
205 37 => "D",
206 38 => "E",
207 39 => "F",
208 40 => "G",
209 41 => "H",
210 42 => "I",
211 43 => "J",
212 44 => "K",
213 45 => "L",
214 46 => "M",
215 47 => "N",
216 48 => "O",
217 49 => "P",
218 50 => "Q",
219 51 => "R",
220 52 => "S",
221 53 => "T",
222 54 => "U",
223 55 => "V",
224 56 => "W",
225 57 => "X",
226 58 => "Y",
227 59 => "Z",
228 60 => "bracketleft",
229 61 => "backslash",
230 62 => "bracketright",
231 63 => "asciicircum",
232 64 => "underscore",
233 65 => "quoteleft",
234 66 => "a",
235 67 => "b",
236 68 => "c",
237 69 => "d",
238 70 => "e",
239 71 => "f",
240 72 => "g",
241 73 => "h",
242 74 => "i",
243 75 => "j",
244 76 => "k",
245 77 => "l",
246 78 => "m",
247 79 => "n",
248 80 => "o",
249 81 => "p",
250 82 => "q",
251 83 => "r",
252 84 => "s",
253 85 => "t",
254 86 => "u",
255 87 => "v",
256 88 => "w",
257 89 => "x",
258 90 => "y",
259 91 => "z",
260 92 => "braceleft",
261 93 => "bar",
262 94 => "braceright",
263 95 => "asciitilde",
264 96 => "exclamdown",
265 97 => "cent",
266 98 => "sterling",
267 99 => "fraction",
268 100 => "yen",
269 101 => "florin",
270 102 => "section",
271 103 => "currency",
272 104 => "quotesingle",
273 105 => "quotedblleft",
274 106 => "guillemotleft",
275 107 => "guilsinglleft",
276 108 => "guilsinglright",
277 109 => "fi",
278 110 => "fl",
279 111 => "endash",
280 112 => "dagger",
281 113 => "daggerdbl",
282 114 => "periodcentered",
283 115 => "paragraph",
284 116 => "bullet",
285 117 => "quotesinglbase",
286 118 => "quotedblbase",
287 119 => "quotedblright",
288 120 => "guillemotright",
289 121 => "ellipsis",
290 122 => "perthousand",
291 123 => "questiondown",
292 124 => "grave",
293 125 => "acute",
294 126 => "circumflex",
295 127 => "tilde",
296 128 => "macron",
297 129 => "breve",
298 130 => "dotaccent",
299 131 => "dieresis",
300 132 => "ring",
301 133 => "cedilla",
302 134 => "hungarumlaut",
303 135 => "ogonek",
304 136 => "caron",
305 137 => "emdash",
306 138 => "AE",
307 139 => "ordfeminine",
308 140 => "Lslash",
309 141 => "Oslash",
310 142 => "OE",
311 143 => "ordmasculine",
312 144 => "ae",
313 145 => "dotlessi",
314 146 => "lslash",
315 147 => "oslash",
316 148 => "oe",
317 149 => "germandbls",
318 150 => "onesuperior",
319 151 => "logicalnot",
320 152 => "mu",
321 153 => "trademark",
322 154 => "Eth",
323 155 => "onehalf",
324 156 => "plusminus",
325 157 => "Thorn",
326 158 => "onequarter",
327 159 => "divide",
328 160 => "brokenbar",
329 161 => "degree",
330 162 => "thorn",
331 163 => "threequarters",
332 164 => "twosuperior",
333 165 => "registered",
334 166 => "minus",
335 167 => "eth",
336 168 => "multiply",
337 169 => "threesuperior",
338 170 => "copyright",
339 171 => "Aacute",
340 172 => "Acircumflex",
341 173 => "Adieresis",
342 174 => "Agrave",
343 175 => "Aring",
344 176 => "Atilde",
345 177 => "Ccedilla",
346 178 => "Eacute",
347 179 => "Ecircumflex",
348 180 => "Edieresis",
349 181 => "Egrave",
350 182 => "Iacute",
351 183 => "Icircumflex",
352 184 => "Idieresis",
353 185 => "Igrave",
354 186 => "Ntilde",
355 187 => "Oacute",
356 188 => "Ocircumflex",
357 189 => "Odieresis",
358 190 => "Ograve",
359 191 => "Otilde",
360 192 => "Scaron",
361 193 => "Uacute",
362 194 => "Ucircumflex",
363 195 => "Udieresis",
364 196 => "Ugrave",
365 197 => "Yacute",
366 198 => "Ydieresis",
367 199 => "Zcaron",
368 200 => "aacute",
369 201 => "acircumflex",
370 202 => "adieresis",
371 203 => "agrave",
372 204 => "aring",
373 205 => "atilde",
374 206 => "ccedilla",
375 207 => "eacute",
376 208 => "ecircumflex",
377 209 => "edieresis",
378 210 => "egrave",
379 211 => "iacute",
380 212 => "icircumflex",
381 213 => "idieresis",
382 214 => "igrave",
383 215 => "ntilde",
384 216 => "oacute",
385 217 => "ocircumflex",
386 218 => "odieresis",
387 219 => "ograve",
388 220 => "otilde",
389 221 => "scaron",
390 222 => "uacute",
391 223 => "ucircumflex",
392 224 => "udieresis",
393 225 => "ugrave",
394 226 => "yacute",
395 227 => "ydieresis",
396 228 => "zcaron",
397 _ => return None,
398 })
399}
400
401fn get_expert(glyph_id: GlyphID) -> Option<&'static str> {
402 Some(match glyph_id {
403 1 => "space",
404 229 => "exclamsmall",
405 230 => "Hungarumlautsmall",
406 231 => "dollaroldstyle",
407 232 => "dollarsuperior",
408 233 => "ampersandsmall",
409 234 => "Acutesmall",
410 235 => "parenleftsuperior",
411 236 => "parenrightsuperior",
412 237 => "twodotenleader",
413 238 => "onedotenleader",
414 13 => "comma",
415 14 => "hyphen",
416 15 => "period",
417 99 => "fraction",
418 239 => "zerooldstyle",
419 240 => "oneoldstyle",
420 241 => "twooldstyle",
421 242 => "threeoldstyle",
422 243 => "fouroldstyle",
423 244 => "fiveoldstyle",
424 245 => "sixoldstyle",
425 246 => "sevenoldstyle",
426 247 => "eightoldstyle",
427 248 => "nineoldstyle",
428 27 => "colon",
429 28 => "semicolon",
430 249 => "commasuperior",
431 250 => "threequartersemdash",
432 251 => "periodsuperior",
433 252 => "questionsmall",
434 253 => "asuperior",
435 254 => "bsuperior",
436 255 => "centsuperior",
437 256 => "dsuperior",
438 257 => "esuperior",
439 258 => "isuperior",
440 259 => "lsuperior",
441 260 => "msuperior",
442 261 => "nsuperior",
443 262 => "osuperior",
444 263 => "rsuperior",
445 264 => "ssuperior",
446 265 => "tsuperior",
447 266 => "ff",
448 109 => "fi",
449 110 => "fl",
450 267 => "ffi",
451 268 => "ffl",
452 269 => "parenleftinferior",
453 270 => "parenrightinferior",
454 271 => "Circumflexsmall",
455 272 => "hyphensuperior",
456 273 => "Gravesmall",
457 274 => "Asmall",
458 275 => "Bsmall",
459 276 => "Csmall",
460 277 => "Dsmall",
461 278 => "Esmall",
462 279 => "Fsmall",
463 280 => "Gsmall",
464 281 => "Hsmall",
465 282 => "Ismall",
466 283 => "Jsmall",
467 284 => "Ksmall",
468 285 => "Lsmall",
469 286 => "Msmall",
470 287 => "Nsmall",
471 288 => "Osmall",
472 289 => "Psmall",
473 290 => "Qsmall",
474 291 => "Rsmall",
475 292 => "Ssmall",
476 293 => "Tsmall",
477 294 => "Usmall",
478 295 => "Vsmall",
479 296 => "Wsmall",
480 297 => "Xsmall",
481 298 => "Ysmall",
482 299 => "Zsmall",
483 300 => "colonmonetary",
484 301 => "onefitted",
485 302 => "rupiah",
486 303 => "Tildesmall",
487 304 => "exclamdownsmall",
488 305 => "centoldstyle",
489 306 => "Lslashsmall",
490 307 => "Scaronsmall",
491 308 => "Zcaronsmall",
492 309 => "Dieresissmall",
493 310 => "Brevesmall",
494 311 => "Caronsmall",
495 312 => "Dotaccentsmall",
496 313 => "Macronsmall",
497 314 => "figuredash",
498 315 => "hypheninferior",
499 316 => "Ogoneksmall",
500 317 => "Ringsmall",
501 318 => "Cedillasmall",
502 158 => "onequarter",
503 155 => "onehalf",
504 163 => "threequarters",
505 319 => "questiondownsmall",
506 320 => "oneeighth",
507 321 => "threeeighths",
508 322 => "fiveeighths",
509 323 => "seveneighths",
510 324 => "onethird",
511 325 => "twothirds",
512 326 => "zerosuperior",
513 150 => "onesuperior",
514 164 => "twosuperior",
515 169 => "threesuperior",
516 327 => "foursuperior",
517 328 => "fivesuperior",
518 329 => "sixsuperior",
519 330 => "sevensuperior",
520 331 => "eightsuperior",
521 332 => "ninesuperior",
522 333 => "zeroinferior",
523 334 => "oneinferior",
524 335 => "twoinferior",
525 336 => "threeinferior",
526 337 => "fourinferior",
527 338 => "fiveinferior",
528 339 => "sixinferior",
529 340 => "seveninferior",
530 341 => "eightinferior",
531 342 => "nineinferior",
532 343 => "centinferior",
533 344 => "dollarinferior",
534 345 => "periodinferior",
535 346 => "commainferior",
536 347 => "Agravesmall",
537 348 => "Aacutesmall",
538 349 => "Acircumflexsmall",
539 350 => "Atildesmall",
540 351 => "Adieresissmall",
541 352 => "Aringsmall",
542 353 => "AEsmall",
543 354 => "Ccedillasmall",
544 355 => "Egravesmall",
545 356 => "Eacutesmall",
546 357 => "Ecircumflexsmall",
547 358 => "Edieresissmall",
548 359 => "Igravesmall",
549 360 => "Iacutesmall",
550 361 => "Icircumflexsmall",
551 362 => "Idieresissmall",
552 363 => "Ethsmall",
553 364 => "Ntildesmall",
554 365 => "Ogravesmall",
555 366 => "Oacutesmall",
556 367 => "Ocircumflexsmall",
557 368 => "Otildesmall",
558 369 => "Odieresissmall",
559 370 => "OEsmall",
560 371 => "Oslashsmall",
561 372 => "Ugravesmall",
562 373 => "Uacutesmall",
563 374 => "Ucircumflexsmall",
564 375 => "Udieresissmall",
565 376 => "Yacutesmall",
566 377 => "Thornsmall",
567 378 => "Ydieresissmall",
568 _ => return None,
569 })
570}
571
572fn get_expert_subset(glyph_id: GlyphID) -> Option<&'static str> {
573 Some(match glyph_id {
574 1 => "space",
575 231 => "dollaroldstyle",
576 232 => "dollarsuperior",
577 235 => "parenleftsuperior",
578 236 => "parenrightsuperior",
579 237 => "twodotenleader",
580 238 => "onedotenleader",
581 13 => "comma",
582 14 => "hyphen",
583 15 => "period",
584 99 => "fraction",
585 239 => "zerooldstyle",
586 240 => "oneoldstyle",
587 241 => "twooldstyle",
588 242 => "threeoldstyle",
589 243 => "fouroldstyle",
590 244 => "fiveoldstyle",
591 245 => "sixoldstyle",
592 246 => "sevenoldstyle",
593 247 => "eightoldstyle",
594 248 => "nineoldstyle",
595 27 => "colon",
596 28 => "semicolon",
597 249 => "commasuperior",
598 250 => "threequartersemdash",
599 251 => "periodsuperior",
600 253 => "asuperior",
601 254 => "bsuperior",
602 255 => "centsuperior",
603 256 => "dsuperior",
604 257 => "esuperior",
605 258 => "isuperior",
606 259 => "lsuperior",
607 260 => "msuperior",
608 261 => "nsuperior",
609 262 => "osuperior",
610 263 => "rsuperior",
611 264 => "ssuperior",
612 265 => "tsuperior",
613 266 => "ff",
614 109 => "fi",
615 110 => "fl",
616 267 => "ffi",
617 268 => "ffl",
618 269 => "parenleftinferior",
619 270 => "parenrightinferior",
620 272 => "hyphensuperior",
621 300 => "colonmonetary",
622 301 => "onefitted",
623 302 => "rupiah",
624 305 => "centoldstyle",
625 314 => "figuredash",
626 315 => "hypheninferior",
627 158 => "onequarter",
628 155 => "onehalf",
629 163 => "threequarters",
630 320 => "oneeighth",
631 321 => "threeeighths",
632 322 => "fiveeighths",
633 323 => "seveneighths",
634 324 => "onethird",
635 325 => "twothirds",
636 326 => "zerosuperior",
637 150 => "onesuperior",
638 164 => "twosuperior",
639 169 => "threesuperior",
640 327 => "foursuperior",
641 328 => "fivesuperior",
642 329 => "sixsuperior",
643 330 => "sevensuperior",
644 331 => "eightsuperior",
645 332 => "ninesuperior",
646 333 => "zeroinferior",
647 334 => "oneinferior",
648 335 => "twoinferior",
649 336 => "threeinferior",
650 337 => "fourinferior",
651 338 => "fiveinferior",
652 339 => "sixinferior",
653 340 => "seveninferior",
654 341 => "eightinferior",
655 342 => "nineinferior",
656 343 => "centinferior",
657 344 => "dollarinferior",
658 345 => "periodinferior",
659 346 => "commainferior",
660 _ => return None,
661 })
662}