pcb 4.1.1
An interactive printed circuit board layout editor.
|
00001 00035 #ifndef PCB_MACRO_H 00036 #define PCB_MACRO_H 00037 00038 /* --------------------------------------------------------------------------- 00039 * macros to transform coord systems 00040 * draw.c uses a different definition of TO_SCREEN 00041 */ 00042 #ifndef SWAP_IDENT 00043 #define SWAP_IDENT Settings.ShowBottomSide 00044 #endif 00045 00046 #define SWAP_SIGN_X(x) (x) 00047 #define SWAP_SIGN_Y(y) (-(y)) 00048 #define SWAP_ANGLE(a) (-(a)) 00049 #define SWAP_DELTA(d) (-(d)) 00050 #define SWAP_X(x) (SWAP_SIGN_X(x)) 00051 #define SWAP_Y(y) (PCB->MaxHeight +SWAP_SIGN_Y(y)) 00052 00053 /* --------------------------------------------------------------------------- 00054 * misc macros, some might already be defined by <limits.h> 00055 */ 00056 #ifndef MIN 00057 #define MIN(a,b) ((a) < (b) ? (a) : (b)) 00058 #define MAX(a,b) ((a) > (b) ? (a) : (b)) 00059 #endif 00060 #ifndef SGN 00061 #define SGN(a) ((a) >0 ? 1 : ((a) == 0 ? 0 : -1)) 00062 #endif 00063 #define SGNZ(a) ((a) >=0 ? 1 : -1) 00064 #define MAKEMIN(a,b) if ((b) < (a)) (a) = (b) 00065 #define MAKEMAX(a,b) if ((b) > (a)) (a) = (b) 00066 00067 #define ENTRIES(x) (sizeof((x))/sizeof((x)[0])) 00068 #define UNKNOWN(a) ((a) && *(a) ? (a) : "(unknown)") 00069 #define UNKNOWN_NAME(a, n) ((a) && *(a) ? (a) : (n)) 00070 #define NSTRCMP(a, b) ((a) ? ((b) ? strcmp((a),(b)) : 1) : -1) 00071 #define EMPTY(a) ((a) ? (a) : "") 00072 #define EMPTY_STRING_P(a) ((a) ? (a)[0]==0 : 1) 00073 #define XOR(a,b) (((a) && !(b)) || (!(a) && (b))) 00074 #define SQUARE(x) ((float) (x) * (float) (x)) 00075 #define TO_RADIANS(degrees) (M180 * (degrees)) 00076 00077 /* Proper rounding for double -> Coord. */ 00078 #define DOUBLE_TO_COORD(x) ((x) >= 0 ? (Coord)((x) + 0.5) : (Coord)((x) - 0.5)) 00079 00080 /* --------------------------------------------------------------------------- 00081 * layer macros 00082 */ 00083 #define LAYER_ON_STACK(n) (&PCB->Data->Layer[LayerStack[(n)]]) 00084 #define LAYER_PTR(n) (&PCB->Data->Layer[(n)]) 00085 #define CURRENT (PCB->SilkActive ? &PCB->Data->Layer[ \ 00086 (Settings.ShowBottomSide ? bottom_silk_layer : top_silk_layer)] \ 00087 : LAYER_ON_STACK(0)) 00088 #define INDEXOFCURRENT (PCB->SilkActive ? \ 00089 (Settings.ShowBottomSide ? bottom_silk_layer : top_silk_layer) \ 00090 : LayerStack[0]) 00091 #define SILKLAYER Layer[ \ 00092 (Settings.ShowBottomSide ? bottom_silk_layer : top_silk_layer)] 00093 #define BACKSILKLAYER Layer[ \ 00094 (Settings.ShowBottomSide ? top_silk_layer : bottom_silk_layer)] 00095 00096 #define TEST_SILK_LAYER(layer) (GetLayerNumber (PCB->Data, layer) >= max_copper_layer) 00097 00098 00099 /* --------------------------------------------------------------------------- 00100 * returns the object ID 00101 */ 00102 #define OBJECT_ID(p) (((AnyObjectType *) p)->ID) 00103 00104 /* --------------------------------------------------------------------------- 00105 * access macro for current buffer 00106 */ 00107 #define PASTEBUFFER (&Buffers[Settings.BufferNumber]) 00108 00109 /* --------------------------------------------------------------------------- 00110 * some routines for flag setting, clearing, changing and testing 00111 */ 00112 #define SET_FLAG(F,P) ((P)->Flags.f |= (F)) 00113 #define CLEAR_FLAG(F,P) ((P)->Flags.f &= (~(F))) 00114 #define TEST_FLAG(F,P) ((P)->Flags.f & (F) ? 1 : 0) 00115 #define TOGGLE_FLAG(F,P) ((P)->Flags.f ^= (F)) 00116 #define ASSIGN_FLAG(F,V,P) ((P)->Flags.f = ((P)->Flags.f & (~(F))) | ((V) ? (F) : 0)) 00117 #define TEST_FLAGS(F,P) (((P)->Flags.f & (F)) == (F) ? 1 : 0) 00118 00119 #define FLAGS_EQUAL(F1,F2) pcb_flag_eq(&(F1), &(F2)) 00120 00121 #define THERMFLAG(L) (0xf << (4 *((L) % 2))) 00122 00123 #define TEST_THERM(L,P) ((P)->Flags.t[(L)/2] & THERMFLAG(L) ? 1 : 0) 00124 #define GET_THERM(L,P) (((P)->Flags.t[(L)/2] >> (4 * ((L) % 2))) & 0xf) 00125 #define CLEAR_THERM(L,P) (P)->Flags.t[(L)/2] &= ~THERMFLAG(L) 00126 #define ASSIGN_THERM(L,V,P) (P)->Flags.t[(L)/2] = ((P)->Flags.t[(L)/2] & ~THERMFLAG(L)) | ((V) << (4 * ((L) % 2))) 00127 00128 extern int mem_any_set (unsigned char *, int); 00129 #define TEST_ANY_THERMS(P) mem_any_set((P)->Flags.t, sizeof((P)->Flags.t)) 00130 00131 /* --------------------------------------------------------------------------- 00132 * access macros for elements name structure 00133 */ 00134 #define DESCRIPTION_INDEX 0 00135 #define NAMEONPCB_INDEX 1 00136 #define VALUE_INDEX 2 00137 #define NAME_INDEX(p) (TEST_FLAG(NAMEONPCBFLAG,(p)) ? NAMEONPCB_INDEX :\ 00138 (TEST_FLAG(DESCRIPTIONFLAG, (p)) ? \ 00139 DESCRIPTION_INDEX : VALUE_INDEX)) 00140 #define ELEMENT_NAME(p,e) ((e)->Name[NAME_INDEX((p))].TextString) 00141 #define DESCRIPTION_NAME(e) ((e)->Name[DESCRIPTION_INDEX].TextString) 00142 #define NAMEONPCB_NAME(e) ((e)->Name[NAMEONPCB_INDEX].TextString) 00143 #define VALUE_NAME(e) ((e)->Name[VALUE_INDEX].TextString) 00144 #define ELEMENT_TEXT(p,e) ((e)->Name[NAME_INDEX((p))]) 00145 #define DESCRIPTION_TEXT(e) ((e)->Name[DESCRIPTION_INDEX]) 00146 #define NAMEONPCB_TEXT(e) ((e)->Name[NAMEONPCB_INDEX]) 00147 #define VALUE_TEXT(e) ((e)->Name[VALUE_INDEX]) 00148 00149 /* --------------------------------------------------------------------------- 00150 * Determines if text is actually visible 00151 */ 00152 #define TEXT_IS_VISIBLE(b, l, t) \ 00153 ((l)->On) 00154 00155 /* --------------------------------------------------------------------------- 00156 * Determines if object is on front or back 00157 */ 00158 #define FRONT(o) \ 00159 ((TEST_FLAG(ONSOLDERFLAG, (o)) != 0) == SWAP_IDENT) 00160 00161 /* --------------------------------------------------------------------------- 00162 * Determines if an object is on the given side. side is either BOTTOM_GROUP 00163 * or TOP_GROUP. 00164 */ 00165 #define ON_SIDE(element, side) \ 00166 (TEST_FLAG (ONSOLDERFLAG, element) == (side == BOTTOM_SIDE)) 00167 00168 /* --------------------------------------------------------------------------- 00169 * some loop shortcuts 00170 * 00171 * a pointer is created from index addressing because the base pointer 00172 * may change when new memory is allocated; 00173 * 00174 * all data is relativ to an objects name 'top' which can be either 00175 * PCB or PasteBuffer 00176 */ 00177 #define END_LOOP }} while (0) 00178 00179 #define STYLE_LOOP(top) do { \ 00180 Cardinal n; \ 00181 RouteStyleType *style; \ 00182 for (n = 0; n < NUM_STYLES; n++) \ 00183 { \ 00184 style = &(top)->RouteStyle[n] 00185 00186 #define VIA_LOOP(top) do { \ 00187 GList *__iter, *__next; \ 00188 Cardinal n = 0; \ 00189 for (__iter = (top)->Via, __next = g_list_next (__iter); \ 00190 __iter != NULL; \ 00191 __iter = __next, __next = g_list_next (__iter), n++) { \ 00192 PinType *via = __iter->data; 00193 00194 #define DRILL_LOOP(top) do { \ 00195 Cardinal n; \ 00196 DrillType *drill; \ 00197 for (n = 0; (top)->DrillN > 0 && n < (top)->DrillN; n++) \ 00198 { \ 00199 drill = &(top)->Drill[n] 00200 00201 #define NETLIST_LOOP(top) do { \ 00202 Cardinal n; \ 00203 NetListType *netlist; \ 00204 for (n = (top)->NetListN-1; n != -1; n--) \ 00205 { \ 00206 netlist = &(top)->NetList[n] 00207 00208 #define NET_LOOP(top) do { \ 00209 Cardinal n; \ 00210 NetType *net; \ 00211 for (n = (top)->NetN-1; n != -1; n--) \ 00212 { \ 00213 net = &(top)->Net[n] 00214 00215 #define CONNECTION_LOOP(net) do { \ 00216 Cardinal n; \ 00217 ConnectionType *connection; \ 00218 for (n = (net)->ConnectionN-1; n != -1; n--) \ 00219 { \ 00220 connection = & (net)->Connection[n] 00221 00222 #define ELEMENT_LOOP(top) do { \ 00223 GList *__iter, *__next; \ 00224 Cardinal n = 0; \ 00225 for (__iter = (top)->Element, __next = g_list_next (__iter); \ 00226 __iter != NULL; \ 00227 __iter = __next, __next = g_list_next (__iter), n++) { \ 00228 ElementType *element = __iter->data; 00229 00230 #define RAT_LOOP(top) do { \ 00231 GList *__iter, *__next; \ 00232 Cardinal n = 0; \ 00233 for (__iter = (top)->Rat, __next = g_list_next (__iter); \ 00234 __iter != NULL; \ 00235 __iter = __next, __next = g_list_next (__iter), n++) { \ 00236 RatType *line = __iter->data; 00237 00238 #define ELEMENTTEXT_LOOP(element) do { \ 00239 Cardinal n; \ 00240 TextType *text; \ 00241 for (n = MAX_ELEMENTNAMES-1; n != -1; n--) \ 00242 { \ 00243 text = &(element)->Name[n] 00244 00245 00246 #define ELEMENTNAME_LOOP(element) do { \ 00247 Cardinal n; \ 00248 char *textstring; \ 00249 for (n = MAX_ELEMENTNAMES-1; n != -1; n--) \ 00250 { \ 00251 textstring = (element)->Name[n].TextString 00252 00253 #define PIN_LOOP(element) do { \ 00254 GList *__iter, *__next; \ 00255 Cardinal n = 0; \ 00256 for (__iter = (element)->Pin, __next = g_list_next (__iter); \ 00257 __iter != NULL; \ 00258 __iter = __next, __next = g_list_next (__iter), n++) { \ 00259 PinType *pin = __iter->data; 00260 00261 #define PAD_LOOP(element) do { \ 00262 GList *__iter, *__next; \ 00263 Cardinal n = 0; \ 00264 for (__iter = (element)->Pad, __next = g_list_next (__iter); \ 00265 __iter != NULL; \ 00266 __iter = __next, __next = g_list_next (__iter), n++) { \ 00267 PadType *pad = __iter->data; 00268 00269 #define ARC_LOOP(element) do { \ 00270 GList *__iter, *__next; \ 00271 Cardinal n = 0; \ 00272 for (__iter = (element)->Arc, __next = g_list_next (__iter); \ 00273 __iter != NULL; \ 00274 __iter = __next, __next = g_list_next (__iter), n++) { \ 00275 ArcType *arc = __iter->data; 00276 00277 #define ELEMENTLINE_LOOP(element) do { \ 00278 GList *__iter, *__next; \ 00279 Cardinal n = 0; \ 00280 for (__iter = (element)->Line, __next = g_list_next (__iter); \ 00281 __iter != NULL; \ 00282 __iter = __next, __next = g_list_next (__iter), n++) { \ 00283 LineType *line = __iter->data; 00284 00285 #define ELEMENTARC_LOOP(element) do { \ 00286 GList *__iter, *__next; \ 00287 Cardinal n = 0; \ 00288 for (__iter = (element)->Arc, __next = g_list_next (__iter); \ 00289 __iter != NULL; \ 00290 __iter = __next, __next = g_list_next (__iter), n++) { \ 00291 ArcType *arc = __iter->data; 00292 00293 #define LINE_LOOP(layer) do { \ 00294 GList *__iter, *__next; \ 00295 Cardinal n = 0; \ 00296 for (__iter = (layer)->Line, __next = g_list_next (__iter); \ 00297 __iter != NULL; \ 00298 __iter = __next, __next = g_list_next (__iter), n++) { \ 00299 LineType *line = __iter->data; 00300 00301 #define TEXT_LOOP(layer) do { \ 00302 GList *__iter, *__next; \ 00303 Cardinal n = 0; \ 00304 for (__iter = (layer)->Text, __next = g_list_next (__iter); \ 00305 __iter != NULL; \ 00306 __iter = __next, __next = g_list_next (__iter), n++) { \ 00307 TextType *text = __iter->data; 00308 00309 #define POLYGON_LOOP(layer) do { \ 00310 GList *__iter, *__next; \ 00311 Cardinal n = 0; \ 00312 for (__iter = (layer)->Polygon, __next = g_list_next (__iter); \ 00313 __iter != NULL; \ 00314 __iter = __next, __next = g_list_next (__iter), n++) { \ 00315 PolygonType *polygon = __iter->data; 00316 00317 #define POLYGONPOINT_LOOP(polygon) do { \ 00318 Cardinal n; \ 00319 PointType *point; \ 00320 for (n = (polygon)->PointN-1; n != -1; n--) \ 00321 { \ 00322 point = &(polygon)->Points[n] 00323 00324 #define ENDALL_LOOP }} while (0); }} while(0) 00325 00326 #define ALLPIN_LOOP(top) \ 00327 ELEMENT_LOOP(top); \ 00328 PIN_LOOP(element)\ 00329 00330 #define ALLPAD_LOOP(top) \ 00331 ELEMENT_LOOP(top); \ 00332 PAD_LOOP(element) 00333 00334 #define ALLLINE_LOOP(top) do { \ 00335 Cardinal l; \ 00336 LayerType *layer = (top)->Layer; \ 00337 for (l = 0; l < max_copper_layer + SILK_LAYER; l++, layer++) \ 00338 { \ 00339 LINE_LOOP(layer) 00340 00341 #define ALLARC_LOOP(top) do { \ 00342 Cardinal l; \ 00343 LayerType *layer = (top)->Layer; \ 00344 for (l =0; l < max_copper_layer + SILK_LAYER; l++, layer++) \ 00345 { \ 00346 ARC_LOOP(layer) 00347 00348 #define ALLPOLYGON_LOOP(top) do { \ 00349 Cardinal l; \ 00350 LayerType *layer = (top)->Layer; \ 00351 for (l = 0; l < max_copper_layer + SILK_LAYER; l++, layer++) \ 00352 { \ 00353 POLYGON_LOOP(layer) 00354 00355 #define COPPERLINE_LOOP(top) do { \ 00356 Cardinal l; \ 00357 LayerType *layer = (top)->Layer; \ 00358 for (l = 0; l < max_copper_layer; l++, layer++) \ 00359 { \ 00360 LINE_LOOP(layer) 00361 00362 #define COPPERARC_LOOP(top) do { \ 00363 Cardinal l; \ 00364 LayerType *layer = (top)->Layer; \ 00365 for (l =0; l < max_copper_layer; l++, layer++) \ 00366 { \ 00367 ARC_LOOP(layer) 00368 00369 #define COPPERPOLYGON_LOOP(top) do { \ 00370 Cardinal l; \ 00371 LayerType *layer = (top)->Layer; \ 00372 for (l = 0; l < max_copper_layer; l++, layer++) \ 00373 { \ 00374 POLYGON_LOOP(layer) 00375 00376 #define SILKLINE_LOOP(top) do { \ 00377 Cardinal l; \ 00378 LayerType *layer = (top)->Layer; \ 00379 layer += max_copper_layer + BOTTOM_SILK_LAYER; \ 00380 for (l = 0; l < 2; l++, layer++) \ 00381 { \ 00382 LINE_LOOP(layer) 00383 00384 #define SILKARC_LOOP(top) do { \ 00385 Cardinal l; \ 00386 LayerType *layer = (top)->Layer; \ 00387 layer += max_copper_layer + BOTTOM_SILK_LAYER; \ 00388 for (l = 0; l < 2; l++, layer++) \ 00389 { \ 00390 ARC_LOOP(layer) 00391 00392 #define SILKPOLYGON_LOOP(top) do { \ 00393 Cardinal l; \ 00394 LayerType *layer = (top)->Layer; \ 00395 layer += max_copper_layer + BOTTOM_SILK_LAYER; \ 00396 for (l = 0; l < 2; l++, layer++) \ 00397 { \ 00398 POLYGON_LOOP(layer) 00399 00400 #define ALLTEXT_LOOP(top) do { \ 00401 Cardinal l; \ 00402 LayerType *layer = (top)->Layer; \ 00403 for (l = 0; l < max_copper_layer + SILK_LAYER; l++, layer++) \ 00404 { \ 00405 TEXT_LOOP(layer) 00406 00407 #define VISIBLELINE_LOOP(top) do { \ 00408 Cardinal l; \ 00409 LayerType *layer = (top)->Layer; \ 00410 for (l = 0; l < max_copper_layer + SILK_LAYER; l++, layer++) \ 00411 { \ 00412 if (layer->On) \ 00413 LINE_LOOP(layer) 00414 00415 #define VISIBLEARC_LOOP(top) do { \ 00416 Cardinal l; \ 00417 LayerType *layer = (top)->Layer; \ 00418 for (l = 0; l < max_copper_layer + SILK_LAYER; l++, layer++) \ 00419 { \ 00420 if (layer->On) \ 00421 ARC_LOOP(layer) 00422 00423 #define VISIBLETEXT_LOOP(board) do { \ 00424 Cardinal l; \ 00425 LayerType *layer = (board)->Data->Layer; \ 00426 for (l = 0; l < max_copper_layer + SILK_LAYER; l++, layer++) \ 00427 { \ 00428 TEXT_LOOP(layer); \ 00429 if (TEXT_IS_VISIBLE((board), layer, text)) 00430 00431 #define VISIBLEPOLYGON_LOOP(top) do { \ 00432 Cardinal l; \ 00433 LayerType *layer = (top)->Layer; \ 00434 for (l = 0; l < max_copper_layer + SILK_LAYER; l++, layer++) \ 00435 { \ 00436 if (layer->On) \ 00437 POLYGON_LOOP(layer) 00438 00439 #define POINTER_LOOP(top) do { \ 00440 Cardinal n; \ 00441 void **ptr; \ 00442 for (n = (top)->PtrN-1; n != -1; n--) \ 00443 { \ 00444 ptr = &(top)->Ptr[n] 00445 00446 #define MENU_LOOP(top) do { \ 00447 Cardinal l; \ 00448 LibraryMenuType *menu; \ 00449 for (l = (top)->MenuN-1; l != -1; l--) \ 00450 { \ 00451 menu = &(top)->Menu[l] 00452 00453 #define ENTRY_LOOP(top) do { \ 00454 Cardinal n; \ 00455 LibraryEntryType *entry; \ 00456 for (n = (top)->EntryN-1; n != -1; n--) \ 00457 { \ 00458 entry = &(top)->Entry[n] 00459 00460 #define GROUP_LOOP(data, group) do { \ 00461 Cardinal entry; \ 00462 for (entry = 0; entry < ((PCBType *)(data->pcb))->LayerGroups.Number[(group)]; entry++) \ 00463 { \ 00464 LayerType *layer; \ 00465 Cardinal number; \ 00466 number = ((PCBType *)(data->pcb))->LayerGroups.Entries[(group)][entry]; \ 00467 if (number >= max_copper_layer) \ 00468 continue; \ 00469 layer = &data->Layer[number]; 00470 00471 #define LAYER_LOOP(data, ml) do { \ 00472 Cardinal n; \ 00473 for (n = 0; n < ml; n++) \ 00474 { \ 00475 LayerType *layer = (&data->Layer[(n)]); 00476 00477 #define LAYER_TYPE_LOOP(data, ml, type) do { \ 00478 Cardinal n; \ 00479 for (n = 0; n < ml; n++) { \ 00480 LayerType *layer = (&data->Layer[(n)]); \ 00481 if (layer->Type != (type)) \ 00482 continue; 00483 00484 #endif 00485 00486 #define VIA_IS_BURIED(via) (via->BuriedFrom != 0 || via->BuriedTo != 0) 00487 #define VIA_ON_LAYER(via, layer) (layer >= via->BuriedFrom && layer <= via->BuriedTo )