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}