pcb 4.1.1
An interactive printed circuit board layout editor.

fontmode.c

Go to the documentation of this file.
00001 
00039 #ifdef HAVE_CONFIG_H
00040 #include "config.h"
00041 #endif
00042 
00043 #include "global.h"
00044 
00045 #include <math.h>
00046 #include <memory.h>
00047 #include <limits.h>
00048 
00049 
00050 #include "create.h"
00051 #include "data.h"
00052 #include "draw.h"
00053 #include "misc.h"
00054 #include "move.h"
00055 #include "remove.h"
00056 #include "rtree.h"
00057 #include "strflags.h"
00058 #include "undo.h"
00059 #include "pcb-printf.h"
00060 
00061 #ifdef HAVE_LIBDMALLOC
00062 #include <dmalloc.h>
00063 #endif
00064 
00065 #define CELL_SIZE       ((Coord)MIL_TO_COORD(100))
00066 #define CELL_OFFSET     ((Coord)MIL_TO_COORD(10))
00067 
00068 #define XYtoSym(x,y) ((x + CELL_OFFSET) / CELL_SIZE - 1 \
00069                       + 16 * ((y + CELL_OFFSET) / CELL_SIZE - 1))
00070 
00071 static const char fontedit_syntax[] = "FontEdit()";
00072 
00073 static const char fontedit_help[] =
00074   "Convert the current font to a PCB for editing.";
00075 
00076 /* %start-doc actions FontEdit
00077 
00078 This command only allows a font to be edited if the layout being edited contains
00079 font symbols. The existing font symbols are displayed on a layer with an overlaid
00080 grid, with the new version of the font on another layer which can be modified.
00081 Font symbols consist only of lines. The blue lines next to the font symbols
00082 indicate the space required after the symbol when it is used.
00083 
00084 %end-doc */
00085 
00086 static int
00087 FontEdit (int argc, char **argv, Coord Ux, Coord Uy)
00088 {
00089   FontType *font;
00090   SymbolType *symbol;
00091   LayerType *lfont, *lorig, *lwidth, *lgrid;
00092   int s, l;
00093 
00094   if (hid_actionl ("New", "Font", 0))
00095     return 1;
00096 
00097   Settings.grid_unit = get_unit_struct("mil");
00098   Settings.Bloat = PCB->Bloat = 1;
00099   Settings.Shrink = PCB->Shrink = 1;
00100   Settings.minWid = PCB->minWid = 1;
00101   Settings.minSlk = PCB->minSlk = 1;
00102 
00103   MoveLayerToGroup (max_copper_layer + TOP_SILK_LAYER, 0);
00104   MoveLayerToGroup (max_copper_layer + BOTTOM_SILK_LAYER, 1);
00105 
00106   while (PCB->Data->LayerN > 4)
00107     MoveLayer (4, -1);
00108   for (l = 0; l < 4; l++)
00109     {
00110       MoveLayerToGroup (l, l);
00111     }
00112   PCB->MaxWidth = CELL_SIZE * 18;
00113   PCB->MaxHeight = CELL_SIZE * ((MAX_FONTPOSITION + 15) / 16 + 2);
00114   PCB->Grid = MIL_TO_COORD (5);
00115   PCB->Data->Layer[0].Name = strdup ("Font");
00116   PCB->Data->Layer[1].Name = strdup ("OrigFont");
00117   PCB->Data->Layer[2].Name = strdup ("Width");
00118   PCB->Data->Layer[3].Name = strdup ("Grid");
00119   hid_action ("PCBChanged");
00120   hid_action ("LayersChanged");
00121 
00122   lfont = PCB->Data->Layer + 0;
00123   lorig = PCB->Data->Layer + 1;
00124   lwidth = PCB->Data->Layer + 2;
00125   lgrid = PCB->Data->Layer + 3;
00126 
00127   font = &PCB->Font;
00128   for (s = 0; s <= MAX_FONTPOSITION; s++)
00129     {
00130       Coord ox = (s % 16 + 1) * CELL_SIZE;
00131       Coord oy = (s / 16 + 1) * CELL_SIZE;
00132       Coord w, miny, maxy, maxx = 0;
00133 
00134       symbol = &font->Symbol[s];
00135 
00136       miny = MIL_TO_COORD (5);
00137       maxy = font->MaxHeight;
00138 
00139       for (l = 0; l < symbol->LineN; l++)
00140         {
00141           CreateDrawnLineOnLayer (lfont,
00142                                   symbol->Line[l].Point1.X + ox,
00143                                   symbol->Line[l].Point1.Y + oy,
00144                                   symbol->Line[l].Point2.X + ox,
00145                                   symbol->Line[l].Point2.Y + oy,
00146                                   symbol->Line[l].Thickness,
00147                                   symbol->Line[l].Thickness, NoFlags ());
00148           CreateDrawnLineOnLayer (lorig, symbol->Line[l].Point1.X + ox,
00149                                   symbol->Line[l].Point1.Y + oy,
00150                                   symbol->Line[l].Point2.X + ox,
00151                                   symbol->Line[l].Point2.Y + oy,
00152                                   symbol->Line[l].Thickness,
00153                                   symbol->Line[l].Thickness, NoFlags ());
00154           if (maxx < symbol->Line[l].Point1.X)
00155             maxx = symbol->Line[l].Point1.X;
00156           if (maxx < symbol->Line[l].Point2.X)
00157             maxx = symbol->Line[l].Point2.X;
00158         }
00159       w = maxx + symbol->Delta + ox;
00160       CreateDrawnLineOnLayer (lwidth,
00161                               w, miny + oy,
00162                               w, maxy + oy, MIL_TO_COORD (1), MIL_TO_COORD (1), NoFlags ());
00163     }
00164 
00165   for (l = 0; l < 16; l++)
00166     {
00167       int x = (l + 1) * CELL_SIZE;
00168       CreateDrawnLineOnLayer (lgrid, x, 0, x, PCB->MaxHeight, MIL_TO_COORD (1),
00169                               MIL_TO_COORD (1), NoFlags ());
00170     }
00171   for (l = 0; l <= MAX_FONTPOSITION / 16 + 1; l++)
00172     {
00173       int y = (l + 1) * CELL_SIZE;
00174       CreateDrawnLineOnLayer (lgrid, 0, y, PCB->MaxWidth, y, MIL_TO_COORD (1),
00175                               MIL_TO_COORD (1), NoFlags ());
00176     }
00177   return 0;
00178 }
00179 
00180 static const char fontsave_syntax[] = "FontSave()";
00181 
00182 static const char fontsave_help[] = "Convert the current PCB back to a font.";
00183 
00184 /* %start-doc actions FontSave
00185 
00186 Once a font has been modified with the FontEdit command, the layout can be saved
00187 as a new PCB layout. The new PCB layout can then be opened with a text editor so
00188 that the font section can be removed and saved as a new "default_font" file for
00189 use in other PCB layouts.
00190 
00191 %end-doc */
00192 
00193 static int
00194 FontSave (int argc, char **argv, Coord Ux, Coord Uy)
00195 {
00196   FontType *font;
00197   SymbolType *symbol;
00198   int i;
00199   GList *ii;
00200   LayerType *lfont, *lwidth;
00201 
00202   font = &PCB->Font;
00203   lfont = PCB->Data->Layer + 0;
00204   lwidth = PCB->Data->Layer + 2;
00205 
00206   for (i = 0; i <= MAX_FONTPOSITION; i++)
00207     {
00208       font->Symbol[i].LineN = 0;
00209       font->Symbol[i].Valid = 0;
00210       font->Symbol[i].Width = 0;
00211     }
00212 
00213   for (ii = lfont->Line; ii != NULL; ii = g_list_next (ii))
00214     {
00215       LineType *l = ii->data;
00216       Coord x1 = l->Point1.X;
00217       Coord y1 = l->Point1.Y;
00218       Coord x2 = l->Point2.X;
00219       Coord y2 = l->Point2.Y;
00220       Coord ox, oy;
00221       int s;
00222 
00223       s = XYtoSym (x1, y1);
00224       ox = (s % 16 + 1) * CELL_SIZE;
00225       oy = (s / 16 + 1) * CELL_SIZE;
00226       symbol = &PCB->Font.Symbol[s];
00227 
00228       x1 -= ox;
00229       y1 -= oy;
00230       x2 -= ox;
00231       y2 -= oy;
00232 
00233       if (symbol->Width < x1)
00234         symbol->Width = x1;
00235       if (symbol->Width < x2)
00236         symbol->Width = x2;
00237       symbol->Valid = 1;
00238 
00239       CreateNewLineInSymbol (symbol, x1, y1, x2, y2, l->Thickness);
00240     }
00241 
00242   for (ii = lwidth->Line; ii != NULL; ii = g_list_next (ii))
00243     {
00244       LineType *l = ii->data;
00245       Coord x1 = l->Point1.X;
00246       Coord y1 = l->Point1.Y;
00247       Coord ox, s;
00248 
00249       s = XYtoSym (x1, y1);
00250       ox = (s % 16 + 1) * CELL_SIZE;
00251       symbol = &PCB->Font.Symbol[s];
00252 
00253       x1 -= ox;
00254 
00255       symbol->Delta = x1 - symbol->Width;
00256     }
00257 
00258   SetFontInfo (font);
00259   
00260   return 0;
00261 }
00262 
00263 HID_Action fontmode_action_list[] = {
00264   {"FontEdit", 0, FontEdit,
00265    fontedit_help, fontedit_syntax},
00266   {"FontSave", 0, FontSave,
00267    fontsave_help, fontsave_syntax}
00268 };
00269 
00270 REGISTER_ACTIONS (fontmode_action_list)