Skip to main content

read_fonts/model/glyph/outline/
cff.rs

1//! Outlines from `CFF` and `CFF2` charstrings.
2//!
3//! The charstrings are parsed and evaluated by [`crate::ps::cff`]. This
4//! module pairs a charstring with the font's location and its subfont.
5
6use super::{DrawOptions, DrawnMetrics, PathSink};
7use crate::model::Error;
8use crate::{
9    model::glyph::outline::OutlineSource,
10    model::variation::NormalizedCoord,
11    ps::{
12        cff::{CffFontRef, Subfont},
13        charstring::{NopFilterSink, TransformSink},
14    },
15    types::{F2Dot14, GlyphId},
16};
17
18/// A `CFF` or `CFF2` charstring from a [`Font`](crate::model::Font), with
19/// its subfont.
20#[derive(Clone, Copy)]
21pub struct CffGlyph<'a> {
22    pub(super) cff: &'a CffFontRef<'a>,
23    pub(super) coords: &'a [F2Dot14],
24    pub(super) glyph: GlyphId,
25    pub(super) subfont_index: u16,
26    pub(super) subfont: Subfont,
27    pub(super) source: OutlineSource,
28}
29
30impl<'a> CffGlyph<'a> {
31    /// Returns the glyph identifier.
32    pub fn glyph(&self) -> GlyphId {
33        self.glyph
34    }
35
36    /// Returns the table that contains the charstring, either `CFF` or
37    /// `CFF2`.
38    pub fn source(&self) -> OutlineSource {
39        self.source
40    }
41
42    /// Returns the `CFF` or `CFF2` font that evaluates the charstring.
43    pub fn cff_font(&self) -> &'a CffFontRef<'a> {
44        self.cff
45    }
46
47    /// Returns the normalized variation coordinates used to evaluate the
48    /// charstring.
49    pub fn normalized_coords(&self) -> &'a [NormalizedCoord] {
50        self.coords
51    }
52
53    /// Returns the index of the glyph's subfont.
54    pub fn subfont_index(&self) -> u32 {
55        self.subfont_index as u32
56    }
57
58    /// Returns the glyph's subfont, parsed at [`normalized_coords`](Self::normalized_coords).
59    ///
60    /// For hinting, use [`CffFontRef::subfont_hinted`] with the same index
61    /// to also read the hinting parameters.
62    pub fn subfont(&self) -> &Subfont {
63        &self.subfont
64    }
65
66    /// Draws the charstring and returns its width, which can be
67    /// negative.
68    pub(super) fn draw(
69        &self,
70        options: &DrawOptions,
71        mut sink: &mut dyn PathSink,
72    ) -> Result<DrawnMetrics, Error> {
73        let mut filter = NopFilterSink::new(&mut sink);
74        let transform = self.cff.transform(&self.subfont, options.ppem);
75        let mut transformer = TransformSink::new(&mut filter, transform);
76        let width = self.cff.evaluate_charstring(
77            &self.subfont,
78            self.glyph,
79            self.coords,
80            &mut transformer,
81        )?;
82        Ok(DrawnMetrics {
83            h_advance: width.map(|width| transform.transform_h_metric(width).to_f32()),
84            ..Default::default()
85        })
86    }
87}