6 * PCB, interactive printed circuit board design
7 * Copyright (C) 1994,1995,1996 Thomas Nau
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * Contact addresses for paper mail and Email:
24 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
25 * Thomas.Nau@rz.uni-ulm.de
30 /* functions used to insert points into objects
41 #include "crosshair.h"
55 #ifdef HAVE_LIBDMALLOC
64 /* ---------------------------------------------------------------------------
65 * some local prototypes
67 static void *InsertPointIntoLine (LayerTypePtr
, LineTypePtr
);
68 static void *InsertPointIntoPolygon (LayerTypePtr
, PolygonTypePtr
);
69 static void *InsertPointIntoRat (RatTypePtr
);
71 /* ---------------------------------------------------------------------------
72 * some local identifiers
74 static Coord InsertX
, InsertY
; /* used by local routines as offset */
75 static Cardinal InsertAt
;
76 static bool InsertLast
;
78 static ObjectFunctionType InsertFunctions
= {
81 InsertPointIntoPolygon
,
93 /* ---------------------------------------------------------------------------
94 * inserts a point into a rat-line
97 InsertPointIntoRat (RatTypePtr Rat
)
101 newone
= CreateDrawnLineOnLayer (CURRENT
, Rat
->Point1
.X
, Rat
->Point1
.Y
,
102 InsertX
, InsertY
, Settings
.LineThickness
,
103 2 * Settings
.Keepaway
, Rat
->Flags
);
106 AddObjectToCreateUndoList (LINE_TYPE
, CURRENT
, newone
, newone
);
108 DrawLine (CURRENT
, newone
);
109 newone
= CreateDrawnLineOnLayer (CURRENT
, Rat
->Point2
.X
, Rat
->Point2
.Y
,
110 InsertX
, InsertY
, Settings
.LineThickness
,
111 2 * Settings
.Keepaway
, Rat
->Flags
);
114 AddObjectToCreateUndoList (LINE_TYPE
, CURRENT
, newone
, newone
);
115 DrawLine (CURRENT
, newone
);
117 MoveObjectToRemoveUndoList (RATLINE_TYPE
, Rat
, Rat
, Rat
);
122 /* ---------------------------------------------------------------------------
123 * inserts a point into a line
126 InsertPointIntoLine (LayerTypePtr Layer
, LineTypePtr Line
)
131 if (((Line
->Point1
.X
== InsertX
) && (Line
->Point1
.Y
== InsertY
)) ||
132 ((Line
->Point2
.X
== InsertX
) && (Line
->Point2
.Y
== InsertY
)))
136 AddObjectToMoveUndoList (LINEPOINT_TYPE
, Layer
, Line
, &Line
->Point2
,
137 InsertX
- X
, InsertY
- Y
);
139 r_delete_entry (Layer
->line_tree
, (BoxTypePtr
) Line
);
140 RestoreToPolygon (PCB
->Data
, LINE_TYPE
, Layer
, Line
);
141 Line
->Point2
.X
= InsertX
;
142 Line
->Point2
.Y
= InsertY
;
143 SetLineBoundingBox (Line
);
144 r_insert_entry (Layer
->line_tree
, (BoxTypePtr
) Line
, 0);
145 ClearFromPolygon (PCB
->Data
, LINE_TYPE
, Layer
, Line
);
146 DrawLine (Layer
, Line
);
147 /* we must create after playing with Line since creation may
148 * invalidate the line pointer
150 if ((line
= CreateDrawnLineOnLayer (Layer
, InsertX
, InsertY
,
152 Line
->Thickness
, Line
->Clearance
,
155 AddObjectToCreateUndoList (LINE_TYPE
, Layer
, line
, line
);
156 DrawLine (Layer
, line
);
157 ClearFromPolygon (PCB
->Data
, LINE_TYPE
, Layer
, line
);
158 /* creation call adds it to the rtree */
164 /* ---------------------------------------------------------------------------
165 * inserts a point into a polygon
168 InsertPointIntoPolygon (LayerTypePtr Layer
, PolygonTypePtr Polygon
)
177 * first make sure adding the point is sensible
180 line
.Point1
= Polygon
->Points
[prev_contour_point (Polygon
, InsertAt
)];
181 line
.Point2
= Polygon
->Points
[InsertAt
];
182 if (IsPointOnLine ((float) InsertX
, (float) InsertY
, 0.0, &line
))
186 * second, shift the points up to make room for the new point
188 ErasePolygon (Polygon
);
189 r_delete_entry (Layer
->polygon_tree
, (BoxTypePtr
) Polygon
);
190 save
= *CreateNewPointInPolygon (Polygon
, InsertX
, InsertY
);
191 for (n
= Polygon
->PointN
- 1; n
> InsertAt
; n
--)
192 Polygon
->Points
[n
] = Polygon
->Points
[n
- 1];
194 /* Shift up indices of any holes */
195 for (n
= 0; n
< Polygon
->HoleIndexN
; n
++)
196 if (Polygon
->HoleIndex
[n
] > InsertAt
||
197 (InsertLast
&& Polygon
->HoleIndex
[n
] == InsertAt
))
198 Polygon
->HoleIndex
[n
]++;
200 Polygon
->Points
[InsertAt
] = save
;
201 SetChangedFlag (true);
202 AddObjectToInsertPointUndoList (POLYGONPOINT_TYPE
, Layer
, Polygon
,
203 &Polygon
->Points
[InsertAt
]);
205 SetPolygonBoundingBox (Polygon
);
206 r_insert_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
, 0);
207 InitClip (PCB
->Data
, Layer
, Polygon
);
208 if (Forcible
|| !RemoveExcessPolygonPoints (Layer
, Polygon
))
210 DrawPolygon (Layer
, Polygon
);
213 return (&Polygon
->Points
[InsertAt
]);
216 /* ---------------------------------------------------------------------------
217 * inserts point into objects
220 InsertPointIntoObject (int Type
, void *Ptr1
, void *Ptr2
, Cardinal
* Ptr3
,
221 Coord DX
, Coord DY
, bool Force
,
230 InsertLast
= insert_last
;
233 /* the operation insert the points to the undo-list */
234 ptr
= ObjectOperation (&InsertFunctions
, Type
, Ptr1
, Ptr2
, Ptr3
);
236 IncrementUndoSerialNumber ();
240 /* ---------------------------------------------------------------------------
241 * adjusts the insert point to make 45 degree lines as necessary
244 AdjustInsertPoint (void)
246 static PointType InsertedPoint
;
249 LineTypePtr line
= (LineTypePtr
) Crosshair
.AttachedObject
.Ptr2
;
251 if (Crosshair
.AttachedObject
.State
== STATE_FIRST
)
253 Crosshair
.AttachedObject
.Ptr3
= &InsertedPoint
;
254 if (gui
->shift_is_pressed ())
256 AttachedLineType myline
;
257 /* only force 45 degree for nearest point */
258 if (Distance (Crosshair
.X
, Crosshair
.Y
, line
->Point1
.X
, line
->Point1
.Y
) <
259 Distance (Crosshair
.X
, Crosshair
.Y
, line
->Point2
.X
, line
->Point2
.Y
))
260 myline
.Point1
= myline
.Point2
= line
->Point1
;
262 myline
.Point1
= myline
.Point2
= line
->Point2
;
263 FortyFiveLine (&myline
);
264 InsertedPoint
.X
= myline
.Point2
.X
;
265 InsertedPoint
.Y
= myline
.Point2
.Y
;
266 return &InsertedPoint
;
268 if (TEST_FLAG (ALLDIRECTIONFLAG
, PCB
))
270 InsertedPoint
.X
= Crosshair
.X
;
271 InsertedPoint
.Y
= Crosshair
.Y
;
272 return &InsertedPoint
;
274 if (Crosshair
.X
== line
->Point1
.X
)
275 m1
= 2; /* 2 signals infinite slope */
278 m
= (double) (Crosshair
.X
- line
->Point1
.X
) / (Crosshair
.Y
- line
->Point1
.Y
);
280 if (m
> TAN_30_DEGREE
)
281 m1
= (m
> TAN_60_DEGREE
) ? 2 : 1;
282 else if (m
< -TAN_30_DEGREE
)
283 m1
= (m
< -TAN_60_DEGREE
) ? 2 : -1;
285 if (Crosshair
.X
== line
->Point2
.X
)
286 m2
= 2; /* 2 signals infinite slope */
289 m
= (double) (Crosshair
.X
- line
->Point1
.X
) / (Crosshair
.Y
- line
->Point1
.Y
);
291 if (m
> TAN_30_DEGREE
)
292 m2
= (m
> TAN_60_DEGREE
) ? 2 : 1;
293 else if (m
< -TAN_30_DEGREE
)
294 m2
= (m
< -TAN_60_DEGREE
) ? 2 : -1;
298 InsertedPoint
.X
= line
->Point1
.X
;
299 InsertedPoint
.Y
= line
->Point1
.Y
;
300 return &InsertedPoint
;
305 y
= line
->Point2
.Y
+ m2
* (line
->Point1
.X
- line
->Point2
.X
);
310 y
= line
->Point1
.Y
+ m1
* (line
->Point2
.X
- line
->Point1
.X
);
314 x
= (line
->Point2
.Y
- line
->Point1
.Y
+ m1
* line
->Point1
.X
315 - m2
* line
->Point2
.X
) / (m1
- m2
);
316 y
= (m1
* line
->Point2
.Y
- m1
* m2
* line
->Point2
.X
317 - m2
* line
->Point1
.Y
+ m1
* m2
* line
->Point1
.X
) / (m1
- m2
);
321 return &InsertedPoint
;