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"
|
||||
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]]
|
||||
name = "async-trait"
|
||||
version = "0.1.66"
|
||||
|
@ -90,6 +99,16 @@ dependencies = [
|
|||
"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]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
|
@ -248,6 +267,19 @@ dependencies = [
|
|||
"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]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
|
@ -609,6 +641,23 @@ dependencies = [
|
|||
"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]]
|
||||
name = "rust-embed"
|
||||
version = "6.6.0"
|
||||
|
@ -639,6 +688,7 @@ version = "7.5.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "512b0ab6853f7e14e3c8754acb43d6f748bb9ced66aa5915a6553ac8213f7731"
|
||||
dependencies = [
|
||||
"globset",
|
||||
"sha2",
|
||||
"walkdir",
|
||||
]
|
||||
|
|
|
@ -12,6 +12,6 @@ axum = "0.6.10"
|
|||
tokio = { version = "1.0", features = ["full"] }
|
||||
rand = "0.8.5"
|
||||
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"
|
||||
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 cairo::{Context, Format, ImageSurface};
|
||||
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 {
|
||||
#[serde(default = "default_as_false")]
|
||||
#[serde(deserialize_with = "deserialize_bool")]
|
||||
dark_mode: bool,
|
||||
#[serde(default = "default_as_false")]
|
||||
#[serde(deserialize_with = "deserialize_bool")]
|
||||
text: bool,
|
||||
background_color: Option<Color>,
|
||||
#[serde(default)]
|
||||
variant: LogoVariant,
|
||||
#[serde(default)]
|
||||
orientation: LogoOrientation,
|
||||
}
|
||||
|
||||
#[derive(RustEmbed)]
|
||||
#[folder = "images"]
|
||||
#[folder = "artwork/logo"]
|
||||
#[include = "*_T.png"]
|
||||
struct ImageFiles;
|
||||
|
||||
fn get_surface_and_logo_coordiates(properties: &ImageProperties) -> (ImageSurface, (f64, f64)) {
|
||||
if properties.text {
|
||||
let image = ImageFiles::get("Makerlab.png").unwrap();
|
||||
(
|
||||
ImageSurface::create_from_png(&mut image.data.as_ref()).unwrap(),
|
||||
(604.0, 432.0),
|
||||
)
|
||||
} else {
|
||||
(
|
||||
fn get_surface_and_logo_coordiates(
|
||||
properties: &ImageProperties,
|
||||
) -> (ImageSurface, (f64, f64), f64, f64) {
|
||||
if let LogoVariant::NoText = properties.variant {
|
||||
return (
|
||||
ImageSurface::create(Format::ARgb32, 400, 400).unwrap(),
|
||||
(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 {
|
||||
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();
|
||||
|
||||
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.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();
|
||||
|
||||
let mut data: Vec<u8> = Vec::new();
|
||||
|
|
|
@ -27,9 +27,9 @@
|
|||
<nav>
|
||||
<ul>
|
||||
<li>
|
||||
<img src="logo?dark_mode=false&text=false" style="height: 50px" class="light-only" />
|
||||
<img src="logo?dark_mode=true&text=false" style="height: 50px" class="dark-only" />
|
||||
<strong>MakerLab Murnau Logo generator</strong>
|
||||
<img src="logo?variant=DarkText" style="height: 50px" class="light-only" />
|
||||
<img src="logo?variant=LightText" style="height: 50px" class="dark-only" />
|
||||
logo generator
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
|
@ -45,20 +45,24 @@
|
|||
|
||||
<form action="logo" method="get">
|
||||
<fieldset>
|
||||
<div class="grid">
|
||||
<label for="logo_background_color">
|
||||
Background color
|
||||
<label for="logo_variant">
|
||||
Variant
|
||||
</label>
|
||||
<input type="color" id="logo_background_color" name="background_color" value="">
|
||||
</div>
|
||||
<label for="logo_text">
|
||||
<input type="checkbox" id="logo_text" name="text" role="switch">
|
||||
Add text
|
||||
</label>
|
||||
<label for="logo_dark_mode">
|
||||
<input type="checkbox" id="logo_dark_mode" name="dark_mode" role="switch">
|
||||
Dark mode
|
||||
<select id="logo_variant" value="DarkText">
|
||||
<option value="DarkText" selected>dark text</option>
|
||||
<option value="LightText">light text</option>
|
||||
<option value="NoText">no text</option>
|
||||
</select>
|
||||
|
||||
|
||||
<label for="logo_orientation">
|
||||
Orientation
|
||||
</label>
|
||||
|
||||
<select id="logo_orientation" value="Landscape">
|
||||
<option value="Landscape" selected>landscape</option>
|
||||
<option value="Portrait" selected>portrait</option>
|
||||
</select>
|
||||
</fieldset>
|
||||
|
||||
<div class="grid">
|
||||
|
|
Loading…
Reference in a new issue