r5325 - in developers/werner: . fped
werner at docs.openmoko.org
werner at docs.openmoko.org
Mon Jul 27 09:31:00 CEST 2009
Author: werner
Date: 2009-07-27 09:30:59 +0200 (Mon, 27 Jul 2009)
New Revision: 5325
Added:
developers/werner/fped/
developers/werner/fped/Makefile
developers/werner/fped/coord.h
developers/werner/fped/error.c
developers/werner/fped/error.h
developers/werner/fped/expr.c
developers/werner/fped/expr.h
developers/werner/fped/fpd.l
developers/werner/fped/fpd.y
developers/werner/fped/fped.c
developers/werner/fped/gui.c
developers/werner/fped/gui.h
developers/werner/fped/gui_inst.c
developers/werner/fped/gui_inst.h
developers/werner/fped/gui_style.c
developers/werner/fped/gui_style.h
developers/werner/fped/inst.c
developers/werner/fped/inst.h
developers/werner/fped/obj.c
developers/werner/fped/obj.h
developers/werner/fped/qfn.fpd
developers/werner/fped/util.c
developers/werner/fped/util.h
Log:
Footprint editor. Work in progress.
Added: developers/werner/fped/Makefile
===================================================================
--- developers/werner/fped/Makefile (rev 0)
+++ developers/werner/fped/Makefile 2009-07-27 07:30:59 UTC (rev 5325)
@@ -0,0 +1,44 @@
+OBJS = fped.o expr.o obj.o inst.o util.o error.o lex.yy.o y.tab.o \
+ gui.o gui_style.o gui_inst.o
+
+CFLAGS_GTK = `pkg-config --cflags gtk+-2.0`
+LIBS_GTK = `pkg-config --libs gtk+-2.0`
+
+CFLAGS=-Wall -g $(CFLAGS_GTK)
+CFLAGS_LEX=-g
+CFLAGS_YACC=-g
+LDLIBS = -lm -lfl $(LIBS_GTK)
+YACC=bison -y
+YYFLAGS=-v
+
+all: fped
+
+fped: $(OBJS)
+ $(CC) -o $@ $(OBJS) $(LDLIBS)
+
+lex.yy.c: fpd.l y.tab.h
+ $(LEX) fpd.l
+
+lex.yy.o: lex.yy.c y.tab.h
+ $(CC) -c $(CFLAGS_LEX) lex.yy.c
+
+y.tab.c y.tab.h: fpd.y
+ $(YACC) $(YYFLAGS) -d fpd.y
+
+y.tab.o: y.tab.c
+ $(CC) -c $(CFLAGS_YACC) y.tab.c
+
+# ----- Dependencies ----------------------------------------------------------
+
+dep depend .depend: lex.yy.c y.tab.h y.tab.c
+ $(CPP) $(CFLAGS) -MM -MG *.c >.depend || \
+ { rm -f .depend; exit 1; }
+
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
+
+# ----- Cleanup ---------------------------------------------------------------
+
+clean:
+ rm -f $(OBJS) lex.yy.c y.tab.c y.tab.h y.output
Added: developers/werner/fped/coord.h
===================================================================
--- developers/werner/fped/coord.h (rev 0)
+++ developers/werner/fped/coord.h 2009-07-27 07:30:59 UTC (rev 5325)
@@ -0,0 +1,60 @@
+/*
+ * coord.h - Coordinate representation
+ *
+ * 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 COORD_H
+#define COORD_H
+
+#include <stdint.h>
+
+
+#define MICRON_UNITS 10
+#define MIL_UNITS (25.4*MICRON_UNITS)
+#define MM_UNITS (1000.0*MICRON_UNITS)
+#define KICAD_UNIT (10.0*MIL_UNITS)
+
+
+typedef int32_t unit_type;
+
+
+#define UNIT_ERROR ((unit_type) 1 << (sizeof(unit_type)*8-1))
+
+
+struct coord {
+ unit_type x, y;
+};
+
+
+static inline unit_type mil_to_units(double mil)
+{
+ return mil*MIL_UNITS;
+}
+
+
+static inline unit_type mm_to_units(double mm)
+{
+ return mm*MM_UNITS;
+}
+
+
+static inline double units_to_mm(unit_type u)
+{
+ return (double) u/MM_UNITS;
+}
+
+
+static inline double units_to_kicad(unit_type u)
+{
+ return (double) u/KICAD_UNIT;
+}
+
+#endif /* !COORD_H */
Added: developers/werner/fped/error.c
===================================================================
--- developers/werner/fped/error.c (rev 0)
+++ developers/werner/fped/error.c 2009-07-27 07:30:59 UTC (rev 5325)
@@ -0,0 +1,55 @@
+/*
+ * error.c - Error reporting
+ *
+ * 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 <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "error.h"
+
+
+int lineno = 1;
+
+extern char *yytext;
+
+
+void __attribute__((noreturn)) yyerrorf(const char *fmt, ...)
+{
+ va_list ap;
+
+ fprintf(stderr, "%d: ", lineno);
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ fprintf(stderr, "near \"%s\"\n", yytext);
+ exit(1);
+}
+
+
+void __attribute__((noreturn)) yyerror(const char *s)
+{
+ yyerrorf("%s", s);
+}
+
+
+void fail(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
+ exit(1);
+}
+
Added: developers/werner/fped/error.h
===================================================================
--- developers/werner/fped/error.h (rev 0)
+++ developers/werner/fped/error.h 2009-07-27 07:30:59 UTC (rev 5325)
@@ -0,0 +1,26 @@
+/*
+ * error.h - Error reporting
+ *
+ * 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 ERROR_H
+#define ERROR_H
+
+
+int lineno;
+
+
+void __attribute__((noreturn)) yyerrorf(const char *fmt, ...);
+void __attribute__((noreturn)) yyerror(const char *s);
+
+void __attribute__((noreturn)) fail(const char *fmt, ...);
+
+#endif /* !ERROR_H */
Added: developers/werner/fped/expr.c
===================================================================
--- developers/werner/fped/expr.c (rev 0)
+++ developers/werner/fped/expr.c 2009-07-27 07:30:59 UTC (rev 5325)
@@ -0,0 +1,148 @@
+/*
+ * expr.c - Expressions and values
+ *
+ * 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 "error.h"
+#include "obj.h"
+#include "expr.h"
+
+
+double op_num(const struct expr *self, const struct frame *frame)
+{
+ return self->u.num;
+}
+
+
+static double eval_var(const struct frame *frame, const char *name)
+{
+ const struct table *table;
+ const struct loop *loop;
+ const struct value *value;
+ const struct var *var;
+
+ for (table = frame->tables; table; table = table->next) {
+ value = table->curr_row->values;
+ for (var = table->vars; var; var = var->next) {
+ if (var->name == name)
+ return eval_num(value->expr, frame);
+ value = value->next;
+ }
+ }
+ for (loop = frame->loops; loop; loop = loop->next)
+ if (loop->var == name)
+ return loop->curr_value;
+ if (frame->curr_parent)
+ return eval_var(frame->curr_parent, name);
+ return UNDEF;
+}
+
+
+double op_var(const struct expr *self, const struct frame *frame)
+{
+ double res;
+
+ res = eval_var(frame, self->u.var);
+ if (res == UNDEF)
+ fail("undefined variable \"%s\"", self->u.var);
+ return res;
+}
+
+
+double op_minus(const struct expr *self, const struct frame *frame)
+{
+ double res;
+
+ res = eval_num(self->u.op.a, frame);
+ return res == UNDEF ? UNDEF : -res;
+}
+
+
+#define BINARY \
+ double a, b; \
+ \
+ a = eval_num(self->u.op.a, frame); \
+ b = eval_num(self->u.op.b, frame); \
+ if (a == UNDEF || b == UNDEF) \
+ return UNDEF; \
+
+
+double op_add(const struct expr *self, const struct frame *frame)
+{
+ BINARY;
+ return a+b;
+}
+
+
+double op_sub(const struct expr *self, const struct frame *frame)
+{
+ BINARY;
+ return a-b;
+}
+
+
+double op_mult(const struct expr *self, const struct frame *frame)
+{
+ BINARY;
+ return a*b;
+}
+
+
+double op_div(const struct expr *self, const struct frame *frame)
+{
+ BINARY;
+ if (!b) {
+ fail("Division by zero");
+ return UNDEF;
+ }
+ return a/b;
+}
+
+
+struct expr *new_op(op_type op)
+{
+ struct expr *expr;
+
+ expr = alloc_type(struct expr);
+ expr->op = op;
+ return expr;
+}
+
+
+struct expr *binary_op(op_type op, struct expr *a, struct expr *b)
+{
+ struct expr *expr;
+
+ expr = new_op(op);
+ expr->u.op.a = a;
+ expr->u.op.b = b;
+ return expr;
+}
+
+
+double eval(const struct expr *expr, const struct frame *frame)
+{
+ return expr->op(expr, frame);
+}
+
+char *eval_str(const struct frame *frame, const struct expr *expr)
+{
+ abort();
+}
+
+
+double eval_num(const struct expr *expr, const struct frame *frame)
+{
+ return expr->op(expr, frame);
+}
Added: developers/werner/fped/expr.h
===================================================================
--- developers/werner/fped/expr.h (rev 0)
+++ developers/werner/fped/expr.h 2009-07-27 07:30:59 UTC (rev 5325)
@@ -0,0 +1,58 @@
+/*
+ * expr.h - Expressions and values
+ *
+ * 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 EXPR_H
+#define EXPR_H
+
+#include <math.h>
+
+
+#define UNDEF HUGE_VAL
+
+
+struct frame;
+struct expr;
+
+
+typedef double (*op_type)(const struct expr *self, const struct frame *frame);
+
+struct expr {
+ op_type op;
+ union {
+ double num;
+ const char *var;
+ struct {
+ struct expr *a;
+ struct expr *b;
+ } op;
+ } u;
+};
+
+
+double op_num(const struct expr *self, const struct frame *frame);
+double op_var(const struct expr *self, const struct frame *frame);
+
+double op_minus(const struct expr *self, const struct frame *frame);
+
+double op_add(const struct expr *self, const struct frame *frame);
+double op_sub(const struct expr *self, const struct frame *frame);
+double op_mult(const struct expr *self, const struct frame *frame);
+double op_div(const struct expr *self, const struct frame *frame);
+
+struct expr *new_op(op_type op);
+struct expr *binary_op(op_type op, struct expr *a, struct expr *b);
+
+char *eval_str(const struct frame *frame, const struct expr *expr);
+double eval_num(const struct expr *expr, const struct frame *frame);
+
+#endif /* !EXPR_H */
Added: developers/werner/fped/fpd.l
===================================================================
--- developers/werner/fped/fpd.l (rev 0)
+++ developers/werner/fped/fpd.l 2009-07-27 07:30:59 UTC (rev 5325)
@@ -0,0 +1,59 @@
+%{
+/*
+ * fpd.l - FootPrint Definition language
+ *
+ * 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 "util.h"
+#include "coord.h"
+#include "error.h"
+
+#include "y.tab.h"
+
+%}
+
+
+NUM [0-9]+\.?[0-9]*
+SP [\t ]*
+
+
+%%
+
+
+".frame" return TOK_FRAME;
+".table" return TOK_TABLE;
+".vec" return TOK_VEC;
+".pad" return TOK_PAD;
+".rect" return TOK_RECT;
+".line" return TOK_LINE;
+".arc" return TOK_ARC;
+
+[a-zA-Z_][a-zA-Z_0-9]* { yylval.id = unique(yytext);
+ return ID; }
+
+{NUM}{SP}mm { sscanf(yytext, "%lf", &yylval.num);
+ yylval.num = mm_to_units(yylval.num);
+ return NUMBER; }
+{NUM}{SP}mil { sscanf(yytext, "%lf", &yylval.num);
+ yylval.num = mil_to_units(yylval.num);
+ return NUMBER; }
+{NUM} { sscanf(yytext, "%lf", &yylval.num);
+ return NUMBER; }
+
+\"(\\[^\n\t]|[^\\"\n\t])*\" { *strrchr(yytext, '"') = 0;
+ yylval.str = stralloc(yytext+1);
+ return STRING; }
+
+{SP} ;
+\n lineno++;
+^#.*\n lineno++;
+
+. return *yytext;
Added: developers/werner/fped/fpd.y
===================================================================
--- developers/werner/fped/fpd.y (rev 0)
+++ developers/werner/fped/fpd.y 2009-07-27 07:30:59 UTC (rev 5325)
@@ -0,0 +1,444 @@
+%{
+/*
+ * fpd.y - FootPrint Definition language
+ *
+ * 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 "error.h"
+#include "expr.h"
+#include "obj.h"
+
+
+static struct frame *curr_frame;
+static struct frame **next_frame;
+static struct table **next_table;
+static struct loop **next_loop;
+static struct vec **next_vec;
+static struct obj **next_obj;
+static int n_vars, n_values;
+static struct vec *last_vec = NULL;
+
+
+static struct frame *find_frame(const char *name)
+{
+ struct frame *f;
+
+ for (f = frames; f; f = f->next)
+ if (f->name == name)
+ return f;
+ return NULL;
+}
+
+
+static struct vec *find_vec(const char *name)
+{
+ struct vec *v;
+
+ for (v = curr_frame->vecs; v; v = v->next)
+ if (v->name == name)
+ return v;
+ return NULL;
+}
+
+
+static void set_frame(struct frame *frame)
+{
+ curr_frame = frame;
+ next_table = &frame->tables;
+ next_loop = &frame->loops;
+ next_vec = &frame->vecs;
+ next_obj = &frame->objs;
+ last_vec = NULL;
+}
+
+
+static void make_var(const char *id, struct expr *expr)
+{
+ struct table *table;
+
+ table = zalloc_type(struct table);
+ table->vars = zalloc_type(struct var);
+ table->vars->name = id;
+ table->rows = zalloc_type(struct row);
+ table->rows->values = zalloc_type(struct value);
+ table->rows->values->expr = expr;
+ *next_table = table;
+ next_table = &table->next;
+}
+
+
+static void make_loop(const char *id, struct expr *from, struct expr *to)
+{
+ struct loop *loop;
+
+ loop = alloc_type(struct loop);
+ loop->var = id;
+ loop->from = from;
+ loop->to = to;
+ loop->next = NULL;
+ *next_loop = loop;
+ next_loop = &loop->next;
+}
+
+
+static struct obj *new_obj(enum obj_type type)
+{
+ struct obj *obj;
+
+ obj = alloc_type(struct obj);
+ obj->type = type;
+ obj->next = NULL;
+ return obj;
+}
+
+
+%}
+
+
+%union {
+ double num;
+ char *str;
+ const char *id;
+ struct expr *expr;
+ struct frame *frame;
+ struct table *table;
+ struct var *var;
+ struct row *row;
+ struct value *value;
+ struct vec *vec;
+ struct obj *obj;
+};
+
+
+%token TOK_FRAME TOK_TABLE TOK_VEC TOK_PAD TOK_RECT TOK_LINE TOK_ARC
+
+%token <num> NUMBER
+%token <str> STRING
+%token <id> ID
+
+%type <table> table
+%type <var> vars var
+%type <row> rows
+%type <value> row value
+%type <vec> vec base opt_base
+%type <obj> obj
+%type <expr> opt_range
+%type <expr> expr add_expr mult_expr unary_expr primary_expr
+
+%%
+
+all:
+ {
+ frames = zalloc_type(struct frame);
+ next_frame = &frames->next;
+ set_frame(frames);
+ }
+ frame_defs frame_items
+ ;
+
+frame_defs:
+ | frame_defs frame_def
+ ;
+
+frame_def:
+ TOK_FRAME ID '{'
+ {
+ if (find_frame($2))
+ yyerrorf("duplicate frame \"%s\"", $2);
+ *next_frame = zalloc_type(struct frame);
+ (*next_frame)->name = $2;
+ set_frame(*next_frame);
+ next_frame = &(*next_frame)->next;
+
+ }
+ frame_items '}'
+ {
+ set_frame(frames);
+ }
+ ;
+
+frame_items:
+ | frame_item frame_items
+ ;
+
+frame_item:
+ table
+ | ID '=' expr opt_range
+ {
+ if ($4)
+ make_loop($1, $3, $4);
+ else
+ make_var($1, $3);
+ }
+ | vec
+ | ID '=' vec
+ {
+ if (find_vec($1))
+ yyerrorf("duplicate vector \"%s\"", $1);
+ $3->name = $1;
+ }
+ | obj
+ {
+ *next_obj = $1;
+ next_obj = &$1->next;
+ }
+ ;
+
+opt_range:
+ {
+ $$ = NULL;
+ }
+ | ',' expr
+ {
+ $$ = $2;
+ }
+ ;
+
+table:
+ TOK_TABLE
+ {
+ $<table>$ = zalloc_type(struct table);
+ *next_table = $<table>$;
+ n_vars = 0;
+ }
+ '{' vars '}' rows
+ {
+ $$ = $<table>2;
+ $$->vars = $4;
+ $$->rows = $6;
+ next_table = &$$->next;
+ }
+ ;
+
+vars:
+ var
+ {
+ $$ = $1;
+ }
+ | vars ',' var
+ {
+ struct var **walk;
+
+ $$ = $1;
+ for (walk = &$$; *walk; walk = &(*walk)->next);
+ *walk = $3;
+ }
+ ;
+
+var:
+ ID
+ {
+ $$ = alloc_type(struct var);
+ $$->name = $1;
+ $$->next = NULL;
+ n_vars++;
+ }
+ ;
+
+
+rows:
+ {
+ $$ = NULL;
+ }
+ | '{'
+ {
+ n_values = 0;
+ }
+ row '}'
+ {
+ if (n_vars != n_values)
+ yyerrorf("table has %d variables but row has "
+ "%d values", n_vars, n_values);
+ $<row>$ = alloc_type(struct row);
+ $<row>$->values = $3;
+ }
+ rows
+ {
+ $$ = $<row>5;
+ $$->next = $6;
+ }
+ ;
+
+row:
+ value
+ {
+ $$ = $1;
+ }
+ | row ',' value
+ {
+ struct value **walk;
+
+ $$ = $1;
+ for (walk = &$$; *walk; walk = &(*walk)->next);
+ *walk = $3;
+ }
+ ;
+
+value:
+ expr
+ {
+ $$ = alloc_type(struct value);
+ $$->expr = $1;
+ $$->next = NULL;
+ n_values++;
+ }
+ ;
+
+vec:
+ TOK_VEC base expr ',' expr
+ {
+ $$ = alloc_type(struct vec);
+ $$->base = $2;
+ if ($2)
+ $2->n_refs++;
+ $$->x = $3;
+ $$->y = $5;
+ $$->n_refs = 0;
+ $$->next = NULL;
+ last_vec = $$;
+ *next_vec = $$;
+ next_vec = &$$->next;
+ }
+ ;
+
+base:
+ '@'
+ {
+ $$ = NULL;
+ }
+ | '.'
+ {
+ $$ = last_vec;
+ if (!$$)
+ yyerrorf(". without predecessor");
+ }
+ | ID
+ {
+ $$ = find_vec($1);
+ if (!$$)
+ yyerrorf("unknown vector \"%s\"", $1);
+ }
+ ;
+
+obj:
+ TOK_PAD STRING base base
+ {
+ $$ = new_obj(ot_pad);
+ $$->base = $3;
+ $$->u.pad.name = $2;
+ $$->u.pad.other = $4;
+ }
+ | TOK_RECT base base
+ {
+ $$ = new_obj(ot_rect);
+ $$->base = $2;
+ $$->u.rect.other = $3;
+ }
+ | TOK_LINE base base
+ {
+ $$ = new_obj(ot_line);
+ $$->base = $2;
+ $$->u.line.other = $3;
+ }
+ | TOK_ARC base base opt_base
+ {
+ $$ = new_obj(ot_arc);
+ $$->base = $2;
+ $$->u.arc.start = $3;
+ $$->u.arc.end = $3;
+ }
+ | TOK_FRAME ID base
+ {
+ $$ = new_obj(ot_frame);
+ $$->base = $3;
+ $$->u.frame = find_frame($2);
+ if (!$$->u.frame)
+ yyerrorf("unknown frame \"%s\"", $2);
+ }
+ ;
+
+opt_base:
+ {
+ $$ = NULL;
+ }
+ | ',' base
+ {
+ $$ = $2;
+ }
+ ;
+
+expr:
+ add_expr
+ {
+ $$ = $1;
+ }
+ ;
+
+add_expr:
+ mult_expr
+ {
+ $$ = $1;
+ }
+ | add_expr '+' mult_expr
+ {
+ $$ = binary_op(op_add, $1, $3);
+ }
+ | add_expr '-' mult_expr
+ {
+ $$ = binary_op(op_sub, $1, $3);
+ }
+ ;
+
+mult_expr:
+ unary_expr
+ {
+ $$ = $1;
+ }
+ | mult_expr '*' unary_expr
+ {
+ $$ = binary_op(op_mult, $1, $3);
+ }
+ | mult_expr '/' unary_expr
+ {
+ $$ = binary_op(op_div, $1, $3);
+ }
+ ;
+
+unary_expr:
+ primary_expr
+ {
+ $$ = $1;
+ }
+ | '-' primary_expr
+ {
+ $$ = binary_op(op_minus, $2, NULL);
+ }
+ ;
+
+primary_expr:
+ NUMBER
+ {
+ $$ = new_op(op_num);
+ $$->u.num = $1;
+ }
+ | ID
+ {
+ $$ = new_op(op_var);
+ $$->u.var = $1;
+ }
+ | '(' expr ')'
+ {
+ $$ = $2;
+ }
+ ;
Added: developers/werner/fped/fped.c
===================================================================
--- developers/werner/fped/fped.c (rev 0)
+++ developers/werner/fped/fped.c 2009-07-27 07:30:59 UTC (rev 5325)
@@ -0,0 +1,64 @@
+/*
+ * fped.c - Footprint editor, main function
+ *
+ * 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 <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+
+#include "obj.h"
+#include "inst.h"
+#include "gui.h"
+
+
+int yyparse(void);
+
+
+static void load_file(const char *name)
+{
+ int fd;
+
+ fd = open(name, O_RDONLY);
+ if (fd < 0) {
+ perror(name);
+ exit(1);
+ }
+ if (dup2(fd, 0) < 0) {
+ perror("dup2");
+ exit(1);
+ }
+ (void) yyparse();
+}
+
+
+int main(int argc, char **argv)
+{
+ int error;
+
+ error = gui_init(&argc, &argv);
+ if (error)
+ return error;
+ if (argc > 1) {
+ load_file(argv[1]);
+ argc--;
+ argv++;
+ }
+ instantiate();
+ inst_debug();
+ error = gui_main(argc, argv);
+ if (error)
+ return error;
+ return 0;
+}
Added: developers/werner/fped/gui.c
===================================================================
--- developers/werner/fped/gui.c (rev 0)
+++ developers/werner/fped/gui.c 2009-07-27 07:30:59 UTC (rev 5325)
@@ -0,0 +1,195 @@
+/*
+ * gui.c - Editor GUI core
+ *
+ * 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 <math.h>
+#include <gtk/gtk.h>
+
+#include "obj.h"
+#include "inst.h"
+#include "gui_inst.h"
+#include "gui_style.h"
+#include "gui.h"
+
+
+static void make_menu_bar(GtkWidget *vbox)
+{
+ GtkWidget *bar;
+ GtkWidget *file_menu, *file, *quit;
+
+ bar = gtk_menu_bar_new();
+ gtk_box_pack_start(GTK_BOX(vbox), bar, FALSE, FALSE, 0);
+
+ file_menu = gtk_menu_new();
+
+ file = gtk_menu_item_new_with_label("File");
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(file), file_menu);
+ gtk_menu_shell_append(GTK_MENU_SHELL(bar), file);
+
+ quit = gtk_menu_item_new_with_label("Quit");
+ gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), quit);
+
+ g_signal_connect(G_OBJECT(quit), "activate",
+ G_CALLBACK(gtk_main_quit), NULL);
+}
+
+
+static void add_frame(GtkListStore *list, const char *name)
+{
+ GtkTreeIter iter;
+
+ gtk_list_store_append(list, &iter);
+ gtk_list_store_set(list, &iter, 0, name, -1);
+}
+
+
+static void show_frames(GtkWidget *frame_list)
+{
+ GtkListStore *list;
+ struct frame *f;
+
+ list = gtk_list_store_new(1, G_TYPE_STRING);
+
+ for (f = frames; f; f = f->next)
+ add_frame(list, f->name ? f->name : "(root)");
+
+ gtk_tree_view_set_model(GTK_TREE_VIEW(frame_list),
+ GTK_TREE_MODEL(list));
+ g_object_unref(list);
+}
+
+
+static gboolean expose_event_callback(GtkWidget *widget, GdkEventExpose *event,
+ gpointer data)
+{
+ static int need_style = 1;
+ struct bbox bbox;
+ unit_type h, w;
+ int sx, sy;
+ float aw, ah;
+
+ struct draw_ctx ctx = {
+ .widget = widget,
+ .scale = 1000,
+ .center = {
+ .x = 0,
+ .y = 0,
+ },
+ };
+
+ if (need_style) {
+ gui_setup_style(widget->window);
+ need_style = 0;
+ }
+
+ aw = widget->allocation.width;
+ ah = widget->allocation.height;
+ gdk_draw_rectangle(widget->window, gc_bg, TRUE, 0, 0, aw, ah);
+ bbox = inst_get_bbox();
+ ctx.center.x = (bbox.min.x+bbox.max.x)/2;
+ ctx.center.y = (bbox.min.y+bbox.max.y)/2;
+ h = bbox.max.x-bbox.min.x;
+ w = bbox.max.y-bbox.min.y;
+ aw -= 2*CANVAS_CLEARANCE;
+ ah -= 2*CANVAS_CLEARANCE;
+ if (aw < 1)
+ aw = 1;
+ if (ah < 1)
+ ah = 1;
+ sx = ceil(h/aw);
+ sy = ceil(w/ah);
+ ctx.scale = sx > sy ? sx : sy > 0 ? sy : 1;
+
+ inst_draw(&ctx);
+ return TRUE;
+}
+
+
+static void make_center_area(GtkWidget *vbox)
+{
+ GtkWidget *hbox;
+ GtkWidget *frame_list, *sep, *canvas;
+ GdkColor black = { 0, 0, 0, 0 };
+
+ hbox = gtk_hbox_new(FALSE, 0);
+
+ frame_list = gtk_tree_view_new();
+ gtk_box_pack_start(GTK_BOX(hbox), frame_list, FALSE, TRUE, 0);
+
+ gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(frame_list),
+ -1, "Frame", gtk_cell_renderer_text_new(), "text", 0, NULL);
+
+ show_frames(frame_list);
+
+ sep = gtk_drawing_area_new();
+ gtk_box_pack_start(GTK_BOX(hbox), sep, FALSE, TRUE, 2);
+ gtk_widget_modify_bg(sep, GTK_STATE_NORMAL, &black);
+
+ canvas = gtk_drawing_area_new();
+ gtk_box_pack_start(GTK_BOX(hbox), canvas, TRUE, TRUE, 0);
+ gtk_widget_modify_bg(canvas, GTK_STATE_NORMAL, &black);
+ g_signal_connect (G_OBJECT(canvas), "expose_event",
+ G_CALLBACK(expose_event_callback), NULL);
+
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
+}
+
+
+static void make_input_area(GtkWidget *vbox)
+{
+ GtkWidget *entry;
+
+ entry = gtk_entry_new();
+ gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE, 0);
+}
+
+
+static void make_screen(GtkWidget *root)
+{
+ GtkWidget *vbox;
+
+ vbox = gtk_vbox_new(FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(root), vbox);
+
+ make_menu_bar(vbox);
+ make_center_area(vbox);
+ make_input_area(vbox);
+}
+
+
+int gui_init(int *argc, char ***argv)
+{
+ gtk_init(argc, argv);
+ return 0;
+}
+
+
+int gui_main(int argc, char **argv)
+{
+ GtkWidget *root;
+
+ root = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_position(GTK_WINDOW(root), GTK_WIN_POS_CENTER);
+ gtk_window_set_default_size(GTK_WINDOW(root), 600, 400);
+ gtk_window_set_title(GTK_WINDOW(root), "fped");
+
+ g_signal_connect_swapped(G_OBJECT(root), "destroy",
+ G_CALLBACK(gtk_main_quit), NULL);
+
+ make_screen(root);
+
+ gtk_widget_show_all(root);
+
+ gtk_main();
+
+ return 0;
+}
Added: developers/werner/fped/gui.h
===================================================================
--- developers/werner/fped/gui.h (rev 0)
+++ developers/werner/fped/gui.h 2009-07-27 07:30:59 UTC (rev 5325)
@@ -0,0 +1,23 @@
+/*
+ * gui.h - Editor GUI core
+ *
+ * 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 GUI_H
+#define GUI_H
+
+#include <gtk/gtk.h>
+
+
+int gui_init(int *argc, char ***argv);
+int gui_main(int argc, char **argv);
+
+#endif /* !GUI_H */
Added: developers/werner/fped/gui_inst.c
===================================================================
--- developers/werner/fped/gui_inst.c (rev 0)
+++ developers/werner/fped/gui_inst.c 2009-07-27 07:30:59 UTC (rev 5325)
@@ -0,0 +1,148 @@
+/*
+ * gui_inst.c - GUI, instance functions
+ *
+ * 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 <gtk/gtk.h>
+
+#include "inst.h"
+#include "gui.h"
+#include "gui_style.h"
+#include "gui_inst.h"
+
+
+#define DA GDK_DRAWABLE(ctx->widget->window)
+
+
+static struct coord translate(const struct draw_ctx *ctx, struct coord pos)
+{
+ pos.x -= ctx->center.x;
+ pos.y -= ctx->center.y;
+ pos.x /= ctx->scale;
+ pos.y /= ctx->scale;
+ pos.y = -pos.y;
+ pos.x += ctx->widget->allocation.width/2;
+ pos.y += ctx->widget->allocation.height/2;
+fprintf(stderr, "%d %d\n", (int) pos.x, (int) pos.y);
+ return pos;
+}
+
+
+/* ----- drawing primitives ------------------------------------------------ */
+
+
+static void draw_arc(struct draw_ctx *ctx, GdkGC *gc, int fill,
+ int x, int y, int r, double a1, double a2)
+{
+ gdk_draw_arc(DA, gc, fill, x-r, y-r, 2*r, 2*r, a1*64, a2*64);
+}
+
+
+static void draw_circle(struct draw_ctx *ctx, GdkGC *gc, int fill,
+ int x, int y, int r)
+{
+ draw_arc(ctx, gc, fill, x, y, r, 0, 360);
+}
+
+
+static void draw_eye(struct draw_ctx *ctx, GdkGC *gc, struct coord center,
+ int r1, int r2)
+{
+ center = translate(ctx, center);
+ draw_circle(ctx, gc, TRUE, center.x, center.y, r1);
+ draw_circle(ctx, gc, FALSE, center.x, center.y, r2);
+}
+
+
+/* ----- vec --------------------------------------------------------------- */
+
+
+void gui_draw_vec(struct inst *self, struct draw_ctx *ctx)
+{
+ struct coord from = translate(ctx, self->base);
+ struct coord to = translate(ctx, self->u.end);
+
+ draw_circle(ctx, gc_vec_bg, FALSE, to.x, to.y, VEC_EYE_R);
+ gdk_draw_line(DA, gc_vec_bg, from.x, from.y, to.x, to.y);
+
+}
+
+
+/* ----- line -------------------------------------------------------------- */
+
+
+void gui_draw_line(struct inst *self, struct draw_ctx *ctx)
+{
+ struct coord min = translate(ctx, self->bbox.min);
+ struct coord max = translate(ctx, self->bbox.max);
+
+ gdk_draw_line(DA, gc_line_bg, min.x, min.x, max.x, max.y);
+}
+
+
+/* ----- rect -------------------------------------------------------------- */
+
+
+void gui_draw_rect(struct inst *self, struct draw_ctx *ctx)
+{
+ struct coord min = translate(ctx, self->bbox.min);
+ struct coord max = translate(ctx, self->bbox.max);
+
+ gdk_draw_rectangle(DA, gc_rect_bg, FALSE,
+ min.x, max.y, max.x-min.x+1, min.y-max.y+1);
+}
+
+
+/* ----- pad --------------------------------------------------------------- */
+
+
+void gui_draw_pad(struct inst *self, struct draw_ctx *ctx)
+{
+ struct coord min = translate(ctx, self->bbox.min);
+ struct coord max = translate(ctx, self->bbox.max);
+
+ /* @@@ name */
+ gdk_draw_rectangle(DA, gc_pad_bg, TRUE,
+ min.x, max.y, max.x-min.x+1, min.y-max.y+1);
+}
+
+
+/* ----- arc --------------------------------------------------------------- */
+
+
+void gui_draw_arc(struct inst *self, struct draw_ctx *ctx)
+{
+ struct coord center = translate(ctx, self->base);
+
+ draw_arc(ctx, gc_arc_bg, FALSE, center.x, center.y,
+ self->u.arc.r/ctx->scale, self->u.arc.a1, self->u.arc.a2);
+}
+
+
+/* ----- frame ------------------------------------------------------------- */
+
+
+void gui_draw_frame(struct inst *self, struct draw_ctx *ctx)
+{
+ struct coord pos = translate(ctx, self->base);
+ struct coord corner = { self->bbox.min.x, self->bbox.max.y };
+
+ draw_eye(ctx, gc_frame_bg, pos, FRAME_EYE_R1, FRAME_EYE_R2);
+ if (!self->u.frame.ref->name)
+ return;
+ corner = translate(ctx, corner);
+ corner.x -= FRAME_CLEARANCE;
+ corner.y -= FRAME_CLEARANCE;
+ gdk_draw_line(DA, gc_frame_bg,
+ corner.x, corner.y, corner.x+100, corner.y);
+ gdk_draw_line(DA, gc_frame_bg,
+ corner.x, corner.y, corner.x, corner.y+20);
+}
Added: developers/werner/fped/gui_inst.h
===================================================================
--- developers/werner/fped/gui_inst.h (rev 0)
+++ developers/werner/fped/gui_inst.h 2009-07-27 07:30:59 UTC (rev 5325)
@@ -0,0 +1,37 @@
+/*
+ * gui_inst.h - GUI, instance functions
+ *
+ * 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 GUI_INST_H
+#define GUI_INST_H
+
+#include <gtk/gtk.h>
+
+#include "coord.h"
+#include "inst.h"
+
+
+struct draw_ctx {
+ GtkWidget *widget;
+ int scale;
+ struct coord center;
+};
+
+
+void gui_draw_vec(struct inst *self, struct draw_ctx *ctx);
+void gui_draw_line(struct inst *self, struct draw_ctx *ctx);
+void gui_draw_rect(struct inst *self, struct draw_ctx *ctx);
+void gui_draw_pad(struct inst *self, struct draw_ctx *ctx);
+void gui_draw_arc(struct inst *self, struct draw_ctx *ctx);
+void gui_draw_frame(struct inst *self, struct draw_ctx *ctx);
+
+#endif /* !GUI_INST_H */
Added: developers/werner/fped/gui_style.c
===================================================================
--- developers/werner/fped/gui_style.c (rev 0)
+++ developers/werner/fped/gui_style.c 2009-07-27 07:30:59 UTC (rev 5325)
@@ -0,0 +1,64 @@
+/*
+ * gui_style.c - GUI, style definitions
+ *
+ * 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 <gtk/gtk.h>
+
+#include "gui_style.h"
+
+
+#define GC(spec) gc(drawable, (spec))
+
+
+static GdkColor get_color(GdkColormap *cmap, const char *spec)
+{
+ GdkColor color;
+
+ if (!gdk_color_parse(spec, &color))
+ abort();
+ if (!gdk_colormap_alloc_color(cmap, &color, FALSE, TRUE))
+ abort();
+ return color;
+}
+
+
+static GdkGC *gc(GdkDrawable *drawable, const char *spec)
+{
+ GdkGCValues gc_values = {
+ .background = get_color(gdk_drawable_get_colormap(drawable),
+ "black"),
+ .foreground = get_color(gdk_drawable_get_colormap(drawable),
+ spec),
+ };
+
+ return gdk_gc_new_with_values(drawable, &gc_values,
+ GDK_GC_FOREGROUND | GDK_GC_BACKGROUND);
+}
+
+
+void gui_setup_style(GdkDrawable *drawable)
+{
+ gc_bg = GC("#000000");
+ gc_vec_bg = GC("#ffff00");
+ gc_vec_fg = GC("#ffff00");
+ gc_line_bg = GC("#ffffff");
+ gc_line_fg = GC("#ffffff");
+ gc_rect_bg = gc_line_bg;
+ gc_rect_fg = gc_line_fg;
+ gc_pad_bg = GC("#ff0000");
+ gc_pad_fg = GC("#ff0000");
+ gc_arc_bg = gc_line_bg;
+ gc_arc_fg = gc_line_fg;
+ gc_frame_bg = GC("#00ff00");
+ gc_frame_fg = GC("#00ff00");
+}
Added: developers/werner/fped/gui_style.h
===================================================================
--- developers/werner/fped/gui_style.h (rev 0)
+++ developers/werner/fped/gui_style.h 2009-07-27 07:30:59 UTC (rev 5325)
@@ -0,0 +1,37 @@
+/*
+ * gui_style.h - GUI, style definitions
+ *
+ * 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 GUI_STYLE_H
+#define GUI_STYLE_H
+
+#define CANVAS_CLEARANCE 10
+
+#define VEC_ARROW 6
+#define VEC_EYE_R 4
+
+#define FRAME_CLEARANCE 5
+#define FRAME_EYE_R1 3
+#define FRAME_EYE_R2 5
+
+
+GdkGC *gc_bg;
+GdkGC *gc_vec_bg, *gc_vec_fg;
+GdkGC *gc_line_bg, *gc_line_fg;
+GdkGC *gc_rect_bg, *gc_rect_fg;
+GdkGC *gc_pad_bg, *gc_pad_fg;
+GdkGC *gc_arc_bg, *gc_arc_fg;
+GdkGC *gc_frame_bg, *gc_frame_fg;
+
+void gui_setup_style(GdkDrawable *drawable);
+
+#endif /* !GUI_STYLE_H */
Added: developers/werner/fped/inst.c
===================================================================
--- developers/werner/fped/inst.c (rev 0)
+++ developers/werner/fped/inst.c 2009-07-27 07:30:59 UTC (rev 5325)
@@ -0,0 +1,296 @@
+/*
+ * inst.c - Instance structures
+ *
+ * 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 <stdio.h>
+#include <math.h>
+
+#include "util.h"
+#include "coord.h"
+#include "obj.h"
+#include "gui_inst.h"
+#include "inst.h"
+
+
+static struct inst *insts = NULL, **next_inst;
+struct inst *curr_frame = NULL;
+
+
+static void update_bbox(struct bbox *bbox, struct coord coord)
+{
+ if (bbox->min.x > coord.x)
+ bbox->min.x = coord.x;
+ if (bbox->max.x < coord.x)
+ bbox->max.x = coord.x;
+ if (bbox->min.y > coord.y)
+ bbox->min.y = coord.y;
+ if (bbox->max.y < coord.y)
+ bbox->max.y = coord.y;
+}
+
+
+static void propagate_bbox(const struct inst *inst)
+{
+ update_bbox(&curr_frame->bbox, inst->bbox.min);
+ update_bbox(&curr_frame->bbox, inst->bbox.max);
+}
+
+
+static struct inst *add_inst(const struct inst_ops *ops, struct coord base)
+{
+ struct inst *inst;
+
+ inst = alloc_type(struct inst);
+ inst->ops = ops;
+ inst->base = inst->bbox.min = inst->bbox.max = base;
+ inst->next = NULL;
+ *next_inst = inst;
+ next_inst = &inst->next;
+ return inst;
+}
+
+
+/* ----- vec --------------------------------------------------------------- */
+
+
+static void vec_op_debug(struct inst *self)
+{
+ printf("vec %lg, %lg -> %lg, %lg\n",
+ units_to_mm(self->base.x), units_to_mm(self->base.y),
+ units_to_mm(self->u.end.x), units_to_mm(self->u.end.y));
+}
+
+
+static struct inst_ops vec_ops = {
+ .debug = vec_op_debug,
+ .draw = gui_draw_vec,
+};
+
+
+int inst_vec(struct vec *vec, struct coord base)
+{
+ struct inst *inst;
+
+ inst = add_inst(&vec_ops, base);
+ inst->u.end = vec->pos;
+ update_bbox(&inst->bbox, vec->pos);
+ propagate_bbox(inst);
+ return 1;
+}
+
+
+/* ----- line -------------------------------------------------------------- */
+
+
+static void line_op_debug(struct inst *self)
+{
+ printf("line %lg, %lg / %lg, %lg\n",
+ units_to_mm(self->base.x), units_to_mm(self->base.y),
+ units_to_mm(self->u.end.x), units_to_mm(self->u.end.y));
+}
+
+
+static struct inst_ops line_ops = {
+ .debug = line_op_debug,
+ .draw = gui_draw_line,
+};
+
+
+int inst_line(struct coord a, struct coord b)
+{
+ struct inst *inst;
+
+ inst = add_inst(&line_ops, a);
+ inst->u.end = b;
+ update_bbox(&inst->bbox, b);
+ propagate_bbox(inst);
+ return 1;
+}
+
+
+/* ----- rect -------------------------------------------------------------- */
+
+
+static void rect_op_debug(struct inst *self)
+{
+ printf("rect %lg, %lg / %lg, %lg\n",
+ units_to_mm(self->base.x), units_to_mm(self->base.y),
+ units_to_mm(self->u.end.x), units_to_mm(self->u.end.y));
+}
+
+
+static struct inst_ops rect_ops = {
+ .debug = rect_op_debug,
+ .draw = gui_draw_rect,
+};
+
+
+int inst_rect(struct coord a, struct coord b)
+{
+ struct inst *inst;
+
+ inst = add_inst(&rect_ops, a);
+ inst->u.end = b;
+ update_bbox(&inst->bbox, b);
+ propagate_bbox(inst);
+ return 1;
+}
+
+
+/* ----- pad --------------------------------------------------------------- */
+
+
+static void pad_op_debug(struct inst *self)
+{
+ printf("pad \"%s\" %lg, %lg / %lg, %lg\n", self->u.name,
+ units_to_mm(self->bbox.min.x), units_to_mm(self->bbox.min.y),
+ units_to_mm(self->bbox.max.x), units_to_mm(self->bbox.max.y));
+}
+
+
+static struct inst_ops pad_ops = {
+ .debug = pad_op_debug,
+ .draw = gui_draw_pad,
+};
+
+
+int inst_pad(const char *name, struct coord a, struct coord b)
+{
+ struct inst *inst;
+
+ inst = add_inst(&pad_ops, a);
+ inst->u.name = name;
+ update_bbox(&inst->bbox, b);
+ propagate_bbox(inst);
+ return 1;
+}
+
+
+/* ----- arc --------------------------------------------------------------- */
+
+
+static void arc_op_debug(struct inst *self)
+{
+ printf("arc %lg, %lg radius %lg %lg ... %lg\n",
+ units_to_mm(self->base.x), units_to_mm(self->base.y),
+ units_to_mm(self->u.arc.r), self->u.arc.a1, self->u.arc.a2);
+}
+
+
+static struct inst_ops arc_ops = {
+ .debug = arc_op_debug,
+ .draw = gui_draw_pad,
+};
+
+
+int inst_arc(struct coord center, struct coord start, struct coord end)
+{
+ struct inst *inst;
+ unit_type r;
+
+ inst = add_inst(&arc_ops, center);
+ r = hypot(start.x-center.x, start.y-center.y);
+ inst->bbox.min.x = center.x-r;
+ inst->bbox.max.x = center.x+r;
+ inst->bbox.min.y = center.x-r;
+ inst->bbox.max.y = center.x+r;
+ propagate_bbox(inst);
+ return 1;
+}
+
+
+/* ----- frame ------------------------------------------------------------- */
+
+
+static void frame_op_debug(struct inst *self)
+{
+ printf("frame %s @ %lg, %lg\n",
+ self->u.frame.ref->name ? self->u.frame.ref->name : "(root)",
+ units_to_mm(self->base.x), units_to_mm(self->base.y));
+}
+
+
+static struct inst_ops frame_ops = {
+ .debug = frame_op_debug,
+ .draw = gui_draw_frame,
+};
+
+
+void inst_begin_frame(const struct frame *frame, struct coord base)
+{
+ struct inst *inst;
+
+ inst = add_inst(&frame_ops, base);
+ inst->u.frame.ref = frame;
+ inst->u.frame.outer = curr_frame;
+ curr_frame = inst;
+}
+
+
+void inst_end_frame(const struct frame *frame)
+{
+ struct inst *inst = curr_frame;
+
+ curr_frame = curr_frame->u.frame.outer;
+ if (curr_frame)
+ propagate_bbox(inst);
+}
+
+
+/* ----- misc. ------------------------------------------------------------- */
+
+
+struct bbox inst_get_bbox(void)
+{
+ static struct bbox bbox_zero;
+
+ return insts ? insts->bbox : bbox_zero;
+}
+
+
+static void inst_free(void)
+{
+ struct inst *next;
+
+ while (insts) {
+ next = insts->next;
+ free(insts);
+ insts = next;
+ }
+ next_inst = &insts;
+}
+
+
+void inst_reset(void)
+{
+ inst_free();
+}
+
+
+void inst_draw(struct draw_ctx *ctx)
+{
+ struct inst *walk;
+
+ for (walk = insts; walk; walk = walk->next)
+ if (walk->ops->draw)
+ walk->ops->draw(walk, ctx);
+}
+
+
+void inst_debug(void)
+{
+ struct inst *walk;
+
+ for (walk = insts; walk; walk = walk->next)
+ walk->ops->debug(walk);
+}
Added: developers/werner/fped/inst.h
===================================================================
--- developers/werner/fped/inst.h (rev 0)
+++ developers/werner/fped/inst.h 2009-07-27 07:30:59 UTC (rev 5325)
@@ -0,0 +1,69 @@
+/*
+ * inst.h - Instance structures
+ *
+ * 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 INST_H
+#define INST_H
+
+#include <stdio.h>
+
+#include "coord.h"
+#include "obj.h"
+
+
+struct bbox {
+ struct coord min;
+ struct coord max;
+};
+
+struct inst;
+struct draw_ctx;
+
+struct inst_ops {
+ void (*debug)(struct inst *self);
+ void (*save)(FILE *file, struct inst *self);
+ void (*draw)(struct inst *self, struct draw_ctx *ctx);
+};
+
+struct inst {
+ const struct inst_ops *ops;
+ struct coord base;
+ struct bbox bbox;
+ union {
+ struct {
+ const struct frame *ref;
+ struct inst *outer;
+ } frame;
+ const char *name;
+ struct coord end;
+ struct {
+ unit_type r;
+ double a1, a2;
+ } arc;
+ } u;
+ struct inst *next;
+};
+
+
+int inst_vec(struct vec *vec, struct coord base);
+int inst_line(struct coord a, struct coord b);
+int inst_rect(struct coord a, struct coord b);
+int inst_pad(const char *name, struct coord a, struct coord b);
+int inst_arc(struct coord center, struct coord start, struct coord stop);
+void inst_begin_frame(const struct frame *frame, struct coord base);
+void inst_end_frame(const struct frame *frame);
+struct bbox inst_get_bbox(void);
+void inst_reset(void);
+void inst_draw(struct draw_ctx *ctx);
+void inst_debug(void);
+
+#endif /* !INST_H */
Added: developers/werner/fped/obj.c
===================================================================
--- developers/werner/fped/obj.c (rev 0)
+++ developers/werner/fped/obj.c 2009-07-27 07:30:59 UTC (rev 5325)
@@ -0,0 +1,139 @@
+/*
+ * obj.c - Object definition model
+ *
+ * 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 "expr.h"
+#include "obj.h"
+#include "inst.h"
+
+
+struct frame *frames = NULL;
+
+
+static int generate_frame(struct frame *frame, struct coord base,
+ const struct frame *parent);
+
+
+static int generate_objects(struct frame *frame, struct coord base)
+{
+ struct vec *vec;
+ struct obj *obj;
+ double x, y;
+
+ for (vec = frame->vecs; vec; vec = vec->next) {
+ x = eval_num(vec->x, frame);
+ if (x == UNDEF)
+ return 0;
+ y = eval_num(vec->y, frame);
+ if (y == UNDEF)
+ return 0;
+ vec->pos = vec->base ? vec->base->pos : base;
+ vec->pos.x += x;
+ vec->pos.y += y;
+ if (!inst_vec(vec, base))
+ return 0;
+ }
+ for (obj = frame->objs; obj; obj = obj->next)
+ switch (obj->type) {
+ case ot_frame:
+ if (!generate_frame(obj->u.frame,
+ obj->base ? obj->base->pos : base, frame))
+ return 0;
+ break;
+ case ot_line:
+ if (!inst_line(obj->base ? obj->base->pos : base,
+ obj->u.line.other ? obj->u.line.other->pos : base))
+ return 0;
+ break;
+ case ot_rect:
+ if (!inst_rect(obj->base ? obj->base->pos : base,
+ obj->u.rect.other ? obj->u.rect.other->pos : base))
+ return 0;
+ break;
+ case ot_pad:
+ if (!inst_pad(obj->u.pad.name,
+ obj->base ? obj->base->pos : base,
+ obj->u.pad.other ? obj->u.pad.other->pos : base))
+ return 0;
+ break;
+ case ot_arc:
+ if (!inst_arc(obj->base ? obj->base->pos : base,
+ obj->u.arc.start ? obj->u.arc.start->pos : base,
+ obj->u.arc.end ? obj->u.arc.end->pos : base))
+ return 0;
+ break;
+ default:
+ abort();
+ }
+ return 1;
+}
+
+
+static int run_loops(struct frame *frame, struct loop *loop,
+ struct coord base)
+{
+ double from, to;
+
+ if (!loop)
+ return generate_objects(frame, base);
+ from = eval_num(loop->from, frame);
+ if (from == UNDEF)
+ return 0;
+ to = eval_num(loop->to, frame);
+ if (from == UNDEF)
+ return 0;
+ for (loop->curr_value = from; loop->curr_value <= to;
+ loop->curr_value += 1)
+ if (!run_loops(frame, loop->next, base))
+ return 0;
+ return 1;
+}
+
+
+static int iterate_tables(struct frame *frame, struct table *table,
+ struct coord base)
+{
+ if (!table)
+ return run_loops(frame, frame->loops, base);
+ for (table->curr_row = table->rows; table->curr_row;
+ table->curr_row = table->curr_row->next)
+ if (!iterate_tables(frame, table->next, base))
+ return 0;
+ return 1;
+}
+
+
+static int generate_frame(struct frame *frame, struct coord base,
+ const struct frame *parent)
+{
+ int res;
+
+ /*
+ * We ensure during construction that frames can never recurse.
+ */
+ inst_begin_frame(frame, base);
+ frame->curr_parent = parent;
+ res = iterate_tables(frame, frame->tables, base);
+ inst_end_frame(frame);
+ return res;
+}
+
+
+void instantiate(void)
+{
+ struct coord zero = { 0, 0 };
+
+ inst_reset();
+ generate_frame(frames, zero, NULL);
+}
Added: developers/werner/fped/obj.h
===================================================================
--- developers/werner/fped/obj.h (rev 0)
+++ developers/werner/fped/obj.h 2009-07-27 07:30:59 UTC (rev 5325)
@@ -0,0 +1,120 @@
+/*
+ * obj.h - Object definition model
+ *
+ * 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 OBJ_H
+#define OBJ_H
+
+#include "expr.h"
+#include "coord.h"
+
+
+struct var {
+ const char *name;
+ struct var *next;
+};
+
+struct value {
+ struct expr *expr;
+ struct value *next;
+};
+
+struct row {
+ struct value *values;
+ struct row *next;
+};
+
+struct table {
+ struct var *vars;
+ struct row *rows;
+ struct table *next;
+
+ /* used during generation and when editing */
+ struct row *curr_row;
+};
+
+struct loop {
+ const char *var;
+ struct expr *from;
+ struct expr *to;
+ struct loop *next;
+
+ /* used during generation */
+ double curr_value;
+};
+
+struct vec {
+ const char *name; /* NULL if anonymous */
+ struct expr *x;
+ struct expr *y;
+ struct vec *base; /* NULL if frame */
+ int n_refs;
+ struct vec *next;
+
+ /* used during generation */
+ struct coord pos;
+};
+
+struct frame {
+ const char *name; /* NULL if top-level */
+ struct table *tables;
+ struct loop *loops;
+ struct vec *vecs;
+ struct obj *objs;
+ struct frame *next;
+
+ /* used during generation */
+ const struct frame *curr_parent;
+};
+
+enum obj_type {
+ ot_frame,
+ ot_rect,
+ ot_pad,
+ ot_line,
+ ot_arc,
+};
+
+struct rect {
+ struct vec *other; /* NULL if frame origin */
+};
+
+struct pad {
+ const char *name;
+ struct vec *other; /* NULL if frame origin */
+};
+
+struct arc {
+ struct vec *start; /* NULL if frame origin */
+ struct vec *end; /* NULL if this is a circle */
+};
+
+struct obj {
+ enum obj_type type;
+ union {
+ struct frame *frame;
+ struct rect rect;
+ struct rect line;
+ struct pad pad;
+ struct arc arc;
+ } u;
+ struct vec *base;
+ struct obj *next;
+};
+
+
+struct frame *frames;
+
+
+void instantiate(void);
+
+#endif /* !OBJ_H */
Added: developers/werner/fped/qfn.fpd
===================================================================
--- developers/werner/fped/qfn.fpd (rev 0)
+++ developers/werner/fped/qfn.fpd 2009-07-27 07:30:59 UTC (rev 5325)
@@ -0,0 +1,27 @@
+# http://www.nxp.com/acrobat/packages/footprint/SOT616-1_fp_reflow.pdf
+
+.frame pad_up {
+ .vec @ -D/2, 0
+ .vec . D, C
+ .pad "N/4+n" @ .
+}
+
+N = 24
+
+.table
+ { P, Ax, Ay, By, C, D, SLx, SLy, SPx_tot, SPy_tot, SPx, SPy, Gx, Gy, Hx, Hy }
+ { 0.5mm, 5mm, 5mm, 3.2mm, 3.2mm, 0.9mm, 0.24mm, 2.1mm, 2.1mm, 1.2mm,
+ 0.45mm, 0.45mm, 4.3mm, 4.3mm, 5.25mm, 5.25mm }
+
+h_x0y0 = .vec @ -Hx/2, -Hy/2
+h_x1y1 = .vec . Hx, Hy
+.rect h_x0y0 h_x1y1
+
+g_x0y0 = .vec @ -Gx/2, -Gy/2
+g_x1y1 = .vec . Gx, Gy
+.rect g_x0y0 g_x1y1
+
+n = 0, N/4-1
+
+.vec @ P*(n-(N-1)/2), -Ay/2
+.frame pad_up .
Added: developers/werner/fped/util.c
===================================================================
--- developers/werner/fped/util.c (rev 0)
+++ developers/werner/fped/util.c 2009-07-27 07:30:59 UTC (rev 5325)
@@ -0,0 +1,38 @@
+/*
+ * util.c - Common utility functions
+ *
+ * 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 <string.h>
+
+#include "util.h"
+
+
+static struct unique {
+ const char *s;
+ struct unique *next;
+} *uniques = NULL;
+
+
+/* @@@ consider using rb trees */
+
+const char *unique(const char *s)
+{
+ struct unique **walk;
+
+ for (walk = &uniques; *walk; walk = &(*walk)->next)
+ if (!strcmp(s, (*walk)->s))
+ return (*walk)->s;
+ *walk = alloc_type(struct unique);
+ (*walk)->s = stralloc(s);
+ (*walk)->next = NULL;
+ return (*walk)->s;
+}
Added: developers/werner/fped/util.h
===================================================================
--- developers/werner/fped/util.h (rev 0)
+++ developers/werner/fped/util.h 2009-07-27 07:30:59 UTC (rev 5325)
@@ -0,0 +1,40 @@
+/*
+ * util.h - Common utility functions
+ *
+ * Written 2006, 2009 by Werner Almesberger
+ * Copyright 2006, 2009 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 UTIL_H
+#define UTIL_H
+
+#include <stdlib.h>
+#include <string.h>
+
+
+#define alloc_type(t) \
+ ({ t *alloc_type_tmp = (t *) malloc(sizeof(t)); \
+ if (!alloc_type_tmp) \
+ abort(); \
+ alloc_type_tmp; })
+
+#define zalloc_type(t) \
+ ({ t *zalloc_type_tmp = alloc_type(t); \
+ memset(zalloc_type_tmp, 0, sizeof(t)); \
+ zalloc_type_tmp; })
+
+#define stralloc(s) \
+ ({ char *stralloc_tmp = strdup(s); \
+ if (!stralloc_tmp) \
+ abort(); \
+ stralloc_tmp; })
+
+const char *unique(const char *s);
+
+#endif /* !UTIL_H */
More information about the commitlog
mailing list