read_fonts/tables/
postscript.rs

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