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 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 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());
52
53 Render::new(&[
55 Source::ColorOutline(0),
57 Source::ColorBitmap(StrikeWith::BestFit),
59 Source::Outline,
61 ])
62 .format(Format::Alpha)
64 .offset(offset)
66 .embolden(self.font_embolden)
67 .transform(if cache_key.flags.contains(CacheKeyFlags::FAKE_ITALIC) {
68 Some(Transform::skew(
69 Angle::from_degrees(14.0),
70 Angle::from_degrees(0.0),
71 ))
72 } else {
73 None
74 })
75 .render(&mut scaler, cache_key.glyph_id)
77 }
78}