1mod blob;
4mod format;
5mod instance;
6mod source;
7mod tables;
8
9pub use blob::FontBlob;
10pub use format::FontFormat;
11pub use instance::{
12 FontFeatureVariations, FontInstance, FontInstanceBuilder, FontVariation, NormalizedCoord,
13};
14pub use source::FontSource;
15pub use tables::{FontTableFunction, FontTables};
16
17#[doc(hidden)]
19#[rust_analyzer::completions(hidden_from_completion)]
20pub mod interop;
21
22use super::once::Once;
23use crate::{ps::type1::Type1Font, ReadError};
24use alloc::{boxed::Box, sync::Arc};
25use core::any::Any;
26
27#[derive(Clone)]
32pub struct Font(Arc<FontRepr>);
33
34impl Font {
35 pub fn new(source: impl Into<FontSource>, index: u32) -> Result<Self, ReadError> {
40 let source = source.into();
41 let kind = if let Ok(tables) = FontTables::new(source.clone(), index) {
42 Some(FontKindRepr::Sfnt(tables, index))
43 } else if let FontSource::Blob(blob) = &source {
44 match FontFormat::new(blob) {
45 Some(FontFormat::Type1) => Type1Font::new(blob).ok().map(FontKindRepr::Type1),
46 _ => None,
48 }
49 } else {
50 None
51 };
52 let kind = kind.ok_or(ReadError::MalformedData("Data isn't a font"))?;
53 let repr = FontRepr {
54 source,
55 kind,
56 shaping_data: Once::new(),
57 };
58 Ok(Self(Arc::new(repr)))
59 }
60
61 pub fn source(&self) -> &FontSource {
63 &self.0.source
64 }
65
66 pub fn kind(&self) -> FontKind<'_> {
68 match &self.0.kind {
69 FontKindRepr::Sfnt(tables, index) => FontKind::Sfnt(tables, *index),
70 FontKindRepr::Type1(font) => FontKind::Type1(font),
71 }
72 }
73
74 pub fn tables(&self) -> &FontTables {
78 if let FontKindRepr::Sfnt(tables, _) = &self.0.kind {
79 tables
80 } else {
81 &tables::EMPTY_FONT_TABLES
82 }
83 }
84}
85
86struct FontRepr {
87 source: FontSource,
88 kind: FontKindRepr,
89 shaping_data: Once<Box<dyn Any + Send + Sync>>,
91}
92
93#[derive(Clone)]
95pub enum FontKind<'a> {
96 Sfnt(&'a FontTables, u32),
98 Type1(&'a Type1Font),
100}
101
102#[expect(clippy::large_enum_variant)]
104enum FontKindRepr {
105 Sfnt(FontTables, u32),
106 Type1(Type1Font),
107}