mirror of
git://projects.qi-hardware.com/eda-tools.git
synced 2024-11-23 05:31:53 +02:00
sch2fig/sch.c: separate parsing from rendering
This commit is contained in:
parent
50242899d3
commit
66ca318dbe
@ -69,6 +69,7 @@ static void usage(const char *name)
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
struct sch_ctx sch_ctx;
|
||||||
const char *template = NULL;
|
const char *template = NULL;
|
||||||
char c;
|
char c;
|
||||||
int arg;
|
int arg;
|
||||||
@ -94,20 +95,17 @@ int main(int argc, char **argv)
|
|||||||
if (argc - optind < 1)
|
if (argc - optind < 1)
|
||||||
usage(*argv);
|
usage(*argv);
|
||||||
|
|
||||||
//gfx_init(&fig_ops, template, n_vars, vars);
|
for (arg = optind; arg != argc - 1; arg++) {
|
||||||
gfx_init(&cairo_ops, template, n_vars, vars);
|
struct lib_ctx ctx;
|
||||||
for (arg = optind; arg != argc; arg++) {
|
|
||||||
if (arg == argc - 1) {
|
|
||||||
struct sch_ctx ctx;
|
|
||||||
|
|
||||||
sch_init(&ctx);
|
lib_init(&ctx);
|
||||||
read_file(argv[arg], &ctx, do_sch_parse);
|
read_file(argv[arg], &ctx, do_lib_parse);
|
||||||
} else {
|
|
||||||
struct lib_ctx ctx;
|
|
||||||
|
|
||||||
lib_init(&ctx);
|
|
||||||
read_file(argv[arg], &ctx, do_lib_parse);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sch_init(&sch_ctx);
|
||||||
|
read_file(argv[argc - 1], &sch_ctx, do_sch_parse);
|
||||||
|
gfx_init(&fig_ops, template, n_vars, vars);
|
||||||
|
//gfx_init(&cairo_ops, template, n_vars, vars);
|
||||||
|
sch_render(&sch_ctx);
|
||||||
gfx_end();
|
gfx_end();
|
||||||
}
|
}
|
||||||
|
409
sch2fig/sch.c
409
sch2fig/sch.c
@ -28,6 +28,157 @@
|
|||||||
#include "sch.h"
|
#include "sch.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* ----- Rendering --------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
static void dump_field(const struct comp_field *field, int m[6])
|
||||||
|
{
|
||||||
|
struct text txt = field->txt;
|
||||||
|
int dx, dy;
|
||||||
|
|
||||||
|
dx = txt.x - m[0];
|
||||||
|
dy = txt.y - m[3];
|
||||||
|
txt.x = mx(dx, dy, m);
|
||||||
|
txt.y = my(dx, dy, m);
|
||||||
|
|
||||||
|
text_rot(&txt, matrix_to_angle(m));
|
||||||
|
|
||||||
|
switch (txt.rot) {
|
||||||
|
case 180:
|
||||||
|
text_rot(&txt, 180);
|
||||||
|
txt.hor = text_flip(txt.hor);
|
||||||
|
txt.vert = text_flip(txt.vert);
|
||||||
|
break;
|
||||||
|
case 270:
|
||||||
|
text_rot(&txt, 180);
|
||||||
|
txt.vert = text_flip(txt.vert);
|
||||||
|
txt.hor = text_flip(txt.hor);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matrix_is_mirrored(m)) {
|
||||||
|
if ((txt.rot % 180) == 0)
|
||||||
|
txt.hor = text_flip(txt.hor);
|
||||||
|
else
|
||||||
|
txt.vert = text_flip(txt.vert);
|
||||||
|
}
|
||||||
|
|
||||||
|
text_fig(&txt, COLOR_FIELD, LAYER_FIELD);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void do_hsheet_text(const struct sch_obj *obj,
|
||||||
|
const struct sch_sheet *sheet)
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
assert(sheet->sheet && sheet->file);
|
||||||
|
|
||||||
|
struct text sheet_txt = {
|
||||||
|
.size = sheet->sheet_dim,
|
||||||
|
.x = obj->x,
|
||||||
|
.y = obj->y,
|
||||||
|
.rot = 0,
|
||||||
|
.hor = text_min,
|
||||||
|
.vert = text_min,
|
||||||
|
};
|
||||||
|
if (asprintf(&s, "Sheet: %s", sheet->sheet)) {}
|
||||||
|
sheet_txt.s = s; /* work around "const" mismatch */
|
||||||
|
|
||||||
|
struct text file_txt = {
|
||||||
|
.size = sheet->file_dim,
|
||||||
|
.x = obj->x,
|
||||||
|
.y = obj->y,
|
||||||
|
.rot = 0,
|
||||||
|
.hor = text_min,
|
||||||
|
.vert = text_max,
|
||||||
|
};
|
||||||
|
if (asprintf(&s, "File: %s", sheet->file)) {}
|
||||||
|
file_txt.s = s; /* work around "const" mismatch */
|
||||||
|
|
||||||
|
if (sheet->rotated) {
|
||||||
|
sheet_txt.rot = file_txt.rot = 90;
|
||||||
|
sheet_txt.x -= HSHEET_FIELD_OFFSET;
|
||||||
|
sheet_txt.y += sheet->h;
|
||||||
|
file_txt.x += sheet->w + HSHEET_FIELD_OFFSET;
|
||||||
|
file_txt.y += sheet->h;
|
||||||
|
} else {
|
||||||
|
sheet_txt.y -= HSHEET_FIELD_OFFSET;
|
||||||
|
file_txt.y += sheet->h + HSHEET_FIELD_OFFSET;
|
||||||
|
}
|
||||||
|
|
||||||
|
text_fig(&sheet_txt, COLOR_HSHEET_SHEET, LAYER_HSHEET_FIELD);
|
||||||
|
text_fig(&file_txt, COLOR_HSHEET_FILE, LAYER_HSHEET_FIELD);
|
||||||
|
|
||||||
|
// free((void *) ctx->sheet);
|
||||||
|
// free((void *) ctx->file);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void render_sheet(const struct sch_obj *obj,
|
||||||
|
const struct sch_sheet *sheet)
|
||||||
|
{
|
||||||
|
const struct sheet_field *field;
|
||||||
|
|
||||||
|
gfx_rect(obj->x, obj->y, obj->x + sheet->w, obj->y + sheet->h,
|
||||||
|
COLOR_HSHEET_BOX, COLOR_NONE, LAYER_HSHEET_BOX);
|
||||||
|
do_hsheet_text(obj, sheet);
|
||||||
|
|
||||||
|
for (field = sheet->fields; field; field = field->next)
|
||||||
|
dwg_hlabel(obj->x, obj->y, field->s,
|
||||||
|
field->side, field->dim,
|
||||||
|
field->shape);
|
||||||
|
// free(field->s)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void sch_render(const struct sch_ctx *ctx)
|
||||||
|
{
|
||||||
|
const struct sch_obj *obj;
|
||||||
|
|
||||||
|
for (obj = ctx->objs; obj; obj = obj->next)
|
||||||
|
switch (obj->type) {
|
||||||
|
case sch_obj_wire:
|
||||||
|
{
|
||||||
|
const struct sch_wire *wire = &obj->u.wire;
|
||||||
|
|
||||||
|
wire->fn(obj->x, obj->y, wire->ex, wire->ey);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case sch_obj_junction:
|
||||||
|
dwg_junction(obj->x, obj->y);
|
||||||
|
break;
|
||||||
|
case sch_obj_noconn:
|
||||||
|
dwg_noconn(obj->x, obj->y);
|
||||||
|
break;
|
||||||
|
case sch_obj_text:
|
||||||
|
{
|
||||||
|
const struct sch_text *text = &obj->u.text;
|
||||||
|
|
||||||
|
text->fn(obj->x, obj->y, text->s, text->dir,
|
||||||
|
text->dim, text->shape);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case sch_obj_comp:
|
||||||
|
{
|
||||||
|
const struct sch_comp *comp = &obj->u.comp;
|
||||||
|
const struct comp_field *field;
|
||||||
|
|
||||||
|
lib_exec(comp->comp, comp->unit, comp->m);
|
||||||
|
for (field = comp->fields; field;
|
||||||
|
field = field->next)
|
||||||
|
dump_field(field, comp->m);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case sch_obj_sheet:
|
||||||
|
render_sheet(obj, &obj->u.sheet);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ----- (Global) Labels --------------------------------------------------- */
|
/* ----- (Global) Labels --------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
@ -98,12 +249,6 @@ static void draw_text(int x, int y, const char *s, int dir, int dim,
|
|||||||
/* ----- Component fields -------------------------------------------------- */
|
/* ----- Component fields -------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
struct sch_field {
|
|
||||||
struct text txt;
|
|
||||||
struct sch_field *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void decode_alignment(struct text *txt, char hor, char vert)
|
void decode_alignment(struct text *txt, char hor, char vert)
|
||||||
{
|
{
|
||||||
switch (hor) {
|
switch (hor) {
|
||||||
@ -138,13 +283,14 @@ void decode_alignment(struct text *txt, char hor, char vert)
|
|||||||
|
|
||||||
static bool parse_field(struct sch_ctx *ctx, const char *line)
|
static bool parse_field(struct sch_ctx *ctx, const char *line)
|
||||||
{
|
{
|
||||||
|
struct sch_comp *comp = &ctx->obj.u.comp;
|
||||||
int n;
|
int n;
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
char hv, hor, vert, italic, bold;
|
char hv, hor, vert, italic, bold;
|
||||||
struct sch_field *field;
|
struct comp_field *field;
|
||||||
struct text *txt;
|
struct text *txt;
|
||||||
|
|
||||||
field = alloc_type(struct sch_field);
|
field = alloc_type(struct comp_field);
|
||||||
txt = &field->txt;
|
txt = &field->txt;
|
||||||
|
|
||||||
if (sscanf(line, "F %d \"\" %c %d %d %u %u %c %c%c%c",
|
if (sscanf(line, "F %d \"\" %c %d %d %u %u %c %c%c%c",
|
||||||
@ -158,12 +304,12 @@ static bool parse_field(struct sch_ctx *ctx, const char *line)
|
|||||||
&hor, &vert, &italic, &bold) != 11)
|
&hor, &vert, &italic, &bold) != 11)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (flags || !lib_field_visible(ctx->comp, n)) {
|
if (flags || !lib_field_visible(comp->comp, n)) {
|
||||||
free(field);
|
free(field);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n == 0 && ctx->comp->units > 1) {
|
if (n == 0 && comp->comp->units > 1) {
|
||||||
int len = strlen(txt->s);
|
int len = strlen(txt->s);
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
@ -172,17 +318,16 @@ static bool parse_field(struct sch_ctx *ctx, const char *line)
|
|||||||
perror("realloc");
|
perror("realloc");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (ctx->unit <= 26)
|
if (comp->unit <= 26)
|
||||||
sprintf(s + len, "%c", 'A' + ctx->unit - 1);
|
sprintf(s + len, "%c", 'A' + comp->unit - 1);
|
||||||
else
|
else
|
||||||
sprintf(s + len, "%c%c",
|
sprintf(s + len, "%c%c",
|
||||||
'A' + (ctx->unit - 1) / 26 - 1,
|
'A' + (comp->unit - 1) / 26 - 1,
|
||||||
'A' + (ctx->unit - 1) % 26);
|
'A' + (comp->unit - 1) % 26);
|
||||||
txt->s = s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
field->next = ctx->fields;
|
field->next = comp->fields;
|
||||||
ctx->fields = field;
|
comp->fields = field;
|
||||||
|
|
||||||
switch (hv) {
|
switch (hv) {
|
||||||
case 'H':
|
case 'H':
|
||||||
@ -203,59 +348,6 @@ static bool parse_field(struct sch_ctx *ctx, const char *line)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void dump_field(const struct sch_field *field, int m[6])
|
|
||||||
{
|
|
||||||
struct text txt = field->txt;
|
|
||||||
int dx, dy;
|
|
||||||
|
|
||||||
dx = txt.x - m[0];
|
|
||||||
dy = txt.y - m[3];
|
|
||||||
txt.x = mx(dx, dy, m);
|
|
||||||
txt.y = my(dx, dy, m);
|
|
||||||
|
|
||||||
text_rot(&txt, matrix_to_angle(m));
|
|
||||||
|
|
||||||
switch (txt.rot) {
|
|
||||||
case 180:
|
|
||||||
text_rot(&txt, 180);
|
|
||||||
txt.hor = text_flip(txt.hor);
|
|
||||||
txt.vert = text_flip(txt.vert);
|
|
||||||
break;
|
|
||||||
case 270:
|
|
||||||
text_rot(&txt, 180);
|
|
||||||
txt.vert = text_flip(txt.vert);
|
|
||||||
txt.hor = text_flip(txt.hor);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (matrix_is_mirrored(m)) {
|
|
||||||
if ((txt.rot % 180) == 0)
|
|
||||||
txt.hor = text_flip(txt.hor);
|
|
||||||
else
|
|
||||||
txt.vert = text_flip(txt.vert);
|
|
||||||
}
|
|
||||||
|
|
||||||
text_fig(&txt, COLOR_FIELD, LAYER_FIELD);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void dump_fields(struct sch_field *fields, int m[6])
|
|
||||||
{
|
|
||||||
while (fields) {
|
|
||||||
struct text *txt = &fields->txt;
|
|
||||||
struct sch_field *next = fields->next;
|
|
||||||
|
|
||||||
dump_field(fields, m);
|
|
||||||
text_free(txt);
|
|
||||||
|
|
||||||
free(fields);
|
|
||||||
fields = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ----- Sheet field ------------------------------------------------------- */
|
/* ----- Sheet field ------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
@ -299,29 +391,34 @@ static int decode_side(char side)
|
|||||||
|
|
||||||
static bool parse_hsheet_field(struct sch_ctx *ctx, const char *line)
|
static bool parse_hsheet_field(struct sch_ctx *ctx, const char *line)
|
||||||
{
|
{
|
||||||
|
struct sch_sheet *sheet = &ctx->obj.u.sheet;
|
||||||
char *s;
|
char *s;
|
||||||
int x, y;
|
|
||||||
char form, side;
|
char form, side;
|
||||||
unsigned n, dim;
|
unsigned n, dim;
|
||||||
|
struct sheet_field *field;
|
||||||
|
|
||||||
if (sscanf(line, "F%d \"%m[^\"]\" %u", &n, &s, &dim) == 3) {
|
if (sscanf(line, "F%d \"%m[^\"]\" %u", &n, &s, &dim) == 3) {
|
||||||
switch (n) {
|
switch (n) {
|
||||||
case 0:
|
case 0:
|
||||||
ctx->sheet = s;
|
sheet->sheet = s;
|
||||||
ctx->sheet_dim = dim;
|
sheet->sheet_dim = dim;
|
||||||
return 1;
|
return 1;
|
||||||
case 1:
|
case 1:
|
||||||
ctx->file = s;
|
sheet->file = s;
|
||||||
ctx->file_dim = dim;
|
sheet->file_dim = dim;
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
field = alloc_type(struct sheet_field);
|
||||||
if (sscanf(line, "F%d \"%m[^\"]\" %c %c %d %d %u",
|
if (sscanf(line, "F%d \"%m[^\"]\" %c %c %d %d %u",
|
||||||
&n, &s, &form, &side, &x, &y, &dim) != 7)
|
&n, &field->s, &form, &side, &field->x, &field->y, &field->dim)
|
||||||
|
!= 7) {
|
||||||
|
free(field);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
assert(n >= 2);
|
assert(n >= 2);
|
||||||
|
|
||||||
if (side == 'B' || side == 'T') {
|
if (side == 'B' || side == 'T') {
|
||||||
@ -339,71 +436,38 @@ static bool parse_hsheet_field(struct sch_ctx *ctx, const char *line)
|
|||||||
* flips rotated sheets where the last imported pin is deleted
|
* flips rotated sheets where the last imported pin is deleted
|
||||||
* back.
|
* back.
|
||||||
*/
|
*/
|
||||||
ctx->rotated = 1;
|
sheet->rotated = 1;
|
||||||
}
|
}
|
||||||
dwg_hlabel(x, y, s, decode_side(side), dim, decode_form(form));
|
field->shape = decode_form(form);
|
||||||
free(s);
|
field->side = decode_side(side);
|
||||||
|
|
||||||
|
field->next = sheet->fields;
|
||||||
|
sheet->fields = field;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void do_hsheet_text(struct sch_ctx *ctx)
|
|
||||||
{
|
|
||||||
char *s;
|
|
||||||
|
|
||||||
assert(ctx->sheet && ctx->file);
|
|
||||||
|
|
||||||
struct text sheet_txt = {
|
|
||||||
.size = ctx->sheet_dim,
|
|
||||||
.x = ctx->x,
|
|
||||||
.y = ctx->y,
|
|
||||||
.rot = 0,
|
|
||||||
.hor = text_min,
|
|
||||||
.vert = text_min,
|
|
||||||
};
|
|
||||||
if (asprintf(&s, "Sheet: %s", ctx->sheet)) {}
|
|
||||||
sheet_txt.s = s; /* work around "const" mismatch */
|
|
||||||
|
|
||||||
struct text file_txt = {
|
|
||||||
.size = ctx->file_dim,
|
|
||||||
.x = ctx->x,
|
|
||||||
.y = ctx->y,
|
|
||||||
.rot = 0,
|
|
||||||
.hor = text_min,
|
|
||||||
.vert = text_max,
|
|
||||||
};
|
|
||||||
if (asprintf(&s, "File: %s", ctx->file)) {}
|
|
||||||
file_txt.s = s; /* work around "const" mismatch */
|
|
||||||
|
|
||||||
if (ctx->rotated) {
|
|
||||||
sheet_txt.rot = file_txt.rot = 90;
|
|
||||||
sheet_txt.x -= HSHEET_FIELD_OFFSET;
|
|
||||||
sheet_txt.y += ctx->h;
|
|
||||||
file_txt.x += ctx->w + HSHEET_FIELD_OFFSET;
|
|
||||||
file_txt.y += ctx->h;
|
|
||||||
} else {
|
|
||||||
sheet_txt.y -= HSHEET_FIELD_OFFSET;
|
|
||||||
file_txt.y += ctx->h + HSHEET_FIELD_OFFSET;
|
|
||||||
}
|
|
||||||
|
|
||||||
text_fig(&sheet_txt, COLOR_HSHEET_SHEET, LAYER_HSHEET_FIELD);
|
|
||||||
text_fig(&file_txt, COLOR_HSHEET_FILE, LAYER_HSHEET_FIELD);
|
|
||||||
|
|
||||||
free((void *) ctx->sheet);
|
|
||||||
free((void *) ctx->file);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ----- Schematics parser ------------------------------------------------- */
|
/* ----- Schematics parser ------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
static void submit_obj(struct sch_ctx *ctx, enum sch_obj_type type)
|
||||||
|
{
|
||||||
|
struct sch_obj *obj;
|
||||||
|
|
||||||
|
obj = alloc_type(struct sch_obj);
|
||||||
|
*obj = ctx->obj;
|
||||||
|
obj->type = type;
|
||||||
|
obj->next = ctx->objs;
|
||||||
|
ctx->objs = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool sch_parse(struct sch_ctx *ctx, const char *line)
|
bool sch_parse(struct sch_ctx *ctx, const char *line)
|
||||||
{
|
{
|
||||||
|
struct sch_obj *obj = &ctx->obj;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
int x, y, ex, ey;
|
|
||||||
char *s;
|
char *s;
|
||||||
int m[4];
|
|
||||||
|
|
||||||
ctx->lineno++;
|
ctx->lineno++;
|
||||||
|
|
||||||
@ -411,57 +475,60 @@ bool sch_parse(struct sch_ctx *ctx, const char *line)
|
|||||||
case sch_basic:
|
case sch_basic:
|
||||||
if (sscanf(line, "$Comp%n", &n) == 0 && n) {
|
if (sscanf(line, "$Comp%n", &n) == 0 && n) {
|
||||||
ctx->state = sch_comp;
|
ctx->state = sch_comp;
|
||||||
ctx->fields = NULL;
|
obj->u.comp.fields = NULL;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (sscanf(line, "$Sheet%n", &n) == 0 && n) {
|
if (sscanf(line, "$Sheet%n", &n) == 0 && n) {
|
||||||
ctx->state = sch_sheet;
|
ctx->state = sch_sheet;
|
||||||
ctx->sheet = NULL;
|
obj->u.sheet.sheet = NULL;
|
||||||
ctx->file = NULL;
|
obj->u.sheet.file = NULL;
|
||||||
ctx->rotated = 0;
|
obj->u.sheet.rotated = 0;
|
||||||
|
obj->u.sheet.fields = NULL;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Text */
|
/* Text */
|
||||||
|
|
||||||
|
struct sch_text *text = &obj->u.text;
|
||||||
|
|
||||||
if (sscanf(line, "Text Notes %d %d %d %d",
|
if (sscanf(line, "Text Notes %d %d %d %d",
|
||||||
&ctx->x, &ctx->y, &ctx->dir, &ctx->dim) == 4) {
|
&obj->x, &obj->y, &text->dir, &text->dim) == 4) {
|
||||||
ctx->state = sch_text;
|
ctx->state = sch_text;
|
||||||
ctx->text = draw_text;
|
obj->u.text.fn = draw_text;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (sscanf(line, "Text GLabel %d %d %d %d %ms",
|
if (sscanf(line, "Text GLabel %d %d %d %d %ms",
|
||||||
&ctx->x, &ctx->y, &ctx->dir, &ctx->dim, &s) == 5) {
|
&obj->x, &obj->y, &text->dir, &text->dim, &s) == 5) {
|
||||||
ctx->state = sch_text;
|
ctx->state = sch_text;
|
||||||
ctx->shape = decode_shape(s);
|
obj->u.text.fn = dwg_glabel;
|
||||||
ctx->text = dwg_glabel;
|
obj->u.text.shape = decode_shape(s);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (sscanf(line, "Text HLabel %d %d %d %d %ms",
|
if (sscanf(line, "Text HLabel %d %d %d %d %ms",
|
||||||
&ctx->x, &ctx->y, &ctx->dir, &ctx->dim, &s) == 5) {
|
&obj->x, &obj->y, &text->dir, &text->dim, &s) == 5) {
|
||||||
ctx->state = sch_text;
|
ctx->state = sch_text;
|
||||||
ctx->shape = decode_shape(s);
|
obj->u.text.fn = dwg_hlabel;
|
||||||
ctx->text = dwg_hlabel;
|
obj->u.text.shape = decode_shape(s);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (sscanf(line, "Text Label %d %d %d %d",
|
if (sscanf(line, "Text Label %d %d %d %d",
|
||||||
&ctx->x, &ctx->y, &ctx->dir, &ctx->dim) == 4) {
|
&obj->x, &obj->y, &text->dir, &text->dim) == 4) {
|
||||||
ctx->state = sch_text;
|
ctx->state = sch_text;
|
||||||
ctx->text = dwg_label;
|
obj->u.text.fn = dwg_label;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Connection */
|
/* Connection */
|
||||||
|
|
||||||
if (sscanf(line, "Connection ~ %d %d", &x, &y) == 2) {
|
if (sscanf(line, "Connection ~ %d %d", &obj->x, &obj->y) == 2) {
|
||||||
dwg_junction(x, y);
|
submit_obj(ctx, sch_obj_junction);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NoConn */
|
/* NoConn */
|
||||||
|
|
||||||
if (sscanf(line, "NoConn ~ %d %d", &x, &y) == 2) {
|
if (sscanf(line, "NoConn ~ %d %d", &obj->x, &obj->y) == 2) {
|
||||||
dwg_noconn(x, y);
|
submit_obj(ctx, sch_obj_noconn);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,17 +536,17 @@ bool sch_parse(struct sch_ctx *ctx, const char *line)
|
|||||||
|
|
||||||
if (sscanf(line, "Wire Wire Line%n", &n) == 0 && n) {
|
if (sscanf(line, "Wire Wire Line%n", &n) == 0 && n) {
|
||||||
ctx->state = sch_wire;
|
ctx->state = sch_wire;
|
||||||
ctx->wire = dwg_wire;
|
obj->u.wire.fn = dwg_wire;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (sscanf(line, "Wire Bus Line%n", &n) == 0 && n) {
|
if (sscanf(line, "Wire Bus Line%n", &n) == 0 && n) {
|
||||||
ctx->state = sch_wire;
|
ctx->state = sch_wire;
|
||||||
ctx->wire = dwg_bus;
|
obj->u.wire.fn = dwg_bus;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (sscanf(line, "Wire Notes Line%n", &n) == 0 && n) {
|
if (sscanf(line, "Wire Notes Line%n", &n) == 0 && n) {
|
||||||
ctx->state = sch_wire;
|
ctx->state = sch_wire;
|
||||||
ctx->wire = dwg_line;
|
obj->u.wire.fn = dwg_line;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -497,12 +564,12 @@ bool sch_parse(struct sch_ctx *ctx, const char *line)
|
|||||||
*/
|
*/
|
||||||
if (sscanf(line, "Entry Wire Line%n", &n) == 0 && n) {
|
if (sscanf(line, "Entry Wire Line%n", &n) == 0 && n) {
|
||||||
ctx->state = sch_wire;
|
ctx->state = sch_wire;
|
||||||
ctx->wire = dwg_wire;
|
obj->u.wire.fn = dwg_wire;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (sscanf(line, "Entry Bus Bus%n", &n) == 0 && n) {
|
if (sscanf(line, "Entry Bus Bus%n", &n) == 0 && n) {
|
||||||
ctx->state = sch_wire;
|
ctx->state = sch_wire;
|
||||||
ctx->wire = dwg_bus;
|
obj->u.wire.fn = dwg_bus;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -519,46 +586,42 @@ bool sch_parse(struct sch_ctx *ctx, const char *line)
|
|||||||
case sch_comp:
|
case sch_comp:
|
||||||
if (sscanf(line, "$EndComp%n", &n) == 0 && n) {
|
if (sscanf(line, "$EndComp%n", &n) == 0 && n) {
|
||||||
ctx->state = sch_basic;
|
ctx->state = sch_basic;
|
||||||
ctx->comp = NULL;
|
submit_obj(ctx, sch_obj_comp);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (sscanf(line, "L %ms", &s) == 1) {
|
if (sscanf(line, "L %ms", &s) == 1) {
|
||||||
ctx->comp = lib_find(s);
|
obj->u.comp.comp = lib_find(s);
|
||||||
free(s);
|
free(s);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (sscanf(line, "U %u", &ctx->unit) == 1)
|
if (sscanf(line, "U %u", &obj->u.comp.unit) == 1)
|
||||||
return 1;
|
return 1;
|
||||||
if (sscanf(line, "P %d %d", &ctx->x, &ctx->y) == 2)
|
if (sscanf(line, "P %d %d", &obj->x, &obj->y) == 2)
|
||||||
return 1;
|
return 1;
|
||||||
if (parse_field(ctx, line))
|
if (parse_field(ctx, line))
|
||||||
return 1;
|
return 1;
|
||||||
if (sscanf(line, "AR %n", &n) == 0 && n)
|
if (sscanf(line, "AR %n", &n) == 0 && n)
|
||||||
return 1; /* @@@ what is "AR" ? */
|
return 1; /* @@@ what is "AR" ? */
|
||||||
n = sscanf(line, " %d %d %d %d", m + 1, m + 2, m + 4, m + 5);
|
n = sscanf(line, " %d %d %d %d",
|
||||||
|
obj->u.comp.m + 1, obj->u.comp.m + 2,
|
||||||
|
obj->u.comp.m + 4, obj->u.comp.m + 5);
|
||||||
if (n == 3)
|
if (n == 3)
|
||||||
return 1;
|
return 1;
|
||||||
if (n == 4) {
|
if (n == 4) {
|
||||||
m[0] = ctx->x;
|
obj->u.comp.m[0] = obj->x;
|
||||||
m[3] = ctx->y;
|
obj->u.comp.m[3] = obj->y;
|
||||||
lib_exec(ctx->comp, ctx->unit, m);
|
|
||||||
dump_fields(ctx->fields, m);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case sch_sheet:
|
case sch_sheet:
|
||||||
if (sscanf(line, "$EndSheet%n", &n) == 0 && n) {
|
if (sscanf(line, "$EndSheet%n", &n) == 0 && n) {
|
||||||
ctx->state = sch_basic;
|
ctx->state = sch_basic;
|
||||||
do_hsheet_text(ctx);
|
submit_obj(ctx, sch_obj_sheet);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (sscanf(line, "S %d %d %u %u",
|
if (sscanf(line, "S %d %d %u %u",
|
||||||
&ctx->x, &ctx->y, &ctx->w, &ctx->h) == 4) {
|
&obj->x, &obj->y, &obj->u.sheet.w, &obj->u.sheet.h) == 4)
|
||||||
gfx_rect(ctx->x, ctx->y,
|
|
||||||
ctx->x + ctx->w, ctx->y + ctx->h,
|
|
||||||
COLOR_HSHEET_BOX, COLOR_NONE, LAYER_HSHEET_BOX);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
if (sscanf(line, "U %*x%n", &n) == 0 && n)
|
if (sscanf(line, "U %*x%n", &n) == 0 && n)
|
||||||
return 1;
|
return 1;
|
||||||
if (parse_hsheet_field(ctx, line))
|
if (parse_hsheet_field(ctx, line))
|
||||||
@ -566,7 +629,7 @@ bool sch_parse(struct sch_ctx *ctx, const char *line)
|
|||||||
break;
|
break;
|
||||||
case sch_text:
|
case sch_text:
|
||||||
ctx->state = sch_basic;
|
ctx->state = sch_basic;
|
||||||
if (ctx->text) {
|
{
|
||||||
const char *from;
|
const char *from;
|
||||||
char *to;
|
char *to;
|
||||||
|
|
||||||
@ -582,16 +645,15 @@ bool sch_parse(struct sch_ctx *ctx, const char *line)
|
|||||||
from += 2;
|
from += 2;
|
||||||
}
|
}
|
||||||
*to = 0;
|
*to = 0;
|
||||||
ctx->text(ctx->x, ctx->y, s, ctx->dir, ctx->dim,
|
obj->u.text.s = s;
|
||||||
ctx->shape);
|
submit_obj(ctx, sch_obj_text);
|
||||||
free(s);
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
case sch_wire:
|
case sch_wire:
|
||||||
if (sscanf(line, "%d %d %d %d", &x, &y, &ex, &ey) != 4)
|
if (sscanf(line, "%d %d %d %d", &obj->x, &obj->y,
|
||||||
|
&obj->u.wire.ex, &obj->u.wire.ey) != 4)
|
||||||
break;
|
break;
|
||||||
if (ctx->wire)
|
submit_obj(ctx, sch_obj_wire);
|
||||||
ctx->wire(x, y, ex, ey);
|
|
||||||
ctx->state = sch_basic;
|
ctx->state = sch_basic;
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
default:
|
||||||
@ -605,5 +667,6 @@ bool sch_parse(struct sch_ctx *ctx, const char *line)
|
|||||||
void sch_init(struct sch_ctx *ctx)
|
void sch_init(struct sch_ctx *ctx)
|
||||||
{
|
{
|
||||||
ctx->state = sch_descr;
|
ctx->state = sch_descr;
|
||||||
|
ctx->objs = NULL;
|
||||||
ctx->lineno = 0;
|
ctx->lineno = 0;
|
||||||
}
|
}
|
||||||
|
@ -30,36 +30,67 @@ enum sch_state {
|
|||||||
sch_wire, /* wire */
|
sch_wire, /* wire */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct sch_obj {
|
||||||
|
enum sch_obj_type {
|
||||||
|
sch_obj_wire,
|
||||||
|
sch_obj_junction,
|
||||||
|
sch_obj_noconn,
|
||||||
|
sch_obj_text,
|
||||||
|
sch_obj_comp,
|
||||||
|
sch_obj_sheet,
|
||||||
|
} type;
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct sch_wire {
|
||||||
|
void (*fn)(int sx, int sy, int ex, int ey);
|
||||||
|
int ex, ey;
|
||||||
|
} wire;
|
||||||
|
struct sch_text {
|
||||||
|
void (*fn)(int x, int y, const char *s,
|
||||||
|
int dir, int dim, enum dwg_shape shape);
|
||||||
|
const char *s;
|
||||||
|
int dir; /* orientation */
|
||||||
|
int dim; /* dimension */
|
||||||
|
enum dwg_shape shape;
|
||||||
|
} text;
|
||||||
|
struct sch_comp {
|
||||||
|
const struct comp *comp; /* current component */
|
||||||
|
unsigned unit; /* unit of current component */
|
||||||
|
struct comp_field {
|
||||||
|
struct text txt;
|
||||||
|
struct comp_field *next;
|
||||||
|
} *fields;
|
||||||
|
int m[6];
|
||||||
|
} comp;
|
||||||
|
struct sch_sheet {
|
||||||
|
unsigned h, w;
|
||||||
|
const char *sheet;
|
||||||
|
unsigned sheet_dim;
|
||||||
|
const char *file;
|
||||||
|
unsigned file_dim;
|
||||||
|
bool rotated;
|
||||||
|
|
||||||
|
struct sheet_field {
|
||||||
|
char *s;
|
||||||
|
int x, y;
|
||||||
|
unsigned dim;
|
||||||
|
enum dwg_shape shape;
|
||||||
|
unsigned side;
|
||||||
|
struct sheet_field *next;
|
||||||
|
} *fields;
|
||||||
|
} sheet;
|
||||||
|
} u;
|
||||||
|
|
||||||
|
struct sch_obj *next;
|
||||||
|
};
|
||||||
|
|
||||||
struct sch_ctx {
|
struct sch_ctx {
|
||||||
enum sch_state state;
|
enum sch_state state;
|
||||||
void (*wire)(int sx, int sy, int ex, int ey);
|
|
||||||
|
|
||||||
/* text and component */
|
struct sch_obj obj;
|
||||||
|
struct sch_obj *objs;
|
||||||
int x, y; /* saved coordinates */
|
|
||||||
|
|
||||||
/* text */
|
|
||||||
|
|
||||||
void (*text)(int x, int y, const char *s, int dir, int dim,
|
|
||||||
enum dwg_shape shape);
|
|
||||||
int dir; /* orientation */
|
|
||||||
int dim; /* dimension */
|
|
||||||
enum dwg_shape shape;
|
|
||||||
|
|
||||||
/* component */
|
|
||||||
|
|
||||||
const struct comp *comp; /* current component */
|
|
||||||
unsigned unit; /* unit of current component */
|
|
||||||
struct sch_field *fields;
|
|
||||||
|
|
||||||
/* subsheet */
|
|
||||||
|
|
||||||
unsigned h, w;
|
|
||||||
const char *sheet;
|
|
||||||
unsigned sheet_dim;
|
|
||||||
const char *file;
|
|
||||||
unsigned file_dim;
|
|
||||||
bool rotated;
|
|
||||||
|
|
||||||
unsigned lineno;
|
unsigned lineno;
|
||||||
};
|
};
|
||||||
@ -67,6 +98,7 @@ struct sch_ctx {
|
|||||||
|
|
||||||
void decode_alignment(struct text *txt, char hor, char vert);
|
void decode_alignment(struct text *txt, char hor, char vert);
|
||||||
|
|
||||||
|
void sch_render(const struct sch_ctx *ctx);
|
||||||
bool sch_parse(struct sch_ctx *ctx, const char *line);
|
bool sch_parse(struct sch_ctx *ctx, const char *line);
|
||||||
void sch_init(struct sch_ctx *ctx);
|
void sch_init(struct sch_ctx *ctx);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user