mirror of
https://github.com/penpot/penpot.git
synced 2025-05-21 13:36:14 +02:00
🎉 Basic wasm support for svg attrs and svg defs
This commit is contained in:
parent
751df46dc9
commit
79df616108
12 changed files with 452 additions and 60 deletions
|
@ -1,4 +1,5 @@
|
|||
use skia_safe::{self as skia, RRect};
|
||||
use std::collections::HashMap;
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::{BlurType, Corners, Fill, Image, Kind, Path, Shape, Stroke, StrokeCap, StrokeKind};
|
||||
|
@ -93,22 +94,68 @@ impl Renderable for Shape {
|
|||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn is_recursive(&self) -> bool {
|
||||
!matches!(self.kind, Kind::SVGRaw(_))
|
||||
}
|
||||
}
|
||||
|
||||
fn render_fills_for_kind(
|
||||
shape: &Shape,
|
||||
canvas: &skia::Canvas,
|
||||
images: &ImageStore,
|
||||
path_transform: Option<&skia::Matrix>,
|
||||
svg_attrs: &HashMap<String, String>,
|
||||
) {
|
||||
for fill in shape.fills().rev() {
|
||||
render_fill(
|
||||
canvas,
|
||||
images,
|
||||
fill,
|
||||
shape.selrect,
|
||||
&shape.kind,
|
||||
path_transform,
|
||||
svg_attrs,
|
||||
);
|
||||
}
|
||||
|
||||
//TODO: remove when strokes are implemented, this is just for testing paths with no fills
|
||||
if shape.fills().len() == 0 {
|
||||
if let Kind::Path(ref path) = shape.kind {
|
||||
let mut p = skia::Paint::default();
|
||||
p.set_style(skia_safe::PaintStyle::Stroke);
|
||||
p.set_stroke_width(2.0);
|
||||
p.set_anti_alias(true);
|
||||
p.set_blend_mode(skia::BlendMode::SrcOver);
|
||||
|
||||
if let Some("round") = svg_attrs.get("stroke-linecap").map(String::as_str) {
|
||||
p.set_stroke_cap(skia::paint::Cap::Round);
|
||||
}
|
||||
if let Some("round") = svg_attrs.get("stroke-linejoin").map(String::as_str) {
|
||||
p.set_stroke_join(skia::paint::Join::Round);
|
||||
}
|
||||
let mut skia_path = &mut path.to_skia_path();
|
||||
skia_path = skia_path.transform(path_transform.unwrap());
|
||||
canvas.draw_path(&skia_path, &p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn render_fill(
|
||||
surface: &mut skia::Surface,
|
||||
canvas: &skia::Canvas,
|
||||
images: &ImageStore,
|
||||
fill: &Fill,
|
||||
selrect: Rect,
|
||||
kind: &Kind,
|
||||
path_transform: Option<&skia::Matrix>,
|
||||
svg_attrs: &HashMap<String, String>,
|
||||
) {
|
||||
match (fill, kind) {
|
||||
(Fill::Image(image_fill), kind) => {
|
||||
let image = images.get(&image_fill.id());
|
||||
if let Some(image) = image {
|
||||
draw_image_fill_in_container(
|
||||
surface.canvas(),
|
||||
canvas,
|
||||
&image,
|
||||
image_fill.size(),
|
||||
kind,
|
||||
|
@ -119,20 +166,26 @@ fn render_fill(
|
|||
}
|
||||
}
|
||||
(_, Kind::Rect(rect, None)) => {
|
||||
surface.canvas().draw_rect(rect, &fill.to_paint(&selrect));
|
||||
canvas.draw_rect(rect, &fill.to_paint(&selrect));
|
||||
}
|
||||
(_, Kind::Rect(rect, Some(corners))) => {
|
||||
let rrect = RRect::new_rect_radii(rect, corners);
|
||||
surface.canvas().draw_rrect(rrect, &fill.to_paint(&selrect));
|
||||
canvas.draw_rrect(rrect, &fill.to_paint(&selrect));
|
||||
}
|
||||
(_, Kind::Circle(rect)) => {
|
||||
surface.canvas().draw_oval(rect, &fill.to_paint(&selrect));
|
||||
canvas.draw_oval(rect, &fill.to_paint(&selrect));
|
||||
}
|
||||
(_, Kind::Path(path)) | (_, Kind::Bool(_, path)) => {
|
||||
surface.canvas().draw_path(
|
||||
&path.to_skia_path().transform(path_transform.unwrap()),
|
||||
&fill.to_paint(&selrect),
|
||||
);
|
||||
let mut skia_path = &mut path.to_skia_path();
|
||||
skia_path = skia_path.transform(path_transform.unwrap());
|
||||
if let Some("evenodd") = svg_attrs.get("fill-rule").map(String::as_str) {
|
||||
skia_path.set_fill_type(skia::PathFillType::EvenOdd);
|
||||
}
|
||||
|
||||
canvas.draw_path(&skia_path, &fill.to_paint(&selrect));
|
||||
}
|
||||
(_, Kind::SVGRaw(_sr)) => {
|
||||
// NOOP
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -514,6 +567,9 @@ pub fn draw_image_fill_in_container(
|
|||
true,
|
||||
);
|
||||
}
|
||||
Kind::SVGRaw(_) => {
|
||||
canvas.clip_rect(container, skia::ClipOp::Intersect, true);
|
||||
}
|
||||
}
|
||||
|
||||
canvas.draw_image_rect(image, None, dest_rect, &paint);
|
||||
|
|
10
render-wasm/src/shapes/svgraw.rs
Normal file
10
render-wasm/src/shapes/svgraw.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct SVGRaw {
|
||||
pub content: String,
|
||||
}
|
||||
|
||||
impl SVGRaw {
|
||||
pub fn from_content(svg: String) -> SVGRaw {
|
||||
SVGRaw { content: svg }
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue