Skip to main content

reda_gds/io/write/
text.rs

1use std::{fs::File, path::Path};
2use crate::{GdsAref, GdsBoundary, GdsBox, GdsLibrary, GdsNode, GdsPath, GdsSref, GdsStructure, GdsText};
3
4use super::GdsWriteResult;
5
6pub struct TextWriter<W> {
7    writer: W,
8}
9
10impl TextWriter<File> {
11    pub fn open<P: AsRef<Path>>(path: P) -> GdsWriteResult<Self> {
12        let file = File::create(path)?;
13        Ok(Self { writer: file })
14    }
15}
16
17impl<W: std::io::Write> TextWriter<W> {
18    pub fn new(writer: W) -> Self {
19        Self { writer }
20    }
21}
22
23impl<W: std::io::Write> TextWriter<W> {
24    pub fn write(&mut self, layout: &GdsLibrary) -> GdsWriteResult<()> {
25        let indent = 0;
26        self.write_indent(indent)?;
27        writeln!(self.writer, "GDSII Layout Object")?;
28
29        let attr_indent = indent + 1;
30
31        self.write_indent(attr_indent)?;
32        writeln!(self.writer, "version: {}", layout.version)?;
33
34        self.write_indent(attr_indent)?;
35        writeln!(self.writer, "library name: {}", layout.name)?;
36
37        self.write_indent(attr_indent)?;
38        writeln!(self.writer, "units: ({}, {})", layout.usrunits_per_dbunit, layout.meters_per_dbunit)?;
39
40        self.write_indent(attr_indent)?;
41        writeln!(self.writer, "create date: {}", layout.create_date.to_string())?;
42
43        self.write_indent(attr_indent)?;
44        writeln!(self.writer, "modify date: {}", layout.modify_date.to_string())?;
45
46        for (_key, structure) in &layout.structures {
47            self.write_structure(&structure.read().unwrap(), attr_indent)?;
48        }
49
50        Ok(())
51    }
52}
53
54
55impl<W: std::io::Write> TextWriter<W> {
56    pub fn write_structure(&mut self, structure: &GdsStructure, indent: usize) -> GdsWriteResult<()> {
57        self.write_indent(indent)?;
58        writeln!(self.writer, "Structure:")?;
59
60        let attr_indent = indent + 1;
61
62        self.write_indent(attr_indent)?;
63        writeln!(self.writer, "name: {}", structure.name)?;
64
65        self.write_indent(attr_indent)?;
66        writeln!(self.writer, "create date: {}", structure.create_date.to_string())?;
67
68        self.write_indent(attr_indent)?;
69        writeln!(self.writer, "modify date: {}", structure.modify_date.to_string())?;
70
71        for e in &structure.boundarys {
72            self.write_boundary(e, attr_indent)?;
73        }
74
75        for e in &structure.paths {
76            self.write_path(e, attr_indent)?;
77        }
78
79        for e in &structure.srefs {
80            self.write_sref(e, attr_indent)?;
81        }
82
83        for e in &structure.arefs {
84            self.write_aref(e, attr_indent)?;
85        }
86
87        for e in &structure.texts {
88            self.write_text(e, attr_indent)?;
89        }
90
91        for e in &structure.nodes {
92            self.write_node(e, attr_indent)?;
93        }
94
95        for e in &structure.boxes {
96            self.write_box(e, attr_indent)?;
97        }
98
99        Ok(())
100    }
101}
102
103
104impl<W: std::io::Write> TextWriter<W> {
105    pub fn write_boundary(&mut self, boundary: &GdsBoundary, indent: usize) -> GdsWriteResult<()> {
106        self.write_indent(indent)?;
107        writeln!(self.writer, "Boundary Element")?;
108
109        let attr_indent = indent + 1;
110
111        if let Some(flags) = boundary.elf_flags {
112            self.write_indent(attr_indent)?;
113            writeln!(self.writer, "elf_flags: {}", flags)?;
114        }
115
116        if let Some(plex) = boundary.plex {
117            self.write_indent(attr_indent)?;
118            writeln!(self.writer, "plex: {}", plex)?;
119        }
120
121        self.write_indent(attr_indent)?;
122        writeln!(self.writer, "layer: {}", boundary.layer)?;
123
124        self.write_indent(attr_indent)?;
125        writeln!(self.writer, "data_type: {}", boundary.data_type)?;
126
127        self.write_indent(attr_indent)?;
128        write!(self.writer, "xy: [")?;
129        for (i, coord) in boundary.xy.iter().enumerate() {
130            if i > 0 {
131                write!(self.writer, ", ")?;
132            }
133            write!(self.writer, "({}, {})", coord.x, coord.y)?;
134        }
135        writeln!(self.writer, "]")?;
136
137        Ok(())
138    }
139
140    pub fn write_path(&mut self, path: &GdsPath, indent: usize) -> GdsWriteResult<()> {
141        self.write_indent(indent)?;
142        writeln!(self.writer, "Path Element")?;
143
144        let attr_indent = indent + 1;
145
146        if let Some(flags) = path.elf_flags {
147            self.write_indent(attr_indent)?;
148            writeln!(self.writer, "elf_flags: {}", flags)?;
149        }
150
151        if let Some(plex) = path.plex {
152            self.write_indent(attr_indent)?;
153            writeln!(self.writer, "plex: {}", plex)?;
154        }
155
156        self.write_indent(attr_indent)?;
157        writeln!(self.writer, "layer: {}", path.layer)?;
158
159        if let Some(purpose) = path.purpose_layer {
160            self.write_indent(attr_indent)?;
161            writeln!(self.writer, "purpose layer: {}", purpose)?;
162        }
163
164        self.write_indent(attr_indent)?;
165        writeln!(self.writer, "data_type: {}", path.data_type)?;
166
167        self.write_indent(attr_indent)?;
168        writeln!(self.writer, "path_type: {}", path.path_type)?;
169
170        if let Some(width) = path.width {
171            self.write_indent(attr_indent)?;
172            writeln!(self.writer, "width: {}", width)?;
173        }
174
175        self.write_indent(attr_indent)?;
176        write!(self.writer, "xy: [")?;
177        for (i, coord) in path.xy.iter().enumerate() {
178            if i > 0 {
179                write!(self.writer, ", ")?;
180            }
181            write!(self.writer, "({}, {})", coord.x, coord.y)?;
182        }
183        writeln!(self.writer, "]")?;
184
185        Ok(())
186    }
187
188    pub fn write_sref(&mut self, sref: &GdsSref, indent: usize) -> GdsWriteResult<()> {
189        self.write_indent(indent)?;
190        writeln!(self.writer, "Sref Element")?;
191
192        let attr_indent = indent + 1;
193
194        if let Some(flags) = sref.elf_flags {
195            self.write_indent(attr_indent)?;
196            writeln!(self.writer, "elf_flags: {}", flags)?;
197        }
198
199        if let Some(plex) = sref.plex {
200            self.write_indent(attr_indent)?;
201            writeln!(self.writer, "plex: {}", plex)?;
202        }
203
204        self.write_indent(attr_indent)?;
205        writeln!(self.writer, "s_name: {}", sref.s_name)?;
206
207        if let Some(transform) = &sref.transform {
208            self.write_indent(attr_indent)?;
209            write!(self.writer, "s_trans:")?;
210            if transform.flag.reflect {
211                write!(self.writer, " x_mirror")?;
212            }
213            if transform.flag.absolute_magnification {
214                write!(self.writer, "absolute magnification")?;
215            }
216            if transform.flag.absolute_angle {
217                write!(self.writer, "absolute angle")?;
218            }
219            writeln!(self.writer)?;
220        
221            self.write_indent(attr_indent)?;
222            writeln!(self.writer, "mag: {}", transform.magnification())?;
223            self.write_indent(attr_indent)?;
224            writeln!(self.writer, "angle: {}", transform.angle())?;
225        }
226
227        self.write_indent(attr_indent)?;
228        writeln!(self.writer, "coordinate: [{}, {}]", sref.position.x, sref.position.y)?;
229
230        Ok(())
231    }
232
233    pub fn write_aref(&mut self, aref: &GdsAref, indent: usize) -> GdsWriteResult<()> {
234        self.write_indent(indent)?;
235        writeln!(self.writer, "Aref Element")?;
236
237        let attr_indent = indent + 1;
238
239        if let Some(flags) = aref.elf_flags {
240            self.write_indent(attr_indent)?;
241            writeln!(self.writer, "elf_flags: {}", flags)?;
242        }
243
244        if let Some(plex) = aref.plex {
245            self.write_indent(attr_indent)?;
246            writeln!(self.writer, "plex: {}", plex)?;
247        }
248
249        self.write_indent(attr_indent)?;
250        writeln!(self.writer, "s_name: {}", aref.s_name)?;
251
252        if let Some(transform) = &aref.transform {
253            self.write_indent(attr_indent)?;
254            write!(self.writer, "s_trans:")?;
255            if transform.flag.reflect {
256                write!(self.writer, " x_mirror")?;
257            }
258            if transform.flag.absolute_magnification {
259                write!(self.writer, "absolute magnification")?;
260            }
261            if transform.flag.absolute_angle {
262                write!(self.writer, "absolute angle")?;
263            }
264            writeln!(self.writer)?;
265        
266            self.write_indent(attr_indent)?;
267            writeln!(self.writer, "mag: {}", transform.magnification())?;
268            self.write_indent(attr_indent)?;
269            writeln!(self.writer, "angle: {}", transform.angle())?;
270        }
271
272        self.write_indent(attr_indent)?;
273        writeln!(self.writer, "col: {}", aref.col)?;
274
275        self.write_indent(attr_indent)?;
276        writeln!(self.writer, "row: {}", aref.row)?;
277
278        self.write_indent(attr_indent)?;
279        writeln!(self.writer, "coordinate: [{}, {}]", aref.position.x, aref.position.y)?;
280
281        Ok(())
282    }
283
284    pub fn write_text(&mut self, text: &GdsText, indent: usize) -> GdsWriteResult<()> {
285        self.write_indent(indent)?;
286        writeln!(self.writer, "Text Element")?;
287
288        let attr_indent = indent + 1;
289
290        if let Some(flags) = text.elf_flags {
291            self.write_indent(attr_indent)?;
292            writeln!(self.writer, "elf_flags: {}", flags)?;
293        }
294
295        if let Some(plex) = text.plex {
296            self.write_indent(attr_indent)?;
297            writeln!(self.writer, "plex: {}", plex)?;
298        }
299
300        self.write_indent(attr_indent)?;
301        writeln!(self.writer, "layer: {}", text.layer)?;
302
303        self.write_indent(attr_indent)?;
304        writeln!(self.writer, "data_type: {}", text.text_type)?;
305
306        if let Some(presentation) = text.presentation {
307            self.write_indent(attr_indent)?;
308            writeln!(self.writer, "presentation: {}", presentation)?;
309        }
310
311        self.write_indent(attr_indent)?;
312        writeln!(self.writer, "path_type: {}", text.path_type)?;
313
314        if let Some(width) = text.width {
315            self.write_indent(attr_indent)?;
316            writeln!(self.writer, "width: {}", width)?;
317        }
318
319        if let Some(transform) = &text.transform {
320            self.write_indent(attr_indent)?;
321            write!(self.writer, "s_trans:")?;
322            if transform.flag.reflect {
323                write!(self.writer, " x_mirror")?;
324            }
325            if transform.flag.absolute_magnification {
326                write!(self.writer, "absolute magnification")?;
327            }
328            if transform.flag.absolute_angle {
329                write!(self.writer, "absolute angle")?;
330            }
331            writeln!(self.writer)?;
332            
333            self.write_indent(attr_indent)?;
334            writeln!(self.writer, "mag: {}", transform.magnification())?;
335            self.write_indent(attr_indent)?;
336            writeln!(self.writer, "angle: {}", transform.angle())?;
337        }
338
339        self.write_indent(attr_indent)?;
340        writeln!(self.writer, "coordinate: [{}, {}]", text.position.x, text.position.y)?;
341
342        self.write_indent(attr_indent)?;
343        writeln!(self.writer, "string: {}", text.string)?;
344
345        Ok(())
346    }
347
348    pub fn write_node(&mut self, node: &GdsNode, indent: usize) -> GdsWriteResult<()> {
349        self.write_indent(indent)?;
350        writeln!(self.writer, "Node Element")?;
351
352        let attr_indent = indent + 1;
353
354        if let Some(flags) = node.elf_flags {
355            self.write_indent(attr_indent)?;
356            writeln!(self.writer, "elf_flags: {}", flags)?;
357        }
358
359        if let Some(plex) = node.plex {
360            self.write_indent(attr_indent)?;
361            writeln!(self.writer, "plex: {}", plex)?;
362        }
363
364        self.write_indent(attr_indent)?;
365        writeln!(self.writer, "layer: {}", node.layer)?;
366
367        self.write_indent(attr_indent)?;
368        writeln!(self.writer, "data_type: {}", node.node_type)?;
369
370        self.write_indent(attr_indent)?;
371        write!(self.writer, "xy: [")?;
372        for coord in &node.xy {
373            write!(self.writer, "({}, {}), ", coord.x, coord.y)?;
374        }
375        writeln!(self.writer, "]")?;
376
377        Ok(())
378    }
379
380    pub fn write_box(&mut self, boxx: &GdsBox, indent: usize) -> GdsWriteResult<()> {
381        self.write_indent(indent)?;
382        writeln!(self.writer, "Box Element")?;
383
384        let attr_indent = indent + 1;
385
386        if let Some(flags) = boxx.elf_flags {
387            self.write_indent(attr_indent)?;
388            writeln!(self.writer, "elf_flags: {}", flags)?;
389        }
390
391        if let Some(plex) = boxx.plex {
392            self.write_indent(attr_indent)?;
393            writeln!(self.writer, "plex: {}", plex)?;
394        }
395
396        self.write_indent(attr_indent)?;
397        writeln!(self.writer, "layer: {}", boxx.layer)?;
398
399        self.write_indent(attr_indent)?;
400        writeln!(self.writer, "box_type: {}", boxx.box_type)?;
401
402        self.write_indent(attr_indent)?;
403        write!(self.writer, "xy: [")?;
404        for coord in &boxx.xy {
405            write!(self.writer, "({}, {}), ", coord.x, coord.y)?;
406        }
407        writeln!(self.writer, "]")?;
408
409        Ok(())
410    }
411}
412
413impl<W: std::io::Write> TextWriter<W> {
414    fn write_indent(&mut self, level: usize) -> GdsWriteResult<()> {
415        for _ in 0..level {
416            write!(self.writer, "    ")?;
417        }
418        Ok(())
419    }
420}