void MirrorBuffer (BufferType *Buffer) { int i; if (Buffer->Data->ElementN) { Message (_("You can't mirror a buffer that has elements!\n")); return; } for (i = 0; i < max_copper_layer + 2; i++) { LayerType *layer = Buffer->Data->Layer + i; if (layer->TextN) { Message (_("You can't mirror a buffer that has text!\n")); return; } } /* set buffer offset to 'mark' position */ Buffer->X = SWAP_X (Buffer->X); Buffer->Y = SWAP_Y (Buffer->Y); VIA_LOOP (Buffer->Data); { via->X = SWAP_X (via->X); via->Y = SWAP_Y (via->Y); } END_LOOP; ALLLINE_LOOP (Buffer->Data); { 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); } ENDALL_LOOP; ALLARC_LOOP (Buffer->Data); { 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); } ENDALL_LOOP; ALLPOLYGON_LOOP (Buffer->Data); { POLYGONPOINT_LOOP (polygon); { point->X = SWAP_X (point->X); point->Y = SWAP_Y (point->Y); } END_LOOP; SetPolygonBoundingBox (polygon); } ENDALL_LOOP; SetBufferBoundingBox (Buffer); SetCrosshairRangeToBuffer (); }
/* --------------------------------------------------------------------------- * removes a polygon-point from a polygon */ static void * RemovePolygonPoint (LayerTypePtr Layer, PolygonTypePtr Polygon, PointTypePtr Point) { Cardinal point_idx; Cardinal i; Cardinal contour; Cardinal contour_start, contour_end, contour_points; point_idx = polygon_point_idx (Polygon, Point); contour = polygon_point_contour (Polygon, point_idx); contour_start = (contour == 0) ? 0 : Polygon->HoleIndex[contour - 1]; contour_end = (contour == Polygon->HoleIndexN) ? Polygon->PointN : Polygon->HoleIndex[contour]; contour_points = contour_end - contour_start; if (contour_points <= 3) return RemovePolygonContour (Layer, Polygon, contour); if (Layer->On) ErasePolygon (Polygon); /* insert the polygon-point into the undo list */ AddObjectToRemovePointUndoList (POLYGONPOINT_TYPE, Layer, Polygon, point_idx); r_delete_entry (Layer->polygon_tree, (BoxType *) Polygon); /* remove point from list, keep point order */ for (i = point_idx; i < Polygon->PointN - 1; i++) Polygon->Points[i] = Polygon->Points[i + 1]; Polygon->PointN--; /* Shift down indices of any holes */ for (i = 0; i < Polygon->HoleIndexN; i++) if (Polygon->HoleIndex[i] > point_idx) Polygon->HoleIndex[i]--; SetPolygonBoundingBox (Polygon); r_insert_entry (Layer->polygon_tree, (BoxType *) Polygon, 0); RemoveExcessPolygonPoints (Layer, Polygon); InitClip (PCB->Data, Layer, Polygon); /* redraw polygon if necessary */ if (Layer->On) { DrawPolygon (Layer, Polygon); if (!Bulk) Draw (); } return NULL; }
/* --------------------------------------------------------------------------- * inserts a point into a polygon */ static void * InsertPointIntoPolygon (LayerTypePtr Layer, PolygonTypePtr Polygon) { PointType save; Cardinal n; LineType line; if (!Forcible) { /* * first make sure adding the point is sensible */ line.Thickness = 0; line.Point1 = Polygon->Points[prev_contour_point (Polygon, InsertAt)]; line.Point2 = Polygon->Points[InsertAt]; if (IsPointOnLine ((float) InsertX, (float) InsertY, 0.0, &line)) return (NULL); } /* * second, shift the points up to make room for the new point */ ErasePolygon (Polygon); r_delete_entry (Layer->polygon_tree, (BoxTypePtr) Polygon); save = *CreateNewPointInPolygon (Polygon, InsertX, InsertY); for (n = Polygon->PointN - 1; n > InsertAt; n--) Polygon->Points[n] = Polygon->Points[n - 1]; /* Shift up indices of any holes */ for (n = 0; n < Polygon->HoleIndexN; n++) if (Polygon->HoleIndex[n] > InsertAt || (InsertLast && Polygon->HoleIndex[n] == InsertAt)) Polygon->HoleIndex[n]++; Polygon->Points[InsertAt] = save; SetChangedFlag (true); AddObjectToInsertPointUndoList (POLYGONPOINT_TYPE, Layer, Polygon, &Polygon->Points[InsertAt]); SetPolygonBoundingBox (Polygon); r_insert_entry (Layer->polygon_tree, (BoxType *) Polygon, 0); InitClip (PCB->Data, Layer, Polygon); if (Forcible || !RemoveExcessPolygonPoints (Layer, Polygon)) { DrawPolygon (Layer, Polygon, 0); Draw (); } return (&Polygon->Points[InsertAt]); }
/* --------------------------------------------------------------------------- * creates a new polygon from the old formats rectangle data */ PolygonTypePtr CreateNewPolygonFromRectangle (LayerTypePtr Layer, LocationType X1, LocationType Y1, LocationType X2, LocationType Y2, FlagType Flags) { PolygonTypePtr polygon = CreateNewPolygon (Layer, Flags); if (!polygon) return (polygon); CreateNewPointInPolygon (polygon, X1, Y1); CreateNewPointInPolygon (polygon, X2, Y1); CreateNewPointInPolygon (polygon, X2, Y2); CreateNewPointInPolygon (polygon, X1, Y2); SetPolygonBoundingBox (polygon); if (!Layer->polygon_tree) Layer->polygon_tree = r_create_tree (NULL, 0, 0); r_insert_entry (Layer->polygon_tree, (BoxTypePtr) polygon, 0); return (polygon); }
/* --------------------------------------------------------------------------- * copies data from one polygon to another * 'Dest' has to exist */ PolygonType * CopyPolygonLowLevel (PolygonType *Dest, PolygonType *Src) { Cardinal hole = 0; Cardinal n; for (n = 0; n < Src->PointN; n++) { if (hole < Src->HoleIndexN && n == Src->HoleIndex[hole]) { CreateNewHoleInPolygon (Dest); hole++; } CreateNewPointInPolygon (Dest, Src->Points[n].X, Src->Points[n].Y); } SetPolygonBoundingBox (Dest); Dest->Flags = Src->Flags; CLEAR_FLAG (NOCOPY_FLAGS, Dest); return (Dest); }
/*! * \brief Creates a new polygon from the old formats rectangle data. */ PolygonType * CreateNewPolygonFromRectangle (LayerType *Layer, Coord X1, Coord Y1, Coord X2, Coord Y2, FlagType Flags) { PolygonType *polygon = CreateNewPolygon (Layer, Flags); if (!polygon) return (polygon); CreateNewPointInPolygon (polygon, X1, Y1); CreateNewPointInPolygon (polygon, X2, Y1); CreateNewPointInPolygon (polygon, X2, Y2); CreateNewPointInPolygon (polygon, X1, Y2); SetPolygonBoundingBox (polygon); if (!Layer->polygon_tree) Layer->polygon_tree = r_create_tree (NULL, 0, 0); r_insert_entry (Layer->polygon_tree, (BoxType *) polygon, 0); return (polygon); }
/* --------------------------------------------------------------------------- * moves a polygon-point */ static void * MovePolygonPoint (LayerTypePtr Layer, PolygonTypePtr Polygon, PointTypePtr Point) { if (Layer->On) { ErasePolygon (Polygon); } r_delete_entry (Layer->polygon_tree, (BoxType *)Polygon); MOVE (Point->X, Point->Y, DeltaX, DeltaY); SetPolygonBoundingBox (Polygon); r_insert_entry (Layer->polygon_tree, (BoxType *)Polygon, 0); RemoveExcessPolygonPoints (Layer, Polygon); InitClip (PCB->Data, Layer, Polygon); if (Layer->On) { DrawPolygon (Layer, Polygon); Draw (); } return (Point); }
/* --------------------------------------------------------------------------- * removes a polygon-point from a polygon and destroys the data */ static void * DestroyPolygonPoint (LayerTypePtr Layer, PolygonTypePtr Polygon, PointTypePtr Point) { Cardinal point_idx; Cardinal i; Cardinal contour; Cardinal contour_start, contour_end, contour_points; point_idx = polygon_point_idx (Polygon, Point); contour = polygon_point_contour (Polygon, point_idx); contour_start = (contour == 0) ? 0 : Polygon->HoleIndex[contour - 1]; contour_end = (contour == Polygon->HoleIndexN) ? Polygon->PointN : Polygon->HoleIndex[contour]; contour_points = contour_end - contour_start; if (contour_points <= 3) return RemovePolygonContour (Layer, Polygon, contour); r_delete_entry (Layer->polygon_tree, (BoxType *) Polygon); /* remove point from list, keep point order */ for (i = point_idx; i < Polygon->PointN - 1; i++) Polygon->Points[i] = Polygon->Points[i + 1]; Polygon->PointN--; /* Shift down indices of any holes */ for (i = 0; i < Polygon->HoleIndexN; i++) if (Polygon->HoleIndex[i] > point_idx) Polygon->HoleIndex[i]--; SetPolygonBoundingBox (Polygon); r_insert_entry (Layer->polygon_tree, (BoxType *) Polygon, 0); InitClip (PCB->Data, Layer, Polygon); return (Polygon); }
/* --------------------------------------------------------------------------- * 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 (); }