Skip to main content

read_fonts/ps/
error.rs

1//! Errors that may occur when processing PostScript fonts.
2
3use crate::ReadError;
4use core::fmt;
5
6/// Errors that are specific to PostScript processing.
7#[derive(Clone, Debug)]
8pub enum Error {
9    InvalidVariationStoreIndex,
10    StackOverflow,
11    StackUnderflow,
12    ExpectedInt,
13    InvalidNumber,
14    CharstringNestingDepthLimitExceeded,
15    MissingSubroutines,
16    MissingBlendState,
17    MissingFdArray,
18    MissingPrivateDict,
19    MissingCharstrings,
20    MissingCharset,
21    InvalidSeacCode(i32),
22    /// The data does not make sense: absent where it was required, too short,
23    /// or self-inconsistent.
24    ///
25    /// Carries nothing. This module answers a malformed read with `None`
26    /// wherever it can; this is what it says where a `Result` is required.
27    Malformed,
28}
29
30/// Kept so the `?` inside this module still reads well. It is `read-fonts`
31/// converting one of its own error types into another, which is why it can
32/// stay: nothing outside the crate has to name `ReadError` to use `Error`.
33impl From<ReadError> for Error {
34    fn from(_: ReadError) -> Self {
35        Self::Malformed
36    }
37}
38
39impl fmt::Display for Error {
40    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41        match self {
42            Self::InvalidVariationStoreIndex => {
43                write!(f, "variation store index referenced an invalid region")
44            }
45            Self::StackOverflow => {
46                write!(f, "attempted to push a value to a full stack")
47            }
48            Self::StackUnderflow => {
49                write!(f, "attempted to pop a value from an empty stack")
50            }
51            Self::ExpectedInt => {
52                write!(
53                    f,
54                    "expected an integer on the stack, found a fixed point value"
55                )
56            }
57            Self::InvalidNumber => {
58                write!(f, "number is in an invalid format")
59            }
60            Self::CharstringNestingDepthLimitExceeded => {
61                write!(
62                    f,
63                    "exceeded subroutine nesting depth limit {} while evaluating a charstring",
64                    crate::ps::cs::NESTING_DEPTH_LIMIT
65                )
66            }
67            Self::MissingSubroutines => {
68                write!(
69                    f,
70                    "encountered a callsubr operator but no subroutine index was provided"
71                )
72            }
73            Self::MissingBlendState => {
74                write!(
75                    f,
76                    "encountered a blend operator but no blend state was provided"
77                )
78            }
79            Self::MissingFdArray => {
80                write!(f, "CFF table does not contain a font dictionary index")
81            }
82            Self::MissingPrivateDict => {
83                write!(f, "CFF table does not contain a private dictionary")
84            }
85            Self::MissingCharstrings => {
86                write!(f, "CFF table does not contain a charstrings index")
87            }
88            Self::MissingCharset => {
89                write!(f, "CFF table does not contain a valid charset")
90            }
91            Self::InvalidSeacCode(code) => {
92                write!(f, "seac code {code} is not valid")
93            }
94            Self::Malformed => write!(f, "font data was absent or malformed"),
95        }
96    }
97}
98
99impl core::error::Error for Error {}