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 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}