From e0aee6375ece92f2613e45e470f83ec24609642c Mon Sep 17 00:00:00 2001 From: Stephen D <webmaster@scd31.com> Date: Fri, 15 Oct 2021 22:55:20 -0300 Subject: [PATCH] Among us font with SUS --- Cargo.lock | 93 +++++++++++++++++++++++-- Cargo.toml | 3 +- src/amongus.ttf | Bin 0 -> 15576 bytes src/handlers/mod.rs | 3 + src/handlers/sus.rs | 160 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 252 insertions(+), 7 deletions(-) create mode 100644 src/amongus.ttf create mode 100644 src/handlers/sus.rs diff --git a/Cargo.lock b/Cargo.lock index ab6188d..ad41dd1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "adler" version = "0.2.3" @@ -12,6 +14,15 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" +[[package]] +name = "arrayvec" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" +dependencies = [ + "nodrop", +] + [[package]] name = "async-trait" version = "0.1.41" @@ -65,7 +76,7 @@ checksum = "1374191e2dd25f9ae02e3aa95041ed5d747fc77b3c102b49fe2dd9a8117a6244" dependencies = [ "num-bigint", "num-integer", - "num-traits", + "num-traits 0.2.14", ] [[package]] @@ -111,6 +122,7 @@ dependencies = [ "phf", "png", "reqwest", + "rusttype", "serde", "serde_json", "serenity", @@ -145,7 +157,7 @@ checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" dependencies = [ "libc", "num-integer", - "num-traits", + "num-traits 0.2.14", "serde", "time", "winapi 0.3.9", @@ -204,7 +216,7 @@ dependencies = [ "diesel_derives", "num-bigint", "num-integer", - "num-traits", + "num-traits 0.2.14", "pq-sys", ] @@ -775,6 +787,12 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + [[package]] name = "num-bigint" version = "0.2.6" @@ -783,7 +801,7 @@ checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" dependencies = [ "autocfg", "num-integer", - "num-traits", + "num-traits 0.2.14", ] [[package]] @@ -804,7 +822,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" dependencies = [ "autocfg", - "num-traits", + "num-traits 0.2.14", +] + +[[package]] +name = "num-traits" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" +dependencies = [ + "num-traits 0.2.14", ] [[package]] @@ -871,6 +898,16 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "ordered-float" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb5259643245d3f292c7a146b2df53bba24d7eab159410e648eb73dc164669d" +dependencies = [ + "num-traits 0.1.43", + "unreachable", +] + [[package]] name = "percent-encoding" version = "2.1.0" @@ -1231,6 +1268,17 @@ dependencies = [ "webpki", ] +[[package]] +name = "rusttype" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ff03da02f6d340bbee5ec55eed03ff9abd6ea013b93bc7c35973cc28f65999" +dependencies = [ + "arrayvec", + "ordered-float", + "stb_truetype 0.2.8", +] + [[package]] name = "ryu" version = "1.0.5" @@ -1405,6 +1453,24 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "stb_truetype" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1bec4382294c5a680fcebd29f8451e8d8c04479a026f6909004e2ab1cb425d" +dependencies = [ + "stb_truetype 0.3.1", +] + +[[package]] +name = "stb_truetype" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f77b6b07e862c66a9f3e62a07588fee67cd90a9135a2b942409f195507b4fb51" +dependencies = [ + "byteorder", +] + [[package]] name = "syn" version = "0.15.44" @@ -1663,6 +1729,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +dependencies = [ + "void", +] + [[package]] name = "untrusted" version = "0.7.1" @@ -1699,6 +1774,12 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + [[package]] name = "want" version = "0.3.0" @@ -1887,6 +1968,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff711e02a0840644b63e9906fd12bc15e7346f08531467b3962b3ed712bdd6ba" dependencies = [ "num-derive", - "num-traits", + "num-traits 0.2.14", "phf", ] diff --git a/Cargo.toml b/Cargo.toml index c738368..3d6dc6b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,4 +18,5 @@ diesel = { version = "1.4", features = ["postgres", "numeric"] } dotenv = "0.15.0" bigdecimal = "0.1.2" reqwest = { version = "0.10", features = ["json"] } -serde_json = "1.0" \ No newline at end of file +serde_json = "1.0" +rusttype = "0.4.3" diff --git a/src/amongus.ttf b/src/amongus.ttf new file mode 100644 index 0000000000000000000000000000000000000000..359054c46a43ce71ef78e3d43397d20d14a49946 GIT binary patch literal 15576 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 literal 0 HcmV?d00001 diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index 730a63e..f02fdb0 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -1,9 +1,11 @@ mod joke; mod react; +mod sus; mod xbasic; use crate::handlers::joke::*; use crate::handlers::react::*; +use crate::handlers::sus::*; use crate::handlers::xbasic::*; use serenity::async_trait; @@ -46,6 +48,7 @@ impl Default for Dispatcher { Box::new(XbasicHandler::default()), Box::new(JokeHandler::default()), Box::new(ReactHandler::default()), + Box::new(SusHandler::default()), ], } } diff --git a/src/handlers/sus.rs b/src/handlers/sus.rs new file mode 100644 index 0000000..82856b0 --- /dev/null +++ b/src/handlers/sus.rs @@ -0,0 +1,160 @@ +use crate::framebuffer::FrameBuffer; +use crate::handlers::LineHandler; +use rusttype::LayoutIter; +use rusttype::{point, FontCollection, Scale}; +use serenity::async_trait; +use serenity::http::AttachmentType; +use serenity::model::channel::Message; +use serenity::prelude::*; +use std::borrow::Cow; + +const COLOUR: (u8, u8, u8) = (255, 0, 0); +const SCALE: Scale = Scale { x: 48.0, y: 48.0 }; +const PADDING_X: u32 = 0; +const PADDING_Y: u32 = 0; +const MAX_WIDTH: i32 = 800; +const Y_GAP: i32 = 5; + +// Wrap text when width exceeds MAX_WIDTH +struct WrappingLayoutIter<'a> { + iter: LayoutIter<'a, 'a>, + offset_x: i32, + offset_y: i32, + cur_x: i32, + cur_y: i32, +} + +impl<'a> WrappingLayoutIter<'a> { + fn new(iter: LayoutIter<'a, 'a>, offset_x: i32, offset_y: i32) -> Self { + Self { + iter, + offset_x, + offset_y, + cur_x: 0, + cur_y: 0, + } + } +} + +impl<'a> Iterator for WrappingLayoutIter<'a> { + type Item = Vec<(i32, i32, f32)>; + + fn next(&mut self) -> Option<Self::Item> { + let (glyph, bounding_box) = loop { + let glyph = self.iter.next()?; + if let Some(bb) = glyph.pixel_bounding_box() { + break (glyph, bb); + } + }; + + if bounding_box.max.x + self.cur_x > MAX_WIDTH { + self.cur_x = -bounding_box.min.x; + self.cur_y += bounding_box.max.y - bounding_box.min.y + Y_GAP; + } + + let mut buf = Vec::new(); + + glyph.draw(|x, y, a| { + let x = x as i32 + bounding_box.min.x + self.offset_x + self.cur_x; + let y = y as i32 + bounding_box.min.y + self.offset_y + self.cur_y; + + buf.push((x, y, a)); + }); + + Some(buf) + } +} + +#[derive(Default)] +pub struct SusHandler; + +impl SusHandler { + async fn render_font(&self, ctx: &Context, msg: &Message, s: &str) { + let font_data = include_bytes!("../amongus.ttf"); + let collection = FontCollection::from_bytes(font_data as &[u8]); + let font = collection.into_font().unwrap(); + + let start = point(0.0, 0.0); + + // Find image dimensions + let mut min_x = 0; + let mut max_x = 0; + let mut max_y = 0; + let mut min_y = 0; + for arr in WrappingLayoutIter::new(font.layout(s, SCALE, start), 0, 0) { + for (x, y, _) in arr { + if x < min_x { + min_x = x; + } + + if x > max_x { + max_x = x; + } + + if y < min_y { + min_y = y; + } + + if y > max_y { + max_y = y; + } + } + } + + let offset_x = -min_x; + let offset_y = -min_y; + max_x += offset_x; + max_y += offset_y; + + let mut framebuffer = + FrameBuffer::new(max_x as u32 + PADDING_X * 2, max_y as u32 + PADDING_Y * 2); + + for arr in WrappingLayoutIter::new( + font.layout(s, SCALE, start), + offset_x + PADDING_X as i32, + offset_y + PADDING_Y as i32, + ) { + for (x, y, a) in arr { + framebuffer.set_pixel( + x as u32, + y as u32, + COLOUR.0, + COLOUR.1, + COLOUR.2, + (a * 255.0) as u8, + ); + } + } + + let buf = framebuffer.as_png_vec(); + + msg.channel_id + .send_message(&ctx, |e| { + e.add_file(AttachmentType::Bytes { + data: Cow::Borrowed(&buf), + filename: "output.png".to_string(), + }); + + e + }) + .await + .unwrap(); + } +} + +#[async_trait] +impl LineHandler for SusHandler { + async fn line(&self, ctx: &Context, msg: &Message, line: &str) { + if line.starts_with("!SUS") { + let s = line.split(' ').collect::<Vec<_>>()[1..] + .join(" ") + .to_uppercase(); + + if s.is_empty() { + return; + } + + self.render_font(ctx, msg, &s).await; + } + } +} -- GitLab