Compare commits

..

No commits in common. "8b139af1994862a010747ca1e105bb3da9d85557" and "cec5d50aa61a229bda1499bc167d8ca21618ad69" have entirely different histories.

5 changed files with 318 additions and 444 deletions

705
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

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

View file

@ -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,
)
}

View file

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

View file

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