mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-16 23:08:05 +08:00
* Extract CEF rendered UI into a separate process and crate * Review * Review * Review * Review * Remove necessary workarounds * Block on frame copy ack * Crop and resample frames correctly * Skip blank frames * Fix deps * Fix fmt * Fix clippy warning * Review * Fix todo
112 lines
3.2 KiB
Rust
112 lines
3.2 KiB
Rust
use std::fs::File;
|
|
#[cfg(feature = "embedded_resources")]
|
|
use std::io;
|
|
use std::io::Read;
|
|
use std::path::{Component, PathBuf};
|
|
use std::sync::Arc;
|
|
|
|
#[derive(Clone)]
|
|
pub(crate) struct Resource {
|
|
pub(crate) reader: ResourceReader,
|
|
pub(crate) mimetype: Option<String>,
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub(crate) enum ResourceReader {
|
|
#[cfg(feature = "embedded_resources")]
|
|
Embedded(io::Cursor<&'static [u8]>),
|
|
File(Arc<File>),
|
|
}
|
|
impl Read for ResourceReader {
|
|
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
|
match self {
|
|
#[cfg(feature = "embedded_resources")]
|
|
ResourceReader::Embedded(cursor) => cursor.read(buf),
|
|
ResourceReader::File(file) => file.as_ref().read(buf),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
|
pub enum WebResources {
|
|
Embedded,
|
|
External(PathBuf),
|
|
}
|
|
|
|
pub(crate) fn load(path: PathBuf) -> Option<Resource> {
|
|
if path.components().any(|component| matches!(component, Component::ParentDir)) {
|
|
tracing::error!("Rejected resource path with a parent directory component: {path:?}");
|
|
return None;
|
|
}
|
|
|
|
let resources = if cfg!(feature = "embedded_resources") {
|
|
WebResources::Embedded
|
|
} else {
|
|
match std::env::var("GRAPHITE_RESOURCES") {
|
|
Ok(dir) => WebResources::External(dir.into()),
|
|
Err(_) => {
|
|
tracing::error!("GRAPHITE_RESOURCES must point to the frontend assets when embedded resources are disabled");
|
|
return None;
|
|
}
|
|
}
|
|
};
|
|
|
|
let path = if path.as_os_str().is_empty() { PathBuf::from("index.html") } else { path };
|
|
|
|
let mimetype = match path.extension().and_then(|s| s.to_str()).unwrap_or("") {
|
|
"html" => Some("text/html".to_string()),
|
|
"css" => Some("text/css".to_string()),
|
|
"txt" => Some("text/plain".to_string()),
|
|
"wasm" => Some("application/wasm".to_string()),
|
|
"js" => Some("application/javascript".to_string()),
|
|
"png" => Some("image/png".to_string()),
|
|
"jpg" | "jpeg" => Some("image/jpeg".to_string()),
|
|
"svg" => Some("image/svg+xml".to_string()),
|
|
"xml" => Some("application/xml".to_string()),
|
|
"json" => Some("application/json".to_string()),
|
|
"ico" => Some("image/x-icon".to_string()),
|
|
"woff" => Some("font/woff".to_string()),
|
|
"woff2" => Some("font/woff2".to_string()),
|
|
"ttf" => Some("font/ttf".to_string()),
|
|
"otf" => Some("font/otf".to_string()),
|
|
"webmanifest" => Some("application/manifest+json".to_string()),
|
|
"graphite" => Some("application/graphite+json".to_string()),
|
|
_ => None,
|
|
};
|
|
|
|
match resources {
|
|
WebResources::Embedded => {
|
|
#[cfg(feature = "embedded_resources")]
|
|
{
|
|
if let Some(resources) = &graphite_desktop_embedded_resources::EMBEDDED_RESOURCES
|
|
&& let Some(file) = resources.get_file(&path)
|
|
{
|
|
return Some(Resource {
|
|
reader: ResourceReader::Embedded(io::Cursor::new(file.contents())),
|
|
mimetype,
|
|
});
|
|
}
|
|
None
|
|
}
|
|
#[cfg(not(feature = "embedded_resources"))]
|
|
{
|
|
tracing::error!("Embedded resources requested but the embedded_resources feature is disabled");
|
|
None
|
|
}
|
|
}
|
|
WebResources::External(dir) => {
|
|
let file_path = dir.join(path.strip_prefix("/").unwrap_or(&path));
|
|
if file_path.exists()
|
|
&& file_path.is_file()
|
|
&& let Ok(file) = std::fs::File::open(file_path)
|
|
{
|
|
return Some(Resource {
|
|
reader: ResourceReader::File(file.into()),
|
|
mimetype,
|
|
});
|
|
}
|
|
None
|
|
}
|
|
}
|
|
}
|