AddElementToBuffer(): Let CopyElementLowLevel() create the element to copy into.
[geda-pcb/pcjc2.git] / src / macro.h
blob715f0c9a1ec80f3728c5f9c65117eab0ed2c458a
1 /*
2 * COPYRIGHT
4 * PCB, interactive printed circuit board design
5 * Copyright (C) 1994,1995,1996 Thomas Nau
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * Contact addresses for paper mail and Email:
22 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
23 * Thomas.Nau@rz.uni-ulm.de
27 /* some commonly used macros not related to a special C-file
28 * the file is included by global.h after const.h
31 #ifndef PCB_MACRO_H
32 #define PCB_MACRO_H
34 /* ---------------------------------------------------------------------------
35 * macros to transform coord systems
36 * draw.c uses a different definition of TO_SCREEN
38 #ifndef SWAP_IDENT
39 #define SWAP_IDENT Settings.ShowSolderSide
40 #endif
42 #define SWAP_SIGN_X(x) (x)
43 #define SWAP_SIGN_Y(y) (-(y))
44 #define SWAP_ANGLE(a) (-(a))
45 #define SWAP_DELTA(d) (-(d))
46 #define SWAP_X(x) (SWAP_SIGN_X(x))
47 #define SWAP_Y(y) (PCB->MaxHeight +SWAP_SIGN_Y(y))
49 /* ---------------------------------------------------------------------------
50 * misc macros, some might already be defined by <limits.h>
52 #ifndef MIN
53 #define MIN(a,b) ((a) < (b) ? (a) : (b))
54 #define MAX(a,b) ((a) > (b) ? (a) : (b))
55 #endif
56 #ifndef SGN
57 #define SGN(a) ((a) >0 ? 1 : ((a) == 0 ? 0 : -1))
58 #endif
59 #define SGNZ(a) ((a) >=0 ? 1 : -1)
60 #define MAKEMIN(a,b) if ((b) < (a)) (a) = (b)
61 #define MAKEMAX(a,b) if ((b) > (a)) (a) = (b)
63 #define ENTRIES(x) (sizeof((x))/sizeof((x)[0]))
64 #define UNKNOWN(a) ((a) && *(a) ? (a) : "(unknown)")
65 #define NSTRCMP(a, b) ((a) ? ((b) ? strcmp((a),(b)) : 1) : -1)
66 #define EMPTY(a) ((a) ? (a) : "")
67 #define EMPTY_STRING_P(a) ((a) ? (a)[0]==0 : 1)
68 #define XOR(a,b) (((a) && !(b)) || (!(a) && (b)))
69 #define SQUARE(x) ((float) (x) * (float) (x))
70 #define TO_RADIANS(degrees) (M180 * (degrees))
72 /* ---------------------------------------------------------------------------
73 * layer macros
75 #define LAYER_ON_STACK(n) (&PCB->Data->Layer[LayerStack[(n)]])
76 #define LAYER_PTR(n) (&PCB->Data->Layer[(n)])
77 #define CURRENT (PCB->SilkActive ? &PCB->Data->Layer[ \
78 (Settings.ShowSolderSide ? solder_silk_layer : component_silk_layer)] \
79 : LAYER_ON_STACK(0))
80 #define INDEXOFCURRENT (PCB->SilkActive ? \
81 (Settings.ShowSolderSide ? solder_silk_layer : component_silk_layer) \
82 : LayerStack[0])
83 #define SILKLAYER Layer[ \
84 (Settings.ShowSolderSide ? solder_silk_layer : component_silk_layer)]
85 #define BACKSILKLAYER Layer[ \
86 (Settings.ShowSolderSide ? component_silk_layer : solder_silk_layer)]
88 #define TEST_SILK_LAYER(layer) (GetLayerNumber (PCB->Data, layer) >= max_copper_layer)
91 /* ---------------------------------------------------------------------------
92 * returns the object ID
94 #define OBJECT_ID(p) (((AnyObjectType *) p)->ID)
96 /* ---------------------------------------------------------------------------
97 * access macro for current buffer
99 #define PASTEBUFFER (&Buffers[Settings.BufferNumber])
101 /* ---------------------------------------------------------------------------
102 * some routines for flag setting, clearing, changing and testing
104 #define SET_FLAG(F,P) ((P)->Flags.f |= (F))
105 #define CLEAR_FLAG(F,P) ((P)->Flags.f &= (~(F)))
106 #define TEST_FLAG(F,P) ((P)->Flags.f & (F) ? 1 : 0)
107 #define TOGGLE_FLAG(F,P) ((P)->Flags.f ^= (F))
108 #define ASSIGN_FLAG(F,V,P) ((P)->Flags.f = ((P)->Flags.f & (~(F))) | ((V) ? (F) : 0))
109 #define TEST_FLAGS(F,P) (((P)->Flags.f & (F)) == (F) ? 1 : 0)
111 #define FLAGS_EQUAL(F1,F2) (memcmp (&F1, &F2, sizeof(FlagType)) == 0)
113 #define THERMFLAG(L) (0xf << (4 *((L) % 2)))
115 #define TEST_THERM(L,P) ((P)->Flags.t[(L)/2] & THERMFLAG(L) ? 1 : 0)
116 #define GET_THERM(L,P) (((P)->Flags.t[(L)/2] >> (4 * ((L) % 2))) & 0xf)
117 #define CLEAR_THERM(L,P) (P)->Flags.t[(L)/2] &= ~THERMFLAG(L)
118 #define ASSIGN_THERM(L,V,P) (P)->Flags.t[(L)/2] = ((P)->Flags.t[(L)/2] & ~THERMFLAG(L)) | ((V) << (4 * ((L) % 2)))
120 extern int mem_any_set (unsigned char *, int);
121 #define TEST_ANY_THERMS(P) mem_any_set((P)->Flags.t, sizeof((P)->Flags.t))
123 /* ---------------------------------------------------------------------------
124 * access macros for elements name structure
126 #define DESCRIPTION_INDEX 0
127 #define NAMEONPCB_INDEX 1
128 #define VALUE_INDEX 2
129 #define NAME_INDEX(p) (TEST_FLAG(NAMEONPCBFLAG,(p)) ? NAMEONPCB_INDEX :\
130 (TEST_FLAG(DESCRIPTIONFLAG, (p)) ? \
131 DESCRIPTION_INDEX : VALUE_INDEX))
132 #define ELEMENT_NAME(p,e) ((e)->Name[NAME_INDEX((p))].TextString)
133 #define DESCRIPTION_NAME(e) ((e)->Name[DESCRIPTION_INDEX].TextString)
134 #define NAMEONPCB_NAME(e) ((e)->Name[NAMEONPCB_INDEX].TextString)
135 #define VALUE_NAME(e) ((e)->Name[VALUE_INDEX].TextString)
136 #define ELEMENT_TEXT(p,e) ((e)->Name[NAME_INDEX((p))])
137 #define DESCRIPTION_TEXT(e) ((e)->Name[DESCRIPTION_INDEX])
138 #define NAMEONPCB_TEXT(e) ((e)->Name[NAMEONPCB_INDEX])
139 #define VALUE_TEXT(e) ((e)->Name[VALUE_INDEX])
141 /* ---------------------------------------------------------------------------
142 * Determines if text is actually visible
144 #define TEXT_IS_VISIBLE(b, l, t) \
145 ((l)->On)
147 /* ---------------------------------------------------------------------------
148 * Determines if object is on front or back
150 #define FRONT(o) \
151 ((TEST_FLAG(ONSOLDERFLAG, (o)) != 0) == SWAP_IDENT)
153 /* ---------------------------------------------------------------------------
154 * Determines if an object is on the given side. side is either SOLDER_LAYER
155 * or COMPONENT_LAYER.
157 #define ON_SIDE(element, side) \
158 (TEST_FLAG (ONSOLDERFLAG, element) == (side == SOLDER_LAYER))
160 /* ---------------------------------------------------------------------------
161 * some loop shortcuts
163 * a pointer is created from index addressing because the base pointer
164 * may change when new memory is allocated;
166 * all data is relativ to an objects name 'top' which can be either
167 * PCB or PasteBuffer
169 #define END_LOOP }} while (0)
171 #define STYLE_LOOP(top) do { \
172 Cardinal n; \
173 RouteStyleType *style; \
174 for (n = 0; n < NUM_STYLES; n++) \
176 style = &(top)->RouteStyle[n]
178 #define VIA_LOOP(top) do { \
179 GList *__iter, *__next; \
180 Cardinal n = 0; \
181 for (__iter = (top)->Via, __next = g_list_next (__iter); \
182 __iter != NULL; \
183 __iter = __next, __next = g_list_next (__iter), n++) { \
184 PinType *via = __iter->data;
186 #define DRILL_LOOP(top) do { \
187 Cardinal n; \
188 DrillType *drill; \
189 for (n = 0; (top)->DrillN > 0 && n < (top)->DrillN; n++) \
191 drill = &(top)->Drill[n]
193 #define NETLIST_LOOP(top) do { \
194 Cardinal n; \
195 NetListType *netlist; \
196 for (n = (top)->NetListN-1; n != -1; n--) \
198 netlist = &(top)->NetList[n]
200 #define NET_LOOP(top) do { \
201 Cardinal n; \
202 NetType *net; \
203 for (n = (top)->NetN-1; n != -1; n--) \
205 net = &(top)->Net[n]
207 #define CONNECTION_LOOP(net) do { \
208 Cardinal n; \
209 ConnectionType *connection; \
210 for (n = (net)->ConnectionN-1; n != -1; n--) \
212 connection = & (net)->Connection[n]
214 #define ELEMENT_LOOP(top) do { \
215 GList *__iter, *__next; \
216 Cardinal n = 0; \
217 for (__iter = (top)->Element, __next = g_list_next (__iter); \
218 __iter != NULL; \
219 __iter = __next, __next = g_list_next (__iter), n++) { \
220 ElementType *element = __iter->data;
222 #define RAT_LOOP(top) do { \
223 GList *__iter, *__next; \
224 Cardinal n = 0; \
225 for (__iter = (top)->Rat, __next = g_list_next (__iter); \
226 __iter != NULL; \
227 __iter = __next, __next = g_list_next (__iter), n++) { \
228 RatType *line = __iter->data;
230 #define ELEMENTTEXT_LOOP(element) do { \
231 Cardinal n; \
232 TextType *text; \
233 for (n = MAX_ELEMENTNAMES-1; n != -1; n--) \
235 text = &(element)->Name[n]
238 #define ELEMENTNAME_LOOP(element) do { \
239 Cardinal n; \
240 char *textstring; \
241 for (n = MAX_ELEMENTNAMES-1; n != -1; n--) \
243 textstring = (element)->Name[n].TextString
245 #define PIN_LOOP(element) do { \
246 GList *__iter, *__next; \
247 Cardinal n = 0; \
248 for (__iter = (element)->Pin, __next = g_list_next (__iter); \
249 __iter != NULL; \
250 __iter = __next, __next = g_list_next (__iter), n++) { \
251 PinType *pin = __iter->data;
253 #define PAD_LOOP(element) do { \
254 GList *__iter, *__next; \
255 Cardinal n = 0; \
256 for (__iter = (element)->Pad, __next = g_list_next (__iter); \
257 __iter != NULL; \
258 __iter = __next, __next = g_list_next (__iter), n++) { \
259 PadType *pad = __iter->data;
261 #define ARC_LOOP(element) do { \
262 GList *__iter, *__next; \
263 Cardinal n = 0; \
264 for (__iter = (element)->Arc, __next = g_list_next (__iter); \
265 __iter != NULL; \
266 __iter = __next, __next = g_list_next (__iter), n++) { \
267 ArcType *arc = __iter->data;
269 #define ELEMENTLINE_LOOP(element) do { \
270 GList *__iter, *__next; \
271 Cardinal n = 0; \
272 for (__iter = (element)->Line, __next = g_list_next (__iter); \
273 __iter != NULL; \
274 __iter = __next, __next = g_list_next (__iter), n++) { \
275 LineType *line = __iter->data;
277 #define ELEMENTARC_LOOP(element) do { \
278 GList *__iter, *__next; \
279 Cardinal n = 0; \
280 for (__iter = (element)->Arc, __next = g_list_next (__iter); \
281 __iter != NULL; \
282 __iter = __next, __next = g_list_next (__iter), n++) { \
283 ArcType *arc = __iter->data;
285 #define LINE_LOOP(layer) do { \
286 GList *__iter, *__next; \
287 Cardinal n = 0; \
288 for (__iter = (layer)->Line, __next = g_list_next (__iter); \
289 __iter != NULL; \
290 __iter = __next, __next = g_list_next (__iter), n++) { \
291 LineType *line = __iter->data;
293 #define TEXT_LOOP(layer) do { \
294 GList *__iter, *__next; \
295 Cardinal n = 0; \
296 for (__iter = (layer)->Text, __next = g_list_next (__iter); \
297 __iter != NULL; \
298 __iter = __next, __next = g_list_next (__iter), n++) { \
299 TextType *text = __iter->data;
301 #define POLYGON_LOOP(layer) do { \
302 GList *__iter, *__next; \
303 Cardinal n = 0; \
304 for (__iter = (layer)->Polygon, __next = g_list_next (__iter); \
305 __iter != NULL; \
306 __iter = __next, __next = g_list_next (__iter), n++) { \
307 PolygonType *polygon = __iter->data;
309 #define POLYGONPOINT_LOOP(polygon) do { \
310 Cardinal n; \
311 PointType *point; \
312 for (n = (polygon)->PointN-1; n != -1; n--) \
314 point = &(polygon)->Points[n]
316 #define ENDALL_LOOP }} while (0); }} while(0)
318 #define ALLPIN_LOOP(top) \
319 ELEMENT_LOOP(top); \
320 PIN_LOOP(element)\
322 #define ALLPAD_LOOP(top) \
323 ELEMENT_LOOP(top); \
324 PAD_LOOP(element)
326 #define ALLLINE_LOOP(top) do { \
327 Cardinal l; \
328 LayerType *layer = (top)->Layer; \
329 for (l = 0; l < max_copper_layer + 2; l++, layer++) \
331 LINE_LOOP(layer)
333 #define ALLARC_LOOP(top) do { \
334 Cardinal l; \
335 LayerType *layer = (top)->Layer; \
336 for (l =0; l < max_copper_layer + 2; l++, layer++) \
338 ARC_LOOP(layer)
340 #define ALLPOLYGON_LOOP(top) do { \
341 Cardinal l; \
342 LayerType *layer = (top)->Layer; \
343 for (l = 0; l < max_copper_layer + 2; l++, layer++) \
345 POLYGON_LOOP(layer)
347 #define COPPERLINE_LOOP(top) do { \
348 Cardinal l; \
349 LayerType *layer = (top)->Layer; \
350 for (l = 0; l < max_copper_layer; l++, layer++) \
352 LINE_LOOP(layer)
354 #define COPPERARC_LOOP(top) do { \
355 Cardinal l; \
356 LayerType *layer = (top)->Layer; \
357 for (l =0; l < max_copper_layer; l++, layer++) \
359 ARC_LOOP(layer)
361 #define COPPERPOLYGON_LOOP(top) do { \
362 Cardinal l; \
363 LayerType *layer = (top)->Layer; \
364 for (l = 0; l < max_copper_layer; l++, layer++) \
366 POLYGON_LOOP(layer)
368 #define SILKLINE_LOOP(top) do { \
369 Cardinal l; \
370 LayerType *layer = (top)->Layer; \
371 layer += max_copper_layer; \
372 for (l = 0; l < 2; l++, layer++) \
374 LINE_LOOP(layer)
376 #define SILKARC_LOOP(top) do { \
377 Cardinal l; \
378 LayerType *layer = (top)->Layer; \
379 layer += max_copper_layer; \
380 for (l = 0; l < 2; l++, layer++) \
382 ARC_LOOP(layer)
384 #define SILKPOLYGON_LOOP(top) do { \
385 Cardinal l; \
386 LayerType *layer = (top)->Layer; \
387 layer += max_copper_layer; \
388 for (l = 0; l < 2; l++, layer++) \
390 POLYGON_LOOP(layer)
392 #define ALLTEXT_LOOP(top) do { \
393 Cardinal l; \
394 LayerType *layer = (top)->Layer; \
395 for (l = 0; l < max_copper_layer + 2; l++, layer++) \
397 TEXT_LOOP(layer)
399 #define VISIBLELINE_LOOP(top) do { \
400 Cardinal l; \
401 LayerType *layer = (top)->Layer; \
402 for (l = 0; l < max_copper_layer + 2; l++, layer++) \
404 if (layer->On) \
405 LINE_LOOP(layer)
407 #define VISIBLEARC_LOOP(top) do { \
408 Cardinal l; \
409 LayerType *layer = (top)->Layer; \
410 for (l = 0; l < max_copper_layer + 2; l++, layer++) \
412 if (layer->On) \
413 ARC_LOOP(layer)
415 #define VISIBLETEXT_LOOP(board) do { \
416 Cardinal l; \
417 LayerType *layer = (board)->Data->Layer; \
418 for (l = 0; l < max_copper_layer + 2; l++, layer++) \
420 TEXT_LOOP(layer); \
421 if (TEXT_IS_VISIBLE((board), layer, text))
423 #define VISIBLEPOLYGON_LOOP(top) do { \
424 Cardinal l; \
425 LayerType *layer = (top)->Layer; \
426 for (l = 0; l < max_copper_layer + 2; l++, layer++) \
428 if (layer->On) \
429 POLYGON_LOOP(layer)
431 #define POINTER_LOOP(top) do { \
432 Cardinal n; \
433 void **ptr; \
434 for (n = (top)->PtrN-1; n != -1; n--) \
436 ptr = &(top)->Ptr[n]
438 #define MENU_LOOP(top) do { \
439 Cardinal l; \
440 LibraryMenuType *menu; \
441 for (l = (top)->MenuN-1; l != -1; l--) \
443 menu = &(top)->Menu[l]
445 #define ENTRY_LOOP(top) do { \
446 Cardinal n; \
447 LibraryEntryType *entry; \
448 for (n = (top)->EntryN-1; n != -1; n--) \
450 entry = &(top)->Entry[n]
452 #define GROUP_LOOP(data, group) do { \
453 Cardinal entry; \
454 for (entry = 0; entry < ((PCBType *)(data->pcb))->LayerGroups.Number[(group)]; entry++) \
456 LayerType *layer; \
457 Cardinal number; \
458 number = ((PCBType *)(data->pcb))->LayerGroups.Entries[(group)][entry]; \
459 if (number >= max_copper_layer) \
460 continue; \
461 layer = &data->Layer[number];
463 #define LAYER_LOOP(data, ml) do { \
464 Cardinal n; \
465 for (n = 0; n < ml; n++) \
467 LayerType *layer = (&data->Layer[(n)]);
470 #endif