floem_renderer/
swash.rs

1use cosmic_text::{CacheKey, CacheKeyFlags, SwashImage};
2use swash::{
3    scale::{Render, ScaleContext, Source, StrikeWith},
4    zeno::{Angle, Format, Transform, Vector},
5};
6
7use crate::text::FONT_SYSTEM;
8
9const IS_MACOS: bool = cfg!(target_os = "macos");
10
11pub struct SwashScaler {
12    context: ScaleContext,
13    pub font_embolden: f32,
14}
15
16impl Default for SwashScaler {
17    fn default() -> Self {
18        Self {
19            context: ScaleContext::new(),
20            font_embolden: 0.,
21        }
22    }
23}
24
25impl SwashScaler {
26    pub fn new(font_embolden: f32) -> Self {
27        Self {
28            context: ScaleContext::new(),
29            font_embolden,
30        }
31    }
32
33    pub fn get_image(&mut self, cache_key: CacheKey) -> Option<SwashImage> {
34        let font = match FONT_SYSTEM.lock().get_font(cache_key.font_id) {
35            Some(some) => some,
36            None => {
37                return None;
38            }
39        };
40
41        // Build the scaler
42        let mut scaler = self
43            .context
44            .builder(font.as_swash())
45            .size(f32::from_bits(cache_key.font_size_bits))
46            .hint(!IS_MACOS)
47            .build();
48
49        let offset = Vector::new(cache_key.x_bin.as_float(), cache_key.y_bin.as_float());
50
51        Render::new(&[
52            Source::ColorOutline(0),
53            Source::ColorBitmap(StrikeWith::BestFit),
54            Source::Outline,
55        ])
56        .format(Format::Alpha)
57        .offset(offset)
58        .embolden(self.font_embolden)
59        .transform(if cache_key.flags.contains(CacheKeyFlags::FAKE_ITALIC) {
60            Some(Transform::skew(
61                Angle::from_degrees(14.0),
62                Angle::from_degrees(0.0),
63            ))
64        } else {
65            None
66        })
67        .render(&mut scaler, cache_key.glyph_id)
68    }
69}