~ubuntu-branches/ubuntu/precise/pcb/precise

« back to all changes in this revision

Viewing changes to src/rotate.c

  • Committer: Bazaar Package Importer
  • Author(s): Hamish Moffatt
  • Date: 2005-02-20 13:14:00 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050220131400-pfz66g5vhx0azl8f
Tags: 1.99j+20050127-2
* Improved package description: (closes: #295405)
* Fixed dependency: tk84 -> tk8.4 (closes: #295404)
* Updated README.debian (closes: #269578)
* Applied patch to src/djopt.c to allow compilation with gcc-4.0
  (closes: #294319), thanks to Andreas Jochens for the patch.
* Prevent example files from being compressed

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: rotate.c,v 1.12 2005/01/03 12:57:00 danmc Exp $ */
 
2
 
1
3
/*
2
4
 *                            COPYRIGHT
3
5
 *
24
26
 *
25
27
 */
26
28
 
27
 
static  char    *rcsid = "$Id: rotate.c,v 1.6 1998/02/24 22:54:47 cad Exp $";
28
29
 
29
30
/* functions used to rotate pins, elements ...
30
31
 */
31
32
 
 
33
#ifdef HAVE_CONFIG_H
 
34
#include "config.h"
 
35
#endif
 
36
 
32
37
#include <stdlib.h>
33
38
 
34
39
#include "global.h"
36
41
#include "crosshair.h"
37
42
#include "data.h"
38
43
#include "draw.h"
 
44
#include "error.h"
39
45
#include "misc.h"
40
46
#include "polygon.h"
41
47
#include "rotate.h"
 
48
#include "rtree.h"
 
49
#include "rubberband.h"
42
50
#include "search.h"
43
51
#include "select.h"
 
52
#include "set.h"
44
53
#include "undo.h"
45
54
 
 
55
#ifdef HAVE_LIBDMALLOC
 
56
#include <dmalloc.h>
 
57
#endif
 
58
 
 
59
RCSID("$Id: rotate.c,v 1.12 2005/01/03 12:57:00 danmc Exp $");
 
60
 
 
61
 
 
62
 
 
63
 
46
64
/* ---------------------------------------------------------------------------
47
65
 * some local prototypes
48
66
 */
49
 
static  void    *RotateText(LayerTypePtr, TextTypePtr);
50
 
static  void    *RotateArc(LayerTypePtr, ArcTypePtr);
51
 
static  void    *RotateElement(ElementTypePtr);
52
 
static  void    *RotateElementName(ElementTypePtr);
53
 
static  void    *RotateLinePoint(LayerTypePtr, LineTypePtr, PointTypePtr);
 
67
static void *RotateText (LayerTypePtr, TextTypePtr);
 
68
static void *RotateArc (LayerTypePtr, ArcTypePtr);
 
69
static void *RotateElement (ElementTypePtr);
 
70
static void *RotateElementName (ElementTypePtr);
 
71
static void *RotateLinePoint (LayerTypePtr, LineTypePtr, PointTypePtr);
54
72
 
55
73
/* ----------------------------------------------------------------------
56
74
 * some local identifiers
57
75
 */
58
 
static  Position                        CenterX,        /* center of rotation */
59
 
                                                        CenterY;
60
 
static  BYTE                            Number;         /* number of rotations */
61
 
static  ObjectFunctionType      RotateFunctions = {
62
 
        NULL,
63
 
        RotateText,
64
 
        NULL,
65
 
        NULL,
66
 
        RotateElement,
67
 
        RotateElementName,
68
 
        NULL,
69
 
        NULL,
70
 
        RotateLinePoint,
71
 
        NULL,
72
 
        RotateArc,
73
 
        NULL };
 
76
static LocationType CenterX,    /* center of rotation */
 
77
  CenterY;
 
78
static BYTE Number;             /* number of rotations */
 
79
static ObjectFunctionType RotateFunctions = {
 
80
  NULL,
 
81
  RotateText,
 
82
  NULL,
 
83
  NULL,
 
84
  RotateElement,
 
85
  RotateElementName,
 
86
  NULL,
 
87
  NULL,
 
88
  RotateLinePoint,
 
89
  NULL,
 
90
  RotateArc,
 
91
  NULL
 
92
};
74
93
 
75
94
/* ---------------------------------------------------------------------------
76
95
 * rotates a point in 90 degree steps
77
96
 */
78
 
void RotatePointLowLevel(PointTypePtr Point, Position X, Position Y, BYTE Number)
 
97
void
 
98
RotatePointLowLevel (PointTypePtr Point, LocationType X, LocationType Y, BYTE Number)
79
99
{
80
 
        ROTATE(Point->X, Point->Y, X, Y, Number);
 
100
  ROTATE (Point->X, Point->Y, X, Y, Number);
81
101
}
82
102
 
83
103
/* ---------------------------------------------------------------------------
84
104
 * rotates a line in 90 degree steps
85
105
 */
86
 
void RotateLineLowLevel(LineTypePtr Line, Position X, Position Y, BYTE Number)
 
106
void
 
107
RotateLineLowLevel (LineTypePtr Line, LocationType X, LocationType Y, BYTE Number)
87
108
{
88
 
        ROTATE(Line->Point1.X, Line->Point1.Y, X, Y, Number);
89
 
        ROTATE(Line->Point2.X, Line->Point2.Y, X, Y, Number);
90
 
 
 
109
  ROTATE (Line->Point1.X, Line->Point1.Y, X, Y, Number);
 
110
  ROTATE (Line->Point2.X, Line->Point2.Y, X, Y, Number);
 
111
  /* keep horizontal, vertical Point2 > Point1 */
 
112
  if (Line->Point1.X == Line->Point2.X)
 
113
    {
 
114
      if (Line->Point1.Y > Line->Point2.Y)
 
115
        {
 
116
          LocationType t;
 
117
          t = Line->Point1.Y;
 
118
          Line->Point1.Y = Line->Point2.Y;
 
119
          Line->Point2.Y = t;
 
120
        }
 
121
    }
 
122
  else if (Line->Point1.Y == Line->Point2.Y)
 
123
    {
 
124
      if (Line->Point1.X > Line->Point2.X)
 
125
        {
 
126
          LocationType t;
 
127
          t = Line->Point1.X;
 
128
          Line->Point1.X = Line->Point2.X;
 
129
          Line->Point2.X = t;
 
130
        }
 
131
    }
 
132
  /* instead of rotating the bounding box, the call updates both end points too */
 
133
  SetLineBoundingBox (Line);
91
134
}
92
135
 
93
136
/* ---------------------------------------------------------------------------
95
138
 * only the bounding box is rotated, text rotation itself
96
139
 * is done by the drawing routines
97
140
 */
98
 
void RotateTextLowLevel(TextTypePtr Text, Position X, Position Y, BYTE Number)
 
141
void
 
142
RotateTextLowLevel (TextTypePtr Text, LocationType X, LocationType Y, BYTE Number)
99
143
{
100
 
        BYTE    number;
101
 
 
102
 
        number = TEST_FLAG(ONSOLDERFLAG, Text) ? (4 - Number) & 3 : Number;
103
 
        RotateBoxLowLevel(&Text->BoundingBox, X, Y, Number);
104
 
        ROTATE(Text->X, Text->Y, X, Y, Number);
105
 
 
106
 
                /* set new direction, 0..3,
107
 
                 * 0-> to the right, 1-> straight up,
108
 
                 * 2-> to the left, 3-> straight down
109
 
                 */
110
 
        Text->Direction = ((Text->Direction + number) & 0x03);
 
144
  BYTE number;
 
145
 
 
146
  number = TEST_FLAG (ONSOLDERFLAG, Text) ? (4 - Number) & 3 : Number;
 
147
  RotateBoxLowLevel (&Text->BoundingBox, X, Y, Number);
 
148
  ROTATE (Text->X, Text->Y, X, Y, Number);
 
149
 
 
150
  /* set new direction, 0..3,
 
151
   * 0-> to the right, 1-> straight up,
 
152
   * 2-> to the left, 3-> straight down
 
153
   */
 
154
  Text->Direction = ((Text->Direction + number) & 0x03);
111
155
}
112
156
 
113
157
/* ---------------------------------------------------------------------------
114
158
 * rotates a polygon in 90 degree steps
115
159
 */
116
 
void RotatePolygonLowLevel(PolygonTypePtr Polygon,
117
 
        Position X, Position Y, BYTE Number)
 
160
void
 
161
RotatePolygonLowLevel (PolygonTypePtr Polygon,
 
162
                       LocationType X, LocationType Y, BYTE Number)
118
163
{
119
 
        POLYGONPOINT_LOOP(Polygon,
120
 
                ROTATE(point->X, point->Y, X, Y, Number);
121
 
        );
122
 
        RotateBoxLowLevel(&Polygon->BoundingBox, X, Y, Number);
 
164
  POLYGONPOINT_LOOP (Polygon);
 
165
    {
 
166
      ROTATE (point->X, point->Y, X, Y, Number);
 
167
    }
 
168
  END_LOOP;
 
169
  RotateBoxLowLevel (&Polygon->BoundingBox, X, Y, Number);
123
170
}
124
171
 
125
172
/* ---------------------------------------------------------------------------
126
173
 * rotates a text object and redraws it
127
174
 */
128
 
static void *RotateText(LayerTypePtr Layer, TextTypePtr Text)
 
175
static void *
 
176
RotateText (LayerTypePtr Layer, TextTypePtr Text)
129
177
{
130
 
        EraseText(Text);
131
 
        RotateTextLowLevel(Text, CenterX, CenterY, Number);
132
 
        DrawText(Layer, Text, 0);
133
 
        Draw();
134
 
        return(Text);
 
178
  EraseText (Text);
 
179
  r_delete_entry (Layer->text_tree, (BoxTypePtr) Text);
 
180
  RotateTextLowLevel (Text, CenterX, CenterY, Number);
 
181
  r_insert_entry (Layer->text_tree, (BoxTypePtr) Text, 0);
 
182
  DrawText (Layer, Text, 0);
 
183
  Draw ();
 
184
  return (Text);
135
185
}
136
186
 
137
187
/* ---------------------------------------------------------------------------
138
188
 * rotates an arc
139
189
 */
140
 
void RotateArcLowLevel(ArcTypePtr Arc,
141
 
        Position X, Position Y,
142
 
        BYTE Number)
 
190
void
 
191
RotateArcLowLevel (ArcTypePtr Arc, LocationType X, LocationType Y, BYTE Number)
143
192
{
144
 
        Dimension       save;
145
 
 
146
 
                /* add Number*90 degrees to the startangle and check for overflow */
147
 
        Arc->StartAngle = (Arc->StartAngle +Number*90) % 360;
148
 
        ROTATE(Arc->X, Arc->Y, X, Y, Number);
149
 
 
150
 
                /* now change width and height */
151
 
        if (Number == 1 || Number == 3)
152
 
        {
153
 
                save = Arc->Width;
154
 
                Arc->Width = Arc->Height;
155
 
                Arc->Height = save;
156
 
        }
157
 
        SetArcBoundingBox(Arc);
 
193
  BDimension save;
 
194
 
 
195
  /* add Number*90 degrees to the startangle and check for overflow */
 
196
  Arc->StartAngle = (Arc->StartAngle + Number * 90) % 360;
 
197
  ROTATE (Arc->X, Arc->Y, X, Y, Number);
 
198
 
 
199
  /* now change width and height */
 
200
  if (Number == 1 || Number == 3)
 
201
    {
 
202
      save = Arc->Width;
 
203
      Arc->Width = Arc->Height;
 
204
      Arc->Height = save;
 
205
    }
 
206
  RotateBoxLowLevel (&Arc->BoundingBox, X, Y, Number);
158
207
}
159
208
 
160
209
/* ---------------------------------------------------------------------------
161
210
 * rotate an element in 90 degree steps
162
211
 */
163
 
void RotateElementLowLevel(ElementTypePtr Element,
164
 
        Position X, Position Y,
165
 
        BYTE Number)
 
212
void
 
213
RotateElementLowLevel (DataTypePtr Data, ElementTypePtr Element,
 
214
                       LocationType X, LocationType Y, BYTE Number)
166
215
{
167
 
        Boolean OnLayout = False;
168
 
 
169
 
        ELEMENT_LOOP(PCB->Data,
170
 
                if (element == Element)
171
 
                        OnLayout = True;
172
 
        );
173
 
                /* solder side objects need a different orientation */
174
 
 
175
 
                /* the text subroutine decides by itself if the direction
176
 
                 * is to be corrected
177
 
                 */
178
 
        ELEMENTTEXT_LOOP(Element, RotateTextLowLevel(text, X, Y, Number));
179
 
        ELEMENTLINE_LOOP(Element, RotateLineLowLevel(line, X, Y, Number););
180
 
        PIN_LOOP(Element, {
181
 
                ROTATE_PIN_LOWLEVEL(pin, X, Y, Number);
182
 
                if (OnLayout)
183
 
                        UpdatePIPFlags(pin, Element, NULL, NULL, True);
184
 
        });
185
 
        PAD_LOOP(Element, ROTATE_PAD_LOWLEVEL(pad, X, Y, Number););
186
 
        ARC_LOOP(Element, RotateArcLowLevel(arc, X, Y, Number););
187
 
        ROTATE(Element->MarkX, Element->MarkY, X, Y, Number);
188
 
        RotateBoxLowLevel(&Element->BoundingBox, X, Y, Number);
 
216
  /* solder side objects need a different orientation */
 
217
 
 
218
  /* the text subroutine decides by itself if the direction
 
219
   * is to be corrected
 
220
   */
 
221
  ELEMENTTEXT_LOOP (Element);
 
222
    {
 
223
      if (Data->name_tree[n])
 
224
        r_delete_entry (Data->name_tree[n], (BoxType *) text);
 
225
      RotateTextLowLevel (text, X, Y, Number);
 
226
    }
 
227
  END_LOOP;
 
228
  ELEMENTLINE_LOOP (Element);
 
229
    {
 
230
      RotateLineLowLevel (line, X, Y, Number);
 
231
    }
 
232
  END_LOOP;
 
233
  PIN_LOOP (Element);
 
234
    {
 
235
      /* pre-delete the pins from the pin-tree before their coordinates change */
 
236
      if (Data)
 
237
        r_delete_entry (PCB->Data->pin_tree, (BoxType *) pin);
 
238
      ROTATE_PIN_LOWLEVEL (pin, X, Y, Number);
 
239
      if (PCB->Data == Data)
 
240
        UpdatePIPFlags (pin, Element, NULL, True);
 
241
    }
 
242
  END_LOOP;
 
243
  PAD_LOOP (Element);
 
244
    {
 
245
      /* pre-delete the pads before their coordinates change */
 
246
      if (Data)
 
247
        r_delete_entry (PCB->Data->pad_tree, (BoxType *) pad);
 
248
      ROTATE_PAD_LOWLEVEL (pad, X, Y, Number);
 
249
    }
 
250
  END_LOOP;
 
251
  ARC_LOOP (Element);
 
252
    {
 
253
      RotateArcLowLevel (arc, X, Y, Number);
 
254
    }
 
255
  END_LOOP;
 
256
  ROTATE (Element->MarkX, Element->MarkY, X, Y, Number);
 
257
  /* SetElementBoundingBox reenters the pins/pads into their trees */
 
258
  SetElementBoundingBox (Data, Element, &PCB->Font);
189
259
}
190
260
 
191
261
/* ---------------------------------------------------------------------------
192
262
 * rotates a line's point
193
263
 */
194
 
static void *RotateLinePoint(LayerTypePtr Layer, LineTypePtr Line, PointTypePtr Point)
 
264
static void *
 
265
RotateLinePoint (LayerTypePtr Layer, LineTypePtr Line, PointTypePtr Point)
195
266
{
196
 
        EraseLine(Line);
197
 
        RotatePointLowLevel(Point, CenterX, CenterY, Number);
198
 
        DrawLine(Layer, Line, 0);
199
 
        Draw();
200
 
        return(Line);
 
267
  EraseLine (Line);
 
268
  if (Layer)
 
269
    r_delete_entry (Layer->line_tree, (BoxTypePtr) Line);
 
270
  else
 
271
    r_delete_entry (PCB->Data->rat_tree, (BoxTypePtr) Line);
 
272
  RotatePointLowLevel (Point, CenterX, CenterY, Number);
 
273
  SetLineBoundingBox (Line);
 
274
  if (Layer)
 
275
    {
 
276
      r_insert_entry (Layer->line_tree, (BoxTypePtr) Line, 0);
 
277
      DrawLine (Layer, Line, 0);
 
278
    }
 
279
  else
 
280
    {
 
281
      r_insert_entry (PCB->Data->rat_tree, (BoxTypePtr) Line, 0);
 
282
      DrawRat ((RatTypePtr)Line, 0);
 
283
    }
 
284
  Draw ();
 
285
  return (Line);
201
286
}
202
287
 
203
288
/* ---------------------------------------------------------------------------
204
289
 * rotates an arc
205
290
 */
206
 
static void *RotateArc(LayerTypePtr Layer, ArcTypePtr Arc)
 
291
static void *
 
292
RotateArc (LayerTypePtr Layer, ArcTypePtr Arc)
207
293
{
208
 
        EraseArc(Arc);
209
 
        RotateArcLowLevel(Arc, CenterX, CenterY, Number);
210
 
        DrawArc(Layer, Arc, 0);
211
 
        Draw();
212
 
        return(Arc);
 
294
  EraseArc (Arc);
 
295
  r_delete_entry (Layer->arc_tree, (BoxTypePtr) Arc);
 
296
  RotateArcLowLevel (Arc, CenterX, CenterY, Number);
 
297
  r_insert_entry (Layer->arc_tree, (BoxTypePtr) Arc, 0);
 
298
  DrawArc (Layer, Arc, 0);
 
299
  Draw ();
 
300
  return (Arc);
213
301
}
214
302
 
215
303
/* ---------------------------------------------------------------------------
216
304
 * rotates an element
217
305
 */
218
 
static void *RotateElement(ElementTypePtr Element)
 
306
static void *
 
307
RotateElement (ElementTypePtr Element)
219
308
{
220
 
        EraseElement(Element);
221
 
        RotateElementLowLevel(Element, CenterX, CenterY, Number);
222
 
        DrawElement(Element, 0);
223
 
        Draw();
224
 
        return(Element);
 
309
  EraseElement (Element);
 
310
  RotateElementLowLevel (PCB->Data, Element, CenterX, CenterY, Number);
 
311
  DrawElement (Element, 0);
 
312
  Draw ();
 
313
  return (Element);
225
314
}
226
315
 
227
316
/* ----------------------------------------------------------------------
228
317
 * rotates the name of an element
229
318
 */
230
 
static void *RotateElementName(ElementTypePtr Element)
 
319
static void *
 
320
RotateElementName (ElementTypePtr Element)
231
321
{
232
 
        EraseElementName(Element);
233
 
        ELEMENTTEXT_LOOP(Element, RotateTextLowLevel(text,CenterX,CenterY,Number));
234
 
        DrawElementName(Element, 0);
235
 
        Draw();
236
 
        return(Element);
 
322
  EraseElementName (Element);
 
323
  ELEMENTTEXT_LOOP (Element);
 
324
    {
 
325
      r_delete_entry (PCB->Data->name_tree[n], (BoxType *)text);
 
326
      RotateTextLowLevel (text, CenterX, CenterY, Number);
 
327
      r_insert_entry (PCB->Data->name_tree[n], (BoxType *)text, 0);
 
328
    }
 
329
  END_LOOP;
 
330
  DrawElementName (Element, 0);
 
331
  Draw ();
 
332
  return (Element);
237
333
}
238
334
 
239
335
/* ---------------------------------------------------------------------------
240
336
 * rotates a box in 90 degree steps 
241
337
 */
242
 
void RotateBoxLowLevel(BoxTypePtr Box,
243
 
        Position X, Position Y, BYTE Number)
 
338
void
 
339
RotateBoxLowLevel (BoxTypePtr Box, LocationType X, LocationType Y, BYTE Number)
244
340
{
245
 
        Position        x1 = Box->X1,
246
 
                                y1 = Box->Y1,
247
 
                                x2 = Box->X2,
248
 
                                y2 = Box->Y2;
 
341
  LocationType x1 = Box->X1, y1 = Box->Y1, x2 = Box->X2, y2 = Box->Y2;
249
342
 
250
 
        ROTATE(x1, y1, X, Y, Number);
251
 
        ROTATE(x2, y2, X, Y, Number);
252
 
        Box->X1 = MIN(x1, x2);
253
 
        Box->Y1 = MIN(y1, y2);
254
 
        Box->X2 = MAX(x1, x2);
255
 
        Box->Y2 = MAX(y1, y2);
 
343
  ROTATE (x1, y1, X, Y, Number);
 
344
  ROTATE (x2, y2, X, Y, Number);
 
345
  Box->X1 = MIN (x1, x2);
 
346
  Box->Y1 = MIN (y1, y2);
 
347
  Box->X2 = MAX (x1, x2);
 
348
  Box->Y2 = MAX (y1, y2);
256
349
}
257
350
 
258
351
/* ----------------------------------------------------------------------
259
352
 * rotates an objects at the cursor position as identified by its ID
260
353
 * the center of rotation is determined by the current cursor location
261
354
 */
262
 
void *RotateObject(int Type, void *Ptr1, void *Ptr2, void *Ptr3,
263
 
        Position X, Position Y, BYTE Steps)
264
 
{
265
 
        RubberbandTypePtr       ptr;
266
 
        void                    *ptr2;
267
 
        Boolean                 changed = False;
268
 
 
269
 
                /* setup default  global identifiers */
270
 
        Number = Steps;
271
 
        CenterX = X;
272
 
        CenterY = Y;
273
 
 
274
 
                /* move all the rubberband lines... and reset the counter */
275
 
        ptr = Crosshair.AttachedObject.Rubberband;
276
 
        while (Crosshair.AttachedObject.RubberbandN)
277
 
        {
278
 
                changed = True;
279
 
                ptr->Line->Flags &= ~RUBBERENDFLAG;
280
 
                AddObjectToRotateUndoList(LINEPOINT_TYPE, ptr->Layer, ptr->Line, ptr->MovedPoint,
281
 
                        CenterX, CenterY, Steps);
282
 
                EraseLine(ptr->Line);
283
 
                RotatePointLowLevel(ptr->MovedPoint, CenterX, CenterY, Steps);
284
 
                DrawLine(ptr->Layer, ptr->Line, 0);
285
 
                Crosshair.AttachedObject.RubberbandN--;
286
 
                ptr++;
287
 
        }
288
 
        AddObjectToRotateUndoList(Type, Ptr1, Ptr2, Ptr3, CenterX, CenterY, Number);
289
 
        ptr2 = ObjectOperation(&RotateFunctions, Type, Ptr1, Ptr2, Ptr3);
290
 
        changed |= (ptr2 != NULL);
291
 
        if (changed)
292
 
        {
293
 
                Draw();
294
 
                IncrementUndoSerialNumber();
295
 
        }
296
 
        return(ptr2);
297
 
}
298
 
 
 
355
void *
 
356
RotateObject (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
 
357
              LocationType X, LocationType Y, BYTE Steps)
 
358
{
 
359
  RubberbandTypePtr ptr;
 
360
  void *ptr2;
 
361
  Boolean changed = False;
 
362
 
 
363
  /* setup default  global identifiers */
 
364
  Number = Steps;
 
365
  CenterX = X;
 
366
  CenterY = Y;
 
367
 
 
368
  /* move all the rubberband lines... and reset the counter */
 
369
  ptr = Crosshair.AttachedObject.Rubberband;
 
370
  while (Crosshair.AttachedObject.RubberbandN)
 
371
    {
 
372
      changed = True;
 
373
      ptr->Line->Flags &= ~RUBBERENDFLAG;
 
374
      AddObjectToRotateUndoList (LINEPOINT_TYPE, ptr->Layer, ptr->Line,
 
375
                                 ptr->MovedPoint, CenterX, CenterY, Steps);
 
376
      EraseLine (ptr->Line);
 
377
      if (ptr->Layer)
 
378
        r_delete_entry (ptr->Layer->line_tree, (BoxType *) ptr->Line);
 
379
      else
 
380
        r_delete_entry (PCB->Data->rat_tree, (BoxType *) ptr->Line);
 
381
      RotatePointLowLevel (ptr->MovedPoint, CenterX, CenterY, Steps);
 
382
      SetLineBoundingBox (ptr->Line);
 
383
      if (ptr->Layer)
 
384
        {
 
385
          r_insert_entry (ptr->Layer->line_tree, (BoxType *) ptr->Line, 0);
 
386
          DrawLine (ptr->Layer, ptr->Line, 0);
 
387
        }
 
388
      else
 
389
        {
 
390
          r_insert_entry (PCB->Data->rat_tree, (BoxType *) ptr->Line, 0);
 
391
          DrawRat ((RatTypePtr) ptr->Line, 0);
 
392
        }
 
393
      Crosshair.AttachedObject.RubberbandN--;
 
394
      ptr++;
 
395
    }
 
396
  AddObjectToRotateUndoList (Type, Ptr1, Ptr2, Ptr3, CenterX, CenterY,
 
397
                             Number);
 
398
  ptr2 = ObjectOperation (&RotateFunctions, Type, Ptr1, Ptr2, Ptr3);
 
399
  changed |= (ptr2 != NULL);
 
400
  if (changed)
 
401
    {
 
402
      Draw ();
 
403
      IncrementUndoSerialNumber ();
 
404
    }
 
405
  return (ptr2);
 
406
}
 
407
 
 
408
void
 
409
RotateScreenObject (LocationType X, LocationType Y, BYTE Steps)
 
410
{
 
411
  int type;
 
412
  void *ptr1, *ptr2, *ptr3;
 
413
  if ((type = SearchScreen (X, Y, ROTATE_TYPES, &ptr1, &ptr2,
 
414
                            &ptr3)) != NO_TYPE)
 
415
    {
 
416
      if (TEST_FLAG (LOCKFLAG, (ArcTypePtr) ptr2))
 
417
        {
 
418
          Message ("Sorry that object is locked\n");
 
419
          return;
 
420
        }
 
421
      Crosshair.AttachedObject.RubberbandN = 0;
 
422
      if (TEST_FLAG (RUBBERBANDFLAG, PCB))
 
423
        LookupRubberbandLines (type, ptr1, ptr2, ptr3);
 
424
      if (type == ELEMENT_TYPE)
 
425
        LookupRatLines (type, ptr1, ptr2, ptr3);
 
426
      RotateObject (type, ptr1, ptr2, ptr3, X, Y, Steps);
 
427
      SetChangedFlag (True);
 
428
    }
 
429
}