1use std::sync::Arc;
2use std::sync::RwLock;
3
4use super::*;
5use crate::gds_record;
6use crate::gds_writer;
7
8#[derive(Debug)]
11pub struct Ref {
12 pub refed_struc: Arc<RwLock<Struc>>,
13 pub reflection_x: bool,
14 pub magnific: f64,
16 pub angle: f64, 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 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 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 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 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 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 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 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 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 data.extend(self.property.to_gds(scaling)?);
135
136 data.extend(4_u16.to_be_bytes());
138 data.extend(gds_record::ENDEL);
139
140 Ok(data)
141 }
142}
143
144pub(crate) struct FakeRef {
146 pub refed_struc_name: String,
147 pub reflection_x: bool,
148 pub magnific: f64,
150 pub angle: f64, 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}