0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-09 00:28:20 -05:00
penpot/render-wasm/src/main.rs

217 lines
6.1 KiB
Rust
Raw Normal View History

mod debug;
mod images;
mod math;
mod render;
mod shapes;
mod state;
mod utils;
mod view;
2024-11-12 11:09:50 +01:00
use skia_safe as skia;
2024-11-12 11:09:50 +01:00
use crate::state::State;
use crate::utils::uuid_from_u32_quartet;
2024-11-12 11:09:50 +01:00
static mut STATE: Option<Box<State>> = None;
2024-11-14 12:08:50 +01:00
extern "C" {
fn emscripten_GetProcAddress(
name: *const ::std::os::raw::c_char,
) -> *const ::std::os::raw::c_void;
}
fn init_gl() {
unsafe {
gl::load_with(|addr| {
let addr = std::ffi::CString::new(addr).unwrap();
emscripten_GetProcAddress(addr.into_raw() as *const _) as *const _
});
}
}
/// This is called from JS after the WebGL context has been created.
#[no_mangle]
pub extern "C" fn init(width: i32, height: i32) {
let state_box = Box::new(State::new(width, height, 2048));
2024-11-12 11:09:50 +01:00
unsafe {
STATE = Some(state_box);
}
}
#[no_mangle]
pub extern "C" fn set_render_options(debug: u32, dpr: f32) {
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
let render_state = state.render_state();
render_state.set_debug_flags(debug);
2024-11-25 17:57:01 +01:00
render_state.set_dpr(dpr);
}
#[no_mangle]
2024-11-20 13:49:45 +01:00
pub unsafe extern "C" fn render() {
2024-11-12 11:09:50 +01:00
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
state.render_all(true);
}
#[no_mangle]
pub unsafe extern "C" fn render_without_cache() {
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
state.render_all(false);
}
#[no_mangle]
pub unsafe extern "C" fn navigate() {
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
state.navigate();
2024-11-12 11:09:50 +01:00
}
#[no_mangle]
pub extern "C" fn reset_canvas() {
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
2024-11-14 12:08:50 +01:00
state.render_state().reset_canvas();
2024-11-12 11:09:50 +01:00
}
2024-11-20 13:49:45 +01:00
#[no_mangle]
2024-11-25 17:57:01 +01:00
pub extern "C" fn resize_viewbox(width: i32, height: i32) {
2024-11-20 15:05:16 +01:00
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
state.resize(width, height);
}
#[no_mangle]
pub extern "C" fn set_view(zoom: f32, x: f32, y: f32) {
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
2024-11-25 17:57:01 +01:00
state.render_state().viewbox.set_all(zoom, x, y);
2024-11-20 15:05:16 +01:00
}
#[no_mangle]
pub extern "C" fn set_view_zoom(zoom: f32) {
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
2024-11-25 17:57:01 +01:00
state.render_state().viewbox.set_zoom(zoom);
2024-11-20 15:05:16 +01:00
}
#[no_mangle]
pub extern "C" fn set_view_xy(x: f32, y: f32) {
2024-11-20 13:49:45 +01:00
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
2024-11-25 17:57:01 +01:00
state.render_state().viewbox.set_pan_xy(x, y);
2024-11-20 13:49:45 +01:00
}
2024-11-12 11:09:50 +01:00
#[no_mangle]
pub extern "C" fn use_shape(a: u32, b: u32, c: u32, d: u32) {
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
let id = uuid_from_u32_quartet(a, b, c, d);
state.use_shape(id);
2024-11-12 11:09:50 +01:00
}
#[no_mangle]
2024-11-20 15:05:16 +01:00
pub unsafe extern "C" fn set_shape_selrect(left: f32, top: f32, right: f32, bottom: f32) {
2024-11-12 11:09:50 +01:00
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
if let Some(shape) = state.current_shape() {
2024-11-20 15:05:16 +01:00
shape.selrect.set_ltrb(left, top, right, bottom);
2024-11-12 11:09:50 +01:00
}
}
#[no_mangle]
2024-11-12 11:09:50 +01:00
pub unsafe extern "C" fn set_shape_rotation(rotation: f32) {
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
if let Some(shape) = state.current_shape() {
2024-11-12 11:09:50 +01:00
shape.rotation = rotation;
}
}
#[no_mangle]
pub unsafe extern "C" fn set_shape_transform(a: f32, b: f32, c: f32, d: f32, e: f32, f: f32) {
2024-11-12 11:09:50 +01:00
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
if let Some(shape) = state.current_shape() {
shape.transform.a = a;
shape.transform.b = b;
shape.transform.c = c;
shape.transform.d = d;
shape.transform.e = e;
shape.transform.f = f;
2024-11-12 11:09:50 +01:00
}
}
#[no_mangle]
pub extern "C" fn add_shape_child(a: u32, b: u32, c: u32, d: u32) {
2024-11-12 11:09:50 +01:00
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
let id = uuid_from_u32_quartet(a, b, c, d);
if let Some(shape) = state.current_shape() {
shape.children.push(id);
}
}
#[no_mangle]
pub extern "C" fn clear_shape_children() {
2024-11-12 11:09:50 +01:00
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
if let Some(shape) = state.current_shape() {
shape.children.clear();
}
}
2024-11-13 12:12:14 +01:00
#[no_mangle]
pub extern "C" fn add_shape_solid_fill(raw_color: u32) {
2024-11-13 12:12:14 +01:00
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
if let Some(shape) = state.current_shape() {
let color = skia::Color::new(raw_color);
2024-11-13 12:12:14 +01:00
shape.add_fill(shapes::Fill::from(color));
}
}
2024-11-28 15:50:04 +01:00
#[no_mangle]
pub extern "C" fn add_shape_linear_fill(
start_x: f32,
start_y: f32,
end_x: f32,
end_y: f32,
opacity: f32,
) {
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
if let Some(shape) = state.current_shape() {
shape.add_fill(shapes::Fill::new_linear_gradient(
(start_x, start_y),
(end_x, end_y),
opacity,
))
}
}
#[no_mangle]
pub extern "C" fn add_shape_fill_stop(raw_color: u32, offset: f32) {
2024-11-28 15:50:04 +01:00
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
if let Some(shape) = state.current_shape() {
let color = skia::Color::new(raw_color);
2024-11-28 15:50:04 +01:00
shape
.add_gradient_stop(color, offset)
.expect("got no fill or an invalid one");
}
}
2024-11-13 12:12:14 +01:00
#[no_mangle]
pub extern "C" fn clear_shape_fills() {
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
if let Some(shape) = state.current_shape() {
2024-11-13 12:12:14 +01:00
shape.clear_fills();
}
}
#[no_mangle]
pub extern "C" fn set_shape_blend_mode(mode: i32) {
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
if let Some(shape) = state.current_shape() {
shape.set_blend_mode(shapes::BlendMode::from(mode));
}
}
2024-11-25 07:17:29 +01:00
#[no_mangle]
pub extern "C" fn set_shape_opacity(opacity: f32) {
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
if let Some(shape) = state.current_shape() {
shape.opacity = opacity;
}
}
fn main() {
init_gl();
}