skrifa/outline/
error.rs

1//! Error types associated with outlines.
2
3use core::fmt;
4use read_fonts::types::GlyphId;
5
6pub use read_fonts::{tables::postscript::Error as CffError, ReadError};
7
8pub use super::glyf::HintError;
9pub use super::path::ToPathError;
10
11/// Errors that may occur when drawing glyphs.
12#[derive(Clone, Debug)]
13pub enum DrawError {
14    /// No viable sources were available.
15    NoSources,
16    /// The requested glyph was not present in the font.
17    GlyphNotFound(GlyphId),
18    /// Exceeded memory limits when loading a glyph.
19    InsufficientMemory,
20    /// Exceeded a recursion limit when loading a glyph.
21    RecursionLimitExceeded(GlyphId),
22    /// Glyph outline contains too many points.
23    TooManyPoints(GlyphId),
24    /// Error occurred during hinting.
25    HintingFailed(HintError),
26    /// An anchor point had invalid indices.
27    InvalidAnchorPoint(GlyphId, u16),
28    /// Error occurred while loading a PostScript (CFF/CFF2) glyph.
29    PostScript(CffError),
30    /// Conversion from outline to path failed.
31    ToPath(ToPathError),
32    /// Error occurred when reading font data.
33    Read(ReadError),
34    /// HarfBuzz style drawing with hints is not supported
35    // Error rather than silently returning unhinted per f2f discussion.
36    HarfBuzzHintingUnsupported,
37}
38
39impl From<HintError> for DrawError {
40    fn from(value: HintError) -> Self {
41        Self::HintingFailed(value)
42    }
43}
44
45impl From<ToPathError> for DrawError {
46    fn from(e: ToPathError) -> Self {
47        Self::ToPath(e)
48    }
49}
50
51impl From<ReadError> for DrawError {
52    fn from(e: ReadError) -> Self {
53        Self::Read(e)
54    }
55}
56
57impl From<CffError> for DrawError {
58    fn from(value: CffError) -> Self {
59        Self::PostScript(value)
60    }
61}
62
63impl fmt::Display for DrawError {
64    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
65        match self {
66            Self::NoSources => write!(f, "No glyph sources are available for the given font"),
67            Self::GlyphNotFound(gid) => write!(f, "Glyph {gid} was not found in the given font"),
68            Self::InsufficientMemory => write!(f, "exceeded memory limits"),
69            Self::RecursionLimitExceeded(gid) => write!(
70                f,
71                "Recursion limit ({}) exceeded when loading composite component {gid}",
72                super::GLYF_COMPOSITE_RECURSION_LIMIT,
73            ),
74            Self::TooManyPoints(gid) => write!(f, "Glyph {gid} contains more than 64k points"),
75            Self::HintingFailed(e) => write!(f, "{e}"),
76            Self::InvalidAnchorPoint(gid, index) => write!(
77                f,
78                "Invalid anchor point index ({index}) for composite glyph {gid}",
79            ),
80            Self::PostScript(e) => write!(f, "{e}"),
81            Self::ToPath(e) => write!(f, "{e}"),
82            Self::Read(e) => write!(f, "{e}"),
83            Self::HarfBuzzHintingUnsupported => write!(
84                f,
85                "HarfBuzz style paths with hinting is not (yet?) supported"
86            ),
87        }
88    }
89}
90
91#[cfg(feature = "std")]
92impl std::error::Error for DrawError {}