makepad_draw/text/
sdfer.rs1use {
2 super::image::{Subimage, SubimageMut, R},
3 std::fmt,
4};
5
6pub struct Sdfer {
7 settings: Settings,
8 reusable_buffers: Option<sdfer::esdt::ReusableBuffers>,
9}
10
11impl Sdfer {
12 pub fn new(settings: Settings) -> Self {
13 Self {
14 settings,
15 reusable_buffers: None,
16 }
17 }
18
19 pub fn settings(&self) -> Settings {
20 self.settings
21 }
22
23 pub fn coverage_to_sdf(&mut self, coverage: &Subimage<'_, R>, output: &mut SubimageMut<'_, R>) {
24 use {
25 super::geom::{Point, Size},
26 sdfer::{esdt, esdt::Params, Image2d, Unorm8},
27 };
28
29 assert_eq!(
30 output.size() - coverage.size(),
31 Size::from(self.settings.padding) * 2,
32 );
33 let mut pixels = Vec::with_capacity(coverage.size().width * coverage.size().height);
34 for y in 0..coverage.size().height {
35 for x in 0..coverage.size().width {
36 pixels.push(Unorm8::from_bits(coverage[Point::new(x, y)].r()));
37 }
38 }
39 let mut coverage =
40 Image2d::from_storage(coverage.size().width, coverage.size().height, pixels);
41 let (sdf, reusable_buffers) = esdt::glyph_to_sdf(
42 &mut coverage,
43 Params {
44 pad: self.settings.padding,
45 radius: self.settings.radius,
46 cutoff: self.settings.cutoff,
47 ..Params::default()
48 },
49 self.reusable_buffers.take(),
50 );
51 self.reusable_buffers = Some(reusable_buffers);
52 for y in 0..sdf.height() {
53 for x in 0..sdf.width() {
54 output[Point::new(x, y)] = R::new(sdf[(x, y)].to_bits())
55 }
56 }
57 }
58}
59
60impl fmt::Debug for Sdfer {
61 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62 f.debug_struct("Sdfer").finish_non_exhaustive()
63 }
64}
65
66#[derive(Clone, Copy, Debug)]
67pub struct Settings {
68 pub padding: usize,
69 pub radius: f32,
70 pub cutoff: f32,
71}