read_fonts/model/glyph/outline/
cff.rs1use 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#[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 pub fn glyph(&self) -> GlyphId {
33 self.glyph
34 }
35
36 pub fn source(&self) -> OutlineSource {
39 self.source
40 }
41
42 pub fn cff_font(&self) -> &'a CffFontRef<'a> {
44 self.cff
45 }
46
47 pub fn normalized_coords(&self) -> &'a [NormalizedCoord] {
50 self.coords
51 }
52
53 pub fn subfont_index(&self) -> u32 {
55 self.subfont_index as u32
56 }
57
58 pub fn subfont(&self) -> &Subfont {
63 &self.subfont
64 }
65
66 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}