/* --------------------------------------------------------------------------- * searches for any kind of object or for a set of object types * the calling routine passes two pointers to allocated memory for storing * the results. * A type value is returned too which is NO_TYPE if no objects has been found. * A set of object types is passed in. * The object is located by it's position. * * The layout is checked in the following order: * polygon-point, pin, via, line, text, elementname, polygon, element * * Note that if Type includes LOCKED_TYPE, then the search includes * locked items. Otherwise, locked items are ignored. */ int SearchObjectByLocation (unsigned Type, void **Result1, void **Result2, void **Result3, Coord X, Coord Y, Coord Radius) { void *r1, *r2, *r3; void **pr1 = &r1, **pr2 = &r2, **pr3 = &r3; int i; double HigherBound = 0; int HigherAvail = NO_TYPE; int locked = Type & LOCKED_TYPE; /* setup variables used by local functions */ PosX = X; PosY = Y; SearchRadius = Radius; if (Radius) { SearchBox.X1 = X - Radius; SearchBox.Y1 = Y - Radius; SearchBox.X2 = X + Radius; SearchBox.Y2 = Y + Radius; } else { SearchBox = point_box (X, Y); } if (TEST_FLAG (LOCKNAMESFLAG, PCB)) { Type &= ~ (ELEMENTNAME_TYPE | TEXT_TYPE); } if (TEST_FLAG (HIDENAMESFLAG, PCB)) { Type &= ~ELEMENTNAME_TYPE; } if (TEST_FLAG (ONLYNAMESFLAG, PCB)) { Type &= (ELEMENTNAME_TYPE | TEXT_TYPE); } if (TEST_FLAG (THINDRAWFLAG, PCB) || TEST_FLAG (THINDRAWPOLYFLAG, PCB)) { Type &= ~POLYGON_TYPE; } if (Type & RATLINE_TYPE && PCB->RatOn && SearchRatLineByLocation (locked, (RatTypePtr *) Result1, (RatTypePtr *) Result2, (RatTypePtr *) Result3)) return (RATLINE_TYPE); if (Type & VIA_TYPE && SearchViaByLocation (locked, (PinTypePtr *) Result1, (PinTypePtr *) Result2, (PinTypePtr *) Result3)) return (VIA_TYPE); if (Type & PIN_TYPE && SearchPinByLocation (locked, (ElementTypePtr *) pr1, (PinTypePtr *) pr2, (PinTypePtr *) pr3)) HigherAvail = PIN_TYPE; if (!HigherAvail && Type & PAD_TYPE && SearchPadByLocation (locked, (ElementTypePtr *) pr1, (PadTypePtr *) pr2, (PadTypePtr *) pr3, false)) HigherAvail = PAD_TYPE; if (!HigherAvail && Type & ELEMENTNAME_TYPE && SearchElementNameByLocation (locked, (ElementTypePtr *) pr1, (TextTypePtr *) pr2, (TextTypePtr *) pr3, false)) { BoxTypePtr box = &((TextTypePtr) r2)->BoundingBox; HigherBound = (double) (box->X2 - box->X1) * (double) (box->Y2 - box->Y1); HigherAvail = ELEMENTNAME_TYPE; } if (!HigherAvail && Type & ELEMENT_TYPE && SearchElementByLocation (locked, (ElementTypePtr *) pr1, (ElementTypePtr *) pr2, (ElementTypePtr *) pr3, false)) { BoxTypePtr box = &((ElementTypePtr) r1)->BoundingBox; HigherBound = (double) (box->X2 - box->X1) * (double) (box->Y2 - box->Y1); HigherAvail = ELEMENT_TYPE; } for (i = -1; i < max_copper_layer + 1; i++) { if (i < 0) SearchLayer = &PCB->Data->SILKLAYER; else if (i < max_copper_layer) SearchLayer = LAYER_ON_STACK (i); else { SearchLayer = &PCB->Data->BACKSILKLAYER; if (!PCB->InvisibleObjectsOn) continue; } if (SearchLayer->On) { if ((HigherAvail & (PIN_TYPE | PAD_TYPE)) == 0 && Type & POLYGONPOINT_TYPE && SearchPointByLocation (locked, (LayerTypePtr *) Result1, (PolygonTypePtr *) Result2, (PointTypePtr *) Result3)) return (POLYGONPOINT_TYPE); if ((HigherAvail & (PIN_TYPE | PAD_TYPE)) == 0 && Type & LINEPOINT_TYPE && SearchLinePointByLocation (locked, (LayerTypePtr *) Result1, (LineTypePtr *) Result2, (PointTypePtr *) Result3)) return (LINEPOINT_TYPE); if ((HigherAvail & (PIN_TYPE | PAD_TYPE)) == 0 && Type & LINE_TYPE && SearchLineByLocation (locked, (LayerTypePtr *) Result1, (LineTypePtr *) Result2, (LineTypePtr *) Result3)) return (LINE_TYPE); if ((HigherAvail & (PIN_TYPE | PAD_TYPE)) == 0 && Type & ARC_TYPE && SearchArcByLocation (locked, (LayerTypePtr *) Result1, (ArcTypePtr *) Result2, (ArcTypePtr *) Result3)) return (ARC_TYPE); if ((HigherAvail & (PIN_TYPE | PAD_TYPE)) == 0 && Type & TEXT_TYPE && SearchTextByLocation (locked, (LayerTypePtr *) Result1, (TextTypePtr *) Result2, (TextTypePtr *) Result3)) return (TEXT_TYPE); if (Type & POLYGON_TYPE && SearchPolygonByLocation (locked, (LayerTypePtr *) Result1, (PolygonTypePtr *) Result2, (PolygonTypePtr *) Result3)) { if (HigherAvail) { BoxTypePtr box = &(*(PolygonTypePtr *) Result2)->BoundingBox; double area = (double) (box->X2 - box->X1) * (double) (box->X2 - box->X1); if (HigherBound < area) break; else return (POLYGON_TYPE); } else return (POLYGON_TYPE); } } } /* return any previously found objects */ if (HigherAvail & PIN_TYPE) { *Result1 = r1; *Result2 = r2; *Result3 = r3; return (PIN_TYPE); } if (HigherAvail & PAD_TYPE) { *Result1 = r1; *Result2 = r2; *Result3 = r3; return (PAD_TYPE); } if (HigherAvail & ELEMENTNAME_TYPE) { *Result1 = r1; *Result2 = r2; *Result3 = r3; return (ELEMENTNAME_TYPE); } if (HigherAvail & ELEMENT_TYPE) { *Result1 = r1; *Result2 = r2; *Result3 = r3; return (ELEMENT_TYPE); } /* search the 'invisible objects' last */ if (!PCB->InvisibleObjectsOn) return (NO_TYPE); if (Type & PAD_TYPE && SearchPadByLocation (locked, (ElementTypePtr *) Result1, (PadTypePtr *) Result2, (PadTypePtr *) Result3, true)) return (PAD_TYPE); if (Type & ELEMENTNAME_TYPE && SearchElementNameByLocation (locked, (ElementTypePtr *) Result1, (TextTypePtr *) Result2, (TextTypePtr *) Result3, true)) return (ELEMENTNAME_TYPE); if (Type & ELEMENT_TYPE && SearchElementByLocation (locked, (ElementTypePtr *) Result1, (ElementTypePtr *) Result2, (ElementTypePtr *) Result3, true)) return (ELEMENT_TYPE); return (NO_TYPE); }
/* --------------------------------------------------------------------------- * initializes some identifiers for a new zoom factor and redraws whole screen */ static void DrawEverything (const BoxType *drawn_area) { int i, ngroups, side; int component, solder; /* This is the list of layer groups we will draw. */ int do_group[MAX_LAYER]; /* This is the reverse of the order in which we draw them. */ int drawn_groups[MAX_LAYER]; int plated, unplated; bool paste_empty; PCB->Data->SILKLAYER.Color = PCB->ElementColor; PCB->Data->BACKSILKLAYER.Color = PCB->InvisibleObjectsColor; memset (do_group, 0, sizeof (do_group)); for (ngroups = 0, i = 0; i < max_copper_layer; i++) { LayerType *l = LAYER_ON_STACK (i); int group = GetLayerGroupNumberByNumber (LayerStack[i]); if (l->On && !do_group[group]) { do_group[group] = 1; drawn_groups[ngroups++] = group; } } component = GetLayerGroupNumberByNumber (component_silk_layer); solder = GetLayerGroupNumberByNumber (solder_silk_layer); /* * first draw all 'invisible' stuff */ if (!TEST_FLAG (CHECKPLANESFLAG, PCB) && gui->set_layer ("invisible", SL (INVISIBLE, 0), 0)) { side = SWAP_IDENT ? COMPONENT_LAYER : SOLDER_LAYER; if (PCB->ElementOn) { r_search (PCB->Data->element_tree, drawn_area, NULL, element_callback, &side); r_search (PCB->Data->name_tree[NAME_INDEX (PCB)], drawn_area, NULL, name_callback, &side); DrawLayer (&(PCB->Data->Layer[max_copper_layer + side]), drawn_area); } r_search (PCB->Data->pad_tree, drawn_area, NULL, pad_callback, &side); gui->end_layer (); } /* draw all layers in layerstack order */ for (i = ngroups - 1; i >= 0; i--) { int group = drawn_groups[i]; if (gui->set_layer (0, group, 0)) { DrawLayerGroup (group, drawn_area); gui->end_layer (); } } if (TEST_FLAG (CHECKPLANESFLAG, PCB) && gui->gui) return; /* Draw pins, pads, vias below silk */ if (gui->gui) DrawPPV (SWAP_IDENT ? solder : component, drawn_area); else { CountHoles (&plated, &unplated, drawn_area); if (plated && gui->set_layer ("plated-drill", SL (PDRILL, 0), 0)) { DrawHoles (true, false, drawn_area); gui->end_layer (); } if (unplated && gui->set_layer ("unplated-drill", SL (UDRILL, 0), 0)) { DrawHoles (false, true, drawn_area); gui->end_layer (); } } /* Draw the solder mask if turned on */ if (gui->set_layer ("componentmask", SL (MASK, TOP), 0)) { DrawMask (COMPONENT_LAYER, drawn_area); gui->end_layer (); } if (gui->set_layer ("soldermask", SL (MASK, BOTTOM), 0)) { DrawMask (SOLDER_LAYER, drawn_area); gui->end_layer (); } if (gui->set_layer ("topsilk", SL (SILK, TOP), 0)) { DrawSilk (COMPONENT_LAYER, drawn_area); gui->end_layer (); } if (gui->set_layer ("bottomsilk", SL (SILK, BOTTOM), 0)) { DrawSilk (SOLDER_LAYER, drawn_area); gui->end_layer (); } if (gui->gui) { /* Draw element Marks */ if (PCB->PinOn) r_search (PCB->Data->element_tree, drawn_area, NULL, EMark_callback, NULL); /* Draw rat lines on top */ if (gui->set_layer ("rats", SL (RATS, 0), 0)) { DrawRats(drawn_area); gui->end_layer (); } } paste_empty = IsPasteEmpty (COMPONENT_LAYER); if (gui->set_layer ("toppaste", SL (PASTE, TOP), paste_empty)) { DrawPaste (COMPONENT_LAYER, drawn_area); gui->end_layer (); } paste_empty = IsPasteEmpty (SOLDER_LAYER); if (gui->set_layer ("bottompaste", SL (PASTE, BOTTOM), paste_empty)) { DrawPaste (SOLDER_LAYER, drawn_area); gui->end_layer (); } if (gui->set_layer ("topassembly", SL (ASSY, TOP), 0)) { PrintAssembly (COMPONENT_LAYER, drawn_area); gui->end_layer (); } if (gui->set_layer ("bottomassembly", SL (ASSY, BOTTOM), 0)) { PrintAssembly (SOLDER_LAYER, drawn_area); gui->end_layer (); } if (gui->set_layer ("fab", SL (FAB, 0), 0)) { PrintFab (Output.fgGC); gui->end_layer (); } }