void *ChangeViaSize( PinTypePtr Via ) { int eax; int ebx; int esi; BDimension value = Absolute; if ( value > 0x989680 || ( ( Via->Flags.f & 8 ) & 255 ) || value <= 1999 || value <= Via->DrillingHole + 399 || Via->Thickness == value ) { } AddObjectToSizeUndoList( 1, (void*)Via, (void*)Via, (void*)Via ); EraseVia( Via ); r_delete_entry( &PCB->Data->via_tree, (int)( &Via->BoundingBox ) ); RestoreToPolygon( &PCB->Data, 256, (void*)Via, (void*)Via ); if ( Via->Mask ) { AddObjectToMaskSizeUndoList( 1, (void*)Via, (void*)Via, (void*)Via ); Via->Mask = ( Via->Mask + value ) - Via->Thickness; } Via->Thickness = value; SetPinBoundingBox( Via ); r_insert_entry( &PCB->Data->via_tree, (int)( &Via->BoundingBox ), 0 ); ClearFromPolygon( &PCB->Data, 1, (void*)Via, (void*)Via ); DrawVia( Via, 0 ); return (void*)Via; }
void *ChangeViaClearSize( PinTypePtr Via ) { int eax; int ecx; int ebx; int esi; BDimension value = Absolute; if ( ( Via->Flags.f & 8192 ) == 0 ) { value = ( value <= 0x989680 ? 0x989680 : value ) < 0 ? value <= 0x989680 ? 10000000 : value : Via->Flags.f & 8192; if ( Delta < 0 ) value = value < ( PCB->Bloat * 2 ) ? value : Via->Flags.f & 8192; else if ( !1 ) value = value < ( PCB->Bloat * 2 ) ? value : ( PCB->Bloat + 1 ) * 2; if ( Via->Clearance != value ) { RestoreToPolygon( &PCB->Data, 1, (void*)Via, (void*)Via ); AddObjectToClearSizeUndoList( 1, (void*)Via, (void*)Via, (void*)Via ); EraseVia( Via ); r_delete_entry( &PCB->Data->via_tree, (int)( &Via->BoundingBox ) ); Via->Clearance = value; SetPinBoundingBox( Via ); r_insert_entry( &PCB->Data->via_tree, (int)( &Via->BoundingBox ), 0 ); ClearFromPolygon( &PCB->Data, 1, (void*)Via, (void*)Via ); DrawVia( Via, 0 ); Via->Element = 0; return (void*)Via; } } return 0; }
void FreeRotateElementLowLevel (DataType *Data, ElementType *Element, Coord X, Coord Y, double cosa, double sina, Angle angle) { /* solder side objects need a different orientation */ /* the text subroutine decides by itself if the direction * is to be corrected */ #if 0 ELEMENTTEXT_LOOP (Element); { if (Data && Data->name_tree[n]) r_delete_entry (Data->name_tree[n], (BoxType *)text); RotateTextLowLevel (text, X, Y, Number); } END_LOOP; #endif ELEMENTLINE_LOOP (Element); { free_rotate (&line->Point1.X, &line->Point1.Y, X, Y, cosa, sina); free_rotate (&line->Point2.X, &line->Point2.Y, X, Y, cosa, sina); SetLineBoundingBox (line); } END_LOOP; PIN_LOOP (Element); { /* pre-delete the pins from the pin-tree before their coordinates change */ if (Data) r_delete_entry (Data->pin_tree, (BoxType *)pin); RestoreToPolygon (Data, PIN_TYPE, Element, pin); free_rotate (&pin->X, &pin->Y, X, Y, cosa, sina); SetPinBoundingBox (pin); } END_LOOP; PAD_LOOP (Element); { /* pre-delete the pads before their coordinates change */ if (Data) r_delete_entry (Data->pad_tree, (BoxType *)pad); RestoreToPolygon (Data, PAD_TYPE, Element, pad); free_rotate (&pad->Point1.X, &pad->Point1.Y, X, Y, cosa, sina); free_rotate (&pad->Point2.X, &pad->Point2.Y, X, Y, cosa, sina); SetLineBoundingBox ((LineType *) pad); } END_LOOP; ARC_LOOP (Element); { free_rotate (&arc->X, &arc->Y, X, Y, cosa, sina); arc->StartAngle = NormalizeAngle (arc->StartAngle + angle); } END_LOOP; free_rotate (&Element->MarkX, &Element->MarkY, X, Y, cosa, sina); SetElementBoundingBox (Data, Element, &PCB->Font); ClearFromPolygon (Data, ELEMENT_TYPE, Element, Element); }
/* --------------------------------------------------------------------------- * rotates the contents of the pastebuffer */ void RotateBuffer (BufferType *Buffer, BYTE Number) { /* rotate vias */ VIA_LOOP (Buffer->Data); { r_delete_entry (Buffer->Data->via_tree, (BoxType *)via); ROTATE_VIA_LOWLEVEL (via, Buffer->X, Buffer->Y, Number); SetPinBoundingBox (via); r_insert_entry (Buffer->Data->via_tree, (BoxType *)via, 0); } END_LOOP; /* elements */ ELEMENT_LOOP (Buffer->Data); { RotateElementLowLevel (Buffer->Data, element, Buffer->X, Buffer->Y, Number); } END_LOOP; /* all layer related objects */ ALLLINE_LOOP (Buffer->Data); { r_delete_entry (layer->line_tree, (BoxType *)line); RotateLineLowLevel (line, Buffer->X, Buffer->Y, Number); r_insert_entry (layer->line_tree, (BoxType *)line, 0); } ENDALL_LOOP; ALLARC_LOOP (Buffer->Data); { r_delete_entry (layer->arc_tree, (BoxType *)arc); RotateArcLowLevel (arc, Buffer->X, Buffer->Y, Number); r_insert_entry (layer->arc_tree, (BoxType *)arc, 0); } ENDALL_LOOP; ALLTEXT_LOOP (Buffer->Data); { r_delete_entry (layer->text_tree, (BoxType *)text); RotateTextLowLevel (text, Buffer->X, Buffer->Y, Number); r_insert_entry (layer->text_tree, (BoxType *)text, 0); } ENDALL_LOOP; ALLPOLYGON_LOOP (Buffer->Data); { r_delete_entry (layer->polygon_tree, (BoxType *)polygon); RotatePolygonLowLevel (polygon, Buffer->X, Buffer->Y, Number); r_insert_entry (layer->polygon_tree, (BoxType *)polygon, 0); } ENDALL_LOOP; /* finally the origin and the bounding box */ ROTATE (Buffer->X, Buffer->Y, Buffer->X, Buffer->Y, Number); RotateBoxLowLevel (&Buffer->BoundingBox, Buffer->X, Buffer->Y, Number); SetCrosshairRangeToBuffer (); }
/* --------------------------------------------------------------------------- * creates a new via */ PinTypePtr CreateNewVia (DataTypePtr Data, LocationType X, LocationType Y, BDimension Thickness, BDimension Clearance, BDimension Mask, BDimension DrillingHole, char *Name, FlagType Flags) { PinTypePtr Via; if (!be_lenient) { VIA_LOOP (Data); { if (SQUARE (via->X - X) + SQUARE (via->Y - Y) <= SQUARE (via->DrillingHole / 2 + DrillingHole / 2)) { Message (_("Dropping via at (%d, %d) because it's hole would overlap with the via " "at (%d, %d)\n"), X/100, Y/100, via->X/100, via->Y/100); return (NULL); /* don't allow via stacking */ } } END_LOOP; } Via = GetViaMemory (Data); if (!Via) return (Via); /* copy values */ Via->X = X; Via->Y = Y; Via->Thickness = Thickness; Via->Clearance = Clearance; Via->Mask = Mask; Via->DrillingHole = vendorDrillMap (DrillingHole); if (Via->DrillingHole != DrillingHole) { Message (_ ("Mapped via drill hole to %.2f mils from %.2f mils per vendor table\n"), 0.01 * Via->DrillingHole, 0.01 * DrillingHole); } Via->Name = STRDUP (Name); Via->Flags = Flags; CLEAR_FLAG (WARNFLAG, Via); SET_FLAG (VIAFLAG, Via); Via->ID = ID++; /* * don't complain about MIN_PINORVIACOPPER on a mounting hole (pure * hole) */ if (!TEST_FLAG (HOLEFLAG, Via) && (Via->Thickness < Via->DrillingHole + MIN_PINORVIACOPPER)) { Via->Thickness = Via->DrillingHole + MIN_PINORVIACOPPER; Message (_("Increased via thickness to %.2f mils to allow enough copper" " at (%.2f,%.2f).\n"), 0.01 * Via->Thickness, 0.01 * Via->X, 0.01 * Via->Y); } SetPinBoundingBox (Via); if (!Data->via_tree) Data->via_tree = r_create_tree (NULL, 0, 0); r_insert_entry (Data->via_tree, (BoxTypePtr) Via, 0); return (Via); }
/*! * \brief Creates a new via. */ PinType * CreateNewVia (DataType *Data, Coord X, Coord Y, Coord Thickness, Coord Clearance, Coord Mask, Coord DrillingHole, char *Name, FlagType Flags) { PinType *Via; if (!be_lenient) { VIA_LOOP (Data); { if (Distance (X, Y, via->X, via->Y) <= via->DrillingHole / 2 + DrillingHole / 2) { Message (_("%m+Dropping via at %$mD because it's hole would overlap with the via " "at %$mD\n"), Settings.grid_unit->allow, X, Y, via->X, via->Y); return (NULL); /* don't allow via stacking */ } } END_LOOP; } Via = GetViaMemory (Data); if (!Via) return (Via); /* copy values */ Via->X = X; Via->Y = Y; Via->Thickness = Thickness; Via->Clearance = Clearance; Via->Mask = Mask; Via->DrillingHole = vendorDrillMap (DrillingHole); if (Via->DrillingHole != DrillingHole) { Message (_("%m+Mapped via drill hole to %$mS from %$mS per vendor table\n"), Settings.grid_unit->allow, Via->DrillingHole, DrillingHole); } Via->Name = STRDUP (Name); Via->Flags = Flags; CLEAR_FLAG (WARNFLAG, Via); SET_FLAG (VIAFLAG, Via); Via->ID = ID++; /* * don't complain about MIN_PINORVIACOPPER on a mounting hole (pure * hole) */ if (!TEST_FLAG (HOLEFLAG, Via) && (Via->Thickness < Via->DrillingHole + MIN_PINORVIACOPPER)) { Via->Thickness = Via->DrillingHole + MIN_PINORVIACOPPER; Message (_("%m+Increased via thickness to %$mS to allow enough copper" " at %$mD.\n"), Settings.grid_unit->allow, Via->Thickness, Via->X, Via->Y); } SetPinBoundingBox (Via); if (!Data->via_tree) Data->via_tree = r_create_tree (NULL, 0, 0); r_insert_entry (Data->via_tree, (BoxType *) Via, 0); return (Via); }
/* --------------------------------------------------------------------------- * flip components/tracks from one side to the other */ static void SwapBuffer (BufferType *Buffer) { int j, k; Cardinal sgroup, cgroup; LayerType swap; ELEMENT_LOOP (Buffer->Data); { r_delete_element (Buffer->Data, element); MirrorElementCoordinates (Buffer->Data, element, 0); } END_LOOP; /* set buffer offset to 'mark' position */ Buffer->X = SWAP_X (Buffer->X); Buffer->Y = SWAP_Y (Buffer->Y); VIA_LOOP (Buffer->Data); { r_delete_entry (Buffer->Data->via_tree, (BoxType *)via); via->X = SWAP_X (via->X); via->Y = SWAP_Y (via->Y); SetPinBoundingBox (via); r_insert_entry (Buffer->Data->via_tree, (BoxType *)via, 0); } END_LOOP; ALLLINE_LOOP (Buffer->Data); { r_delete_entry (layer->line_tree, (BoxType *)line); line->Point1.X = SWAP_X (line->Point1.X); line->Point1.Y = SWAP_Y (line->Point1.Y); line->Point2.X = SWAP_X (line->Point2.X); line->Point2.Y = SWAP_Y (line->Point2.Y); SetLineBoundingBox (line); r_insert_entry (layer->line_tree, (BoxType *)line, 0); } ENDALL_LOOP; ALLARC_LOOP (Buffer->Data); { r_delete_entry (layer->arc_tree, (BoxType *)arc); arc->X = SWAP_X (arc->X); arc->Y = SWAP_Y (arc->Y); arc->StartAngle = SWAP_ANGLE (arc->StartAngle); arc->Delta = SWAP_DELTA (arc->Delta); SetArcBoundingBox (arc); r_insert_entry (layer->arc_tree, (BoxType *)arc, 0); } ENDALL_LOOP; ALLPOLYGON_LOOP (Buffer->Data); { r_delete_entry (layer->polygon_tree, (BoxType *)polygon); POLYGONPOINT_LOOP (polygon); { point->X = SWAP_X (point->X); point->Y = SWAP_Y (point->Y); } END_LOOP; SetPolygonBoundingBox (polygon); r_insert_entry (layer->polygon_tree, (BoxType *)polygon, 0); /* hmmm, how to handle clip */ } ENDALL_LOOP; ALLTEXT_LOOP (Buffer->Data); { r_delete_entry (layer->text_tree, (BoxType *)text); text->X = SWAP_X (text->X); text->Y = SWAP_Y (text->Y); TOGGLE_FLAG (ONSOLDERFLAG, text); SetTextBoundingBox (&PCB->Font, text); r_insert_entry (layer->text_tree, (BoxType *)text, 0); } ENDALL_LOOP; /* swap silkscreen layers */ swap = Buffer->Data->Layer[solder_silk_layer]; Buffer->Data->Layer[solder_silk_layer] = Buffer->Data->Layer[component_silk_layer]; Buffer->Data->Layer[component_silk_layer] = swap; /* swap layer groups when balanced */ sgroup = GetLayerGroupNumberByNumber (solder_silk_layer); cgroup = GetLayerGroupNumberByNumber (component_silk_layer); if (PCB->LayerGroups.Number[cgroup] == PCB->LayerGroups.Number[sgroup]) { for (j = k = 0; j < PCB->LayerGroups.Number[sgroup]; j++) { int t1, t2; Cardinal cnumber = PCB->LayerGroups.Entries[cgroup][k]; Cardinal snumber = PCB->LayerGroups.Entries[sgroup][j]; if (snumber >= max_copper_layer) continue; swap = Buffer->Data->Layer[snumber]; while (cnumber >= max_copper_layer) { k++; cnumber = PCB->LayerGroups.Entries[cgroup][k]; } Buffer->Data->Layer[snumber] = Buffer->Data->Layer[cnumber]; Buffer->Data->Layer[cnumber] = swap; k++; /* move the thermal flags with the layers */ ALLPIN_LOOP (Buffer->Data); { t1 = TEST_THERM (snumber, pin); t2 = TEST_THERM (cnumber, pin); ASSIGN_THERM (snumber, t2, pin); ASSIGN_THERM (cnumber, t1, pin); } ENDALL_LOOP; VIA_LOOP (Buffer->Data); { t1 = TEST_THERM (snumber, via); t2 = TEST_THERM (cnumber, via); ASSIGN_THERM (snumber, t2, via); ASSIGN_THERM (cnumber, t1, via); } END_LOOP; } } SetBufferBoundingBox (Buffer); SetCrosshairRangeToBuffer (); }
void FreeRotateBuffer (BufferType *Buffer, Angle angle) { double cosa, sina; cosa = cos(angle * M_PI/180.0); sina = sin(angle * M_PI/180.0); /* rotate vias */ VIA_LOOP (Buffer->Data); { r_delete_entry (Buffer->Data->via_tree, (BoxType *)via); free_rotate (&via->X, &via->Y, Buffer->X, Buffer->Y, cosa, sina); SetPinBoundingBox (via); r_insert_entry (Buffer->Data->via_tree, (BoxType *)via, 0); } END_LOOP; /* elements */ ELEMENT_LOOP (Buffer->Data); { FreeRotateElementLowLevel (Buffer->Data, element, Buffer->X, Buffer->Y, cosa, sina, angle); } END_LOOP; /* all layer related objects */ ALLLINE_LOOP (Buffer->Data); { r_delete_entry (layer->line_tree, (BoxType *)line); free_rotate (&line->Point1.X, &line->Point1.Y, Buffer->X, Buffer->Y, cosa, sina); free_rotate (&line->Point2.X, &line->Point2.Y, Buffer->X, Buffer->Y, cosa, sina); SetLineBoundingBox (line); r_insert_entry (layer->line_tree, (BoxType *)line, 0); } ENDALL_LOOP; ALLARC_LOOP (Buffer->Data); { r_delete_entry (layer->arc_tree, (BoxType *)arc); free_rotate (&arc->X, &arc->Y, Buffer->X, Buffer->Y, cosa, sina); arc->StartAngle = NormalizeAngle (arc->StartAngle + angle); r_insert_entry (layer->arc_tree, (BoxType *)arc, 0); } ENDALL_LOOP; /* FIXME: rotate text */ ALLPOLYGON_LOOP (Buffer->Data); { r_delete_entry (layer->polygon_tree, (BoxType *)polygon); POLYGONPOINT_LOOP (polygon); { free_rotate (&point->X, &point->Y, Buffer->X, Buffer->Y, cosa, sina); } END_LOOP; SetPolygonBoundingBox (polygon); r_insert_entry (layer->polygon_tree, (BoxType *)polygon, 0); } ENDALL_LOOP; SetBufferBoundingBox (Buffer); SetCrosshairRangeToBuffer (); }