Chore: commit unstaged changed
This commit is contained in:
parent
9d89154b23
commit
cec5d50aa6
3 changed files with 40 additions and 29 deletions
|
@ -7,7 +7,7 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
png = "0.11.0"
|
||||
cairo-rs = { version = "0.17.0", default-features = false, features = ["png", "freetype"] }
|
||||
cairo-rs = { version = "0.17.0", default-features = false, features = ["png", "svg", "freetype"] }
|
||||
axum = "0.6.10"
|
||||
tokio = { version = "1.0", features = ["full"] }
|
||||
rand = "0.8.5"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use axum::{http::Request, response::Response, Router};
|
||||
use axum::{http::Request, response::Response, routing::get, Router};
|
||||
use std::{net::SocketAddr, time::Duration};
|
||||
use text::EmbeddedFonts;
|
||||
use tower_http::{catch_panic::CatchPanicLayer, trace::TraceLayer};
|
||||
|
@ -21,7 +21,8 @@ async fn main() {
|
|||
};
|
||||
let app = Router::new()
|
||||
.nest("/", routes::static_files::routes())
|
||||
.nest("/logo", routes::logo::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()
|
||||
|
|
|
@ -5,7 +5,7 @@ use axum::{
|
|||
routing::get,
|
||||
Router,
|
||||
};
|
||||
use cairo::{freetype::Face, Context, FontFace, Format, ImageSurface};
|
||||
use cairo::{freetype::Face, Context, FontFace, Format, ImageSurface, SvgSurface};
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{color::Color, polygon, text::DrawableText, SharedState};
|
||||
|
@ -27,23 +27,32 @@ enum LogoOrientation {
|
|||
}
|
||||
|
||||
#[derive(Deserialize, Default)]
|
||||
struct ImageProperties {
|
||||
pub struct ImageProperties {
|
||||
#[serde(default)]
|
||||
variant: LogoVariant,
|
||||
#[serde(default)]
|
||||
orientation: LogoOrientation,
|
||||
}
|
||||
|
||||
fn create_surface(properties: &ImageProperties) -> ImageSurface {
|
||||
let (width, height) = match (&properties.variant, &properties.orientation) {
|
||||
fn get_surface_size(properties: &ImageProperties) -> (i32, i32) {
|
||||
match (&properties.variant, &properties.orientation) {
|
||||
(LogoVariant::NoText, _) => (400, 400),
|
||||
(_, LogoOrientation::Landscape) => (2127, 591),
|
||||
(_, LogoOrientation::Portrait) => (1654, 1654),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn create_image_surface(properties: &ImageProperties) -> ImageSurface {
|
||||
let (width, height) = get_surface_size(properties);
|
||||
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) {
|
||||
|
@ -123,38 +132,21 @@ fn draw_text(
|
|||
}
|
||||
|
||||
#[axum_macros::debug_handler]
|
||||
async fn handler(
|
||||
pub async fn png(
|
||||
Query(properties): Query<ImageProperties>,
|
||||
State(state): State<SharedState>,
|
||||
) -> impl axum::response::IntoResponse {
|
||||
let start = Instant::now();
|
||||
let (font_regular, font_light) = state.fonts.get().await;
|
||||
println!("{:?}", start.elapsed());
|
||||
let start = Instant::now();
|
||||
|
||||
// cannot use await after this, because surface does not implement Send
|
||||
|
||||
let surface = create_surface(&properties);
|
||||
let surface = create_image_surface(&properties);
|
||||
let context = Context::new(&surface).unwrap();
|
||||
|
||||
println!("{:?}", (surface.width(), surface.height()));
|
||||
|
||||
println!("{:?}", start.elapsed());
|
||||
let start = Instant::now();
|
||||
|
||||
draw_logo(&context, &properties);
|
||||
println!("{:?}", start.elapsed());
|
||||
|
||||
let start = Instant::now();
|
||||
|
||||
draw_text(&context, &font_regular, &font_light, &properties);
|
||||
|
||||
println!("{:?}", start.elapsed());
|
||||
let start = Instant::now();
|
||||
|
||||
let mut data: Vec<u8> = Vec::new();
|
||||
surface.write_to_png(&mut data).unwrap();
|
||||
println!("{:?}", start.elapsed());
|
||||
|
||||
(
|
||||
axum::response::AppendHeaders([(axum::http::header::CONTENT_TYPE, "image/png")]),
|
||||
|
@ -162,6 +154,24 @@ async fn handler(
|
|||
)
|
||||
}
|
||||
|
||||
pub fn routes() -> Router<SharedState> {
|
||||
Router::<SharedState>::new().route("/", get(handler))
|
||||
#[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,
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue