Skip to content

Commit

Permalink
refactor(painter): 💡 implement svg implement by paintcommand
Browse files Browse the repository at this point in the history
  • Loading branch information
wjian23 committed Sep 20, 2023
1 parent a74e72a commit f52ac97
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 143 deletions.
64 changes: 8 additions & 56 deletions gpu/src/gpu_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,12 +241,7 @@ where
if let Some((rect, mask_head)) = self.new_mask_layer(path) {
self.update_to_radial_gradient_indices();
let prim: RadialGradientPrimitive = RadialGradientPrimitive {
transform: radial_gradient
.transform
.then(&ts)
.inverse()
.unwrap()
.to_array(),
transform: ts.inverse().unwrap().to_array(),
stop_start: self.radial_gradient_stops.len() as u32,
stop_cnt: radial_gradient.stops.len() as u32,
start_center: radial_gradient.start_center.to_array(),
Expand Down Expand Up @@ -279,12 +274,7 @@ where
if let Some((rect, mask_head)) = self.new_mask_layer(path) {
self.update_to_linear_gradient_indices();
let prim: LinearGradientPrimitive = LinearGradientPrimitive {
transform: linear_gradient
.transform
.then(&ts)
.inverse()
.unwrap()
.to_array(),
transform: ts.inverse().unwrap().to_array(),
stop_start: self.linear_gradient_stops.len() as u32,
stop_cnt: linear_gradient.stops.len() as u32,
start_position: linear_gradient.start.to_array(),
Expand Down Expand Up @@ -541,10 +531,7 @@ mod tests {
use ribir_algo::ShareResource;
use ribir_dev_helper::*;
use ribir_geom::*;
use ribir_painter::{
color::{LinearGradient, RadialGradient},
Brush, Color, GradientStop, Painter, Path, PixelImage,
};
use ribir_painter::{Brush, Color, Painter, Path, PixelImage, Svg};

fn painter(bounds: Size) -> Painter { Painter::new(Rect::from_size(bounds)) }

Expand Down Expand Up @@ -682,48 +669,13 @@ mod tests {
painter
}

painter_backend_eq_image_test!(draw_radial_gradient);
fn draw_radial_gradient() -> Painter {
painter_backend_eq_image_test!(draw_svg_gradient);
fn draw_svg_gradient() -> Painter {
let mut painter = painter(Size::new(64., 64.));
let brush = Brush::RadialGradient(RadialGradient {
start_center: Point::new(16., 32.),
start_radius: 0.,
end_center: Point::new(32., 32.),
end_radius: 32.,
stops: vec![
GradientStop::new(Color::RED, 0.),
GradientStop::new(Color::BLUE, 1.),
],
transform: Transform::translation(16., 0.),
..Default::default()
});

painter
.set_brush(brush)
.rect(&Rect::from_size(Size::new(64., 64.)))
.fill();

painter
}

painter_backend_eq_image_test!(draw_linear_gradient);
fn draw_linear_gradient() -> Painter {
let mut painter = painter(Size::new(32., 32.));
let brush = Brush::LinearGradient(LinearGradient {
start: Point::new(0., 0.),
end: Point::new(16., 16.),
stops: vec![
GradientStop::new(Color::RED, 0.),
GradientStop::new(Color::BLUE, 1.),
],
..Default::default()
});

painter
.set_brush(brush)
.rect(&Rect::from_size(Size::new(64., 64.)))
.fill();
let svg =
Svg::parse_from_bytes(include_bytes!("../../tests/assets/fill_with_gradient.svg")).unwrap();

painter.draw_svg(&svg);
painter
}
}
4 changes: 2 additions & 2 deletions gpu/src/gpu_backend/textures_mgr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ where
// apply path transform matrix to view.
.then(path_ts)
}

let prefer_scale: f32 = transform.m11.abs().max(transform.m22.abs());
let Transform { m11, m12, m21, m22, .. } = *transform;
let prefer_scale: f32 = (m11.abs() + m12.abs()).max(m21.abs() + m22.abs());
let key = PathKey::from_path(path);

if let Some(h) = self
Expand Down
4 changes: 1 addition & 3 deletions painter/src/color.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use material_color_utilities_rs::htc;
use ribir_geom::{Point, Transform};
use ribir_geom::Point;
use serde::{Deserialize, Serialize};

use crate::SpreadMethod;
Expand Down Expand Up @@ -30,7 +30,6 @@ pub struct RadialGradient {
pub end_center: Point,
pub end_radius: f32,
pub stops: Vec<GradientStop>,
pub transform: Transform,
pub spread_method: SpreadMethod,
}

Expand All @@ -39,7 +38,6 @@ pub struct LinearGradient {
pub start: Point,
pub end: Point,
pub stops: Vec<GradientStop>,
pub transform: Transform,
pub spread_method: SpreadMethod,
}

Expand Down
45 changes: 35 additions & 10 deletions painter/src/painter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,36 @@ pub enum PaintCommand {
PopClip,
}

impl PaintCommand {
pub fn pre_transform(mut self, transform: &Transform) -> Self {
match &mut self {
PaintCommand::ColorPath { path, .. }
| PaintCommand::ImgPath { path, .. }
| PaintCommand::RadialGradient { path, .. }
| PaintCommand::LinearGradient { path, .. }
| PaintCommand::Clip(path) => {
path.transform = path.transform.then(transform);
}
PaintCommand::PopClip => {}
}
self
}

pub fn transform(mut self, transform: &Transform) -> Self {
match &mut self {
PaintCommand::ColorPath { path, .. }
| PaintCommand::ImgPath { path, .. }
| PaintCommand::RadialGradient { path, .. }
| PaintCommand::LinearGradient { path, .. }
| PaintCommand::Clip(path) => {
path.transform = transform.then(&path.transform);
}
PaintCommand::PopClip => {}
}
self
}
}

#[derive(Clone)]
struct PainterState {
/// The line width use to stroke path.
Expand Down Expand Up @@ -474,16 +504,11 @@ impl Painter {
}

pub fn draw_svg(&mut self, svg: &Svg) -> &mut Self {
self.scale(svg.view_scale.x, svg.view_scale.y);
svg.paths.iter().for_each(|c| {
self.set_brush(c.brush.clone());
match &c.style {
PathPaintStyle::Fill => self.fill_path(c.path.clone()),
PathPaintStyle::Stroke(options) => self
.set_strokes(options.clone())
.stroke_path(c.path.clone()),
};
});
let transform = *self.get_transform();
svg
.paint_commands
.iter()
.for_each(|c| self.commands.push(c.clone().pre_transform(&transform)));
self
}

Expand Down
Loading

0 comments on commit f52ac97

Please sign in to comment.