msdf_sys/
lib.rs

1#![allow(non_upper_case_globals)]
2#![allow(non_camel_case_types)]
3#![allow(non_snake_case)]
4
5#[allow(clippy::all)]
6mod sys {
7    // to make clippy happy
8    include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
9}
10pub use sys::*;
11
12#[cfg(test)]
13mod tests {
14    use super::*;
15    use image::{DynamicImage, ImageBuffer, Luma, Rgb32FImage, RgbImage};
16    use std::os::raw::c_int;
17    use std::{env, iter, ptr};
18
19    fn compare_images(image: &RgbImage, path: &str) {
20        // i'm hoping that floating point optimizations and whatnot do not affect the results enough that a bitwise comparison fails
21        let path = env::current_dir()
22            .unwrap()
23            .join("test_resources")
24            .join(path)
25            .with_extension("png");
26        let truth = image::open(path).expect("Unable to open test resource");
27        let truth = truth.into_rgb8(); // make sure we're working in rgb8
28
29        if image.len() != truth.len() {
30            panic!("Image sizes do not match.");
31        }
32
33        for pixel in iter::zip(image.pixels(), truth.pixels()) {
34            if pixel.0 != pixel.1 {
35                panic!("Images do not match.");
36            }
37        }
38    }
39
40    #[test]
41    fn can_generate_sdf_from_shape() {
42        unsafe {
43            let shape_desc = "{ 1471,0; 1149,0; 1021,333; 435,333; 314,0; 0,0; 571,1466; 884,1466; # }{ 926,580; 724,1124; 526,580; # }";
44            let mut shape = msdfgen_Shape::new();
45            let mut colors_specified = false;
46
47            msdfgen_readShapeDescription1(
48                shape_desc.as_ptr() as *const _,
49                &mut shape,
50                &mut colors_specified,
51            );
52
53            shape.normalize();
54            shape.inverseYAxis = true;
55
56            msdfgen_edgeColoringSimple(&mut shape, 3.0, 0);
57
58            let image = ImageBuffer::<Luma<f32>, Vec<f32>>::new(16, 16);
59
60            let msdf = msdfgen_Bitmap {
61                pixels: image.as_flat_samples().samples.as_ptr() as *mut f32,
62                w: image.width() as c_int,
63                h: image.height() as c_int,
64                _phantom_0: Default::default(),
65            };
66
67            let scale = msdfgen_Vector2::new1(0.01, 0.01);
68            let translation = msdfgen_Vector2::new1(100.0, 100.0);
69            let projection = msdfgen_Projection::new1(&scale, &translation);
70
71            let config = msdfgen_GeneratorConfig {
72                overlapSupport: true,
73            };
74
75            msdfgen_generateSDF(
76                &msdf as *const msdfgen_Bitmap<f32> as *const _,
77                &shape,
78                &projection,
79                200.0,
80                &config,
81            );
82
83            let image: DynamicImage = image.into();
84            let image = image.into_rgb8();
85
86            compare_images(&image, "sdf");
87        }
88    }
89
90    #[test]
91    fn can_generate_msdf_from_shape() {
92        unsafe {
93            let shape_desc = "{ 1471,0; 1149,0; 1021,333; 435,333; 314,0; 0,0; 571,1466; 884,1466; # }{ 926,580; 724,1124; 526,580; # }";
94            let mut shape = msdfgen_Shape::new();
95            let mut colors_specified = false;
96
97            msdfgen_readShapeDescription1(
98                shape_desc.as_ptr() as *const _,
99                &mut shape,
100                &mut colors_specified,
101            );
102
103            shape.normalize();
104            shape.inverseYAxis = true;
105
106            msdfgen_edgeColoringSimple(&mut shape, 3.0, 0);
107
108            let image = Rgb32FImage::new(16, 16);
109
110            let msdf = msdfgen_Bitmap {
111                pixels: image.as_flat_samples().samples.as_ptr() as *mut f32,
112                w: image.width() as c_int,
113                h: image.height() as c_int,
114                _phantom_0: Default::default(),
115            };
116
117            let scale = msdfgen_Vector2::new1(0.01, 0.01);
118            let translation = msdfgen_Vector2::new1(100.0, 100.0);
119            let projection = msdfgen_Projection::new1(&scale, &translation);
120
121            let config = msdfgen_MSDFGeneratorConfig {
122                _base: msdfgen_GeneratorConfig {
123                    overlapSupport: true,
124                },
125                errorCorrection: msdfgen_ErrorCorrectionConfig {
126                    mode: 0,
127                    distanceCheckMode: 0,
128                    minDeviationRatio: 0.0,
129                    minImproveRatio: 0.0,
130                    buffer: ptr::null_mut(),
131                },
132            };
133
134            msdfgen_generateMSDF(
135                &msdf as *const msdfgen_Bitmap<f32> as *const _,
136                &shape,
137                &projection,
138                200.0,
139                &config,
140            );
141
142            let image: DynamicImage = image.into();
143            let image = image.into_rgb8();
144
145            compare_images(&image, "msdf");
146        }
147    }
148}