void DrawSilk (int side, const BoxType * drawn_area) { #if 0 /* This code is used when you want to mask silk to avoid exposed pins and pads. We decided it was a bad idea to do this unconditionally, but the code remains. */ #endif #if 0 if (gui->poly_before) { gui->graphics->use_mask (HID_MASK_BEFORE); #endif DrawLayer (LAYER_PTR (max_copper_layer + side), drawn_area); /* draw package */ 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); #if 0 } gui->graphics->use_mask (HID_MASK_CLEAR); r_search (PCB->Data->pin_tree, drawn_area, NULL, clearPin_callback, NULL); r_search (PCB->Data->via_tree, drawn_area, NULL, clearPin_callback, NULL); r_search (PCB->Data->pad_tree, drawn_area, NULL, clearPad_callback, &side); if (gui->poly_after) { gui->graphics->use_mask (HID_MASK_AFTER); DrawLayer (LAYER_PTR (max_copper_layer + layer), drawn_area); /* draw package */ 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); } gui->graphics->use_mask (HID_MASK_OFF); #endif }
/* --------------------------------------------------------------------------- * searches the name of an element * the search starts with the last element and goes back to the beginning */ static bool SearchElementNameByLocation (int locked, ElementTypePtr * Element, TextTypePtr * Text, TextTypePtr * Dummy, bool BackToo) { struct ans_info info; /* package layer have to be switched on */ if (PCB->ElementOn) { info.ptr1 = (void **) Element; info.ptr2 = (void **) Text; info.ptr3 = (void **) Dummy; info.area = SQUARE (MAX_COORD); info.BackToo = (BackToo && PCB->InvisibleObjectsOn); info.locked = (locked & LOCKED_TYPE) ? 0 : LOCKFLAG; if (r_search (PCB->Data->name_tree[NAME_INDEX (PCB)], &SearchBox, NULL, name_callback, &info)) return true; } return (false); }
static int ReportDialog (int argc, char **argv, Coord x, Coord y) { void *ptr1, *ptr2, *ptr3; int type; char report[2048]; type = SearchScreen (x, y, REPORT_TYPES, &ptr1, &ptr2, &ptr3); if (type == NO_TYPE) type = SearchScreen (x, y, REPORT_TYPES | LOCKED_TYPE, &ptr1, &ptr2, &ptr3); switch (type) { case VIA_TYPE: { PinType *via; #ifndef NDEBUG if (gui->shift_is_pressed ()) { __r_dump_tree (PCB->Data->via_tree->root, 0); return 0; } #endif via = (PinType *) ptr2; if (TEST_FLAG (HOLEFLAG, via)) pcb_snprintf (report, sizeof (report), _("%m+VIA ID# %ld; Flags:%s\n" "(X,Y) = %$mD.\n" "It is a pure hole of diameter %$mS.\n" "Name = \"%s\"." "%s"), USER_UNITMASK, via->ID, flags_to_string (via->Flags, VIA_TYPE), via->X, via->Y, via->DrillingHole, EMPTY (via->Name), TEST_FLAG (LOCKFLAG, via) ? _("It is LOCKED.\n") : ""); else pcb_snprintf (report, sizeof (report), _("%m+VIA ID# %ld; Flags:%s\n" "(X,Y) = %$mD.\n" "Copper width = %$mS. Drill width = %$mS.\n" "Clearance width in polygons = %$mS.\n" "Annulus = %$mS.\n" "Solder mask hole = %$mS (gap = %$mS).\n" "Name = \"%s\"." "%s"), USER_UNITMASK, via->ID, flags_to_string (via->Flags, VIA_TYPE), via->X, via->Y, via->Thickness, via->DrillingHole, via->Clearance / 2, (via->Thickness - via->DrillingHole) / 2, via->Mask, (via->Mask - via->Thickness) / 2, EMPTY (via->Name), TEST_FLAG (LOCKFLAG, via) ? _("It is LOCKED.\n") : ""); break; } case PIN_TYPE: { PinType *Pin; ElementType *element; #ifndef NDEBUG if (gui->shift_is_pressed ()) { __r_dump_tree (PCB->Data->pin_tree->root, 0); return 0; } #endif Pin = (PinType *) ptr2; element = (ElementType *) ptr1; PIN_LOOP (element); { if (pin == Pin) break; } END_LOOP; if (TEST_FLAG (HOLEFLAG, Pin)) pcb_snprintf (report, sizeof (report), _("%m+PIN ID# %ld; Flags:%s\n" "(X,Y) = %$mD.\n" "It is a mounting hole. Drill width = %$mS.\n" "It is owned by element %$mS.\n" "%s"), USER_UNITMASK, Pin->ID, flags_to_string (Pin->Flags, PIN_TYPE), Pin->X, Pin->Y, Pin->DrillingHole, EMPTY (element->Name[1].TextString), TEST_FLAG (LOCKFLAG, Pin) ? _("It is LOCKED.\n") : ""); else pcb_snprintf (report, sizeof (report), _("%m+PIN ID# %ld; Flags:%s\n" "(X,Y) = %$mD.\n" "Copper width = %$mS. Drill width = %$mS.\n" "Clearance width to Polygon = %$mS.\n" "Annulus = %$mS.\n" "Solder mask hole = %$mS (gap = %$mS).\n" "Name = \"%s\".\n" "It is owned by element %s\n as pin number %s.\n" "%s"), USER_UNITMASK, Pin->ID, flags_to_string (Pin->Flags, PIN_TYPE), Pin->X, Pin->Y, Pin->Thickness, Pin->DrillingHole, Pin->Clearance / 2, (Pin->Thickness - Pin->DrillingHole) / 2, Pin->Mask, (Pin->Mask - Pin->Thickness) / 2, EMPTY (Pin->Name), EMPTY (element->Name[1].TextString), EMPTY (Pin->Number), TEST_FLAG (LOCKFLAG, Pin) ? _("It is LOCKED.\n") : ""); break; } case LINE_TYPE: { LineType *line; #ifndef NDEBUG if (gui->shift_is_pressed ()) { LayerType *layer = (LayerType *) ptr1; __r_dump_tree (layer->line_tree->root, 0); return 0; } #endif line = (LineType *) ptr2; pcb_snprintf (report, sizeof (report), _("%m+LINE ID# %ld; Flags:%s\n" "FirstPoint(X,Y) = %$mD, ID = %ld.\n" "SecondPoint(X,Y) = %$mD, ID = %ld.\n" "Width = %$mS.\nClearance width in polygons = %$mS.\n" "It is on layer %d\n" "and has name \"%s\".\n" "%s"), USER_UNITMASK, line->ID, flags_to_string (line->Flags, LINE_TYPE), line->Point1.X, line->Point1.Y, line->Point1.ID, line->Point2.X, line->Point2.Y, line->Point2.ID, line->Thickness, line->Clearance / 2, GetLayerNumber (PCB->Data, (LayerType *) ptr1), UNKNOWN (line->Number), TEST_FLAG (LOCKFLAG, line) ? _("It is LOCKED.\n") : ""); break; } case RATLINE_TYPE: { RatType *line; #ifndef NDEBUG if (gui->shift_is_pressed ()) { __r_dump_tree (PCB->Data->rat_tree->root, 0); return 0; } #endif line = (RatType *) ptr2; pcb_snprintf (report, sizeof (report), _("%m+RAT-LINE ID# %ld; Flags:%s\n" "FirstPoint(X,Y) = %$mD; ID = %ld; " "connects to layer group %d.\n" "SecondPoint(X,Y) = %$mD; ID = %ld; " "connects to layer group %d.\n"), USER_UNITMASK, line->ID, flags_to_string (line->Flags, LINE_TYPE), line->Point1.X, line->Point1.Y, line->Point1.ID, line->group1, line->Point2.X, line->Point2.Y, line->Point2.ID, line->group2); break; } case ARC_TYPE: { ArcType *Arc; BoxType *box; #ifndef NDEBUG if (gui->shift_is_pressed ()) { LayerType *layer = (LayerType *) ptr1; __r_dump_tree (layer->arc_tree->root, 0); return 0; } #endif Arc = (ArcType *) ptr2; box = GetArcEnds (Arc); pcb_snprintf (report, sizeof (report), _("%m+ARC ID# %ld; Flags:%s\n" "CenterPoint(X,Y) = %$mD.\n" "Radius = %$mS, Thickness = %$mS.\n" "Clearance width in polygons = %$mS.\n" "StartAngle = %ma degrees, DeltaAngle = %ma degrees.\n" "Bounding Box is %$mD, %$mD.\n" "That makes the end points at %$mD and %$mD.\n" "It is on layer %d.\n" "%s"), USER_UNITMASK, Arc->ID, flags_to_string (Arc->Flags, ARC_TYPE), Arc->X, Arc->Y, Arc->Width, Arc->Thickness, Arc->Clearance / 2, Arc->StartAngle, Arc->Delta, Arc->BoundingBox.X1, Arc->BoundingBox.Y1, Arc->BoundingBox.X2, Arc->BoundingBox.Y2, box->X1, box->Y1, box->X2, box->Y2, GetLayerNumber (PCB->Data, (LayerType *) ptr1), TEST_FLAG (LOCKFLAG, Arc) ? _("It is LOCKED.\n") : ""); break; } case POLYGON_TYPE: { PolygonType *Polygon; #ifndef NDEBUG if (gui->shift_is_pressed ()) { LayerType *layer = (LayerType *) ptr1; __r_dump_tree (layer->polygon_tree->root, 0); return 0; } #endif Polygon = (PolygonType *) ptr2; pcb_snprintf (report, sizeof (report), _("%m+POLYGON ID# %ld; Flags:%s\n" "Its bounding box is %$mD %$mD.\n" "It has %d points and could store %d more\n" " without using more memory.\n" "It has %d holes and resides on layer %d.\n" "%s"), USER_UNITMASK, Polygon->ID, flags_to_string (Polygon->Flags, POLYGON_TYPE), Polygon->BoundingBox.X1, Polygon->BoundingBox.Y1, Polygon->BoundingBox.X2, Polygon->BoundingBox.Y2, Polygon->PointN, Polygon->PointMax - Polygon->PointN, Polygon->HoleIndexN, GetLayerNumber (PCB->Data, (LayerType *) ptr1), TEST_FLAG (LOCKFLAG, Polygon) ? _("It is LOCKED.\n") : ""); break; } case PAD_TYPE: { Coord len; PadType *Pad; ElementType *element; #ifndef NDEBUG if (gui->shift_is_pressed ()) { __r_dump_tree (PCB->Data->pad_tree->root, 0); return 0; } #endif Pad = (PadType *) ptr2; element = (ElementType *) ptr1; PAD_LOOP (element); { { if (pad == Pad) break; } } END_LOOP; len = Distance (Pad->Point1.X, Pad->Point1.Y, Pad->Point2.X, Pad->Point2.Y); pcb_snprintf (report, sizeof (report), _("%m+PAD ID# %ld; Flags:%s\n" "FirstPoint(X,Y) = %$mD; ID = %ld.\n" "SecondPoint(X,Y) = %$mD; ID = %ld.\n" "Width = %$mS. Length = %$mS.\n" "Clearance width in polygons = %$mS.\n" "Solder mask = %$mS x %$mS (gap = %$mS).\n" "Name = \"%s\".\n" "It is owned by SMD element %s\n" " as pin number %s and is on the %s\n" "side of the board.\n" "%s"), USER_UNITMASK, Pad->ID, flags_to_string (Pad->Flags, PAD_TYPE), Pad->Point1.X, Pad->Point1.Y, Pad->Point1.ID, Pad->Point2.X, Pad->Point2.Y, Pad->Point2.ID, Pad->Thickness, len + Pad->Thickness, Pad->Clearance / 2, Pad->Mask, len + Pad->Mask, (Pad->Mask - Pad->Thickness) / 2, EMPTY (Pad->Name), EMPTY (element->Name[1].TextString), EMPTY (Pad->Number), TEST_FLAG (ONSOLDERFLAG, Pad) ? _("solder (bottom)") : _("component"), TEST_FLAG (LOCKFLAG, Pad) ? _("It is LOCKED.\n") : ""); break; } case ELEMENT_TYPE: { ElementType *element; #ifndef NDEBUG if (gui->shift_is_pressed ()) { __r_dump_tree (PCB->Data->element_tree->root, 0); return 0; } #endif element = (ElementType *) ptr2; pcb_snprintf (report, sizeof (report), _("%m+ELEMENT ID# %ld; Flags:%s\n" "BoundingBox %$mD %$mD.\n" "Descriptive Name \"%s\".\n" "Name on board \"%s\".\n" "Part number name \"%s\".\n" "It is %$mS tall and is located at (X,Y) = %$mD %s.\n" "Mark located at point (X,Y) = %$mD.\n" "It is on the %s side of the board.\n" "%s"), USER_UNITMASK, element->ID, flags_to_string (element->Flags, ELEMENT_TYPE), element->BoundingBox.X1, element->BoundingBox.Y1, element->BoundingBox.X2, element->BoundingBox.Y2, EMPTY (element->Name[0].TextString), EMPTY (element->Name[1].TextString), EMPTY (element->Name[2].TextString), SCALE_TEXT (FONT_CAPHEIGHT, element->Name[1].Scale), element->Name[1].X, element->Name[1].Y, TEST_FLAG (HIDENAMEFLAG, element) ? _(",\n but it's hidden") : "", element->MarkX, element->MarkY, TEST_FLAG (ONSOLDERFLAG, element) ? _("solder (bottom)") : _("component"), TEST_FLAG (LOCKFLAG, element) ? _("It is LOCKED.\n") : ""); break; } case TEXT_TYPE: #ifndef NDEBUG if (gui->shift_is_pressed ()) { LayerType *layer = (LayerType *) ptr1; __r_dump_tree (layer->text_tree->root, 0); return 0; } #endif case ELEMENTNAME_TYPE: { char laynum[32]; TextType *text; #ifndef NDEBUG if (gui->shift_is_pressed ()) { __r_dump_tree (PCB->Data->name_tree[NAME_INDEX (PCB)]->root, 0); return 0; } #endif text = (TextType *) ptr2; if (type == TEXT_TYPE) sprintf (laynum, _("It is on layer %d."), GetLayerNumber (PCB->Data, (LayerType *) ptr1)); pcb_snprintf (report, sizeof (report), _("%m+TEXT ID# %ld; Flags:%s\n" "Located at (X,Y) = %$mD.\n" "Characters are %$mS tall.\n" "Value is \"%s\".\n" "Direction is %d.\n" "The bounding box is %$mD %$mD.\n" "%s\n" "%s"), USER_UNITMASK, text->ID, flags_to_string (text->Flags, TEXT_TYPE), text->X, text->Y, SCALE_TEXT (FONT_CAPHEIGHT, text->Scale), text->TextString, text->Direction, text->BoundingBox.X1, text->BoundingBox.Y1, text->BoundingBox.X2, text->BoundingBox.Y2, (type == TEXT_TYPE) ? laynum : _("It is an element name."), TEST_FLAG (LOCKFLAG, text) ? _("It is LOCKED.\n") : ""); break; } case LINEPOINT_TYPE: case POLYGONPOINT_TYPE: { PointType *point = (PointType *) ptr2; pcb_snprintf (report, sizeof (report), _("%m+POINT ID# %ld.\n" "Located at (X,Y) = %$mD.\n" "It belongs to a %s on layer %d.\n"), USER_UNITMASK, point->ID, point->X, point->Y, (type == LINEPOINT_TYPE) ? C_("report", "line") : C_("report", "polygon"), GetLayerNumber (PCB->Data, (LayerType *) ptr1)); break; } case NO_TYPE: report[0] = '\0'; break; default: sprintf (report, _("Unknown\n")); break; } if (report[0] == '\0') { Message (_("Nothing found to report on\n")); return 1; } /* create dialog box */ gui->report_dialog (_("Report"), report); return 0; }
static int ReportDialog (int argc, char **argv, int x, int y) { void *ptr1, *ptr2, *ptr3; int type, prec = Settings.grid_units_mm? 4: 2; char report[2048]; type = SearchScreen (x, y, REPORT_TYPES, &ptr1, &ptr2, &ptr3); if (type == NO_TYPE) type = SearchScreen (x, y, REPORT_TYPES | LOCKED_TYPE, &ptr1, &ptr2, &ptr3); switch (type) { case VIA_TYPE: { PinTypePtr via; #ifndef NDEBUG if (gui->shift_is_pressed ()) { __r_dump_tree (PCB->Data->via_tree->root, 0); return 0; } #endif via = (PinTypePtr) ptr2; if (TEST_FLAG (HOLEFLAG, via)) sprintf (&report[0], "VIA ID# %ld; Flags:%s\n" "(X,Y) = (%.*f, %.*f) %s.\n" "It is a pure hole of diameter %.*f %s.\n" "Name = \"%s\"." "%s", via->ID, flags_to_string (via->Flags, VIA_TYPE), prec, units (via->X), prec, UNIT (via->Y), prec, UNIT (via->DrillingHole), EMPTY (via->Name), TEST_FLAG (LOCKFLAG, via) ? "It is LOCKED.\n" : ""); else sprintf (&report[0], "VIA ID# %ld; Flags:%s\n" "(X,Y) = (%.*f, %.*f) %s.\n" "Copper width = %0.*f %s. Drill width = %0.*f %s.\n" "Clearance width in polygons = %0.*f %s.\n" "Annulus = %0.*f %s.\n" "Solder mask hole = %0.*f %s (gap = %0.*f %s).\n" "Name = \"%s\"." "%s", via->ID, flags_to_string (via->Flags, VIA_TYPE), prec, units (via->X), prec, UNIT (via->Y), prec, UNIT (via->Thickness), prec, UNIT (via->DrillingHole), prec, UNIT (via->Clearance / 2.), prec, UNIT ((via->Thickness - via->DrillingHole)/2), prec, UNIT (via->Mask), prec, UNIT ((via->Mask - via->Thickness)/2), EMPTY (via->Name), TEST_FLAG (LOCKFLAG, via) ? "It is LOCKED.\n" : ""); break; } case PIN_TYPE: { PinTypePtr Pin; ElementTypePtr element; #ifndef NDEBUG if (gui->shift_is_pressed ()) { __r_dump_tree (PCB->Data->pin_tree->root, 0); return 0; } #endif Pin = (PinTypePtr) ptr2; element = (ElementTypePtr) ptr1; PIN_LOOP (element); { if (pin == Pin) break; } END_LOOP; if (TEST_FLAG (HOLEFLAG, Pin)) sprintf (&report[0], "PIN ID# %ld; Flags:%s\n" "(X,Y) = (%.*f, %.*f) %s.\n" "It is a mounting hole. Drill width = %0.*f %s.\n" "It is owned by element %s.\n" "%s", Pin->ID, flags_to_string (Pin->Flags, PIN_TYPE), prec, units (Pin->X), prec, UNIT (Pin->Y), prec, UNIT (Pin->DrillingHole), EMPTY (element->Name[1].TextString), TEST_FLAG (LOCKFLAG, Pin) ? "It is LOCKED.\n" : ""); else sprintf (&report[0], "PIN ID# %ld; Flags:%s\n" "(X,Y) = (%.*f, %.*f) %s.\n" "Copper width = %0.*f %s. Drill width = %0.*f %s.\n" "Clearance width to Polygon = %0.*f %s.\n" "Annulus = %0.*f %s.\n" "Solder mask hole = %0.*f %s (gap = %0.*f %s).\n" "Name = \"%s\".\n" "It is owned by element %s\n as pin number %s.\n" "%s", Pin->ID, flags_to_string (Pin->Flags, PIN_TYPE), prec, units(Pin->X), prec, UNIT(Pin->Y), prec, UNIT (Pin->Thickness), prec, UNIT (Pin->DrillingHole), prec, UNIT (Pin->Clearance / 2.), prec, UNIT ((Pin->Thickness - Pin->DrillingHole)/2), prec, UNIT (Pin->Mask), prec, UNIT ((Pin->Mask - Pin->Thickness)/2), EMPTY (Pin->Name), EMPTY (element->Name[1].TextString), EMPTY (Pin->Number), TEST_FLAG (LOCKFLAG, Pin) ? "It is LOCKED.\n" : ""); break; } case LINE_TYPE: { LineTypePtr line; #ifndef NDEBUG if (gui->shift_is_pressed ()) { LayerTypePtr layer = (LayerTypePtr) ptr1; __r_dump_tree (layer->line_tree->root, 0); return 0; } #endif line = (LineTypePtr) ptr2; sprintf (&report[0], "LINE ID# %ld; Flags:%s\n" "FirstPoint(X,Y) = (%.*f, %.*f) %s, ID = %ld.\n" "SecondPoint(X,Y) = (%.*f, %.*f) %s, ID = %ld.\n" "Width = %0.*f %s.\nClearance width in polygons = %0.*f %s.\n" "It is on layer %d\n" "and has name \"%s\".\n" "%s", line->ID, flags_to_string (line->Flags, LINE_TYPE), prec, units (line->Point1.X), prec, UNIT (line->Point1.Y), line->Point1.ID, prec, units (line->Point2.X), prec, UNIT (line->Point2.Y), line->Point2.ID, prec, UNIT (line->Thickness), prec, UNIT (line->Clearance / 2.), GetLayerNumber (PCB->Data, (LayerTypePtr) ptr1), UNKNOWN (line->Number), TEST_FLAG (LOCKFLAG, line) ? "It is LOCKED.\n" : ""); break; } case RATLINE_TYPE: { RatTypePtr line; #ifndef NDEBUG if (gui->shift_is_pressed ()) { __r_dump_tree (PCB->Data->rat_tree->root, 0); return 0; } #endif line = (RatTypePtr) ptr2; sprintf (&report[0], "RAT-LINE ID# %ld; Flags:%s\n" "FirstPoint(X,Y) = (%.*f, %.*f) %s; ID = %ld; " "connects to layer group %d.\n" "SecondPoint(X,Y) = (%.*f, %.*f) %s; ID = %ld; " "connects to layer group %d.\n", line->ID, flags_to_string (line->Flags, LINE_TYPE), prec, units (line->Point1.X), prec, UNIT (line->Point1.Y), line->Point1.ID, line->group1, prec, units (line->Point2.X), prec, UNIT (line->Point2.Y), line->Point2.ID, line->group2); break; } case ARC_TYPE: { ArcTypePtr Arc; BoxTypePtr box; #ifndef NDEBUG if (gui->shift_is_pressed ()) { LayerTypePtr layer = (LayerTypePtr) ptr1; __r_dump_tree (layer->arc_tree->root, 0); return 0; } #endif Arc = (ArcTypePtr) ptr2; box = GetArcEnds (Arc); sprintf (&report[0], "ARC ID# %ld; Flags:%s\n" "CenterPoint(X,Y) = (%.*f, %.*f) %s.\n" "Radius = %0.*f %s, Thickness = %0.*f %s.\n" "Clearance width in polygons = %0.*f %s.\n" "StartAngle = %ld degrees, DeltaAngle = %ld degrees.\n" "Bounding Box is (%.*f,%.*f), (%.*f,%.*f) %s.\n" "That makes the end points at (%.*f,%.*f) %s and (%.*f,%.*f) %s.\n" "It is on layer %d.\n" "%s", Arc->ID, flags_to_string (Arc->Flags, ARC_TYPE), prec, units(Arc->X), prec, UNIT(Arc->Y), prec, UNIT (Arc->Width), prec, UNIT (Arc->Thickness), prec, UNIT (Arc->Clearance / 2.), Arc->StartAngle, Arc->Delta, prec, units (Arc->BoundingBox.X1), prec, units (Arc->BoundingBox.Y1), prec, units (Arc->BoundingBox.X2), prec, UNIT (Arc->BoundingBox.Y2), prec, units (box->X1), prec, UNIT (box->Y1), prec, units (box->X2), prec, UNIT (box->Y2), GetLayerNumber (PCB->Data, (LayerTypePtr) ptr1), TEST_FLAG (LOCKFLAG, Arc) ? "It is LOCKED.\n" : ""); break; } case POLYGON_TYPE: { PolygonTypePtr Polygon; #ifndef NDEBUG if (gui->shift_is_pressed ()) { LayerTypePtr layer = (LayerTypePtr) ptr1; __r_dump_tree (layer->polygon_tree->root, 0); return 0; } #endif Polygon = (PolygonTypePtr) ptr2; sprintf (&report[0], "POLYGON ID# %ld; Flags:%s\n" "Its bounding box is (%.*f,%.*f) (%.*f,%.*f) %s.\n" "It has %d points and could store %d more\n" " without using more memory.\n" "It has %d holes and resides on layer %d.\n" "%s", Polygon->ID, flags_to_string (Polygon->Flags, POLYGON_TYPE), prec, units(Polygon->BoundingBox.X1), prec, units(Polygon->BoundingBox.Y1), prec, units(Polygon->BoundingBox.X2), prec, UNIT(Polygon->BoundingBox.Y2), Polygon->PointN, Polygon->PointMax - Polygon->PointN, Polygon->HoleIndexN, GetLayerNumber (PCB->Data, (LayerTypePtr) ptr1), TEST_FLAG (LOCKFLAG, Polygon) ? "It is LOCKED.\n" : ""); break; } case PAD_TYPE: { int len, dx, dy, mgap; PadTypePtr Pad; ElementTypePtr element; #ifndef NDEBUG if (gui->shift_is_pressed ()) { __r_dump_tree (PCB->Data->pad_tree->root, 0); return 0; } #endif Pad = (PadTypePtr) ptr2; element = (ElementTypePtr) ptr1; PAD_LOOP (element); { { if (pad == Pad) break; } } END_LOOP; dx = Pad->Point1.X - Pad->Point2.X; dy = Pad->Point1.Y - Pad->Point2.Y; len = sqrt (dx*dx+dy*dy); mgap = (Pad->Mask - Pad->Thickness)/2; sprintf (&report[0], "PAD ID# %ld; Flags:%s\n" "FirstPoint(X,Y) = (%.*f, %.*f) %s; ID = %ld.\n" "SecondPoint(X,Y) = (%.*f, %.*f) %s; ID = %ld.\n" "Width = %0.*f %s. Length = %0.*f %s.\n" "Clearance width in polygons = %0.*f %s.\n" "Solder mask = %0.*f x %0.*f %s (gap = %0.*f %s).\n" "Name = \"%s\".\n" "It is owned by SMD element %s\n" " as pin number %s and is on the %s\n" "side of the board.\n" "%s", Pad->ID, flags_to_string (Pad->Flags, PAD_TYPE), prec, units (Pad->Point1.X), prec, UNIT (Pad->Point1.Y), Pad->Point1.ID, prec, units (Pad->Point2.X), prec, UNIT (Pad->Point2.Y), Pad->Point2.ID, prec, UNIT (Pad->Thickness), prec, UNIT (len + Pad->Thickness), prec, UNIT (Pad->Clearance / 2.), prec, units (Pad->Mask), prec, UNIT (Pad->Mask + len), prec, UNIT (mgap), EMPTY (Pad->Name), EMPTY (element->Name[1].TextString), EMPTY (Pad->Number), TEST_FLAG (ONSOLDERFLAG, Pad) ? "solder (bottom)" : "component", TEST_FLAG (LOCKFLAG, Pad) ? "It is LOCKED.\n" : ""); break; } case ELEMENT_TYPE: { ElementTypePtr element; #ifndef NDEBUG if (gui->shift_is_pressed ()) { __r_dump_tree (PCB->Data->element_tree->root, 0); return 0; } #endif element = (ElementTypePtr) ptr2; sprintf (&report[0], "ELEMENT ID# %ld; Flags:%s\n" "BoundingBox (%.*f,%.*f) (%.*f,%.*f) %s.\n" "Descriptive Name \"%s\".\n" "Name on board \"%s\".\n" "Part number name \"%s\".\n" "It is %.*f %s tall and is located at (X,Y) = (%.*f,%.*f)%s.\n" "Mark located at point (X,Y) = (%.*f,%.*f).\n" "It is on the %s side of the board.\n" "%s", element->ID, flags_to_string (element->Flags, ELEMENT_TYPE), prec, units(element->BoundingBox.X1), prec, units (element->BoundingBox.Y1), prec, units(element->BoundingBox.X2), prec, UNIT (element->BoundingBox.Y2), EMPTY (element->Name[0].TextString), EMPTY (element->Name[1].TextString), EMPTY (element->Name[2].TextString), prec, UNIT (0.45 * element->Name[1].Scale * 100.), prec, units(element->Name[1].X), prec, units(element->Name[1].Y), TEST_FLAG (HIDENAMEFLAG, element) ? ",\n but it's hidden" : "", prec, units(element->MarkX), prec, units(element->MarkY), TEST_FLAG (ONSOLDERFLAG, element) ? "solder (bottom)" : "component", TEST_FLAG (LOCKFLAG, element) ? "It is LOCKED.\n" : ""); break; } case TEXT_TYPE: #ifndef NDEBUG if (gui->shift_is_pressed ()) { LayerTypePtr layer = (LayerTypePtr) ptr1; __r_dump_tree (layer->text_tree->root, 0); return 0; } #endif case ELEMENTNAME_TYPE: { char laynum[32]; TextTypePtr text; #ifndef NDEBUG if (gui->shift_is_pressed ()) { __r_dump_tree (PCB->Data->name_tree[NAME_INDEX (PCB)]->root, 0); return 0; } #endif text = (TextTypePtr) ptr2; if (type == TEXT_TYPE) sprintf (laynum, "It is on layer %d.", GetLayerNumber (PCB->Data, (LayerTypePtr) ptr1)); sprintf (&report[0], "TEXT ID# %ld; Flags:%s\n" "Located at (X,Y) = (%.*f,%.*f) %s.\n" "Characters are %0.*f %s tall.\n" "Value is \"%s\".\n" "Direction is %d.\n" "The bounding box is (%.*f,%.*f) (%.*f, %.*f) %s.\n" "%s\n" "%s", text->ID, flags_to_string (text->Flags, TEXT_TYPE), prec, units(text->X), prec, UNIT (text->Y), prec, UNIT (0.45 * text->Scale * 100.), text->TextString, text->Direction, prec, units(text->BoundingBox.X1), prec, units(text->BoundingBox.Y1), prec, units(text->BoundingBox.X2), prec, UNIT (text->BoundingBox.Y2), (type == TEXT_TYPE) ? laynum : "It is an element name.", TEST_FLAG (LOCKFLAG, text) ? "It is LOCKED.\n" : ""); break; } case LINEPOINT_TYPE: case POLYGONPOINT_TYPE: { PointTypePtr point = (PointTypePtr) ptr2; sprintf (&report[0], "POINT ID# %ld.\n" "Located at (X,Y) = (%.*f,%.*f) %s.\n" "It belongs to a %s on layer %d.\n", point->ID, prec, units (point->X), prec, UNIT (point->Y), (type == LINEPOINT_TYPE) ? "line" : "polygon", GetLayerNumber (PCB->Data, (LayerTypePtr) ptr1)); break; } case NO_TYPE: report[0] = '\0'; break; default: sprintf (&report[0], "Unknown\n"); break; } if (report[0] == '\0') { Message (_("Nothing found to report on\n")); return 1; } HideCrosshair (false); /* create dialog box */ gui->report_dialog ("Report", &report[0]); RestoreCrosshair (false); return 0; }
/* * AlignText(X, [Lefts/Rights/Centers, [First/Last/Crosshair/Average[, Gridless]]]) * AlignText(Y, [Tops/Bottoms/Centers, [First/Last/Crosshair/Average[, Gridless]]]) * * X or Y - Select which axis will move, other is untouched * Lefts, Rights, * Tops, Bottoms, * Centers - Pick alignment point within each element. * NB: text objects have no Mark * First, Last, * Crosshair, * Average - Alignment reference, First=Topmost/Leftmost, * Last=Bottommost/Rightmost, Average or Crosshair point * Gridless - Do not force results to align to prevailing grid * * Defaults are Lefts/Tops, First */ static int aligntext(int argc, char **argv, Coord x, Coord y) { int dir; int point; int reference; int gridless; Coord q; Coord p, dp, dx, dy; int changed = 0; if (argc < 1 || argc > 4) { AFAIL(aligntext); } /* parse direction arg */ switch ((dir = keyword(ARG(0)))) { case K_X: case K_Y: break; default: AFAIL(aligntext); } /* parse point (within each element) which will be aligned */ switch ((point = keyword(ARG(1)))) { case K_Centers: break; case K_Lefts: case K_Rights: if (dir == K_Y) { AFAIL(aligntext); } break; case K_Tops: case K_Bottoms: if (dir == K_X) { AFAIL(aligntext); } break; case K_none: /* default value */ if (dir == K_X) { point = K_Lefts; } else { point = K_Tops; } break; default: AFAIL(aligntext); } /* parse reference which will determine alignment coordinates */ switch ((reference = keyword(ARG(2)))) { case K_First: case K_Last: case K_Average: case K_Crosshair: break; case K_none: reference = K_First; /* default value */ break; default: AFAIL(aligntext); } /* optionally work off the grid (solar cells!) */ switch (keyword(ARG(3))) { case K_Gridless: gridless = 1; break; case K_none: gridless = 0; break; default: AFAIL(aligntext); } SaveUndoSerialNumber(); /* find the final alignment coordinate using the above options */ q = reference_coord(K_aligntext, Crosshair.X, Crosshair.Y, dir, point, reference); /* move all selected elements to the new coordinate */ /* selected text part of an element */ ELEMENT_LOOP(PCB->Data); { TextType *text; text = &(element)->Name[NAME_INDEX(PCB)]; if (! TEST_FLAG (SELECTEDFLAG, text)) continue; /* find delta from reference point to reference point */ p = coord(text, dir, point); dp = q - p; /* ...but if we're gridful, keep the mark on the grid */ /* TODO re-enable for text, need textcoord() if (! gridless) { dp -= (coord(text, dir, K_Marks) + dp) % (long) (PCB->Grid); } */ if (dp) { /* move from generic to X or Y */ dx = dy = dp; if (dir == K_X) dy = 0; else dx = 0; MoveObject(ELEMENTNAME_TYPE, element, text, text, dx, dy); changed = 1; } } END_LOOP; /* Selected bare text objects */ ALLTEXT_LOOP (PCB->Data); { if (TEST_FLAG (SELECTEDFLAG, text)) { /* find delta from reference point to reference point */ p = coord(text, dir, point); dp = q - p; /* ...but if we're gridful, keep the mark on the grid */ /* TODO re-enable for text, need textcoord() if (! gridless) { dp -= (coord(text, dir, K_Marks) + dp) % (long) (PCB->Grid); } */ if (dp) { /* move from generic to X or Y */ dx = dy = dp; if (dir == K_X) dy = 0; else dx = 0; MoveObject(TEXT_TYPE, layer, text, text, dx, dy); changed = 1; } } } ENDALL_LOOP; if (changed) { RestoreUndoSerialNumber(); IncrementUndoSerialNumber(); Redraw(); SetChangedFlag(true); } free_texts_by_pos(); return 0; }
/* * Find all selected text objects, then order them in order by coordinate in * the 'dir' axis. This is used to find the "First" and "Last" elements * and also to choose the distribution order. * * For alignment, first and last are in the orthogonal axis (imagine if * you were lining up letters in a sentence, aligning *vertically* to the * first letter means selecting the first letter *horizontally*). * * For distribution, first and last are in the distribution axis. */ static int sort_texts_by_pos(int op, int dir, int point) { int nsel = 0; if (ntexts_by_pos) return ntexts_by_pos; if (op == K_aligntext) dir = dir == K_X ? K_Y : K_X; /* see above */ ELEMENT_LOOP(PCB->Data); { TextType *text; text = &(element)->Name[NAME_INDEX(PCB)]; if (! TEST_FLAG (SELECTEDFLAG, text)) continue; nsel++; } END_LOOP; ALLTEXT_LOOP (PCB->Data); { if (! TEST_FLAG (SELECTEDFLAG, text)) continue; nsel++; } ENDALL_LOOP; if (! nsel) return 0; texts_by_pos = malloc(nsel * sizeof(*texts_by_pos)); ntexts_by_pos = nsel; nsel = 0; ELEMENT_LOOP(PCB->Data); { TextType *text; text = &(element)->Name[NAME_INDEX(PCB)]; if (! TEST_FLAG (SELECTEDFLAG, text)) continue; texts_by_pos[nsel].text = text; texts_by_pos[nsel].type = ELEMENTNAME_TYPE; texts_by_pos[nsel++].pos = coord(text, dir, point); } END_LOOP; ALLTEXT_LOOP (PCB->Data); { if (! TEST_FLAG (SELECTEDFLAG, text)) continue; texts_by_pos[nsel].text = text; texts_by_pos[nsel].type = TEXT_TYPE; texts_by_pos[nsel++].pos = coord(text, dir, point); } ENDALL_LOOP; qsort(texts_by_pos, ntexts_by_pos, sizeof(*texts_by_pos), cmp_tbp); return ntexts_by_pos; }
/* --------------------------------------------------------------------------- * 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 (); } }