diff options
Diffstat (limited to 'third_party/rust/wpf-gpu-raster/src/c_bindings.rs')
-rw-r--r-- | third_party/rust/wpf-gpu-raster/src/c_bindings.rs | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/third_party/rust/wpf-gpu-raster/src/c_bindings.rs b/third_party/rust/wpf-gpu-raster/src/c_bindings.rs new file mode 100644 index 0000000000..e5f5f12af6 --- /dev/null +++ b/third_party/rust/wpf-gpu-raster/src/c_bindings.rs @@ -0,0 +1,163 @@ +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_reset(pb: &mut PathBuilder) { + pb.reset(); +} + +#[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<OutputPath> 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<OutputPath> 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)); +} |