This commit is contained in:
parent
5ca0021533
commit
43b0b1d7a7
7 changed files with 139 additions and 43 deletions
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "artwork"]
|
||||||
|
path = artwork
|
||||||
|
url = https://git.makerlab-murnau.de/MakerLab/artwork.git
|
50
Cargo.lock
generated
50
Cargo.lock
generated
|
@ -8,6 +8,15 @@ version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
|
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "0.7.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-trait"
|
name = "async-trait"
|
||||||
version = "0.1.66"
|
version = "0.1.66"
|
||||||
|
@ -90,6 +99,16 @@ dependencies = [
|
||||||
"generic-array",
|
"generic-array",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bstr"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3d4260bcc2e8fc9df1eac4919a720effeb63a3f0952f5bf4944adfa18897f09"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
version = "1.4.3"
|
version = "1.4.3"
|
||||||
|
@ -248,6 +267,19 @@ dependencies = [
|
||||||
"wasi",
|
"wasi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "globset"
|
||||||
|
version = "0.4.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"bstr",
|
||||||
|
"fnv",
|
||||||
|
"log",
|
||||||
|
"regex",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
|
@ -609,6 +641,23 @@ dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "1.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.6.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rust-embed"
|
name = "rust-embed"
|
||||||
version = "6.6.0"
|
version = "6.6.0"
|
||||||
|
@ -639,6 +688,7 @@ version = "7.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "512b0ab6853f7e14e3c8754acb43d6f748bb9ced66aa5915a6553ac8213f7731"
|
checksum = "512b0ab6853f7e14e3c8754acb43d6f748bb9ced66aa5915a6553ac8213f7731"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"globset",
|
||||||
"sha2",
|
"sha2",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
]
|
]
|
||||||
|
|
|
@ -12,6 +12,6 @@ axum = "0.6.10"
|
||||||
tokio = { version = "1.0", features = ["full"] }
|
tokio = { version = "1.0", features = ["full"] }
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
serde = { version = "1.0.152", features = ["derive"] }
|
serde = { version = "1.0.152", features = ["derive"] }
|
||||||
rust-embed = "6.6.0"
|
rust-embed = { version = "6.6.0", features = ["include-exclude"] }
|
||||||
mime_guess = "2.0.4"
|
mime_guess = "2.0.4"
|
||||||
serde_json = "1.0.94"
|
serde_json = "1.0.94"
|
||||||
|
|
1
artwork
Submodule
1
artwork
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit f7ead83291e2f462888d73530f239ab3a48b4abd
|
Binary file not shown.
Before Width: | Height: | Size: 26 KiB |
|
@ -1,3 +1,5 @@
|
||||||
|
use std::default;
|
||||||
|
|
||||||
use axum::{extract::Query, routing::get, Router};
|
use axum::{extract::Query, routing::get, Router};
|
||||||
use cairo::{Context, Format, ImageSurface};
|
use cairo::{Context, Format, ImageSurface};
|
||||||
use rust_embed::RustEmbed;
|
use rust_embed::RustEmbed;
|
||||||
|
@ -25,49 +27,85 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize, Default)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
enum LogoVariant {
|
||||||
|
NoText,
|
||||||
|
#[default]
|
||||||
|
DarkText,
|
||||||
|
LightText,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Default)]
|
||||||
|
enum LogoOrientation {
|
||||||
|
#[default]
|
||||||
|
Landscape,
|
||||||
|
Portrait,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Default)]
|
||||||
struct ImageProperties {
|
struct ImageProperties {
|
||||||
#[serde(default = "default_as_false")]
|
#[serde(default)]
|
||||||
#[serde(deserialize_with = "deserialize_bool")]
|
variant: LogoVariant,
|
||||||
dark_mode: bool,
|
#[serde(default)]
|
||||||
#[serde(default = "default_as_false")]
|
orientation: LogoOrientation,
|
||||||
#[serde(deserialize_with = "deserialize_bool")]
|
|
||||||
text: bool,
|
|
||||||
background_color: Option<Color>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(RustEmbed)]
|
#[derive(RustEmbed)]
|
||||||
#[folder = "images"]
|
#[folder = "artwork/logo"]
|
||||||
|
#[include = "*_T.png"]
|
||||||
struct ImageFiles;
|
struct ImageFiles;
|
||||||
|
|
||||||
fn get_surface_and_logo_coordiates(properties: &ImageProperties) -> (ImageSurface, (f64, f64)) {
|
fn get_surface_and_logo_coordiates(
|
||||||
if properties.text {
|
properties: &ImageProperties,
|
||||||
let image = ImageFiles::get("Makerlab.png").unwrap();
|
) -> (ImageSurface, (f64, f64), f64, f64) {
|
||||||
(
|
if let LogoVariant::NoText = properties.variant {
|
||||||
ImageSurface::create_from_png(&mut image.data.as_ref()).unwrap(),
|
return (
|
||||||
(604.0, 432.0),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
(
|
|
||||||
ImageSurface::create(Format::ARgb32, 400, 400).unwrap(),
|
ImageSurface::create(Format::ARgb32, 400, 400).unwrap(),
|
||||||
(200.0, 200.0),
|
(200.0, 200.0),
|
||||||
)
|
148.0,
|
||||||
|
67.0,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let background_image_path = match (&properties.variant, &properties.orientation) {
|
||||||
|
(LogoVariant::DarkText, LogoOrientation::Landscape) => "landscape/4C_T.png",
|
||||||
|
(LogoVariant::LightText, LogoOrientation::Landscape) => "landscape/W_T.png",
|
||||||
|
(LogoVariant::DarkText, LogoOrientation::Portrait) => "portrait/4C_T.png",
|
||||||
|
(LogoVariant::LightText, LogoOrientation::Portrait) => "portrait/W_T.png",
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let (coordinates, outer_radius, inner_radius) = match &properties.orientation {
|
||||||
|
LogoOrientation::Landscape => ((412.0, 299.0), 209.0, 99.0),
|
||||||
|
LogoOrientation::Portrait => ((828.0, 563.0), 253.0, 118.0),
|
||||||
|
};
|
||||||
|
|
||||||
|
let image = ImageFiles::get(background_image_path).unwrap();
|
||||||
|
(
|
||||||
|
ImageSurface::create_from_png(&mut image.data.as_ref()).unwrap(),
|
||||||
|
coordinates,
|
||||||
|
outer_radius,
|
||||||
|
inner_radius,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handler(Query(properties): Query<ImageProperties>) -> impl axum::response::IntoResponse {
|
async fn handler(Query(properties): Query<ImageProperties>) -> impl axum::response::IntoResponse {
|
||||||
let (surface, logo_coordinates) = get_surface_and_logo_coordiates(&properties);
|
let (surface, logo_coordinates, logo_outer_radius, logo_inner_radius) =
|
||||||
|
get_surface_and_logo_coordiates(&properties);
|
||||||
let context = Context::new(&surface).unwrap();
|
let context = Context::new(&surface).unwrap();
|
||||||
|
|
||||||
if let Some(c) = properties.background_color {
|
|
||||||
context.set_source_rgb(c.r as f64 / 255.0, c.g as f64 / 255.0, c.b as f64 / 255.0);
|
|
||||||
} else {
|
|
||||||
context.set_source_rgba(0.0, 0.0, 0.0, 0.0);
|
context.set_source_rgba(0.0, 0.0, 0.0, 0.0);
|
||||||
}
|
|
||||||
|
|
||||||
context.paint().unwrap();
|
context.paint().unwrap();
|
||||||
|
|
||||||
polygon::draw_polygon_of_segmented_polygons(logo_coordinates, 148.0, 67.0, 6, &context)
|
polygon::draw_polygon_of_segmented_polygons(
|
||||||
|
logo_coordinates,
|
||||||
|
logo_outer_radius,
|
||||||
|
logo_inner_radius,
|
||||||
|
6,
|
||||||
|
&context,
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut data: Vec<u8> = Vec::new();
|
let mut data: Vec<u8> = Vec::new();
|
||||||
|
|
|
@ -27,9 +27,9 @@
|
||||||
<nav>
|
<nav>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<img src="logo?dark_mode=false&text=false" style="height: 50px" class="light-only" />
|
<img src="logo?variant=DarkText" style="height: 50px" class="light-only" />
|
||||||
<img src="logo?dark_mode=true&text=false" style="height: 50px" class="dark-only" />
|
<img src="logo?variant=LightText" style="height: 50px" class="dark-only" />
|
||||||
<strong>MakerLab Murnau Logo generator</strong>
|
logo generator
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -45,20 +45,24 @@
|
||||||
|
|
||||||
<form action="logo" method="get">
|
<form action="logo" method="get">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<div class="grid">
|
<label for="logo_variant">
|
||||||
<label for="logo_background_color">
|
Variant
|
||||||
Background color
|
|
||||||
</label>
|
</label>
|
||||||
<input type="color" id="logo_background_color" name="background_color" value="">
|
<select id="logo_variant" value="DarkText">
|
||||||
</div>
|
<option value="DarkText" selected>dark text</option>
|
||||||
<label for="logo_text">
|
<option value="LightText">light text</option>
|
||||||
<input type="checkbox" id="logo_text" name="text" role="switch">
|
<option value="NoText">no text</option>
|
||||||
Add text
|
</select>
|
||||||
</label>
|
|
||||||
<label for="logo_dark_mode">
|
|
||||||
<input type="checkbox" id="logo_dark_mode" name="dark_mode" role="switch">
|
<label for="logo_orientation">
|
||||||
Dark mode
|
Orientation
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
<select id="logo_orientation" value="Landscape">
|
||||||
|
<option value="Landscape" selected>landscape</option>
|
||||||
|
<option value="Portrait" selected>portrait</option>
|
||||||
|
</select>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
|
|
Loading…
Reference in a new issue