read_fonts/tables/
postscript.rs

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