wpf_gpu_raster/
c_bindings.rs

1use crate::{PathBuilder, OutputPath, OutputVertex, FillMode, rasterize_to_tri_list};
2use crate::types::{BYTE, POINT};
3
4#[no_mangle]
5pub extern "C" fn wgr_new_builder() -> *mut PathBuilder {
6    let pb = PathBuilder::new();
7    Box::into_raw(Box::new(pb))
8}
9
10#[no_mangle]
11pub extern "C" fn wgr_builder_move_to(pb: &mut PathBuilder, x: f32, y: f32) {
12    pb.move_to(x, y);
13}
14
15#[no_mangle]
16pub extern "C" fn wgr_builder_line_to(pb: &mut PathBuilder, x: f32, y: f32) {
17    pb.line_to(x, y);
18}
19
20#[no_mangle]
21pub extern "C" fn wgr_builder_curve_to(pb: &mut PathBuilder, c1x: f32, c1y: f32, c2x: f32, c2y: f32, x: f32, y: f32) {
22    pb.curve_to(c1x, c1y, c2x, c2y, x, y);
23}
24
25#[no_mangle]
26pub extern "C" fn wgr_builder_quad_to(pb: &mut PathBuilder, cx: f32, cy: f32, x: f32, y: f32) {
27    pb.quad_to(cx, cy, x, y);
28}
29
30#[no_mangle]
31pub extern "C" fn wgr_builder_close(pb: &mut PathBuilder) {
32    pb.close();
33}
34
35#[no_mangle]
36pub extern "C" fn wgr_builder_set_fill_mode(pb: &mut PathBuilder, fill_mode: FillMode) {
37    pb.set_fill_mode(fill_mode)
38}
39
40#[repr(C)]
41pub struct Path {
42    fill_mode: FillMode,
43    points: *const POINT,
44    num_points: usize,
45    types: *const BYTE,
46    num_types: usize,
47}
48
49impl From<OutputPath> for Path {
50    fn from(output_path: OutputPath) -> Self {
51        let path = Self {
52            fill_mode: output_path.fill_mode,
53            points: output_path.points.as_ptr(),
54            num_points: output_path.points.len(),
55            types: output_path.types.as_ptr(),
56            num_types: output_path.types.len(),
57        };
58        std::mem::forget(output_path);
59        path
60    }
61}
62
63impl Into<OutputPath> for Path {
64    fn into(self) -> OutputPath {
65        OutputPath {
66            fill_mode: self.fill_mode,
67            points: unsafe {
68                if self.points == std::ptr::null() {
69                    Default::default()
70                } else {
71                    Box::from_raw(std::slice::from_raw_parts_mut(self.points as *mut POINT, self.num_points))
72                }
73            },
74            types: unsafe {
75                if self.types == std::ptr::null() {
76                    Default::default()
77                } else {
78                    Box::from_raw(std::slice::from_raw_parts_mut(self.types as *mut BYTE, self.num_types))
79                }
80            },
81        }
82    }
83}
84
85#[no_mangle]
86pub extern "C" fn wgr_builder_get_path(pb: &mut PathBuilder) -> Path {
87    Path::from(pb.get_path().unwrap_or_default())
88}
89
90#[repr(C)]
91pub struct VertexBuffer {
92    data: *const OutputVertex,
93    len: usize
94}
95
96#[no_mangle]
97pub extern "C" fn wgr_path_rasterize_to_tri_list(
98    path: &Path,
99    clip_x: i32,
100    clip_y: i32,
101    clip_width: i32,
102    clip_height: i32,
103    need_inside: bool,
104    need_outside: bool,
105    rasterization_truncates: bool,
106    output_ptr: *mut OutputVertex,
107    output_capacity: usize,
108) -> VertexBuffer {
109    let output_buffer = if output_ptr != std::ptr::null_mut() {
110        unsafe { Some(std::slice::from_raw_parts_mut(output_ptr, output_capacity)) }
111    } else {
112        None
113    };
114    let mut result = rasterize_to_tri_list(
115        path.fill_mode,
116        unsafe { std::slice::from_raw_parts(path.types, path.num_types) },
117        unsafe { std::slice::from_raw_parts(path.points, path.num_points) },
118        clip_x, clip_y, clip_width, clip_height,
119        need_inside, need_outside,
120        rasterization_truncates,
121        output_buffer
122    );
123    if let Some(output_buffer_size) = result.get_output_buffer_size() {
124        VertexBuffer {
125            data: std::ptr::null(),
126            len: output_buffer_size,
127        }
128    } else {
129        let slice = result.flush_output();
130        let vb = VertexBuffer {
131            data: slice.as_ptr(),
132            len: slice.len(),
133        };
134        std::mem::forget(slice);
135        vb
136    }
137}
138
139#[no_mangle]
140pub extern "C" fn wgr_path_release(path: Path) {
141    let output_path: OutputPath = path.into();
142    drop(output_path);
143}
144
145#[no_mangle]
146pub extern "C" fn wgr_vertex_buffer_release(vb: VertexBuffer)
147{
148    if vb.data != std::ptr::null() {
149        unsafe {
150            drop(Box::from_raw(std::slice::from_raw_parts_mut(vb.data as *mut OutputVertex, vb.len)));
151        }
152    }
153}
154
155#[no_mangle]
156pub unsafe extern "C" fn wgr_builder_release(pb: *mut PathBuilder) {
157    drop(Box::from_raw(pb));
158}