/* --------------------------------------------------------------------------- * 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; }
/* --------------------------------------------------------------------------- * 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); }
/* --------------------------------------------------------------------------- * draws the attached object while in MOVE_MODE or COPY_MODE */ static void XORDrawMoveOrCopyObject (void) { RubberbandTypePtr ptr; Cardinal i; LocationType dx = Crosshair.X - Crosshair.AttachedObject.X, dy = Crosshair.Y - Crosshair.AttachedObject.Y; switch (Crosshair.AttachedObject.Type) { case VIA_TYPE: { PinTypePtr via = (PinTypePtr) Crosshair.AttachedObject.Ptr1; gui->draw_arc (Crosshair.GC, via->X + dx, via->Y + dy, via->Thickness / 2, via->Thickness / 2, 0, 360); break; } case LINE_TYPE: { LineTypePtr line = (LineTypePtr) Crosshair.AttachedObject.Ptr2; XORDrawAttachedLine (line->Point1.X + dx, line->Point1.Y + dy, line->Point2.X + dx, line->Point2.Y + dy, line->Thickness); break; } case ARC_TYPE: { ArcTypePtr Arc = (ArcTypePtr) Crosshair.AttachedObject.Ptr2; gui->draw_arc (Crosshair.GC, Arc->X + dx, Arc->Y + dy, Arc->Width, Arc->Height, Arc->StartAngle, Arc->Delta); break; } case POLYGON_TYPE: { PolygonTypePtr polygon = (PolygonTypePtr) Crosshair.AttachedObject.Ptr2; /* the tmp polygon has n+1 points because the first * and the last one are set to the same coordinates */ XORPolygon (polygon, dx, dy); break; } case LINEPOINT_TYPE: { LineTypePtr line; PointTypePtr point; line = (LineTypePtr) Crosshair.AttachedObject.Ptr2; point = (PointTypePtr) Crosshair.AttachedObject.Ptr3; if (point == &line->Point1) XORDrawAttachedLine (point->X + dx, point->Y + dy, line->Point2.X, line->Point2.Y, line->Thickness); else XORDrawAttachedLine (point->X + dx, point->Y + dy, line->Point1.X, line->Point1.Y, line->Thickness); break; } case POLYGONPOINT_TYPE: { PolygonTypePtr polygon; PointTypePtr point; Cardinal point_idx, prev, next; polygon = (PolygonTypePtr) Crosshair.AttachedObject.Ptr2; point = (PointTypePtr) Crosshair.AttachedObject.Ptr3; point_idx = polygon_point_idx (polygon, point); /* get previous and following point */ prev = prev_contour_point (polygon, point_idx); next = next_contour_point (polygon, point_idx); /* draw the two segments */ gui->draw_line (Crosshair.GC, polygon->Points[prev].X, polygon->Points[prev].Y, point->X + dx, point->Y + dy); gui->draw_line (Crosshair.GC, point->X + dx, point->Y + dy, polygon->Points[next].X, polygon->Points[next].Y); break; } case ELEMENTNAME_TYPE: { /* locate the element "mark" and draw an association line from crosshair to it */ ElementTypePtr element = (ElementTypePtr) Crosshair.AttachedObject.Ptr1; gui->draw_line (Crosshair.GC, element->MarkX, element->MarkY, Crosshair.X, Crosshair.Y); /* fall through to move the text as a box outline */ } case TEXT_TYPE: { TextTypePtr text = (TextTypePtr) Crosshair.AttachedObject.Ptr2; BoxTypePtr box = &text->BoundingBox; gui->draw_rect (Crosshair.GC, box->X1 + dx, box->Y1 + dy, box->X2 + dx, box->Y2 + dy); break; } /* pin/pad movements result in moving an element */ case PAD_TYPE: case PIN_TYPE: case ELEMENT_TYPE: XORDrawElement ((ElementTypePtr) Crosshair.AttachedObject.Ptr2, dx, dy); break; } /* draw the attached rubberband lines too */ i = Crosshair.AttachedObject.RubberbandN; ptr = Crosshair.AttachedObject.Rubberband; while (i) { PointTypePtr point1, point2; if (TEST_FLAG (VIAFLAG, ptr->Line)) { /* this is a rat going to a polygon. do not draw for rubberband */; } else if (TEST_FLAG (RUBBERENDFLAG, ptr->Line)) { /* 'point1' is always the fix-point */ if (ptr->MovedPoint == &ptr->Line->Point1) { point1 = &ptr->Line->Point2; point2 = &ptr->Line->Point1; } else { point1 = &ptr->Line->Point1; point2 = &ptr->Line->Point2; } XORDrawAttachedLine (point1->X, point1->Y, point2->X + dx, point2->Y + dy, ptr->Line->Thickness); } else if (ptr->MovedPoint == &ptr->Line->Point1) XORDrawAttachedLine (ptr->Line->Point1.X + dx, ptr->Line->Point1.Y + dy, ptr->Line->Point2.X + dx, ptr->Line->Point2.Y + dy, ptr->Line->Thickness); ptr++; i--; } }