Skip to main content

fonts_traits/
lib.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5#![deny(unsafe_code)]
6
7mod font_descriptor;
8mod font_identifier;
9mod font_template;
10mod system_font_service_proxy;
11
12use std::sync::Arc;
13use std::sync::atomic::AtomicUsize;
14
15pub use font_descriptor::*;
16pub use font_identifier::*;
17pub use font_template::*;
18use malloc_size_of_derive::MallocSizeOf;
19pub use memmap2::Mmap;
20use serde::{Deserialize, Serialize};
21use servo_arc::Arc as ServoArc;
22use servo_base::generic_channel::GenericSharedMemory;
23use style::font_face::Descriptors;
24use style::stylesheets::LockedFontFaceRule;
25pub use system_font_service_proxy::*;
26
27#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
28pub enum WebFontLoadEvent {
29    LoadedSuccessfully,
30    UnblockedFontReadyPromise,
31}
32
33pub type StylesheetWebFontLoadFinishedCallback =
34    Arc<dyn Fn(WebFontLoadEvent) + Send + Sync + 'static>;
35
36#[derive(Serialize, Deserialize)]
37struct SerializableFontData(Arc<GenericSharedMemory>);
38
39impl From<FontData> for SerializableFontData {
40    fn from(value: FontData) -> Self {
41        match value {
42            FontData::MemoryMapped(mmap) => {
43                SerializableFontData(Arc::new(GenericSharedMemory::from_bytes(&mmap)))
44            },
45            FontData::SharedMemory(generic_shared_memory) => {
46                SerializableFontData(generic_shared_memory)
47            },
48        }
49    }
50}
51
52impl From<SerializableFontData> for FontData {
53    fn from(value: SerializableFontData) -> Self {
54        FontData::SharedMemory(value.0)
55    }
56}
57
58/// A data structure to store data for fonts. Data is stored internally in an
59/// [`GenericSharedMemory`] handle, so that it can be sent without serialization
60/// across IPC channels.
61#[derive(Clone, Deserialize, Serialize, MallocSizeOf)]
62#[serde(from = "SerializableFontData", into = "SerializableFontData")]
63pub enum FontData {
64    MemoryMapped(#[conditional_malloc_size_of] Arc<Mmap>),
65    SharedMemory(#[conditional_malloc_size_of] Arc<GenericSharedMemory>),
66}
67
68impl FontData {
69    pub fn from_bytes(bytes: &[u8]) -> Self {
70        Self::SharedMemory(Arc::new(GenericSharedMemory::from_bytes(bytes)))
71    }
72
73    pub fn from_mmap(mmap: Mmap) -> Self {
74        Self::MemoryMapped(Arc::new(mmap))
75    }
76
77    pub fn as_ipc_shared_memory(self) -> Arc<GenericSharedMemory> {
78        match self {
79            FontData::MemoryMapped(mmap) => Arc::new(GenericSharedMemory::from_bytes(&mmap)),
80            FontData::SharedMemory(generic_shared_memory) => generic_shared_memory,
81        }
82    }
83
84    /// This is in single process mode more efficient because we do not have to copy the vector.
85    pub fn from_vec(bytes: Vec<u8>) -> Self {
86        Self::SharedMemory(Arc::new(GenericSharedMemory::from_vec(bytes)))
87    }
88}
89
90impl AsRef<[u8]> for FontData {
91    fn as_ref(&self) -> &[u8] {
92        match &self {
93            FontData::MemoryMapped(mmap) => mmap,
94            FontData::SharedMemory(generic_shared_memory) => generic_shared_memory,
95        }
96    }
97}
98
99/// Raw font data and an index
100///
101/// If the font data is of a TTC (TrueType collection) file, then the index of a specific font within
102/// the collection. If the font data is for is single font then the index will always be 0.
103#[derive(Deserialize, Clone, Serialize, MallocSizeOf)]
104pub struct FontDataAndIndex {
105    /// The raw font file data (.ttf, .otf, .ttc, etc)
106    pub data: FontData,
107    /// The index of the font within the file (0 if the file is not a ttc)
108    pub index: u32,
109}
110
111#[derive(Copy, Clone, PartialEq)]
112pub enum FontDataError {
113    FailedToLoad,
114}
115
116/// Describes how the set of active `@font-face` rules was changed after a call to `FontContext::rebuild_font_face_set`.
117#[derive(Clone, Default)]
118pub struct WebFontSetDifference {
119    /// A list of `@font-face` rules that were added in this update.
120    pub added_font_faces: Vec<ServoArc<FontFaceRuleInfo>>,
121    /// A list of `@font-face` rules that were removed in this update.
122    pub removed_font_faces: Vec<ServoArc<FontFaceRuleInfo>>,
123    /// Whether the cascade index of any `@font-face` rule changed during this update.
124    ///
125    /// This can cause different fonts to be selected during font matching.
126    pub cascade_index_of_any_rule_changed: bool,
127}
128
129impl WebFontSetDifference {
130    /// Returns `true` iff the font face set remained unchanged by the update.
131    pub fn is_empty(&self) -> bool {
132        self.added_font_faces.is_empty() && self.removed_font_faces.is_empty()
133    }
134}
135
136#[derive(MallocSizeOf)]
137pub struct FontFaceRuleInfo {
138    /// The index of this `@font-face` in the cascade, relative to all
139    /// other `@font-face` rules.
140    pub cascade_index: AtomicUsize,
141    /// The descriptors on the `@font-face` rule.
142    pub descriptors: Descriptors,
143    /// The CSS rule that created this `@font-face`.
144    ///
145    /// This does *not* uniquely identify this struct across updates
146    /// to the set of live `@font-face` rules.
147    #[conditional_malloc_size_of]
148    pub rule: ServoArc<LockedFontFaceRule>,
149}