From da22f1cc57bac40abcb3a18265f59fe828424d86 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Sat, 23 Jul 2016 14:59:37 -0300 Subject: [PATCH] sch2fig/: basic field support --- sch2fig/Makefile | 5 +- sch2fig/lib.c | 33 +----------- sch2fig/misc.c | 38 ++++++++++++++ sch2fig/misc.h | 33 ++++++++++++ sch2fig/sch.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++- sch2fig/sch.h | 2 +- sch2fig/style.h | 11 ++-- sch2fig/text.c | 23 +++++++++ sch2fig/text.h | 3 ++ 9 files changed, 237 insertions(+), 40 deletions(-) create mode 100644 sch2fig/misc.c create mode 100644 sch2fig/misc.h diff --git a/sch2fig/Makefile b/sch2fig/Makefile index 2eff1db..7cf80d9 100644 --- a/sch2fig/Makefile +++ b/sch2fig/Makefile @@ -11,7 +11,7 @@ # NAME = sch2fig -OBJS = main.o sch.o lib.o fig.o text.o +OBJS = main.o sch.o lib.o fig.o text.o misc.o CFLAGS = -g -Wall -Wextra -Wno-unused-parameter LIBS = -lm @@ -28,6 +28,9 @@ $(NAME): $(OBJS) NEO900_HW = ../../../n9/ee/hw KICAD_LIBS = ../../kicad-libs/components +sch: + eeschema test.sch + test: $(NAME) ./$(NAME) $(NEO900_HW)/neo900.lib \ $(KICAD_LIBS)/powered.lib \ diff --git a/sch2fig/lib.c b/sch2fig/lib.c index 7ef27d7..5a764df 100644 --- a/sch2fig/lib.c +++ b/sch2fig/lib.c @@ -17,6 +17,7 @@ #include #include "util.h" +#include "misc.h" #include "style.h" #include "fig.h" #include "text.h" @@ -95,18 +96,6 @@ static struct comp **next_comp = &comps; static struct obj **next_obj; -static inline int mx(int x, int y, int m[6]) -{ - return m[0] + x * m[1] + y * m[2]; -} - - -static inline int my(int x, int y, int m[6]) -{ - return m[3] + x * m[4] + y * m[5]; -} - - static void draw_poly(const struct poly *poly, int m[6]) { int n = poly->points; @@ -151,26 +140,6 @@ static void draw_pin(const struct pin_obj *pin, int m[6]) } -static bool eq(int m[6], int xx, int xy, int yx, int yy) -{ - return m[1] == xx && m[2] == xy && m[4] == yx && m[5] == yy; -} - - -static unsigned matrix_to_angle(int m[6]) -{ - if (eq(m, 1, 0, 0, -1)) - return 0; - if (eq(m, 0, -1, -1, 0)) - return 90; - if (eq(m, 0, 1, 1, 0)) - return 270; - fprintf(stderr, "unrecognized matrix %d %d %d %d\n", - m[1], m[2], m[4], m[5]); - exit(1); -} - - static void draw_text(const struct text_obj *text, int m[6]) { struct text txt = { diff --git a/sch2fig/misc.c b/sch2fig/misc.c new file mode 100644 index 0000000..1a15c04 --- /dev/null +++ b/sch2fig/misc.c @@ -0,0 +1,38 @@ +/* + * misc.c - Helper functions for geometry and attributes + * + * Written 2016 by Werner Almesberger + * Copyright 2016 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 +#include +#include + +#include "misc.h" + + +static bool eq(int m[6], int xx, int xy, int yx, int yy) +{ + return m[1] == xx && m[2] == xy && m[4] == yx && m[5] == yy; +} + + +unsigned matrix_to_angle(int m[6]) +{ + if (eq(m, 1, 0, 0, -1)) + return 0; + if (eq(m, 0, -1, -1, 0)) + return 90; + if (eq(m, 0, 1, 1, 0)) + return 270; + fprintf(stderr, "unrecognized matrix %d %d %d %d\n", + m[1], m[2], m[4], m[5]); + exit(1); +} diff --git a/sch2fig/misc.h b/sch2fig/misc.h new file mode 100644 index 0000000..3cc05d4 --- /dev/null +++ b/sch2fig/misc.h @@ -0,0 +1,33 @@ +/* + * misc.h - Helper functions for geometry and attributes + * + * Written 2016 by Werner Almesberger + * Copyright 2016 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 MISC_H +#define MISC_H + +#include + + +static inline int mx(int x, int y, int m[6]) +{ + return m[0] + x * m[1] + y * m[2]; +} + + +static inline int my(int x, int y, int m[6]) +{ + return m[3] + x * m[4] + y * m[5]; +} + +unsigned matrix_to_angle(int m[6]); + +#endif /* !MISC_H */ diff --git a/sch2fig/sch.c b/sch2fig/sch.c index b9e9238..7813bf4 100644 --- a/sch2fig/sch.c +++ b/sch2fig/sch.c @@ -18,6 +18,7 @@ #include #include "util.h" +#include "misc.h" #include "style.h" #include "fig.h" #include "lib.h" @@ -56,6 +57,128 @@ static void draw_text(int x, int y, const char *s, int dir, int dim, } +struct sch_field { + struct text txt; + struct sch_field *next; +}; + + +static bool parse_field(struct sch_ctx *ctx, const char *line) +{ + unsigned flags; + char hv, hor, vert, italic, bold; + struct sch_field *field; + struct text *txt; + + field = alloc_type(struct sch_field); + txt = &field->txt; + + if (sscanf(line, "F %*d \"\" %c %d %d %u %u %c %c%c%c", + &hv, &txt->x, &txt->y, &txt->size, &flags, &hor, &vert, + &italic, &bold) == 9) { + free(field); + return 1; + } + if (sscanf(line, "F %*d \"%m[^\"]\" %c %d %d %u %u %c %c%c%c", + &txt->s, &hv, &txt->x, &txt->y, &txt->size, &flags, &hor, &vert, + &italic, &bold) != 10) + return 0; + + if (flags) { + free(field); + return 1; + } + + field->next = ctx->fields; + ctx->fields = field; + + switch (hv) { + case 'H': + txt->rot = 0; + break; + case 'V': + txt->rot = 90; + break; + default: + abort(); + } + + switch (hor) { + case 'L': + txt->hor = text_min; + break; + case 'C': + txt->hor = text_mid; + break; + case 'R': + txt->hor = text_max; + break; + default: + abort(); + } + + switch (vert) { + case 'B': + txt->vert = text_min; + break; + case 'C': + txt->vert = text_mid; + break; + case 'T': + txt->vert = text_max; + break; + default: + abort(); + } + + // @@@ decode font + + return 1; +} + + +static void dump_fields(struct sch_field *fields, int m[6]) +{ + + while (fields) { + struct text *txt = &fields->txt; + struct sch_field *next; + int dx, dy; + + next = fields->next; + + 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; + } + + text_fig(txt, COLOR_FIELD, LAYER_FIELD); + text_free(txt); + + free(fields); + fields = next; + } + +} + + bool sch_parse(struct sch_ctx *ctx, const char *line) { int n = 0; @@ -69,6 +192,7 @@ bool sch_parse(struct sch_ctx *ctx, const char *line) case sch_basic: if (sscanf(line, "$Comp%n", &n) == 0 && n) { ctx->state = sch_comp; + ctx->fields = NULL; return 1; } if (sscanf(line, "$Sheet%n", &n) == 0 && n) { @@ -166,8 +290,8 @@ bool sch_parse(struct sch_ctx *ctx, const char *line) return 1; if (sscanf(line, "P %d %d", &ctx->x, &ctx->y) == 2) return 1; - if (sscanf(line, "F%d", &n) == 1) - return 1; // @@@ + if (parse_field(ctx, line)) + return 1; n = sscanf(line, " %d %d %d %d", m + 1, m + 2, m + 4, m + 5); if (n == 3) return 1; @@ -175,6 +299,7 @@ bool sch_parse(struct sch_ctx *ctx, const char *line) m[0] = ctx->x; m[3] = ctx->y; lib_exec(ctx->comp, ctx->unit, m); + dump_fields(ctx->fields, m); return 1; } break; diff --git a/sch2fig/sch.h b/sch2fig/sch.h index 47b45db..7e3d1d6 100644 --- a/sch2fig/sch.h +++ b/sch2fig/sch.h @@ -46,7 +46,7 @@ struct sch_ctx { char *comp; /* current component */ unsigned unit; /* unit of current component */ - + struct sch_field *fields; unsigned lineno; }; diff --git a/sch2fig/style.h b/sch2fig/style.h index 4f99840..fd5327a 100644 --- a/sch2fig/style.h +++ b/sch2fig/style.h @@ -16,22 +16,25 @@ #define COLOR_BLACK 0 #define COLOR_BLUE 1 #define COLOR_GREEN4 12 +#define COLOR_CYAN3 16 #define COLOR_RED4 18 #define COLOR_RED3 19 #define COLOR_COMP_DWG COLOR_RED4 #define COLOR_SHEET_DWG COLOR_BLUE -#define COLOR_TEXT COLOR_BLACK +#define COLOR_TEXT COLOR_BLUE #define COLOR_WIRE COLOR_GREEN4 #define COLOR_GLABEL COLOR_RED4 +#define COLOR_FIELD COLOR_CYAN3 #define FONT_HELVETICA_BOLD 18 +#define LAYER_GLABEL 20 #define LAYER_TEXT 30 #define LAYER_WIRES 50 -#define LAYER_LINES 60 -#define LAYER_COMP_DWG 70 -#define LAYER_GLABEL 20 +#define LAYER_FIELD 60 +#define LAYER_LINES 100 +#define LAYER_COMP_DWG 120 #define WIDTH_WIRE 2 #define WIDTH_LINE 2 diff --git a/sch2fig/text.c b/sch2fig/text.c index 9087500..a898674 100644 --- a/sch2fig/text.c +++ b/sch2fig/text.c @@ -47,6 +47,29 @@ void text_set(struct text *txt, const char *s) } +void text_rot(struct text *txt, int deg) +{ + txt->rot += deg; + while (txt->rot < 0) + txt->rot += 360; + txt->rot %= 360; +} + + +enum text_align text_flip(enum text_align align) +{ + switch (align) { + case text_min: + return text_max; + case text_mid: + return text_mid; + case text_max: + return text_max; + default: + abort(); + } +} + static int rx(int x, int y, int rot) { float a = rot / 180.0 * M_PI; diff --git a/sch2fig/text.h b/sch2fig/text.h index 608b86a..c5446b6 100644 --- a/sch2fig/text.h +++ b/sch2fig/text.h @@ -34,7 +34,10 @@ struct text { void text_init(struct text *txt); void text_free(struct text *txt); + void text_set(struct text *txt, const char *s); +void text_rot(struct text *txt, int deg); +enum text_align text_flip(enum text_align align); void text_fig(const struct text *txt, int color, unsigned layer);