1#![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#[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#[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#[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#[derive(Deserialize, Clone, Serialize)]
167pub struct FontDataAndIndex {
168 pub data: FontData,
170 pub index: u32,
172}
173
174#[derive(Copy, Clone, PartialEq)]
175pub enum FontDataError {
176 FailedToLoad,
177}
178
179#[derive(Clone, Default)]
181pub struct WebFontSetDifference {
182 pub added_font_faces: Vec<FontFaceRuleWithOrigin>,
184 pub removed_font_faces: Vec<FontFaceRuleWithOrigin>,
186}
187
188impl WebFontSetDifference {
189 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}