Skip to main content

easydoc_core/style/
font.rs

1use super::color::Color;
2
3/// 文本片段的字体配置。
4///
5/// 用于段落文本和表格单元格内容。
6///
7/// 对应 Java: `com.alibaba.excel.write.metadata.style.WriteFont`
8#[derive(Debug, Clone)]
9pub struct FontConfig {
10    /// Font family name (e.g. "Arial", "Times New Roman", "宋体").
11    pub name: Option<String>,
12    /// Font size in half-points (e.g. 24 = 12pt).
13    pub size: Option<u32>,
14    /// Whether the text is bold.
15    pub bold: bool,
16    /// Whether the text is italic.
17    pub italic: bool,
18    /// Whether the text is underlined.
19    pub underline: bool,
20    /// Text color. `None` means auto/inherit.
21    pub color: Option<Color>,
22}
23
24impl Default for FontConfig {
25    fn default() -> Self {
26        Self {
27            name: None,
28            size: Some(22), // 11pt default
29            bold: false,
30            italic: false,
31            underline: false,
32            color: Some(Color::BLACK),
33        }
34    }
35}
36
37impl FontConfig {
38    /// Creates default font configuration.
39    #[must_use]
40    pub fn new() -> Self {
41        Self::default()
42    }
43
44    /// Creates a bold font.
45    #[must_use]
46    pub fn bold() -> Self {
47        Self {
48            bold: true,
49            ..Default::default()
50        }
51    }
52
53    /// Creates a font for table headers (bold, white on blue).
54    #[must_use]
55    pub fn header() -> Self {
56        Self {
57            bold: true,
58            size: Some(22),
59            color: Some(Color::WHITE),
60            ..Default::default()
61        }
62    }
63
64    /// Sets the font family.
65    #[must_use]
66    pub fn name(mut self, name: impl Into<String>) -> Self {
67        self.name = Some(name.into());
68        self
69    }
70
71    /// Sets the font size in half-points.
72    #[must_use]
73    pub fn size(mut self, size: u32) -> Self {
74        self.size = Some(size);
75        self
76    }
77
78    /// Sets bold on or off.
79    #[must_use]
80    pub fn with_bold(mut self, bold: bool) -> Self {
81        self.bold = bold;
82        self
83    }
84
85    /// Sets italic on or off.
86    #[must_use]
87    pub fn with_italic(mut self, italic: bool) -> Self {
88        self.italic = italic;
89        self
90    }
91
92    /// Sets underline on or off.
93    #[must_use]
94    pub fn with_underline(mut self, underline: bool) -> Self {
95        self.underline = underline;
96        self
97    }
98
99    /// Sets the text color.
100    #[must_use]
101    pub fn color(mut self, color: Color) -> Self {
102        self.color = Some(color);
103        self
104    }
105}
106
107#[cfg(test)]
108mod tests {
109    use super::*;
110
111    #[test]
112    fn default_font_config() {
113        let f = FontConfig::default();
114        assert!(!f.bold);
115        assert!(!f.italic);
116        assert!(!f.underline);
117        assert_eq!(f.size, Some(22));
118        assert_eq!(f.color, Some(Color::BLACK));
119        assert!(f.name.is_none());
120    }
121
122    #[test]
123    fn new_equals_default() {
124        assert_eq!(FontConfig::new().size, FontConfig::default().size);
125    }
126
127    #[test]
128    fn bold_font() {
129        let f = FontConfig::bold();
130        assert!(f.bold);
131        assert!(!f.italic);
132    }
133
134    #[test]
135    fn header_font() {
136        let f = FontConfig::header();
137        assert!(f.bold);
138        assert_eq!(f.color, Some(Color::WHITE));
139        assert_eq!(f.size, Some(22));
140    }
141
142    #[test]
143    fn builder_chain() {
144        let f = FontConfig::new()
145            .name("Arial")
146            .size(28)
147            .with_bold(true)
148            .with_italic(true)
149            .with_underline(true)
150            .color(Color::RED);
151        assert_eq!(f.name.as_deref(), Some("Arial"));
152        assert_eq!(f.size, Some(28));
153        assert!(f.bold);
154        assert!(f.italic);
155        assert!(f.underline);
156        assert_eq!(f.color, Some(Color::RED));
157    }
158}