use paperforge_core::{Color, Point, Size};
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Align {
Left,
Center,
Right,
Justified,
}
#[derive(Debug, Clone)]
pub enum Element {
Paragraph(Paragraph),
Heading(Heading),
Image(Image),
List(List),
Table(Table),
Spacer(Spacer),
}
#[derive(Debug, Clone)]
pub struct Paragraph {
pub text: String,
pub align: Align,
pub font_size: f64,
pub color: Color,
pub line_spacing: f64,
}
impl Paragraph {
pub fn new(text: &str) -> Self {
Self {
text: text.to_string(),
align: Align::Left,
font_size: 12.0,
color: Color::black(),
line_spacing: 1.15,
}
}
pub fn align(mut self, align: Align) -> Self {
self.align = align;
self
}
pub fn font_size(mut self, size: f64) -> Self {
self.font_size = size;
self
}
pub fn color(mut self, color: Color) -> Self {
self.color = color;
self
}
pub fn line_spacing(mut self, spacing: f64) -> Self {
self.line_spacing = spacing;
self
}
}
#[derive(Debug, Clone)]
pub struct Heading {
pub text: String,
pub level: u8,
pub font_size: f64,
pub color: Color,
}
impl Heading {
pub fn new(text: &str) -> Self {
Self {
text: text.to_string(),
level: 1,
font_size: 24.0,
color: Color::black(),
}
}
pub fn level(mut self, level: u8) -> Self {
self.level = level;
self
}
pub fn font_size(mut self, size: f64) -> Self {
self.font_size = size;
self
}
pub fn color(mut self, color: Color) -> Self {
self.color = color;
self
}
}
#[derive(Debug, Clone)]
pub struct Image {
pub data: Vec<u8>,
pub position: Point,
pub size: Size,
pub rotation: f64,
pub opacity: f64,
}
impl Image {
pub fn new(data: Vec<u8>) -> Self {
Self {
data,
position: Point::new(0.0, 0.0),
size: Size::new(100.0, 100.0),
rotation: 0.0,
opacity: 1.0,
}
}
pub fn at(mut self, x: f64, y: f64) -> Self {
self.position = Point::new(x, y);
self
}
pub fn width(mut self, width: f64) -> Self {
self.size.width = width;
self
}
pub fn height(mut self, height: f64) -> Self {
self.size.height = height;
self
}
pub fn rotate(mut self, angle: f64) -> Self {
self.rotation = angle;
self
}
pub fn opacity(mut self, opacity: f64) -> Self {
self.opacity = opacity.clamp(0.0, 1.0);
self
}
}
#[derive(Debug, Clone)]
pub enum List {
Unordered { items: Vec<String> },
Ordered { items: Vec<String> },
}
impl List {
pub fn unordered() -> Self {
Self::Unordered { items: Vec::new() }
}
pub fn ordered() -> Self {
Self::Ordered { items: Vec::new() }
}
pub fn item(mut self, text: &str) -> Self {
match &mut self {
Self::Unordered { items } => items.push(text.to_string()),
Self::Ordered { items } => items.push(text.to_string()),
}
self
}
}
#[derive(Debug, Clone)]
pub struct Table {
pub headers: Vec<String>,
pub rows: Vec<Vec<String>>,
pub column_widths: Vec<f64>,
}
impl Table {
pub fn new() -> Self {
Self {
headers: Vec::new(),
rows: Vec::new(),
column_widths: Vec::new(),
}
}
pub fn header(mut self, columns: &[&str]) -> Self {
self.headers = columns.iter().map(|s| s.to_string()).collect();
self
}
pub fn row(mut self, cells: &[&str]) -> Self {
self.rows
.push(cells.iter().map(|s| s.to_string()).collect());
self
}
pub fn column_widths(mut self, widths: Vec<f64>) -> Self {
self.column_widths = widths;
self
}
}
impl Default for Table {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone)]
pub struct Spacer {
pub height: f64,
}
impl Spacer {
pub fn new(height: f64) -> Self {
Self { height }
}
}