use crate::{PathBuilder, OutputPath, OutputVertex, FillMode, rasterize_to_tri_list}; use crate::types::{BYTE, POINT}; #[no_mangle] pub extern "C" fn wgr_new_builder() -> *mut PathBuilder { let pb = PathBuilder::new(); Box::into_raw(Box::new(pb)) } #[no_mangle] pub extern "C" fn wgr_builder_move_to(pb: &mut PathBuilder, x: f32, y: f32) { pb.move_to(x, y); } #[no_mangle] pub extern "C" fn wgr_builder_line_to(pb: &mut PathBuilder, x: f32, y: f32) { pb.line_to(x, y); } #[no_mangle] pub extern "C" fn wgr_builder_curve_to(pb: &mut PathBuilder, c1x: f32, c1y: f32, c2x: f32, c2y: f32, x: f32, y: f32) { pb.curve_to(c1x, c1y, c2x, c2y, x, y); } #[no_mangle] pub extern "C" fn wgr_builder_quad_to(pb: &mut PathBuilder, cx: f32, cy: f32, x: f32, y: f32) { pb.quad_to(cx, cy, x, y); } #[no_mangle] pub extern "C" fn wgr_builder_close(pb: &mut PathBuilder) { pb.close(); } #[no_mangle] pub extern "C" fn wgr_builder_set_fill_mode(pb: &mut PathBuilder, fill_mode: FillMode) { pb.set_fill_mode(fill_mode) } #[repr(C)] pub struct Path { fill_mode: FillMode, points: *const POINT, num_points: usize, types: *const BYTE, num_types: usize, } impl From for Path { fn from(output_path: OutputPath) -> Self { let path = Self { fill_mode: output_path.fill_mode, points: output_path.points.as_ptr(), num_points: output_path.points.len(), types: output_path.types.as_ptr(), num_types: output_path.types.len(), }; std::mem::forget(output_path); path } } impl Into for Path { fn into(self) -> OutputPath { OutputPath { fill_mode: self.fill_mode, points: unsafe { if self.points == std::ptr::null() { Default::default() } else { Box::from_raw(std::slice::from_raw_parts_mut(self.points as *mut POINT, self.num_points)) } }, types: unsafe { if self.types == std::ptr::null() { Default::default() } else { Box::from_raw(std::slice::from_raw_parts_mut(self.types as *mut BYTE, self.num_types)) } }, } } } #[no_mangle] pub extern "C" fn wgr_builder_get_path(pb: &mut PathBuilder) -> Path { Path::from(pb.get_path().unwrap_or_default()) } #[repr(C)] pub struct VertexBuffer { data: *const OutputVertex, len: usize } #[no_mangle] pub extern "C" fn wgr_path_rasterize_to_tri_list( path: &Path, clip_x: i32, clip_y: i32, clip_width: i32, clip_height: i32, need_inside: bool, need_outside: bool, rasterization_truncates: bool, output_ptr: *mut OutputVertex, output_capacity: usize, ) -> VertexBuffer { let output_buffer = if output_ptr != std::ptr::null_mut() { unsafe { Some(std::slice::from_raw_parts_mut(output_ptr, output_capacity)) } } else { None }; let mut result = rasterize_to_tri_list( path.fill_mode, unsafe { std::slice::from_raw_parts(path.types, path.num_types) }, unsafe { std::slice::from_raw_parts(path.points, path.num_points) }, clip_x, clip_y, clip_width, clip_height, need_inside, need_outside, rasterization_truncates, output_buffer ); if let Some(output_buffer_size) = result.get_output_buffer_size() { VertexBuffer { data: std::ptr::null(), len: output_buffer_size, } } else { let slice = result.flush_output(); let vb = VertexBuffer { data: slice.as_ptr(), len: slice.len(), }; std::mem::forget(slice); vb } } #[no_mangle] pub extern "C" fn wgr_path_release(path: Path) { let output_path: OutputPath = path.into(); drop(output_path); } #[no_mangle] pub extern "C" fn wgr_vertex_buffer_release(vb: VertexBuffer) { if vb.data != std::ptr::null() { unsafe { drop(Box::from_raw(std::slice::from_raw_parts_mut(vb.data as *mut OutputVertex, vb.len))); } } } #[no_mangle] pub unsafe extern "C" fn wgr_builder_release(pb: *mut PathBuilder) { drop(Box::from_raw(pb)); }