zed_font_kit/handle.rs
1// font-kit/src/handle.rs
2//
3// Copyright © 2018 The Pathfinder Project Developers.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11//! Encapsulates the information needed to locate and open a font.
12//!
13//! This is either the path to the font or the raw in-memory font data.
14//!
15//! To open the font referenced by a handle, use a loader.
16
17use std::any::Any;
18use std::path::PathBuf;
19use std::sync::Arc;
20
21use crate::error::FontLoadingError;
22use crate::font::Font;
23use crate::loader::Loader;
24
25/// Encapsulates the information needed to locate and open a font.
26///
27/// This is either the path to the font or the raw in-memory font data.
28///
29/// To open the font referenced by a handle, use a loader.
30#[derive(Debug, Clone)]
31pub enum Handle {
32 /// A font on disk referenced by a path.
33 Path {
34 /// The path to the font.
35 path: PathBuf,
36 /// The index of the font, if the path refers to a collection.
37 ///
38 /// If the path refers to a single font, this value will be 0.
39 font_index: u32,
40 },
41 /// A font in memory.
42 Memory {
43 /// The raw TrueType/OpenType/etc. data that makes up this font.
44 bytes: Arc<Vec<u8>>,
45 /// The index of the font, if the memory consists of a collection.
46 ///
47 /// If the memory consists of a single font, this value will be 0.
48 font_index: u32,
49 },
50 /// An already-loaded font.
51 Native {
52 /// Type-erased font storage. Use [`Self::from_native`] to retrieve the font object.
53 inner: Arc<dyn Any + Sync + Send>,
54 },
55}
56
57impl Handle {
58 /// Creates a new handle from a path.
59 ///
60 /// `font_index` specifies the index of the font to choose if the path points to a font
61 /// collection. If the path points to a single font file, pass 0.
62 #[inline]
63 pub fn from_path(path: PathBuf, font_index: u32) -> Handle {
64 Handle::Path { path, font_index }
65 }
66
67 /// Creates a new handle from raw TTF/OTF/etc. data in memory.
68 ///
69 /// `font_index` specifies the index of the font to choose if the memory represents a font
70 /// collection. If the memory represents a single font file, pass 0.
71 #[inline]
72 pub fn from_memory(bytes: Arc<Vec<u8>>, font_index: u32) -> Handle {
73 Handle::Memory { bytes, font_index }
74 }
75
76 /// Creates a new handle from a system handle.
77 pub fn from_native<T: Loader>(inner: &T) -> Self
78 where
79 T::NativeFont: Sync + Send,
80 {
81 Self::Native {
82 inner: Arc::new(inner.native_font()),
83 }
84 }
85 /// Retrieves a handle to the font object.
86 ///
87 /// May return None if inner object is not of type `T` or if this handle does not contain a native font object.
88 pub fn native_as<T: 'static>(&self) -> Option<&T> {
89 if let Self::Native { inner } = self {
90 inner.downcast_ref()
91 } else {
92 None
93 }
94 }
95 /// A convenience method to load this handle with the default loader, producing a Font.
96 #[inline]
97 pub fn load(&self) -> Result<Font, FontLoadingError> {
98 Font::from_handle(self)
99 }
100}