use nox_gfx::canvas::{Canvas, Paint}; use nox_gfx::color::{hex, rgba, Color}; use nox_gfx::geom::{pt, Rect}; use nox_text::{draw_text, measure, Font, GlyphCache, TextStyle}; const BG: Color = hex(0x0e0e16); const FG: Color = hex(0xe8e8f2); const DIM: Color = hex(0x8a8aa5); const ACCENT: Color = hex(0x7c5cff); const CYAN: Color = hex(0x35d0ff); const SANS: &str = "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"; const SANS_BOLD: &str = "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf"; const SERIF: &str = "/usr/share/fonts/truetype/dejavu/DejaVuSerif.ttf"; const MONO: &str = "/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf"; const LIB: &str = "/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf"; fn main() { let (w, h) = (1180usize, 1000usize); let mut c = Canvas::new(w, h); c.fill( &{ let mut p = nox_gfx::path::Path::new(); p.rect(c.full()); p }, &nox_gfx::geom::IDENTITY, &Paint::vgrad(c.full(), hex(0x14141f), BG), ); let sans_b = std::fs::read(SANS).unwrap(); let bold_b = std::fs::read(SANS_BOLD).unwrap(); let serif_b = std::fs::read(SERIF).unwrap(); let mono_b = std::fs::read(MONO).unwrap(); let lib_b = std::fs::read(LIB).unwrap(); let sans = Font::parse(&sans_b).unwrap(); let bold = Font::parse(&bold_b).unwrap(); let serif = Font::parse(&serif_b).unwrap(); let mono = Font::parse(&mono_b).unwrap(); let lib = Font::parse(&lib_b).unwrap(); let mut cache = GlyphCache::new(); cache.set_gamma(0.85); let mut y = 62.0; draw_text(&mut c, &mut cache, &bold, "Noxstrap", 60.0, y, TextStyle::new(46.0), FG); let wdt = measure(&bold, "Noxstrap", TextStyle::new(46.0)); draw_text( &mut c, &mut cache, &sans, "every glyph here was parsed and rasterised by this repo", 60.0 + wdt + 16.0, y, TextStyle::new(14.0), DIM, ); y += 40.0; c.fill_rect(Rect::new(60.0, y, 1120.0, y + 1.0), rgba(255, 255, 255, 26)); y += 40.0; draw_text(&mut c, &mut cache, &bold, "SIZE LADDER", 60.0, y, TextStyle { px: 11.0, letter_spacing: 1.6, kerning: true }, CYAN); y += 26.0; for px in [8.0f32, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 16.0, 18.0, 21.0, 24.0, 30.0] { draw_text(&mut c, &mut cache, &sans, &format!("{px:.0}"), 60.0, y, TextStyle::new(10.0), DIM); draw_text( &mut c, &mut cache, &sans, "Handgloves Roblox 0123 — the quick brown fox", 92.0, y, TextStyle::new(px), FG, ); y += px * 1.42 + 5.0; } y += 18.0; draw_text(&mut c, &mut cache, &bold, "KERNING", 60.0, y, TextStyle { px: 11.0, letter_spacing: 1.6, kerning: true }, CYAN); y += 28.0; for (label, kern) in [("off", false), ("on", true)] { draw_text(&mut c, &mut cache, &sans, label, 60.0, y, TextStyle::new(11.0), DIM); draw_text( &mut c, &mut cache, &sans, "AV Wa To LT V. Yo P, ff fi Type", 92.0, y, TextStyle { px: 26.0, letter_spacing: 0.0, kerning: kern }, if kern { FG } else { DIM }, ); y += 36.0; } y += 20.0; draw_text(&mut c, &mut cache, &bold, "FACES", 60.0, y, TextStyle { px: 11.0, letter_spacing: 1.6, kerning: true }, CYAN); y += 28.0; for (name, f) in [ ("DejaVu Sans", &sans), ("DejaVu Sans Bold", &bold), ("DejaVu Serif", &serif), ("DejaVu Sans Mono", &mono), ("Liberation Sans", &lib), ] { draw_text(&mut c, &mut cache, &sans, name, 60.0, y, TextStyle::new(11.0), DIM); draw_text(&mut c, &mut cache, f, "Bootstrapper — Ærøskøbing, naïve café 42%", 240.0, y, TextStyle::new(17.0), FG); y += 30.0; } y += 16.0; draw_text(&mut c, &mut cache, &bold, "COMPOSITES & COVERAGE", 60.0, y, TextStyle { px: 11.0, letter_spacing: 1.6, kerning: true }, CYAN); y += 30.0; draw_text(&mut c, &mut cache, &sans, "ÀÁÂÃÄÅ Çéèêë ñÑ öÖ üÜ ýÿ Ω→ ‹›«» ①②③ ★☆♠♥ ¼½¾ ≈≠≤≥", 60.0, y, TextStyle::new(22.0), FG); y += 46.0; let panel = Rect::new(60.0, y, 1120.0, y + 92.0); let mut p = nox_gfx::path::Path::new(); p.rrect(panel, 12.0); c.shadow(&p, &nox_gfx::geom::IDENTITY, 14.0, rgba(0, 0, 0, 150), pt(0.0, 6.0)); c.fill(&p, &nox_gfx::geom::IDENTITY, &Paint::vgrad(panel, hex(0x1b1b28), hex(0x15151f))); c.stroke(&p, &nox_gfx::geom::IDENTITY, &Paint::Solid(rgba(255, 255, 255, 20)), &nox_gfx::canvas::Stroke::new(1.0)); draw_text(&mut c, &mut cache, &bold, "Installing Roblox", 84.0, y + 34.0, TextStyle::new(17.0), FG); draw_text(&mut c, &mut cache, &mono, "version-a1b2c3d4e5f6 · 184.2 MB / 271.9 MB", 84.0, y + 58.0, TextStyle::new(12.5), DIM); let track = Rect::new(84.0, y + 70.0, 1096.0, y + 76.0); c.fill_rrect(track, 3.0, &Paint::Solid(rgba(255, 255, 255, 22))); let fill = Rect::new(track.x0, track.y0, track.x0 + (track.x1 - track.x0) * 0.677, track.y1); c.fill_rrect(fill, 3.0, &Paint::hgrad(fill, ACCENT, CYAN)); let out = std::env::args().nth(1).unwrap_or_else(|| "specimen.png".into()); std::fs::write(&out, c.to_png()).unwrap(); println!( "wrote {out} ({} glyphs cached, {} KB)", cache.len(), cache.bytes() / 1024 ); }