Added icon caching
This commit is contained in:
66
Cargo.lock
generated
66
Cargo.lock
generated
@@ -117,6 +117,15 @@ version = "1.3.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "block-buffer"
|
||||||
|
version = "0.10.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
version = "3.11.1"
|
version = "3.11.1"
|
||||||
@@ -286,6 +295,15 @@ version = "0.8.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
|
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cpufeatures"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crc32fast"
|
name = "crc32fast"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
@@ -344,6 +362,16 @@ version = "0.2.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crypto-common"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
"typenum",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxx"
|
name = "cxx"
|
||||||
version = "1.0.83"
|
version = "1.0.83"
|
||||||
@@ -394,6 +422,16 @@ version = "0.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8d7439c3735f405729d52c3fbbe4de140eaf938a1fe47d227c27f8254d4302a5"
|
checksum = "8d7439c3735f405729d52c3fbbe4de140eaf938a1fe47d227c27f8254d4302a5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "digest"
|
||||||
|
version = "0.10.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
|
||||||
|
dependencies = [
|
||||||
|
"block-buffer",
|
||||||
|
"crypto-common",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "directories"
|
name = "directories"
|
||||||
version = "4.0.1"
|
version = "4.0.1"
|
||||||
@@ -582,6 +620,16 @@ version = "0.3.25"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9"
|
checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "generic-array"
|
||||||
|
version = "0.14.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"
|
||||||
|
dependencies = [
|
||||||
|
"typenum",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.8"
|
version = "0.2.8"
|
||||||
@@ -1232,6 +1280,7 @@ dependencies = [
|
|||||||
"nix",
|
"nix",
|
||||||
"resvg",
|
"resvg",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
|
"sha2",
|
||||||
"stardust-xr-molecules",
|
"stardust-xr-molecules",
|
||||||
"tempdir",
|
"tempdir",
|
||||||
"tokio",
|
"tokio",
|
||||||
@@ -1535,6 +1584,17 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sha2"
|
||||||
|
version = "0.10.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures",
|
||||||
|
"digest",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sharded-slab"
|
name = "sharded-slab"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
@@ -1949,6 +2009,12 @@ version = "2.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f114398da254e78168e12edec0ece6b4ca15a97262ecd8e5efd5025e3fc30204"
|
checksum = "f114398da254e78168e12edec0ece6b4ca15a97262ecd8e5efd5025e3fc30204"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typenum"
|
||||||
|
version = "1.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-bidi"
|
name = "unicode-bidi"
|
||||||
version = "0.3.8"
|
version = "0.3.8"
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ mint = "0.5.9"
|
|||||||
nix = "0.26.1"
|
nix = "0.26.1"
|
||||||
resvg = "0.28.0"
|
resvg = "0.28.0"
|
||||||
rustc-hash = "1.1.0"
|
rustc-hash = "1.1.0"
|
||||||
|
sha2 = "0.10.6"
|
||||||
stardust-xr-molecules = "0.17.0"
|
stardust-xr-molecules = "0.17.0"
|
||||||
tokio = { version = "1.24.1", features = ["full"] }
|
tokio = { version = "1.24.1", features = ["full"] }
|
||||||
tracing-subscriber = { version = "0.3.16", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3.16", features = ["env-filter"] }
|
||||||
|
|||||||
10
README.md
10
README.md
@@ -1,2 +1,12 @@
|
|||||||
# protostar
|
# protostar
|
||||||
|
|
||||||
Prototype application launcher
|
Prototype application launcher
|
||||||
|
|
||||||
|
TODO:
|
||||||
|
|
||||||
|
1) ~~Make it work with all icons (should be done)~~
|
||||||
|
|
||||||
|
2. ~~If the right sized png exists, then use that, otherwise rasterize it (a bit janky but it works)~~
|
||||||
|
3. ~~Use XDG_CACHE_DIR to rasterize svgs (done)~~
|
||||||
|
4. Make sure it's using the current icon theme
|
||||||
|
5. Design a better app launcher ui
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ impl AppGrid {
|
|||||||
let apps = get_desktop_files()
|
let apps = get_desktop_files()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|d| parse_desktop_file(d).ok())
|
.filter_map(|d| parse_desktop_file(d).ok())
|
||||||
|
.filter(|d| !d.no_display)
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|(i, _)| *i <= APP_LIMIT)
|
.filter(|(i, _)| *i <= APP_LIMIT)
|
||||||
.filter_map(|(i, a)| {
|
.filter_map(|(i, a)| {
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ impl ProtoStar {
|
|||||||
RawIconType::Gltf(_) => true,
|
RawIconType::Gltf(_) => true,
|
||||||
})
|
})
|
||||||
.or(last_icon)
|
.or(last_icon)
|
||||||
.map(|i| dbg!(i.process(64)).ok())
|
.map(|i| i.process(128).ok())
|
||||||
.ok_or_else(|| eyre!("No compatible icons found"))?;
|
.ok_or_else(|| eyre!("No compatible icons found"))?;
|
||||||
Self::new_raw(
|
Self::new_raw(
|
||||||
parent,
|
parent,
|
||||||
@@ -144,6 +144,7 @@ impl RootHandler for ProtoStar {
|
|||||||
self.icon_shrink = Some(Tweener::quart_in_out(1.0, 0.0, 0.25));
|
self.icon_shrink = Some(Tweener::quart_in_out(1.0, 0.0, 0.25));
|
||||||
let future = startup_settings.generate_startup_token().unwrap();
|
let future = startup_settings.generate_startup_token().unwrap();
|
||||||
let executable = dbg!(self.execute_command.clone());
|
let executable = dbg!(self.execute_command.clone());
|
||||||
|
//TODO: split the executable string for the args
|
||||||
tokio::task::spawn(async move {
|
tokio::task::spawn(async move {
|
||||||
std::env::set_var("STARDUST_STARTUP_TOKEN", future.await.unwrap());
|
std::env::set_var("STARDUST_STARTUP_TOKEN", future.await.unwrap());
|
||||||
if unsafe { fork() }.unwrap().is_parent() {
|
if unsafe { fork() }.unwrap().is_parent() {
|
||||||
|
|||||||
113
src/xdg.rs
113
src/xdg.rs
@@ -4,37 +4,50 @@ use resvg::tiny_skia::{Pixmap, Transform};
|
|||||||
use resvg::usvg::{FitTo, Tree};
|
use resvg::usvg::{FitTo, Tree};
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
use std::fs::create_dir_all;
|
use std::fs::create_dir_all;
|
||||||
use std::io::{BufRead, BufReader, ErrorKind};
|
use std::io::{BufRead, BufReader, ErrorKind, self};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::{env, fs};
|
use std::{env, fs};
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
use sha2::{Sha224, Digest};
|
||||||
|
|
||||||
const ICON_SIZES: &[&str] = &["128x128", "scalable", "256x256", "64x64", "32x32"];
|
const ICON_SIZES: &[&str] = &["64x64", "32x32", "scalable", "128x128"];
|
||||||
|
|
||||||
|
fn get_data_dirs() -> Vec<PathBuf> {
|
||||||
|
let xdg_data_dirs_str = std::env::var("XDG_DATA_DIRS")
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
let xdg_data_dirs = xdg_data_dirs_str
|
||||||
|
.split(":")
|
||||||
|
.filter_map(|dir| PathBuf::from_str(dir).ok());
|
||||||
|
|
||||||
|
let data_home = dirs::home_dir()
|
||||||
|
.unwrap_or(PathBuf::from_str("/usr/share/")
|
||||||
|
.expect("No XDG_DATA_DIR set, no HOME directory found and no /usr/share direcotry found"))
|
||||||
|
.join(".local")
|
||||||
|
.join("share");
|
||||||
|
|
||||||
|
xdg_data_dirs
|
||||||
|
.chain([data_home].into_iter())
|
||||||
|
.filter(|dir| dir.exists() && dir.is_dir())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_app_dirs() -> Vec<PathBuf>{
|
||||||
|
get_data_dirs()
|
||||||
|
.into_iter()
|
||||||
|
.map(|dir| dir.join("applications"))
|
||||||
|
.filter(|dir| dir.exists() && dir.is_dir())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_desktop_files() -> Vec<PathBuf> {
|
pub fn get_desktop_files() -> Vec<PathBuf> {
|
||||||
// Get the XDG data directories
|
|
||||||
let xdg_data_dirs =
|
|
||||||
std::env::var("XDG_DATA_DIRS").unwrap_or("/usr/local/share:/usr/share".to_string());
|
|
||||||
|
|
||||||
// Append the applications directory to each data directory
|
|
||||||
let app_dirs = xdg_data_dirs
|
|
||||||
.split(":")
|
|
||||||
.map(|dir| Path::new(dir).join("applications"));
|
|
||||||
|
|
||||||
// Get the user's local applications directory
|
|
||||||
let local_app_dir = dirs::home_dir()
|
|
||||||
.unwrap()
|
|
||||||
.join(".local")
|
|
||||||
.join("share")
|
|
||||||
.join("applications");
|
|
||||||
|
|
||||||
let desktop_extension = OsString::from_str("desktop").unwrap();
|
let desktop_extension = OsString::from_str("desktop").unwrap();
|
||||||
|
|
||||||
// Get the list of directories to search
|
// Get the list of directories to search
|
||||||
|
let app_dirs = get_app_dirs();
|
||||||
|
dbg!(&app_dirs);
|
||||||
app_dirs
|
app_dirs
|
||||||
.chain(Some(local_app_dir))
|
.into_iter()
|
||||||
.filter(|dir| dir.exists() && dir.is_dir())
|
|
||||||
.flat_map(|dir| {
|
.flat_map(|dir| {
|
||||||
// Follow symlinks and recursively search directories
|
// Follow symlinks and recursively search directories
|
||||||
WalkDir::new(dir)
|
WalkDir::new(dir)
|
||||||
@@ -75,6 +88,7 @@ pub fn parse_desktop_file(path: PathBuf) -> Result<DesktopFile, String> {
|
|||||||
let mut command = None;
|
let mut command = None;
|
||||||
let mut categories = Vec::new();
|
let mut categories = Vec::new();
|
||||||
let mut icon = None;
|
let mut icon = None;
|
||||||
|
let mut no_display = false;
|
||||||
|
|
||||||
// Loop through each line of the file
|
// Loop through each line of the file
|
||||||
for line in reader.lines() {
|
for line in reader.lines() {
|
||||||
@@ -107,6 +121,10 @@ pub fn parse_desktop_file(path: PathBuf) -> Result<DesktopFile, String> {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
"Icon" => icon = Some(value.to_string()),
|
"Icon" => icon = Some(value.to_string()),
|
||||||
|
"NoDisplay" => no_display = match value{
|
||||||
|
"true" => true,
|
||||||
|
_ => false
|
||||||
|
},
|
||||||
_ => (), // Ignore unknown keys
|
_ => (), // Ignore unknown keys
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,6 +136,7 @@ pub fn parse_desktop_file(path: PathBuf) -> Result<DesktopFile, String> {
|
|||||||
command,
|
command,
|
||||||
categories,
|
categories,
|
||||||
icon,
|
icon,
|
||||||
|
no_display,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,6 +168,7 @@ pub struct DesktopFile {
|
|||||||
pub command: Option<String>,
|
pub command: Option<String>,
|
||||||
pub categories: Vec<String>,
|
pub categories: Vec<String>,
|
||||||
pub icon: Option<String>,
|
pub icon: Option<String>,
|
||||||
|
pub no_display: bool,
|
||||||
}
|
}
|
||||||
impl DesktopFile {
|
impl DesktopFile {
|
||||||
pub fn get_raw_icons(&self) -> Vec<RawIconType> {
|
pub fn get_raw_icons(&self) -> Vec<RawIconType> {
|
||||||
@@ -167,12 +187,11 @@ impl DesktopFile {
|
|||||||
let icon_theme = env::var_os("XDG_ICON_THEME").unwrap_or("hicolor".into());
|
let icon_theme = env::var_os("XDG_ICON_THEME").unwrap_or("hicolor".into());
|
||||||
|
|
||||||
// Get the XDG_DATA_HOME and XDG_DATA_DIRS environment variables, and split the XDG_DATA_DIRS variable into a list of directories
|
// Get the XDG_DATA_HOME and XDG_DATA_DIRS environment variables, and split the XDG_DATA_DIRS variable into a list of directories
|
||||||
let Some(xdg_data_dirs) = env::var_os("XDG_DATA_DIRS") else { return Vec::new(); };
|
let xdg_data_dirs = get_data_dirs();
|
||||||
let Ok(binding) = xdg_data_dirs.into_string() else { return Vec::new(); };
|
|
||||||
let xdg_data_dirs = binding.split(":").map(Path::new);
|
|
||||||
|
|
||||||
// Concatenate the XDG_DATA_HOME and XDG_DATA_DIRS directories with the default path for icon themes
|
// Concatenate the XDG_DATA_HOME and XDG_DATA_DIRS directories with the default path for icon themes
|
||||||
xdg_data_dirs // XDG_DATA_DIRS directories
|
xdg_data_dirs // XDG_DATA_DIRS directories
|
||||||
|
.into_iter()
|
||||||
.flat_map(|dir| {
|
.flat_map(|dir| {
|
||||||
let icons_path = dir.join("icons").join(&icon_theme);
|
let icons_path = dir.join("icons").join(&icon_theme);
|
||||||
ICON_SIZES
|
ICON_SIZES
|
||||||
@@ -214,9 +233,7 @@ impl RawIconType {
|
|||||||
match self {
|
match self {
|
||||||
RawIconType::Png(path) => Ok(Icon::Png(path)),
|
RawIconType::Png(path) => Ok(Icon::Png(path)),
|
||||||
RawIconType::Svg(path) => {
|
RawIconType::Svg(path) => {
|
||||||
let png_path = path.with_extension("png");
|
Ok(Icon::Png(get_png_from_svg(&path, size)?))
|
||||||
render_svg_to_png(path, &png_path, size)?;
|
|
||||||
Ok(Icon::Png(png_path))
|
|
||||||
}
|
}
|
||||||
RawIconType::Gltf(path) => Ok(Icon::Gltf(path)),
|
RawIconType::Gltf(path) => Ok(Icon::Gltf(path)),
|
||||||
}
|
}
|
||||||
@@ -232,6 +249,7 @@ fn test_get_icon_path() {
|
|||||||
command: None,
|
command: None,
|
||||||
categories: vec![],
|
categories: vec![],
|
||||||
icon: Some("krita".into()),
|
icon: Some("krita".into()),
|
||||||
|
no_display: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Call the get_icon_path() function with a size argument and store the result
|
// Call the get_icon_path() function with a size argument and store the result
|
||||||
@@ -240,7 +258,7 @@ fn test_get_icon_path() {
|
|||||||
|
|
||||||
// Assert that the get_icon_path() function returns the expected result
|
// Assert that the get_icon_path() function returns the expected result
|
||||||
assert!(icon_paths.contains(&RawIconType::Png(PathBuf::from(
|
assert!(icon_paths.contains(&RawIconType::Png(PathBuf::from(
|
||||||
"/usr/share/icons/hicolor/16x16/apps/krita.png"
|
"/usr/share/icons/hicolor/32x32/apps/krita.png"
|
||||||
))));
|
))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,22 +268,41 @@ pub enum Icon {
|
|||||||
Gltf(PathBuf),
|
Gltf(PathBuf),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_svg_to_png(
|
pub fn get_png_from_svg(svg_path: impl AsRef<Path>, size: u32,) -> Result<PathBuf, std::io::Error> {
|
||||||
cache_dir: impl AsRef<Path>,
|
|
||||||
svg_path: impl AsRef<Path>,
|
|
||||||
size: u32,
|
|
||||||
) -> Result<PathBuf, std::io::Error> {
|
|
||||||
let svg_path = fs::canonicalize(svg_path)?;
|
let svg_path = fs::canonicalize(svg_path)?;
|
||||||
let tree = Tree::from_data(
|
let tree = Tree::from_data(
|
||||||
fs::read(svg_path.as_path())?.as_slice(),
|
fs::read(svg_path.as_path())?.as_slice(),
|
||||||
&resvg::usvg::Options::default(),
|
&resvg::usvg::Options::default(),
|
||||||
)
|
)
|
||||||
.map_err(|_| ErrorKind::InvalidData)?;
|
.map_err(|_| ErrorKind::InvalidData)?;
|
||||||
create_dir_all(cache_dir.as_ref())?;
|
|
||||||
let png_path = cache_dir
|
let cache_dir;
|
||||||
.as_ref()
|
if let Ok(xdg_cache_home) = std::env::var("XDG_CACHE_HOME") {
|
||||||
.join(svg_path.file_name().unwrap())
|
cache_dir = PathBuf::from_str(&xdg_cache_home).unwrap_or(
|
||||||
|
dirs::home_dir().unwrap().join(".cache")
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
cache_dir = dirs::home_dir().unwrap().join(".cache");
|
||||||
|
}
|
||||||
|
|
||||||
|
let image_cache_dir = cache_dir.join("protostar_icon_cache");
|
||||||
|
|
||||||
|
create_dir_all(&image_cache_dir).expect("Could not create image cache directory");
|
||||||
|
|
||||||
|
//TODO: come up with a better way to cache images system
|
||||||
|
let mut hasher = Sha224::new();
|
||||||
|
let mut svg_file = fs::File::open(&svg_path)?;
|
||||||
|
io::copy(&mut svg_file, &mut hasher)?;
|
||||||
|
let hash_bytes = hasher.finalize();
|
||||||
|
|
||||||
|
let png_path = image_cache_dir
|
||||||
|
.join(format!("{}-{:02x}",svg_path.with_extension("").file_name().unwrap().to_str().unwrap(), hash_bytes))
|
||||||
.with_extension("png");
|
.with_extension("png");
|
||||||
|
|
||||||
|
if png_path.exists() {
|
||||||
|
return Ok(png_path)
|
||||||
|
}
|
||||||
|
|
||||||
let mut pixmap = Pixmap::new(size, size).unwrap();
|
let mut pixmap = Pixmap::new(size, size).unwrap();
|
||||||
render(
|
render(
|
||||||
&tree,
|
&tree,
|
||||||
@@ -293,7 +330,7 @@ fn test_render_svg_to_png() {
|
|||||||
fs::write(&svg_path, test_svg_data).unwrap();
|
fs::write(&svg_path, test_svg_data).unwrap();
|
||||||
|
|
||||||
// Call the function with the test input and output paths and a size of 200
|
// Call the function with the test input and output paths and a size of 200
|
||||||
let png_path = render_svg_to_png(".", &svg_path, 200).unwrap();
|
let png_path = get_png_from_svg(&svg_path, 200).unwrap();
|
||||||
dbg!(&png_path);
|
dbg!(&png_path);
|
||||||
|
|
||||||
// Check that the output file exists
|
// Check that the output file exists
|
||||||
|
|||||||
Reference in New Issue
Block a user