mirror of
https://github.com/penpot/penpot.git
synced 2025-02-01 11:59:17 -05:00
♻️ Refactor blend mode and fills into their own submodules
This commit is contained in:
parent
2d4281bdf2
commit
00ab9ad3f0
5 changed files with 116 additions and 109 deletions
|
@ -154,7 +154,7 @@ pub extern "C" fn add_shape_solid_fill(raw_color: u32) {
|
||||||
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() {
|
||||||
let color = skia::Color::new(raw_color);
|
let color = skia::Color::new(raw_color);
|
||||||
shape.add_fill(shapes::Fill::from(color));
|
shape.add_fill(shapes::Fill::Solid(color));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use skia_safe as skia;
|
use skia_safe as skia;
|
||||||
|
|
||||||
pub type Rect = skia::Rect;
|
pub type Rect = skia::Rect;
|
||||||
pub type Matrix = skia::Matrix;
|
|
||||||
|
|
|
@ -2,12 +2,17 @@ use crate::math;
|
||||||
use skia_safe as skia;
|
use skia_safe as skia;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
mod blend;
|
||||||
|
mod fills;
|
||||||
|
pub use blend::*;
|
||||||
|
pub use fills::*;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum Kind {
|
pub enum Kind {
|
||||||
Rect,
|
Rect,
|
||||||
}
|
}
|
||||||
|
|
||||||
type Color = skia::Color;
|
pub type Color = skia::Color;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Matrix {
|
pub struct Matrix {
|
||||||
|
@ -32,110 +37,6 @@ impl Matrix {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
|
||||||
pub struct Gradient {
|
|
||||||
colors: Vec<Color>,
|
|
||||||
offsets: Vec<f32>,
|
|
||||||
opacity: f32,
|
|
||||||
start: (f32, f32),
|
|
||||||
end: (f32, f32),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Gradient {
|
|
||||||
fn to_shader(&self, rect: &math::Rect) -> skia::Shader {
|
|
||||||
let start = (
|
|
||||||
rect.left + self.start.0 * rect.width(),
|
|
||||||
rect.top + self.start.1 * rect.height(),
|
|
||||||
);
|
|
||||||
let end = (
|
|
||||||
rect.left + self.end.0 * rect.width(),
|
|
||||||
rect.top + self.end.1 * rect.height(),
|
|
||||||
);
|
|
||||||
let shader = skia::shader::Shader::linear_gradient(
|
|
||||||
(start, end),
|
|
||||||
self.colors.as_slice(),
|
|
||||||
self.offsets.as_slice(),
|
|
||||||
skia::TileMode::Clamp,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
shader
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
|
||||||
pub enum Fill {
|
|
||||||
Solid(Color),
|
|
||||||
LinearGradient(Gradient),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Color> for Fill {
|
|
||||||
fn from(value: Color) -> Self {
|
|
||||||
Self::Solid(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Fill {
|
|
||||||
pub fn new_linear_gradient(start: (f32, f32), end: (f32, f32), opacity: f32) -> Self {
|
|
||||||
Self::LinearGradient(Gradient {
|
|
||||||
start,
|
|
||||||
end,
|
|
||||||
opacity,
|
|
||||||
colors: vec![],
|
|
||||||
offsets: vec![],
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_paint(&self, rect: &math::Rect) -> skia::Paint {
|
|
||||||
match self {
|
|
||||||
Self::Solid(color) => {
|
|
||||||
let mut p = skia::Paint::default();
|
|
||||||
p.set_color(*color);
|
|
||||||
p.set_style(skia::PaintStyle::Fill);
|
|
||||||
p.set_anti_alias(true);
|
|
||||||
p.set_blend_mode(skia::BlendMode::SrcOver);
|
|
||||||
p
|
|
||||||
}
|
|
||||||
Self::LinearGradient(gradient) => {
|
|
||||||
let mut p = skia::Paint::default();
|
|
||||||
p.set_shader(gradient.to_shader(&rect));
|
|
||||||
p.set_alpha((gradient.opacity * 255.) as u8);
|
|
||||||
p.set_style(skia::PaintStyle::Fill);
|
|
||||||
p.set_blend_mode(skia::BlendMode::SrcOver);
|
|
||||||
p
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
|
||||||
pub struct BlendMode(skia::BlendMode);
|
|
||||||
|
|
||||||
impl Default for BlendMode {
|
|
||||||
fn default() -> Self {
|
|
||||||
BlendMode(skia::BlendMode::SrcOver)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<i32> for BlendMode {
|
|
||||||
fn from(value: i32) -> Self {
|
|
||||||
if value <= skia::BlendMode::Luminosity as i32 {
|
|
||||||
unsafe { Self(std::mem::transmute(value)) }
|
|
||||||
} else {
|
|
||||||
Self::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Into<skia::BlendMode> for BlendMode {
|
|
||||||
fn into(self) -> skia::BlendMode {
|
|
||||||
match self {
|
|
||||||
Self(skia_blend) => skia_blend,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub struct Shape {
|
pub struct Shape {
|
||||||
|
@ -196,8 +97,7 @@ impl Shape {
|
||||||
_ => Err("Active fill is not a gradient"),
|
_ => Err("Active fill is not a gradient"),
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
gradient.colors.push(color);
|
gradient.add_stop(color, offset);
|
||||||
gradient.offsets.push(offset);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
28
render-wasm/src/shapes/blend.rs
Normal file
28
render-wasm/src/shapes/blend.rs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
use skia_safe as skia;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||||
|
pub struct BlendMode(skia::BlendMode);
|
||||||
|
|
||||||
|
impl Default for BlendMode {
|
||||||
|
fn default() -> Self {
|
||||||
|
BlendMode(skia::BlendMode::SrcOver)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<i32> for BlendMode {
|
||||||
|
fn from(value: i32) -> Self {
|
||||||
|
if value <= skia::BlendMode::Luminosity as i32 {
|
||||||
|
unsafe { Self(std::mem::transmute(value)) }
|
||||||
|
} else {
|
||||||
|
Self::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<skia::BlendMode> for BlendMode {
|
||||||
|
fn into(self) -> skia::BlendMode {
|
||||||
|
match self {
|
||||||
|
Self(skia_blend) => skia_blend,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
80
render-wasm/src/shapes/fills.rs
Normal file
80
render-wasm/src/shapes/fills.rs
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
use skia_safe as skia;
|
||||||
|
|
||||||
|
use super::Color;
|
||||||
|
use crate::math;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub struct Gradient {
|
||||||
|
colors: Vec<Color>,
|
||||||
|
offsets: Vec<f32>,
|
||||||
|
opacity: f32,
|
||||||
|
start: (f32, f32),
|
||||||
|
end: (f32, f32),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Gradient {
|
||||||
|
pub fn add_stop(&mut self, color: Color, offset: f32) {
|
||||||
|
self.colors.push(color);
|
||||||
|
self.offsets.push(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_shader(&self, rect: &math::Rect) -> skia::Shader {
|
||||||
|
let start = (
|
||||||
|
rect.left + self.start.0 * rect.width(),
|
||||||
|
rect.top + self.start.1 * rect.height(),
|
||||||
|
);
|
||||||
|
let end = (
|
||||||
|
rect.left + self.end.0 * rect.width(),
|
||||||
|
rect.top + self.end.1 * rect.height(),
|
||||||
|
);
|
||||||
|
let shader = skia::shader::Shader::linear_gradient(
|
||||||
|
(start, end),
|
||||||
|
self.colors.as_slice(),
|
||||||
|
self.offsets.as_slice(),
|
||||||
|
skia::TileMode::Clamp,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
shader
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub enum Fill {
|
||||||
|
Solid(Color),
|
||||||
|
LinearGradient(Gradient),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Fill {
|
||||||
|
pub fn new_linear_gradient(start: (f32, f32), end: (f32, f32), opacity: f32) -> Self {
|
||||||
|
Self::LinearGradient(Gradient {
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
opacity,
|
||||||
|
colors: vec![],
|
||||||
|
offsets: vec![],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_paint(&self, rect: &math::Rect) -> skia::Paint {
|
||||||
|
match self {
|
||||||
|
Self::Solid(color) => {
|
||||||
|
let mut p = skia::Paint::default();
|
||||||
|
p.set_color(*color);
|
||||||
|
p.set_style(skia::PaintStyle::Fill);
|
||||||
|
p.set_anti_alias(true);
|
||||||
|
p.set_blend_mode(skia::BlendMode::SrcOver);
|
||||||
|
p
|
||||||
|
}
|
||||||
|
Self::LinearGradient(gradient) => {
|
||||||
|
let mut p = skia::Paint::default();
|
||||||
|
p.set_shader(gradient.to_shader(&rect));
|
||||||
|
p.set_alpha((gradient.opacity * 255.) as u8);
|
||||||
|
p.set_style(skia::PaintStyle::Fill);
|
||||||
|
p.set_blend_mode(skia::BlendMode::SrcOver);
|
||||||
|
p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue