00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <stdio.h>
00013 #include <math.h>
00014
00015 #include "global.h"
00016 #include "data.h"
00017 #include "hid.h"
00018 #include "misc.h"
00019 #include "create.h"
00020 #include "rtree.h"
00021 #include "undo.h"
00022 #include "move.h"
00023 #include "draw.h"
00024 #include "set.h"
00025 #include "polygon.h"
00026
00027 static void *
00028 MyMoveViaLowLevel(DataTypePtr Data, PinTypePtr Via, LocationType dx, LocationType dy)
00029 {
00030 if (Data) {
00031 RestoreToPolygon(Data, VIA_TYPE, Via, Via);
00032 r_delete_entry(Data->via_tree, (BoxTypePtr) Via);
00033 }
00034 MOVE_VIA_LOWLEVEL(Via, dx, dy);
00035 if (Data) {
00036 r_insert_entry(Data->via_tree, (BoxTypePtr) Via, 0);
00037 ClearFromPolygon(Data, VIA_TYPE, Via, Via);
00038 }
00039 return Via;
00040 }
00041
00042 static void *
00043 MyMoveLineLowLevel(DataTypePtr Data, LayerTypePtr Layer, LineTypePtr Line, LocationType dx, LocationType dy)
00044 {
00045 if (Data) {
00046 RestoreToPolygon(Data, LINE_TYPE, Layer, Line);
00047 r_delete_entry(Layer->line_tree, (BoxTypePtr) Line);
00048 }
00049 MOVE_LINE_LOWLEVEL(Line, dx, dy);
00050 if (Data) {
00051 r_insert_entry(Layer->line_tree, (BoxTypePtr) Line, 0);
00052 ClearFromPolygon(Data, LINE_TYPE, Layer, Line);
00053 }
00054 return Line;
00055 }
00056
00057 static void *
00058 MyMoveArcLowLevel(DataTypePtr Data, LayerTypePtr Layer, ArcTypePtr Arc, LocationType dx, LocationType dy)
00059 {
00060 if (Data) {
00061 RestoreToPolygon(Data, ARC_TYPE, Layer, Arc);
00062 r_delete_entry(Layer->arc_tree, (BoxTypePtr) Arc);
00063 }
00064 MOVE_ARC_LOWLEVEL(Arc, dx, dy);
00065 if (Data) {
00066 r_insert_entry(Layer->arc_tree, (BoxTypePtr) Arc, 0);
00067 ClearFromPolygon(Data, ARC_TYPE, Layer, Arc);
00068 }
00069 return Arc;
00070 }
00071
00072 static void *
00073 MyMovePolygonLowLevel(DataTypePtr Data, LayerTypePtr Layer, PolygonTypePtr Polygon, LocationType dx, LocationType dy)
00074 {
00075 if (Data) {
00076 r_delete_entry(Layer->polygon_tree, (BoxTypePtr) Polygon);
00077 }
00078
00079 MovePolygonLowLevel(Polygon, dx, dy);
00080 if (Data) {
00081 r_insert_entry(Layer->polygon_tree, (BoxTypePtr) Polygon, 0);
00082 InitClip(Data, Layer, Polygon);
00083 }
00084 return Polygon;
00085 }
00086
00087 static void *
00088 MyMoveTextLowLevel(LayerTypePtr Layer, TextTypePtr Text, LocationType dx, LocationType dy)
00089 {
00090 if (Layer)
00091 r_delete_entry(Layer->text_tree, (BoxTypePtr) Text);
00092 MOVE_TEXT_LOWLEVEL(Text, dx, dy);
00093 if (Layer)
00094 r_insert_entry(Layer->text_tree, (BoxTypePtr) Text, 0);
00095 return Text;
00096 }
00097
00098
00099
00100
00101
00102
00103
00104 static void
00105 MoveAll(LocationType dx, LocationType dy)
00106 {
00107 ELEMENT_LOOP(PCB->Data);
00108 {
00109 MoveElementLowLevel(PCB->Data, element, dx, dy);
00110 AddObjectToMoveUndoList(ELEMENT_TYPE, NULL, NULL, element, dx, dy);
00111 }
00112 END_LOOP;
00113
00114 VIA_LOOP(PCB->Data);
00115 {
00116 MyMoveViaLowLevel(PCB->Data, via, dx, dy);
00117 AddObjectToMoveUndoList(VIA_TYPE, NULL, NULL, via, dx, dy);
00118 }
00119 END_LOOP;
00120
00121 ALLLINE_LOOP(PCB->Data);
00122 {
00123 MyMoveLineLowLevel(PCB->Data, layer, line, dx, dy);
00124 AddObjectToMoveUndoList(LINE_TYPE, NULL, NULL, line, dx, dy);
00125 }
00126 ENDALL_LOOP;
00127
00128 ALLARC_LOOP(PCB->Data);
00129 {
00130 MyMoveArcLowLevel(PCB->Data, layer, arc, dx, dy);
00131 AddObjectToMoveUndoList(ARC_TYPE, NULL, NULL, arc, dx, dy);
00132 }
00133 ENDALL_LOOP;
00134
00135 ALLTEXT_LOOP(PCB->Data);
00136 {
00137 MyMoveTextLowLevel(layer, text, dx, dy);
00138 AddObjectToMoveUndoList(TEXT_TYPE, NULL, NULL, text, dx, dy);
00139 }
00140 ENDALL_LOOP;
00141
00142 ALLPOLYGON_LOOP(PCB->Data);
00143 {
00144
00145
00146
00147
00148
00149 MyMovePolygonLowLevel(PCB->Data, layer, polygon, dx, dy);
00150 AddObjectToMoveUndoList(POLYGON_TYPE, NULL, NULL, polygon, dx, dy);
00151 }
00152 ENDALL_LOOP;
00153 }
00154
00155 static int
00156 autocrop(int argc, char **argv, int x, int y)
00157 {
00158
00159 LocationType dx, dy, pad;
00160 BoxTypePtr box;
00161
00162 box = GetDataBoundingBox(PCB->Data);
00163
00164 if (!box || (box->X1 == box->X2 || box->Y1 == box->Y2)) {
00165
00166 return 0;
00167 }
00168
00169
00170
00171
00172
00173
00174
00175
00176 pad = PCB->minWid * 5;
00177 dx = -box->X1 + pad;
00178 dy = -box->Y1 + pad;
00179 box->X2 += pad;
00180 box->Y2 += pad;
00181
00182
00183
00184
00185
00186 dx -= dx % (long) PCB->Grid;
00187 dy -= dy % (long) PCB->Grid;
00188 box->X2 += dx;
00189 box->Y2 += dy;
00190
00191
00192
00193
00194 if (dx == 0 && dy == 0 &&
00195 PCB->MaxWidth == box->X2 && PCB->MaxHeight == box->Y2) {
00196 return 0;
00197 }
00198
00199
00200 PCB->MaxWidth = box->X2;
00201 PCB->MaxHeight = box->Y2;
00202
00203 MoveAll(dx, dy);
00204
00205 IncrementUndoSerialNumber();
00206 ClearAndRedrawOutput();
00207 SetChangedFlag(1);
00208 return 0;
00209 }
00210
00211 static HID_Action autocrop_action_list[] = {
00212 {"autocrop", NULL, autocrop, NULL, NULL}
00213 };
00214
00215 REGISTER_ACTIONS (autocrop_action_list)
00216
00217 void
00218 hid_autocrop_init()
00219 {
00220 register_autocrop_action_list();
00221 }