mirror of
git://projects.qi-hardware.com/fped.git
synced 2024-11-22 14:31:53 +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 \
|
||||
unparse.o dump.o \
|
||||
unparse.o dump.o meas.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_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
|
||||
since deletion, fped may misbehave. If deleting a vector, all items
|
||||
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 "expr.h"
|
||||
#include "error.h"
|
||||
#include "meas.h"
|
||||
|
||||
#include "y.tab.h"
|
||||
|
||||
@ -94,6 +95,12 @@ SP [\t ]*
|
||||
return TOK_ARC; }
|
||||
<INITIAL>"meas" { BEGIN(NOKEYWORD);
|
||||
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;
|
||||
yylval.id = unique(yytext);
|
||||
@ -118,6 +125,11 @@ SP [\t ]*
|
||||
yylval.str = stralloc(yytext+1);
|
||||
return STRING; }
|
||||
|
||||
"->" return TOK_NEXT;
|
||||
"<-" return TOK_NEXT_INVERTED;
|
||||
">>" return TOK_MAX;
|
||||
"<<" return TOK_MAX_INVERTED;
|
||||
|
||||
{SP} ;
|
||||
\n { if (!disable_keywords)
|
||||
BEGIN(INITIAL);
|
||||
|
127
fpd.y
127
fpd.y
@ -18,6 +18,7 @@
|
||||
#include "error.h"
|
||||
#include "expr.h"
|
||||
#include "obj.h"
|
||||
#include "meas.h"
|
||||
|
||||
|
||||
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;
|
||||
|
||||
for (v = curr_frame->vecs; v; v = v->next)
|
||||
for (v = frame->vecs; v; v = v->next)
|
||||
if (v->name == name)
|
||||
return v;
|
||||
return NULL;
|
||||
@ -140,12 +141,20 @@ static struct obj *new_obj(enum obj_type type)
|
||||
struct value *value;
|
||||
struct vec *vec;
|
||||
struct obj *obj;
|
||||
struct meas *meas;
|
||||
enum meas_type mt;
|
||||
struct {
|
||||
int inverted;
|
||||
int max;
|
||||
} mo;
|
||||
};
|
||||
|
||||
|
||||
%token START_FPD START_EXPR
|
||||
%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 <str> STRING
|
||||
@ -155,9 +164,13 @@ static struct obj *new_obj(enum obj_type type)
|
||||
%type <var> vars var
|
||||
%type <row> rows
|
||||
%type <value> row value
|
||||
%type <vec> vec base
|
||||
%type <vec> vec base qbase
|
||||
%type <obj> obj
|
||||
%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;
|
||||
|
||||
if (!*p) {
|
||||
if (!*$2) {
|
||||
yyerrorf("invalid part name");
|
||||
YYABORT;
|
||||
}
|
||||
@ -232,6 +245,10 @@ frame_def:
|
||||
;
|
||||
|
||||
frame_items:
|
||||
measurements
|
||||
{
|
||||
measurements = $1;
|
||||
}
|
||||
| frame_item frame_items
|
||||
;
|
||||
|
||||
@ -248,7 +265,7 @@ frame_item:
|
||||
| vec
|
||||
| LABEL vec
|
||||
{
|
||||
if (find_vec($1)) {
|
||||
if (find_vec(curr_frame, $1)) {
|
||||
yyerrorf("duplicate vector \"%s\"", $1);
|
||||
YYABORT;
|
||||
}
|
||||
@ -370,6 +387,7 @@ vec:
|
||||
$$->y = $6;
|
||||
$$->frame = curr_frame;
|
||||
$$->next = NULL;
|
||||
$$->samples = NULL;
|
||||
last_vec = $$;
|
||||
*next_vec = $$;
|
||||
next_vec = &$$->next;
|
||||
@ -391,7 +409,7 @@ base:
|
||||
}
|
||||
| ID
|
||||
{
|
||||
$$ = find_vec($1);
|
||||
$$ = find_vec(curr_frame, $1);
|
||||
if (!$$) {
|
||||
yyerrorf("unknown vector \"%s\"", $1);
|
||||
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:
|
||||
{
|
||||
$$ = NULL;
|
||||
|
42
gui_inst.c
42
gui_inst.c
@ -16,6 +16,7 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "coord.h"
|
||||
#include "inst.h"
|
||||
#include "gui.h"
|
||||
#include "gui_util.h"
|
||||
@ -329,13 +330,12 @@ void gui_draw_arc(struct inst *self, struct draw_ctx *ctx)
|
||||
/* ----- 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;
|
||||
|
||||
a = self->base;
|
||||
b = self->u.meas.end;
|
||||
res.x = a.y-b.y;
|
||||
res.y = b.x-a.x;
|
||||
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;
|
||||
unit_type d;
|
||||
|
||||
off = offset_vec(self);
|
||||
off = offset_vec(self->base, self->u.meas.end, self);
|
||||
a = add_vec(self->base, off);
|
||||
b = add_vec(self->u.meas.end, off);
|
||||
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;
|
||||
GdkGC *gc;
|
||||
double len;
|
||||
const char *label = self->u.meas.meas ?
|
||||
self->u.meas.meas->label ? self->u.meas.meas->label : "" : "";
|
||||
char *s;
|
||||
|
||||
off = offset_vec(self);
|
||||
a0 = translate(ctx, self->base);
|
||||
b0 = translate(ctx, self->u.meas.end);
|
||||
a1 = translate(ctx, add_vec(self->base, off));
|
||||
b1 = translate(ctx, add_vec(self->u.meas.end, off));
|
||||
a1 = self->base;
|
||||
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)];
|
||||
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);
|
||||
@ -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);
|
||||
|
||||
c = add_vec(a1, b1);
|
||||
d = sub_vec(b0, a0);
|
||||
s = stralloc_printf("%lgmm",
|
||||
units_to_mm(dist_point(self->base, self->u.meas.end)));
|
||||
d = sub_vec(b1, a1);
|
||||
s = stralloc_printf("%s%lgmm", label, len);
|
||||
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,
|
||||
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)
|
||||
{
|
||||
update_bbox(&curr_frame->bbox, inst->bbox.min);
|
||||
update_bbox(&curr_frame->bbox, inst->bbox.max);
|
||||
/* @@@ for new-style measurements */
|
||||
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);
|
||||
status_set_type_entry("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);
|
||||
}
|
||||
|
||||
@ -648,6 +653,8 @@ static int meas_op_anchors(struct inst *inst, struct vec ***anchors)
|
||||
{
|
||||
struct obj *obj = inst->obj;
|
||||
|
||||
if (!inst->obj)
|
||||
return 0; /* @@@ new-style measurements */
|
||||
anchors[0] = &obj->base;
|
||||
anchors[1] = &obj->u.meas.other;
|
||||
return 2;
|
||||
@ -664,8 +671,8 @@ static struct inst_ops meas_ops = {
|
||||
};
|
||||
|
||||
|
||||
int inst_meas(struct obj *obj, struct coord from, struct coord to,
|
||||
unit_type offset)
|
||||
int inst_meas(struct obj *obj, struct meas *meas,
|
||||
struct coord from, struct coord to, unit_type offset)
|
||||
{
|
||||
struct inst *inst;
|
||||
|
||||
@ -673,6 +680,9 @@ int inst_meas(struct obj *obj, struct coord from, struct coord to,
|
||||
inst->obj = obj;
|
||||
inst->u.meas.end = to;
|
||||
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 */
|
||||
update_bbox(&inst->bbox, to);
|
||||
propagate_bbox(inst);
|
||||
|
6
inst.h
6
inst.h
@ -18,6 +18,7 @@
|
||||
|
||||
#include "coord.h"
|
||||
#include "obj.h"
|
||||
#include "meas.h"
|
||||
|
||||
|
||||
enum mode {
|
||||
@ -70,6 +71,7 @@ struct inst {
|
||||
struct {
|
||||
struct coord end;
|
||||
double offset;
|
||||
struct meas *meas; /* new-style measurement */
|
||||
} meas;
|
||||
} u;
|
||||
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_arc(struct obj *obj, struct coord center, struct coord start,
|
||||
struct coord stop, unit_type width);
|
||||
int inst_meas(struct obj *obj, struct coord from, struct coord to,
|
||||
unit_type offset);
|
||||
int inst_meas(struct obj *obj, struct meas *meas,
|
||||
struct coord from, struct coord to, unit_type offset);
|
||||
|
||||
void inst_begin_active(int active);
|
||||
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 "error.h"
|
||||
#include "expr.h"
|
||||
#include "meas.h"
|
||||
#include "inst.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);
|
||||
|
||||
|
||||
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;
|
||||
|
||||
@ -78,6 +80,7 @@ static int generate_vecs(struct frame *frame, struct coord base)
|
||||
vec->pos.y += y.n;
|
||||
if (!inst_vec(vec, vec_base))
|
||||
return 0;
|
||||
meas_post(vec, vec->pos);
|
||||
}
|
||||
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);
|
||||
if (is_undef(offset))
|
||||
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,
|
||||
offset.n))
|
||||
return 0;
|
||||
@ -261,7 +265,10 @@ int instantiate(void)
|
||||
int ok;
|
||||
|
||||
inst_start();
|
||||
meas_start();
|
||||
ok = generate_frame(root_frame, zero, NULL, NULL, 1);
|
||||
if (ok)
|
||||
ok = instantiate_meas();
|
||||
if (ok)
|
||||
inst_commit();
|
||||
else
|
||||
|
9
obj.h
9
obj.h
@ -84,6 +84,8 @@ struct loop {
|
||||
int initialized;
|
||||
};
|
||||
|
||||
struct sample;
|
||||
|
||||
struct vec {
|
||||
const char *name; /* NULL if anonymous */
|
||||
struct expr *x;
|
||||
@ -96,6 +98,9 @@ struct vec {
|
||||
|
||||
/* used when editing */
|
||||
struct frame *frame;
|
||||
|
||||
/* samples for measurements */
|
||||
struct sample *samples;
|
||||
};
|
||||
|
||||
struct frame {
|
||||
@ -147,7 +152,7 @@ struct arc {
|
||||
struct expr *width;
|
||||
};
|
||||
|
||||
struct meas {
|
||||
struct old_meas {
|
||||
struct vec *other; /* NULL if frame origin */
|
||||
struct expr *offset;
|
||||
};
|
||||
@ -160,7 +165,7 @@ struct obj {
|
||||
struct rect line;
|
||||
struct pad pad;
|
||||
struct arc arc;
|
||||
struct meas meas;
|
||||
struct old_meas meas;
|
||||
} u;
|
||||
struct frame *frame;
|
||||
struct vec *base;
|
||||
|
14
sc89.fpd
14
sc89.fpd
@ -1,12 +1,12 @@
|
||||
/* MACHINE-GENERATED ! */
|
||||
|
||||
frame pad {
|
||||
_pad_0: vec @(-Px/2, -Py/2)
|
||||
_pad_1: vec .(Px, 0mm)
|
||||
_pad_2: vec _pad_0(0mm, Py)
|
||||
pad "$pad" _pad_1 _pad_2
|
||||
meas _pad_0 _pad_1 -0.1mm
|
||||
meas _pad_0 _pad_2 0.1mm
|
||||
sw: vec @(-Px/2, -Py/2)
|
||||
se: vec sw(Px, 0mm)
|
||||
nw: vec sw(0mm, Py)
|
||||
pad "$pad" se nw
|
||||
// meas sw se -0.1mm
|
||||
// meas sw nw 0.1mm
|
||||
}
|
||||
|
||||
frame pad_ne {
|
||||
@ -41,3 +41,5 @@ __2: vec @(Gx/2, -Gy/2)
|
||||
frame pad_sc __0
|
||||
frame pad_nw __1
|
||||
frame pad_ne __2
|
||||
|
||||
measx pad.sw -> pad.se 1mm
|
||||
|
Loading…
Reference in New Issue
Block a user