1use api::{FontInstanceData, FontInstanceFlags, FontInstanceKey};
6use api::{FontInstanceOptions, FontInstancePlatformOptions};
7use api::{FontKey, FontRenderMode, FontSize, FontTemplate, FontVariation};
8use api::{ColorU, GlyphIndex, GlyphDimensions, SyntheticItalics};
9use api::{IdNamespace, BlobImageResources};
10use api::channel::crossbeam::{unbounded, Receiver, Sender};
11use api::units::*;
12use api::ImageFormat;
13use crate::platform::font::FontContext;
14use crate::profiler::GlyphRasterizeProfiler;
15use crate::types::{FastHashMap, FastHashSet};
16use crate::telemetry::Telemetry;
17use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
18use rayon::ThreadPool;
19use rayon::prelude::*;
20use euclid::approxeq::ApproxEq;
21use smallvec::SmallVec;
22use std::cmp;
23use std::cell::Cell;
24use std::hash::{Hash, Hasher};
25use std::mem;
26use std::ops::Deref;
27use std::sync::{Arc, Condvar, Mutex, MutexGuard, Weak};
28use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
29use std::sync::atomic::{AtomicBool, Ordering};
30
31pub static GLYPH_FLASHING: AtomicBool = AtomicBool::new(false);
32const GLYPH_BATCH_SIZE: usize = 32;
33
34impl FontContexts {
35 pub fn lock_current_context(&self) -> MutexGuard<FontContext> {
37 match self.current_worker_id() {
38 Some(id) => self.lock_context(id),
39 None => self.lock_any_context(),
40 }
41 }
42
43 pub(in super) fn current_worker_id(&self) -> Option<usize> {
44 self.workers.current_thread_index()
45 }
46}
47
48thread_local! {
49 pub static SEED: Cell<u32> = Cell::new(0);
50}
51
52fn random() -> u32 {
54 SEED.with(|seed| {
55 seed.set(seed.get().wrapping_mul(22695477).wrapping_add(1));
56 seed.get()
57 })
58}
59
60impl GlyphRasterizer {
61 pub fn request_glyphs<F>(
62 &mut self,
63 font: FontInstance,
64 glyph_keys: &[GlyphKey],
65 mut handle: F,
66 )
67 where F: FnMut(&GlyphKey) -> bool
68 {
69 assert!(self.has_font(font.font_key));
70
71 let mut batch_size = 0;
72
73 for key in glyph_keys {
75 if !handle(key) {
76 continue;
77 }
78
79 self.pending_glyph_count += 1;
82 self.glyph_request_count += 1;
83
84 match self.pending_glyph_requests.get_mut(&font) {
87 Some(container) => {
88 container.push(*key);
89 batch_size = container.len();
90 }
91 None => {
92 self.pending_glyph_requests.insert(
94 font.clone(),
95 smallvec![*key],
96 );
97 }
98 }
99 }
100
101 if batch_size >= GLYPH_BATCH_SIZE {
104 let container = self.pending_glyph_requests.get_mut(&font).unwrap();
105 let glyphs = mem::replace(container, SmallVec::new());
106 self.flush_glyph_requests(font, glyphs, true);
107 }
108 }
109
110 pub fn enable_multithreading(&mut self, enable: bool) {
111 self.enable_multithreading = enable;
112 }
113
114 fn flush_glyph_requests(
118 &mut self,
119 font: FontInstance,
120 glyphs: SmallVec<[GlyphKey; 16]>,
121 use_workers: bool,
122 ) {
123 let font = Arc::new(font);
124 let font_contexts = Arc::clone(&self.font_contexts);
125 self.pending_glyph_jobs += glyphs.len();
126 self.pending_glyph_count -= glyphs.len();
127
128 let can_use_r8_format = self.can_use_r8_format;
129
130 if let Some(thread) = &self.dedicated_thread {
133 let tx = self.glyph_tx.clone();
134 let _ = thread.tx.send(GlyphRasterMsg::Rasterize { font, glyphs, can_use_r8_format, tx });
135 } else if self.enable_multithreading && use_workers {
136 profile_scope!("spawning process_glyph jobs");
140 let tx = self.glyph_tx.clone();
141 self.workers.spawn(move || {
142 FontContext::begin_rasterize(&font);
143 if FontContext::distribute_across_threads() {
147 glyphs.par_iter().for_each(|key| {
148 let mut context = font_contexts.lock_current_context();
149 let job_font = font.clone();
150 let job = process_glyph(&mut context, can_use_r8_format, job_font, *key);
151 tx.send(job).unwrap();
152 });
153 } else {
154 for key in glyphs {
157 let mut context = font_contexts.lock_current_context();
158 let job_font = font.clone();
159 let job = process_glyph(&mut context, can_use_r8_format, job_font, key);
160 tx.send(job).unwrap();
161 }
162 }
163 FontContext::end_rasterize(&font);
164 });
165 } else {
166 FontContext::begin_rasterize(&font);
167 for key in glyphs {
168 let mut context = font_contexts.lock_current_context();
169 let job_font = font.clone();
170 let job = process_glyph(&mut context, can_use_r8_format, job_font, key);
171 self.glyph_tx.send(job).unwrap();
172 }
173 FontContext::end_rasterize(&font);
174 }
175 }
176
177 pub fn resolve_glyphs<F, G>(
178 &mut self,
179 mut handle: F,
180 profile: &mut G,
181 )
182 where
183 F: FnMut(GlyphRasterJob, bool),
184 G: GlyphRasterizeProfiler,
185 {
186 profile.start_time();
187 let timer_id = Telemetry::start_rasterize_glyphs_time();
188
189 let mut pending_glyph_requests = mem::replace(
191 &mut self.pending_glyph_requests,
192 FastHashMap::default(),
193 );
194 let use_workers = self.pending_glyph_count >= 8;
197 for (font, pending_glyphs) in pending_glyph_requests.drain() {
198 self.flush_glyph_requests(
199 font,
200 pending_glyphs,
201 use_workers,
202 );
203 }
204 self.pending_glyph_requests = pending_glyph_requests;
206 debug_assert_eq!(self.pending_glyph_count, 0);
207 debug_assert!(self.pending_glyph_requests.is_empty());
208
209 if self.glyph_request_count > 0 {
210 profile.set(self.glyph_request_count as f64);
211 self.glyph_request_count = 0;
212 }
213
214 profile_scope!("resolve_glyphs");
215 let mut jobs = {
220 profile_scope!("blocking wait on glyph_rx");
221 self.glyph_rx.iter().take(self.pending_glyph_jobs).collect::<Vec<_>>()
222 };
223 assert_eq!(jobs.len(), self.pending_glyph_jobs, "BUG: Didn't receive all pending glyphs!");
224 self.pending_glyph_jobs = 0;
225
226 jobs.sort_by(|a, b| (*a.font).cmp(&*b.font).then(a.key.cmp(&b.key)));
232
233 for job in jobs {
234 handle(job, self.can_use_r8_format);
235 }
236
237 self.remove_dead_fonts();
240
241 Telemetry::stop_and_accumulate_rasterize_glyphs_time(timer_id);
242 profile.end_time();
243 }
244}
245
246#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd)]
247#[cfg_attr(feature = "capture", derive(Serialize))]
248#[cfg_attr(feature = "replay", derive(Deserialize))]
249pub struct FontTransform {
250 pub scale_x: f32,
251 pub skew_x: f32,
252 pub skew_y: f32,
253 pub scale_y: f32,
254}
255
256impl Eq for FontTransform {}
258impl Ord for FontTransform {
259 fn cmp(&self, other: &Self) -> cmp::Ordering {
260 self.partial_cmp(other).unwrap_or(cmp::Ordering::Equal)
261 }
262}
263impl Hash for FontTransform {
264 fn hash<H: Hasher>(&self, state: &mut H) {
265 self.scale_x.to_bits().hash(state);
267 self.skew_x.to_bits().hash(state);
268 self.skew_y.to_bits().hash(state);
269 self.scale_y.to_bits().hash(state);
270 }
271}
272
273impl FontTransform {
274 const QUANTIZE_SCALE: f32 = 1024.0;
275
276 pub fn new(scale_x: f32, skew_x: f32, skew_y: f32, scale_y: f32) -> Self {
277 FontTransform { scale_x, skew_x, skew_y, scale_y }
278 }
279
280 pub fn identity() -> Self {
281 FontTransform::new(1.0, 0.0, 0.0, 1.0)
282 }
283
284 #[allow(dead_code)]
285 pub fn is_identity(&self) -> bool {
286 *self == FontTransform::identity()
287 }
288
289 pub fn quantize(&self) -> Self {
290 FontTransform::new(
291 (self.scale_x * Self::QUANTIZE_SCALE).round() / Self::QUANTIZE_SCALE,
292 (self.skew_x * Self::QUANTIZE_SCALE).round() / Self::QUANTIZE_SCALE,
293 (self.skew_y * Self::QUANTIZE_SCALE).round() / Self::QUANTIZE_SCALE,
294 (self.scale_y * Self::QUANTIZE_SCALE).round() / Self::QUANTIZE_SCALE,
295 )
296 }
297
298 #[allow(dead_code)]
299 pub fn determinant(&self) -> f64 {
300 self.scale_x as f64 * self.scale_y as f64 - self.skew_y as f64 * self.skew_x as f64
301 }
302
303 #[allow(dead_code)]
304 pub fn compute_scale(&self) -> Option<(f64, f64)> {
305 let det = self.determinant();
306 if det != 0.0 {
307 let x_scale = (self.scale_x as f64).hypot(self.skew_y as f64);
308 let y_scale = det.abs() / x_scale;
309 Some((x_scale, y_scale))
310 } else {
311 None
312 }
313 }
314
315 #[allow(dead_code)]
316 pub fn pre_scale(&self, scale_x: f32, scale_y: f32) -> Self {
317 FontTransform::new(
318 self.scale_x * scale_x,
319 self.skew_x * scale_y,
320 self.skew_y * scale_x,
321 self.scale_y * scale_y,
322 )
323 }
324
325 #[allow(dead_code)]
326 pub fn scale(&self, scale: f32) -> Self { self.pre_scale(scale, scale) }
327
328 #[allow(dead_code)]
329 pub fn invert_scale(&self, x_scale: f64, y_scale: f64) -> Self {
330 self.pre_scale(x_scale.recip() as f32, y_scale.recip() as f32)
331 }
332
333 pub fn synthesize_italics(&self, angle: SyntheticItalics, size: f64, vertical: bool) -> (Self, (f64, f64)) {
334 let skew_factor = angle.to_skew();
335 if vertical {
336 let (tx, ty) = (0.0, -size * 0.5 * skew_factor as f64);
339 (FontTransform::new(
340 self.scale_x + self.skew_x * skew_factor,
341 self.skew_x,
342 self.skew_y + self.scale_y * skew_factor,
343 self.scale_y,
344 ), (self.scale_x as f64 * tx + self.skew_x as f64 * ty,
345 self.skew_y as f64 * tx + self.scale_y as f64 * ty))
346 } else {
347 (FontTransform::new(
348 self.scale_x,
349 self.skew_x - self.scale_x * skew_factor,
350 self.skew_y,
351 self.scale_y - self.skew_y * skew_factor,
352 ), (0.0, 0.0))
353 }
354 }
355
356 pub fn swap_xy(&self) -> Self {
357 FontTransform::new(self.skew_x, self.scale_x, self.scale_y, self.skew_y)
358 }
359
360 pub fn flip_x(&self) -> Self {
361 FontTransform::new(-self.scale_x, self.skew_x, -self.skew_y, self.scale_y)
362 }
363
364 pub fn flip_y(&self) -> Self {
365 FontTransform::new(self.scale_x, -self.skew_x, self.skew_y, -self.scale_y)
366 }
367
368 pub fn transform(&self, point: &LayoutPoint) -> DevicePoint {
369 DevicePoint::new(
370 self.scale_x * point.x + self.skew_x * point.y,
371 self.skew_y * point.x + self.scale_y * point.y,
372 )
373 }
374
375 pub fn get_subpx_dir(&self) -> SubpixelDirection {
376 if self.skew_y.approx_eq(&0.0) {
377 SubpixelDirection::Horizontal
379 } else if self.scale_x.approx_eq(&0.0) {
380 SubpixelDirection::Vertical
382 } else {
383 SubpixelDirection::None
385 }
386 }
387}
388
389impl<'a> From<&'a LayoutToWorldTransform> for FontTransform {
390 fn from(xform: &'a LayoutToWorldTransform) -> Self {
391 FontTransform::new(xform.m11, xform.m21, xform.m12, xform.m22)
392 }
393}
394
395pub const FONT_SIZE_LIMIT: f32 = 320.0;
398
399#[derive(Clone, Debug, Ord, PartialOrd, MallocSizeOf)]
403#[cfg_attr(feature = "capture", derive(Serialize))]
404#[cfg_attr(feature = "replay", derive(Deserialize))]
405pub struct BaseFontInstance {
406 pub instance_key: FontInstanceKey,
408 pub font_key: FontKey,
410 pub size: FontSize,
412 pub options: FontInstanceOptions,
414 #[cfg_attr(any(feature = "capture", feature = "replay"), serde(skip))]
416 pub platform_options: Option<FontInstancePlatformOptions>,
417 pub variations: Vec<FontVariation>,
419}
420
421impl BaseFontInstance {
422 pub fn new(
423 instance_key: FontInstanceKey,
424 font_key: FontKey,
425 size: f32,
426 options: Option<FontInstanceOptions>,
427 platform_options: Option<FontInstancePlatformOptions>,
428 variations: Vec<FontVariation>,
429 ) -> Self {
430 BaseFontInstance {
431 instance_key,
432 font_key,
433 size: size.into(),
434 options: options.unwrap_or_default(),
435 platform_options,
436 variations,
437 }
438 }
439}
440
441impl Deref for BaseFontInstance {
442 type Target = FontInstanceOptions;
443 fn deref(&self) -> &FontInstanceOptions {
444 &self.options
445 }
446}
447
448impl Hash for BaseFontInstance {
449 fn hash<H: Hasher>(&self, state: &mut H) {
450 self.font_key.hash(state);
452 self.size.hash(state);
453 self.options.hash(state);
454 self.platform_options.hash(state);
455 self.variations.hash(state);
456 }
457}
458
459impl PartialEq for BaseFontInstance {
460 fn eq(&self, other: &BaseFontInstance) -> bool {
461 self.font_key == other.font_key &&
463 self.size == other.size &&
464 self.options == other.options &&
465 self.platform_options == other.platform_options &&
466 self.variations == other.variations
467 }
468}
469impl Eq for BaseFontInstance {}
470
471struct MappedFontKey {
472 font_key: FontKey,
473 template: FontTemplate,
474}
475
476struct FontKeyMapLocked {
477 namespace: IdNamespace,
478 next_id: u32,
479 template_map: FastHashMap<FontTemplate, Arc<MappedFontKey>>,
480 key_map: FastHashMap<FontKey, Arc<MappedFontKey>>,
481}
482
483#[derive(Clone)]
493pub struct FontKeyMap(Arc<RwLock<FontKeyMapLocked>>);
494
495impl FontKeyMap {
496 pub fn new(namespace: IdNamespace) -> Self {
497 FontKeyMap(Arc::new(RwLock::new(FontKeyMapLocked {
498 namespace,
499 next_id: 1,
500 template_map: FastHashMap::default(),
501 key_map: FastHashMap::default(),
502 })))
503 }
504
505 fn lock(&self) -> RwLockReadGuard<FontKeyMapLocked> {
506 self.0.read().unwrap()
507 }
508
509 fn lock_mut(&mut self) -> RwLockWriteGuard<FontKeyMapLocked> {
510 self.0.write().unwrap()
511 }
512
513 pub fn keys(&self) -> Vec<FontKey> {
514 self.lock().key_map.keys().cloned().collect()
515 }
516
517 pub fn map_key(&self, font_key: &FontKey) -> FontKey {
518 match self.lock().key_map.get(font_key) {
519 Some(mapped) => mapped.font_key,
520 None => *font_key,
521 }
522 }
523
524 pub fn add_key(&mut self, font_key: &FontKey, template: &FontTemplate) -> Option<FontKey> {
525 let mut locked = self.lock_mut();
526 if locked.key_map.contains_key(font_key) {
527 return None;
528 }
529 if let Some(mapped) = locked.template_map.get(template).cloned() {
530 locked.key_map.insert(*font_key, mapped);
531 return None;
532 }
533 let shared_key = FontKey::new(locked.namespace, locked.next_id);
534 locked.next_id += 1;
535 let mapped = Arc::new(MappedFontKey {
536 font_key: shared_key,
537 template: template.clone(),
538 });
539 locked.template_map.insert(template.clone(), mapped.clone());
540 locked.key_map.insert(*font_key, mapped);
541 Some(shared_key)
542 }
543
544 pub fn delete_key(&mut self, font_key: &FontKey) -> Option<FontKey> {
545 let mut locked = self.lock_mut();
546 let mapped = match locked.key_map.remove(font_key) {
547 Some(mapped) => mapped,
548 None => return Some(*font_key),
549 };
550 if Arc::strong_count(&mapped) <= 2 {
551 locked.template_map.remove(&mapped.template);
553 Some(mapped.font_key)
554 } else {
555 None
556 }
557 }
558
559 pub fn clear_namespace(&mut self, namespace: IdNamespace) -> Vec<FontKey> {
560 let mut locked = self.lock_mut();
561 locked.key_map.retain(|key, _| {
562 if key.0 == namespace {
563 false
564 } else {
565 true
566 }
567 });
568 let mut deleted_keys = Vec::new();
569 locked.template_map.retain(|_, mapped| {
570 if Arc::strong_count(mapped) <= 1 {
571 deleted_keys.push(mapped.font_key);
573 false
574 } else {
575 true
576 }
577 });
578 deleted_keys
579 }
580}
581
582type FontTemplateMapLocked = FastHashMap<FontKey, FontTemplate>;
583
584#[derive(Clone)]
587pub struct FontTemplateMap(Arc<RwLock<FontTemplateMapLocked>>);
588
589impl FontTemplateMap {
590 pub fn new() -> Self {
591 FontTemplateMap(Arc::new(RwLock::new(FastHashMap::default())))
592 }
593
594 pub fn lock(&self) -> RwLockReadGuard<FontTemplateMapLocked> {
595 self.0.read().unwrap()
596 }
597
598 fn lock_mut(&mut self) -> RwLockWriteGuard<FontTemplateMapLocked> {
599 self.0.write().unwrap()
600 }
601
602 pub fn clear(&mut self) {
603 self.lock_mut().clear();
604 }
605
606 pub fn len(&self) -> usize {
607 self.lock().len()
608 }
609
610 pub fn has_font(&self, key: &FontKey) -> bool {
611 self.lock().contains_key(key)
612 }
613
614 pub fn get_font(&self, key: &FontKey) -> Option<FontTemplate> {
615 self.lock().get(key).cloned()
616 }
617
618 pub fn add_font(&mut self, key: FontKey, template: FontTemplate) -> bool {
619 self.lock_mut().insert(key, template).is_none()
620 }
621
622 pub fn delete_font(&mut self, key: &FontKey) -> Option<FontTemplate> {
623 self.lock_mut().remove(key)
624 }
625
626 pub fn delete_fonts(&mut self, keys: &[FontKey]) {
627 if !keys.is_empty() {
628 let mut map = self.lock_mut();
629 for key in keys {
630 map.remove(key);
631 }
632 }
633 }
634
635 pub fn clear_namespace(&mut self, namespace: IdNamespace) -> Vec<FontKey> {
636 let mut deleted_keys = Vec::new();
637 self.lock_mut().retain(|key, _| {
638 if key.0 == namespace {
639 deleted_keys.push(*key);
640 false
641 } else {
642 true
643 }
644 });
645 deleted_keys
646 }
647}
648
649struct FontInstanceKeyMapLocked {
650 namespace: IdNamespace,
651 next_id: u32,
652 instances: FastHashSet<Arc<BaseFontInstance>>,
653 key_map: FastHashMap<FontInstanceKey, Weak<BaseFontInstance>>,
654}
655
656#[derive(Clone)]
666pub struct FontInstanceKeyMap(Arc<RwLock<FontInstanceKeyMapLocked>>);
667
668impl FontInstanceKeyMap {
669 pub fn new(namespace: IdNamespace) -> Self {
670 FontInstanceKeyMap(Arc::new(RwLock::new(FontInstanceKeyMapLocked {
671 namespace,
672 next_id: 1,
673 instances: FastHashSet::default(),
674 key_map: FastHashMap::default(),
675 })))
676 }
677
678 fn lock(&self) -> RwLockReadGuard<FontInstanceKeyMapLocked> {
679 self.0.read().unwrap()
680 }
681
682 fn lock_mut(&mut self) -> RwLockWriteGuard<FontInstanceKeyMapLocked> {
683 self.0.write().unwrap()
684 }
685
686 pub fn keys(&self) -> Vec<FontInstanceKey> {
687 self.lock().key_map.keys().cloned().collect()
688 }
689
690 pub fn map_key(&self, key: &FontInstanceKey) -> FontInstanceKey {
691 match self.lock().key_map.get(key).and_then(|weak| weak.upgrade()) {
692 Some(mapped) => mapped.instance_key,
693 None => *key,
694 }
695 }
696
697 pub fn add_key(&mut self, mut instance: BaseFontInstance) -> Option<Arc<BaseFontInstance>> {
698 let mut locked = self.lock_mut();
699 if locked.key_map.contains_key(&instance.instance_key) {
700 return None;
701 }
702 if let Some(weak) = locked.instances.get(&instance).map(|mapped| Arc::downgrade(mapped)) {
703 locked.key_map.insert(instance.instance_key, weak);
704 return None;
705 }
706 let unmapped_key = instance.instance_key;
707 instance.instance_key = FontInstanceKey::new(locked.namespace, locked.next_id);
708 locked.next_id += 1;
709 let shared_instance = Arc::new(instance);
710 locked.instances.insert(shared_instance.clone());
711 locked.key_map.insert(unmapped_key, Arc::downgrade(&shared_instance));
712 Some(shared_instance)
713 }
714
715 pub fn delete_key(&mut self, key: &FontInstanceKey) -> Option<FontInstanceKey> {
716 let mut locked = self.lock_mut();
717 let mapped = match locked.key_map.remove(key).and_then(|weak| weak.upgrade()) {
718 Some(mapped) => mapped,
719 None => return Some(*key),
720 };
721 if Arc::weak_count(&mapped) == 0 {
722 locked.instances.remove(&mapped);
724 Some(mapped.instance_key)
725 } else {
726 None
727 }
728 }
729
730 pub fn clear_namespace(&mut self, namespace: IdNamespace) -> Vec<FontInstanceKey> {
731 let mut locked = self.lock_mut();
732 locked.key_map.retain(|key, _| {
733 if key.0 == namespace {
734 false
735 } else {
736 true
737 }
738 });
739 let mut deleted_keys = Vec::new();
740 locked.instances.retain(|mapped| {
741 if Arc::weak_count(mapped) == 0 {
742 deleted_keys.push(mapped.instance_key);
744 false
745 } else {
746 true
747 }
748 });
749 deleted_keys
750 }
751}
752
753type FontInstanceMapLocked = FastHashMap<FontInstanceKey, Arc<BaseFontInstance>>;
754
755#[derive(Clone)]
757pub struct FontInstanceMap(Arc<RwLock<FontInstanceMapLocked>>);
758
759impl FontInstanceMap {
760 pub fn new() -> Self {
762 FontInstanceMap(Arc::new(RwLock::new(FastHashMap::default())))
763 }
764
765 pub fn lock(&self) -> RwLockReadGuard<FontInstanceMapLocked> {
767 self.0.read().unwrap()
768 }
769
770 fn lock_mut(&mut self) -> RwLockWriteGuard<FontInstanceMapLocked> {
772 self.0.write().unwrap()
773 }
774
775 pub fn clear(&mut self) {
777 self.lock_mut().clear();
778 }
779
780 pub fn get_font_instance_data(&self, key: FontInstanceKey) -> Option<FontInstanceData> {
782 match self.lock().get(&key) {
783 Some(instance) => Some(FontInstanceData {
784 font_key: instance.font_key,
785 size: instance.size.into(),
786 options: Some(FontInstanceOptions {
787 render_mode: instance.render_mode,
788 flags: instance.flags,
789 synthetic_italics: instance.synthetic_italics,
790 _padding: 0,
791 }),
792 platform_options: instance.platform_options,
793 variations: instance.variations.clone(),
794 }),
795 None => None,
796 }
797 }
798
799 pub fn get_font_instance(&self, instance_key: FontInstanceKey) -> Option<Arc<BaseFontInstance>> {
801 let instance_map = self.lock();
802 instance_map.get(&instance_key).cloned()
803 }
804
805 pub fn add_font_instance(&mut self, instance: Arc<BaseFontInstance>) {
807 self.lock_mut().insert(instance.instance_key, instance);
808 }
809
810 pub fn delete_font_instance(&mut self, instance_key: FontInstanceKey) {
812 self.lock_mut().remove(&instance_key);
813 }
814
815 pub fn delete_font_instances(&mut self, keys: &[FontInstanceKey]) {
817 if !keys.is_empty() {
818 let mut map = self.lock_mut();
819 for key in keys {
820 map.remove(key);
821 }
822 }
823 }
824
825 pub fn clear_namespace(&mut self, namespace: IdNamespace) {
827 self.lock_mut().retain(|key, _| key.0 != namespace);
828 }
829}
830
831#[derive(Clone)]
835pub struct SharedFontResources {
836 pub templates: FontTemplateMap,
837 pub instances: FontInstanceMap,
838 pub font_keys: FontKeyMap,
839 pub instance_keys: FontInstanceKeyMap,
840}
841
842impl SharedFontResources {
843 pub fn new(namespace: IdNamespace) -> Self {
844 SharedFontResources {
845 templates: FontTemplateMap::new(),
846 instances: FontInstanceMap::new(),
847 font_keys: FontKeyMap::new(namespace),
848 instance_keys: FontInstanceKeyMap::new(namespace),
849 }
850 }
851}
852
853impl BlobImageResources for SharedFontResources {
854 fn get_font_data(&self, key: FontKey) -> Option<FontTemplate> {
855 let shared_key = self.font_keys.map_key(&key);
856 self.templates.get_font(&shared_key)
857 }
858
859 fn get_font_instance_data(&self, key: FontInstanceKey) -> Option<FontInstanceData> {
860 let shared_key = self.instance_keys.map_key(&key);
861 self.instances.get_font_instance_data(shared_key)
862 }
863}
864
865#[derive(Clone, Debug, Ord, PartialOrd)]
870#[cfg_attr(feature = "capture", derive(Serialize))]
871#[cfg_attr(feature = "replay", derive(Deserialize))]
872pub struct FontInstance {
873 pub base: Arc<BaseFontInstance>,
874 pub transform: FontTransform,
875 pub render_mode: FontRenderMode,
876 pub flags: FontInstanceFlags,
877 pub color: ColorU,
878 pub size: FontSize,
881}
882
883impl Hash for FontInstance {
884 fn hash<H: Hasher>(&self, state: &mut H) {
885 self.base.instance_key.hash(state);
888 self.transform.hash(state);
889 self.render_mode.hash(state);
890 self.flags.hash(state);
891 self.color.hash(state);
892 self.size.hash(state);
893 }
894}
895
896impl PartialEq for FontInstance {
897 fn eq(&self, other: &FontInstance) -> bool {
898 self.base.instance_key == other.base.instance_key &&
900 self.transform == other.transform &&
901 self.render_mode == other.render_mode &&
902 self.flags == other.flags &&
903 self.color == other.color &&
904 self.size == other.size
905 }
906}
907impl Eq for FontInstance {}
908
909impl Deref for FontInstance {
910 type Target = BaseFontInstance;
911 fn deref(&self) -> &BaseFontInstance {
912 self.base.as_ref()
913 }
914}
915
916impl MallocSizeOf for FontInstance {
917 fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize { 0 }
918}
919
920impl FontInstance {
921 pub fn new(
922 base: Arc<BaseFontInstance>,
923 color: ColorU,
924 render_mode: FontRenderMode,
925 flags: FontInstanceFlags,
926 ) -> Self {
927 FontInstance {
928 transform: FontTransform::identity(),
929 color,
930 size: base.size,
931 base,
932 render_mode,
933 flags,
934 }
935 }
936
937 pub fn from_base(
938 base: Arc<BaseFontInstance>,
939 ) -> Self {
940 let color = ColorU::new(0, 0, 0, 255);
941 let render_mode = base.render_mode;
942 let flags = base.flags;
943 Self::new(base, color, render_mode, flags)
944 }
945
946 pub fn use_texture_padding(&self) -> bool {
947 self.flags.contains(FontInstanceFlags::TEXTURE_PADDING)
948 }
949
950 pub fn use_transform_glyphs(&self) -> bool {
951 self.flags.contains(FontInstanceFlags::TRANSFORM_GLYPHS)
952 }
953
954 pub fn get_alpha_glyph_format(&self) -> GlyphFormat {
955 if self.use_transform_glyphs() { GlyphFormat::TransformedAlpha } else { GlyphFormat::Alpha }
956 }
957
958 pub fn get_subpixel_glyph_format(&self) -> GlyphFormat {
959 if self.use_transform_glyphs() { GlyphFormat::TransformedSubpixel } else { GlyphFormat::Subpixel }
960 }
961
962 pub fn disable_subpixel_aa(&mut self) {
963 self.render_mode = self.render_mode.limit_by(FontRenderMode::Alpha);
964 }
965
966 pub fn disable_subpixel_position(&mut self) {
967 self.flags.remove(FontInstanceFlags::SUBPIXEL_POSITION);
968 }
969
970 pub fn use_subpixel_position(&self) -> bool {
971 self.flags.contains(FontInstanceFlags::SUBPIXEL_POSITION) &&
972 self.render_mode != FontRenderMode::Mono
973 }
974
975 pub fn get_subpx_dir(&self) -> SubpixelDirection {
976 if self.use_subpixel_position() {
977 let mut subpx_dir = self.transform.get_subpx_dir();
978 if self.flags.contains(FontInstanceFlags::TRANSPOSE) {
979 subpx_dir = subpx_dir.swap_xy();
980 }
981 subpx_dir
982 } else {
983 SubpixelDirection::None
984 }
985 }
986
987 #[allow(dead_code)]
988 pub fn get_subpx_offset(&self, glyph: &GlyphKey) -> (f64, f64) {
989 if self.use_subpixel_position() {
990 let (dx, dy) = glyph.subpixel_offset();
991 (dx.into(), dy.into())
992 } else {
993 (0.0, 0.0)
994 }
995 }
996
997 #[allow(dead_code)]
998 pub fn get_glyph_format(&self) -> GlyphFormat {
999 match self.render_mode {
1000 FontRenderMode::Mono | FontRenderMode::Alpha => self.get_alpha_glyph_format(),
1001 FontRenderMode::Subpixel => self.get_subpixel_glyph_format(),
1002 }
1003 }
1004
1005 #[allow(dead_code)]
1006 pub fn get_extra_strikes(&self, flags: FontInstanceFlags, x_scale: f64) -> usize {
1007 if self.flags.intersects(flags) {
1008 let mut bold_offset = self.size.to_f64_px() / 48.0;
1009 if bold_offset < 1.0 {
1010 bold_offset = 0.25 + 0.75 * bold_offset;
1011 }
1012 (bold_offset * x_scale).max(1.0).round() as usize
1013 } else {
1014 0
1015 }
1016 }
1017
1018 pub fn synthesize_italics(&self, transform: FontTransform, size: f64) -> (FontTransform, (f64, f64)) {
1019 transform.synthesize_italics(self.synthetic_italics, size, self.flags.contains(FontInstanceFlags::VERTICAL))
1020 }
1021
1022 #[allow(dead_code)]
1023 pub fn get_transformed_size(&self) -> f64 {
1024 let (_, y_scale) = self.transform.compute_scale().unwrap_or((1.0, 1.0));
1025 self.size.to_f64_px() * y_scale
1026 }
1027}
1028
1029#[repr(u32)]
1030#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug, Ord, PartialOrd)]
1031pub enum SubpixelDirection {
1032 None = 0,
1033 Horizontal,
1034 Vertical,
1035}
1036
1037impl SubpixelDirection {
1038 pub fn limit_by(self, glyph_format: GlyphFormat) -> Self {
1040 match glyph_format {
1041 GlyphFormat::Bitmap |
1042 GlyphFormat::ColorBitmap => SubpixelDirection::None,
1043 _ => self,
1044 }
1045 }
1046
1047 pub fn swap_xy(self) -> Self {
1048 match self {
1049 SubpixelDirection::None => self,
1050 SubpixelDirection::Horizontal => SubpixelDirection::Vertical,
1051 SubpixelDirection::Vertical => SubpixelDirection::Horizontal,
1052 }
1053 }
1054}
1055
1056#[repr(u8)]
1057#[derive(Hash, Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
1058#[cfg_attr(feature = "capture", derive(Serialize))]
1059#[cfg_attr(feature = "replay", derive(Deserialize))]
1060pub enum SubpixelOffset {
1061 Zero = 0,
1062 Quarter = 1,
1063 Half = 2,
1064 ThreeQuarters = 3,
1065}
1066
1067impl SubpixelOffset {
1068 fn quantize(pos: f32) -> Self {
1071 let apos = ((pos - pos.floor()) * 8.0) as i32;
1080
1081 match apos {
1082 1..=2 => SubpixelOffset::Quarter,
1083 3..=4 => SubpixelOffset::Half,
1084 5..=6 => SubpixelOffset::ThreeQuarters,
1085 _ => SubpixelOffset::Zero,
1086 }
1087 }
1088}
1089
1090impl Into<f64> for SubpixelOffset {
1091 fn into(self) -> f64 {
1092 match self {
1093 SubpixelOffset::Zero => 0.0,
1094 SubpixelOffset::Quarter => 0.25,
1095 SubpixelOffset::Half => 0.5,
1096 SubpixelOffset::ThreeQuarters => 0.75,
1097 }
1098 }
1099}
1100
1101impl SubpixelOffset {
1102 fn to_f32(self) -> f32 {
1103 match self {
1104 SubpixelOffset::Zero => 0.0,
1105 SubpixelOffset::Quarter => 0.25,
1106 SubpixelOffset::Half => 0.5,
1107 SubpixelOffset::ThreeQuarters => 0.75,
1108 }
1109 }
1110}
1111
1112#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug, Ord, PartialOrd)]
1113#[cfg_attr(feature = "capture", derive(Serialize))]
1114#[cfg_attr(feature = "replay", derive(Deserialize))]
1115pub struct GlyphKey(u32);
1116
1117#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug, Ord, PartialOrd)]
1118#[cfg_attr(feature = "capture", derive(Serialize))]
1119#[cfg_attr(feature = "replay", derive(Deserialize))]
1120pub struct GlyphCacheKey(u32);
1121
1122impl GlyphKey {
1123 pub fn new(
1124 index: u32,
1125 point: DevicePoint,
1126 subpx_dir: SubpixelDirection,
1127 ) -> Self {
1128 let (dx, dy) = match subpx_dir {
1129 SubpixelDirection::None => (0.0, 0.0),
1130 SubpixelDirection::Horizontal => (point.x, 0.0),
1131 SubpixelDirection::Vertical => (0.0, point.y),
1132 };
1133 let sox = SubpixelOffset::quantize(dx);
1134 let soy = SubpixelOffset::quantize(dy);
1135 assert_eq!(0, index & 0xFC000000);
1136
1137 GlyphKey(index | (sox as u32) << 26 | (soy as u32) << 28 | (subpx_dir as u32) << 30)
1138 }
1139
1140 pub fn index(&self) -> GlyphIndex {
1141 self.0 & 0x03FFFFFF
1142 }
1143
1144 pub fn subpixel_offset(&self) -> (SubpixelOffset, SubpixelOffset) {
1145 let x = (self.0 >> 26) as u8 & 3;
1146 let y = (self.0 >> 28) as u8 & 3;
1147 unsafe {
1148 (mem::transmute(x), mem::transmute(y))
1149 }
1150 }
1151
1152 pub fn subpixel_dir(&self) -> SubpixelDirection {
1153 let dir = (self.0 >> 30) as u8 & 3;
1154 unsafe {
1155 mem::transmute(dir as u32)
1156 }
1157 }
1158
1159 pub fn cache_key(&self) -> GlyphCacheKey {
1160 let index = self.index();
1161 let subpx_dir = self.subpixel_dir();
1162 assert_eq!(0, index & 0xFC000000);
1163 GlyphCacheKey(index | (subpx_dir as u32) << 30)
1164 }
1165}
1166
1167impl GlyphCacheKey {
1168 pub fn index(&self) -> GlyphIndex {
1169 self.0 & 0x03FFFFFF
1170 }
1171
1172 pub fn subpixel_dir(&self) -> SubpixelDirection {
1173 let dir = ((self.0 >> 30) & 3) as u32;
1174 unsafe {
1175 mem::transmute(dir)
1176 }
1177 }
1178}
1179
1180#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
1181#[cfg_attr(feature = "capture", derive(Serialize))]
1182#[cfg_attr(feature = "replay", derive(Deserialize))]
1183#[allow(dead_code)]
1184pub enum GlyphFormat {
1185 Alpha,
1186 TransformedAlpha,
1187 Subpixel,
1188 TransformedSubpixel,
1189 Bitmap,
1190 ColorBitmap,
1191}
1192
1193impl GlyphFormat {
1194 pub fn image_format(&self, can_use_r8_format: bool) -> ImageFormat {
1198 match *self {
1199 GlyphFormat::Alpha |
1200 GlyphFormat::TransformedAlpha |
1201 GlyphFormat::Bitmap => {
1202 if can_use_r8_format {
1203 ImageFormat::R8
1204 } else {
1205 ImageFormat::BGRA8
1206 }
1207 }
1208 GlyphFormat::Subpixel |
1209 GlyphFormat::TransformedSubpixel |
1210 GlyphFormat::ColorBitmap => ImageFormat::BGRA8,
1211 }
1212 }
1213}
1214
1215#[allow(dead_code)]
1216#[inline]
1217fn blend_strike_pixel(dest: u8, src: u32, src_alpha: u32) -> u8 {
1218 let x = src * 255 + dest as u32 * (255 - src_alpha) + 128;
1223 ((x + (x >> 8)) >> 8) as u8
1224}
1225
1226#[allow(dead_code)]
1230fn blend_strike(
1231 dest_bitmap: &mut [u8],
1232 src_bitmap: &[u8],
1233 width: usize,
1234 height: usize,
1235 subpixel_mask: bool,
1236 offset: f64,
1237) {
1238 let dest_stride = dest_bitmap.len() / height;
1239 let src_stride = width * 4;
1240 let offset_integer = offset.floor() as usize * 4;
1241 let offset_fract = (offset.fract() * 256.0) as u32;
1242 for (src_row, dest_row) in src_bitmap.chunks(src_stride).zip(dest_bitmap.chunks_mut(dest_stride)) {
1243 let mut prev_px = [0u32; 4];
1244 let dest_row_offset = &mut dest_row[offset_integer .. offset_integer + src_stride];
1245 for (src, dest) in src_row.chunks(4).zip(dest_row_offset.chunks_mut(4)) {
1246 let px = [src[0] as u32, src[1] as u32, src[2] as u32, src[3] as u32];
1247 let next_px = [px[0] * offset_fract,
1249 px[1] * offset_fract,
1250 px[2] * offset_fract,
1251 px[3] * offset_fract];
1252 let offset_px = [(((px[0] << 8) - next_px[0]) + prev_px[0] + 128) >> 8,
1253 (((px[1] << 8) - next_px[1]) + prev_px[1] + 128) >> 8,
1254 (((px[2] << 8) - next_px[2]) + prev_px[2] + 128) >> 8,
1255 (((px[3] << 8) - next_px[3]) + prev_px[3] + 128) >> 8];
1256 if subpixel_mask {
1257 dest[0] = blend_strike_pixel(dest[0], offset_px[0], offset_px[0]);
1259 dest[1] = blend_strike_pixel(dest[1], offset_px[1], offset_px[1]);
1260 dest[2] = blend_strike_pixel(dest[2], offset_px[2], offset_px[2]);
1261 dest[3] = blend_strike_pixel(dest[3], offset_px[3], offset_px[3]);
1262 } else {
1263 dest[0] = blend_strike_pixel(dest[0], offset_px[0], offset_px[3]);
1265 dest[1] = blend_strike_pixel(dest[1], offset_px[1], offset_px[3]);
1266 dest[2] = blend_strike_pixel(dest[2], offset_px[2], offset_px[3]);
1267 dest[3] = blend_strike_pixel(dest[3], offset_px[3], offset_px[3]);
1268 }
1269 prev_px = next_px;
1271 }
1272 if offset_fract > 0 {
1273 let dest = &mut dest_row[offset_integer + src_stride .. ];
1276 let offset_px = [(prev_px[0] + 128) >> 8,
1277 (prev_px[1] + 128) >> 8,
1278 (prev_px[2] + 128) >> 8,
1279 (prev_px[3] + 128) >> 8];
1280 if subpixel_mask {
1281 dest[0] = blend_strike_pixel(dest[0], offset_px[0], offset_px[0]);
1282 dest[1] = blend_strike_pixel(dest[1], offset_px[1], offset_px[1]);
1283 dest[2] = blend_strike_pixel(dest[2], offset_px[2], offset_px[2]);
1284 dest[3] = blend_strike_pixel(dest[3], offset_px[3], offset_px[3]);
1285 } else {
1286 dest[0] = blend_strike_pixel(dest[0], offset_px[0], offset_px[3]);
1287 dest[1] = blend_strike_pixel(dest[1], offset_px[1], offset_px[3]);
1288 dest[2] = blend_strike_pixel(dest[2], offset_px[2], offset_px[3]);
1289 dest[3] = blend_strike_pixel(dest[3], offset_px[3], offset_px[3]);
1290 }
1291 }
1292 }
1293}
1294
1295#[allow(dead_code)]
1301pub fn apply_multistrike_bold(
1302 src_bitmap: &[u8],
1303 width: usize,
1304 height: usize,
1305 subpixel_mask: bool,
1306 extra_strikes: usize,
1307 pixel_step: f64,
1308) -> (Vec<u8>, usize) {
1309 let src_stride = width * 4;
1310 let extra_width = (extra_strikes as f64 * pixel_step).ceil() as usize;
1312 let dest_width = width + extra_width;
1313 let dest_stride = dest_width * 4;
1314 let mut dest_bitmap = vec![0u8; dest_stride * height];
1316 for (src_row, dest_row) in src_bitmap.chunks(src_stride).zip(dest_bitmap.chunks_mut(dest_stride)) {
1317 dest_row[0 .. src_stride].copy_from_slice(src_row);
1319 }
1320 for i in 1 ..= extra_strikes {
1322 let offset = i as f64 * pixel_step;
1323 blend_strike(&mut dest_bitmap, src_bitmap, width, height, subpixel_mask, offset);
1324 }
1325 (dest_bitmap, dest_width)
1326}
1327
1328pub struct RasterizedGlyph {
1329 pub top: f32,
1330 pub left: f32,
1331 pub width: i32,
1332 pub height: i32,
1333 pub scale: f32,
1334 pub format: GlyphFormat,
1335 pub bytes: Vec<u8>,
1336 pub is_packed_glyph: bool,
1337}
1338
1339impl RasterizedGlyph {
1340 #[allow(dead_code)]
1341 pub fn downscale_bitmap_if_required(&mut self, font: &FontInstance) {
1342 match self.format {
1350 GlyphFormat::Bitmap | GlyphFormat::ColorBitmap => {},
1351 _ => return,
1352 }
1353 let (x_scale, y_scale) = font.transform.compute_scale().unwrap_or((1.0, 1.0));
1354 let upscaled = x_scale.max(y_scale) as f32;
1355 let mut new_scale = self.scale;
1356 if new_scale * upscaled <= 0.0 {
1357 return;
1358 }
1359 let mut steps = 0;
1360 while new_scale * upscaled <= 0.5 {
1361 new_scale *= 2.0;
1362 steps += 1;
1363 }
1364 if steps == 0 {
1366 return;
1367 }
1368
1369 let new_width = (self.width as usize + (1 << steps) - 1) >> steps;
1371 let new_height = (self.height as usize + (1 << steps) - 1) >> steps;
1372 let mut new_bytes: Vec<u8> = Vec::with_capacity(new_width * new_height * 4);
1373
1374 for y in 0 .. new_height {
1377 for x in 0 .. new_width {
1378 let src_y = y << steps;
1380 let src_x = x << steps;
1381 let y_samples = (1 << steps).min(self.height as usize - src_y);
1382 let x_samples = (1 << steps).min(self.width as usize - src_x);
1383 let num_samples = (x_samples * y_samples) as u32;
1384
1385 let mut src_idx = (src_y * self.width as usize + src_x) * 4;
1386 let mut accum = [num_samples / 2; 4];
1390 for _ in 0 .. y_samples {
1392 for _ in 0 .. x_samples {
1393 accum[0] += self.bytes[src_idx + 0] as u32;
1394 accum[1] += self.bytes[src_idx + 1] as u32;
1395 accum[2] += self.bytes[src_idx + 2] as u32;
1396 accum[3] += self.bytes[src_idx + 3] as u32;
1397 src_idx += 4;
1398 }
1399 src_idx += (self.width as usize - x_samples) * 4;
1400 }
1401
1402 new_bytes.extend_from_slice(&[
1404 (accum[0] / num_samples) as u8,
1405 (accum[1] / num_samples) as u8,
1406 (accum[2] / num_samples) as u8,
1407 (accum[3] / num_samples) as u8,
1408 ]);
1409 }
1410 }
1411
1412 self.top /= (1 << steps) as f32;
1414 self.left /= (1 << steps) as f32;
1415 self.width = new_width as i32;
1416 self.height = new_height as i32;
1417 self.scale = new_scale;
1418 self.bytes = new_bytes;
1419 }
1420}
1421
1422pub struct FontContexts {
1423 worker_contexts: Vec<Mutex<FontContext>>,
1426 #[allow(dead_code)]
1428 workers: Arc<ThreadPool>,
1429 locked_mutex: Mutex<bool>,
1430 locked_cond: Condvar,
1431}
1432
1433impl FontContexts {
1434 pub fn lock_context(&self, id: usize) -> MutexGuard<FontContext> {
1439 self.worker_contexts[id].lock().unwrap()
1440 }
1441
1442 pub fn lock_any_context(&self) -> MutexGuard<FontContext> {
1445 for context in &self.worker_contexts {
1446 if let Ok(mutex) = context.try_lock() {
1447 return mutex;
1448 }
1449 }
1450 self.lock_context(0)
1451 }
1452
1453 pub fn num_worker_contexts(&self) -> usize {
1455 self.worker_contexts.len()
1456 }
1457}
1458
1459pub trait AsyncForEach<T> {
1460 fn async_for_each<F: Fn(MutexGuard<T>) + Send + 'static>(&self, f: F);
1461}
1462
1463impl AsyncForEach<FontContext> for Arc<FontContexts> {
1464 fn async_for_each<F: Fn(MutexGuard<FontContext>) + Send + 'static>(&self, f: F) {
1465 let mut locked = self.locked_mutex.lock().unwrap();
1467 *locked = false;
1468
1469 let font_contexts = self.clone();
1471 self.workers.spawn(move || {
1473 let mut locks = Vec::with_capacity(font_contexts.num_worker_contexts());
1475 for i in 0 .. font_contexts.num_worker_contexts() {
1476 locks.push(font_contexts.lock_context(i));
1477 }
1478
1479 *font_contexts.locked_mutex.lock().unwrap() = true;
1481 font_contexts.locked_cond.notify_all();
1482
1483 for context in locks {
1485 f(context);
1486 }
1487 });
1488
1489 while !*locked {
1493 locked = self.locked_cond.wait(locked).unwrap();
1494 }
1495 }
1496}
1497
1498pub struct GlyphRasterizer {
1499 #[allow(dead_code)]
1500 workers: Arc<ThreadPool>,
1501 font_contexts: Arc<FontContexts>,
1502 dedicated_thread: Option<GlyphRasterThread>,
1503
1504 fonts: FastHashSet<FontKey>,
1506
1507 pending_glyph_count: usize,
1509
1510 pending_glyph_jobs: usize,
1512
1513 glyph_request_count: usize,
1515
1516 pending_glyph_requests: FastHashMap<FontInstance, SmallVec<[GlyphKey; 16]>>,
1518
1519 glyph_rx: Receiver<GlyphRasterJob>,
1521 glyph_tx: Sender<GlyphRasterJob>,
1522
1523 fonts_to_remove: Vec<FontKey>,
1528 font_instances_to_remove: Vec<FontInstance>,
1530
1531 enable_multithreading: bool,
1533
1534 can_use_r8_format: bool,
1536}
1537
1538impl GlyphRasterizer {
1539 pub fn new(workers: Arc<ThreadPool>, dedicated_thread: Option<GlyphRasterThread>, can_use_r8_format: bool) -> Self {
1540 let (glyph_tx, glyph_rx) = unbounded();
1541
1542 let num_workers = workers.current_num_threads();
1543 let mut contexts = Vec::with_capacity(num_workers);
1544
1545 for _ in 0 .. num_workers {
1546 contexts.push(Mutex::new(FontContext::new()));
1547 }
1548
1549 let font_context = FontContexts {
1550 worker_contexts: contexts,
1551 workers: Arc::clone(&workers),
1552 locked_mutex: Mutex::new(false),
1553 locked_cond: Condvar::new(),
1554 };
1555
1556 GlyphRasterizer {
1557 font_contexts: Arc::new(font_context),
1558 fonts: FastHashSet::default(),
1559 dedicated_thread,
1560 pending_glyph_jobs: 0,
1561 pending_glyph_count: 0,
1562 glyph_request_count: 0,
1563 glyph_rx,
1564 glyph_tx,
1565 workers,
1566 fonts_to_remove: Vec::new(),
1567 font_instances_to_remove: Vec::new(),
1568 enable_multithreading: true,
1569 pending_glyph_requests: FastHashMap::default(),
1570 can_use_r8_format,
1571 }
1572 }
1573
1574 pub fn add_font(&mut self, font_key: FontKey, template: FontTemplate) {
1575 if self.fonts.insert(font_key.clone()) {
1577 if let Some(thread) = &self.dedicated_thread {
1578 let _ = thread.tx.send(GlyphRasterMsg::AddFont { font_key, template });
1579 } else {
1580 self.font_contexts.async_for_each(move |mut context| {
1581 context.add_font(&font_key, &template);
1582 });
1583 }
1584 }
1585 }
1586
1587 pub fn delete_font(&mut self, font_key: FontKey) {
1588 self.fonts_to_remove.push(font_key);
1589 }
1590
1591 pub fn delete_fonts(&mut self, font_keys: &[FontKey]) {
1592 self.fonts_to_remove.extend_from_slice(font_keys);
1593 }
1594
1595 pub fn delete_font_instance(&mut self, instance: &FontInstance) {
1596 self.font_instances_to_remove.push(instance.clone());
1597 }
1598
1599 pub fn prepare_font(&self, font: &mut FontInstance) {
1600 FontContext::prepare_font(font);
1601
1602 font.transform = font.transform.quantize();
1608 }
1609
1610 pub fn has_font(&self, font_key: FontKey) -> bool {
1611 self.fonts.contains(&font_key)
1612 }
1613
1614 pub fn get_glyph_dimensions(
1615 &mut self,
1616 font: &FontInstance,
1617 glyph_index: GlyphIndex,
1618 ) -> Option<GlyphDimensions> {
1619 let glyph_key = GlyphKey::new(
1620 glyph_index,
1621 DevicePoint::zero(),
1622 SubpixelDirection::None,
1623 );
1624
1625 self.font_contexts
1626 .lock_any_context()
1627 .get_glyph_dimensions(font, &glyph_key)
1628 }
1629
1630 pub fn get_glyph_index(&mut self, font_key: FontKey, ch: char) -> Option<u32> {
1631 self.font_contexts
1632 .lock_any_context()
1633 .get_glyph_index(font_key, ch)
1634 }
1635
1636 fn remove_dead_fonts(&mut self) {
1637 if self.fonts_to_remove.is_empty() && self.font_instances_to_remove.is_empty() {
1638 return
1639 }
1640
1641 profile_scope!("remove_dead_fonts");
1642 let mut fonts_to_remove = mem::replace(& mut self.fonts_to_remove, Vec::new());
1643 fonts_to_remove.retain(|font| self.fonts.remove(font));
1645 let font_instances_to_remove = mem::replace(& mut self.font_instances_to_remove, Vec::new());
1646 if let Some(thread) = &self.dedicated_thread {
1647 for font_key in fonts_to_remove {
1648 let _ = thread.tx.send(GlyphRasterMsg::DeleteFont { font_key });
1649 }
1650 for instance in font_instances_to_remove {
1651 let _ = thread.tx.send(GlyphRasterMsg::DeleteFontInstance { instance });
1652 }
1653 } else {
1654 self.font_contexts.async_for_each(move |mut context| {
1655 for font_key in &fonts_to_remove {
1656 context.delete_font(font_key);
1657 }
1658 for instance in &font_instances_to_remove {
1659 context.delete_font_instance(instance);
1660 }
1661 });
1662 }
1663 }
1664
1665 #[cfg(feature = "replay")]
1666 pub fn reset(&mut self) {
1667 self.pending_glyph_jobs = 0;
1669 self.pending_glyph_count = 0;
1670 self.glyph_request_count = 0;
1671 self.fonts_to_remove.clear();
1672 self.font_instances_to_remove.clear();
1673 }
1674}
1675
1676trait AddFont {
1677 fn add_font(&mut self, font_key: &FontKey, template: &FontTemplate);
1678}
1679
1680impl AddFont for FontContext {
1681 fn add_font(&mut self, font_key: &FontKey, template: &FontTemplate) {
1682 match *template {
1683 FontTemplate::Raw(ref bytes, index) => {
1684 self.add_raw_font(font_key, bytes.clone(), index);
1685 }
1686 FontTemplate::Native(ref native_font_handle) => {
1687 self.add_native_font(font_key, (*native_font_handle).clone());
1688 }
1689 }
1690 }
1691}
1692
1693#[allow(dead_code)]
1694pub struct GlyphRasterJob {
1695 pub font: Arc<FontInstance>,
1696 pub key: GlyphKey,
1697 pub result: GlyphRasterResult,
1698}
1699
1700#[allow(dead_code)]
1701#[derive(Debug)]
1702pub enum GlyphRasterError {
1703 LoadFailed,
1704}
1705
1706#[allow(dead_code)]
1707pub type GlyphRasterResult = Result<RasterizedGlyph, GlyphRasterError>;
1708
1709#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq)]
1710#[cfg_attr(feature = "capture", derive(Serialize))]
1711#[cfg_attr(feature = "replay", derive(Deserialize))]
1712pub struct GpuGlyphCacheKey(pub u32);
1713
1714fn pack_glyph_variants_horizontal(variants: &[RasterizedGlyph]) -> RasterizedGlyph {
1715 let min_left = variants.iter().map(|v| v.left.floor()).fold(f32::INFINITY, f32::min);
1719 let max_top = variants.iter().map(|v| v.top.floor()).fold(f32::NEG_INFINITY, f32::max);
1720
1721 let slot_width = variants.iter()
1723 .map(|v| v.width + (v.left.floor() - min_left) as i32)
1724 .max().unwrap();
1725
1726 let slot_height = variants.iter()
1728 .map(|v| v.height + (max_top - v.top.floor()) as i32)
1729 .max().unwrap();
1730
1731 let packed_width = slot_width * 4;
1732 let bpp = 4;
1733
1734 let mut packed_bytes = vec![0u8; (packed_width * slot_height * bpp) as usize];
1735
1736 for (variant_idx, variant) in variants.iter().enumerate() {
1737 let left_pad = (variant.left.floor() - min_left) as i32;
1739 let top_pad = (max_top - variant.top.floor()) as i32;
1740 let slot_x = variant_idx as i32 * slot_width;
1741
1742 for src_y in 0..variant.height {
1743 let dst_y = src_y + top_pad;
1744 if dst_y >= slot_height {
1745 break;
1746 }
1747
1748 let dst_x = slot_x + left_pad;
1749 if dst_x < 0 {
1750 continue;
1751 }
1752
1753 let src_row_start = (src_y * variant.width * bpp) as usize;
1754 let src_row_end = src_row_start + (variant.width * bpp) as usize;
1755 let dst_row_start = (dst_y * packed_width * bpp + dst_x * bpp) as usize;
1756 let dst_row_end = dst_row_start + (variant.width * bpp) as usize;
1757
1758 if dst_row_end <= packed_bytes.len() && src_row_end <= variant.bytes.len() {
1759 packed_bytes[dst_row_start..dst_row_end]
1760 .copy_from_slice(&variant.bytes[src_row_start..src_row_end]);
1761 }
1762 }
1763 }
1764
1765 RasterizedGlyph {
1766 top: max_top,
1767 left: min_left,
1768 width: packed_width,
1769 height: slot_height,
1770 scale: variants[0].scale,
1771 format: variants[0].format,
1772 bytes: packed_bytes,
1773 is_packed_glyph: true,
1774 }
1775}
1776
1777fn process_glyph(
1778 context: &mut FontContext,
1779 can_use_r8_format: bool,
1780 font: Arc<FontInstance>,
1781 key: GlyphKey,
1782) -> GlyphRasterJob {
1783 profile_scope!("glyph-raster");
1784
1785 let subpx_dir = key.subpixel_dir();
1786
1787 let result = if subpx_dir == SubpixelDirection::None {
1788 context.rasterize_glyph(&font, &key)
1789 } else {
1790 let offsets = [
1791 SubpixelOffset::Zero,
1792 SubpixelOffset::Quarter,
1793 SubpixelOffset::Half,
1794 SubpixelOffset::ThreeQuarters,
1795 ];
1796
1797 let mut variants = Vec::with_capacity(4);
1798 for offset in &offsets {
1799 let variant_key = GlyphKey::new(
1800 key.index(),
1801 match subpx_dir {
1802 SubpixelDirection::Horizontal => DevicePoint::new(offset.to_f32(), 0.0),
1803 SubpixelDirection::Vertical => DevicePoint::new(0.0, offset.to_f32()),
1804 SubpixelDirection::None => DevicePoint::zero(),
1805 },
1806 subpx_dir,
1807 );
1808
1809 match context.rasterize_glyph(&font, &variant_key) {
1810 Ok(glyph) => variants.push(glyph),
1811 Err(e) => return GlyphRasterJob {
1812 font: font,
1813 key: key.clone(),
1814 result: Err(e),
1815 },
1816 }
1817 }
1818
1819 Ok(pack_glyph_variants_horizontal(&variants))
1820 };
1821
1822 let mut job = GlyphRasterJob {
1823 font: font,
1824 key: key.clone(),
1825 result,
1826 };
1827
1828 if let Ok(ref mut glyph) = job.result {
1829 let bpp = 4; assert_eq!(
1832 glyph.bytes.len(),
1833 bpp * (glyph.width * glyph.height) as usize
1834 );
1835
1836 fn over(dst: u8, src: u8) -> u8 {
1838 let a = src as u32;
1839 let a = 256 - a;
1840 let dst = ((dst as u32 * a) >> 8) as u8;
1841 src + dst
1842 }
1843
1844 if GLYPH_FLASHING.load(Ordering::Relaxed) {
1845 let color = (random() & 0xff) as u8;
1846 for i in &mut glyph.bytes {
1847 *i = over(*i, color);
1848 }
1849 }
1850
1851 assert_eq!((glyph.left.fract(), glyph.top.fract()), (0.0, 0.0));
1852
1853 glyph.downscale_bitmap_if_required(&job.font);
1855
1856 if glyph.format.image_format(can_use_r8_format).bytes_per_pixel() == 1 {
1860 glyph.bytes = glyph.bytes
1861 .chunks_mut(4)
1862 .map(|pixel| pixel[3])
1863 .collect::<Vec<_>>();
1864 }
1865 }
1866
1867 job
1868}
1869
1870
1871pub enum GlyphRasterMsg {
1872 Rasterize {
1873 font: Arc<FontInstance>,
1874 glyphs: SmallVec<[GlyphKey; 16]>,
1875 can_use_r8_format: bool,
1876 tx: Sender<GlyphRasterJob>,
1877 },
1878 AddFont { font_key: FontKey, template: FontTemplate },
1879 DeleteFont { font_key: FontKey },
1880 DeleteFontInstance { instance: FontInstance },
1881 ShutDown,
1882}
1883
1884#[derive(Clone)]
1885pub struct GlyphRasterThread {
1886 tx: Sender<GlyphRasterMsg>,
1887}
1888
1889impl GlyphRasterThread {
1890 pub fn new(
1891 on_start: impl FnOnce() + Send + 'static,
1892 on_end: impl FnOnce() + Send+ 'static,
1893 ) -> std::io::Result<Self> {
1894 let (tx, rx) = unbounded();
1895
1896 std::thread::Builder::new().name("Glyph rasterizer".to_string()).spawn(move || {
1897 on_start();
1898
1899 let mut context = FontContext::new();
1900
1901 loop {
1902 match rx.recv() {
1903 Ok(GlyphRasterMsg::Rasterize { font, glyphs, can_use_r8_format, tx }) => {
1904 for glyph in &glyphs {
1905 let job = process_glyph(&mut context, can_use_r8_format, font.clone(), *glyph);
1906 let _ = tx.send(job);
1907 }
1908 }
1909 Ok(GlyphRasterMsg::AddFont { font_key, template }) => {
1910 context.add_font(&font_key, &template)
1911 }
1912 Ok(GlyphRasterMsg::DeleteFont { font_key }) => {
1913 context.delete_font(&font_key)
1914 }
1915 Ok(GlyphRasterMsg::DeleteFontInstance { instance }) => {
1916 context.delete_font_instance(&instance)
1917 }
1918 Ok(GlyphRasterMsg::ShutDown) => {
1919 break;
1920 }
1921 Err(..) => {
1922 break;
1923 }
1924 }
1925 }
1926
1927 on_end();
1928 })?;
1929
1930 Ok(GlyphRasterThread {
1931 tx,
1932 })
1933 }
1934
1935 pub fn shut_down(&self) {
1936 let _ = self.tx.send(GlyphRasterMsg::ShutDown);
1937 }
1938}
1939
1940#[cfg(test)]
1941mod test_glyph_rasterizer {
1942 use crate::profiler::GlyphRasterizeProfiler;
1943
1944 struct Profiler;
1945 impl GlyphRasterizeProfiler for Profiler {
1946 fn start_time(&mut self) {}
1947 fn end_time(&mut self) -> f64 {
1948 0.
1949 }
1950 fn set(&mut self, _value: f64) {}
1951 }
1952
1953 #[test]
1954 fn rasterize_200_glyphs() {
1955 use rayon::ThreadPoolBuilder;
1959 use std::fs::File;
1960 use std::io::Read;
1961 use api::{FontKey, FontInstanceKey, FontTemplate, IdNamespace};
1962 use api::units::DevicePoint;
1963 use std::sync::Arc;
1964 use crate::rasterizer::{FontInstance, BaseFontInstance, GlyphKey, GlyphRasterizer};
1965
1966 let worker = ThreadPoolBuilder::new()
1967 .thread_name(|idx|{ format!("WRWorker#{}", idx) })
1968 .build();
1969 let workers = Arc::new(worker.unwrap());
1970 let mut glyph_rasterizer = GlyphRasterizer::new(workers, None, true);
1971 let mut font_file =
1972 File::open("../wrench/reftests/text/VeraBd.ttf").expect("Couldn't open font file");
1973 let mut font_data = vec![];
1974 font_file
1975 .read_to_end(&mut font_data)
1976 .expect("failed to read font file");
1977
1978 let font_key = FontKey::new(IdNamespace(0), 0);
1979 glyph_rasterizer.add_font(font_key, FontTemplate::Raw(Arc::new(font_data), 0));
1980
1981 let font = FontInstance::from_base(Arc::new(BaseFontInstance::new(
1982 FontInstanceKey::new(IdNamespace(0), 0),
1983 font_key,
1984 32.0,
1985 None,
1986 None,
1987 Vec::new(),
1988 )));
1989
1990 let subpx_dir = font.get_subpx_dir();
1991
1992 let mut glyph_keys = Vec::with_capacity(200);
1993 for i in 0 .. 200 {
1994 glyph_keys.push(GlyphKey::new(
1995 i,
1996 DevicePoint::zero(),
1997 subpx_dir,
1998 ));
1999 }
2000
2001 for i in 0 .. 4 {
2002 glyph_rasterizer.request_glyphs(
2003 font.clone(),
2004 &glyph_keys[(50 * i) .. (50 * (i + 1))],
2005 |_| true,
2006 );
2007 }
2008
2009 glyph_rasterizer.delete_font(font_key);
2010
2011 glyph_rasterizer.resolve_glyphs(
2012 |_, _| {},
2013 &mut Profiler,
2014 );
2015 }
2016
2017 #[test]
2018 fn rasterize_large_glyphs() {
2019 use rayon::ThreadPoolBuilder;
2022 use std::fs::File;
2023 use std::io::Read;
2024 use api::{FontKey, FontInstanceKey, FontTemplate, IdNamespace};
2025 use api::units::DevicePoint;
2026 use std::sync::Arc;
2027 use crate::rasterizer::{FontInstance, BaseFontInstance, GlyphKey, GlyphRasterizer};
2028
2029 let worker = ThreadPoolBuilder::new()
2030 .thread_name(|idx|{ format!("WRWorker#{}", idx) })
2031 .build();
2032 let workers = Arc::new(worker.unwrap());
2033 let mut glyph_rasterizer = GlyphRasterizer::new(workers, None, true);
2034 let mut font_file =
2035 File::open("../wrench/reftests/text/VeraBd.ttf").expect("Couldn't open font file");
2036 let mut font_data = vec![];
2037 font_file
2038 .read_to_end(&mut font_data)
2039 .expect("failed to read font file");
2040
2041 let font_key = FontKey::new(IdNamespace(0), 0);
2042 glyph_rasterizer.add_font(font_key, FontTemplate::Raw(Arc::new(font_data), 0));
2043
2044 let font = FontInstance::from_base(Arc::new(BaseFontInstance::new(
2045 FontInstanceKey::new(IdNamespace(0), 0),
2046 font_key,
2047 200.0,
2048 None,
2049 None,
2050 Vec::new(),
2051 )));
2052
2053 let subpx_dir = font.get_subpx_dir();
2054
2055 let mut glyph_keys = Vec::with_capacity(10);
2056 for i in 0 .. 10 {
2057 glyph_keys.push(GlyphKey::new(
2058 i,
2059 DevicePoint::zero(),
2060 subpx_dir,
2061 ));
2062 }
2063
2064 glyph_rasterizer.request_glyphs(
2065 font.clone(),
2066 &glyph_keys,
2067 |_| true,
2068 );
2069
2070 glyph_rasterizer.delete_font(font_key);
2071
2072 glyph_rasterizer.resolve_glyphs(
2073 |_, _| {},
2074 &mut Profiler,
2075 );
2076 }
2077
2078 #[test]
2079 fn test_subpx_quantize() {
2080 use crate::rasterizer::SubpixelOffset;
2081
2082 assert_eq!(SubpixelOffset::quantize(0.0), SubpixelOffset::Zero);
2083 assert_eq!(SubpixelOffset::quantize(-0.0), SubpixelOffset::Zero);
2084
2085 assert_eq!(SubpixelOffset::quantize(0.1), SubpixelOffset::Zero);
2086 assert_eq!(SubpixelOffset::quantize(0.01), SubpixelOffset::Zero);
2087 assert_eq!(SubpixelOffset::quantize(0.05), SubpixelOffset::Zero);
2088 assert_eq!(SubpixelOffset::quantize(0.12), SubpixelOffset::Zero);
2089 assert_eq!(SubpixelOffset::quantize(0.124), SubpixelOffset::Zero);
2090
2091 assert_eq!(SubpixelOffset::quantize(0.125), SubpixelOffset::Quarter);
2092 assert_eq!(SubpixelOffset::quantize(0.2), SubpixelOffset::Quarter);
2093 assert_eq!(SubpixelOffset::quantize(0.25), SubpixelOffset::Quarter);
2094 assert_eq!(SubpixelOffset::quantize(0.33), SubpixelOffset::Quarter);
2095 assert_eq!(SubpixelOffset::quantize(0.374), SubpixelOffset::Quarter);
2096
2097 assert_eq!(SubpixelOffset::quantize(0.375), SubpixelOffset::Half);
2098 assert_eq!(SubpixelOffset::quantize(0.4), SubpixelOffset::Half);
2099 assert_eq!(SubpixelOffset::quantize(0.5), SubpixelOffset::Half);
2100 assert_eq!(SubpixelOffset::quantize(0.58), SubpixelOffset::Half);
2101 assert_eq!(SubpixelOffset::quantize(0.624), SubpixelOffset::Half);
2102
2103 assert_eq!(SubpixelOffset::quantize(0.625), SubpixelOffset::ThreeQuarters);
2104 assert_eq!(SubpixelOffset::quantize(0.67), SubpixelOffset::ThreeQuarters);
2105 assert_eq!(SubpixelOffset::quantize(0.7), SubpixelOffset::ThreeQuarters);
2106 assert_eq!(SubpixelOffset::quantize(0.78), SubpixelOffset::ThreeQuarters);
2107 assert_eq!(SubpixelOffset::quantize(0.874), SubpixelOffset::ThreeQuarters);
2108
2109 assert_eq!(SubpixelOffset::quantize(0.875), SubpixelOffset::Zero);
2110 assert_eq!(SubpixelOffset::quantize(0.89), SubpixelOffset::Zero);
2111 assert_eq!(SubpixelOffset::quantize(0.91), SubpixelOffset::Zero);
2112 assert_eq!(SubpixelOffset::quantize(0.967), SubpixelOffset::Zero);
2113 assert_eq!(SubpixelOffset::quantize(0.999), SubpixelOffset::Zero);
2114
2115 assert_eq!(SubpixelOffset::quantize(-1.0), SubpixelOffset::Zero);
2116 assert_eq!(SubpixelOffset::quantize(1.0), SubpixelOffset::Zero);
2117 assert_eq!(SubpixelOffset::quantize(1.5), SubpixelOffset::Half);
2118 assert_eq!(SubpixelOffset::quantize(-1.625), SubpixelOffset::Half);
2119 assert_eq!(SubpixelOffset::quantize(-4.33), SubpixelOffset::ThreeQuarters);
2120 }
2121}