diff --git a/Makefile b/Makefile index f5b2ba1..8ea9a1e 100644 --- a/Makefile +++ b/Makefile @@ -118,7 +118,7 @@ clean: # ----- Install / uninstall --------------------------------------------------- -install: +install: all install -m 755 fped $(PREFIX)/bin/ uninstall: diff --git a/README b/README index 68ff9a2..b785e45 100644 --- a/README +++ b/README @@ -90,6 +90,7 @@ The file has the following structure: frame definitions ... package name +unit objects ... @@ -125,6 +126,15 @@ set b = 10*1mm All values used as dimensions must be either mm or mil. +The default unit can be set with one of the following directives: + +unit mm +unit mil +unit auto + +When saving a footprint definition, the default unit is set to the +unit set in the GUI. + Vectors - - - - diff --git a/dump.c b/dump.c index 6d2971d..5970500 100644 --- a/dump.c +++ b/dump.c @@ -17,6 +17,7 @@ #include "util.h" #include "unparse.h" #include "obj.h" +#include "gui_status.h" #include "dump.h" @@ -491,6 +492,24 @@ static void dump_frame(FILE *file, struct frame *frame, const char *indent) /* ----- file -------------------------------------------------------------- */ +static void dump_unit(FILE *file) +{ + switch (curr_unit) { + case curr_unit_mm: + fprintf(file, "unit mm\n"); + break; + case curr_unit_mil: + fprintf(file, "unit mil\n"); + break; + case curr_unit_auto: + fprintf(file, "unit auto\n"); + break; + default: + abort(); + } +} + + int dump(FILE *file) { struct frame *frame; @@ -501,6 +520,7 @@ int dump(FILE *file) for (frame = frames; frame; frame = frame->next) { if (!frame->name) { fprintf(file, "package \"%s\"\n", pkg_name); + dump_unit(file); dump_frame(file, frame, ""); } else { dump_frame(file, frame, "\t"); diff --git a/fpd.l b/fpd.l index 5d6f200..b9dc821 100644 --- a/fpd.l +++ b/fpd.l @@ -118,6 +118,8 @@ SP [\t ]* return TOK_MEASX; } "measy" { BEGIN(NOKEYWORD); return TOK_MEASY; } +"unit" { BEGIN(NOKEYWORD); + return TOK_UNIT; } [a-zA-Z_][a-zA-Z_0-9]*: { *strchr(yytext, ':') = 0; yylval.id = unique(yytext); diff --git a/fpd.y b/fpd.y index 8648d4f..e79f071 100644 --- a/fpd.y +++ b/fpd.y @@ -19,6 +19,7 @@ #include "expr.h" #include "obj.h" #include "meas.h" +#include "gui_status.h" #include "fpd.h" @@ -156,7 +157,7 @@ static struct obj *new_obj(enum obj_type type) %token START_FPD START_EXPR START_VAR START_VALUES %token TOK_SET TOK_LOOP TOK_PACKAGE TOK_FRAME TOK_TABLE TOK_VEC %token TOK_PAD TOK_RPAD TOK_RECT TOK_LINE TOK_CIRC TOK_ARC -%token TOK_MEAS TOK_MEASX TOK_MEASY +%token TOK_MEAS TOK_MEASX TOK_MEASY TOK_UNIT %token TOK_NEXT TOK_NEXT_INVERTED TOK_MAX TOK_MAX_INVERTED %token NUMBER @@ -206,7 +207,7 @@ all: ; fpd: - | frame_defs part_name frame_items + | frame_defs part_name opt_unit frame_items ; part_name: @@ -227,6 +228,22 @@ part_name: } ; +opt_unit: + | TOK_UNIT ID + { + if (!strcmp($2, "mm")) + curr_unit = curr_unit_mm; + else if (!strcmp($2, "mil")) + curr_unit = curr_unit_mil; + else if (!strcmp($2, "auto")) + curr_unit = curr_unit_auto; + else { + yyerrorf("unrecognized unit \"%s\"", $2); + YYABORT; + } + } + ; + frame_defs: | frame_defs frame_def ; diff --git a/gui_inst.c b/gui_inst.c index 64b01d5..b279a23 100644 --- a/gui_inst.c +++ b/gui_inst.c @@ -241,13 +241,17 @@ static void gui_draw_pad_text(struct inst *self) GdkGC *gc; struct coord c; unit_type h, w; + int rot; + w = self->bbox.max.x-self->bbox.min.x; + h = self->bbox.max.y-self->bbox.min.y; + rot = w/1.1 < h; gc = gc_ptext[get_mode(self)]; sort_coord(&min, &max); c = add_vec(min, max); h = max.y-min.y; w = max.x-min.x; - render_text(DA, gc, c.x/2, c.y/2, w <= h*1.1 ? 0 : 90, + render_text(DA, gc, c.x/2, c.y/2, rot ? 0 : 90, self->u.pad.name, PAD_FONT, 0.5, 0.5, w-2*PAD_BORDER, h-2*PAD_BORDER); } diff --git a/gui_status.c b/gui_status.c index babd245..839c3d1 100644 --- a/gui_status.c +++ b/gui_status.c @@ -736,25 +736,31 @@ void status_begin_reporting(void) /* ----- unit selection ---------------------------------------------------- */ +static void show_curr_unit(void) +{ + switch (curr_unit) { + case curr_unit_mm: + status_set_unit("mm"); + break; + case curr_unit_mil: + status_set_unit("mil"); + break; + case curr_unit_auto: + status_set_unit("auto"); + break; + default: + abort(); + } +} + + static gboolean unit_button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data) { switch (event->button) { case 1: curr_unit = (curr_unit+1) % curr_unit_n; - switch (curr_unit) { - case curr_unit_mm: - status_set_unit("mm"); - break; - case curr_unit_mil: - status_set_unit("mil"); - break; - case curr_unit_auto: - status_set_unit("auto"); - break; - default: - abort(); - } + show_curr_unit(); break; } refresh_pos(); @@ -859,7 +865,7 @@ void make_status_area(GtkWidget *vbox) /* unit selection */ label_in_box_bg(status_unit, COLOR_UNIT_SELECTOR); - status_set_unit("mm"); + show_curr_unit(); g_signal_connect(G_OBJECT(box_of_label(status_unit)), "button_press_event", G_CALLBACK(unit_button_press_event), NULL); diff --git a/gui_tool.c b/gui_tool.c index 6f0fb51..fa25f45 100644 --- a/gui_tool.c +++ b/gui_tool.c @@ -215,8 +215,19 @@ void tool_selected_inst(struct inst *inst) static struct coord gridify(struct coord base, struct coord pos) { struct coord new; - unit_type unit = mm_to_units(0.1); + unit_type unit; + switch (curr_unit) { + case curr_unit_mm: + case curr_unit_auto: + unit = mm_to_units(0.1); + break; + case curr_unit_mil: + unit = mil_to_units(10); + break; + default: + abort(); + } new.x = pos.x-((pos.x-base.x) % unit); new.y = pos.y-((pos.y-base.y) % unit); if (new.x != base.x || new.y != base.y) @@ -238,8 +249,20 @@ static struct pix_buf *drag_new_vec(struct inst *from, struct coord to) to = gridify(pos, to); status_set_type_x("dX ="); status_set_type_y("dX ="); - status_set_x("%lg mm", units_to_mm(to.x-pos.x)); - status_set_y("%lg mm", units_to_mm(to.y-pos.y)); + /* @@@ use status_set_xy */ + switch (curr_unit) { + case curr_unit_mm: + case curr_unit_auto: + status_set_x("%lg mm", units_to_mm(to.x-pos.x)); + status_set_y("%lg mm", units_to_mm(to.y-pos.y)); + break; + case curr_unit_mil: + status_set_x("%lg mil", units_to_mil(to.x-pos.x)); + status_set_y("%lg mil", units_to_mil(to.y-pos.y)); + break; + default: + abort(); + } pos = translate(pos); to = translate(to); buf = save_pix_buf(DA, pos.x, pos.y, to.x, to.y, 1); @@ -270,8 +293,19 @@ static int end_new_raw_vec(struct inst *from, struct coord to) vec = new_vec(from); pos = inst_get_point(from); to = gridify(pos, to); - vec->x = new_num(make_mm(units_to_mm(to.x-pos.x))); - vec->y = new_num(make_mm(units_to_mm(to.y-pos.y))); + switch (curr_unit) { + case curr_unit_mm: + case curr_unit_auto: + vec->x = new_num(make_mm(units_to_mm(to.x-pos.x))); + vec->y = new_num(make_mm(units_to_mm(to.y-pos.y))); + break; + case curr_unit_mil: + vec->x = new_num(make_mil(units_to_mil(to.x-pos.x))); + vec->y = new_num(make_mil(units_to_mil(to.y-pos.y))); + break; + default: + abort(); + } return 1; } diff --git a/inst.c b/inst.c index db94b43..dbafe7e 100644 --- a/inst.c +++ b/inst.c @@ -208,6 +208,26 @@ int inst_select(struct coord pos) if (selected_inst) goto selected; } + + /* give vectors a second chance */ + + if (show_stuff) { + FOR_ALL_INSTS(i, ip_vec, inst) { + if (!inst->active) + continue; + if (!inst_connected(inst)) + continue; + dist = gui_dist_vec_fallback(inst, pos, draw_ctx.scale); + if (dist >= 0 && (!selected_inst || best_dist > dist)) { + selected_inst = inst; + best_dist = dist; + } + } + + if (selected_inst) + goto selected; + } + if (any_same_frame) { if (activate_item(any_same_frame)) return inst_select(pos); @@ -220,25 +240,7 @@ int inst_select(struct coord pos) } } - if (!show_stuff) - return 0; - - /* give vectors a second chance */ - - FOR_ALL_INSTS(i, ip_vec, inst) { - if (!inst->active) - continue; - if (!inst_connected(inst)) - continue; - dist = gui_dist_vec_fallback(inst, pos, draw_ctx.scale); - if (dist >= 0 && (!selected_inst || best_dist > dist)) { - selected_inst = inst; - best_dist = dist; - } - } - - if (!selected_inst) - return 0; + return 0; selected: inst_select_inst(selected_inst); diff --git a/postscript.c b/postscript.c index dd54a3f..85617e9 100644 --- a/postscript.c +++ b/postscript.c @@ -53,6 +53,8 @@ #define PS_DIVIDER_BORDER mm_to_units(2) #define PS_DIVIDER_WIDTH mm_to_units(0.5) +#define PS_MISC_TEXT_HEIGHT mm_to_units(3) + #define PS_DOT_DIST mm_to_units(0.03) #define PS_DOT_DIAM mm_to_units(0.01) #define PS_HATCH mm_to_units(0.1) @@ -454,7 +456,7 @@ static void ps_hline(FILE *file, int y) { fprintf(file, "gsave %d setlinewidth\n", PS_DIVIDER_WIDTH); fprintf(file, " %d %d moveto\n", -PAGE_HALF_WIDTH, y); - fprintf(file, " %d 0 rlineto stroke gsave\n", PAGE_HALF_WIDTH*2); + fprintf(file, " %d 0 rlineto stroke grestore\n", PAGE_HALF_WIDTH*2); } @@ -488,6 +490,32 @@ static void ps_page(FILE *file, int page) } +static void ps_unit(FILE *file, + unit_type x, unit_type y, unit_type w, unit_type h) +{ + const char *s; + + switch (curr_unit) { + case curr_unit_mm: + s = "Dimensions in mm"; + break; + case curr_unit_mil: + s = "Dimensions in mil"; + break; + case curr_unit_auto: + return; + default: + abort(); + } + + fprintf(file, "gsave %d %d moveto\n", x, y); + fprintf(file, " /Helvetica findfont dup\n"); + fprintf(file, " (%s) %d %d\n", s, w, h); + fprintf(file, " 4 copy 1000 maxfont maxfont scalefont setfont\n"); + fprintf(file, " (%s) show grestore\n", s); +} + + static void ps_package(FILE *file, const struct pkg *pkg, int page) { struct bbox bbox; @@ -504,8 +532,8 @@ static void ps_package(FILE *file, const struct pkg *pkg, int page) y = PAGE_HALF_HEIGHT-PS_HEADER_HEIGHT-3*PS_DIVIDER_BORDER; bbox = inst_get_bbox(); - w = 2*(-bbox.min.y > bbox.max.y ? -bbox.min.y : bbox.max.y); - h = 2*(-bbox.min.x > bbox.max.x ? -bbox.min.x : bbox.max.x); + w = 2*(-bbox.min.x > bbox.max.x ? -bbox.min.x : bbox.max.x); + h = 2*(-bbox.min.y > bbox.max.y ? -bbox.min.y : bbox.max.y); /* * Zoom such that we can fit at least one drawing @@ -574,6 +602,8 @@ static void ps_package(FILE *file, const struct pkg *pkg, int page) } fprintf(file, "grestore\n"); + ps_unit(file, -PAGE_HALF_WIDTH, PS_DIVIDER_BORDER, PAGE_HALF_WIDTH, + PS_MISC_TEXT_HEIGHT); ps_hline(file, 0); /*