4 * PCB, interactive printed circuit board design
5 * Copyright (C) 1994,1995,1996 Thomas Nau
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * Contact addresses for paper mail and Email:
22 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
23 * Thomas.Nau@rz.uni-ulm.de
28 /* functions used to insert points into objects
39 #include "crosshair.h"
53 #ifdef HAVE_LIBDMALLOC
57 /* ---------------------------------------------------------------------------
58 * some local prototypes
60 static void *InsertPointIntoLine (LayerType
*, LineType
*);
61 static void *InsertPointIntoPolygon (LayerType
*, PolygonType
*);
62 static void *InsertPointIntoRat (RatType
*);
64 /* ---------------------------------------------------------------------------
65 * some local identifiers
67 static Coord InsertX
, InsertY
; /* used by local routines as offset */
68 static Cardinal InsertAt
;
69 static bool InsertLast
;
71 static ObjectFunctionType InsertFunctions
= {
74 InsertPointIntoPolygon
,
86 /* ---------------------------------------------------------------------------
87 * inserts a point into a rat-line
90 InsertPointIntoRat (RatType
*Rat
)
94 newone
= CreateDrawnLineOnLayer (CURRENT
, Rat
->Point1
.X
, Rat
->Point1
.Y
,
95 InsertX
, InsertY
, Settings
.LineThickness
,
96 2 * Settings
.Keepaway
, Rat
->Flags
);
99 AddObjectToCreateUndoList (LINE_TYPE
, CURRENT
, newone
, newone
);
101 DrawLine (CURRENT
, newone
);
102 newone
= CreateDrawnLineOnLayer (CURRENT
, Rat
->Point2
.X
, Rat
->Point2
.Y
,
103 InsertX
, InsertY
, Settings
.LineThickness
,
104 2 * Settings
.Keepaway
, Rat
->Flags
);
107 AddObjectToCreateUndoList (LINE_TYPE
, CURRENT
, newone
, newone
);
108 DrawLine (CURRENT
, newone
);
110 MoveObjectToRemoveUndoList (RATLINE_TYPE
, Rat
, Rat
, Rat
);
115 /* ---------------------------------------------------------------------------
116 * inserts a point into a line
119 InsertPointIntoLine (LayerType
*Layer
, LineType
*Line
)
124 if (((Line
->Point1
.X
== InsertX
) && (Line
->Point1
.Y
== InsertY
)) ||
125 ((Line
->Point2
.X
== InsertX
) && (Line
->Point2
.Y
== InsertY
)))
129 AddObjectToMoveUndoList (LINEPOINT_TYPE
, Layer
, Line
, &Line
->Point2
,
130 InsertX
- X
, InsertY
- Y
);
132 r_delete_entry (Layer
->line_tree
, (BoxType
*) Line
);
133 RestoreToPolygon (PCB
->Data
, LINE_TYPE
, Layer
, Line
);
134 Line
->Point2
.X
= InsertX
;
135 Line
->Point2
.Y
= InsertY
;
136 SetLineBoundingBox (Line
);
137 r_insert_entry (Layer
->line_tree
, (BoxType
*) Line
, 0);
138 ClearFromPolygon (PCB
->Data
, LINE_TYPE
, Layer
, Line
);
139 DrawLine (Layer
, Line
);
140 /* we must create after playing with Line since creation may
141 * invalidate the line pointer
143 if ((line
= CreateDrawnLineOnLayer (Layer
, InsertX
, InsertY
,
145 Line
->Thickness
, Line
->Clearance
,
148 AddObjectToCreateUndoList (LINE_TYPE
, Layer
, line
, line
);
149 DrawLine (Layer
, line
);
150 ClearFromPolygon (PCB
->Data
, LINE_TYPE
, Layer
, line
);
151 /* creation call adds it to the rtree */
157 /* ---------------------------------------------------------------------------
158 * inserts a point into a polygon
161 InsertPointIntoPolygon (LayerType
*Layer
, PolygonType
*Polygon
)
170 * first make sure adding the point is sensible
173 line
.Point1
= Polygon
->Points
[prev_contour_point (Polygon
, InsertAt
)];
174 line
.Point2
= Polygon
->Points
[InsertAt
];
175 if (IsPointOnLine ((float) InsertX
, (float) InsertY
, 0.0, &line
))
179 * second, shift the points up to make room for the new point
181 ErasePolygon (Polygon
);
182 r_delete_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
);
183 save
= *CreateNewPointInPolygon (Polygon
, InsertX
, InsertY
);
184 for (n
= Polygon
->PointN
- 1; n
> InsertAt
; n
--)
185 Polygon
->Points
[n
] = Polygon
->Points
[n
- 1];
187 /* Shift up indices of any holes */
188 for (n
= 0; n
< Polygon
->HoleIndexN
; n
++)
189 if (Polygon
->HoleIndex
[n
] > InsertAt
||
190 (InsertLast
&& Polygon
->HoleIndex
[n
] == InsertAt
))
191 Polygon
->HoleIndex
[n
]++;
193 Polygon
->Points
[InsertAt
] = save
;
194 SetChangedFlag (true);
195 AddObjectToInsertPointUndoList (POLYGONPOINT_TYPE
, Layer
, Polygon
,
196 &Polygon
->Points
[InsertAt
]);
198 SetPolygonBoundingBox (Polygon
);
199 r_insert_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
, 0);
200 InitClip (PCB
->Data
, Layer
, Polygon
);
201 if (Forcible
|| !RemoveExcessPolygonPoints (Layer
, Polygon
))
203 DrawPolygon (Layer
, Polygon
);
206 return (&Polygon
->Points
[InsertAt
]);
209 /* ---------------------------------------------------------------------------
210 * inserts point into objects
213 InsertPointIntoObject (int Type
, void *Ptr1
, void *Ptr2
, Cardinal
* Ptr3
,
214 Coord DX
, Coord DY
, bool Force
,
223 InsertLast
= insert_last
;
226 /* the operation insert the points to the undo-list */
227 ptr
= ObjectOperation (&InsertFunctions
, Type
, Ptr1
, Ptr2
, Ptr3
);
229 IncrementUndoSerialNumber ();
233 /* ---------------------------------------------------------------------------
234 * adjusts the insert point to make 45 degree lines as necessary
237 AdjustInsertPoint (void)
239 static PointType InsertedPoint
;
242 LineType
*line
= (LineType
*) Crosshair
.AttachedObject
.Ptr2
;
244 if (Crosshair
.AttachedObject
.State
== STATE_FIRST
)
246 Crosshair
.AttachedObject
.Ptr3
= &InsertedPoint
;
247 if (gui
->shift_is_pressed ())
249 AttachedLineType myline
;
250 /* only force 45 degree for nearest point */
251 if (Distance (Crosshair
.X
, Crosshair
.Y
, line
->Point1
.X
, line
->Point1
.Y
) <
252 Distance (Crosshair
.X
, Crosshair
.Y
, line
->Point2
.X
, line
->Point2
.Y
))
253 myline
.Point1
= myline
.Point2
= line
->Point1
;
255 myline
.Point1
= myline
.Point2
= line
->Point2
;
256 FortyFiveLine (&myline
);
257 InsertedPoint
.X
= myline
.Point2
.X
;
258 InsertedPoint
.Y
= myline
.Point2
.Y
;
259 return &InsertedPoint
;
261 if (TEST_FLAG (ALLDIRECTIONFLAG
, PCB
))
263 InsertedPoint
.X
= Crosshair
.X
;
264 InsertedPoint
.Y
= Crosshair
.Y
;
265 return &InsertedPoint
;
267 if (Crosshair
.X
== line
->Point1
.X
)
268 m1
= 2; /* 2 signals infinite slope */
271 m
= (double) (Crosshair
.Y
- line
->Point1
.Y
) / (Crosshair
.X
- line
->Point1
.X
);
273 if (m
> TAN_30_DEGREE
)
274 m1
= (m
> TAN_60_DEGREE
) ? 2 : 1;
275 else if (m
< -TAN_30_DEGREE
)
276 m1
= (m
< -TAN_60_DEGREE
) ? 2 : -1;
278 if (Crosshair
.X
== line
->Point2
.X
)
279 m2
= 2; /* 2 signals infinite slope */
282 m
= (double) (Crosshair
.Y
- line
->Point2
.Y
) / (Crosshair
.X
- line
->Point2
.X
);
284 if (m
> TAN_30_DEGREE
)
285 m2
= (m
> TAN_60_DEGREE
) ? 2 : 1;
286 else if (m
< -TAN_30_DEGREE
)
287 m2
= (m
< -TAN_60_DEGREE
) ? 2 : -1;
291 InsertedPoint
.X
= line
->Point1
.X
;
292 InsertedPoint
.Y
= line
->Point1
.Y
;
293 return &InsertedPoint
;
298 y
= line
->Point2
.Y
+ m2
* (line
->Point1
.X
- line
->Point2
.X
);
303 y
= line
->Point1
.Y
+ m1
* (line
->Point2
.X
- line
->Point1
.X
);
307 x
= (line
->Point2
.Y
- line
->Point1
.Y
+ m1
* line
->Point1
.X
308 - m2
* line
->Point2
.X
) / (m1
- m2
);
309 y
= (m1
* line
->Point2
.Y
- m1
* m2
* line
->Point2
.X
310 - m2
* line
->Point1
.Y
+ m1
* m2
* line
->Point1
.X
) / (m1
- m2
);
314 return &InsertedPoint
;