Feat: add new logo
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed

This commit is contained in:
Dorian Zedler 2023-04-20 17:08:55 +02:00
parent 5ca0021533
commit 43b0b1d7a7
Signed by: dozedler
GPG key ID: 989DE36109AFA354
7 changed files with 139 additions and 43 deletions

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "artwork"]
path = artwork
url = https://git.makerlab-murnau.de/MakerLab/artwork.git

50
Cargo.lock generated
View file

@ -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",
] ]

View file

@ -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

@ -0,0 +1 @@
Subproject commit f7ead83291e2f462888d73530f239ab3a48b4abd

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

View file

@ -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,50 +27,86 @@ 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_rgba(0.0, 0.0, 0.0, 0.0);
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(); context.paint().unwrap();
polygon::draw_polygon_of_segmented_polygons(logo_coordinates, 148.0, 67.0, 6, &context) polygon::draw_polygon_of_segmented_polygons(
.unwrap(); logo_coordinates,
logo_outer_radius,
logo_inner_radius,
6,
&context,
)
.unwrap();
let mut data: Vec<u8> = Vec::new(); let mut data: Vec<u8> = Vec::new();
surface.write_to_png(&mut data).unwrap(); surface.write_to_png(&mut data).unwrap();

View file

@ -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>
<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>
<label for="logo_dark_mode"> <select id="logo_variant" value="DarkText">
<input type="checkbox" id="logo_dark_mode" name="dark_mode" role="switch"> <option value="DarkText" selected>dark text</option>
Dark mode <option value="LightText">light text</option>
<option value="NoText">no text</option>
</select>
<label for="logo_orientation">
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">