mirror of
https://github.com/penpot/penpot.git
synced 2025-02-01 11:59:17 -05:00
♻️ Refactor navigate() method
This commit is contained in:
parent
52a705ac02
commit
5ce6cbff6f
3 changed files with 70 additions and 55 deletions
|
@ -55,8 +55,13 @@ impl GpuState {
|
||||||
pub(crate) struct CachedSurfaceImage {
|
pub(crate) struct CachedSurfaceImage {
|
||||||
pub image: Image,
|
pub image: Image,
|
||||||
pub viewbox: Viewbox,
|
pub viewbox: Viewbox,
|
||||||
// is_complete indicates if stored image renders the complete shape tree
|
has_all_shapes: bool,
|
||||||
pub is_complete: bool,
|
}
|
||||||
|
|
||||||
|
impl CachedSurfaceImage {
|
||||||
|
fn is_dirty(&self, viewbox: &Viewbox) -> bool {
|
||||||
|
!self.has_all_shapes && !self.viewbox.area.contains(viewbox.area)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Copy, Clone, PartialEq)]
|
#[derive(Debug, Default, Copy, Clone, PartialEq)]
|
||||||
|
@ -198,49 +203,20 @@ impl RenderState {
|
||||||
.clear(skia::Color::TRANSPARENT);
|
.clear(skia::Color::TRANSPARENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn navigate(&mut self, viewbox: &Viewbox, shapes: &HashMap<Uuid, Shape>) {
|
pub fn navigate(
|
||||||
self.reset_canvas();
|
&mut self,
|
||||||
if let Some(cached_surface_image) = &self.cached_surface_image {
|
viewbox: &Viewbox,
|
||||||
// If we are drawing something bigger than the visible let's do a redraw
|
shapes: &HashMap<Uuid, Shape>,
|
||||||
if !cached_surface_image.is_complete
|
) -> Result<(), String> {
|
||||||
&& ((viewbox.x > cached_surface_image.viewbox.x)
|
if let Some(cached_surface_image) = self.cached_surface_image.as_ref() {
|
||||||
|| (-viewbox.x + viewbox.area.width()
|
if cached_surface_image.is_dirty(viewbox) {
|
||||||
> -cached_surface_image.viewbox.x
|
|
||||||
+ cached_surface_image.viewbox.area.width())
|
|
||||||
|| (viewbox.y > cached_surface_image.viewbox.y)
|
|
||||||
|| (-viewbox.y + viewbox.area.height()
|
|
||||||
> -cached_surface_image.viewbox.y
|
|
||||||
+ cached_surface_image.viewbox.area.height()))
|
|
||||||
{
|
|
||||||
self.render_all(viewbox, shapes, true);
|
self.render_all(viewbox, shapes, true);
|
||||||
} else {
|
} else {
|
||||||
let image = &cached_surface_image.image;
|
self.render_all_from_cache(viewbox)?;
|
||||||
let paint = skia::Paint::default();
|
|
||||||
self.final_surface.canvas().save();
|
|
||||||
self.drawing_surface.canvas().save();
|
|
||||||
|
|
||||||
let navigate_zoom = viewbox.zoom / cached_surface_image.viewbox.zoom;
|
|
||||||
let navigate_x = cached_surface_image.viewbox.zoom
|
|
||||||
* (viewbox.x - cached_surface_image.viewbox.x);
|
|
||||||
let navigate_y = cached_surface_image.viewbox.zoom
|
|
||||||
* (viewbox.y - cached_surface_image.viewbox.y);
|
|
||||||
|
|
||||||
self.final_surface
|
|
||||||
.canvas()
|
|
||||||
.scale((navigate_zoom, navigate_zoom));
|
|
||||||
self.final_surface
|
|
||||||
.canvas()
|
|
||||||
.translate((navigate_x, navigate_y));
|
|
||||||
self.final_surface
|
|
||||||
.canvas()
|
|
||||||
.draw_image(image.clone(), (0, 0), Some(&paint));
|
|
||||||
|
|
||||||
self.final_surface.canvas().restore();
|
|
||||||
self.drawing_surface.canvas().restore();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.flush();
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_all(
|
pub fn render_all(
|
||||||
|
@ -251,14 +227,14 @@ impl RenderState {
|
||||||
) {
|
) {
|
||||||
self.reset_canvas();
|
self.reset_canvas();
|
||||||
self.scale(viewbox.zoom, viewbox.zoom);
|
self.scale(viewbox.zoom, viewbox.zoom);
|
||||||
self.translate(viewbox.x, viewbox.y);
|
self.translate(viewbox.pan_x, viewbox.pan_y);
|
||||||
|
|
||||||
let is_complete = self.render_shape_tree(&Uuid::nil(), viewbox, shapes);
|
let is_complete = self.render_shape_tree(&Uuid::nil(), viewbox, shapes);
|
||||||
if generate_cached_surface_image || self.cached_surface_image.is_none() {
|
if generate_cached_surface_image || self.cached_surface_image.is_none() {
|
||||||
self.cached_surface_image = Some(CachedSurfaceImage {
|
self.cached_surface_image = Some(CachedSurfaceImage {
|
||||||
image: self.final_surface.image_snapshot(),
|
image: self.final_surface.image_snapshot(),
|
||||||
viewbox: viewbox.clone(),
|
viewbox: viewbox.clone(),
|
||||||
is_complete,
|
has_all_shapes: is_complete,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,6 +245,41 @@ impl RenderState {
|
||||||
self.flush();
|
self.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render_all_from_cache(&mut self, viewbox: &Viewbox) -> Result<(), String> {
|
||||||
|
self.reset_canvas();
|
||||||
|
|
||||||
|
let cached = self
|
||||||
|
.cached_surface_image
|
||||||
|
.as_ref()
|
||||||
|
.ok_or("Uninitialized cached surface image")?;
|
||||||
|
|
||||||
|
let image = &cached.image;
|
||||||
|
let paint = skia::Paint::default();
|
||||||
|
self.final_surface.canvas().save();
|
||||||
|
self.drawing_surface.canvas().save();
|
||||||
|
|
||||||
|
let navigate_zoom = viewbox.zoom / cached.viewbox.zoom;
|
||||||
|
let navigate_x = cached.viewbox.zoom * (viewbox.pan_x - cached.viewbox.pan_x);
|
||||||
|
let navigate_y = cached.viewbox.zoom * (viewbox.pan_y - cached.viewbox.pan_y);
|
||||||
|
|
||||||
|
self.final_surface
|
||||||
|
.canvas()
|
||||||
|
.scale((navigate_zoom, navigate_zoom));
|
||||||
|
self.final_surface
|
||||||
|
.canvas()
|
||||||
|
.translate((navigate_x, navigate_y));
|
||||||
|
self.final_surface
|
||||||
|
.canvas()
|
||||||
|
.draw_image(image.clone(), (0, 0), Some(&paint));
|
||||||
|
|
||||||
|
self.final_surface.canvas().restore();
|
||||||
|
self.drawing_surface.canvas().restore();
|
||||||
|
|
||||||
|
self.flush();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn render_debug_view(&mut self, viewbox: &Viewbox) {
|
fn render_debug_view(&mut self, viewbox: &Viewbox) {
|
||||||
let mut paint = skia::Paint::default();
|
let mut paint = skia::Paint::default();
|
||||||
paint.set_style(skia::PaintStyle::Stroke);
|
paint.set_style(skia::PaintStyle::Stroke);
|
||||||
|
|
|
@ -27,8 +27,8 @@ impl<'a> State<'a> {
|
||||||
current_shape: None,
|
current_shape: None,
|
||||||
shapes: HashMap::with_capacity(capacity),
|
shapes: HashMap::with_capacity(capacity),
|
||||||
viewbox: Viewbox {
|
viewbox: Viewbox {
|
||||||
x: 0.,
|
pan_x: 0.,
|
||||||
y: 0.,
|
pan_y: 0.,
|
||||||
zoom: 1.,
|
zoom: 1.,
|
||||||
width: width as f32,
|
width: width as f32,
|
||||||
height: height as f32,
|
height: height as f32,
|
||||||
|
@ -47,7 +47,11 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn navigate(&mut self) {
|
pub fn navigate(&mut self) {
|
||||||
self.render_state.navigate(&self.viewbox, &self.shapes);
|
// TODO: propagate error to main fn
|
||||||
|
let _ = self
|
||||||
|
.render_state
|
||||||
|
.navigate(&self.viewbox, &self.shapes)
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_all(&mut self, generate_cached_surface_image: bool) {
|
pub fn render_all(&mut self, generate_cached_surface_image: bool) {
|
||||||
|
|
|
@ -2,8 +2,8 @@ use skia_safe as skia;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub(crate) struct Viewbox {
|
pub(crate) struct Viewbox {
|
||||||
pub x: f32,
|
pub pan_x: f32,
|
||||||
pub y: f32,
|
pub pan_y: f32,
|
||||||
pub width: f32,
|
pub width: f32,
|
||||||
pub height: f32,
|
pub height: f32,
|
||||||
pub zoom: f32,
|
pub zoom: f32,
|
||||||
|
@ -11,13 +11,13 @@ pub(crate) struct Viewbox {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Viewbox {
|
impl Viewbox {
|
||||||
pub fn set_all(&mut self, zoom: f32, x: f32, y: f32) -> &Self {
|
pub fn set_all(&mut self, zoom: f32, x: f32, y: f32) -> &mut Self {
|
||||||
self.x = x;
|
self.pan_x = x;
|
||||||
self.y = y;
|
self.pan_y = y;
|
||||||
self.zoom = zoom;
|
self.zoom = zoom;
|
||||||
self.area.set_xywh(
|
self.area.set_xywh(
|
||||||
-self.x,
|
-self.pan_x,
|
||||||
-self.y,
|
-self.pan_y,
|
||||||
self.width / self.zoom,
|
self.width / self.zoom,
|
||||||
self.height / self.zoom,
|
self.height / self.zoom,
|
||||||
);
|
);
|
||||||
|
@ -31,9 +31,9 @@ impl Viewbox {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_xy(&mut self, x: f32, y: f32) -> &Self {
|
pub fn set_xy(&mut self, x: f32, y: f32) -> &mut Self {
|
||||||
self.x = x;
|
self.pan_x = x;
|
||||||
self.y = y;
|
self.pan_y = y;
|
||||||
self.area.left = -x;
|
self.area.left = -x;
|
||||||
self.area.top = -y;
|
self.area.top = -y;
|
||||||
self
|
self
|
||||||
|
|
Loading…
Add table
Reference in a new issue