mirror of
https://github.com/penpot/penpot.git
synced 2025-03-12 15:51:37 -05:00
♻️ Move rendering a single shape to the shape itself
This commit is contained in:
parent
001aa3f319
commit
967bc75a1c
5 changed files with 121 additions and 72 deletions
|
@ -307,7 +307,7 @@ pub extern "C" fn clear_shape_fills() {
|
||||||
pub extern "C" fn set_shape_blend_mode(mode: i32) {
|
pub extern "C" fn set_shape_blend_mode(mode: i32) {
|
||||||
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
|
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
|
||||||
if let Some(shape) = state.current_shape() {
|
if let Some(shape) = state.current_shape() {
|
||||||
shape.set_blend_mode(shapes::BlendMode::from(mode));
|
shape.set_blend_mode(render::BlendMode::from(mode));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,30 @@
|
||||||
mod gpu_state;
|
|
||||||
mod options;
|
|
||||||
|
|
||||||
use skia::Contains;
|
use skia::Contains;
|
||||||
use skia_safe as skia;
|
use skia_safe as skia;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::math::Rect;
|
use crate::shapes::{Image, Shape};
|
||||||
use crate::shapes::{draw_image_in_container, Fill, Image, Kind, Shape};
|
|
||||||
use crate::view::Viewbox;
|
use crate::view::Viewbox;
|
||||||
|
|
||||||
|
mod blend;
|
||||||
|
mod gpu_state;
|
||||||
|
mod options;
|
||||||
|
|
||||||
use gpu_state::GpuState;
|
use gpu_state::GpuState;
|
||||||
use options::RenderOptions;
|
use options::RenderOptions;
|
||||||
|
|
||||||
|
pub use blend::BlendMode;
|
||||||
|
|
||||||
|
pub trait Renderable {
|
||||||
|
fn render(
|
||||||
|
&self,
|
||||||
|
surface: &mut skia::Surface,
|
||||||
|
images: &HashMap<Uuid, Image>,
|
||||||
|
) -> Result<(), String>;
|
||||||
|
fn blend_mode(&self) -> BlendMode;
|
||||||
|
fn opacity(&self) -> f32;
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) struct CachedSurfaceImage {
|
pub(crate) struct CachedSurfaceImage {
|
||||||
pub image: Image,
|
pub image: Image,
|
||||||
pub viewbox: Viewbox,
|
pub viewbox: Viewbox,
|
||||||
|
@ -133,39 +145,15 @@ impl RenderState {
|
||||||
.reset_matrix();
|
.reset_matrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_single_shape(&mut self, shape: &Shape) {
|
pub fn render_single_element(&mut self, element: &impl Renderable) {
|
||||||
let mut transform = skia::Matrix::new_identity();
|
element
|
||||||
let (translate_x, translate_y) = shape.translation();
|
.render(&mut self.drawing_surface, &self.images)
|
||||||
let (scale_x, scale_y) = shape.scale();
|
.unwrap();
|
||||||
let (skew_x, skew_y) = shape.skew();
|
|
||||||
transform.set_all(
|
|
||||||
scale_x,
|
|
||||||
skew_x,
|
|
||||||
translate_x,
|
|
||||||
skew_y,
|
|
||||||
scale_y,
|
|
||||||
translate_y,
|
|
||||||
0.,
|
|
||||||
0.,
|
|
||||||
1.,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check transform-matrix code from common/src/app/common/geom/shapes/transforms.cljc
|
|
||||||
let center = shape.selrect.center();
|
|
||||||
let mut matrix = skia::Matrix::new_identity();
|
|
||||||
matrix.pre_translate(center);
|
|
||||||
matrix.pre_concat(&transform);
|
|
||||||
matrix.pre_translate(-center);
|
|
||||||
|
|
||||||
self.drawing_surface.canvas().concat(&matrix);
|
|
||||||
|
|
||||||
for fill in shape.fills().rev() {
|
|
||||||
self.render_fill(fill, shape.selrect, &shape.kind);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut paint = skia::Paint::default();
|
let mut paint = skia::Paint::default();
|
||||||
paint.set_blend_mode(shape.blend_mode.into());
|
paint.set_blend_mode(element.blend_mode().into());
|
||||||
paint.set_alpha_f(shape.opacity);
|
paint.set_alpha_f(element.opacity());
|
||||||
|
|
||||||
self.drawing_surface.draw(
|
self.drawing_surface.draw(
|
||||||
&mut self.final_surface.canvas(),
|
&mut self.final_surface.canvas(),
|
||||||
(0.0, 0.0),
|
(0.0, 0.0),
|
||||||
|
@ -217,38 +205,6 @@ impl RenderState {
|
||||||
self.flush();
|
self.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_fill(&mut self, fill: &Fill, selrect: Rect, kind: &Kind) {
|
|
||||||
match (fill, kind) {
|
|
||||||
(Fill::Image(image_fill), kind) => {
|
|
||||||
let image = self.images.get(&image_fill.id());
|
|
||||||
if let Some(image) = image {
|
|
||||||
draw_image_in_container(
|
|
||||||
&self.drawing_surface.canvas(),
|
|
||||||
&image,
|
|
||||||
image_fill.size(),
|
|
||||||
kind,
|
|
||||||
&fill.to_paint(&selrect),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(_, Kind::Rect(rect)) => {
|
|
||||||
self.drawing_surface
|
|
||||||
.canvas()
|
|
||||||
.draw_rect(rect, &fill.to_paint(&selrect));
|
|
||||||
}
|
|
||||||
(_, Kind::Circle(rect)) => {
|
|
||||||
self.drawing_surface
|
|
||||||
.canvas()
|
|
||||||
.draw_oval(rect, &fill.to_paint(&selrect));
|
|
||||||
}
|
|
||||||
(_, Kind::Path(path)) => {
|
|
||||||
self.drawing_surface
|
|
||||||
.canvas()
|
|
||||||
.draw_path(&path.to_skia_path(), &fill.to_paint(&selrect));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_all_from_cache(&mut self) -> Result<(), String> {
|
fn render_all_from_cache(&mut self) -> Result<(), String> {
|
||||||
self.reset_canvas();
|
self.reset_canvas();
|
||||||
|
|
||||||
|
@ -353,7 +309,7 @@ impl RenderState {
|
||||||
self.drawing_surface.canvas().save();
|
self.drawing_surface.canvas().save();
|
||||||
|
|
||||||
if !id.is_nil() {
|
if !id.is_nil() {
|
||||||
self.render_single_shape(shape);
|
self.render_single_element(shape);
|
||||||
if shape.clip_content {
|
if shape.clip_content {
|
||||||
self.drawing_surface.canvas().clip_rect(
|
self.drawing_surface.canvas().clip_rect(
|
||||||
shape.selrect,
|
shape.selrect,
|
||||||
|
|
|
@ -2,11 +2,12 @@ use crate::math;
|
||||||
use skia_safe as skia;
|
use skia_safe as skia;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
mod blend;
|
use crate::render::BlendMode;
|
||||||
|
|
||||||
mod fills;
|
mod fills;
|
||||||
mod images;
|
mod images;
|
||||||
mod paths;
|
mod paths;
|
||||||
pub use blend::*;
|
mod render;
|
||||||
pub use fills::*;
|
pub use fills::*;
|
||||||
pub use images::*;
|
pub use images::*;
|
||||||
pub use paths::*;
|
pub use paths::*;
|
||||||
|
|
92
render-wasm/src/shapes/render.rs
Normal file
92
render-wasm/src/shapes/render.rs
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
use skia_safe as skia;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
use super::{draw_image_in_container, Fill, Image, Kind, Shape};
|
||||||
|
use crate::math::Rect;
|
||||||
|
use crate::render::Renderable;
|
||||||
|
|
||||||
|
impl Renderable for Shape {
|
||||||
|
fn blend_mode(&self) -> crate::render::BlendMode {
|
||||||
|
self.blend_mode
|
||||||
|
}
|
||||||
|
|
||||||
|
fn opacity(&self) -> f32 {
|
||||||
|
self.opacity
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(
|
||||||
|
&self,
|
||||||
|
surface: &mut skia_safe::Surface,
|
||||||
|
images: &HashMap<Uuid, Image>,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
let mut transform = skia::Matrix::new_identity();
|
||||||
|
let (translate_x, translate_y) = self.translation();
|
||||||
|
let (scale_x, scale_y) = self.scale();
|
||||||
|
let (skew_x, skew_y) = self.skew();
|
||||||
|
transform.set_all(
|
||||||
|
scale_x,
|
||||||
|
skew_x,
|
||||||
|
translate_x,
|
||||||
|
skew_y,
|
||||||
|
scale_y,
|
||||||
|
translate_y,
|
||||||
|
0.,
|
||||||
|
0.,
|
||||||
|
1.,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check transform-matrix code from common/src/app/common/geom/shapes/transforms.cljc
|
||||||
|
let center = self.selrect.center();
|
||||||
|
let mut matrix = skia::Matrix::new_identity();
|
||||||
|
matrix.pre_translate(center);
|
||||||
|
matrix.pre_concat(&transform);
|
||||||
|
matrix.pre_translate(-center);
|
||||||
|
|
||||||
|
surface.canvas().concat(&matrix);
|
||||||
|
|
||||||
|
for fill in self.fills().rev() {
|
||||||
|
render_fill(surface, images, fill, self.selrect, &self.kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut paint = skia::Paint::default();
|
||||||
|
paint.set_blend_mode(self.blend_mode.into());
|
||||||
|
paint.set_alpha_f(self.opacity);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_fill(
|
||||||
|
surface: &mut skia::Surface,
|
||||||
|
images: &HashMap<Uuid, Image>,
|
||||||
|
fill: &Fill,
|
||||||
|
selrect: Rect,
|
||||||
|
kind: &Kind,
|
||||||
|
) {
|
||||||
|
match (fill, kind) {
|
||||||
|
(Fill::Image(image_fill), kind) => {
|
||||||
|
let image = images.get(&image_fill.id());
|
||||||
|
if let Some(image) = image {
|
||||||
|
draw_image_in_container(
|
||||||
|
surface.canvas(),
|
||||||
|
&image,
|
||||||
|
image_fill.size(),
|
||||||
|
kind,
|
||||||
|
&fill.to_paint(&selrect),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(_, Kind::Rect(rect)) => {
|
||||||
|
surface.canvas().draw_rect(rect, &fill.to_paint(&selrect));
|
||||||
|
}
|
||||||
|
(_, Kind::Circle(rect)) => {
|
||||||
|
surface.canvas().draw_oval(rect, &fill.to_paint(&selrect));
|
||||||
|
}
|
||||||
|
(_, Kind::Path(path)) => {
|
||||||
|
surface
|
||||||
|
.canvas()
|
||||||
|
.draw_path(&path.to_skia_path(), &fill.to_paint(&selrect));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue