1 /***************************************************************************
2 SCED - Schematic Capture Editor
3 JSPICE3 adaptation of Spice3e2 - Copyright (c) Stephen R. Whiteley 1992
4 Copyright 1990 Regents of the University of California.  All rights reserved.
5 Authors: 1981 Giles C. Billingsley  (parts of KIC layout editor)
6          1992 Stephen R. Whiteley
7 ****************************************************************************/
8 
9 /*
10  * Transforms package.
11  */
12 
13 #include "cddefs.h"
14 #include <string.h>
15 
16 struct tt {
17     long ttMatrix[3][3];
18     struct tt *ttNext;
19 };
20 static struct tt *Transforms;
21 
22 void
TInit()23 TInit()
24 {
25     struct tt *Tmp;
26 
27     for (Tmp = Transforms; Tmp; Tmp = Transforms) {
28         Transforms = Tmp->ttNext;
29         tfree(Tmp);
30     }
31     Transforms = alloc(tt);
32     if (Transforms == NULL) MallocFailed();
33     Transforms->ttNext = NULL;
34     TIdentity();
35 }
36 
37 int
TEmpty()38 TEmpty()
39 {
40     if (Transforms == NULL)
41         return(True);
42     else
43         return(False);
44 }
45 
46 int
TFull()47 TFull()
48 {
49     return(False);
50 }
51 
52 void
TPush()53 TPush()
54 {
55     struct tt *Tmp;
56 
57     Tmp = alloc(tt);
58     if (Tmp == NULL) MallocFailed();
59     Tmp->ttNext = Transforms;
60     Transforms = Tmp;
61 }
62 
63 void
TPop()64 TPop()
65 {
66     struct tt *Tmp;
67 
68     Tmp = Transforms;
69     Transforms = Tmp->ttNext;
70     tfree(Tmp);
71 }
72 
73 void
TCurrent(TFP)74 TCurrent(TFP)
75 long *TFP;
76 {
77     int i,j;
78 
79     for(i = 0; i < 3; ++i)
80         for(j = 0; j<3; ++j)
81             TFP[(3 * i) + j] = Transforms->ttMatrix[i][j];
82 }
83 
84 void
TLoadCurrent(TFP)85 TLoadCurrent(TFP)
86 long *TFP;
87 {
88     int i,j;
89 
90     for(i = 0; i < 3; ++i)
91         for(j = 0; j < 3; ++j)
92             Transforms->ttMatrix[i][j] = TFP[(3 * i) + j];
93 }
94 
95 void
TTranslate(X,Y)96 TTranslate(X,Y)
97 long X,Y;
98 {
99     Transforms->ttMatrix[2][0] += X;
100     Transforms->ttMatrix[2][1] += Y;
101 }
102 
103 void
TMY()104 TMY()
105 {
106     Transforms->ttMatrix[0][1] = -Transforms->ttMatrix[0][1];
107     Transforms->ttMatrix[1][1] = -Transforms->ttMatrix[1][1];
108     Transforms->ttMatrix[2][1] = -Transforms->ttMatrix[2][1];
109 }
110 
111 void
TMX()112 TMX()
113 {
114     Transforms->ttMatrix[0][0] = -Transforms->ttMatrix[0][0];
115     Transforms->ttMatrix[1][0] = -Transforms->ttMatrix[1][0];
116     Transforms->ttMatrix[2][0] = -Transforms->ttMatrix[2][0];
117 }
118 
119 void
TRotate(XDirection,YDirection)120 TRotate(XDirection,YDirection)
121 long XDirection,YDirection;
122 {
123     /*
124     Rotation angle is expressed as a CIF-style direction vector.
125     */
126     long Int1;
127 
128     if (XDirection == 0){
129         if (Abs(YDirection) > 1)
130             if (YDirection < 0)
131                 YDirection = -1;
132             else
133                 YDirection = 1;
134     }
135     elif (YDirection == 0){
136         if (Abs(XDirection) > 1)
137             if (XDirection < 0)
138                 XDirection = -1;
139             else
140                 XDirection = 1;
141     }
142     if (XDirection == 1 And YDirection == 0)
143         /*
144         Don't rotate at all.
145         */
146         return;
147     elif (XDirection == 0 And YDirection == -1){
148         /*
149         Rotate ccw by 270 degrees.
150         */
151         Int1 = Transforms->ttMatrix[0][0];
152         Transforms->ttMatrix[0][0] = Transforms->ttMatrix[0][1];
153         Transforms->ttMatrix[0][1] = -Int1;
154         Int1 = Transforms->ttMatrix[1][0];
155         Transforms->ttMatrix[1][0] = Transforms->ttMatrix[1][1];
156         Transforms->ttMatrix[1][1] = -Int1;
157         Int1 = Transforms->ttMatrix[2][0];
158         Transforms->ttMatrix[2][0] = Transforms->ttMatrix[2][1];
159         Transforms->ttMatrix[2][1] = -Int1;
160     }
161     elif (XDirection == 0 And YDirection == 1){
162         /*
163         Rotate ccw by 90 degrees.
164         */
165         Int1 = Transforms->ttMatrix[0][0];
166         Transforms->ttMatrix[0][0] = -Transforms->ttMatrix[0][1];
167         Transforms->ttMatrix[0][1] = Int1;
168         Int1 = Transforms->ttMatrix[1][0];
169         Transforms->ttMatrix[1][0] = -Transforms->ttMatrix[1][1];
170         Transforms->ttMatrix[1][1] = Int1;
171         Int1 = Transforms->ttMatrix[2][0];
172         Transforms->ttMatrix[2][0] = -Transforms->ttMatrix[2][1];
173         Transforms->ttMatrix[2][1] = Int1;
174     }
175     elif (XDirection == -1 And YDirection == 0){
176         /*
177         Rotate ccw by 180 degrees.
178         */
179         Transforms->ttMatrix[0][0]    = -Transforms->ttMatrix[0][0];
180         Transforms->ttMatrix[0][1]    = -Transforms->ttMatrix[0][1];
181         Transforms->ttMatrix[1][0]    = -Transforms->ttMatrix[1][0];
182         Transforms->ttMatrix[1][1]    = -Transforms->ttMatrix[1][1];
183         Transforms->ttMatrix[2][0]    = -Transforms->ttMatrix[2][0];
184         Transforms->ttMatrix[2][1]    = -Transforms->ttMatrix[2][1];
185     }
186 }
187 
188 void
TIdentity()189 TIdentity()
190 {
191     long *l;
192 
193     l = (long *)Transforms->ttMatrix;
194     *l++ = 1; *l++ = 0; *l++ = 0;
195     *l++ = 0; *l++ = 1; *l++ = 0;
196     *l++ = 0; *l++ = 0; *l++ = 1;
197 }
198 
199 void
TPoint(X,Y)200 TPoint(X,Y)
201 long *X,*Y;
202 {
203     /*
204     Transform the point.
205     */
206     long Int1;
207 
208     Int1 = *X*Transforms->ttMatrix[0][0] + *Y*Transforms->ttMatrix[1][0] +
209         Transforms->ttMatrix[2][0];
210     *Y = *X*Transforms->ttMatrix[0][1] + *Y*Transforms->ttMatrix[1][1] +
211         Transforms->ttMatrix[2][1];
212     *X = Int1;
213 }
214 
215 void
TPremultiply()216 TPremultiply()
217 {
218     /*
219      * Form the instance transform.
220      * This is done by computing
221      *   Transforms->ttMatrix * Transforms->ttNext->ttMatrix and
222      * placing the product in Transforms.ttMatrix.
223      * So, the scenario for transforming the coordinates of a master follows.
224      * TPush();
225      * TIdentity();
226      * Invoke TMX, Translate, etc. to build instance transform.
227      * Form the instance transform.
228      * TPremultiply();
229      * Invoke TPoint to transform master points to instance points.
230      * TPop();
231      */
232 
233     long Int1,Int2,Int3,Int4,Int5,Int6;
234     int SP;
235     struct tt *Next;
236 
237     Next = Transforms->ttNext;
238 
239     Int1 = Transforms->ttMatrix[0][0]*Next->ttMatrix[0][0] +
240         Transforms->ttMatrix[0][1]*Next->ttMatrix[1][0];
241 
242     Int2 = Transforms->ttMatrix[0][0]*Next->ttMatrix[0][1] +
243         Transforms->ttMatrix[0][1]*Next->ttMatrix[1][1];
244 
245     Int3 = Transforms->ttMatrix[1][0]*Next->ttMatrix[0][0] +
246         Transforms->ttMatrix[1][1]*Next->ttMatrix[1][0];
247 
248     Int4 = Transforms->ttMatrix[1][0]*Next->ttMatrix[0][1] +
249         Transforms->ttMatrix[1][1]*Next->ttMatrix[1][1];
250 
251     Int5 = Transforms->ttMatrix[2][0]*Next->ttMatrix[0][0] +
252         Transforms->ttMatrix[2][1]*Next->ttMatrix[1][0] +
253         Next->ttMatrix[2][0];
254 
255     Int6 = Transforms->ttMatrix[2][0]*Next->ttMatrix[0][1] +
256         Transforms->ttMatrix[2][1]*Next->ttMatrix[1][1] +
257         Next->ttMatrix[2][1];
258 
259     Transforms->ttMatrix[0][0] = Int1;
260     Transforms->ttMatrix[0][1] = Int2;
261     Transforms->ttMatrix[1][0] = Int3;
262     Transforms->ttMatrix[1][1] = Int4;
263     Transforms->ttMatrix[2][0] = Int5;
264     Transforms->ttMatrix[2][1] = Int6;
265 }
266 
267 static long Storage[3][3];
268 static long InverseMatrix[3][3];
269 
270 void
TInverse()271 TInverse()
272 {
273     /*
274     Compute the inverse transform of the current transform.
275     Because all transformations are Manhattan, the
276     det of the current transform matrix is always -1 or +1.
277     */
278 
279     long Det;
280 
281     Det =
282         Transforms->ttMatrix[0][0]*Transforms->ttMatrix[1][1] -
283         Transforms->ttMatrix[1][0]*Transforms->ttMatrix[0][1];
284 
285     if (Det == 1) {
286         InverseMatrix[0][0] = Transforms->ttMatrix[1][1];
287         InverseMatrix[0][1] = -Transforms->ttMatrix[0][1];
288         InverseMatrix[1][0] = -Transforms->ttMatrix[1][0];
289         InverseMatrix[1][1] = Transforms->ttMatrix[0][0];
290         InverseMatrix[2][0] =
291             Transforms->ttMatrix[1][0]*Transforms->ttMatrix[2][1] -
292             Transforms->ttMatrix[2][0]*Transforms->ttMatrix[1][1];
293         InverseMatrix[2][1] =
294             - Transforms->ttMatrix[0][0]*Transforms->ttMatrix[2][1] +
295             Transforms->ttMatrix[0][1]*Transforms->ttMatrix[2][0];
296     }
297     else {
298         InverseMatrix[0][0] = -Transforms->ttMatrix[1][1];
299         InverseMatrix[0][1] = Transforms->ttMatrix[0][1];
300         InverseMatrix[1][0] = Transforms->ttMatrix[1][0];
301         InverseMatrix[1][1] = -Transforms->ttMatrix[0][0];
302         InverseMatrix[2][0] =
303             - Transforms->ttMatrix[1][0]*Transforms->ttMatrix[2][1] +
304             Transforms->ttMatrix[2][0]*Transforms->ttMatrix[1][1];
305         InverseMatrix[2][1] =
306             Transforms->ttMatrix[0][0]*Transforms->ttMatrix[2][1] -
307             Transforms->ttMatrix[0][1]*Transforms->ttMatrix[2][0];
308     }
309     InverseMatrix[0][2] = 0;
310     InverseMatrix[1][2] = 0;
311     InverseMatrix[2][2] = 1;
312 }
313 
314 void
TInversePoint(X,Y)315 TInversePoint(X,Y)
316 long *X,*Y;
317 {
318     /*
319     Transform the point.
320     */
321     long Int1;
322 
323     Int1 = *X*InverseMatrix[0][0] + *Y*InverseMatrix[1][0]
324         + InverseMatrix[2][0];
325     *Y = *X*InverseMatrix[0][1] + *Y*InverseMatrix[1][1]
326         + InverseMatrix[2][1];
327     *X = Int1;
328 }
329 
330 void
TStore()331 TStore()
332 {
333     memcpy((char *)Storage,
334         (char *)Transforms->ttMatrix,9*sizeof(long));
335 }
336 
337 void
TLoad()338 TLoad()
339 {
340     memcpy((char *)Transforms->ttMatrix,
341         (char *)Storage,9*sizeof(long));
342 }
343 
344 void
TLoadInverse()345 TLoadInverse()
346 {
347     memcpy((char *)Transforms->ttMatrix,
348         (char *)InverseMatrix,9*sizeof(long));
349 }
350