[Perf] add path protection logic

This commit is contained in:
Mist 2024-03-16 23:10:35 +08:00
parent d35273cfae
commit b92e7706e6
11 changed files with 34 additions and 188 deletions

1
generator/Cargo.lock generated
View file

@ -357,6 +357,7 @@ dependencies = [
"arboard", "arboard",
"cosmic-text", "cosmic-text",
"nvim-oxi", "nvim-oxi",
"regex",
"serde", "serde",
"syntect", "syntect",
"thiserror", "thiserror",

View file

@ -11,6 +11,7 @@ cosmic-text = "0.11.2"
serde = "1.0.197" serde = "1.0.197"
arboard = "3.3.2" arboard = "3.3.2"
thiserror = "1.0.58" thiserror = "1.0.58"
regex = "1.10.3"
[lib] [lib]
crate-type = ["cdylib"] crate-type = ["cdylib"]

View file

@ -1,121 +1,2 @@
pub mod code; pub mod code;
pub mod mac_title_bar; pub mod mac_title_bar;
use crate::edges::{edge::Edge, padding::Padding};
use self::{code::Code, mac_title_bar::MacTitleBar};
use super::{interface::component::Component, rect::Rect};
const CONTROL_BAR_RADIUS: f32 = 8.;
pub struct Editor {
x: f32,
y: f32,
w: f32,
h: f32,
children: Vec<Box<dyn Component>>,
has_title_bar: bool,
padding: Padding,
code_y_offset: f32,
}
impl Component for Editor {
fn children(&self) -> &Vec<Box<dyn Component>> {
&self.children
}
// fn get_children(&self) -> &Vec<Box<dyn Component>> {
// &self.children
// }
}
impl Editor {
pub fn new(x: f32, y: f32, w: f32, h: f32, has_title_bar: bool) -> Editor {
Editor {
x,
y,
w,
h,
has_title_bar,
padding: Padding {
left: 0.,
right: 0.,
top: 0.,
bottom: 0.,
},
children: vec![],
code_y_offset: 0.,
}
}
// pub fn render_mac_title_bar(mut self) -> Self {
// if self.has_title_bar {
// let mac_title_bar = MacTitleBar::from_xyr(
// self.x + CONTROL_BAR_RADIUS + self.padding.left,
// self.y + CONTROL_BAR_RADIUS + self.padding.top,
// CONTROL_BAR_RADIUS,
// );
//
// self.children.push(Box::new(mac_title_bar));
// }
//
// self
// }
// pub fn render_editor(mut self, radius: f32) -> Self {
// let roundrect = Rect::from_xywh(
// self.x,
// self.y,
// self.w + self.padding.horizontal(),
// self.h + self.header_height() + self.padding.vertical() + self.code_y_offset,
// )
// .radius(radius);
// self.children.push(Box::new(roundrect));
//
// self
// }
pub fn width(&self) -> f32 {
self.w + self.padding.horizontal()
}
pub fn height(&self) -> f32 {
self.h + self.header_height() + self.padding.vertical() + self.code_y_offset
}
pub fn header_height(&self) -> f32 {
if self.has_title_bar {
CONTROL_BAR_RADIUS * 2.
} else {
0.
}
}
// pub fn render_code(mut self, code: &str, line_height: f32, font_size: f32) -> Self {
// let code = Code::new(
// self.x + self.padding.left,
// self.y + self.header_height() + self.padding.top + self.code_y_offset,
// self.w,
// self.h,
// code.to_string(),
// )
// .line_height(line_height)
// .font_size(font_size);
//
// self.children.push(Box::new(code));
// self
// }
pub fn padding(mut self, padding: Padding) -> Self {
self.padding = padding;
self
}
pub fn code_y_offset(mut self, code_y_offset: f32) -> Self {
if self.has_title_bar {
self.code_y_offset = code_y_offset;
}
self
}
}

View file

@ -2,10 +2,7 @@ use std::sync::Arc;
use tiny_skia::Pixmap; use tiny_skia::Pixmap;
use crate::{ use crate::{config::TakeSnapshotParams, edges::edge::Edge};
config::TakeSnapshotParams,
edges::{edge::Edge, padding::Padding},
};
use super::{ use super::{
render_error, render_error,

View file

@ -3,7 +3,7 @@ use crate::edges::padding::Padding;
use super::interface::{ use super::interface::{
component::{Component, ComponentContext, RenderParams}, component::{Component, ComponentContext, RenderParams},
render_error, render_error,
style::{ComponentAlign, ComponentStyle, RawComponentStyle, Size, Style}, style::{ComponentAlign, ComponentStyle, RawComponentStyle, Style},
}; };
use tiny_skia::{FillRule, Paint, PathBuilder, Pixmap, Transform}; use tiny_skia::{FillRule, Paint, PathBuilder, Pixmap, Transform};

View file

@ -11,7 +11,7 @@ use super::interface::{
pub struct Watermark { pub struct Watermark {
children: Vec<Box<dyn Component>>, children: Vec<Box<dyn Component>>,
value: Option<String>, value: String,
} }
impl Component for Watermark { impl Component for Watermark {
@ -24,7 +24,7 @@ impl Component for Watermark {
) -> render_error::Result<()> { ) -> render_error::Result<()> {
let params = &context.take_snapshot_params; let params = &context.take_snapshot_params;
if let Some(value) = &params.watermark { if &params.watermark != "" {
let attrs = Attrs::new().family(Family::Name( let attrs = Attrs::new().family(Family::Name(
&context.take_snapshot_params.watermark_font_family, &context.take_snapshot_params.watermark_font_family,
)); ));
@ -40,7 +40,7 @@ impl Component for Watermark {
render_params.y, render_params.y,
pixmap.width() as f32, pixmap.width() as f32,
pixmap.height() as f32, pixmap.height() as f32,
&value, &params.watermark,
attrs, attrs,
Some(Align::Center), Some(Align::Center),
pixmap, pixmap,
@ -57,7 +57,7 @@ impl Component for Watermark {
fn style(&self) -> RawComponentStyle { fn style(&self) -> RawComponentStyle {
let default_style = RawComponentStyle::default(); let default_style = RawComponentStyle::default();
if self.value.is_some() { if self.value != "" {
default_style.margin(Margin { default_style.margin(Margin {
bottom: 22., bottom: 22.,
top: 15., top: 15.,
@ -70,7 +70,7 @@ impl Component for Watermark {
} }
impl Watermark { impl Watermark {
pub fn new(value: Option<String>) -> Watermark { pub fn new(value: String) -> Watermark {
Watermark { Watermark {
children: vec![], children: vec![],
value, value,

View file

@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Clone)] #[derive(Serialize, Deserialize, Clone)]
pub struct TakeSnapshotParams { pub struct TakeSnapshotParams {
pub mac_window_bar: bool, pub mac_window_bar: bool,
pub watermark: Option<String>, pub watermark: String,
pub title: Option<String>, pub title: Option<String>,
pub code_font_family: String, pub code_font_family: String,
pub watermark_font_family: String, pub watermark_font_family: String,

View file

@ -4,6 +4,7 @@ mod config;
mod copy; mod copy;
mod edges; mod edges;
mod highlight; mod highlight;
mod path;
mod save; mod save;
mod snapshot; mod snapshot;
mod text; mod text;

10
generator/src/path.rs Normal file
View file

@ -0,0 +1,10 @@
use regex::Regex;
use std::env::{var, VarError};
pub fn parse_save_path(path: String) -> Result<String, VarError> {
let home_path = var("HOME")?;
let regex = Regex::new(r"(~|$HOME)").unwrap();
let path = regex.replace_all(&path, home_path);
Ok(path.to_string())
}

View file

@ -1,16 +1,24 @@
use crate::{config::TakeSnapshotParams, snapshot::take_snapshot}; use crate::{config::TakeSnapshotParams, path::parse_save_path, snapshot::take_snapshot};
use nvim_oxi::{lua, Result}; use nvim_oxi::{lua::Error::RuntimeError, Error, Result};
pub fn save_snapshot(config: TakeSnapshotParams) -> Result<()> { pub fn save_snapshot(config: TakeSnapshotParams) -> Result<()> {
match &config.save_path { match &config.save_path {
Some(path) => { Some(path) => {
if !path.ends_with(".png") {
return Err(Error::Lua(RuntimeError(
"The save_path must ends with .png".to_string(),
)));
}
let pixmap = take_snapshot(config.clone())?; let pixmap = take_snapshot(config.clone())?;
let path = parse_save_path(path.to_string())
.map_err(|err| Error::Lua(RuntimeError(err.to_string())))?;
pixmap pixmap
.save_png(path) .save_png(path)
.map_err(|err| nvim_oxi::Error::Lua(lua::Error::RuntimeError(err.to_string()))) .map_err(|err| Error::Lua(RuntimeError(err.to_string())))
} }
None => Err(nvim_oxi::Error::Lua(lua::Error::RuntimeError( None => Err(Error::Lua(RuntimeError(
"Cannot find 'save_path' in config".to_string(), "Cannot find 'save_path' in config".to_string(),
))), ))),
} }

View file

@ -6,74 +6,21 @@ use crate::components::background::Background;
use crate::components::container::Container; use crate::components::container::Container;
use crate::components::editor::code::Code; use crate::components::editor::code::Code;
use crate::components::editor::mac_title_bar::MacTitleBar; use crate::components::editor::mac_title_bar::MacTitleBar;
// use crate::components::editor::mac_title_bar::MacTitleBar; use crate::components::interface::component::ComponentContext;
use crate::components::interface::render_error; use crate::components::interface::render_error;
use crate::components::rect::Rect; use crate::components::rect::Rect;
use crate::components::watermark::Watermark; use crate::components::watermark::Watermark;
// use crate::components::watermark::Watermark;
use crate::config::TakeSnapshotParams; use crate::config::TakeSnapshotParams;
use crate::{
code::calc_wh,
components::interface::component::{Component, ComponentContext},
};
// Scale the screenshot to 3 times its size // Scale the screenshot to 3 times its size
const SCALE_FACTOR: f32 = 3.; const SCALE_FACTOR: f32 = 3.;
// The params is come from neovim instance // The params is come from neovim instance
pub fn take_snapshot(params: TakeSnapshotParams) -> render_error::Result<Pixmap> { pub fn take_snapshot(params: TakeSnapshotParams) -> render_error::Result<Pixmap> {
// let (width, height) = calc_wh(&params.code, 9.05, 20.);
// let pixmap_vertical_padding = 82.;
// let pixmap_horizontal_padding = 122.;
// // Padding of editor shape
// let padding = Padding {
// left: 20.,
// right: 20.,
// top: 20.,
// bottom: 24.,
// };
// let editor = Editor::new(
// pixmap_horizontal_padding,
// pixmap_vertical_padding,
// width,
// height,
// params.mac_window_bar,
// )
// .code_y_offset(15.)
// .padding(padding.clone())
// .render_editor(16.)
// .render_mac_title_bar()
// .render_code(&params.code, 20., 15.);
// let pixmap_width = (pixmap_horizontal_padding * 2. + editor.width()) as u32;
// let pixmap_height = (pixmap_vertical_padding * 2. + editor.height()) as u32;
// let (watermark_bottom_margin, watermark_offset_y) = params
// .watermark
// .as_ref()
// .map(|_| (200., 40.))
// .unwrap_or((0., 0.));
//
// let mut pixmap = Pixmap::new(
// 0,
// 0, // pixmap_width * SCALE_FACTOR as u32,
// // (pixmap_height as f32 * SCALE_FACTOR + watermark_bottom_margin - watermark_offset_y) as u32,
// )
// .unwrap();
// .unwrap();
let context = ComponentContext { let context = ComponentContext {
scale_factor: SCALE_FACTOR, scale_factor: SCALE_FACTOR,
take_snapshot_params: Arc::new(params.clone()), take_snapshot_params: Arc::new(params.clone()),
}; };
// let watermark = Watermark::new(
// params.watermark,
// params.watermark_font_family,
// watermark_bottom_margin,
// );
// let background = Background::create().children(vec![Box::new(editor), Box::new(watermark)]);
//
// background.draw_root(&mut pixmap, &context)?;
//
let pixmap = Container::from_children(vec![Box::new(Background::from_children(vec![ let pixmap = Container::from_children(vec![Box::new(Background::from_children(vec![
Box::new(Rect::new( Box::new(Rect::new(
16., 16.,