/* --------------------------------------------------------------------------- * 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 (); }
static void replace_one_footprint_aux(ElementTypePtr old_element, PadOrPinType* old1_pp, PadOrPinType* old2_pp, ElementTypePtr copy_element, PadOrPinType* copy1_pp, PadOrPinType* copy2_pp) { Boolean two_points = (old2_pp && copy2_pp); Boolean reflect = IS_REFLECTED(copy_element, old_element); debug_log("Reflect?: %s\n", (reflect ? "yes" : "no")); if (reflect) { /* Change side of board */ ChangeElementSide(copy_element, 0); } CheapPointType copy1_pt = pad_or_pin_center(copy1_pp); CheapPointType old1_pt = pad_or_pin_center(old1_pp); BYTE rot_steps = 0; if (two_points) { /* Calculate nearest rotation steps */ CheapPointType copy2_pt = pad_or_pin_center(copy2_pp); CheapPointType old2_pt = pad_or_pin_center(old2_pp); rot_steps = calculate_rotation_steps(copy1_pt, copy2_pt, old1_pt, old2_pt); } if (rot_steps) { /* Rotate copy */ RotateElementLowLevel(PCB->Data, copy_element, 0, 0, rot_steps); /* Recalculate since copy_element has changed. */ copy1_pt = pad_or_pin_center(copy1_pp); } /* Calculate translation */ LocationType dx = old1_pt.X - copy1_pt.X; LocationType dy = old1_pt.Y - copy1_pt.Y; /* Move element */ MoveElementLowLevel(PCB->Data, copy_element, dx, dy); /* Transfer pad/pin text and names. */ transfer_text(old_element, copy_element); transfer_names(old_element, copy_element); transfer_flags(old_element, copy_element); SetElementBoundingBox(PCB->Data, copy_element, &PCB->Font); AddObjectToCreateUndoList(ELEMENT_TYPE, copy_element, copy_element, copy_element); /* Remove old element. */ MoveObjectToRemoveUndoList(ELEMENT_TYPE, old_element, old_element, old_element); }
void doPerturb (PerturbationType * pt, bool undo) { LocationType bbcx, bbcy; /* compute center of element bounding box */ bbcx = (pt->element->VBox.X1 + pt->element->VBox.X2) / 2; bbcy = (pt->element->VBox.Y1 + pt->element->VBox.Y2) / 2; /* do exchange, shift or flip/rotate */ switch (pt->which) { case SHIFT: { LocationType DX = pt->DX, DY = pt->DY; if (undo) { DX = -DX; DY = -DY; } MoveElementLowLevel (PCB->Data, pt->element, DX, DY); return; } case ROTATE: { BYTE b = pt->rotate; if (undo) b = (4 - b) & 3; /* 0 - flip; 1-3, rotate. */ if (b) RotateElementLowLevel (PCB->Data, pt->element, bbcx, bbcy, b); else { LocationType y = pt->element->VBox.Y1; MirrorElementCoordinates (PCB->Data, pt->element, 0); /* mirroring moves the element. move it back. */ MoveElementLowLevel (PCB->Data, pt->element, 0, y - pt->element->VBox.Y1); } return; } case EXCHANGE: { /* first exchange positions */ LocationType x1 = pt->element->VBox.X1; LocationType y1 = pt->element->VBox.Y1; LocationType x2 = pt->other->BoundingBox.X1; LocationType y2 = pt->other->BoundingBox.Y1; MoveElementLowLevel (PCB->Data, pt->element, x2 - x1, y2 - y1); MoveElementLowLevel (PCB->Data, pt->other, x1 - x2, y1 - y2); /* then flip both elements if they are on opposite sides */ if (TEST_FLAG (ONSOLDERFLAG, pt->element) != TEST_FLAG (ONSOLDERFLAG, pt->other)) { PerturbationType mypt; mypt.element = pt->element; mypt.which = ROTATE; mypt.rotate = 0; /* flip */ doPerturb (&mypt, undo); mypt.element = pt->other; doPerturb (&mypt, undo); } /* done */ return; } default: assert (0); } }