gdsdk/gds_model/
sref.rs

1use std::sync::Arc;
2use std::sync::RwLock;
3
4use super::*;
5use crate::gds_record;
6use crate::gds_writer;
7
8/// Gds ArrayRef or StructurRef
9/// refer Gds Structure
10#[derive(Debug)]
11pub struct Ref {
12    pub refed_struc: Arc<RwLock<Struc>>,
13    pub reflection_x: bool,
14    // pub abs_magnific: bool,
15    pub magnific: f64,
16    // pub abs_angel: bool,
17    pub angle: f64, //measured in degrees and in the counterclockwise direction
18    pub origin: Points,
19    pub row: i16,
20    pub column: i16,
21    pub spaceing_row: Vector,
22    pub spaceing_col: Vector,
23    pub property: Property,
24}
25
26impl Ref {
27    pub fn new(refto: &Arc<RwLock<Struc>>) -> Self {
28        Ref {
29            refed_struc: refto.clone(),
30            reflection_x: false,
31            magnific: 1.0,
32            angle: 0.0,
33            origin: Points::new(0.0, 0.0),
34            row: 0,
35            column: 0,
36            spaceing_row: Vector { x: 0.0, y: 0.0 },
37            spaceing_col: Vector { x: 0.0, y: 0.0 },
38            property: Property::default(),
39        }
40    }
41}
42
43impl GdsObject for Ref {
44    fn to_gds(&self, scaling: f64) -> Result<Vec<u8>, Box<dyn Error>> {
45        let mut data = Vec::<u8>::new();
46
47        // sref or aref
48        data.extend(4_i16.to_be_bytes());
49        let mut is_array = false;
50        if self.row != 0 || self.column != 0 {
51            is_array = true;
52        }
53
54        if is_array {
55            data.extend(gds_record::AREF);
56        } else {
57            data.extend(gds_record::SREF);
58        }
59
60        // refered gds structure name
61        let mut struc_name = Vec::<u8>::new();
62        struc_name.extend(gds_record::SNAME);
63
64        let struc = &*(self.refed_struc.read().unwrap());
65        let mut name = gds_writer::ascii_string_to_be_bytes(&struc.name);
66        if name.len() %2 != 0{
67            name.push(0);
68        }
69        struc_name.extend(name);
70
71        data.extend((struc_name.len() as i16 + 2_i16).to_be_bytes());
72        data.extend(struc_name);
73
74        // strans
75        data.extend(6_i16.to_be_bytes());
76        data.extend(gds_record::STRANS);
77
78        let mut flag: u16 = 0;
79        if self.reflection_x {
80            flag |= 0x8000
81        }
82        data.extend(flag.to_be_bytes());
83
84        // magnification
85        data.extend(12_u16.to_be_bytes());
86        data.extend(gds_record::MAG);
87        data.extend(gds_writer::f64_to_gds_bytes(self.magnific));
88
89        // rotate
90        data.extend(12_u16.to_be_bytes());
91        data.extend(gds_record::ANGLE);
92        data.extend(gds_writer::f64_to_gds_bytes(self.angle));
93
94        if is_array {
95            // colrow
96            data.extend(8_u16.to_be_bytes());
97            data.extend(gds_record::COLROW);
98            data.extend((self.column as u16).to_be_bytes());
99            data.extend((self.row as u16).to_be_bytes());
100            // xy
101            data.extend(28_u16.to_be_bytes());
102            data.extend(gds_record::XY);
103            data.extend((f64::round(self.origin.x * scaling) as i32).to_be_bytes());
104            data.extend((f64::round(self.origin.y * scaling) as i32).to_be_bytes());
105            // spaceing
106            data.extend(
107                (f64::round((self.spaceing_col.x * self.column as f64 + self.origin.x) * scaling)
108                    as i32)
109                    .to_be_bytes(),
110            );
111            data.extend(
112                (f64::round((self.spaceing_col.y * self.column as f64 + self.origin.y) * scaling)
113                    as i32)
114                    .to_be_bytes(),
115            );
116            data.extend(
117                (f64::round((self.spaceing_row.x * self.row as f64 + self.origin.x) * scaling)
118                    as i32)
119                    .to_be_bytes(),
120            );
121            data.extend(
122                (f64::round((self.spaceing_row.y * self.row as f64 + self.origin.y) * scaling)
123                    as i32)
124                    .to_be_bytes(),
125            );
126        } else {
127            data.extend(12_u16.to_be_bytes());
128            data.extend(gds_record::XY);
129            data.extend((f64::round(self.origin.x * scaling) as i32).to_be_bytes());
130            data.extend((f64::round(self.origin.y * scaling) as i32).to_be_bytes());
131        }
132
133        // properties
134        data.extend(self.property.to_gds(scaling)?);
135
136        // endel
137        data.extend(4_u16.to_be_bytes());
138        data.extend(gds_record::ENDEL);
139
140        Ok(data)
141    }
142}
143
144// FakeRef only used for gdsii file parse, cache Ref data
145pub(crate) struct FakeRef {
146    pub refed_struc_name: String,
147    pub reflection_x: bool,
148    // pub abs_magnific: bool,
149    pub magnific: f64,
150    // pub abs_angel: bool,
151    pub angle: f64, //measured in degrees and in the counterclockwise direction
152    pub origin: Points,
153    pub row: i16,
154    pub column: i16,
155    pub spaceing_row: Vector,
156    pub spaceing_col: Vector,
157    pub property: Property,
158}
159
160impl FakeRef {
161    pub(crate) fn new() -> Self {
162        FakeRef {
163            refed_struc_name: String::new(),
164            reflection_x: false,
165            magnific: 1.0,
166            angle: 0.0,
167            origin: Points::new(0.0, 0.0),
168            row: 0,
169            column: 0,
170            spaceing_row: Vector { x: 0.0, y: 0.0 },
171            spaceing_col: Vector { x: 0.0, y: 0.0 },
172            property: Property::default(),
173        }
174    }
175
176    pub(crate) fn create_true_ref(self, struc: &Arc<RwLock<Struc>>) -> Ref {
177        let mut struc_ref = Ref::new(struc);
178        struc_ref.reflection_x = self.reflection_x;
179        struc_ref.magnific = self.magnific;
180        struc_ref.angle = self.angle;
181        struc_ref.origin = self.origin;
182        struc_ref.row = self.row;
183        struc_ref.column = self.column;
184        struc_ref.spaceing_row = self.spaceing_row;
185        struc_ref.spaceing_col = self.spaceing_col;
186        struc_ref.property = self.property;
187        struc_ref
188    }
189}