use crate::mark::Mark;
use crate::visual::color::SingleColor;
#[derive(Debug, Clone)]
pub struct MarkText {
pub(crate) text: String,
pub(crate) color: SingleColor,
pub(crate) font_size: f64,
pub(crate) font_family: String,
pub(crate) font_weight: FontWeight,
pub(crate) text_anchor: TextAnchor,
pub(crate) opacity: f64,
}
#[derive(Debug, Clone, Default)]
pub enum FontWeight {
#[default]
Normal,
Bold,
Weight(u16),
}
impl From<&str> for FontWeight {
fn from(s: &str) -> Self {
match s.to_lowercase().as_str() {
"bold" => FontWeight::Bold,
"normal" => FontWeight::Normal,
_ => {
s.parse::<u16>()
.map(FontWeight::Weight)
.unwrap_or(FontWeight::Normal)
}
}
}
}
impl std::fmt::Display for FontWeight {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
FontWeight::Normal => write!(f, "normal"),
FontWeight::Bold => write!(f, "bold"),
FontWeight::Weight(w) => write!(f, "{}", w),
}
}
}
#[derive(Debug, Clone, Default)]
pub enum TextAnchor {
Start,
#[default]
Middle,
End,
}
impl From<&str> for TextAnchor {
fn from(s: &str) -> Self {
match s.to_lowercase().as_str() {
"start" | "left" => TextAnchor::Start,
"end" | "right" => TextAnchor::End,
_ => TextAnchor::Middle, }
}
}
impl std::fmt::Display for TextAnchor {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
TextAnchor::Start => write!(f, "start"),
TextAnchor::Middle => write!(f, "middle"),
TextAnchor::End => write!(f, "end"),
}
}
}
impl MarkText {
pub(crate) fn new() -> Self {
let font_stack = "Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, 'PingFang SC', 'Microsoft YaHei', Ubuntu, Cantarell, 'Noto Sans', sans-serif".to_string();
Self {
text: String::new(),
color: SingleColor::new("black"),
font_size: 12.0,
font_family: font_stack,
font_weight: "normal".into(),
text_anchor: TextAnchor::default(),
opacity: 1.0,
}
}
pub fn with_color(mut self, color: impl Into<SingleColor>) -> Self {
self.color = color.into();
self
}
pub fn with_size(mut self, size: f64) -> Self {
self.font_size = size;
self
}
pub fn with_text(mut self, text: impl Into<String>) -> Self {
self.text = text.into();
self
}
pub fn with_weight(mut self, anchor: impl Into<FontWeight>) -> Self {
self.font_weight = anchor.into();
self
}
pub fn with_anchor(mut self, anchor: impl Into<TextAnchor>) -> Self {
self.text_anchor = anchor.into();
self
}
pub fn with_opacity(mut self, opacity: f64) -> Self {
self.opacity = opacity.clamp(0.0, 1.0);
self
}
}
impl Default for MarkText {
fn default() -> Self {
Self::new()
}
}
impl Mark for MarkText {
fn mark_type(&self) -> &'static str {
"text"
}
}