#[cfg(feature = "pyo3")]
use pyo3::prelude::*;
use serde::Deserialize;
use super::{
SolidColor,
layers::{Background, Ellipse, Icon, LayerOffset, Polygon, Rectangle, Size, Typography},
};
#[cfg_attr(
feature = "pyo3",
pyclass(module = "img_gen", get_all, set_all, from_py_object)
)]
#[derive(Debug, Clone, Default, Deserialize)]
pub struct Mask {
pub size: Option<Size>,
pub offset: LayerOffset,
pub invert: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub background: Option<Background>,
#[serde(skip_serializing_if = "Option::is_none")]
pub rectangle: Option<Rectangle>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ellipse: Option<Ellipse>,
#[serde(skip_serializing_if = "Option::is_none")]
pub polygon: Option<Polygon>,
#[serde(skip_serializing_if = "Option::is_none")]
pub icon: Option<Icon>,
#[serde(skip_serializing_if = "Option::is_none")]
pub typography: Option<Typography>,
}
#[cfg_attr(
feature = "pyo3",
pyclass(module = "img_gen", get_all, set_all, from_py_object)
)]
#[derive(Debug, Clone, Default, Deserialize)]
pub struct Layer {
pub size: Option<Size>,
#[serde(default)]
pub offset: LayerOffset,
pub background: Option<Background>,
pub rectangle: Option<Rectangle>,
pub ellipse: Option<Ellipse>,
pub polygon: Option<Polygon>,
pub icon: Option<Icon>,
pub typography: Option<Typography>,
pub mask: Option<Mask>,
}
#[cfg_attr(
feature = "pyo3",
pyclass(module = "img_gen", set_all, get_all, from_py_object)
)]
#[derive(Debug, Clone, Deserialize)]
pub struct Debug {
#[serde(default)]
pub enable: bool,
#[serde(default = "Debug::default_grid")]
pub grid: bool,
#[serde(default = "Debug::default_grid_step")]
pub grid_step: u32,
#[serde(default = "Debug::default_color")]
pub color: SolidColor,
}
impl Debug {
pub fn get_foreground_color(&self) -> SolidColor {
let luminance = {
let mut result = 0.0f32;
for (index, c) in vec![
&self.color.get_r(),
&self.color.get_g(),
&self.color.get_b(),
]
.into_iter()
.take(3)
.enumerate()
{
let component = *c as f32 / 255.0;
let new_component = if component <= 0.03928 {
component / 12.92
} else {
((component + 0.055) / 1.055).powf(2.4)
};
match index {
0 => {
result += 0.2126 * new_component;
}
1 => {
result += 0.7152 * new_component;
}
_ => {
result += 0.0722 * new_component;
}
}
}
result
};
if luminance > 0.451 {
SolidColor::new(0, 0, 0, 255)
} else {
SolidColor::new(255, 255, 255, 255)
}
}
pub(crate) const fn default_grid_step() -> u32 {
30
}
pub(crate) fn default_color() -> SolidColor {
SolidColor::new(128, 128, 128, 255)
}
const fn default_grid() -> bool {
true
}
}
impl Default for Debug {
fn default() -> Self {
Self {
enable: false,
grid: Self::default_grid(),
grid_step: Self::default_grid_step(),
color: Self::default_color(),
}
}
}
#[cfg_attr(
feature = "pyo3",
pyclass(module = "img_gen", set_all, get_all, from_py_object)
)]
#[derive(Debug, Clone, Default, Deserialize)]
pub struct Layout {
#[serde(default)]
pub size: Size,
#[serde(default)]
pub layers: Vec<Layer>,
pub debug: Option<Debug>,
}