easyofd_core/page_obj/
ct_layer.rs1use super::CT_PageBlock;
4
5#[allow(non_camel_case_types)]
11#[derive(Debug, Clone)]
12pub struct CT_Layer {
13 pub layer_type: LayerType,
15 pub draw_param: Option<u32>,
17 pub block: CT_PageBlock,
19}
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23pub enum LayerType {
24 Body,
26 Foreground,
28 Background,
30}
31
32impl LayerType {
33 #[must_use]
35 pub fn as_str(&self) -> &'static str {
36 match self {
37 Self::Body => "Body",
38 Self::Foreground => "Foreground",
39 Self::Background => "Background",
40 }
41 }
42}
43
44impl std::fmt::Display for LayerType {
45 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46 f.write_str(self.as_str())
47 }
48}
49
50impl CT_Layer {
51 #[must_use]
53 pub fn new(layer_type: LayerType) -> Self {
54 Self {
55 layer_type,
56 draw_param: None,
57 block: CT_PageBlock::new(),
58 }
59 }
60
61 #[must_use]
63 pub fn body() -> Self {
64 Self::new(LayerType::Body)
65 }
66
67 #[must_use]
69 pub fn foreground() -> Self {
70 Self::new(LayerType::Foreground)
71 }
72
73 #[must_use]
75 pub fn background() -> Self {
76 Self::new(LayerType::Background)
77 }
78
79 #[must_use]
81 pub fn draw_param(mut self, id: u32) -> Self {
82 self.draw_param = Some(id);
83 self
84 }
85
86 #[must_use]
88 pub fn layer_type(mut self, layer_type: LayerType) -> Self {
89 self.layer_type = layer_type;
90 self
91 }
92
93 #[must_use]
95 pub fn get_type(&self) -> LayerType {
96 self.layer_type
97 }
98
99 #[must_use]
101 pub fn get_draw_param(&self) -> Option<u32> {
102 self.draw_param
103 }
104
105 pub fn add_page_block(&mut self, page_block: CT_PageBlock) {
107 self.block.add_page_block(page_block);
108 }
109
110 #[must_use]
112 pub fn to_xml_string(&self) -> String {
113 use std::fmt::Write;
114 let mut xml = format!("<ofd:Layer Type=\"{}\"", self.layer_type.as_str());
115 if let Some(dp) = self.draw_param {
116 write!(xml, " DrawParam=\"{dp}\"").expect("写入内存缓冲区不会失败");
117 }
118 xml.push_str(">\n");
119 for text_obj in &self.block.text_objects {
121 let _ = writeln!(
122 xml,
123 " <ofd:TextObject ID=\"{}\" Boundary=\"{}\">{}</ofd:TextObject>",
124 text_obj.id, text_obj.boundary, text_obj.content
125 );
126 }
127 for path_obj in &self.block.path_objects {
128 let _ = writeln!(
129 xml,
130 " <ofd:PathObject ID=\"{}\" Boundary=\"{}\">\
131 <ofd:AbbreviatedData>{}</ofd:AbbreviatedData>\
132 </ofd:PathObject>",
133 path_obj.id, path_obj.boundary, path_obj.abbreviated_data
134 );
135 }
136 for img_obj in &self.block.image_objects {
137 let _ = writeln!(
138 xml,
139 " <ofd:ImageObject ID=\"{}\" Boundary=\"{}\" ResourceID=\"{}\" />",
140 img_obj.id, img_obj.boundary, img_obj.resource_id
141 );
142 }
143 for nested in &self.block.page_blocks {
144 xml.push_str(&nested.to_xml_string());
145 }
146 xml.push_str("</ofd:Layer>\n");
147 xml
148 }
149}
150
151#[cfg(test)]
152mod tests {
153 use super::super::ct_page_block::{PageBlockImageObject, PageBlockTextObject};
154 use super::*;
155
156 #[test]
157 fn test_ct_layer_body() {
158 let layer = CT_Layer::body();
159 assert_eq!(layer.layer_type, LayerType::Body);
160 assert!(layer.draw_param.is_none());
161 }
162
163 #[test]
164 fn test_ct_layer_foreground() {
165 let layer = CT_Layer::foreground();
166 assert_eq!(layer.layer_type, LayerType::Foreground);
167 }
168
169 #[test]
170 fn test_ct_layer_background() {
171 let layer = CT_Layer::background();
172 assert_eq!(layer.layer_type, LayerType::Background);
173 }
174
175 #[test]
176 fn test_ct_layer_builder() {
177 let layer = CT_Layer::new(LayerType::Body).draw_param(42);
178 assert_eq!(layer.get_draw_param(), Some(42));
179 }
180
181 #[test]
182 fn test_layer_type_display() {
183 assert_eq!(LayerType::Body.to_string(), "Body");
184 assert_eq!(LayerType::Foreground.to_string(), "Foreground");
185 assert_eq!(LayerType::Background.to_string(), "Background");
186 }
187
188 #[test]
189 fn test_layer_type_as_str() {
190 assert_eq!(LayerType::Body.as_str(), "Body");
191 assert_eq!(LayerType::Foreground.as_str(), "Foreground");
192 assert_eq!(LayerType::Background.as_str(), "Background");
193 }
194
195 #[test]
196 fn test_ct_layer_to_xml_basic() {
197 let layer = CT_Layer::body();
198 let xml = layer.to_xml_string();
199 assert!(xml.contains("<ofd:Layer"));
200 assert!(xml.contains("Type=\"Body\""));
201 assert!(xml.contains("</ofd:Layer>"));
202 }
203
204 #[test]
205 fn test_ct_layer_to_xml_with_draw_param() {
206 let layer = CT_Layer::foreground().draw_param(7);
207 let xml = layer.to_xml_string();
208 assert!(xml.contains("DrawParam=\"7\""));
209 assert!(xml.contains("Type=\"Foreground\""));
210 }
211
212 #[test]
213 fn test_ct_layer_to_xml_with_content() {
214 let mut layer = CT_Layer::body();
215 layer
216 .block
217 .add_text_object(PageBlockTextObject::new(1, "0 0 50 20", "hi"));
218 layer
219 .block
220 .add_image_object(PageBlockImageObject::new(2, "0 0 100 100", 3));
221 let xml = layer.to_xml_string();
222 assert!(xml.contains("ofd:TextObject"));
223 assert!(xml.contains("hi"));
224 assert!(xml.contains("ofd:ImageObject"));
225 }
226
227 #[test]
228 fn test_ct_layer_clone_debug() {
229 let layer = CT_Layer::body();
230 let layer2 = layer.clone();
231 assert_eq!(layer2.layer_type, LayerType::Body);
232 assert!(format!("{layer:?}").contains("CT_Layer"));
233 }
234}