mirror of
git://projects.qi-hardware.com/fped.git
synced 2024-11-22 19:59:22 +02:00
- fpd.y: fixed check for empty part name
- added new-style measurements (experimental) git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5400 99fdad57-331a-0410-800a-d7fa5415bdb3
This commit is contained in:
parent
63b4cb912e
commit
d046f9306c
2
Makefile
2
Makefile
@ -11,7 +11,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
OBJS = fped.o expr.o coord.o obj.o delete.o inst.o util.o error.o \
|
OBJS = fped.o expr.o coord.o obj.o delete.o inst.o util.o error.o \
|
||||||
unparse.o dump.o \
|
unparse.o dump.o meas.o \
|
||||||
cpp.o lex.yy.o y.tab.o \
|
cpp.o lex.yy.o y.tab.o \
|
||||||
gui.o gui_util.o gui_style.o gui_inst.o gui_status.o gui_canvas.o \
|
gui.o gui_util.o gui_style.o gui_inst.o gui_status.o gui_canvas.o \
|
||||||
gui_tools.o
|
gui_tools.o
|
||||||
|
42
README
42
README
@ -427,3 +427,45 @@ To delete an object, select it and press Delete. Deleted objects can
|
|||||||
be undeleted by pressing "u". If any other changes have been made
|
be undeleted by pressing "u". If any other changes have been made
|
||||||
since deletion, fped may misbehave. If deleting a vector, all items
|
since deletion, fped may misbehave. If deleting a vector, all items
|
||||||
that reference it are deleted.
|
that reference it are deleted.
|
||||||
|
|
||||||
|
|
||||||
|
Experimental: new-style measurements
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
New-style measurements can measure the distance between various pairs
|
||||||
|
of points, not only between points in the same instance and the same
|
||||||
|
frame. They operate on the set of points produced during instantiation.
|
||||||
|
|
||||||
|
New-style measurements are placed in the root frame after all other
|
||||||
|
items.
|
||||||
|
|
||||||
|
Known issues:
|
||||||
|
- they are currently not dumped and they can't be entered or edited
|
||||||
|
through the GUI
|
||||||
|
-
|
||||||
|
|
||||||
|
Syntax:
|
||||||
|
|
||||||
|
<type> <from> <op> <to> <offset>
|
||||||
|
|
||||||
|
Types:
|
||||||
|
- measxy: measure diagonally
|
||||||
|
- measx: measure along the X axis
|
||||||
|
- measy: measure along the y axis
|
||||||
|
|
||||||
|
Note that the type also affects the selection of the points. E.g.,
|
||||||
|
measx will select maximum x values.
|
||||||
|
|
||||||
|
Operators:
|
||||||
|
- A -> B: smallest value of A and smallest B greater than A
|
||||||
|
- A <- B: like A -> B, but normal (for offset and text) is inverted
|
||||||
|
- A >> B: smallest value of A and greatest value of B
|
||||||
|
- A << B: like A -> B, but normal (for offset and text) is inverted
|
||||||
|
|
||||||
|
Operands are qualified vector names. Vectors in the root frame are
|
||||||
|
referenced by their name. Vectors in other frames are prefixed with
|
||||||
|
the name of the frame followed by a dot.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
measx pad.sw -> pad.se 1mm
|
||||||
|
12
fpd.l
12
fpd.l
@ -18,6 +18,7 @@
|
|||||||
#include "coord.h"
|
#include "coord.h"
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "meas.h"
|
||||||
|
|
||||||
#include "y.tab.h"
|
#include "y.tab.h"
|
||||||
|
|
||||||
@ -94,6 +95,12 @@ SP [\t ]*
|
|||||||
return TOK_ARC; }
|
return TOK_ARC; }
|
||||||
<INITIAL>"meas" { BEGIN(NOKEYWORD);
|
<INITIAL>"meas" { BEGIN(NOKEYWORD);
|
||||||
return TOK_MEAS; }
|
return TOK_MEAS; }
|
||||||
|
<INITIAL>"measxy" { BEGIN(NOKEYWORD);
|
||||||
|
return TOK_MEASXY; }
|
||||||
|
<INITIAL>"measx" { BEGIN(NOKEYWORD);
|
||||||
|
return TOK_MEASX; }
|
||||||
|
<INITIAL>"measy" { BEGIN(NOKEYWORD);
|
||||||
|
return TOK_MEASY; }
|
||||||
|
|
||||||
<INITIAL>[a-zA-Z_][a-zA-Z_0-9]*: { *strchr(yytext, ':') = 0;
|
<INITIAL>[a-zA-Z_][a-zA-Z_0-9]*: { *strchr(yytext, ':') = 0;
|
||||||
yylval.id = unique(yytext);
|
yylval.id = unique(yytext);
|
||||||
@ -118,6 +125,11 @@ SP [\t ]*
|
|||||||
yylval.str = stralloc(yytext+1);
|
yylval.str = stralloc(yytext+1);
|
||||||
return STRING; }
|
return STRING; }
|
||||||
|
|
||||||
|
"->" return TOK_NEXT;
|
||||||
|
"<-" return TOK_NEXT_INVERTED;
|
||||||
|
">>" return TOK_MAX;
|
||||||
|
"<<" return TOK_MAX_INVERTED;
|
||||||
|
|
||||||
{SP} ;
|
{SP} ;
|
||||||
\n { if (!disable_keywords)
|
\n { if (!disable_keywords)
|
||||||
BEGIN(INITIAL);
|
BEGIN(INITIAL);
|
||||||
|
127
fpd.y
127
fpd.y
@ -18,6 +18,7 @@
|
|||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
|
#include "meas.h"
|
||||||
|
|
||||||
|
|
||||||
extern struct expr *expr_result;
|
extern struct expr *expr_result;
|
||||||
@ -48,11 +49,11 @@ static struct frame *find_frame(const char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct vec *find_vec(const char *name)
|
static struct vec *find_vec(const struct frame *frame, const char *name)
|
||||||
{
|
{
|
||||||
struct vec *v;
|
struct vec *v;
|
||||||
|
|
||||||
for (v = curr_frame->vecs; v; v = v->next)
|
for (v = frame->vecs; v; v = v->next)
|
||||||
if (v->name == name)
|
if (v->name == name)
|
||||||
return v;
|
return v;
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -140,12 +141,20 @@ static struct obj *new_obj(enum obj_type type)
|
|||||||
struct value *value;
|
struct value *value;
|
||||||
struct vec *vec;
|
struct vec *vec;
|
||||||
struct obj *obj;
|
struct obj *obj;
|
||||||
|
struct meas *meas;
|
||||||
|
enum meas_type mt;
|
||||||
|
struct {
|
||||||
|
int inverted;
|
||||||
|
int max;
|
||||||
|
} mo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
%token START_FPD START_EXPR
|
%token START_FPD START_EXPR
|
||||||
%token TOK_SET TOK_LOOP TOK_PART TOK_FRAME TOK_TABLE TOK_VEC
|
%token TOK_SET TOK_LOOP TOK_PART TOK_FRAME TOK_TABLE TOK_VEC
|
||||||
%token TOK_PAD TOK_RECT TOK_LINE TOK_CIRC TOK_ARC TOK_MEAS
|
%token TOK_PAD TOK_RECT TOK_LINE TOK_CIRC TOK_ARC
|
||||||
|
%token TOK_MEAS TOK_MEASXY TOK_MEASX TOK_MEASY
|
||||||
|
%token TOK_NEXT TOK_NEXT_INVERTED TOK_MAX TOK_MAX_INVERTED
|
||||||
|
|
||||||
%token <num> NUMBER
|
%token <num> NUMBER
|
||||||
%token <str> STRING
|
%token <str> STRING
|
||||||
@ -155,9 +164,13 @@ static struct obj *new_obj(enum obj_type type)
|
|||||||
%type <var> vars var
|
%type <var> vars var
|
||||||
%type <row> rows
|
%type <row> rows
|
||||||
%type <value> row value
|
%type <value> row value
|
||||||
%type <vec> vec base
|
%type <vec> vec base qbase
|
||||||
%type <obj> obj
|
%type <obj> obj
|
||||||
%type <expr> expr opt_expr add_expr mult_expr unary_expr primary_expr
|
%type <expr> expr opt_expr add_expr mult_expr unary_expr primary_expr
|
||||||
|
%type <meas> measurements meas
|
||||||
|
%type <str> opt_string
|
||||||
|
%type <mt> meas_type
|
||||||
|
%type <mo> meas_op
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
@ -191,7 +204,7 @@ part_name:
|
|||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
|
|
||||||
if (!*p) {
|
if (!*$2) {
|
||||||
yyerrorf("invalid part name");
|
yyerrorf("invalid part name");
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
@ -232,6 +245,10 @@ frame_def:
|
|||||||
;
|
;
|
||||||
|
|
||||||
frame_items:
|
frame_items:
|
||||||
|
measurements
|
||||||
|
{
|
||||||
|
measurements = $1;
|
||||||
|
}
|
||||||
| frame_item frame_items
|
| frame_item frame_items
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -248,7 +265,7 @@ frame_item:
|
|||||||
| vec
|
| vec
|
||||||
| LABEL vec
|
| LABEL vec
|
||||||
{
|
{
|
||||||
if (find_vec($1)) {
|
if (find_vec(curr_frame, $1)) {
|
||||||
yyerrorf("duplicate vector \"%s\"", $1);
|
yyerrorf("duplicate vector \"%s\"", $1);
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
@ -370,6 +387,7 @@ vec:
|
|||||||
$$->y = $6;
|
$$->y = $6;
|
||||||
$$->frame = curr_frame;
|
$$->frame = curr_frame;
|
||||||
$$->next = NULL;
|
$$->next = NULL;
|
||||||
|
$$->samples = NULL;
|
||||||
last_vec = $$;
|
last_vec = $$;
|
||||||
*next_vec = $$;
|
*next_vec = $$;
|
||||||
next_vec = &$$->next;
|
next_vec = &$$->next;
|
||||||
@ -391,7 +409,7 @@ base:
|
|||||||
}
|
}
|
||||||
| ID
|
| ID
|
||||||
{
|
{
|
||||||
$$ = find_vec($1);
|
$$ = find_vec(curr_frame, $1);
|
||||||
if (!$$) {
|
if (!$$) {
|
||||||
yyerrorf("unknown vector \"%s\"", $1);
|
yyerrorf("unknown vector \"%s\"", $1);
|
||||||
YYABORT;
|
YYABORT;
|
||||||
@ -463,6 +481,101 @@ obj:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
measurements:
|
||||||
|
{
|
||||||
|
$$ = NULL;
|
||||||
|
}
|
||||||
|
| meas measurements
|
||||||
|
{
|
||||||
|
$$ = $1;
|
||||||
|
$$->next = $2;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
meas:
|
||||||
|
meas_type opt_string qbase meas_op qbase expr
|
||||||
|
{
|
||||||
|
$$ = alloc_type(struct meas);
|
||||||
|
$$->type = $4.max ? $1+3 : $1;
|
||||||
|
$$->label = $2;
|
||||||
|
$$->low = $3;
|
||||||
|
$$->inverted = $4.inverted;
|
||||||
|
$$->high = $5;
|
||||||
|
$$->offset = $6;
|
||||||
|
$$->next = NULL;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
qbase:
|
||||||
|
ID
|
||||||
|
{
|
||||||
|
$$ = find_vec(root_frame, $1);
|
||||||
|
if (!$$) {
|
||||||
|
yyerrorf("unknown vector \"%s\"", $1);
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
| ID '.' ID
|
||||||
|
{
|
||||||
|
const struct frame *frame;
|
||||||
|
|
||||||
|
frame = find_frame($1);
|
||||||
|
$$ = frame ? find_vec(frame, $3) : NULL;
|
||||||
|
if (!$$) {
|
||||||
|
yyerrorf("unknown vector \"%s.%s\"", $1, $3);
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
meas_type:
|
||||||
|
TOK_MEASXY
|
||||||
|
{
|
||||||
|
$$ = mt_xy_next;
|
||||||
|
}
|
||||||
|
| TOK_MEASX
|
||||||
|
{
|
||||||
|
$$ = mt_x_next;
|
||||||
|
}
|
||||||
|
| TOK_MEASY
|
||||||
|
{
|
||||||
|
$$ = mt_y_next;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
meas_op:
|
||||||
|
TOK_NEXT
|
||||||
|
{
|
||||||
|
$$.max = 0;
|
||||||
|
$$.inverted = 0;
|
||||||
|
}
|
||||||
|
| TOK_NEXT_INVERTED
|
||||||
|
{
|
||||||
|
$$.max = 0;
|
||||||
|
$$.inverted = 1;
|
||||||
|
}
|
||||||
|
| TOK_MAX
|
||||||
|
{
|
||||||
|
$$.max = 1;
|
||||||
|
$$.inverted = 0;
|
||||||
|
}
|
||||||
|
| TOK_MAX_INVERTED
|
||||||
|
{
|
||||||
|
$$.max = 1;
|
||||||
|
$$.inverted = 1;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
opt_string:
|
||||||
|
{
|
||||||
|
$$ = NULL;
|
||||||
|
}
|
||||||
|
| STRING
|
||||||
|
{
|
||||||
|
$$ = $1;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
opt_expr:
|
opt_expr:
|
||||||
{
|
{
|
||||||
$$ = NULL;
|
$$ = NULL;
|
||||||
|
42
gui_inst.c
42
gui_inst.c
@ -16,6 +16,7 @@
|
|||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "coord.h"
|
||||||
#include "inst.h"
|
#include "inst.h"
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
#include "gui_util.h"
|
#include "gui_util.h"
|
||||||
@ -329,13 +330,12 @@ void gui_draw_arc(struct inst *self, struct draw_ctx *ctx)
|
|||||||
/* ----- meas -------------------------------------------------------------- */
|
/* ----- meas -------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
static struct coord offset_vec(const struct inst *self)
|
static struct coord offset_vec(struct coord a, struct coord b,
|
||||||
|
const struct inst *self)
|
||||||
{
|
{
|
||||||
struct coord a, b, res;
|
struct coord res;
|
||||||
double f;
|
double f;
|
||||||
|
|
||||||
a = self->base;
|
|
||||||
b = self->u.meas.end;
|
|
||||||
res.x = a.y-b.y;
|
res.x = a.y-b.y;
|
||||||
res.y = b.x-a.x;
|
res.y = b.x-a.x;
|
||||||
if (res.x == 0 && res.y == 0)
|
if (res.x == 0 && res.y == 0)
|
||||||
@ -352,7 +352,7 @@ unit_type gui_dist_meas(struct inst *self, struct coord pos, unit_type scale)
|
|||||||
struct coord a, b, off;
|
struct coord a, b, off;
|
||||||
unit_type d;
|
unit_type d;
|
||||||
|
|
||||||
off = offset_vec(self);
|
off = offset_vec(self->base, self->u.meas.end, self);
|
||||||
a = add_vec(self->base, off);
|
a = add_vec(self->base, off);
|
||||||
b = add_vec(self->u.meas.end, off);
|
b = add_vec(self->u.meas.end, off);
|
||||||
d = dist_line(pos, a, b)/scale;
|
d = dist_line(pos, a, b)/scale;
|
||||||
@ -364,13 +364,34 @@ void gui_draw_meas(struct inst *self, struct draw_ctx *ctx)
|
|||||||
{
|
{
|
||||||
struct coord a0, b0, a1, b1, off, c, d;
|
struct coord a0, b0, a1, b1, off, c, d;
|
||||||
GdkGC *gc;
|
GdkGC *gc;
|
||||||
|
double len;
|
||||||
|
const char *label = self->u.meas.meas ?
|
||||||
|
self->u.meas.meas->label ? self->u.meas.meas->label : "" : "";
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
off = offset_vec(self);
|
|
||||||
a0 = translate(ctx, self->base);
|
a0 = translate(ctx, self->base);
|
||||||
b0 = translate(ctx, self->u.meas.end);
|
b0 = translate(ctx, self->u.meas.end);
|
||||||
a1 = translate(ctx, add_vec(self->base, off));
|
a1 = self->base;
|
||||||
b1 = translate(ctx, add_vec(self->u.meas.end, off));
|
b1 = self->u.meas.end;
|
||||||
|
switch (self->u.meas.meas ? self->u.meas.meas->type : mt_xy_next) {
|
||||||
|
case mt_xy_next:
|
||||||
|
case mt_xy_max:
|
||||||
|
break;
|
||||||
|
case mt_x_next:
|
||||||
|
case mt_x_max:
|
||||||
|
b1.y = a1.y;
|
||||||
|
break;
|
||||||
|
case mt_y_next:
|
||||||
|
case mt_y_max:
|
||||||
|
b1.x = a1.x;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
off = offset_vec(a1, b1, self);
|
||||||
|
len = units_to_mm(dist_point(a1, b1));
|
||||||
|
a1 = translate(ctx, add_vec(a1, off));
|
||||||
|
b1 = translate(ctx, add_vec(b1, off));
|
||||||
gc = gc_meas[get_mode(self)];
|
gc = gc_meas[get_mode(self)];
|
||||||
gdk_draw_line(DA, gc, a0.x, a0.y, a1.x, a1.y);
|
gdk_draw_line(DA, gc, a0.x, a0.y, a1.x, a1.y);
|
||||||
gdk_draw_line(DA, gc, b0.x, b0.y, b1.x, b1.y);
|
gdk_draw_line(DA, gc, b0.x, b0.y, b1.x, b1.y);
|
||||||
@ -379,9 +400,8 @@ void gui_draw_meas(struct inst *self, struct draw_ctx *ctx)
|
|||||||
draw_arrow(ctx, gc, FALSE, b1, a1, MEAS_ARROW_LEN, MEAS_ARROW_ANGLE);
|
draw_arrow(ctx, gc, FALSE, b1, a1, MEAS_ARROW_LEN, MEAS_ARROW_ANGLE);
|
||||||
|
|
||||||
c = add_vec(a1, b1);
|
c = add_vec(a1, b1);
|
||||||
d = sub_vec(b0, a0);
|
d = sub_vec(b1, a1);
|
||||||
s = stralloc_printf("%lgmm",
|
s = stralloc_printf("%s%lgmm", label, len);
|
||||||
units_to_mm(dist_point(self->base, self->u.meas.end)));
|
|
||||||
render_text(DA, gc, c.x/2, c.y/2, -atan2(d.y, d.x)/M_PI*180, s,
|
render_text(DA, gc, c.x/2, c.y/2, -atan2(d.y, d.x)/M_PI*180, s,
|
||||||
MEAS_FONT, 0.5, -MEAS_BASELINE_OFFSET,
|
MEAS_FONT, 0.5, -MEAS_BASELINE_OFFSET,
|
||||||
dist_point(a1, b1)-1.5*MEAS_ARROW_LEN, 0);
|
dist_point(a1, b1)-1.5*MEAS_ARROW_LEN, 0);
|
||||||
|
18
inst.c
18
inst.c
@ -291,8 +291,11 @@ static void update_bbox(struct bbox *bbox, struct coord coord)
|
|||||||
|
|
||||||
static void propagate_bbox(const struct inst *inst)
|
static void propagate_bbox(const struct inst *inst)
|
||||||
{
|
{
|
||||||
update_bbox(&curr_frame->bbox, inst->bbox.min);
|
/* @@@ for new-style measurements */
|
||||||
update_bbox(&curr_frame->bbox, inst->bbox.max);
|
struct inst *frame = curr_frame ? curr_frame : insts[ip_frame];
|
||||||
|
|
||||||
|
update_bbox(&frame->bbox, inst->bbox.min);
|
||||||
|
update_bbox(&frame->bbox, inst->bbox.max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -640,6 +643,8 @@ static void meas_op_select(struct inst *self)
|
|||||||
rect_status(self->bbox.min, self->bbox.max, -1);
|
rect_status(self->bbox.min, self->bbox.max, -1);
|
||||||
status_set_type_entry("offset =");
|
status_set_type_entry("offset =");
|
||||||
status_set_name("%5.2f mm", units_to_mm(self->u.meas.offset));
|
status_set_name("%5.2f mm", units_to_mm(self->u.meas.offset));
|
||||||
|
if (!self->obj)
|
||||||
|
return; /* @@@ new-style measurements */
|
||||||
edit_expr(&self->obj->u.meas.offset, 0);
|
edit_expr(&self->obj->u.meas.offset, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -648,6 +653,8 @@ static int meas_op_anchors(struct inst *inst, struct vec ***anchors)
|
|||||||
{
|
{
|
||||||
struct obj *obj = inst->obj;
|
struct obj *obj = inst->obj;
|
||||||
|
|
||||||
|
if (!inst->obj)
|
||||||
|
return 0; /* @@@ new-style measurements */
|
||||||
anchors[0] = &obj->base;
|
anchors[0] = &obj->base;
|
||||||
anchors[1] = &obj->u.meas.other;
|
anchors[1] = &obj->u.meas.other;
|
||||||
return 2;
|
return 2;
|
||||||
@ -664,8 +671,8 @@ static struct inst_ops meas_ops = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int inst_meas(struct obj *obj, struct coord from, struct coord to,
|
int inst_meas(struct obj *obj, struct meas *meas,
|
||||||
unit_type offset)
|
struct coord from, struct coord to, unit_type offset)
|
||||||
{
|
{
|
||||||
struct inst *inst;
|
struct inst *inst;
|
||||||
|
|
||||||
@ -673,6 +680,9 @@ int inst_meas(struct obj *obj, struct coord from, struct coord to,
|
|||||||
inst->obj = obj;
|
inst->obj = obj;
|
||||||
inst->u.meas.end = to;
|
inst->u.meas.end = to;
|
||||||
inst->u.meas.offset = offset;
|
inst->u.meas.offset = offset;
|
||||||
|
inst->u.meas.meas = meas;
|
||||||
|
if (!obj)
|
||||||
|
inst->active = 1; /* @@@ new-style measurements */
|
||||||
/* @@@ our bbox is actually a bit more complex than this */
|
/* @@@ our bbox is actually a bit more complex than this */
|
||||||
update_bbox(&inst->bbox, to);
|
update_bbox(&inst->bbox, to);
|
||||||
propagate_bbox(inst);
|
propagate_bbox(inst);
|
||||||
|
6
inst.h
6
inst.h
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "coord.h"
|
#include "coord.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
|
#include "meas.h"
|
||||||
|
|
||||||
|
|
||||||
enum mode {
|
enum mode {
|
||||||
@ -70,6 +71,7 @@ struct inst {
|
|||||||
struct {
|
struct {
|
||||||
struct coord end;
|
struct coord end;
|
||||||
double offset;
|
double offset;
|
||||||
|
struct meas *meas; /* new-style measurement */
|
||||||
} meas;
|
} meas;
|
||||||
} u;
|
} u;
|
||||||
struct inst *next;
|
struct inst *next;
|
||||||
@ -95,8 +97,8 @@ int inst_rect(struct obj *obj, struct coord a, struct coord b, unit_type width);
|
|||||||
int inst_pad(struct obj *obj, const char *name, struct coord a, struct coord b);
|
int inst_pad(struct obj *obj, const char *name, struct coord a, struct coord b);
|
||||||
int inst_arc(struct obj *obj, struct coord center, struct coord start,
|
int inst_arc(struct obj *obj, struct coord center, struct coord start,
|
||||||
struct coord stop, unit_type width);
|
struct coord stop, unit_type width);
|
||||||
int inst_meas(struct obj *obj, struct coord from, struct coord to,
|
int inst_meas(struct obj *obj, struct meas *meas,
|
||||||
unit_type offset);
|
struct coord from, struct coord to, unit_type offset);
|
||||||
|
|
||||||
void inst_begin_active(int active);
|
void inst_begin_active(int active);
|
||||||
void inst_end_active(void);
|
void inst_end_active(void);
|
||||||
|
193
meas.c
Normal file
193
meas.c
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
/*
|
||||||
|
* meas.c - Measurements
|
||||||
|
*
|
||||||
|
* Written 2009 by Werner Almesberger
|
||||||
|
* Copyright 2009 by Werner Almesberger
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
#include "coord.h"
|
||||||
|
#include "expr.h"
|
||||||
|
#include "obj.h"
|
||||||
|
#include "inst.h"
|
||||||
|
#include "meas.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct num eval_unit(const struct expr *expr, const struct frame *frame);
|
||||||
|
|
||||||
|
struct sample {
|
||||||
|
struct coord pos;
|
||||||
|
struct sample *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct meas *measurements = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
static void reset_samples(struct sample **samples)
|
||||||
|
{
|
||||||
|
struct sample *next;
|
||||||
|
|
||||||
|
while (*samples) {
|
||||||
|
next = (*samples)->next;
|
||||||
|
free(*samples);
|
||||||
|
*samples = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void meas_start(void)
|
||||||
|
{
|
||||||
|
struct frame *frame;
|
||||||
|
struct vec *vec;
|
||||||
|
|
||||||
|
for (frame = frames; frame; frame = frame->next)
|
||||||
|
for (vec = frame->vecs; vec; vec = vec->next)
|
||||||
|
reset_samples(&vec->samples);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void meas_post(struct vec *vec, struct coord pos)
|
||||||
|
{
|
||||||
|
struct sample **walk, *new;
|
||||||
|
|
||||||
|
for (walk = &vec->samples; *walk; walk = &(*walk)->next) {
|
||||||
|
if (pos.y < (*walk)->pos.y)
|
||||||
|
break;
|
||||||
|
if (pos.y > (*walk)->pos.y)
|
||||||
|
continue;
|
||||||
|
if (pos.x < (*walk)->pos.x)
|
||||||
|
break;
|
||||||
|
if (pos.x == (*walk)->pos.x)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
new = alloc_type(struct sample);
|
||||||
|
new->pos = pos;
|
||||||
|
new->next = *walk;
|
||||||
|
*walk = new;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int lt_x(struct coord a, struct coord b)
|
||||||
|
{
|
||||||
|
return a.x < b.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int lt_y(struct coord a, struct coord b)
|
||||||
|
{
|
||||||
|
return a.y < b.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int lt_xy(struct coord a, struct coord b)
|
||||||
|
{
|
||||||
|
return a.y < b.y || (a.y == b.y && a.x < b.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int (*lt_op[mt_n])(struct coord a, struct coord b) = {
|
||||||
|
lt_xy,
|
||||||
|
lt_x,
|
||||||
|
lt_y,
|
||||||
|
lt_xy,
|
||||||
|
lt_x,
|
||||||
|
lt_y
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int is_next[mt_n] = {
|
||||||
|
1, 1, 1,
|
||||||
|
0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int better_next(int (*lt)(struct coord a, struct coord b),
|
||||||
|
struct coord a0, struct coord b0, struct coord b)
|
||||||
|
{
|
||||||
|
/* if we don't have any suitable point A0 < B0 yet, use this one */
|
||||||
|
if (!lt(a0, b0))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* B must be strictly greater than A0 */
|
||||||
|
if (!lt(a0, b))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* if we can get closer to A0, do so */
|
||||||
|
if (lt(b, b0))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* reject B > B0 */
|
||||||
|
if (lt(b0, b))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* B == B0 along the coordinate we measure. Now give the other
|
||||||
|
* coordinate a chance. This gives us a stable sort order and it
|
||||||
|
* makes meas/measx/measy usually select the same point.
|
||||||
|
*/
|
||||||
|
if (lt == lt_xy)
|
||||||
|
return 0;
|
||||||
|
if (lt == lt_x)
|
||||||
|
return better_next(lt_y, a0, b0, b);
|
||||||
|
if (lt == lt_y)
|
||||||
|
return better_next(lt_x, a0, b0, b);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int instantiate_meas(void)
|
||||||
|
{
|
||||||
|
struct meas *meas;
|
||||||
|
struct coord a0, b0;
|
||||||
|
const struct sample *a, *b;
|
||||||
|
int (*lt)(struct coord a, struct coord b);
|
||||||
|
struct num offset;
|
||||||
|
|
||||||
|
for (meas = measurements; meas; meas = meas->next) {
|
||||||
|
if (!meas->low->samples || !meas->high->samples)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
lt = lt_op[meas->type];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In order to obtain a stable order, we sort points equal on
|
||||||
|
* the measured coordinate also by xy:
|
||||||
|
*
|
||||||
|
* if (*a < a0) use *a
|
||||||
|
* else if (*a == a0 && *a <xy a0) use *a
|
||||||
|
*/
|
||||||
|
a0 = meas->low->samples->pos;
|
||||||
|
for (a = meas->low->samples; a; a = a->next)
|
||||||
|
if (lt(a->pos, a0) ||
|
||||||
|
(!lt(a0, a->pos) && lt_xy(a->pos, a0)))
|
||||||
|
a0 = a->pos;
|
||||||
|
|
||||||
|
b0 = meas->high->samples->pos;
|
||||||
|
for (b = meas->high->samples; b; b = b->next) {
|
||||||
|
if (is_next[meas->type]) {
|
||||||
|
if (better_next(lt, a0, b0, b->pos))
|
||||||
|
b0 = b->pos;
|
||||||
|
} else {
|
||||||
|
if (lt(b0, b->pos) ||
|
||||||
|
(!lt(b->pos, b0) && lt_xy(b0, b->pos)))
|
||||||
|
b0 = b->pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
offset = eval_unit(meas->offset, root_frame);
|
||||||
|
if (is_undef(offset))
|
||||||
|
return 0;
|
||||||
|
inst_meas(NULL, meas,
|
||||||
|
meas->inverted ? b0 : a0, meas->inverted ? a0 : b0,
|
||||||
|
offset.n);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
24
meas.fpd
Normal file
24
meas.fpd
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* new-style measurements demo
|
||||||
|
*/
|
||||||
|
|
||||||
|
part "measurements"
|
||||||
|
loop x = -2, 2
|
||||||
|
A: vec @(0mm, 0mm)
|
||||||
|
B: vec @(x*2mm, 2mm)
|
||||||
|
C: vec @(0mm, 4mm)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we measure (x, y), y trumps x
|
||||||
|
*/
|
||||||
|
measxy "A -> B = " A -> B 0.2mm
|
||||||
|
measxy "A <- B = " A <- B 0.5mm
|
||||||
|
|
||||||
|
measxy "A >> B = " A >> B 1.5mm
|
||||||
|
|
||||||
|
measx "x(A -> B) = " A -> B -0.5mm
|
||||||
|
measx "x(A >> B) = " A >> B -1mm
|
||||||
|
measy "y(A -> B) = " A -> B -2mm
|
||||||
|
measy "y(A >> B) = " A >> B -4.5mm
|
||||||
|
|
||||||
|
measxy "B -> C = " B -> C 0.5mm
|
46
meas.h
Normal file
46
meas.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* meas.h - Measurements
|
||||||
|
*
|
||||||
|
* Written 2009 by Werner Almesberger
|
||||||
|
* Copyright 2009 by Werner Almesberger
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MEAS_H
|
||||||
|
#define MEAS_H
|
||||||
|
|
||||||
|
#include "obj.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct meas {
|
||||||
|
enum meas_type {
|
||||||
|
mt_xy_next,
|
||||||
|
mt_x_next,
|
||||||
|
mt_y_next,
|
||||||
|
mt_xy_max,
|
||||||
|
mt_x_max,
|
||||||
|
mt_y_max,
|
||||||
|
mt_n
|
||||||
|
} type;
|
||||||
|
char *label; /* or NULL */
|
||||||
|
int inverted;
|
||||||
|
struct vec *low;
|
||||||
|
struct vec *high;
|
||||||
|
struct expr *offset;
|
||||||
|
struct meas *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
extern struct meas *measurements;
|
||||||
|
|
||||||
|
|
||||||
|
void meas_start(void);
|
||||||
|
void meas_post(struct vec *vec, struct coord pos);
|
||||||
|
int instantiate_meas(void);
|
||||||
|
|
||||||
|
#endif /* !MEAS_H */
|
11
obj.c
11
obj.c
@ -18,6 +18,7 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
|
#include "meas.h"
|
||||||
#include "inst.h"
|
#include "inst.h"
|
||||||
#include "obj.h"
|
#include "obj.h"
|
||||||
|
|
||||||
@ -37,7 +38,8 @@ static int generate_frame(struct frame *frame, struct coord base,
|
|||||||
const struct frame *parent, struct obj *frame_ref, int active);
|
const struct frame *parent, struct obj *frame_ref, int active);
|
||||||
|
|
||||||
|
|
||||||
static struct num eval_unit(const struct expr *expr, const struct frame *frame)
|
struct num eval_unit(const struct expr *expr, const struct frame *frame);
|
||||||
|
/*static*/ struct num eval_unit(const struct expr *expr, const struct frame *frame)
|
||||||
{
|
{
|
||||||
struct num d;
|
struct num d;
|
||||||
|
|
||||||
@ -78,6 +80,7 @@ static int generate_vecs(struct frame *frame, struct coord base)
|
|||||||
vec->pos.y += y.n;
|
vec->pos.y += y.n;
|
||||||
if (!inst_vec(vec, vec_base))
|
if (!inst_vec(vec, vec_base))
|
||||||
return 0;
|
return 0;
|
||||||
|
meas_post(vec, vec->pos);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -144,7 +147,8 @@ static int generate_objs(struct frame *frame, struct coord base, int active)
|
|||||||
offset = eval_unit(obj->u.meas.offset, frame);
|
offset = eval_unit(obj->u.meas.offset, frame);
|
||||||
if (is_undef(offset))
|
if (is_undef(offset))
|
||||||
return 0;
|
return 0;
|
||||||
if (!inst_meas(obj, obj->base ? obj->base->pos : base,
|
if (!inst_meas(obj, NULL,
|
||||||
|
obj->base ? obj->base->pos : base,
|
||||||
obj->u.meas.other ? obj->u.meas.other->pos : base,
|
obj->u.meas.other ? obj->u.meas.other->pos : base,
|
||||||
offset.n))
|
offset.n))
|
||||||
return 0;
|
return 0;
|
||||||
@ -261,7 +265,10 @@ int instantiate(void)
|
|||||||
int ok;
|
int ok;
|
||||||
|
|
||||||
inst_start();
|
inst_start();
|
||||||
|
meas_start();
|
||||||
ok = generate_frame(root_frame, zero, NULL, NULL, 1);
|
ok = generate_frame(root_frame, zero, NULL, NULL, 1);
|
||||||
|
if (ok)
|
||||||
|
ok = instantiate_meas();
|
||||||
if (ok)
|
if (ok)
|
||||||
inst_commit();
|
inst_commit();
|
||||||
else
|
else
|
||||||
|
9
obj.h
9
obj.h
@ -84,6 +84,8 @@ struct loop {
|
|||||||
int initialized;
|
int initialized;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct sample;
|
||||||
|
|
||||||
struct vec {
|
struct vec {
|
||||||
const char *name; /* NULL if anonymous */
|
const char *name; /* NULL if anonymous */
|
||||||
struct expr *x;
|
struct expr *x;
|
||||||
@ -96,6 +98,9 @@ struct vec {
|
|||||||
|
|
||||||
/* used when editing */
|
/* used when editing */
|
||||||
struct frame *frame;
|
struct frame *frame;
|
||||||
|
|
||||||
|
/* samples for measurements */
|
||||||
|
struct sample *samples;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct frame {
|
struct frame {
|
||||||
@ -147,7 +152,7 @@ struct arc {
|
|||||||
struct expr *width;
|
struct expr *width;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct meas {
|
struct old_meas {
|
||||||
struct vec *other; /* NULL if frame origin */
|
struct vec *other; /* NULL if frame origin */
|
||||||
struct expr *offset;
|
struct expr *offset;
|
||||||
};
|
};
|
||||||
@ -160,7 +165,7 @@ struct obj {
|
|||||||
struct rect line;
|
struct rect line;
|
||||||
struct pad pad;
|
struct pad pad;
|
||||||
struct arc arc;
|
struct arc arc;
|
||||||
struct meas meas;
|
struct old_meas meas;
|
||||||
} u;
|
} u;
|
||||||
struct frame *frame;
|
struct frame *frame;
|
||||||
struct vec *base;
|
struct vec *base;
|
||||||
|
14
sc89.fpd
14
sc89.fpd
@ -1,12 +1,12 @@
|
|||||||
/* MACHINE-GENERATED ! */
|
/* MACHINE-GENERATED ! */
|
||||||
|
|
||||||
frame pad {
|
frame pad {
|
||||||
_pad_0: vec @(-Px/2, -Py/2)
|
sw: vec @(-Px/2, -Py/2)
|
||||||
_pad_1: vec .(Px, 0mm)
|
se: vec sw(Px, 0mm)
|
||||||
_pad_2: vec _pad_0(0mm, Py)
|
nw: vec sw(0mm, Py)
|
||||||
pad "$pad" _pad_1 _pad_2
|
pad "$pad" se nw
|
||||||
meas _pad_0 _pad_1 -0.1mm
|
// meas sw se -0.1mm
|
||||||
meas _pad_0 _pad_2 0.1mm
|
// meas sw nw 0.1mm
|
||||||
}
|
}
|
||||||
|
|
||||||
frame pad_ne {
|
frame pad_ne {
|
||||||
@ -41,3 +41,5 @@ __2: vec @(Gx/2, -Gy/2)
|
|||||||
frame pad_sc __0
|
frame pad_sc __0
|
||||||
frame pad_nw __1
|
frame pad_nw __1
|
||||||
frame pad_ne __2
|
frame pad_ne __2
|
||||||
|
|
||||||
|
measx pad.sw -> pad.se 1mm
|
||||||
|
Loading…
Reference in New Issue
Block a user