From 6e6e68e445b59846109a22ff7ed2d11ac314c693 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Sat, 23 Jul 2016 06:58:21 -0300 Subject: [PATCH] sch2fig/: partial glabel support; ongoing development --- sch2fig/Makefile | 3 +- sch2fig/fig.c | 57 +++++++++++++++++++++++++++- sch2fig/lib.c | 11 ++++-- sch2fig/sch.c | 25 ++++++++---- sch2fig/style.h | 2 + sch2fig/text.c | 99 ++++++++++++++++++++++++++++++++++++++++-------- sch2fig/text.h | 13 +++++-- sch2fig/util.h | 44 +++++++++++++++++++++ 8 files changed, 221 insertions(+), 33 deletions(-) create mode 100644 sch2fig/util.h diff --git a/sch2fig/Makefile b/sch2fig/Makefile index 4df5ab5..2eff1db 100644 --- a/sch2fig/Makefile +++ b/sch2fig/Makefile @@ -14,6 +14,7 @@ NAME = sch2fig OBJS = main.o sch.o lib.o fig.o text.o CFLAGS = -g -Wall -Wextra -Wno-unused-parameter +LIBS = -lm include ../common/Makefile.c-common @@ -22,7 +23,7 @@ include ../common/Makefile.c-common all:: $(NAME) $(NAME): $(OBJS) - $(CC) -o $(NAME) $(OBJS) + $(CC) -o $(NAME) $(OBJS) $(LIBS) NEO900_HW = ../../../n9/ee/hw KICAD_LIBS = ../../kicad-libs/components diff --git a/sch2fig/fig.c b/sch2fig/fig.c index 495124a..92c76dd 100644 --- a/sch2fig/fig.c +++ b/sch2fig/fig.c @@ -11,7 +11,9 @@ */ +#include #include +#include #include "style.h" #include "text.h" @@ -74,9 +76,62 @@ void fig_poly(int points, int x[points], int y[points]) } +#define OFF 20 + void fig_glabel(int x, int y, const char *s, int dir, int dim, enum fig_shape shape) { + struct text txt = { + .s = s, + .size = dim, + .x = x, + .y = y, + .rot = 0, + .hor = 0, + .vert = text_mid, + }; + int n = 6; + int vx[5]; + int vy[5]; + int half = (dim >> 1) + OFF; + + switch (dir) { + case 0: + txt.rot = 0; + txt.hor = text_max; + break; + default: + abort(); + } + + switch (shape) { + case fig_in: + text_shift(&txt, txt.hor, text_mid, -OFF - half, 0); + text_rel(&txt, text_min, text_min, -OFF, OFF, vx + 1, vy + 1); + text_rel(&txt, text_max, text_min, OFF, OFF, vx + 2, vy + 2); + text_rel(&txt, text_max, text_mid, OFF + half, 0, + vx + 3, vy + 3); + text_rel(&txt, text_max, text_max, OFF, -OFF, vx + 4, vy + 4); + text_rel(&txt, text_min, text_max, -OFF, -OFF, vx + 5, vy + 5); + break; + case fig_out: + text_shift(&txt, txt.hor, text_mid, -OFF, 0); + text_rel(&txt, text_min, text_min, -OFF, OFF, vx + 1, vy + 1); + text_rel(&txt, text_max, text_min, OFF, OFF, vx + 2, vy + 2); + text_rel(&txt, text_max, text_max, OFF, -OFF, vx + 3, vy + 3); + text_rel(&txt, text_min, text_max, -OFF, -OFF, vx + 4, vy + 4); + text_rel(&txt, text_min, text_mid, -OFF - half, 0, + vx + 5, vy + 5); + break; + default: + abort(); + } + + text_fig(&txt, COLOR_GLABEL, LAYER_GLABEL); + + vx[0] = vx[n - 1]; + vy[0] = vy[n - 1]; + fig_poly(n, vx, vy); } @@ -121,7 +176,7 @@ void fig_text(int x, int y, const char *s, unsigned size, // Color Font Flags X Y printf("4 %u %d %d -1 %d %f %f 4 0.0 0.0 %d %d %s\\001\n", align, color, layer, FONT_HELVETICA_BOLD, - pt(size), rot / 3.1415926 * 180, cx(x), cy(y), s); + pt(size), rot / 180.0 * M_PI, cx(x), cy(y), s); } diff --git a/sch2fig/lib.c b/sch2fig/lib.c index b248f14..7ef27d7 100644 --- a/sch2fig/lib.c +++ b/sch2fig/lib.c @@ -16,6 +16,7 @@ #include #include +#include "util.h" #include "style.h" #include "fig.h" #include "text.h" @@ -199,8 +200,10 @@ static void draw(const struct obj *obj, int m[6]) // @@@ break; case obj_circ: + unsupported("circle"); break; case obj_arc: + unsupported("arc"); break; case obj_text: draw_text(&obj->u.text, m); @@ -247,8 +250,8 @@ static bool parse_poly(struct obj *obj, const char *line, int points) int i, n; obj->u.poly.points = points; - obj->u.poly.x = malloc(sizeof(int) * points); - obj->u.poly.y = malloc(sizeof(int) * points); + obj->u.poly.x = alloc_size(sizeof(int) * points); + obj->u.poly.y = alloc_size(sizeof(int) * points); for (i = 0; i != points; i++) { if (sscanf(line, "%d %d %n", obj->u.poly.x + i, obj->u.poly.y + i, &n) != 2) @@ -277,7 +280,7 @@ bool lib_parse(struct lib_ctx *ctx, const char *line) case lib_skip: if (sscanf(line, "DEF %ms", &s) == 1) { ctx->state = lib_def; - comp = malloc(sizeof(struct comp)); + comp = alloc_type(struct comp); if (*s == '~') s++; comp->name = s; @@ -301,7 +304,7 @@ bool lib_parse(struct lib_ctx *ctx, const char *line) return 1; } - obj = malloc(sizeof(struct obj)); + obj = alloc_type(struct obj); obj->next = NULL; *next_obj = obj; next_obj = &obj->next; diff --git a/sch2fig/sch.c b/sch2fig/sch.c index 3bfbe2f..b9e9238 100644 --- a/sch2fig/sch.c +++ b/sch2fig/sch.c @@ -11,11 +11,13 @@ */ +#include #include #include #include #include +#include "util.h" #include "style.h" #include "fig.h" #include "lib.h" @@ -92,12 +94,14 @@ bool sch_parse(struct sch_ctx *ctx, const char *line) if (sscanf(line, "Text HLabel %d %d %d %d %ms", &ctx->x, &ctx->y, &ctx->dir, &ctx->dim, &s) == 5) { ctx->state = sch_text; -abort(); + unsupported("Text HLabel"); + ctx->text = NULL; return 1; } if (sscanf(line, "Text Label%n", &n) == 0 && n) { ctx->state = sch_text; -abort(); + unsupported("Text Label"); + ctx->text = NULL; return 1; } @@ -117,7 +121,8 @@ abort(); } if (sscanf(line, "Wire Bus Line%n", &n) == 0 && n) { ctx->state = sch_wire; -abort(); + unsupported("Wire Bus Line"); + ctx->wire = NULL; return 1; } if (sscanf(line, "Wire Notes Line%n", &n) == 0 && n) { @@ -127,12 +132,14 @@ abort(); } if (sscanf(line, "Wire Wire Bus%n", &n) == 0 && n) { ctx->state = sch_wire; -abort(); + unsupported("Wire Wire Bus"); + ctx->wire = NULL; return 1; } if (sscanf(line, "Wire Bus Bus%n", &n) == 0 && n) { ctx->state = sch_wire; -abort(); + unsupported("Wire Bus Bus"); + ctx->wire = NULL; return 1; } @@ -178,13 +185,15 @@ abort(); return 1; case sch_text: ctx->state = sch_basic; - ctx->text(ctx->x, ctx->y, line, ctx->dir, ctx->dim, - ctx->shape); + if (ctx->text) + ctx->text(ctx->x, ctx->y, line, ctx->dir, ctx->dim, + ctx->shape); return 1; case sch_wire: if (sscanf(line, "%d %d %d %d", &x, &y, &ex, &ey) != 4) break; - ctx->wire(x, y, ex, ey); + if (ctx->wire) + ctx->wire(x, y, ex, ey); ctx->state = sch_basic; return 1; default: diff --git a/sch2fig/style.h b/sch2fig/style.h index b1543f9..4f99840 100644 --- a/sch2fig/style.h +++ b/sch2fig/style.h @@ -23,6 +23,7 @@ #define COLOR_SHEET_DWG COLOR_BLUE #define COLOR_TEXT COLOR_BLACK #define COLOR_WIRE COLOR_GREEN4 +#define COLOR_GLABEL COLOR_RED4 #define FONT_HELVETICA_BOLD 18 @@ -30,6 +31,7 @@ #define LAYER_WIRES 50 #define LAYER_LINES 60 #define LAYER_COMP_DWG 70 +#define LAYER_GLABEL 20 #define WIDTH_WIRE 2 #define WIDTH_LINE 2 diff --git a/sch2fig/text.c b/sch2fig/text.c index 2d9905b..9087500 100644 --- a/sch2fig/text.c +++ b/sch2fig/text.c @@ -11,10 +11,13 @@ */ +#include #include #include #include +#include +#include "util.h" #include "fig.h" #include "text.h" @@ -33,41 +36,105 @@ void text_init(struct text *txt) void text_free(struct text *txt) { free((void *) txt->s); + txt->s = NULL; } + void text_set(struct text *txt, const char *s) { free((void *) txt->s); - txt->s = strdup(s); + txt->s = stralloc(s); } -void text_fig(struct text *txt, int color, unsigned layer) +static int rx(int x, int y, int rot) +{ + float a = rot / 180.0 * M_PI; + + return cos(a) * x + sin(a) * y; +} + + +static int ry(int x, int y, int rot) +{ + float a = rot / 180.0 * M_PI; + + return -sin(a) * x + cos(a) * y; +} + + +static int align(int dim, enum text_align align) +{ + switch (align) { + case text_min: + return 0; + case text_mid: + return dim / 2; + case text_max: + return dim; + default: + abort(); + } +} + + +void text_fig(const struct text *txt, int color, unsigned layer) { int x = txt->x; int y = txt->y; - switch (txt->vert) { - case text_min: - break; - case text_mid: - y += txt->size >> 1; - break; - case text_max: - y += txt->size; - break; - default: - abort(); - } + x += rx(0, align(txt->size, txt->vert), txt->rot); + y += ry(0, align(txt->size, txt->vert), txt->rot); fig_text(x, y, txt->s, txt->size, txt->hor, txt->rot, color, layer); } -void text_rel_x(struct text *txt, int x, int y) +static unsigned guess_width(const struct text *txt) { + /* + * Note that fig.c stretches the text size, so the ratio is larger than + * expressed here. + */ + return strlen(txt->s) * txt->size * 1.0; } -void text_rel_y(struct text *txt, int x, int y) +void text_rel(const struct text *txt, enum text_align xr, enum text_align yr, + int dx, int dy, int *res_x, int *res_y) { + dx -= align(guess_width(txt), txt->hor); + dy += align(txt->size, txt->vert); + dx += align(guess_width(txt), xr); + dy -= align(txt->size, yr); + if (res_x) + *res_x = txt->x + rx(dx, dy, txt->rot); + if (res_y) + *res_y = txt->y + ry(dx, dy, txt->rot); +} + + +void text_shift(struct text *txt, enum text_align xr, enum text_align yr, + int dx, int dy) +{ + text_rel(txt, xr, yr, dx, dy, &txt->x, &txt->y); +} + + +int text_rel_x(const struct text *txt, enum text_align xr, enum text_align yr, + int dx, int dy) +{ + int x; + + text_rel(txt, xr, yr, dx, dy, &x, NULL); + return x; +} + + +int text_rel_y(const struct text *txt, enum text_align xr, enum text_align yr, + int dx, int dy) +{ + int y; + + text_rel(txt, xr, yr, dx, dy, NULL, &y); + return y; } diff --git a/sch2fig/text.h b/sch2fig/text.h index 9756ef4..608b86a 100644 --- a/sch2fig/text.h +++ b/sch2fig/text.h @@ -36,8 +36,15 @@ void text_init(struct text *txt); void text_free(struct text *txt); void text_set(struct text *txt, const char *s); -void text_fig(struct text *txt, int color, unsigned layer); -void text_rel_x(struct text *txt, int x, int y); -void text_rel_y(struct text *txt, int x, int y); +void text_fig(const struct text *txt, int color, unsigned layer); + +void text_rel(const struct text *txt, enum text_align xr, enum text_align yr, + int dx, int dy, int *res_x, int *res_y); +void text_shift(struct text *txt, enum text_align xr, enum text_align yr, + int dx, int dy); +int text_rel_x(const struct text *txt, enum text_align xr, enum text_align yr, + int dx, int dy); +int text_rel_y(const struct text *txt, enum text_align xr, enum text_align yr, + int dx, int dy); #endif /* !TEXT_H */ diff --git a/sch2fig/util.h b/sch2fig/util.h new file mode 100644 index 0000000..4f2bec7 --- /dev/null +++ b/sch2fig/util.h @@ -0,0 +1,44 @@ +/* + * util.h - Common utility functions + * + * 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 UTIL_H +#define UTIL_H + +#include +#include +#include + + +#define alloc_size(s) \ + ({ void *alloc_size_tmp = malloc(s); \ + if (!alloc_size_tmp) { \ + perror("malloc"); \ + exit(1); \ + } \ + alloc_size_tmp; }) + +#define alloc_type(t) ((t *) alloc_size(sizeof(t))) + +#define stralloc(s) \ + ({ char *stralloc_tmp = strdup(s); \ + if (!stralloc_tmp) { \ + perror("strdup"); \ + exit(1); \ + } \ + stralloc_tmp; }) + + +#define unsupported(s) \ + fprintf(stderr, __FILE__ ":%d: unsupported: " s "\n", __LINE__) + +#endif /* !UTIL_H */