1 //! PostScript (CFF and CFF2) common tables.
2 
3 use std::fmt;
4 
5 mod blend;
6 mod fd_select;
7 mod index;
8 mod stack;
9 mod string;
10 
11 pub mod charstring;
12 pub mod dict;
13 
14 include!("../../generated/generated_postscript.rs");
15 
16 pub use blend::BlendState;
17 pub use index::Index;
18 pub use stack::{Number, Stack};
19 pub use string::{Latin1String, StringId, STANDARD_STRINGS};
20 
21 /// Errors that are specific to PostScript processing.
22 #[derive(Clone, Debug)]
23 pub enum Error {
24     InvalidIndexOffsetSize(u8),
25     ZeroOffsetInIndex,
26     InvalidVariationStoreIndex(u16),
27     StackOverflow,
28     StackUnderflow,
29     InvalidStackAccess(usize),
30     ExpectedI32StackEntry(usize),
31     InvalidNumber,
32     InvalidDictOperator(u8),
33     InvalidCharstringOperator(u8),
34     CharstringNestingDepthLimitExceeded,
35     MissingSubroutines,
36     MissingBlendState,
37     MissingPrivateDict,
38     MissingCharstrings,
39     Read(ReadError),
40 }
41 
42 impl From<ReadError> for Error {
from(value: ReadError) -> Self43     fn from(value: ReadError) -> Self {
44         Self::Read(value)
45     }
46 }
47 
48 impl fmt::Display for Error {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result49     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50         match self {
51             Self::InvalidIndexOffsetSize(size) => {
52                 write!(f, "invalid offset size of {size} for INDEX (expected 1-4)")
53             }
54             Self::ZeroOffsetInIndex => {
55                 write!(f, "invalid offset of 0 in INDEX (must be >= 1)")
56             }
57             Self::InvalidVariationStoreIndex(index) => {
58                 write!(
59                     f,
60                     "variation store index {index} referenced an invalid variation region"
61                 )
62             }
63             Self::StackOverflow => {
64                 write!(f, "attempted to push a value to a full stack")
65             }
66             Self::StackUnderflow => {
67                 write!(f, "attempted to pop a value from an empty stack")
68             }
69             Self::InvalidStackAccess(index) => {
70                 write!(f, "invalid stack access for index {index}")
71             }
72             Self::ExpectedI32StackEntry(index) => {
73                 write!(f, "attempted to read an integer at stack index {index}, but found a fixed point value")
74             }
75             Self::InvalidNumber => {
76                 write!(f, "number is in an invalid format")
77             }
78             Self::InvalidDictOperator(operator) => {
79                 write!(f, "dictionary operator {operator} is invalid")
80             }
81             Self::InvalidCharstringOperator(operator) => {
82                 write!(f, "charstring operator {operator} is invalid")
83             }
84             Self::CharstringNestingDepthLimitExceeded => {
85                 write!(
86                     f,
87                     "exceeded subroutine nesting depth limit {} while evaluating a charstring",
88                     charstring::NESTING_DEPTH_LIMIT
89                 )
90             }
91             Self::MissingSubroutines => {
92                 write!(
93                     f,
94                     "encountered a callsubr operator but no subroutine index was provided"
95                 )
96             }
97             Self::MissingBlendState => {
98                 write!(
99                     f,
100                     "encountered a blend operator but no blend state was provided"
101                 )
102             }
103             Self::MissingPrivateDict => {
104                 write!(f, "CFF table does not contain a private dictionary")
105             }
106             Self::MissingCharstrings => {
107                 write!(f, "CFF table does not contain a charstrings index")
108             }
109             Self::Read(err) => write!(f, "{err}"),
110         }
111     }
112 }
113