Skip to main content

stet_core/
glyph_cache.rs

1// stet - A PostScript Interpreter
2// Copyright (c) 2026 Scott Bowman
3// SPDX-License-Identifier: Apache-2.0 OR MIT
4
5//! Glyph path cache: caches charstring interpretation results per font.
6//!
7//! Stores glyph outlines in charstring coordinates (pre-FontMatrix, pre-CTM).
8//! One cache entry per glyph per font, regardless of size/orientation.
9//! FontMatrix and CTM transforms are still applied per-render.
10
11use crate::display_list::DisplayElement;
12use crate::graphics_state::PathSegment;
13use crate::object::{EntityId, NameId};
14use rustc_hash::FxHashMap;
15use std::sync::Arc;
16
17/// Cached glyph outline + width in charstring coordinates.
18#[derive(Clone)]
19pub struct CachedGlyph {
20    pub segments: Arc<Vec<PathSegment>>,
21    pub width_x: f64,
22    pub width_y: f64,
23}
24
25/// Cached Type 3 glyph: display list elements + origin for translation.
26#[derive(Clone)]
27pub struct CachedType3Glyph {
28    pub elements: Vec<DisplayElement>,
29    pub origin_dev_x: f64,
30    pub origin_dev_y: f64,
31    pub width: (f64, f64),
32}
33
34/// Cache mode set by setcachedevice/setcharwidth during Type 3 BuildChar.
35#[derive(Clone, Copy, PartialEq, Eq)]
36pub enum Type3CacheMode {
37    /// setcachedevice was called — glyph is cacheable.
38    Cache,
39    /// setcharwidth was called — glyph is not cacheable (may use color ops).
40    NoCache,
41}
42
43/// Per-font glyph path cache.
44#[derive(Default)]
45pub struct GlyphCache {
46    /// Type 1 and CFF glyphs keyed by glyph name.
47    pub by_name: FxHashMap<NameId, CachedGlyph>,
48    /// CIDFont glyphs keyed by CID.
49    pub by_cid: FxHashMap<i32, CachedGlyph>,
50    /// TrueType glyphs keyed by glyph ID.
51    pub by_gid: FxHashMap<u16, CachedGlyph>,
52    /// Type 3 glyphs keyed by char code (only setcachedevice glyphs).
53    pub by_charcode: FxHashMap<u8, CachedType3Glyph>,
54}
55
56impl GlyphCache {
57    pub fn new() -> Self {
58        Self {
59            by_name: FxHashMap::default(),
60            by_cid: FxHashMap::default(),
61            by_gid: FxHashMap::default(),
62            by_charcode: FxHashMap::default(),
63        }
64    }
65}
66
67/// Get or create the glyph cache for a font entity.
68#[inline]
69pub fn get_or_create_cache(
70    caches: &mut FxHashMap<EntityId, GlyphCache>,
71    font_entity: EntityId,
72) -> &mut GlyphCache {
73    caches.entry(font_entity).or_default()
74}