pcb 4.1.1
An interactive printed circuit board layout editor.
|
00001 00038 #ifdef HAVE_CONFIG_H 00039 #include "config.h" 00040 #endif 00041 00042 #include <math.h> 00043 #include <setjmp.h> 00044 00045 #include "global.h" 00046 00047 #include "box.h" 00048 #include "data.h" 00049 #include "draw.h" 00050 #include "error.h" 00051 #include "find.h" 00052 #include "misc.h" 00053 #include "polygon.h" 00054 #include "rtree.h" 00055 #include "search.h" 00056 00057 #ifdef HAVE_LIBDMALLOC 00058 #include <dmalloc.h> 00059 #endif 00060 00061 /* --------------------------------------------------------------------------- 00062 * some local identifiers 00063 */ 00064 static double PosX, PosY; /* search position for subroutines */ 00065 static Coord SearchRadius; 00066 static BoxType SearchBox; 00067 static LayerType *SearchLayer; 00068 00069 /* --------------------------------------------------------------------------- 00070 * some local prototypes. The first parameter includes LOCKED_TYPE if we 00071 * want to include locked types in the search. 00072 */ 00073 static bool SearchLineByLocation (int, LayerType **, LineType **, 00074 LineType **); 00075 static bool SearchArcByLocation (int, LayerType **, ArcType **, 00076 ArcType **); 00077 static bool SearchRatLineByLocation (int, RatType **, RatType **, 00078 RatType **); 00079 static bool SearchTextByLocation (int, LayerType **, TextType **, 00080 TextType **); 00081 static bool SearchPolygonByLocation (int, LayerType **, PolygonType **, 00082 PolygonType **); 00083 static bool SearchPinByLocation (int, ElementType **, PinType **, 00084 PinType **); 00085 static bool SearchPadByLocation (int, ElementType **, PadType **, 00086 PadType **, bool); 00087 static bool SearchViaByLocation (int, PinType **, PinType **, 00088 PinType **); 00089 static bool SearchElementNameByLocation (int, ElementType **, 00090 TextType **, TextType **, 00091 bool); 00092 static bool SearchLinePointByLocation (int, LayerType **, LineType **, 00093 PointType **); 00094 static bool SearchPointByLocation (int, LayerType **, PolygonType **, 00095 PointType **); 00096 static bool SearchElementByLocation (int, ElementType **, 00097 ElementType **, ElementType **, 00098 bool); 00099 00100 struct ans_info 00101 { 00102 void **ptr1, **ptr2, **ptr3; 00103 bool BackToo; 00104 double area; 00105 jmp_buf env; 00106 int locked; 00107 bool found_anything; 00108 double nearest_sq_dist; 00109 }; 00110 00111 static int 00112 pinorvia_callback (const BoxType * box, void *cl) 00113 { 00114 struct ans_info *i = (struct ans_info *) cl; 00115 PinType *pin = (PinType *) box; 00116 AnyObjectType *ptr1 = pin->Element ? pin->Element : pin; 00117 00118 if (TEST_FLAG (i->locked, ptr1)) 00119 return 0; 00120 00121 if (!IsPointOnPin (PosX, PosY, SearchRadius, pin)) 00122 return 0; 00123 *i->ptr1 = ptr1; 00124 *i->ptr2 = *i->ptr3 = pin; 00125 longjmp (i->env, 1); 00126 return 1; /* never reached */ 00127 } 00128 00132 static bool 00133 SearchViaByLocation (int locked, PinType ** Via, PinType ** Dummy1, 00134 PinType ** Dummy2) 00135 { 00136 struct ans_info info; 00137 00138 /* search only if via-layer is visible */ 00139 if (!PCB->ViaOn) 00140 return false; 00141 00142 info.ptr1 = (void **) Via; 00143 info.ptr2 = (void **) Dummy1; 00144 info.ptr3 = (void **) Dummy2; 00145 info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG; 00146 00147 if (setjmp (info.env) == 0) 00148 { 00149 r_search (PCB->Data->via_tree, &SearchBox, NULL, pinorvia_callback, 00150 &info); 00151 return false; 00152 } 00153 return true; 00154 } 00155 00161 static bool 00162 SearchPinByLocation (int locked, ElementType ** Element, PinType ** Pin, 00163 PinType ** Dummy) 00164 { 00165 struct ans_info info; 00166 00167 /* search only if pin-layer is visible */ 00168 if (!PCB->PinOn) 00169 return false; 00170 info.ptr1 = (void **) Element; 00171 info.ptr2 = (void **) Pin; 00172 info.ptr3 = (void **) Dummy; 00173 info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG; 00174 00175 if (setjmp (info.env) == 0) 00176 r_search (PCB->Data->pin_tree, &SearchBox, NULL, pinorvia_callback, 00177 &info); 00178 else 00179 return true; 00180 return false; 00181 } 00182 00183 static int 00184 pad_callback (const BoxType * b, void *cl) 00185 { 00186 PadType *pad = (PadType *) b; 00187 struct ans_info *i = (struct ans_info *) cl; 00188 AnyObjectType *ptr1 = pad->Element; 00189 double sq_dist; 00190 00191 /* Reject locked pads, backside pads (if !BackToo), and non-hit pads */ 00192 if (TEST_FLAG (i->locked, ptr1) || 00193 (!FRONT (pad) && !i->BackToo) || 00194 !IsPointInPad (PosX, PosY, SearchRadius, pad)) 00195 return 0; 00196 00197 /* Determine how close our test-position was to the center of the pad */ 00198 sq_dist = (PosX - (pad->Point1.X + (pad->Point2.X - pad->Point1.X) / 2)) * 00199 (PosX - (pad->Point1.X + (pad->Point2.X - pad->Point1.X) / 2)) + 00200 (PosY - (pad->Point1.Y + (pad->Point2.Y - pad->Point1.Y) / 2)) * 00201 (PosY - (pad->Point1.Y + (pad->Point2.Y - pad->Point1.Y) / 2)); 00202 00203 /* If this was the closest hit so far, record it */ 00204 if (!i->found_anything || sq_dist < i->nearest_sq_dist) 00205 { 00206 *i->ptr1 = ptr1; 00207 *i->ptr2 = *i->ptr3 = pad; 00208 i->found_anything = true; 00209 i->nearest_sq_dist = sq_dist; 00210 } 00211 return 0; 00212 } 00213 00219 static bool 00220 SearchPadByLocation (int locked, ElementType ** Element, PadType ** Pad, 00221 PadType ** Dummy, bool BackToo) 00222 { 00223 struct ans_info info; 00224 00225 /* search only if pin-layer is visible */ 00226 if (!PCB->PinOn) 00227 return (false); 00228 info.ptr1 = (void **) Element; 00229 info.ptr2 = (void **) Pad; 00230 info.ptr3 = (void **) Dummy; 00231 info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG; 00232 info.BackToo = (BackToo && PCB->InvisibleObjectsOn); 00233 info.found_anything = false; 00234 r_search (PCB->Data->pad_tree, &SearchBox, NULL, pad_callback, &info); 00235 return info.found_anything; 00236 } 00237 00238 struct line_info 00239 { 00240 LineType **Line; 00241 PointType **Point; 00242 double least; 00243 jmp_buf env; 00244 int locked; 00245 }; 00246 00247 static int 00248 line_callback (const BoxType * box, void *cl) 00249 { 00250 struct line_info *i = (struct line_info *) cl; 00251 LineType *l = (LineType *) box; 00252 00253 if (TEST_FLAG (i->locked, l)) 00254 return 0; 00255 00256 if (!IsPointInPad (PosX, PosY, SearchRadius, (PadType *)l)) 00257 return 0; 00258 *i->Line = l; 00259 *i->Point = (PointType *) l; 00260 longjmp (i->env, 1); 00261 return 1; /* never reached */ 00262 } 00263 00264 00268 static bool 00269 SearchLineByLocation (int locked, LayerType ** Layer, LineType ** Line, 00270 LineType ** Dummy) 00271 { 00272 struct line_info info; 00273 00274 info.Line = Line; 00275 info.Point = (PointType **) Dummy; 00276 info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG; 00277 00278 *Layer = SearchLayer; 00279 if (setjmp (info.env) == 0) 00280 { 00281 r_search (SearchLayer->line_tree, &SearchBox, NULL, line_callback, 00282 &info); 00283 return false; 00284 } 00285 return (true); 00286 } 00287 00288 static int 00289 rat_callback (const BoxType * box, void *cl) 00290 { 00291 LineType *line = (LineType *) box; 00292 struct ans_info *i = (struct ans_info *) cl; 00293 00294 if (TEST_FLAG (i->locked, line)) 00295 return 0; 00296 00297 if (TEST_FLAG (VIAFLAG, line) ? 00298 (Distance (line->Point1.X, line->Point1.Y, PosX, PosY) <= 00299 line->Thickness * 2 + SearchRadius) : 00300 IsPointOnLine (PosX, PosY, SearchRadius, line)) 00301 { 00302 *i->ptr1 = *i->ptr2 = *i->ptr3 = line; 00303 longjmp (i->env, 1); 00304 } 00305 return 0; 00306 } 00307 00311 static bool 00312 SearchRatLineByLocation (int locked, RatType ** Line, RatType ** Dummy1, 00313 RatType ** Dummy2) 00314 { 00315 struct ans_info info; 00316 00317 info.ptr1 = (void **) Line; 00318 info.ptr2 = (void **) Dummy1; 00319 info.ptr3 = (void **) Dummy2; 00320 info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG; 00321 00322 if (setjmp (info.env) == 0) 00323 { 00324 r_search (PCB->Data->rat_tree, &SearchBox, NULL, rat_callback, &info); 00325 return false; 00326 } 00327 return (true); 00328 } 00329 00330 struct arc_info 00331 { 00332 ArcType **Arc, **Dummy; 00333 PointType **Point; 00334 double least; 00335 jmp_buf env; 00336 int locked; 00337 }; 00338 00339 static int 00340 arc_callback (const BoxType * box, void *cl) 00341 { 00342 struct arc_info *i = (struct arc_info *) cl; 00343 ArcType *a = (ArcType *) box; 00344 00345 if (TEST_FLAG (i->locked, a)) 00346 return 0; 00347 00348 if (!IsPointOnArc (PosX, PosY, SearchRadius, a)) 00349 return 0; 00350 *i->Arc = a; 00351 *i->Dummy = a; 00352 longjmp (i->env, 1); 00353 return 1; /* never reached */ 00354 } 00355 00356 00360 static bool 00361 SearchArcByLocation (int locked, LayerType ** Layer, ArcType ** Arc, 00362 ArcType ** Dummy) 00363 { 00364 struct arc_info info; 00365 00366 info.Arc = Arc; 00367 info.Dummy = Dummy; 00368 info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG; 00369 00370 *Layer = SearchLayer; 00371 if (setjmp (info.env) == 0) 00372 { 00373 r_search (SearchLayer->arc_tree, &SearchBox, NULL, arc_callback, &info); 00374 return false; 00375 } 00376 return (true); 00377 } 00378 00379 static int 00380 text_callback (const BoxType * box, void *cl) 00381 { 00382 TextType *text = (TextType *) box; 00383 struct ans_info *i = (struct ans_info *) cl; 00384 00385 if (TEST_FLAG (i->locked, text)) 00386 return 0; 00387 00388 if (POINT_IN_BOX (PosX, PosY, &text->BoundingBox)) 00389 { 00390 *i->ptr2 = *i->ptr3 = text; 00391 longjmp (i->env, 1); 00392 } 00393 return 0; 00394 } 00395 00399 static bool 00400 SearchTextByLocation (int locked, LayerType ** Layer, TextType ** Text, 00401 TextType ** Dummy) 00402 { 00403 struct ans_info info; 00404 00405 *Layer = SearchLayer; 00406 info.ptr2 = (void **) Text; 00407 info.ptr3 = (void **) Dummy; 00408 info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG; 00409 00410 if (setjmp (info.env) == 0) 00411 { 00412 r_search (SearchLayer->text_tree, &SearchBox, NULL, text_callback, 00413 &info); 00414 return false; 00415 } 00416 return (true); 00417 } 00418 00419 static int 00420 polygon_callback (const BoxType * box, void *cl) 00421 { 00422 PolygonType *polygon = (PolygonType *) box; 00423 struct ans_info *i = (struct ans_info *) cl; 00424 00425 if (TEST_FLAG (i->locked, polygon)) 00426 return 0; 00427 00428 if (IsPointInPolygon (PosX, PosY, SearchRadius, polygon)) 00429 { 00430 *i->ptr2 = *i->ptr3 = polygon; 00431 longjmp (i->env, 1); 00432 } 00433 return 0; 00434 } 00435 00436 00440 static bool 00441 SearchPolygonByLocation (int locked, LayerType ** Layer, 00442 PolygonType ** Polygon, PolygonType ** Dummy) 00443 { 00444 struct ans_info info; 00445 00446 *Layer = SearchLayer; 00447 info.ptr2 = (void **) Polygon; 00448 info.ptr3 = (void **) Dummy; 00449 info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG; 00450 00451 if (setjmp (info.env) == 0) 00452 { 00453 r_search (SearchLayer->polygon_tree, &SearchBox, NULL, polygon_callback, 00454 &info); 00455 return false; 00456 } 00457 return (true); 00458 } 00459 00460 static int 00461 linepoint_callback (const BoxType * b, void *cl) 00462 { 00463 LineType *line = (LineType *) b; 00464 struct line_info *i = (struct line_info *) cl; 00465 int ret_val = 0; 00466 double d; 00467 00468 if (TEST_FLAG (i->locked, line)) 00469 return 0; 00470 00471 /* some stupid code to check both points */ 00472 d = Distance (PosX, PosY, line->Point1.X, line->Point1.Y); 00473 if (d < i->least) 00474 { 00475 i->least = d; 00476 *i->Line = line; 00477 *i->Point = &line->Point1; 00478 ret_val = 1; 00479 } 00480 00481 d = Distance (PosX, PosY, line->Point2.X, line->Point2.Y); 00482 if (d < i->least) 00483 { 00484 i->least = d; 00485 *i->Line = line; 00486 *i->Point = &line->Point2; 00487 ret_val = 1; 00488 } 00489 return ret_val; 00490 } 00491 00495 static bool 00496 SearchLinePointByLocation (int locked, LayerType ** Layer, 00497 LineType ** Line, PointType ** Point) 00498 { 00499 struct line_info info; 00500 *Layer = SearchLayer; 00501 info.Line = Line; 00502 info.Point = Point; 00503 *Point = NULL; 00504 info.least = MAX_LINE_POINT_DISTANCE + SearchRadius; 00505 info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG; 00506 if (r_search 00507 (SearchLayer->line_tree, &SearchBox, NULL, linepoint_callback, &info)) 00508 return true; 00509 return false; 00510 } 00511 00512 static int 00513 arcpoint_callback (const BoxType * b, void *cl) 00514 { 00515 ArcType *arc = (ArcType *) b; 00516 struct arc_info *i = (struct arc_info *) cl; 00517 int ret_val = 0; 00518 double d; 00519 00520 if (TEST_FLAG (i->locked, arc)) 00521 return 0; 00522 00523 d = Distance (PosX, PosY, arc->Point1.X, arc->Point1.Y); 00524 if (d < i->least) 00525 { 00526 i->least = d; 00527 *i->Arc = arc; 00528 *i->Point = &arc->Point1; 00529 ret_val = 1; 00530 } 00531 00532 d = Distance (PosX, PosY, arc->Point2.X, arc->Point2.Y); 00533 if (d < i->least) 00534 { 00535 i->least = d; 00536 *i->Arc = arc; 00537 *i->Point = &arc->Point2; 00538 ret_val = 1; 00539 } 00540 return ret_val; 00541 } 00542 00546 static bool 00547 SearchArcPointByLocation (int locked, LayerType **Layer, 00548 ArcType **arc, PointType **Point) 00549 { 00550 struct arc_info info; 00551 *Layer = SearchLayer; 00552 info.Arc = arc; 00553 info.Point = Point; 00554 *Point = NULL; 00555 info.least = MAX_ARC_POINT_DISTANCE + SearchRadius; 00556 info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG; 00557 if (r_search 00558 (SearchLayer->arc_tree, &SearchBox, NULL, arcpoint_callback, &info)) 00559 return true; 00560 return false; 00561 } 00566 static bool 00567 SearchPointByLocation (int locked, LayerType ** Layer, 00568 PolygonType ** Polygon, PointType ** Point) 00569 { 00570 double d, least; 00571 bool found = false; 00572 00573 least = SearchRadius + MAX_POLYGON_POINT_DISTANCE; 00574 *Layer = SearchLayer; 00575 POLYGON_LOOP (*Layer); 00576 { 00577 POLYGONPOINT_LOOP (polygon); 00578 { 00579 d = Distance (point->X, point->Y, PosX, PosY); 00580 if (d < least) 00581 { 00582 least = d; 00583 *Polygon = polygon; 00584 *Point = point; 00585 found = true; 00586 } 00587 } 00588 END_LOOP; 00589 } 00590 END_LOOP; 00591 if (found) 00592 return (true); 00593 return (false); 00594 } 00595 00596 static int 00597 name_callback (const BoxType * box, void *cl) 00598 { 00599 TextType *text = (TextType *) box; 00600 struct ans_info *i = (struct ans_info *) cl; 00601 ElementType *element = (ElementType *) text->Element; 00602 double newarea; 00603 00604 if (TEST_FLAG (i->locked, text)) 00605 return 0; 00606 00607 if ((FRONT (element) || i->BackToo) && !TEST_FLAG (HIDENAMEFLAG, element) && 00608 POINT_IN_BOX (PosX, PosY, &text->BoundingBox)) 00609 { 00610 /* use the text with the smallest bounding box */ 00611 newarea = (text->BoundingBox.X2 - text->BoundingBox.X1) * 00612 (double) (text->BoundingBox.Y2 - text->BoundingBox.Y1); 00613 if (newarea < i->area) 00614 { 00615 i->area = newarea; 00616 *i->ptr1 = element; 00617 *i->ptr2 = *i->ptr3 = text; 00618 } 00619 return 1; 00620 } 00621 return 0; 00622 } 00623 00630 static bool 00631 SearchElementNameByLocation (int locked, ElementType ** Element, 00632 TextType ** Text, TextType ** Dummy, 00633 bool BackToo) 00634 { 00635 struct ans_info info; 00636 00637 /* package layer have to be switched on */ 00638 if (PCB->ElementOn) 00639 { 00640 info.ptr1 = (void **) Element; 00641 info.ptr2 = (void **) Text; 00642 info.ptr3 = (void **) Dummy; 00643 info.area = SQUARE (MAX_COORD); 00644 info.BackToo = (BackToo && PCB->InvisibleObjectsOn); 00645 info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG; 00646 if (r_search (PCB->Data->name_tree[NAME_INDEX (PCB)], &SearchBox, NULL, 00647 name_callback, &info)) 00648 return true; 00649 } 00650 return (false); 00651 } 00652 00653 static int 00654 element_callback (const BoxType * box, void *cl) 00655 { 00656 ElementType *element = (ElementType *) box; 00657 struct ans_info *i = (struct ans_info *) cl; 00658 double newarea; 00659 00660 if (TEST_FLAG (i->locked, element)) 00661 return 0; 00662 00663 if ((FRONT (element) || i->BackToo) && 00664 POINT_IN_BOX (PosX, PosY, &element->VBox)) 00665 { 00666 /* use the element with the smallest bounding box */ 00667 newarea = (element->VBox.X2 - element->VBox.X1) * 00668 (double) (element->VBox.Y2 - element->VBox.Y1); 00669 if (newarea < i->area) 00670 { 00671 i->area = newarea; 00672 *i->ptr1 = *i->ptr2 = *i->ptr3 = element; 00673 return 1; 00674 } 00675 } 00676 return 0; 00677 } 00678 00687 static bool 00688 SearchElementByLocation (int locked, 00689 ElementType ** Element, 00690 ElementType ** Dummy1, ElementType ** Dummy2, 00691 bool BackToo) 00692 { 00693 struct ans_info info; 00694 00695 /* Both package layers have to be switched on */ 00696 if (PCB->ElementOn && PCB->PinOn) 00697 { 00698 info.ptr1 = (void **) Element; 00699 info.ptr2 = (void **) Dummy1; 00700 info.ptr3 = (void **) Dummy2; 00701 info.area = SQUARE (MAX_COORD); 00702 info.BackToo = (BackToo && PCB->InvisibleObjectsOn); 00703 info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG; 00704 if (r_search 00705 (PCB->Data->element_tree, &SearchBox, NULL, element_callback, 00706 &info)) 00707 return true; 00708 } 00709 return false; 00710 } 00711 00715 bool 00716 IsPointOnPin (Coord X, Coord Y, Coord Radius, PinType *pin) 00717 { 00718 Coord t = PIN_SIZE (pin) / 2; 00719 if (TEST_FLAG (SQUAREFLAG, pin)) 00720 { 00721 BoxType b; 00722 00723 b.X1 = pin->X - t; 00724 b.X2 = pin->X + t; 00725 b.Y1 = pin->Y - t; 00726 b.Y2 = pin->Y + t; 00727 if (IsPointInBox (X, Y, &b, Radius)) 00728 return true; 00729 } 00730 else if (Distance (pin->X, pin->Y, X, Y) <= Radius + t) 00731 return true; 00732 return false; 00733 } 00734 00738 bool 00739 IsPointOnLineEnd (Coord X, Coord Y, RatType *Line) 00740 { 00741 if (((X == Line->Point1.X) && (Y == Line->Point1.Y)) || 00742 ((X == Line->Point2.X) && (Y == Line->Point2.Y))) 00743 return (true); 00744 return (false); 00745 } 00746 00781 bool 00782 IsPointOnLine (Coord X, Coord Y, Coord Radius, LineType *Line) 00783 { 00784 double D1, D2, L; 00785 00786 /* Get length of segment */ 00787 L = Distance (Line->Point1.X, Line->Point1.Y, Line->Point2.X, Line->Point2.Y); 00788 if (L < 0.1) 00789 return Distance (X, Y, Line->Point1.X, Line->Point1.Y) < Radius + Line->Thickness / 2; 00790 00791 /* Get distance from (X1, Y1) to Q (on the line) */ 00792 D1 = ((double) (Y - Line->Point1.Y) * (Line->Point2.Y - Line->Point1.Y) 00793 + (double) (X - Line->Point1.X) * (Line->Point2.X - Line->Point1.X)) / L; 00794 /* Translate this into distance to Q from segment */ 00795 if (D1 < 0) D1 = -D1; 00796 else if (D1 > L) D1 -= L; 00797 else D1 = 0; 00798 /* Get distance from (X, Y) to Q */ 00799 D2 = ((double) (X - Line->Point1.X) * (Line->Point2.Y - Line->Point1.Y) 00800 - (double) (Y - Line->Point1.Y) * (Line->Point2.X - Line->Point1.X)) / L; 00801 /* Total distance is then the pythagorean sum of these */ 00802 return hypot (D1, D2) <= Radius + Line->Thickness / 2; 00803 } 00804 00808 bool 00809 IsLineInRectangle (Coord X1, Coord Y1, Coord X2, Coord Y2, LineType *Line) 00810 { 00811 LineType line; 00812 00813 /* first, see if point 1 is inside the rectangle */ 00814 /* in case the whole line is inside the rectangle */ 00815 if (X1 < Line->Point1.X && X2 > Line->Point1.X && 00816 Y1 < Line->Point1.Y && Y2 > Line->Point1.Y) 00817 return (true); 00818 /* construct a set of dummy lines and check each of them */ 00819 line.Thickness = 0; 00820 line.Flags = NoFlags (); 00821 00822 /* upper-left to upper-right corner */ 00823 line.Point1.Y = line.Point2.Y = Y1; 00824 line.Point1.X = X1; 00825 line.Point2.X = X2; 00826 if (LineLineIntersect (&line, Line)) 00827 return (true); 00828 00829 /* upper-right to lower-right corner */ 00830 line.Point1.X = X2; 00831 line.Point1.Y = Y1; 00832 line.Point2.Y = Y2; 00833 if (LineLineIntersect (&line, Line)) 00834 return (true); 00835 00836 /* lower-right to lower-left corner */ 00837 line.Point1.Y = Y2; 00838 line.Point1.X = X1; 00839 line.Point2.X = X2; 00840 if (LineLineIntersect (&line, Line)) 00841 return (true); 00842 00843 /* lower-left to upper-left corner */ 00844 line.Point2.X = X1; 00845 line.Point1.Y = Y1; 00846 line.Point2.Y = Y2; 00847 if (LineLineIntersect (&line, Line)) 00848 return (true); 00849 00850 return (false); 00851 } 00852 00856 static int 00857 IsPointInQuadrangle(PointType p[4], PointType *l) 00858 { 00859 Coord dx, dy, x, y; 00860 double prod0, prod1; 00861 00862 dx = p[1].X - p[0].X; 00863 dy = p[1].Y - p[0].Y; 00864 x = l->X - p[0].X; 00865 y = l->Y - p[0].Y; 00866 prod0 = (double) x * dx + (double) y * dy; 00867 x = l->X - p[1].X; 00868 y = l->Y - p[1].Y; 00869 prod1 = (double) x * dx + (double) y * dy; 00870 if (prod0 * prod1 <= 0) 00871 { 00872 dx = p[1].X - p[2].X; 00873 dy = p[1].Y - p[2].Y; 00874 prod0 = (double) x * dx + (double) y * dy; 00875 x = l->X - p[2].X; 00876 y = l->Y - p[2].Y; 00877 prod1 = (double) x * dx + (double) y * dy; 00878 if (prod0 * prod1 <= 0) 00879 return true; 00880 } 00881 return false; 00882 } 00883 00890 bool 00891 IsLineInQuadrangle (PointType p[4], LineType *Line) 00892 { 00893 LineType line; 00894 00895 /* first, see if point 1 is inside the rectangle */ 00896 /* in case the whole line is inside the rectangle */ 00897 if (IsPointInQuadrangle(p,&(Line->Point1))) 00898 return true; 00899 if (IsPointInQuadrangle(p,&(Line->Point2))) 00900 return true; 00901 /* construct a set of dummy lines and check each of them */ 00902 line.Thickness = 0; 00903 line.Flags = NoFlags (); 00904 00905 /* upper-left to upper-right corner */ 00906 line.Point1.X = p[0].X; line.Point1.Y = p[0].Y; 00907 line.Point2.X = p[1].X; line.Point2.Y = p[1].Y; 00908 if (LineLineIntersect (&line, Line)) 00909 return (true); 00910 00911 /* upper-right to lower-right corner */ 00912 line.Point1.X = p[2].X; line.Point1.Y = p[2].Y; 00913 if (LineLineIntersect (&line, Line)) 00914 return (true); 00915 00916 /* lower-right to lower-left corner */ 00917 line.Point2.X = p[3].X; line.Point2.Y = p[3].Y; 00918 if (LineLineIntersect (&line, Line)) 00919 return (true); 00920 00921 /* lower-left to upper-left corner */ 00922 line.Point1.X = p[0].X; line.Point1.Y = p[0].Y; 00923 if (LineLineIntersect (&line, Line)) 00924 return (true); 00925 00926 return (false); 00927 } 00931 bool 00932 IsArcInRectangle (Coord X1, Coord Y1, Coord X2, Coord Y2, ArcType *Arc) 00933 { 00934 LineType line; 00935 00936 /* construct a set of dummy lines and check each of them */ 00937 line.Thickness = 0; 00938 line.Flags = NoFlags (); 00939 00940 /* upper-left to upper-right corner */ 00941 line.Point1.Y = line.Point2.Y = Y1; 00942 line.Point1.X = X1; 00943 line.Point2.X = X2; 00944 if (LineArcIntersect (&line, Arc)) 00945 return (true); 00946 00947 /* upper-right to lower-right corner */ 00948 line.Point1.X = line.Point2.X = X2; 00949 line.Point1.Y = Y1; 00950 line.Point2.Y = Y2; 00951 if (LineArcIntersect (&line, Arc)) 00952 return (true); 00953 00954 /* lower-right to lower-left corner */ 00955 line.Point1.Y = line.Point2.Y = Y2; 00956 line.Point1.X = X1; 00957 line.Point2.X = X2; 00958 if (LineArcIntersect (&line, Arc)) 00959 return (true); 00960 00961 /* lower-left to upper-left corner */ 00962 line.Point1.X = line.Point2.X = X1; 00963 line.Point1.Y = Y1; 00964 line.Point2.Y = Y2; 00965 if (LineArcIntersect (&line, Arc)) 00966 return (true); 00967 00968 return (false); 00969 } 00970 00977 bool 00978 IsPointInPad (Coord X, Coord Y, Coord Radius, PadType *Pad) 00979 { 00980 double r, Sin, Cos; 00981 Coord x; 00982 Coord t2 = (Pad->Thickness + 1) / 2, range; 00983 PadType pad = *Pad; 00984 00985 /* series of transforms saving range */ 00986 /* move Point1 to the origin */ 00987 X -= pad.Point1.X; 00988 Y -= pad.Point1.Y; 00989 00990 pad.Point2.X -= pad.Point1.X; 00991 pad.Point2.Y -= pad.Point1.Y; 00992 /* so, pad.Point1.X = pad.Point1.Y = 0; */ 00993 00994 /* rotate round (0, 0) so that Point2 coordinates be (r, 0) */ 00995 r = Distance (0, 0, pad.Point2.X, pad.Point2.Y); 00996 if (r < .1) 00997 { 00998 Cos = 1; 00999 Sin = 0; 01000 } 01001 else 01002 { 01003 Sin = pad.Point2.Y / r; 01004 Cos = pad.Point2.X / r; 01005 } 01006 x = X; 01007 X = X * Cos + Y * Sin; 01008 Y = Y * Cos - x * Sin; 01009 /* now pad.Point2.X = r; pad.Point2.Y = 0; */ 01010 01011 /* take into account the ends */ 01012 if (TEST_FLAG (SQUAREFLAG, Pad)) 01013 { 01014 r += Pad->Thickness; 01015 X += t2; 01016 } 01017 if (Y < 0) 01018 Y = -Y; /* range value is evident now*/ 01019 01020 if (TEST_FLAG (SQUAREFLAG, Pad)) 01021 { 01022 if (X <= 0) 01023 { 01024 if (Y <= t2) 01025 range = -X; 01026 else 01027 return Radius > Distance (0, t2, X, Y); 01028 } 01029 else if (X >= r) 01030 { 01031 if (Y <= t2) 01032 range = X - r; 01033 else 01034 return Radius > Distance (r, t2, X, Y); 01035 } 01036 else 01037 range = Y - t2; 01038 } 01039 else/*Rounded pad: even more simple*/ 01040 { 01041 if (X <= 0) 01042 return (Radius + t2) > Distance (0, 0, X, Y); 01043 else if (X >= r) 01044 return (Radius + t2) > Distance (r, 0, X, Y); 01045 else 01046 range = Y - t2; 01047 } 01048 return range < Radius; 01049 } 01050 01057 bool 01058 IsPointInBox (Coord X, Coord Y, BoxType *box, Coord Radius) 01059 { 01060 Coord width, height, range; 01061 01062 /* Compute coordinates relative to Point1 */ 01063 X -= box->X1; 01064 Y -= box->Y1; 01065 01066 width = box->X2 - box->X1; 01067 height = box->Y2 - box->Y1; 01068 01069 if (X <= 0) 01070 { 01071 if (Y < 0) 01072 return Radius > Distance (0, 0, X, Y); 01073 else if (Y > height) 01074 return Radius > Distance (0, height, X, Y); 01075 else 01076 range = -X; 01077 } 01078 else if (X >= width) 01079 { 01080 if (Y < 0) 01081 return Radius > Distance (width, 0, X, Y); 01082 else if (Y > height) 01083 return Radius > Distance (width, height, X, Y); 01084 else 01085 range = X - width; 01086 } 01087 else 01088 { 01089 if (Y < 0) 01090 range = -Y; 01091 else if (Y > height) 01092 range = Y - height; 01093 else 01094 return true; 01095 } 01096 01097 return range < Radius; 01098 } 01099 01106 bool 01107 IsPointOnArc (Coord X, Coord Y, Coord Radius, ArcType *Arc) 01108 { 01109 /* Calculate angle of point from arc center */ 01110 double p_dist = Distance (X, Y, Arc->X, Arc->Y); 01111 double p_cos = (X - Arc->X) / p_dist; 01112 Angle p_ang = acos (p_cos) * RAD_TO_DEG; 01113 Angle ang1, ang2; 01114 01115 /* Convert StartAngle, Delta into bounding angles in [0, 720) */ 01116 if (Arc->Delta > 0) 01117 { 01118 ang1 = NormalizeAngle (Arc->StartAngle); 01119 ang2 = NormalizeAngle (Arc->StartAngle + Arc->Delta); 01120 } 01121 else 01122 { 01123 ang1 = NormalizeAngle (Arc->StartAngle + Arc->Delta); 01124 ang2 = NormalizeAngle (Arc->StartAngle); 01125 } 01126 if (ang1 > ang2) 01127 ang2 += 360; 01128 /* Make sure full circles aren't treated as zero-length arcs */ 01129 if (Arc->Delta == 360 || Arc->Delta == -360) 01130 ang2 = ang1 + 360; 01131 01132 if (Y > Arc->Y) 01133 p_ang = -p_ang; 01134 p_ang += 180; 01135 01136 /* Check point is outside arc range, check distance from endpoints */ 01137 if (ang1 >= p_ang || ang2 <= p_ang) 01138 { 01139 Coord ArcX, ArcY; 01140 01141 ArcX = Arc->X + Arc->Width * 01142 cos ((Arc->StartAngle + 180) / RAD_TO_DEG); 01143 ArcY = Arc->Y - Arc->Width * 01144 sin ((Arc->StartAngle + 180) / RAD_TO_DEG); 01145 if (Distance (X, Y, ArcX, ArcY) < Radius + Arc->Thickness / 2) 01146 return true; 01147 01148 ArcX = Arc->X + Arc->Width * 01149 cos ((Arc->StartAngle + Arc->Delta + 180) / RAD_TO_DEG); 01150 ArcY = Arc->Y - Arc->Width * 01151 sin ((Arc->StartAngle + Arc->Delta + 180) / RAD_TO_DEG); 01152 if (Distance (X, Y, ArcX, ArcY) < Radius + Arc->Thickness / 2) 01153 return true; 01154 return false; 01155 } 01156 /* If point is inside the arc range, just compare it to the arc */ 01157 return fabs (Distance (X, Y, Arc->X, Arc->Y) - Arc->Width) < Radius + Arc->Thickness / 2; 01158 } 01159 01178 int 01179 SearchObjectByLocation (unsigned Type, 01180 void **Result1, void **Result2, void **Result3, 01181 Coord X, Coord Y, Coord Radius) 01182 { 01183 void *r1, *r2, *r3; 01184 void **pr1 = &r1, **pr2 = &r2, **pr3 = &r3; 01185 int i; 01186 double HigherBound = 0; 01187 int HigherAvail = NO_TYPE; 01188 int locked = Type & LOCKED_TYPE; 01189 /* setup variables used by local functions */ 01190 PosX = X; 01191 PosY = Y; 01192 SearchRadius = Radius; 01193 if (Radius) 01194 { 01195 SearchBox.X1 = X - Radius; 01196 SearchBox.Y1 = Y - Radius; 01197 SearchBox.X2 = X + Radius; 01198 SearchBox.Y2 = Y + Radius; 01199 } 01200 else 01201 { 01202 SearchBox = point_box (X, Y); 01203 } 01204 01205 if (TEST_FLAG (LOCKNAMESFLAG, PCB)) 01206 { 01207 Type &= ~ (ELEMENTNAME_TYPE | TEXT_TYPE); 01208 } 01209 if (TEST_FLAG (HIDENAMESFLAG, PCB)) 01210 { 01211 Type &= ~ELEMENTNAME_TYPE; 01212 } 01213 if (TEST_FLAG (ONLYNAMESFLAG, PCB)) 01214 { 01215 Type &= (ELEMENTNAME_TYPE | TEXT_TYPE); 01216 } 01217 if (TEST_FLAG (THINDRAWFLAG, PCB) || TEST_FLAG (THINDRAWPOLYFLAG, PCB)) 01218 { 01219 Type &= ~POLYGON_TYPE; 01220 } 01221 01222 if (Type & RATLINE_TYPE && PCB->RatOn && 01223 SearchRatLineByLocation (locked, 01224 (RatType **) Result1, 01225 (RatType **) Result2, 01226 (RatType **) Result3)) 01227 return (RATLINE_TYPE); 01228 01229 if (Type & VIA_TYPE && 01230 SearchViaByLocation (locked, 01231 (PinType **) Result1, 01232 (PinType **) Result2, (PinType **) Result3)) 01233 return (VIA_TYPE); 01234 01235 if (Type & PIN_TYPE && 01236 SearchPinByLocation (locked, 01237 (ElementType **) pr1, 01238 (PinType **) pr2, (PinType **) pr3)) 01239 HigherAvail = PIN_TYPE; 01240 01241 if (!HigherAvail && Type & PAD_TYPE && 01242 SearchPadByLocation (locked, 01243 (ElementType **) pr1, 01244 (PadType **) pr2, (PadType **) pr3, false)) 01245 HigherAvail = PAD_TYPE; 01246 01247 if (!HigherAvail && Type & ELEMENTNAME_TYPE && 01248 SearchElementNameByLocation (locked, 01249 (ElementType **) pr1, 01250 (TextType **) pr2, (TextType **) pr3, 01251 false)) 01252 { 01253 BoxType *box = &((TextType *) r2)->BoundingBox; 01254 HigherBound = (double) (box->X2 - box->X1) * (double) (box->Y2 - box->Y1); 01255 HigherAvail = ELEMENTNAME_TYPE; 01256 } 01257 01258 if (!HigherAvail && Type & ELEMENT_TYPE && 01259 SearchElementByLocation (locked, 01260 (ElementType **) pr1, 01261 (ElementType **) pr2, 01262 (ElementType **) pr3, false)) 01263 { 01264 BoxType *box = &((ElementType *) r1)->BoundingBox; 01265 HigherBound = (double) (box->X2 - box->X1) * (double) (box->Y2 - box->Y1); 01266 HigherAvail = ELEMENT_TYPE; 01267 } 01268 01269 for (i = -1; i < max_copper_layer + 1; i++) 01270 { 01271 if (i < 0) 01272 SearchLayer = &PCB->Data->SILKLAYER; 01273 else if (i < max_copper_layer) 01274 SearchLayer = LAYER_ON_STACK (i); 01275 else 01276 { 01277 SearchLayer = &PCB->Data->BACKSILKLAYER; 01278 if (!PCB->InvisibleObjectsOn) 01279 continue; 01280 } 01281 if (SearchLayer->On) 01282 { 01283 if ((HigherAvail & (PIN_TYPE | PAD_TYPE)) == 0 && 01284 Type & POLYGONPOINT_TYPE && 01285 SearchPointByLocation (locked, 01286 (LayerType **) Result1, 01287 (PolygonType **) Result2, 01288 (PointType **) Result3)) 01289 return (POLYGONPOINT_TYPE); 01290 01291 if ((HigherAvail & (PIN_TYPE | PAD_TYPE)) == 0 && 01292 Type & LINEPOINT_TYPE && 01293 SearchLinePointByLocation (locked, 01294 (LayerType **) Result1, 01295 (LineType **) Result2, 01296 (PointType **) Result3)) 01297 return (LINEPOINT_TYPE); 01298 01299 if ((HigherAvail & (PIN_TYPE | PAD_TYPE)) == 0 && Type & LINE_TYPE 01300 && SearchLineByLocation (locked, 01301 (LayerType **) Result1, 01302 (LineType **) Result2, 01303 (LineType **) Result3)) 01304 return (LINE_TYPE); 01305 01306 if ((HigherAvail & (PIN_TYPE | PAD_TYPE)) == 0 && 01307 Type & ARCPOINT_TYPE && 01308 SearchArcPointByLocation (locked, 01309 (LayerType **) Result1, 01310 (ArcType **) Result2, 01311 (PointType **) Result3)) 01312 return (ARCPOINT_TYPE); 01313 01314 if ((HigherAvail & (PIN_TYPE | PAD_TYPE)) == 0 && Type & ARC_TYPE && 01315 SearchArcByLocation (locked, 01316 (LayerType **) Result1, 01317 (ArcType **) Result2, 01318 (ArcType **) Result3)) 01319 return (ARC_TYPE); 01320 01321 if ((HigherAvail & (PIN_TYPE | PAD_TYPE)) == 0 && Type & TEXT_TYPE 01322 && SearchTextByLocation (locked, 01323 (LayerType **) Result1, 01324 (TextType **) Result2, 01325 (TextType **) Result3)) 01326 return (TEXT_TYPE); 01327 01328 if (Type & POLYGON_TYPE && 01329 SearchPolygonByLocation (locked, 01330 (LayerType **) Result1, 01331 (PolygonType **) Result2, 01332 (PolygonType **) Result3)) 01333 { 01334 if (HigherAvail) 01335 { 01336 BoxType *box = 01337 &(*(PolygonType **) Result2)->BoundingBox; 01338 double area = 01339 (double) (box->X2 - box->X1) * (double) (box->X2 - box->X1); 01340 if (HigherBound < area) 01341 break; 01342 else 01343 return (POLYGON_TYPE); 01344 } 01345 else 01346 return (POLYGON_TYPE); 01347 } 01348 } 01349 } 01350 /* return any previously found objects */ 01351 if (HigherAvail & PIN_TYPE) 01352 { 01353 *Result1 = r1; 01354 *Result2 = r2; 01355 *Result3 = r3; 01356 return (PIN_TYPE); 01357 } 01358 01359 if (HigherAvail & PAD_TYPE) 01360 { 01361 *Result1 = r1; 01362 *Result2 = r2; 01363 *Result3 = r3; 01364 return (PAD_TYPE); 01365 } 01366 01367 if (HigherAvail & ELEMENTNAME_TYPE) 01368 { 01369 *Result1 = r1; 01370 *Result2 = r2; 01371 *Result3 = r3; 01372 return (ELEMENTNAME_TYPE); 01373 } 01374 01375 if (HigherAvail & ELEMENT_TYPE) 01376 { 01377 *Result1 = r1; 01378 *Result2 = r2; 01379 *Result3 = r3; 01380 return (ELEMENT_TYPE); 01381 } 01382 01383 /* search the 'invisible objects' last */ 01384 if (!PCB->InvisibleObjectsOn) 01385 return (NO_TYPE); 01386 01387 if (Type & PAD_TYPE && 01388 SearchPadByLocation (locked, 01389 (ElementType **) Result1, 01390 (PadType **) Result2, (PadType **) Result3, 01391 true)) 01392 return (PAD_TYPE); 01393 01394 if (Type & ELEMENTNAME_TYPE && 01395 SearchElementNameByLocation (locked, 01396 (ElementType **) Result1, 01397 (TextType **) Result2, 01398 (TextType **) Result3, true)) 01399 return (ELEMENTNAME_TYPE); 01400 01401 if (Type & ELEMENT_TYPE && 01402 SearchElementByLocation (locked, 01403 (ElementType **) Result1, 01404 (ElementType **) Result2, 01405 (ElementType **) Result3, true)) 01406 return (ELEMENT_TYPE); 01407 01408 return (NO_TYPE); 01409 } 01410 01424 int 01425 SearchObjectByID (DataType *Base, 01426 void **Result1, void **Result2, void **Result3, int ID, 01427 int type) 01428 { 01429 if (type == LINE_TYPE || type == LINEPOINT_TYPE) 01430 { 01431 ALLLINE_LOOP (Base); 01432 { 01433 if (line->ID == ID) 01434 { 01435 *Result1 = (void *) layer; 01436 *Result2 = *Result3 = (void *) line; 01437 return (LINE_TYPE); 01438 } 01439 if (line->Point1.ID == ID) 01440 { 01441 *Result1 = (void *) layer; 01442 *Result2 = (void *) line; 01443 *Result3 = (void *) &line->Point1; 01444 return (LINEPOINT_TYPE); 01445 } 01446 if (line->Point2.ID == ID) 01447 { 01448 *Result1 = (void *) layer; 01449 *Result2 = (void *) line; 01450 *Result3 = (void *) &line->Point2; 01451 return (LINEPOINT_TYPE); 01452 } 01453 } 01454 ENDALL_LOOP; 01455 } 01456 if (type == ARC_TYPE) 01457 { 01458 ALLARC_LOOP (Base); 01459 { 01460 if (arc->ID == ID) 01461 { 01462 *Result1 = (void *) layer; 01463 *Result2 = *Result3 = (void *) arc; 01464 return (ARC_TYPE); 01465 } 01466 } 01467 ENDALL_LOOP; 01468 } 01469 01470 if (type == TEXT_TYPE) 01471 { 01472 ALLTEXT_LOOP (Base); 01473 { 01474 if (text->ID == ID) 01475 { 01476 *Result1 = (void *) layer; 01477 *Result2 = *Result3 = (void *) text; 01478 return (TEXT_TYPE); 01479 } 01480 } 01481 ENDALL_LOOP; 01482 } 01483 01484 if (type == POLYGON_TYPE || type == POLYGONPOINT_TYPE) 01485 { 01486 ALLPOLYGON_LOOP (Base); 01487 { 01488 if (polygon->ID == ID) 01489 { 01490 *Result1 = (void *) layer; 01491 *Result2 = *Result3 = (void *) polygon; 01492 return (POLYGON_TYPE); 01493 } 01494 if (type == POLYGONPOINT_TYPE) 01495 POLYGONPOINT_LOOP (polygon); 01496 { 01497 if (point->ID == ID) 01498 { 01499 *Result1 = (void *) layer; 01500 *Result2 = (void *) polygon; 01501 *Result3 = (void *) point; 01502 return (POLYGONPOINT_TYPE); 01503 } 01504 } 01505 END_LOOP; 01506 } 01507 ENDALL_LOOP; 01508 } 01509 if (type == VIA_TYPE) 01510 { 01511 VIA_LOOP (Base); 01512 { 01513 if (via->ID == ID) 01514 { 01515 *Result1 = *Result2 = *Result3 = (void *) via; 01516 return (VIA_TYPE); 01517 } 01518 } 01519 END_LOOP; 01520 } 01521 01522 if (type == RATLINE_TYPE || type == LINEPOINT_TYPE) 01523 { 01524 RAT_LOOP (Base); 01525 { 01526 if (line->ID == ID) 01527 { 01528 *Result1 = *Result2 = *Result3 = (void *) line; 01529 return (RATLINE_TYPE); 01530 } 01531 if (line->Point1.ID == ID) 01532 { 01533 *Result1 = (void *) NULL; 01534 *Result2 = (void *) line; 01535 *Result3 = (void *) &line->Point1; 01536 return (LINEPOINT_TYPE); 01537 } 01538 if (line->Point2.ID == ID) 01539 { 01540 *Result1 = (void *) NULL; 01541 *Result2 = (void *) line; 01542 *Result3 = (void *) &line->Point2; 01543 return (LINEPOINT_TYPE); 01544 } 01545 } 01546 END_LOOP; 01547 } 01548 01549 if (type == ELEMENT_TYPE || type == PAD_TYPE || type == PIN_TYPE 01550 || type == ELEMENTLINE_TYPE || type == ELEMENTNAME_TYPE 01551 || type == ELEMENTARC_TYPE) 01552 /* check pins and elementnames too */ 01553 ELEMENT_LOOP (Base); 01554 { 01555 if (element->ID == ID) 01556 { 01557 *Result1 = *Result2 = *Result3 = (void *) element; 01558 return (ELEMENT_TYPE); 01559 } 01560 if (type == ELEMENTLINE_TYPE) 01561 ELEMENTLINE_LOOP (element); 01562 { 01563 if (line->ID == ID) 01564 { 01565 *Result1 = (void *) element; 01566 *Result2 = *Result3 = (void *) line; 01567 return (ELEMENTLINE_TYPE); 01568 } 01569 } 01570 END_LOOP; 01571 if (type == ELEMENTARC_TYPE) 01572 ARC_LOOP (element); 01573 { 01574 if (arc->ID == ID) 01575 { 01576 *Result1 = (void *) element; 01577 *Result2 = *Result3 = (void *) arc; 01578 return (ELEMENTARC_TYPE); 01579 } 01580 } 01581 END_LOOP; 01582 if (type == ELEMENTNAME_TYPE) 01583 ELEMENTTEXT_LOOP (element); 01584 { 01585 if (text->ID == ID) 01586 { 01587 *Result1 = (void *) element; 01588 *Result2 = *Result3 = (void *) text; 01589 return (ELEMENTNAME_TYPE); 01590 } 01591 } 01592 END_LOOP; 01593 if (type == PIN_TYPE) 01594 PIN_LOOP (element); 01595 { 01596 if (pin->ID == ID) 01597 { 01598 *Result1 = (void *) element; 01599 *Result2 = *Result3 = (void *) pin; 01600 return (PIN_TYPE); 01601 } 01602 } 01603 END_LOOP; 01604 if (type == PAD_TYPE) 01605 PAD_LOOP (element); 01606 { 01607 if (pad->ID == ID) 01608 { 01609 *Result1 = (void *) element; 01610 *Result2 = *Result3 = (void *) pad; 01611 return (PAD_TYPE); 01612 } 01613 } 01614 END_LOOP; 01615 } 01616 END_LOOP; 01617 01618 Message ("hace: Internal error, search for ID %d failed\n", ID); 01619 return (NO_TYPE); 01620 } 01621 01628 ElementType * 01629 SearchElementByName (DataType *Base, char *Name) 01630 { 01631 ElementType *result = NULL; 01632 01633 ELEMENT_LOOP (Base); 01634 { 01635 if (element->Name[1].TextString && 01636 NSTRCMP (element->Name[1].TextString, Name) == 0) 01637 { 01638 result = element; 01639 return (result); 01640 } 01641 } 01642 END_LOOP; 01643 return result; 01644 } 01645 01652 int 01653 SearchLayerByName (DataType *Base, char *Name) 01654 { 01655 int result = 0; 01656 01657 LAYER_LOOP (Base, max_copper_layer); 01658 { 01659 if (layer->Name && 01660 NSTRCMP (layer->Name, Name) == 0) 01661 { 01662 return result; 01663 } 01664 else 01665 result++; 01666 } 01667 END_LOOP; 01668 return -1; 01669 } 01670 01674 int 01675 SearchScreen (Coord X, Coord Y, int Type, void **Result1, 01676 void **Result2, void **Result3) 01677 { 01678 int ans; 01679 01680 ans = SearchObjectByLocation (Type, Result1, Result2, Result3, 01681 X, Y, SLOP * pixel_slop); 01682 return (ans); 01683 }