mirror of
https://github.com/penpot/penpot.git
synced 2026-07-05 13:55:22 +00:00
99 lines
3.6 KiB
Rust
99 lines
3.6 KiB
Rust
use crate::error::Result;
|
|
use crate::get_gpu_state;
|
|
use crate::state::ShapesPoolRef;
|
|
use crate::uuid::Uuid;
|
|
use skia_safe as skia;
|
|
|
|
use super::{NodeRenderState, RenderState, SurfaceId};
|
|
|
|
pub fn render_shape_pixels(
|
|
render_state: &mut RenderState,
|
|
id: &Uuid,
|
|
tree: ShapesPoolRef,
|
|
scale: f32,
|
|
timestamp: i32,
|
|
) -> Result<(Vec<u8>, i32, i32)> {
|
|
let target_surface = SurfaceId::Export;
|
|
|
|
let saved_focus_mode = render_state.focus_mode.clone();
|
|
let saved_export_context = render_state.export_context;
|
|
let saved_render_area = render_state.render_area;
|
|
let saved_render_area_with_margins = render_state.render_area_with_margins;
|
|
let saved_current_tile = render_state.tile.current;
|
|
let saved_pending_nodes = std::mem::take(&mut render_state.pending_nodes);
|
|
let saved_nested_fills = std::mem::take(&mut render_state.nested_fills);
|
|
let saved_nested_blurs = std::mem::take(&mut render_state.nested_blurs);
|
|
let saved_nested_shadows = std::mem::take(&mut render_state.nested_shadows);
|
|
let saved_ignore_nested_blurs = render_state.ignore_nested_blurs;
|
|
let saved_preview_mode = render_state.preview_mode;
|
|
|
|
render_state.focus_mode.clear();
|
|
|
|
render_state
|
|
.surfaces
|
|
.canvas(target_surface)
|
|
.clear(skia::Color::TRANSPARENT);
|
|
|
|
if tree.len() != 0 {
|
|
let Some(shape) = tree.get(id) else {
|
|
return Ok((Vec::new(), 0, 0));
|
|
};
|
|
let mut extrect = shape.extrect(tree, scale);
|
|
render_state.export_context = Some((extrect, scale));
|
|
let margins = render_state.surfaces.margins;
|
|
extrect.offset((margins.width as f32 / scale, margins.height as f32 / scale));
|
|
|
|
render_state.surfaces.resize_export_surface(scale, extrect);
|
|
render_state.render_area = extrect;
|
|
render_state.render_area_with_margins = extrect;
|
|
render_state.surfaces.update_render_context(extrect, scale);
|
|
|
|
render_state.pending_nodes.push(NodeRenderState {
|
|
id: *id,
|
|
visited_children: false,
|
|
clip_bounds: None,
|
|
visited_mask: false,
|
|
mask: false,
|
|
flattened: false,
|
|
});
|
|
render_state.render_shape_tree_tile( timestamp, false, true)?;
|
|
}
|
|
|
|
render_state.export_context = None;
|
|
|
|
render_state.surfaces.flush_and_submit(target_surface);
|
|
|
|
let image = render_state.surfaces.snapshot(target_surface);
|
|
let data = image
|
|
.encode(
|
|
Some(&mut get_gpu_state().context),
|
|
skia::EncodedImageFormat::PNG,
|
|
100,
|
|
)
|
|
.expect("PNG encode failed");
|
|
let skia::ISize { width, height } = image.dimensions();
|
|
|
|
render_state.focus_mode = saved_focus_mode;
|
|
render_state.export_context = saved_export_context;
|
|
render_state.render_area = saved_render_area;
|
|
render_state.render_area_with_margins = saved_render_area_with_margins;
|
|
render_state.tile.current = saved_current_tile;
|
|
render_state.pending_nodes = saved_pending_nodes;
|
|
render_state.nested_fills = saved_nested_fills;
|
|
render_state.nested_blurs = saved_nested_blurs;
|
|
render_state.nested_shadows = saved_nested_shadows;
|
|
render_state.ignore_nested_blurs = saved_ignore_nested_blurs;
|
|
render_state.preview_mode = saved_preview_mode;
|
|
|
|
let workspace_scale = render_state.get_scale();
|
|
if let Some(tile) = render_state.tile.current {
|
|
render_state.update_render_context(tile);
|
|
} else if !render_state.render_area.is_empty() {
|
|
render_state
|
|
.surfaces
|
|
.update_render_context(render_state.render_area, workspace_scale);
|
|
}
|
|
|
|
Ok((data.as_bytes().to_vec(), width, height))
|
|
}
|