Compare commits
No commits in common. "8b139af1994862a010747ca1e105bb3da9d85557" and "cec5d50aa61a229bda1499bc167d8ca21618ad69" have entirely different histories.
8b139af199
...
cec5d50aa6
5 changed files with 318 additions and 444 deletions
705
Cargo.lock
generated
705
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -4,8 +4,6 @@ use text::EmbeddedFonts;
|
|||
use tower_http::{catch_panic::CatchPanicLayer, trace::TraceLayer};
|
||||
use tracing::Span;
|
||||
|
||||
use crate::routes::static_files;
|
||||
|
||||
mod color;
|
||||
mod polygon;
|
||||
mod routes;
|
||||
|
@ -22,9 +20,9 @@ async fn main() {
|
|||
fonts: EmbeddedFonts::load(),
|
||||
};
|
||||
let app = Router::new()
|
||||
.fallback(static_files::router)
|
||||
.route("/logo", get(routes::logo::png))
|
||||
.nest("/", routes::static_files::routes())
|
||||
.route("/logo.png", get(routes::logo::png))
|
||||
.route("/logo.svg", get(routes::logo::svg))
|
||||
.nest("/favicon.ico", routes::favicon::routes())
|
||||
.layer(
|
||||
TraceLayer::new_for_http()
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
use axum::extract::{Query, State};
|
||||
use cairo::{freetype::Face, Context, FontFace, Format, ImageSurface};
|
||||
use std::time::Instant;
|
||||
|
||||
use axum::{
|
||||
extract::{Query, State},
|
||||
routing::get,
|
||||
Router,
|
||||
};
|
||||
use cairo::{freetype::Face, Context, FontFace, Format, ImageSurface, SvgSurface};
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{color::Color, polygon, text::DrawableText, SharedState};
|
||||
|
@ -41,6 +47,12 @@ fn create_image_surface(properties: &ImageProperties) -> ImageSurface {
|
|||
ImageSurface::create(Format::ARgb32, width, height).unwrap()
|
||||
}
|
||||
|
||||
fn create_svg_surface(properties: &ImageProperties) -> SvgSurface {
|
||||
let (width, height) = get_surface_size(properties);
|
||||
|
||||
SvgSurface::new::<String>(width as f64, height as f64, None).unwrap()
|
||||
}
|
||||
|
||||
fn draw_logo(context: &Context, properties: &ImageProperties) {
|
||||
let (logo_coordinates, logo_outer_radius, logo_inner_radius) =
|
||||
match (&properties.variant, &properties.orientation) {
|
||||
|
@ -141,3 +153,25 @@ pub async fn png(
|
|||
data,
|
||||
)
|
||||
}
|
||||
|
||||
#[axum_macros::debug_handler]
|
||||
pub async fn svg(
|
||||
Query(properties): Query<ImageProperties>,
|
||||
State(state): State<SharedState>,
|
||||
) -> impl axum::response::IntoResponse {
|
||||
let (font_regular, font_light) = state.fonts.get().await;
|
||||
|
||||
// cannot use await after this, because surface does not implement Send
|
||||
let surface = create_svg_surface(&properties);
|
||||
let context = Context::new(&surface).unwrap();
|
||||
|
||||
draw_logo(&context, &properties);
|
||||
draw_text(&context, &font_regular, &font_light, &properties);
|
||||
|
||||
let mut data: Vec<u8> = Vec::new();
|
||||
surface.write_to_png(&mut data).unwrap();
|
||||
(
|
||||
axum::response::AppendHeaders([(axum::http::header::CONTENT_TYPE, "image/png")]),
|
||||
data,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -2,14 +2,17 @@ use axum::{
|
|||
body::{boxed, Full},
|
||||
http::{header, StatusCode, Uri},
|
||||
response::{IntoResponse, Response},
|
||||
Router,
|
||||
};
|
||||
use rust_embed::{EmbeddedFile, RustEmbed};
|
||||
|
||||
use crate::SharedState;
|
||||
|
||||
#[derive(RustEmbed)]
|
||||
#[folder = "web"]
|
||||
struct StaticFiles;
|
||||
|
||||
pub async fn router(uri: Uri) -> impl IntoResponse {
|
||||
async fn static_files(uri: Uri) -> impl IntoResponse {
|
||||
let path = uri.path().trim_start_matches('/');
|
||||
|
||||
match StaticFiles::get(path) {
|
||||
|
@ -47,3 +50,7 @@ fn not_found() -> Response {
|
|||
.body(boxed(Full::from("404")))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn routes() -> Router<SharedState> {
|
||||
Router::new().fallback(static_files)
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
<label for="logo_variant">
|
||||
Variant
|
||||
</label>
|
||||
<select id="logo_variant" name="variant" value="DarkText">
|
||||
<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>
|
||||
|
@ -59,7 +59,7 @@
|
|||
Orientation
|
||||
</label>
|
||||
|
||||
<select id="logo_orientation" name="orientation" value="Landscape">
|
||||
<select id="logo_orientation" value="Landscape">
|
||||
<option value="Landscape" selected>landscape</option>
|
||||
<option value="Portrait" selected>portrait</option>
|
||||
</select>
|
||||
|
|
Loading…
Reference in a new issue