sdfer/
bruteforce_bitmap.rs1use crate::{Bitmap, Image2d, Unorm8};
10
11#[cfg(sdfer_use_f64_instead_of_f32)]
13type f32 = f64;
14
15pub fn sdf(bitmap: &Bitmap, sdf_size: usize, spread: usize) -> Image2d<Unorm8> {
16 let (w, h) = (bitmap.width(), bitmap.height());
17
18 assert!(w.is_power_of_two() && h.is_power_of_two() && sdf_size.is_power_of_two());
19 let scale = w.max(h) / sdf_size;
20 assert_ne!(scale, 0);
21
22 let spread = spread * scale;
23
24 let width = w / scale;
25 let height = h / scale;
26 Image2d::from_fn(width, height, |x, y| {
27 let (x, y) = (x * scale + scale / 2, y * scale + scale / 2);
28 let inside = bitmap.get(x, y);
29 let dist = (((y.saturating_sub(spread)..=(y + spread))
32 .flat_map(|y2| (x.saturating_sub(spread)..=(x + spread)).map(move |x2| (x2, y2)))
33 .filter(|&(x2, y2)| x2 < w && y2 < h && bitmap.get(x2, y2) != inside)
34 .map(|(x2, y2)| x2.abs_diff(x).pow(2) + y2.abs_diff(y).pow(2))
35 .min()
36 .unwrap_or(usize::MAX) as f32)
37 .sqrt()
38 / (spread as f32))
39 .clamp(0.0, 1.0);
40 let signed_dist = if inside { -dist } else { dist };
41
42 Unorm8::encode((signed_dist + 1.0) / 2.0)
44 })
45}