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::ops::{Deref, Range};
13use std::sync::Arc;
14
15pub use font_descriptor::*;
16pub use font_identifier::*;
17pub use font_template::*;
18use malloc_size_of_derive::MallocSizeOf;
19use num_derive::{NumOps, One, Zero};
20use serde::{Deserialize, Serialize};
21use servo_arc::Arc as ServoArc;
22use servo_base::generic_channel::GenericSharedMemory;
23use style::shared_lock::StylesheetGuards;
24use style::stylesheets::{FontFaceRule, LockedFontFaceRule, Origin};
25pub use system_font_service_proxy::*;
26use webrender_api::euclid::num::One;
27
28/// An index that refers to a byte offset in a text run. This could
29/// the middle of a glyph.
30#[derive(
31    Clone,
32    Copy,
33    Debug,
34    Default,
35    Deserialize,
36    Eq,
37    MallocSizeOf,
38    NumOps,
39    Ord,
40    One,
41    PartialEq,
42    PartialOrd,
43    Serialize,
44    Zero,
45)]
46pub struct ByteIndex(pub usize);
47
48impl ByteIndex {
49    pub fn get(&self) -> usize {
50        self.0
51    }
52}
53
54/// A range of UTF-8 bytes in a text run. This is used to identify glyphs in a `GlyphRun`
55/// by their original character byte offsets in the text.
56#[derive(Clone, Debug, Default, Deserialize, MallocSizeOf, PartialEq, Serialize)]
57pub struct TextByteRange(Range<ByteIndex>);
58
59impl TextByteRange {
60    pub fn len(&self) -> ByteIndex {
61        self.0.end - self.0.start
62    }
63
64    #[inline]
65    pub fn intersect(&self, other: &Self) -> Self {
66        let begin = self.start.max(other.start);
67        let end = self.end.min(other.end);
68
69        if end < begin {
70            Self::default()
71        } else {
72            Self::new(begin, end)
73        }
74    }
75
76    #[inline]
77    pub fn contains_inclusive(&self, index: ByteIndex) -> bool {
78        index >= self.start && index <= self.end
79    }
80}
81
82impl Deref for TextByteRange {
83    type Target = Range<ByteIndex>;
84    fn deref(&self) -> &Self::Target {
85        &self.0
86    }
87}
88
89impl Iterator for TextByteRange {
90    type Item = ByteIndex;
91
92    fn next(&mut self) -> Option<Self::Item> {
93        if self.0.start == self.0.end {
94            None
95        } else {
96            let next = self.0.start;
97            self.0.start = self.0.start + ByteIndex::one();
98            Some(next)
99        }
100    }
101
102    fn size_hint(&self) -> (usize, Option<usize>) {
103        (
104            self.0.end.0 - self.0.start.0,
105            Some(self.0.end.0 - self.0.start.0),
106        )
107    }
108}
109
110impl DoubleEndedIterator for TextByteRange {
111    fn next_back(&mut self) -> Option<Self::Item> {
112        if self.0.start == self.0.end {
113            None
114        } else {
115            self.0.end = self.0.end - ByteIndex::one();
116            Some(self.0.end)
117        }
118    }
119}
120
121impl TextByteRange {
122    pub fn new(start: ByteIndex, end: ByteIndex) -> Self {
123        Self(start..end)
124    }
125
126    pub fn iter(&self) -> Range<ByteIndex> {
127        self.0.clone()
128    }
129}
130
131#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
132pub enum WebFontLoadEvent {
133    LoadedSuccessfully,
134    UnblockedFontReadyPromise,
135}
136
137pub type StylesheetWebFontLoadFinishedCallback =
138    Arc<dyn Fn(WebFontLoadEvent) + Send + Sync + 'static>;
139
140/// A data structure to store data for fonts. Data is stored internally in an
141/// [`GenericSharedMemory`] handle, so that it can be sent without serialization
142/// across IPC channels.
143#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
144pub struct FontData(#[conditional_malloc_size_of] pub(crate) Arc<GenericSharedMemory>);
145
146impl FontData {
147    pub fn from_bytes(bytes: &[u8]) -> Self {
148        Self(Arc::new(GenericSharedMemory::from_bytes(bytes)))
149    }
150
151    pub fn as_ipc_shared_memory(&self) -> Arc<GenericSharedMemory> {
152        self.0.clone()
153    }
154}
155
156impl AsRef<[u8]> for FontData {
157    fn as_ref(&self) -> &[u8] {
158        &self.0
159    }
160}
161
162/// Raw font data and an index
163///
164/// If the font data is of a TTC (TrueType collection) file, then the index of a specific font within
165/// the collection. If the font data is for is single font then the index will always be 0.
166#[derive(Deserialize, Clone, Serialize)]
167pub struct FontDataAndIndex {
168    /// The raw font file data (.ttf, .otf, .ttc, etc)
169    pub data: FontData,
170    /// The index of the font within the file (0 if the file is not a ttc)
171    pub index: u32,
172}
173
174#[derive(Copy, Clone, PartialEq)]
175pub enum FontDataError {
176    FailedToLoad,
177}
178
179/// Describes how the set of active `@font-face` rules was changed after a call to `FontContext::rebuild_font_face_set`.
180#[derive(Clone, Default)]
181pub struct WebFontSetDifference {
182    /// A list of `@font-face` rules that were added in this update.
183    pub added_font_faces: Vec<FontFaceRuleWithOrigin>,
184    /// A list of `@font-face` rules that were removed in this update.
185    pub removed_font_faces: Vec<FontFaceRuleWithOrigin>,
186}
187
188impl WebFontSetDifference {
189    /// Returns `true` iff the font face set remained unchanged by the update.
190    pub fn is_empty(&self) -> bool {
191        self.added_font_faces.is_empty() && self.removed_font_faces.is_empty()
192    }
193}
194
195#[derive(Clone, MallocSizeOf)]
196pub struct FontFaceRuleWithOrigin {
197    #[conditional_malloc_size_of]
198    pub rule: ServoArc<LockedFontFaceRule>,
199    origin: Origin,
200}
201
202impl FontFaceRuleWithOrigin {
203    pub fn new(rule: ServoArc<LockedFontFaceRule>, origin: Origin) -> Self {
204        Self { rule, origin }
205    }
206
207    pub fn ptr_eq(first: &Self, second: &Self) -> bool {
208        ServoArc::ptr_eq(&first.rule, &second.rule)
209    }
210
211    pub fn read_with<'a>(&'a self, guards: &'a StylesheetGuards) -> &'a FontFaceRule {
212        match self.origin {
213            Origin::Author => self.rule.read_with(guards.author),
214            Origin::UserAgent | Origin::User => self.rule.read_with(guards.ua_or_user),
215        }
216    }
217}