pcb 4.1.1
An interactive printed circuit board layout editor.

macro.h

Go to the documentation of this file.
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 )