0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-21 06:02:32 -05:00

🎉 Stroke style support for wasm render

This commit is contained in:
Alejandro Alonso 2025-01-03 14:07:40 +01:00
parent e551dd5a99
commit 2467e033b7
3 changed files with 70 additions and 19 deletions

View file

@ -211,6 +211,14 @@
(store-image id))))))
fills))
(defn- translate-stroke-style
[stroke-style]
(case stroke-style
:dotted 1
:dashed 2
:mixed 3
0))
(defn set-shape-strokes
[strokes]
(h/call internal-module "_clear_shape_strokes")
@ -220,11 +228,12 @@
gradient (:stroke-color-gradient stroke)
image (:stroke-image stroke)
width (:stroke-width stroke)
align (:stroke-alignment stroke)]
align (:stroke-alignment stroke)
style (-> stroke :stroke-style translate-stroke-style)]
(case align
:inner (h/call internal-module "_add_shape_inner_stroke" width)
:outer (h/call internal-module "_add_shape_outer_stroke" width)
(h/call internal-module "_add_shape_center_stroke" width))
:inner (h/call internal-module "_add_shape_inner_stroke" width style)
:outer (h/call internal-module "_add_shape_outer_stroke" width style)
(h/call internal-module "_add_shape_center_stroke" width style))
(cond
(some? gradient)

View file

@ -347,26 +347,26 @@ pub extern "C" fn set_shape_path_content() {
}
#[no_mangle]
pub extern "C" fn add_shape_center_stroke(width: f32) {
pub extern "C" fn add_shape_center_stroke(width: f32, style: i32) {
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
if let Some(shape) = state.current_shape() {
shape.add_stroke(shapes::Stroke::new_center_stroke(width))
shape.add_stroke(shapes::Stroke::new_center_stroke(width, style));
}
}
#[no_mangle]
pub extern "C" fn add_shape_inner_stroke(width: f32) {
pub extern "C" fn add_shape_inner_stroke(width: f32, style: i32) {
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
if let Some(shape) = state.current_shape() {
shape.add_stroke(shapes::Stroke::new_inner_stroke(width))
shape.add_stroke(shapes::Stroke::new_inner_stroke(width, style))
}
}
#[no_mangle]
pub extern "C" fn add_shape_outer_stroke(width: f32) {
pub extern "C" fn add_shape_outer_stroke(width: f32, style: i32) {
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
if let Some(shape) = state.current_shape() {
shape.add_stroke(shapes::Stroke::new_outer_stroke(width))
shape.add_stroke(shapes::Stroke::new_outer_stroke(width, style))
}
}

View file

@ -5,9 +5,20 @@ use skia_safe as skia;
#[derive(Debug, Clone, PartialEq)]
pub enum StrokeStyle {
Solid,
// Dotted,
// Dashed,
// Mixed,
Dotted,
Dashed,
Mixed,
}
impl From<i32> for StrokeStyle {
fn from(value: i32) -> Self {
match value {
1 => StrokeStyle::Dotted,
2 => StrokeStyle::Dashed,
3 => StrokeStyle::Mixed,
_ => StrokeStyle::Solid,
}
}
}
#[derive(Debug, Clone, PartialEq)]
@ -39,36 +50,36 @@ pub struct Stroke {
}
impl Stroke {
pub fn new_center_stroke(width: f32) -> Self {
pub fn new_center_stroke(width: f32, style: i32) -> Self {
let transparent = skia::Color::from_argb(0, 0, 0, 0);
Stroke {
fill: Fill::Solid(transparent),
width: width,
style: StrokeStyle::Solid,
style: StrokeStyle::from(style),
cap_end: StrokeCap::None,
cap_start: StrokeCap::None,
kind: StrokeKind::CenterStroke,
}
}
pub fn new_inner_stroke(width: f32) -> Self {
pub fn new_inner_stroke(width: f32, style: i32) -> Self {
let transparent = skia::Color::from_argb(0, 0, 0, 0);
Stroke {
fill: Fill::Solid(transparent),
width: width,
style: StrokeStyle::Solid,
style: StrokeStyle::from(style),
cap_end: StrokeCap::None,
cap_start: StrokeCap::None,
kind: StrokeKind::InnerStroke,
}
}
pub fn new_outer_stroke(width: f32) -> Self {
pub fn new_outer_stroke(width: f32, style: i32) -> Self {
let transparent = skia::Color::from_argb(0, 0, 0, 0);
Stroke {
fill: Fill::Solid(transparent),
width: width,
style: StrokeStyle::Solid,
style: StrokeStyle::from(style),
cap_end: StrokeCap::None,
cap_start: StrokeCap::None,
kind: StrokeKind::OuterStroke,
@ -108,6 +119,37 @@ impl Stroke {
paint.set_style(skia::PaintStyle::Stroke);
paint.set_stroke_width(self.width);
paint.set_anti_alias(true);
if self.style != StrokeStyle::Solid {
let path_effect = match self.style {
StrokeStyle::Dotted => {
let mut circle_path = skia::Path::new();
circle_path.add_circle((0.0, 0.0), self.width / 2.0, None);
let advance = self.width + 5.0;
skia::PathEffect::path_1d(
&circle_path,
advance,
0.0,
skia::path_1d_path_effect::Style::Translate,
)
}
StrokeStyle::Dashed => {
skia::PathEffect::dash(&[self.width + 10., self.width + 10.], 0.)
}
StrokeStyle::Mixed => skia::PathEffect::dash(
&[
self.width + 5.,
self.width + 5.,
self.width + 1.,
self.width + 5.,
],
0.,
),
_ => None,
};
paint.set_path_effect(path_effect);
}
paint
}