use std::collections::HashMap;
use crate::font::FontHandle;
use crate::model::Color;
#[derive(Clone, Copy, Debug)]
pub struct Insets {
pub top: f32,
pub right: f32,
pub bottom: f32,
pub left: f32,
}
impl Insets {
pub const fn all(v: f32) -> Self {
Self { top: v, right: v, bottom: v, left: v }
}
pub const fn symmetric(v: f32, h: f32) -> Self {
Self { top: v, right: h, bottom: v, left: h }
}
}
#[derive(Clone, Debug)]
pub struct Theme {
pub background: Color,
pub text: Color,
pub accent: Color,
pub muted: Color,
pub code_bg: Color,
pub code_text: Color,
pub highlight: Color,
pub border: Color,
pub font_sans: String,
pub font_serif: String,
pub font_mono: String,
pub font_kai: String,
pub base_size: f32,
pub line_height: f32,
pub heading_scale: [f32; 6],
}
impl Theme {
pub fn light() -> Self {
Self {
background: Color::rgb(0xff, 0xff, 0xff),
text: Color::rgb(0x1f, 0x23, 0x28),
accent: Color::rgb(0x25, 0x63, 0xeb),
muted: Color::rgb(0x6e, 0x77, 0x81),
code_bg: Color::rgb(0xf3, 0xf4, 0xf6),
code_text: Color::rgb(0x1f, 0x23, 0x28),
highlight: Color::rgb(0xff, 0xf1, 0xa8),
border: Color::rgb(0xe5, 0xe7, 0xeb),
..Self::common()
}
}
pub fn dark() -> Self {
Self {
background: Color::rgb(0x0d, 0x11, 0x17),
text: Color::rgb(0xe6, 0xed, 0xf3),
accent: Color::rgb(0x58, 0xa6, 0xff),
muted: Color::rgb(0x8b, 0x94, 0x9e),
code_bg: Color::rgb(0x16, 0x1b, 0x22),
code_text: Color::rgb(0xe6, 0xed, 0xf3),
highlight: Color::rgb(0x57, 0x4a, 0x1a),
border: Color::rgb(0x30, 0x36, 0x3d),
..Self::common()
}
}
fn common() -> Self {
Self {
background: Color::rgb(0, 0, 0),
text: Color::rgb(0, 0, 0),
accent: Color::rgb(0, 0, 0),
muted: Color::rgb(0, 0, 0),
code_bg: Color::rgb(0, 0, 0),
code_text: Color::rgb(0, 0, 0),
highlight: Color::rgb(0, 0, 0),
border: Color::rgb(0, 0, 0),
font_sans: "Noto Sans SC".to_string(), font_serif: "Noto Serif SC".to_string(), font_mono: "JetBrains Mono".to_string(), font_kai: "LXGW WenKai GB".to_string(), base_size: 30.0,
line_height: 1.5,
heading_scale: [2.0, 1.6, 1.35, 1.15, 1.0, 0.9],
}
}
}
impl Default for Theme {
fn default() -> Self {
Self::light()
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum OutputFormat {
Png,
PngFast,
Webp,
WebpOrPng,
}
#[derive(Clone)]
pub struct RenderOptions {
pub width: f32,
pub padding: Insets,
pub scale: f32,
pub theme: Theme,
pub fonts: FontHandle,
pub format: OutputFormat,
pub images: HashMap<String, Vec<u8>>,
}
impl Default for RenderOptions {
fn default() -> Self {
Self {
width: 720.0,
padding: Insets::symmetric(32.0, 40.0),
scale: 2.0,
theme: Theme::light(),
fonts: FontHandle::shared_default(),
format: OutputFormat::Png,
images: HashMap::new(),
}
}
}
impl RenderOptions {
pub fn with_width(mut self, w: f32) -> Self {
self.width = w;
self
}
pub fn with_padding(mut self, p: Insets) -> Self {
self.padding = p;
self
}
pub fn with_theme(mut self, t: Theme) -> Self {
self.theme = t;
self
}
pub fn with_fonts(mut self, f: FontHandle) -> Self {
self.fonts = f;
self
}
pub fn with_scale(mut self, s: f32) -> Self {
self.scale = s.clamp(0.25, 8.0);
self
}
pub fn fast(self) -> Self {
self.with_scale(1.0)
}
pub fn standard(self) -> Self {
self.with_scale(1.5)
}
pub fn sharp(self) -> Self {
self.with_scale(2.0)
}
pub fn ultra(self) -> Self {
self.with_scale(3.0)
}
pub fn with_format(mut self, f: OutputFormat) -> Self {
self.format = f;
self
}
pub fn png(self) -> Self {
self.with_format(OutputFormat::Png)
}
pub fn png_fast(self) -> Self {
self.with_format(OutputFormat::PngFast)
}
pub fn webp(self) -> Self {
self.with_format(OutputFormat::Webp)
}
pub fn webp_or_png(self) -> Self {
self.with_format(OutputFormat::WebpOrPng)
}
}