(no commit message)
[geda-pcb/pcjc2.git] / src / fontmode.c
blob4afd3cd9ca2e9011e0a1fcb251a0ff572a747d14
1 /*
2 * COPYRIGHT
4 * PCB, interactive printed circuit board design
5 * Copyright (C) 2006 DJ Delorie
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 * DJ Delorie, 334 North Road, Deerfield NH 03037-1110, USA
23 * dj@delorie.com
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
31 #include "global.h"
33 #include <math.h>
34 #include <memory.h>
35 #include <limits.h>
38 #include "create.h"
39 #include "data.h"
40 #include "draw.h"
41 #include "misc.h"
42 #include "move.h"
43 #include "remove.h"
44 #include "rtree.h"
45 #include "strflags.h"
46 #include "undo.h"
47 #include "pcb-printf.h"
49 #ifdef HAVE_LIBDMALLOC
50 #include <dmalloc.h>
51 #endif
53 /* FIXME - we currently hardcode the grid and PCB size. What we
54 should do in the future is scan the font for its extents, and size
55 the grid appropriately. Also, when we convert back to a font, we
56 should search the grid for the gridlines and use them to figure out
57 where the symbols are. */
59 #define CELL_SIZE MIL_TO_COORD (100)
60 #define CELL_OFFSET MIL_TO_COORD (10)
62 #define XYtoSym(x,y) ((x1 + CELL_OFFSET) / CELL_SIZE - 1 \
63 + 16 * ((y1 + CELL_OFFSET) / CELL_SIZE - 1))
65 static const char fontedit_syntax[] = "FontEdit()";
67 static const char fontedit_help[] =
68 "Convert the current font to a PCB for editing.";
70 /* %start-doc actions FontEdit
72 %end-doc */
74 static int
75 FontEdit (int argc, char **argv, Coord Ux, Coord Uy)
77 FontType *font;
78 SymbolType *symbol;
79 LayerType *lfont, *lorig, *lwidth, *lgrid;
80 int s, l;
82 if (hid_actionl ("New", "Font", 0))
83 return 1;
85 Settings.grid_unit = get_unit_struct("mil");
86 Settings.Bloat = PCB->Bloat = 1;
87 Settings.Shrink = PCB->Shrink = 1;
88 Settings.minWid = PCB->minWid = 1;
89 Settings.minSlk = PCB->minSlk = 1;
91 MoveLayerToGroup (max_copper_layer + TOP_SILK_LAYER, 0);
92 MoveLayerToGroup (max_copper_layer + BOTTOM_SILK_LAYER, 1);
94 while (PCB->Data->LayerN > 4)
95 MoveLayer (4, -1);
96 for (l = 0; l < 4; l++)
98 MoveLayerToGroup (l, l);
100 PCB->MaxWidth = CELL_SIZE * 18;
101 PCB->MaxHeight = CELL_SIZE * ((MAX_FONTPOSITION + 15) / 16 + 2);
102 PCB->Grid = MIL_TO_COORD (5);
103 PCB->Data->Layer[0].Name = strdup ("Font");
104 PCB->Data->Layer[1].Name = strdup ("OrigFont");
105 PCB->Data->Layer[2].Name = strdup ("Width");
106 PCB->Data->Layer[3].Name = strdup ("Grid");
107 hid_action ("PCBChanged");
108 hid_action ("LayersChanged");
110 lfont = PCB->Data->Layer + 0;
111 lorig = PCB->Data->Layer + 1;
112 lwidth = PCB->Data->Layer + 2;
113 lgrid = PCB->Data->Layer + 3;
115 font = &PCB->Font;
116 for (s = 0; s <= MAX_FONTPOSITION; s++)
118 Coord ox = (s % 16 + 1) * CELL_SIZE;
119 Coord oy = (s / 16 + 1) * CELL_SIZE;
120 Coord w, miny, maxy, maxx = 0;
122 symbol = &font->Symbol[s];
124 miny = MIL_TO_COORD (5);
125 maxy = font->MaxHeight;
127 for (l = 0; l < symbol->LineN; l++)
129 CreateDrawnLineOnLayer (lfont,
130 symbol->Line[l].Point1.X + ox,
131 symbol->Line[l].Point1.Y + oy,
132 symbol->Line[l].Point2.X + ox,
133 symbol->Line[l].Point2.Y + oy,
134 symbol->Line[l].Thickness,
135 symbol->Line[l].Thickness, NoFlags ());
136 CreateDrawnLineOnLayer (lorig, symbol->Line[l].Point1.X + ox,
137 symbol->Line[l].Point1.Y + oy,
138 symbol->Line[l].Point2.X + ox,
139 symbol->Line[l].Point2.Y + oy,
140 symbol->Line[l].Thickness,
141 symbol->Line[l].Thickness, NoFlags ());
142 if (maxx < symbol->Line[l].Point1.X)
143 maxx = symbol->Line[l].Point1.X;
144 if (maxx < symbol->Line[l].Point2.X)
145 maxx = symbol->Line[l].Point2.X;
147 w = maxx + symbol->Delta + ox;
148 CreateDrawnLineOnLayer (lwidth,
149 w, miny + oy,
150 w, maxy + oy, MIL_TO_COORD (1), MIL_TO_COORD (1), NoFlags ());
153 for (l = 0; l < 16; l++)
155 int x = (l + 1) * CELL_SIZE;
156 CreateDrawnLineOnLayer (lgrid, x, 0, x, PCB->MaxHeight, MIL_TO_COORD (1),
157 MIL_TO_COORD (1), NoFlags ());
159 for (l = 0; l <= MAX_FONTPOSITION / 16 + 1; l++)
161 int y = (l + 1) * CELL_SIZE;
162 CreateDrawnLineOnLayer (lgrid, 0, y, PCB->MaxWidth, y, MIL_TO_COORD (1),
163 MIL_TO_COORD (1), NoFlags ());
165 return 0;
168 static const char fontsave_syntax[] = "FontSave()";
170 static const char fontsave_help[] = "Convert the current PCB back to a font.";
172 /* %start-doc actions FontSave
174 %end-doc */
176 static int
177 FontSave (int argc, char **argv, Coord Ux, Coord Uy)
179 FontType *font;
180 SymbolType *symbol;
181 int i;
182 GList *ii;
183 LayerType *lfont, *lwidth;
185 font = &PCB->Font;
186 lfont = PCB->Data->Layer + 0;
187 lwidth = PCB->Data->Layer + 2;
189 for (i = 0; i <= MAX_FONTPOSITION; i++)
191 font->Symbol[i].LineN = 0;
192 font->Symbol[i].Valid = 0;
193 font->Symbol[i].Width = 0;
196 for (ii = lfont->Line; ii != NULL; ii = g_list_next (ii))
198 LineType *l = ii->data;
199 int x1 = l->Point1.X;
200 int y1 = l->Point1.Y;
201 int x2 = l->Point2.X;
202 int y2 = l->Point2.Y;
203 int ox, oy, s;
205 s = XYtoSym (x1, y1);
206 ox = (s % 16 + 1) * CELL_SIZE;
207 oy = (s / 16 + 1) * CELL_SIZE;
208 symbol = &PCB->Font.Symbol[s];
210 x1 -= ox;
211 y1 -= oy;
212 x2 -= ox;
213 y2 -= oy;
215 if (symbol->Width < x1)
216 symbol->Width = x1;
217 if (symbol->Width < x2)
218 symbol->Width = x2;
219 symbol->Valid = 1;
221 CreateNewLineInSymbol (symbol, x1, y1, x2, y2, l->Thickness);
224 for (ii = lwidth->Line; ii != NULL; ii = g_list_next (ii))
226 LineType *l = ii->data;
227 Coord x1 = l->Point1.X;
228 Coord y1 = l->Point1.Y;
229 Coord ox, s;
231 s = XYtoSym (x1, y1);
232 ox = (s % 16 + 1) * CELL_SIZE;
233 symbol = &PCB->Font.Symbol[s];
235 x1 -= ox;
237 symbol->Delta = x1 - symbol->Width;
240 SetFontInfo (font);
242 return 0;
245 HID_Action fontmode_action_list[] = {
246 {"FontEdit", 0, FontEdit,
247 fontedit_help, fontedit_syntax},
248 {"FontSave", 0, FontSave,
249 fontsave_help, fontsave_syntax}
252 REGISTER_ACTIONS (fontmode_action_list)