Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 51 additions & 45 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,55 +144,61 @@ Or if you are using CLI tool, CodeSnap will generate a default config file for y
```jsonc
// Both "CaskaydiaCove Nerd Font" and "Pacifico" is pre-installed in CodeSnap, you can use them out of the box
{
"theme": "candy",
"window": {
"mac_window_bar": true,
"shadow": {
"radius": 20,
"color": "#00000040"
},
"margin": {
"x": 82,
"y": 82
"theme": "candy",
"window": {
"mac_window_bar": true,
"shadow": {
"radius": 20,
"color": "#00000040"
},
"margin": {
"x": 82,
"y": 82
},
"border": {
"width": 1,
"color": "#ffffff30"
},
"title_config": {
"color": "#ffffff",
"font_family": "Pacifico"
},
"radius": 12
},
"border": {
"width": 1,
"color": "#ffffff30"
}
},
"code_config": {
"font_family": "CaskaydiaCove Nerd Font",
"breadcrumbs": {
"separator": "/",
"color": "#80848b",
"font_family": "CaskaydiaCove Nerd Font"
}
},
"watermark": {
"content": "CodeSnap",
"font_family": "Pacifico",
"color": "#ffffff"
},
"background": {
"start": {
"x": 0,
"y": 0
"code_config": {
"font_family": "CaskaydiaCove Nerd Font",
"breadcrumbs": {
"enable": false,
"separator": "/",
"color": "#80848b",
"font_family": "CaskaydiaCove Nerd Font"
}
},
"end": {
"x": "max",
"y": 0
"watermark": {
"content": "CodeSnap",
"font_family": "Pacifico",
"color": "#ffffff"
},
"stops": [
{
"position": 0,
"color": "#6bcba5"
"background": {
"start": {
"x": 0,
"y": 0
},
{
"position": 1,
"color": "#caf4c2"
}
]
}
"end": {
"x": "max",
"y": 0
},
"stops": [
{
"position": 0,
"color": "#6bcba5"
},
{
"position": 1,
"color": "#caf4c2"
}
]
}
}
```

Expand Down
3 changes: 2 additions & 1 deletion cli/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"title_config": {
"color": "#ffffff",
"font_family": "Pacifico"
}
},
"radius": 12
},
"code_config": {
"font_family": "CaskaydiaCove Nerd Font",
Expand Down
2 changes: 1 addition & 1 deletion cli/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ impl CodeSnapCLIConfig {
// Get CodeSnap config, create if the config does not exists
pub fn get_config_content() -> anyhow::Result<String> {
let home_dir = home::home_dir().context("Unable to get your home dir")?;
let codesnap_home_path = home_dir.join(".config").join("CodeSnap");
let codesnap_home_path = home_dir.join(".config").join("codesnap");
let config_path = codesnap_home_path.join("config.json");
let is_config_exists = config_path.try_exists()?;

Expand Down
35 changes: 31 additions & 4 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,17 @@ mod watermark;
mod window;

use std::fs::read_to_string;
use std::io;
use std::io::Write;

use anyhow::bail;
use clap::value_parser;
use clap::Parser;
use code::create_content;
use code_config::create_code_config;
use codesnap::config::CodeSnap;
use codesnap::config::Content;
use codesnap::config::SnapshotConfig;
use codesnap::snapshot::snapshot_data::SnapshotData;
use codesnap::themes::parse_code_theme;
use config::CodeSnapCLIConfig;
use egg::say;
Expand Down Expand Up @@ -63,6 +65,9 @@ struct CLI {
#[arg(short, long)]
output: String,

#[arg(long, default_value = "false")]
silent: bool,

/// Executing a command and taking the output as the code snippet.
#[arg(long, short, num_args=1..)]
execute: Vec<String>,
Expand Down Expand Up @@ -235,6 +240,25 @@ struct CLI {
}

fn output_snapshot(cli: &CLI, snapshot: &SnapshotConfig) -> anyhow::Result<String> {
if cli.output == "raw" {
// Output to stdout
match snapshot.create_snapshot()?.png_data()? {
SnapshotData::Image {
data,
width: _,
height: _,
} => {
io::stdout().write_all(&data)?;
io::stdout().flush()?;
}
SnapshotData::Text(content) => {
print!("{content}");
}
};

return Ok("Output to stdout".to_string());
}

// Save snapshot to clipboard
if cli.output == "clipboard" {
match cli.r#type.as_str() {
Expand Down Expand Up @@ -282,9 +306,12 @@ async fn generate_snapshot_with_config(cli: &CLI, codesnap: CodeSnap) -> anyhow:
return Ok(());
}

let message = with_spinner(|| output_snapshot(cli, &snapshot))?;

logger::success(&message);
if !cli.silent {
let message = with_spinner(|| output_snapshot(cli, &snapshot))?;
logger::success(&message)
} else {
output_snapshot(cli, &snapshot)?;
}

Ok(())
}
Expand Down
3 changes: 2 additions & 1 deletion core/assets/theme_configs/bamboo.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"title_config": {
"color": "#ffffff",
"font_family": "Pacifico"
}
},
"radius": 12
},
"code_config": {
"font_family": "CaskaydiaCove Nerd Font",
Expand Down
3 changes: 2 additions & 1 deletion core/assets/theme_configs/mei.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"title_config": {
"color": "#ffffff",
"font_family": "Pacifico"
}
},
"radius": 12
},
"code_config": {
"font_family": "CaskaydiaCove Nerd Font",
Expand Down
57 changes: 51 additions & 6 deletions core/src/components/image.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use tiny_skia::{Pixmap, PixmapPaint};
use anyhow::anyhow;
use tiny_skia::{FillRule, FilterQuality, Mask, Path, PathBuilder, Pixmap, PixmapPaint, Transform};

use crate::components::interface::{
component::{Component, ComponentContext, RenderParams},
Expand Down Expand Up @@ -31,9 +32,10 @@ impl Component for Image {
_style: &ComponentStyle,
_parent_style: &Style<f32>,
) -> render_error::Result<()> {
let transform =
tiny_skia::Transform::from_scale(context.scale_factor, context.scale_factor);
let paint = PixmapPaint::default();
let transform = Transform::from_scale(context.scale_factor, context.scale_factor);
let mut paint = PixmapPaint::default();

paint.quality = FilterQuality::Bilinear;

pixmap.draw_pixmap(
render_params.x as i32,
Expand All @@ -49,12 +51,55 @@ impl Component for Image {
}

impl Image {
pub fn new(image_data: Vec<u8>) -> anyhow::Result<Self> {
let image_pixmap = Pixmap::decode_png(&image_data)?;
pub fn new(radius: f32, image_data: Vec<u8>) -> anyhow::Result<Self> {
let mut image_pixmap = Pixmap::decode_png(&image_data)?;
let rounded_mask = Self::build_round_mask(&image_pixmap, radius)?;
image_pixmap.apply_mask(&rounded_mask);

Ok(Self {
image_pixmap,
children: vec![],
})
}

fn build_round_mask(pixmap: &Pixmap, radius: f32) -> anyhow::Result<Mask> {
let width = pixmap.width();
let height = pixmap.height();

if width == 0 || height == 0 {
return Err(anyhow!("image pixmap must have non-zero dimensions"));
}

let path = Self::rounded_rect_path(width as f32, height as f32, radius)?;
let mut mask = Mask::new(width, height).ok_or_else(|| anyhow!("failed to create mask"))?;
mask.fill_path(&path, FillRule::Winding, true, Transform::identity());

Ok(mask)
}

fn rounded_rect_path(width: f32, height: f32, radius: f32) -> anyhow::Result<Path> {
if width <= 0.0 || height <= 0.0 {
return Err(anyhow!("rounded rect requires positive size"));
}

let mut builder = PathBuilder::new();
let radius = radius.max(0.0).min(width / 2.0).min(height / 2.0);
let right = width;
let bottom = height;

builder.move_to(radius, 0.0);
builder.line_to(right - radius, 0.0);
builder.quad_to(right, 0.0, right, radius);
builder.line_to(right, bottom - radius);
builder.quad_to(right, bottom, right - radius, bottom);
builder.line_to(radius, bottom);
builder.quad_to(0.0, bottom, 0.0, bottom - radius);
builder.line_to(0.0, radius);
builder.quad_to(0.0, 0.0, radius, 0.0);
builder.close();

builder
.finish()
.ok_or_else(|| anyhow!("failed to create rounded rectangle path"))
}
}
4 changes: 4 additions & 0 deletions core/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ pub struct Window {

#[builder(default = ShadowBuilder::default().build().unwrap())]
pub shadow: Shadow,

#[builder(default = 12.0)]
pub radius: f32,
}

impl WindowBuilder {
Expand All @@ -184,6 +187,7 @@ impl WindowBuilder {
border: Some(window.border),
mac_window_bar: Some(window.mac_window_bar),
shadow: Some(window.shadow),
radius: Some(window.radius),
}
}
}
Expand Down
15 changes: 9 additions & 6 deletions core/src/snapshot/image_snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ pub struct ImageSnapshot {

impl ImageSnapshot {
pub fn raw_data(&self) -> Result<SnapshotData, anyhow::Error> {
Ok(SnapshotData::from_pixmap(&self.pixmap, false)?)
SnapshotData::from_pixmap(&self.pixmap, false)
}

pub fn png_data(&self) -> Result<SnapshotData, anyhow::Error> {
Ok(SnapshotData::from_pixmap(&self.pixmap, true)?)
SnapshotData::from_pixmap(&self.pixmap, true)
}

pub fn svg_data(&self) -> Result<SnapshotData, anyhow::Error> {
Expand Down Expand Up @@ -202,7 +202,7 @@ impl ImageSnapshot {
theme_provider_cloned.clone(),
Box::new(
Rect::create_with_border(
12.,
config_cloned.window.radius,
editor_background_color.into(),
DEFAULT_WINDOW_MIN_WIDTH,
window_padding_cloned,
Expand Down Expand Up @@ -232,12 +232,15 @@ impl ImageSnapshot {
theme_provider.clone(),
Box::new(
Rect::new(
12.,
Color::from_rgba8(255, 255, 255, 255),
config.window.radius,
Color::from_rgba8(255, 255, 255, 0),
None,
Padding::default(),
"ImageContainer",
vec![Box::new(Image::new(image_data.to_owned())?)],
vec![Box::new(Image::new(
config.window.radius,
image_data.to_owned(),
)?)],
)
.shadow(
0.,
Expand Down