diff --git a/eeshow/cro.c b/eeshow/cro.c index 8ede2b9..bfdf3f0 100644 --- a/eeshow/cro.c +++ b/eeshow/cro.c @@ -321,6 +321,19 @@ static void end_common(struct cro_ctx *cc, int *w, int *h) } +static cairo_status_t stream_to_stdout(void *closure, + const unsigned char *data, unsigned length) +{ + ssize_t wrote; + + wrote = write(1, data, length); + if (wrote == (ssize_t) length) + return CAIRO_STATUS_SUCCESS; + perror("stdout"); + return CAIRO_STATUS_WRITE_ERROR; +} + + static void cr_png_end(void *ctx) { struct cro_ctx *cc = ctx; @@ -341,8 +354,7 @@ static void cr_png_end(void *ctx) record_replay(&cc->record); record_destroy(&cc->record); - if (cc->output_name) - cairo_surface_write_to_png(cc->s, cc->output_name); + cro_img_write(cc, cc->output_name); } @@ -369,7 +381,11 @@ static void cr_pdf_end(void *ctx) end_common(cc, &w, &h); - cc->s = cairo_pdf_surface_create(cc->output_name, w, h); + if (cc->output_name) + cc->s = cairo_pdf_surface_create(cc->output_name, w, h); + else + cc->s = cairo_pdf_surface_create_for_stream(stream_to_stdout, + NULL, w, h); cc->cr = cairo_create(cc->s); cairo_select_font_face(cc->cr, "Helvetica", CAIRO_FONT_SLANT_NORMAL, @@ -428,7 +444,11 @@ void cro_img_write(void *ctx, const char *name) { struct cro_ctx *cc = ctx; - cairo_surface_write_to_png(cc->s, name); + if (name) + cairo_surface_write_to_png(cc->s, name); + else + cairo_surface_write_to_png_stream(cc->s, stream_to_stdout, + NULL); } diff --git a/eeshow/diff.c b/eeshow/diff.c index 8f7d4a0..a825c82 100644 --- a/eeshow/diff.c +++ b/eeshow/diff.c @@ -258,8 +258,7 @@ static void diff_end(void *ctx) differences(diff, old_img, diff->new_img); show_areas(diff, old_img); - if (diff->output_name) - cro_img_write(diff->cr_ctx, diff->output_name); + cro_img_write(diff->cr_ctx, diff->output_name); } diff --git a/eeshow/main.c b/eeshow/main.c index 7e02d0e..b38761a 100644 --- a/eeshow/main.c +++ b/eeshow/main.c @@ -60,7 +60,7 @@ void usage(const char *name) "Cairo PNG driver spec:\n" " png [-o output.png] [-s scale]\n" "\n" -" -o output.png generate PNG output and write to specified file\n" +" -o output.png write PNG to specified file (default; standard output)\n" " -s scale scale by indicated factor (default: 1.0)\n" "\n" "Cairo PDF driver spec:\n" diff --git a/sch2fig/DEMO b/sch2fig/DEMO deleted file mode 100644 index 4125e12..0000000 --- a/sch2fig/DEMO +++ /dev/null @@ -1,25 +0,0 @@ -# Prerequisites (depends on distribution) - -apt-get install libcairo2-dev -apt-get install libgit2-dev -apt-get install qiv - -# Get all the things we need - -git clone http://neo900.org/git/ee.git newdir -cd newdir/hw -git clone git://projects.qi-hardware.com/kicad-libs.git -git clone git://projects.qi-hardware.com/eda-tools.git -make -C eda-tools/sch2fig - -# Generate PNG for old, new, and difference - -LIBS="neo900.lib kicad-libs/components/powered.lib" -eda-tools/sch2fig/sch2fig $LIBS 6a9f71:neo900_SS_5.sch -- png -s 2 -o old.png -eda-tools/sch2fig/sch2fig $LIBS neo900_SS_5.sch -- png -s 2 -o new.png -eda-tools/sch2fig/sch2fig $LIBS 6a9f71:neo900_SS_5.sch -- \ - diff -s 2 -o diff.png $LIBS neo900_SS_5.sch - -# View the result - -qiv -t diff.png old.png new.png diff --git a/sch2fig/Makefile b/sch2fig/Makefile deleted file mode 100644 index 64d44dd..0000000 --- a/sch2fig/Makefile +++ /dev/null @@ -1,91 +0,0 @@ -# -# Makefile - build sch2fig -# -# Written 2016 by Werner Almesberger -# Copyright 2016 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. -# - -NAME = sch2fig -OBJS = main.o sch-parse.o sch-render.o lib-parse.o lib-render.o \ - file.o git-file.o \ - style.o fig.o record.o cro.o diff.o gfx.o dwg.o text.o misc.o - -CFLAGS = -g -Wall -Wextra -Wno-unused-parameter -Wshadow \ - -Wmissing-prototypes -Wmissing-declarations \ - `pkg-config --cflags cairo` \ - `pkg-config --cflags libgit2` -LDLIBS = -lm \ - `pkg-config --libs cairo` \ - `pkg-config --libs libgit2` - -include ../common/Makefile.c-common - -.PHONY: test neo900 sch test testref png pngref diff view newref - -all:: $(NAME) - -$(NAME): $(OBJS) - $(CC) -o $(NAME) $(OBJS) $(LDLIBS) - -#----- Test sheet ------------------------------------------------------------- - -sch: - eeschema test.sch - -test: $(NAME) - ./$(NAME) test.lib test.sch >out.fig - fig2dev -L png -m 2 out.fig _out.png - [ ! -r ref.png ] || \ - compare -metric AE ref.png _out.png _diff.png || \ - qiv -t -R -D _diff.png ref.png _out.png - -testref: $(NAME) - ./$(NAME) test.lib test.sch | fig2dev -L png -m 2 >ref.png - -png: $(NAME) - ./$(NAME) test.lib test.sch -- png -o _out.png -s 2 - [ ! -r pngref.png ] || \ - compare -metric AE pngref.png _out.png _diff.png || \ - qiv -t -R -D _diff.png pngref.png _out.png - -pngref: $(NAME) - ./$(NAME) test.lib test.sch -- png -o pngref.png -s 2 - -clean:: - rm -f out.fig _out.png _diff.png - -#----- Render Neo900 schematics ----------------------------------------------- - -NEO900_HW = ../../../n9/ee/hw -KICAD_LIBS = ../../kicad-libs/components - -SHEET ?= 12 - -neo900: $(NAME) - ./$(NAME) $(NEO900_HW)/neo900.lib \ - $(KICAD_LIBS)/powered.lib \ - $(NEO900_HW)/neo900_SS_$(SHEET).sch \ - >out.fig - -neo900.pdf: $(NAME) sch2pdf neo900-template.fig - ./sch2pdf -o $@ -t neo900-template.fig \ - $(NEO900_HW)/neo900.lib $(KICAD_LIBS)/powered.lib \ - $(NEO900_HW)/neo900.sch - -#----- Regression test based on Neo900 schematics ----------------------------- - -diff: $(NAME) - test/genpng test out - test/comp test || $(MAKE) view - -view: - qiv -t -R -D `echo test/_diff*.png | \ - sed 's/\([^ ]*\)_diff\([^ ]*\)/\1_diff\2 \1ref\2 \1out\2/g'` - -newref: - test/genpng test ref diff --git a/sch2fig/TODO b/sch2fig/TODO deleted file mode 100644 index a2e2899..0000000 --- a/sch2fig/TODO +++ /dev/null @@ -1,24 +0,0 @@ -- better text size guessing also for FIG -- unify alignment, direction -- support fonts attributes ? -- support line thickness ? -- ~ as overline (grep for ~ in out.fig) -- glabel: build for "right" style, then rotate poly (like hlabel) -- show open pins / wires -- check remaining alignment / direction / rotation cases in switch statements -- support mirroring (and detect-complain if unexpected) [should be done now] -- pin shapes (inverted, clock, etc.) -- optionally display pin type -- find libraries (e.g., from .pro) -- PDF TOC -- let user set PNG size or zoom level -- parse .kicad_wks -- on parse error, politely complain, don't terminate; - convert abort / assert(0) to proper error indications -- implement destructors -- check for memory leaks -- record.c (bb_rot): implement bounding boxes for text -- nesting gfx in diff is a huge kludge, caused by global vars in gfx.c -- move path name guessing into file.c -- return indication of whether diff found any differences -- in diff, pass only options understood by cairo_png diff --git a/sch2fig/cro.c b/sch2fig/cro.c deleted file mode 100644 index 8ede2b9..0000000 --- a/sch2fig/cro.c +++ /dev/null @@ -1,461 +0,0 @@ -/* - * cro.c - Cairo graphics back-end - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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 -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "util.h" -#include "style.h" -#include "text.h" -#include "gfx.h" -#include "record.h" -#include "main.h" -#include "cro.h" - - -/* - * FIG works with 1/1200 in - * KiCad works with mil - * 1 point = 1/72 in - */ - -#define DEFAULT_SCALE (72.0 / 1200) - - -struct cro_ctx { - struct record record; /* must be first */ - - int xo, yo; - float scale; - - cairo_t *cr; - cairo_surface_t *s; - - struct record *sheets; /* for PDF */ - unsigned n_sheets; - - const char *output_name; -}; - - -static inline int cd(struct cro_ctx *cc, int x) -{ - return x * cc->scale; -} - - -static inline int cx(struct cro_ctx *cc, int x) -{ - return cc->xo + x * cc->scale; -} - - -static inline int xc(struct cro_ctx *cc, int x) -{ - return (x - cc->xo) / cc->scale; -} - - -static inline int cy(struct cro_ctx *cc, int y) -{ - return cc->yo + y * cc->scale; -} - - -static inline float pt(struct cro_ctx *cc, int x) -{ - return cd(cc, x) * 72 * 1.5 / 1200.0; -} - - -static void set_color(cairo_t *cr, int color) -{ - uint32_t c; - - if (color < 0) - return; - c = color_rgb[color]; - cairo_set_source_rgb(cr, (c >> 16) / 255.0, ((c >> 8) & 255) / 255.0, - (c & 255) / 255.0); -} - - -static void paint(cairo_t *cr, int color, int fill_color) -{ - if (fill_color != COLOR_NONE) { - set_color(cr, fill_color); - if (color == COLOR_NONE) - cairo_fill(cr); - else - cairo_fill_preserve(cr); - } - if (color != COLOR_NONE) { - set_color(cr, color); - cairo_stroke(cr); - } -} - - -/* ----- General items ----------------------------------------------------- */ - - -static void cr_line(void *ctx, int sx, int sy, int ex, int ey, - int color, unsigned layer) -{ - struct cro_ctx *cc = ctx; - static const double dashes[] = { 4, 2 }; - - cairo_new_path(cc->cr); - cairo_move_to(cc->cr, cx(cc, sx), cy(cc, sy)); - cairo_line_to(cc->cr, cx(cc, ex), cy(cc, ey)); - cairo_set_dash(cc->cr, dashes, ARRAY_ELEMENTS(dashes), 0); - paint(cc->cr, color, COLOR_NONE); - cairo_set_dash(cc->cr, NULL, 0, 0); -} - - -static void cr_poly(void *ctx, - int points, const int x[points], const int y[points], - int color, int fill_color, unsigned layer) -{ - struct cro_ctx *cc = ctx; - bool closed; - int i; - - if (points < 2) - return; - closed = x[0] == x[points - 1] && y[0] == y[points - 1]; - - cairo_new_path(cc->cr); - cairo_move_to(cc->cr, cx(cc, x[0]), cy(cc, y[0])); - - for (i = 1; i != points - closed; i++) - cairo_line_to(cc->cr, cx(cc, x[i]), cy(cc, y[i])); - if (closed) - cairo_close_path(cc->cr); - - paint(cc->cr, color, fill_color); -} - - -static void cr_circ(void *ctx, int x, int y, int r, - int color, int fill_color, unsigned layer) -{ - struct cro_ctx *cc = ctx; - - cairo_new_path(cc->cr); - cairo_arc(cc->cr, cx(cc, x), cy(cc, y), cd(cc, r), 0, 2 * M_PI); - paint(cc->cr, color, fill_color); -} - - -static void cr_arc(void *ctx, int x, int y, int r, int sa, int ea, - int color, int fill_color, unsigned layer) -{ - struct cro_ctx *cc = ctx; - - cairo_new_path(cc->cr); - cairo_arc(cc->cr, cx(cc, x), cy(cc, y), cd(cc, r), - -ea / 180.0 * M_PI, -sa / 180.0 * M_PI); - paint(cc->cr, color, fill_color); -} - - -#define TEXT_STRETCH 1.3 - - -static void cr_text(void *ctx, int x, int y, const char *s, unsigned size, - enum text_align align, int rot, unsigned color, unsigned layer) -{ - struct cro_ctx *cc = ctx; - cairo_text_extents_t ext; - cairo_matrix_t m; - - cairo_set_font_size(cc->cr, cd(cc, size) * TEXT_STRETCH); - cairo_text_extents(cc->cr, s, &ext); - - set_color(cc->cr, color); - - cairo_move_to(cc->cr, cx(cc, x), cy(cc, y)); - - cairo_get_matrix(cc->cr, &m); - cairo_rotate(cc->cr, -rot / 180.0 * M_PI); - - switch (align) { - case text_min: - break; - case text_mid: - cairo_rel_move_to(cc->cr, -ext.width / 2.0, 0); - break; - case text_max: - cairo_rel_move_to(cc->cr, -ext.width, 0); - break; - default: - abort(); - } - - cairo_show_text(cc->cr, s); - cairo_set_matrix(cc->cr, &m); -} - - -static unsigned cr_text_width(void *ctx, const char *s, unsigned size) -{ - struct cro_ctx *cc = ctx; - cairo_text_extents_t ext; - - cairo_set_font_size(cc->cr, cx(cc, size) * TEXT_STRETCH); - cairo_text_extents(cc->cr, s, &ext); - return xc(cc, ext.width) * 1.05; /* @@@ Cairo seems to underestimate */ -} - - -/* ----- Initializatio and termination ------------------------------------- */ - - -static const struct gfx_ops real_cro_ops = { - .name = "cairo", - .line = cr_line, - .poly = cr_poly, - .circ = cr_circ, - .arc = cr_arc, - .text = cr_text, - .text_width = cr_text_width, -}; - - -static struct cro_ctx *init_common(int argc, char *const *argv) -{ - struct cro_ctx *cc; - char c; - - cc = alloc_type(struct cro_ctx); - cc->xo = cc->yo = 0; - cc->scale = DEFAULT_SCALE; - - cc->sheets = NULL; - cc->n_sheets = 0; - - cc->output_name = NULL; - while ((c = getopt(argc, argv, "o:s:")) != EOF) - switch (c) { - case 'o': - cc->output_name = optarg; - break; - case 's': - cc->scale = atof(optarg) * DEFAULT_SCALE; - break; - default: - usage(*argv); - } - - record_init(&cc->record, &real_cro_ops, cc); - - return cc; -} - - -static void *cr_png_init(int argc, char *const *argv) -{ - struct cro_ctx *cc; - - cc = init_common(argc, argv); - - /* cr_text_width needs *something* to work with */ - - cc->s = cairo_image_surface_create(CAIRO_FORMAT_RGB24, 16, 16); - cc->cr = cairo_create(cc->s); - - return cc; -} - - -static void *cr_pdf_init(int argc, char *const *argv) -{ - struct cro_ctx *cc; - - cc = init_common(argc, argv); - - /* cr_text_width needs *something* to work with */ - - cc->s = cairo_pdf_surface_create(NULL, 16, 16); - cc->cr = cairo_create(cc->s); - - return cc; -} - - -static void end_common(struct cro_ctx *cc, int *w, int *h) -{ - int x, y; - - cairo_surface_destroy(cc->s); - cairo_destroy(cc->cr); - - record_bbox(&cc->record, &x, &y, w, h); - -// fprintf(stderr, "%dx%d%+d%+d\n", *w, *h, x, y); - cc->xo = -cd(cc, x); - cc->yo = -cd(cc, y); - *w = cd(cc, *w); - *h = cd(cc, *h); -// fprintf(stderr, "%dx%d%+d%+d\n", *w, *h, x, y); -} - - -static void cr_png_end(void *ctx) -{ - struct cro_ctx *cc = ctx; - int w, h; - - end_common(cc, &w, &h); - - cc->s = cairo_image_surface_create(CAIRO_FORMAT_RGB24, w, h); - cc->cr = cairo_create(cc->s); - - set_color(cc->cr, COLOR_WHITE); - cairo_paint(cc->cr); - - cairo_select_font_face(cc->cr, "Helvetica", CAIRO_FONT_SLANT_NORMAL, - CAIRO_FONT_WEIGHT_BOLD); - cairo_set_line_width(cc->cr, 2); - - record_replay(&cc->record); - record_destroy(&cc->record); - - if (cc->output_name) - cairo_surface_write_to_png(cc->s, cc->output_name); -} - - -static void cr_pdf_new_sheet(void *ctx) -{ - struct cro_ctx *cc = ctx; - - cc->n_sheets++; - cc->sheets = realloc(cc->sheets, sizeof(struct record) * cc->n_sheets); - if (!cc->sheets) { - perror("realloc"); - exit(1); - } - cc->sheets[cc->n_sheets - 1] = cc->record; - record_wipe(&cc->record); -} - - -static void cr_pdf_end(void *ctx) -{ - struct cro_ctx *cc = ctx; - int w, h; - unsigned i; - - end_common(cc, &w, &h); - - cc->s = cairo_pdf_surface_create(cc->output_name, w, h); - cc->cr = cairo_create(cc->s); - - cairo_select_font_face(cc->cr, "Helvetica", CAIRO_FONT_SLANT_NORMAL, - CAIRO_FONT_WEIGHT_BOLD); - cairo_set_line_width(cc->cr, 2); - - for (i = 0; i != cc->n_sheets; i++) { - set_color(cc->cr, COLOR_WHITE); - cairo_paint(cc->cr); - - record_replay(cc->sheets + i); - record_destroy(cc->sheets + i); - - cairo_show_page(cc->cr); - } - - record_replay(&cc->record); - record_destroy(&cc->record); - - cairo_show_page(cc->cr); - - cairo_surface_destroy(cc->s); - cairo_destroy(cc->cr); -} - - -uint32_t *cro_img_end(void *ctx, int *w, int *h, int *stride) -{ - struct cro_ctx *cc = ctx; - uint32_t *data; - - end_common(cc, w, h); - - *stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, *w); - data = alloc_size(*stride * *h); - - cc->s = cairo_image_surface_create_for_data((unsigned char *) data, - CAIRO_FORMAT_RGB24, *w, *h, *stride); - cc->cr = cairo_create(cc->s); - - set_color(cc->cr, COLOR_WHITE); - cairo_paint(cc->cr); - - cairo_select_font_face(cc->cr, "Helvetica", CAIRO_FONT_SLANT_NORMAL, - CAIRO_FONT_WEIGHT_BOLD); - cairo_set_line_width(cc->cr, 2); - - record_replay(&cc->record); - record_destroy(&cc->record); - - return data; -} - - -void cro_img_write(void *ctx, const char *name) -{ - struct cro_ctx *cc = ctx; - - cairo_surface_write_to_png(cc->s, name); -} - - -/* ----- Operations -------------------------------------------------------- */ - - -const struct gfx_ops cro_png_ops = { - .name = "png", - .line = record_line, - .poly = record_poly, - .circ = record_circ, - .arc = record_arc, - .text = record_text, - .text_width = cr_text_width, - .init = cr_png_init, - .end = cr_png_end, -}; - -const struct gfx_ops cro_pdf_ops = { - .name = "pdf", - .line = record_line, - .poly = record_poly, - .circ = record_circ, - .arc = record_arc, - .text = record_text, - .text_width = cr_text_width, - .init = cr_pdf_init, - .new_sheet = cr_pdf_new_sheet, - .end = cr_pdf_end, -}; diff --git a/sch2fig/cro.h b/sch2fig/cro.h deleted file mode 100644 index 3595da8..0000000 --- a/sch2fig/cro.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * cro.h - Cairo graphics back-end - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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 CRO_H -#define CRO_H - -#include - -#include "gfx.h" - - -extern const struct gfx_ops cro_png_ops; -extern const struct gfx_ops cro_pdf_ops; - -#define cro_img_ops cro_png_ops /* just don't call cro_img_ops.end */ - - -uint32_t *cro_img_end(void *ctx, int *w, int *h, int *stride); -void cro_img_write(void *ctx, const char *name); - -#endif /* !CRO_H */ diff --git a/sch2fig/diff.c b/sch2fig/diff.c deleted file mode 100644 index 8f7d4a0..0000000 --- a/sch2fig/diff.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * diff.c - Schematics difference - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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 -#include -#include -#include -#include - -#include "util.h" -#include "main.h" -#include "cro.h" -#include "sch.h" -#include "lib.h" -#include "diff.h" - - -#define DEFAULT_FRAME_RADIUS 30 - - -struct area { - int xa, ya, xb, yb; - struct area *next; -}; - -struct diff { - void *cr_ctx; - uint32_t *new_img; - int w, h, stride; - const char *output_name; - int frame_radius; - struct area *areas; -}; - - -/* ----- Wrappers ---------------------------------------------------------- */ - - -static void diff_line(void *ctx, int sx, int sy, int ex, int ey, - int color, unsigned layer) -{ - const struct diff *diff = ctx; - - cro_img_ops.line(diff->cr_ctx, sx, sy, ex, ey, color, layer); -} - - -static void diff_poly(void *ctx, - int points, const int x[points], const int y[points], - int color, int fill_color, unsigned layer) -{ - const struct diff *diff = ctx; - - cro_img_ops.poly(diff->cr_ctx, points, x, y, color, fill_color, layer); -} - - -static void diff_circ(void *ctx, int x, int y, int r, - int color, int fill_color, unsigned layer) -{ - const struct diff *diff = ctx; - - cro_img_ops.circ(diff->cr_ctx, x, y, r, color, fill_color, layer); -} - - -static void diff_arc(void *ctx, int x, int y, int r, int sa, int ea, - int color, int fill_color, unsigned layer) -{ - const struct diff *diff = ctx; - - cro_img_ops.arc(diff->cr_ctx, x, y, r, sa, ea, - color, fill_color, layer); -} - - -static void diff_text(void *ctx, int x, int y, const char *s, unsigned size, - enum text_align align, int rot, unsigned color, unsigned layer) -{ - const struct diff *diff = ctx; - - cro_img_ops.text(diff->cr_ctx, x, y, s, size, align, rot, - color, layer); -} - - -static unsigned diff_text_width(void *ctx, const char *s, unsigned size) -{ - const struct diff *diff = ctx; - - return cro_img_ops.text_width(diff->cr_ctx, s, size); -} - - -/* ----- Initialization and termination ------------------------------------ */ - - -static void *diff_init(int argc, char *const *argv) -{ - struct diff *diff; - char c; - int arg; - struct sch_ctx new_sch; - struct lib new_lib; - - diff = alloc_type(struct diff); - diff->areas = NULL; - - sch_init(&new_sch, 0); - lib_init(&new_lib); - - diff->output_name = NULL; - diff->frame_radius = DEFAULT_FRAME_RADIUS; - while ((c = getopt(argc, argv, "o:s:")) != EOF) - switch (c) { - case 'o': - diff->output_name = optarg; - break; - case 's': - /* for cro_png */ - break; - default: - usage(*argv); - } - - if (argc - optind < 1) - usage(*argv); - - for (arg = optind; arg != argc - 1; arg++) - lib_parse(&new_lib, argv[arg]); - sch_parse(&new_sch, argv[argc - 1], &new_lib); - - optind = 0; - gfx_init(&cro_img_ops, argc, argv); - diff->cr_ctx = gfx_ctx; - sch_render(new_sch.sheets); - diff->new_img = cro_img_end(gfx_ctx, - &diff->w, &diff->h, &diff->stride); - - optind = 0; - diff->cr_ctx = cro_img_ops.init(argc, argv); - - return diff; -} - - -/* steal from schhist/ppmdiff.c */ - -#define ONLY_OLD 0xff0000 -#define ONLY_NEW 0x00d000 -#define BOTH 0x707070 - -#define AREA_FILL 0xffffc8 - - -static void mark_area(struct diff *diff, int x, int y) -{ - struct area *area; - - for (area = diff->areas; area; area = area->next) - if (x >= area->xa && x <= area->xb && - y >= area->ya && y <= area->yb) { - if (area->xa > x - diff->frame_radius) - area->xa = x - diff->frame_radius; - if (area->xb < x + diff->frame_radius) - area->xb = x + diff->frame_radius; - if (area->ya > y - diff->frame_radius) - area->ya = y - diff->frame_radius; - if (area->yb < y + diff->frame_radius) - area->yb = y + diff->frame_radius; - return; - } - - area = alloc_type(struct area); - - area->xa = x - diff->frame_radius; - area->xb = x + diff->frame_radius; - area->ya = y - diff->frame_radius; - area->yb = y + diff->frame_radius; - - area->next = diff->areas; - diff->areas = area; -} - - -#define MASK 0xffffff - - -static void differences(struct diff *diff, uint32_t *a, const uint32_t *b) -{ - int x, y; - unsigned skip = diff->w * 4 - diff->stride; - - for (y = 0; y != diff->h; y++) { - for (x = 0; x != diff->w; x++) { - if (!((*a ^ *b) & MASK)) { - *a = ((*a >> 3) & 0x1f1f1f) | 0xe0e0e0; -// *a = ((*a >> 2) & 0x3f3f3f) | 0xc0c0c0; - } else { - mark_area(diff, x, y); -//fprintf(stderr, "0x%06x 0x%06x", *a, *b); - *a = (*a & MASK) == MASK ? ONLY_NEW : - (*b & MASK) == MASK ? ONLY_OLD : BOTH; -//fprintf(stderr, "-> 0x%06x\n", *a); - } - a++; - b++; - } - a += skip; - b += skip; - } -} - - -static void show_areas(struct diff *diff, uint32_t *a) -{ - const struct area *area; - uint32_t *p; - int x, y; - - for (area = diff->areas; area; area = area->next) - for (y = area->ya; y != area->yb; y++) { - if (y < 0 || y >= diff->h) - continue; - p = a + y * (diff->stride >> 2); - for (x = area->xa; x != area->xb; x++) { - if (x >= 0 && x < diff->w && - (p[x] & MASK) == MASK) - p[x] = AREA_FILL; - } - } -} - - -static void diff_end(void *ctx) -{ - struct diff *diff = ctx; - uint32_t *old_img; - int w, h, stride; - - old_img = cro_img_end(diff->cr_ctx, &w, &h, &stride); - if (diff->w != w || diff->h != h) { - fprintf(stderr, "%d x %d vs. %d x %d image\n", - w, h, diff->w, diff->h); - exit(1); - } - - differences(diff, old_img, diff->new_img); - show_areas(diff, old_img); - - if (diff->output_name) - cro_img_write(diff->cr_ctx, diff->output_name); -} - - -/* ----- Operations -------------------------------------------------------- */ - - -const struct gfx_ops diff_ops = { - .name = "diff", - .line = diff_line, - .poly = diff_poly, - .circ = diff_circ, - .arc = diff_arc, - .text = diff_text, - .text_width = diff_text_width, - .init = diff_init, - .end = diff_end, -}; diff --git a/sch2fig/diff.h b/sch2fig/diff.h deleted file mode 100644 index 22626b1..0000000 --- a/sch2fig/diff.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * diff.h - Schematics difference - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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 DIFF_H -#define DIFF_H - -#include "gfx.h" - - -extern const struct gfx_ops diff_ops; - -#endif /* !DIFF_H */ diff --git a/sch2fig/dwg.c b/sch2fig/dwg.c deleted file mode 100644 index 08fa64a..0000000 --- a/sch2fig/dwg.c +++ /dev/null @@ -1,463 +0,0 @@ -/* - * dwg.c - Complex drawing functions - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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. - */ - - -#define _GNU_SOURCE /* for asprintf */ -#include -#include -#include -#include - -#include "util.h" -#include "misc.h" -#include "style.h" -#include "text.h" -#include "gfx.h" -#include "dwg.h" - - -/* ----- Labels ------------------------------------------------------------ */ - - -enum box_type { // ___ - box_simple, // [___] - box_left, // <___] - box_right, // [___> - box_both, // <___> -}; - - -static enum box_type flip_box(enum box_type box) -{ - switch (box) { - case box_simple: - return box_simple; - case box_left: - return box_right; - case box_right: - return box_left; - case box_both: - return box_both; - default: - abort(); - } -} - - -void dwg_label(int x, int y, const char *s, int dir, int dim, - enum dwg_shape shape) -{ - struct text txt = { - .s = s, - .size = dim, - .x = x, - .y = y, - .rot = 0, - .hor = 0, - .vert = text_min, - }; - int dx = 0, dy = 0; - - switch (dir) { - case 0: /* right */ - txt.rot = 0; - txt.hor = text_min; - dy = 1; - break; - case 1: /* up */ - txt.rot = 90; - txt.hor = text_min; - dx = -1; - break; - case 2: /* left */ - txt.rot = 0; - txt.hor = text_max; - dy = 1; - break; - case 3: /* down */ - txt.rot = 90; - txt.hor = text_max; - dx = -1; - break; - default: - assert(0); - } - - txt.y -= dy * LABEL_OFFSET; - txt.x += dx * LABEL_OFFSET; - text_fig(&txt, COLOR_LABEL, LAYER_LABEL); -} - - -void dwg_glabel(int x, int y, const char *s, int dir, int dim, - enum dwg_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[7]; - int vy[7]; - int half = (dim >> 1) + GLABEL_OFFSET; - enum box_type box; - int dx, shift_flat, shift_tip; - bool anchor_right = 1; - char *tag; - - switch (shape) { - case dwg_unspec: - box = box_simple; - break; - case dwg_in: - box = box_right; - break; - case dwg_out: - box = box_left; - break; - case dwg_bidir: - box = box_both; - break; - default: - assert(0); - } - - switch (dir) { - case 0: /* left */ - txt.rot = 0; - txt.hor = text_max; - dx = -1; - break; - case 1: /* up */ - txt.rot = 90; - txt.hor = text_min; - dx = 1; - box = flip_box(box); - anchor_right = !anchor_right; - break; - case 2: /* right */ - txt.rot = 0; - txt.hor = text_min; - dx = 1; - box = flip_box(box); - anchor_right = !anchor_right; - break; - case 3: /* down */ - txt.rot = 90; - txt.hor = text_max; - dx = -1; - break; - default: - assert(0); - } - - shift_flat = dx * GLABEL_OFFSET; - shift_tip = dx * (GLABEL_OFFSET + half); - - switch (box) { - case box_simple: - n = 5; - text_shift(&txt, txt.hor, text_mid, shift_flat, 0); - text_rel(&txt, text_min, text_min, - -GLABEL_OFFSET, GLABEL_OFFSET, vx + 1, vy + 1); - text_rel(&txt, text_max, text_min, - GLABEL_OFFSET, GLABEL_OFFSET, vx + 2, vy + 2); - text_rel(&txt, text_max, text_max, - GLABEL_OFFSET, -GLABEL_OFFSET, vx + 3, vy + 3); - text_rel(&txt, text_min, text_max, - -GLABEL_OFFSET, -GLABEL_OFFSET, vx + 4, vy + 4); - break; - case box_right: - text_shift(&txt, txt.hor, text_mid, - anchor_right ? shift_tip : shift_flat, 0); - text_rel(&txt, text_min, text_min, - -GLABEL_OFFSET, GLABEL_OFFSET, vx + 1, vy + 1); - text_rel(&txt, text_max, text_min, - GLABEL_OFFSET, GLABEL_OFFSET, vx + 2, vy + 2); - text_rel(&txt, text_max, text_mid, GLABEL_OFFSET + half, 0, - vx + 3, vy + 3); - text_rel(&txt, text_max, text_max, - GLABEL_OFFSET, -GLABEL_OFFSET, vx + 4, vy + 4); - text_rel(&txt, text_min, text_max, - -GLABEL_OFFSET, -GLABEL_OFFSET, vx + 5, vy + 5); - break; - case box_left: - text_shift(&txt, txt.hor, text_mid, - anchor_right ? shift_flat : shift_tip, 0); - text_rel(&txt, text_min, text_min, - -GLABEL_OFFSET, GLABEL_OFFSET, vx + 1, vy + 1); - text_rel(&txt, text_max, text_min, - GLABEL_OFFSET, GLABEL_OFFSET, vx + 2, vy + 2); - text_rel(&txt, text_max, text_max, - GLABEL_OFFSET, -GLABEL_OFFSET, vx + 3, vy + 3); - text_rel(&txt, text_min, text_max, - -GLABEL_OFFSET, -GLABEL_OFFSET, vx + 4, vy + 4); - text_rel(&txt, text_min, text_mid, -GLABEL_OFFSET- half, 0, - vx + 5, vy + 5); - break; - case box_both: - n = 7; - text_shift(&txt, txt.hor, text_mid, shift_tip, 0); - text_rel(&txt, text_min, text_min, - -GLABEL_OFFSET, GLABEL_OFFSET, vx + 1, vy + 1); - text_rel(&txt, text_max, text_min, - GLABEL_OFFSET, GLABEL_OFFSET, vx + 2, vy + 2); - text_rel(&txt, text_max, text_mid, GLABEL_OFFSET + half, 0, - vx + 3, vy + 3); - text_rel(&txt, text_max, text_max, - GLABEL_OFFSET, -GLABEL_OFFSET, vx + 4, vy + 4); - text_rel(&txt, text_min, text_max, - -GLABEL_OFFSET, -GLABEL_OFFSET, vx + 5, vy + 5); - text_rel(&txt, text_min, text_mid, -GLABEL_OFFSET- half, 0, - vx + 6, vy + 6); - break; - default: - assert(0); - } - - text_fig(&txt, COLOR_GLABEL, LAYER_GLABEL); - - vx[0] = vx[n - 1]; - vy[0] = vy[n - 1]; - gfx_poly(n, vx, vy, COLOR_GLABEL, COLOR_NONE, LAYER_GLABEL); - - if (asprintf(&tag, "G:%s", s)) {} - gfx_tag(tag, n, vx, vy); -} - - -static int make_box(enum box_type box, int h, int *vx, int *vy) -{ - int r = h / 2; - - switch (box) { - case box_simple: - vx[0] = 0; - vy[0] = -r; - vx[1] = 2 * r; - vy[1] = -r; - vx[2] = 2 * r; - vy[2] = r; - vx[3] = 0; - vy[3] = r; - return 4; - case box_right: - vx[0] = 0; - vy[0] = -r; - vx[1] = r; - vy[1] = -r; - vx[2] = 2 * r; - vy[2] = 0; - vx[3] = r; - vy[3] = r; - vx[4] = 0; - vy[4] = r; - return 5; - case box_left: - vx[0] = r; - vy[0] = -r; - vx[1] = 2 * r; - vy[1] = -r; - vx[2] = 2 * r; - vy[2] = r; - vx[3] = r; - vy[3] = r; - vx[4] = 0; - vy[4] = 0; - return 5; - case box_both: - vx[0] = 0; - vy[0] = 0; - vx[1] = r; - vy[1] = -r; - vx[2] = 2 * r; - vy[2] = 0; - vx[3] = r; - vy[3] = r; - return 4; - default: - assert(0); - } -} - - -void dwg_hlabel(int x, int y, const char *s, int dir, int dim, - enum dwg_shape shape) -{ - struct text txt = { - .s = s, - .size = dim, - .x = x, - .y = y, - .rot = 0, - .hor = 0, - .vert = text_mid, - }; - int vx[6], vy[6]; - int rot; - int n, i; - - switch (shape) { - case dwg_unspec: - n = make_box(box_simple, dim, vx, vy); - break; - case dwg_in: - n = make_box(box_left, dim, vx, vy); - break; - case dwg_out: - n = make_box(box_right, dim, vx, vy); - break; - case dwg_bidir: - n = make_box(box_both, dim, vx, vy); - break; - default: - assert(0); - } - - switch (dir) { - case 0: /* right */ - rot = 180; - txt.hor = text_max; - break; - case 1: /* up */ - rot = 90; - txt.hor = text_min; - break; - case 2: /* left */ - rot = 0; - txt.hor = text_min; - break; - case 3: /* down */ - rot = 270; - txt.hor = text_max; - break; - default: - assert(0); - } - - txt.x += rx((1 + HLABEL_OFFSET_F) * dim, 0, rot); - txt.y += ry((1 + HLABEL_OFFSET_F) * dim, 0, rot); - - for (i = 0; i != n; i++) { - int tmp; - - tmp = x + rx(vx[i], vy[i], rot); - vy[i] = y + ry(vx[i], vy[i], rot); - vx[i] = tmp; - } - - vx[n] = vx[0]; - vy[n] = vy[0]; - - txt.rot = rot % 180; - - text_fig(&txt, COLOR_HLABEL, LAYER_HLABEL); - gfx_poly(n + 1, vx, vy, COLOR_HLABEL, COLOR_NONE, LAYER_HLABEL); -} - - -/* ----- Text -------------------------------------------------------------- */ - - -void dwg_text(int x, int y, const char *s, int dir, int dim, - enum dwg_shape shape) -{ - struct text txt = { - .s = s, - .size = dim, - .x = x, - .y = y, - .rot = 0, - .hor = text_min, - .vert = text_min, - }; - - switch (dir) { - case 0: /* right */ - break; - case 1: /* up */ - text_rot(&txt, 90); - break; - case 2: /* left */ - txt.hor = text_max; - break; - case 3: /* down */ - text_rot(&txt, 90); - txt.hor = text_max; - break; - default: - assert(2 + 2 == 5); - } - - text_fig(&txt, COLOR_TEXT, LAYER_TEXT); -} - - -/* ----- Connections ------------------------------------------------------- */ - - -void dwg_junction(int x, int y) -{ - gfx_circ(x, y, JUNCTION_R, COLOR_NONE, COLOR_WIRE, LAYER_WIRES); -} - - -void dwg_noconn(int x, int y) -{ - int vx[2] = { x - NOCONN_LEN, x + NOCONN_LEN }; - int vy[2] = { y - NOCONN_LEN, y + NOCONN_LEN }; - - gfx_poly(2, vx, vy, COLOR_NOCONN, COLOR_NONE, LAYER_NOCONN); - swap(vy[0], vy[1]); - gfx_poly(2, vx, vy, COLOR_NOCONN, COLOR_NONE, LAYER_NOCONN); -} - - -/* ----- Lines ------------------------------------------------------------- */ - -/* - * We can't use gfx_poly because lines are dashed and we don't have that - * property at the gfx_poly API. - */ - -void dwg_line(int sx, int sy, int ex, int ey) -{ - gfx_line(sx, sy, ex, ey, COLOR_SHEET_DWG, LAYER_LINES); -} - - -/* ----- Wires and busses -------------------------------------------------- */ - - -void dwg_wire(int sx, int sy, int ex, int ey) -{ - int vx[] = { sx, ex }; - int vy[] = { sy, ey }; - - // WIDTH_WIRE - gfx_poly(2, vx, vy, COLOR_WIRE, COLOR_NONE, LAYER_WIRES); -} - - -void dwg_bus(int sx, int sy, int ex, int ey) -{ - int vx[] = { sx, ex }; - int vy[] = { sy, ey }; - - // WIDTH_BUS - gfx_poly(2, vx, vy, COLOR_BUS, COLOR_NONE, LAYER_BUSSES); -} diff --git a/sch2fig/dwg.h b/sch2fig/dwg.h deleted file mode 100644 index 697f524..0000000 --- a/sch2fig/dwg.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * dwg.h - Complex drawing functions - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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 DWG_H -#define DWG_H - -#include "fig.h" - - -enum dwg_shape { - dwg_unspec, // UnSpc - dwg_in, // Input - dwg_out, // Output - dwg_tri, // 3State - dwg_bidir, // Bidirectional -}; - - -void dwg_label(int x, int y, const char *s, int dir, int dim, - enum dwg_shape shape); -void dwg_hlabel(int x, int y, const char *s, int dir, int dim, - enum dwg_shape shape); -void dwg_glabel(int x, int y, const char *s, int dir, int dim, - enum dwg_shape shape); -void dwg_text(int x, int y, const char *s, int dir, int dim, - enum dwg_shape shape); - -void dwg_junction(int x, int y); -void dwg_noconn(int x, int y); - -void dwg_line(int sx, int sy, int ex, int ey); - -void dwg_wire(int sx, int sy, int ex, int ey); -void dwg_bus(int sx, int sy, int ex, int ey); - -#endif /* !DWG_H */ diff --git a/sch2fig/fig.c b/sch2fig/fig.c deleted file mode 100644 index 04ec9f4..0000000 --- a/sch2fig/fig.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * fig.c - Generate FIG output for Eeschema items - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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 -#include -#include -#include -#include -#include -#include - -#include "util.h" -#include "style.h" -#include "text.h" -#include "main.h" -#include "fig.h" - - -/* - * FIG works with 1/1200 in - * KiCad works with mil - * 1 point = 1/72 in - */ - - -static inline int cx(int x) -{ - return x * 1200 / 1000; -} - - -static inline int cy(int y) -{ - return y * 1200 / 1000; -} - - -static inline float pt(int x) -{ - return cx(x) * 72 * 1.5 / 1200.0; -} - - -/* ----- Schematics items -------------------------------------------------- */ - - -static void fig_line(void *ctx, int sx, int sy, int ex, int ey, - int color, unsigned layer) -{ - // TypeStyle FillCol AreaFil Cap FwdAr - // SubTy Color Pen StyleV Rad BwdAr - // Thick Depth Join Points - printf("2 1 2 %d %d 7 %d -1 -1 3.0 1 1 -1 0 0 2\n", - WIDTH_LINE, color, layer); - printf("\t%d %d %d %d\n", cx(sx), cy(sy), cx(ex), cy(ey)); -} - - -/* ----- General items ----------------------------------------------------- */ - - -static void fig_rect(void *ctx, int sx, int sy, int ex, int ey, - int color, int fill_color, unsigned layer) -{ - // Type Thick Depth StyleV Rad - // SubTy Color Pen Join FwdAr - // Style FillCol AreaFil Cap BwdAr - printf("2 2 0 %d %d %d %d -1 %d 0.0 1 1 -1 0 0 5\n", - color == -1 ? 0 : WIDTH_COMP_DWG, color, fill_color, layer, - fill_color == -1 ? -1 : 20); - printf("\t%d %d %d %d %d %d %d %d %d %d\n", - cx(sx), cy(sy), cx(ex), cy(sy), cx(ex), cy(ey), cx(sx), cy(ey), - cx(sx), cy(sy)); -} - - -static void fig_poly(void *ctx, - int points, const int x[points], const int y[points], - int color, int fill_color, unsigned layer) -{ - int i; - char ch = '\t'; - - // Type Thick Depth StyleV Rad - // SubTy Color Pen Join FwdAr - // Style FillCol AreaFil Cap BwdAr - printf("2 1 0 %d %d %d %d -1 %d 0.0 1 1 -1 0 0 %d\n", - color == -1 ? 0 : WIDTH_COMP_DWG, color, fill_color, layer, - fill_color == -1 ? -1 : 20, points); - for (i = 0; i != points; i++) { - printf("%c%d %d", ch, cx(x[i]), cy(y[i])); - ch = ' '; - } - printf("\n"); -} - - -static void fig_circ(void *ctx, int x, int y, int r, - int color, int fill_color, unsigned layer) -{ - // Type Thick Depth StyleV Cx Rx Sx Ex - // SubTy Color Pen Dir Cy Ry Sy Ey - // Style FillCol AreaFil Angle - printf("1 3 0 %d %d %d %d -1 %d 0.0 1 0.0 %d %d %d %d %d %d %d %d\n", - color == -1 ? 0 : WIDTH_COMP_DWG, color, fill_color, layer, - fill_color == -1 ? -1 : 20, - cx(x), cy(y), r, r, - cx(x), cy(y), cx(x) + r, cy(y)); -} - - -static int ax(int x, int y, int r, int angle) -{ - float a = angle / 180.0 * M_PI; - - return cx(x + r * cos(a)); -} - - -static int ay(int x, int y, int r, int angle) -{ - float a = angle / 180.0 * M_PI; - - return cy(y - r * sin(a)); -} - - -static void fig_arc(void *ctx, int x, int y, int r, int sa, int ea, - int color, int fill_color, unsigned layer) -{ - int ma = (sa + ea) / 2; - - // Type Thick Depth StyleV FwdAr - // SubTy Color Pen Cap BwdAr - // Style FillCol AreaFil Dir points - printf("5 1 0 %d %d %d %d -1 %d 0.0 1 1 0 0 %d %d %d %d %d %d %d %d\n", - color == -1 ? 0 : WIDTH_COMP_DWG, color, fill_color, layer, - fill_color == -1 ? -1 : 20, - cx(x), cy(y), - ax(x, y, r, sa), ay(x, y, r, sa), - ax(x, y, r, ma), ay(x, y, r, ma), - ax(x, y, r, ea), ay(x, y, r, ea)); -} - - -static void fig_tag(void *ctx, const char *s, - int points, const int x[points], const int y[points]) -{ - printf("# href=\"%s\" alt=\"\"\n", s); - fig_poly(ctx, points, x, y, COLOR_NONE, COLOR_NONE, 999); -} - - -static void fig_text(void *ctx, int x, int y, const char *s, unsigned size, - enum text_align align, int rot, unsigned color, unsigned layer) -{ - // Type Depth FontSiz Height - // Just Pen Angle Length - // 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 / 180.0 * M_PI, cx(x), cy(y), s); -} - - -static unsigned fig_text_width(void *ctx, const char *s, unsigned size) -{ - /* - * Note that we stretch the text size, so the ratio is larger than - * expressed here. - */ - return strlen(s) * size * 1.0; -} - - -/* ----- FIG file header --------------------------------------------------- */ - - -static void fig_header(void) -{ - printf("#FIG 3.2\n"); - printf("Landscape\n"); - printf("Center\n"); - printf("Metric\n"); - printf("A4\n"); - printf("100.00\n"); - printf("Single\n"); - printf("-2\n"); - printf("1200 2\n"); - - /* User32, COLOR_DARK_YELLOW */ - printf("0 32 #848400\n"); -} - - -static bool apply_vars(char *buf, int n_vars, const char **vars) -{ - char *p; - const char **var, *eq; - int var_len, value_len; - - p = strchr(buf, '<'); - if (!p) - return 0; - for (var = vars; var != vars + n_vars; var++) { - eq = strchr(*var, '='); - assert(eq); - var_len = eq - *var; - if (strncmp(p + 1, *var, var_len)) - continue; - value_len = strlen(eq + 1); - memmove(p + value_len, p + var_len + 2, - strlen(p + var_len + 2) + 1); - memcpy(p, eq + 1, value_len); - return 1; - } - return 0; -} - - - -static void *fig_init(int argc, char *const *argv) -{ - const char *template = NULL; - const char **vars = NULL; - int n_vars = 0; - char c; - int arg; - FILE *file; - char buf[1000]; - - while ((c = getopt(argc, argv, "t:")) != EOF) - switch (c) { - case 't': - template = optarg; - break; - default: - usage(*argv); - } - - for (arg = optind; arg != argc; arg++) { - if (!strchr(argv[arg], '=')) - usage(*argv); - n_vars++; - vars = realloc(vars, sizeof(const char *) * n_vars); - vars[n_vars - 1] = argv[arg]; - } - - if (!template) { - fig_header(); - return NULL; - } - - file = fopen(template, "r"); - if (!file) { - perror(template); - exit(1); - } - while (fgets(buf, sizeof(buf), file)) { - while (apply_vars(buf, n_vars, vars)); - printf("%s", buf); - } - fclose(file); - - return NULL; -} - - -/* ----- Operations -------------------------------------------------------- */ - - -const struct gfx_ops fig_ops = { - .name = "fig", - .line = fig_line, - .rect = fig_rect, - .poly = fig_poly, - .circ = fig_circ, - .arc = fig_arc, - .text = fig_text, - .tag = fig_tag, - .text_width = fig_text_width, - .init = fig_init, -}; diff --git a/sch2fig/fig.h b/sch2fig/fig.h deleted file mode 100644 index 6e6a361..0000000 --- a/sch2fig/fig.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * fig.h - Generate FIG output for Eeschema items - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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 FIG_H -#define FIG_H - -#include "gfx.h" - - -extern const struct gfx_ops fig_ops; - -#endif /* !FIG_H */ diff --git a/sch2fig/file.c b/sch2fig/file.c deleted file mode 100644 index 1145173..0000000 --- a/sch2fig/file.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * file.c - Open and read a file - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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 -#include -#include -#include - -#include "util.h" -#include "main.h" -#include "git-file.h" -#include "file.h" - - -bool file_cat(void *user, const char *line) -{ - printf("%s\n", line); - return 1; -} - - -static void read_from_file(FILE *file, - bool (*parse)(void *user, const char *line), void *user) -{ - char buf[1000]; - char *nl; - - while (fgets(buf, sizeof(buf), file)) { - nl = strchr(buf, '\n'); - if (nl) - *nl = 0; - if (!parse(user, buf)) - break; - } -} - - -void file_read(const char *name, bool (*parse)(void *user, const char *line), - void *user) -{ - FILE *file; - char *colon, *tmp; - - file = fopen(name, "r"); - if (file) { - if (verbose) - fprintf(stderr, "reading %s\n", name); - read_from_file(file, parse, user); - fclose(file); - return; - } - - if (verbose) - perror(name); - - colon = strchr(name, ':'); - if (!colon) { - if (!verbose) - perror(name); - exit(1); - } - - tmp = stralloc(name); - tmp[colon - name] = 0; - git_read(tmp, colon + 1, parse, user); - free(tmp); -} diff --git a/sch2fig/file.h b/sch2fig/file.h deleted file mode 100644 index a6cc170..0000000 --- a/sch2fig/file.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * file.h - Open and read a file - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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 FILE_H -#define FILE_H - -#include - -bool file_cat(void *user, const char *line); -void file_read(const char *name, bool (*parse)(void *user, const char *line), - void *user); - -#endif /* !FILE_H */ diff --git a/sch2fig/gfx.c b/sch2fig/gfx.c deleted file mode 100644 index ba88134..0000000 --- a/sch2fig/gfx.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * gfx.c - Generate graphical output for Eeschema items - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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 - -#include "style.h" -#include "text.h" -#include "gfx.h" - - -void *gfx_ctx; - -static const struct gfx_ops *gfx_ops; - - -void gfx_line(int sx, int sy, int ex, int ey, int color, unsigned layer) -{ - if (gfx_ops->line) { - gfx_ops->line(gfx_ctx, sx, sy, ex, ey, color, layer); - return; - } - - int vx[] = { sx, ex }; - int vy[] = { sy, ey }; - - gfx_poly(2, vx, vy, color, COLOR_NONE, layer); -} - - -void gfx_rect(int sx, int sy, int ex, int ey, - int color, int fill_color, unsigned layer) -{ - if (gfx_ops->rect) { - gfx_ops->rect(gfx_ctx, sx, sy, ex, ey, - color, fill_color, layer); - return; - } - - int vx[] = { sx, ex, ex, sx, sx }; - int vy[] = { sy, sy, ey, ey, sy }; - - gfx_poly(5, vx, vy, color, fill_color, layer); -} - - -void gfx_poly(int points, const int x[points], const int y[points], - int color, int fill_color, unsigned layer) -{ - gfx_ops->poly(gfx_ctx, points, x, y, color, fill_color, layer); -} - - -void gfx_circ(int x, int y, int r, int color, int fill_color, unsigned layer) -{ - gfx_ops->circ(gfx_ctx, x, y, r, color, fill_color, layer); -} - - -void gfx_arc(int x, int y, int r, int sa, int ea, - int color, int fill_color, unsigned layer) -{ - gfx_ops->arc(gfx_ctx, x, y, r, sa, ea, color, fill_color, layer); -} - - -void gfx_text(int x, int y, const char *s, unsigned size, - enum text_align align, int rot, unsigned color, unsigned layer) -{ - gfx_ops->text(gfx_ctx, x, y, s, size, align, rot, color, layer); -} - - -void gfx_tag(const char *s, - unsigned points, const int x[points], int const y[points]) -{ - if (gfx_ops->tag) - gfx_ops->tag(gfx_ctx, s, points, x, y); -} - - -unsigned gfx_text_width(const char *s, unsigned size) -{ - return gfx_ops->text_width(gfx_ctx, s, size); -} - - -void gfx_init(const struct gfx_ops *ops, int argc, char *const *argv) -{ - gfx_ctx = ops->init(argc, argv); - gfx_ops = ops; -} - - -void gfx_new_sheet(void) -{ - if (gfx_ops->new_sheet) - gfx_ops->new_sheet(gfx_ctx); -} - - -bool gfx_multi_sheet(void) -{ - return !!gfx_ops->new_sheet; -} - -void gfx_end(void) -{ - if (gfx_ops->end) - gfx_ops->end(gfx_ctx); -} diff --git a/sch2fig/gfx.h b/sch2fig/gfx.h deleted file mode 100644 index d707c24..0000000 --- a/sch2fig/gfx.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * gfx.h - Generate graphical output for Eeschema items - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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 GFX_H -#define GFX_H - -#include - -#include "text.h" - - -struct gfx_ops { - const char *name; - void (*line)(void *ctx, int sx, int sy, int ex, int ey, - int color, unsigned layer); - void (*rect)(void *ctx, int sx, int sy, int ex, int ey, - int color, int fill_color, unsigned layer); - void (*poly)(void *ctx, - int points, const int x[points], const int y[points], - int color, int fill_color, unsigned layer); - void (*circ)(void *ctx, int x, int y, int r, - int color, int fill_color, unsigned layer); - void (*arc)(void *ctx, int x, int y, int r, int sa, int ea, - int color, int fill_color, unsigned layer); - void (*text)(void *ctx, int x, int y, const char *s, unsigned size, - enum text_align align, int rot, unsigned color, unsigned layer); - void (*tag)(void *ctx, const char *s, - int points, const int x[points], const int y[points]); - unsigned (*text_width)(void *ctx, const char *s, unsigned size); - void *(*init)(int argc, char *const *argv); - void (*new_sheet)(void *ctx); - void (*end)(void *ctx); -}; - - -extern void *gfx_ctx; - - -/* wrappers */ - -void gfx_line(int sx, int sy, int ex, int ey, int color, unsigned layer); -void gfx_rect(int sx, int sy, int ex, int ey, - int color, int fill_color, unsigned layer); -void gfx_poly(int points, const int x[points], const int y[points], - int color, int fill_color, unsigned layer); -void gfx_circ(int x, int y, int r, int color, int fill_color, unsigned layer); -void gfx_arc(int x, int y, int r, int sa, int ea, - int color, int fill_color, unsigned layer); -void gfx_text(int x, int y, const char *s, unsigned size, - enum text_align align, int rot, unsigned color, unsigned layer); -void gfx_tag(const char *s, - unsigned points, const int x[points], int const y[points]); -unsigned gfx_text_width(const char *s, unsigned size); - -/* inititalization and termination */ - -void gfx_init(const struct gfx_ops *ops, int argc, char *const *argv); -void gfx_new_sheet(void); -bool gfx_multi_sheet(void); -void gfx_end(void); - -#endif /* !GFX_H */ diff --git a/sch2fig/git-file.c b/sch2fig/git-file.c deleted file mode 100644 index 098f136..0000000 --- a/sch2fig/git-file.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * git-file.c - Open and read a file from git - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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. - */ - -#define _GNU_SOURCE /* for get_current_dir_name */ -#include -#include -#include -#include -#include -#include - -#include - -#include "util.h" -#include "main.h" -#include "git-file.h" - - -static git_repository *select_repo(const char *path) -{ - git_repository *repo = NULL; - char *tmp = stralloc(path); - char *slash; - - /* - * If we can't find a repo, this may be due to the file or directory - * the path points to not existing in the currently checked-out tree. - * So we trim off elements until we find a repository. - */ - while (1) { - if (verbose > 2) - fprintf(stderr, "trying \"%s\"\n", tmp); - if (!git_repository_open_ext(&repo, *tmp ? tmp : "/", - GIT_REPOSITORY_OPEN_CROSS_FS, NULL)) - break; - slash = strrchr(tmp, '/'); - if (!slash) - break; - *slash = 0; - } - free(tmp); - return repo; -} - - -static git_tree *pick_revision(git_repository *repo, const char *revision) -{ - git_commit *commit; - git_object *obj; - git_tree *tree; - - if (git_revparse_single(&obj, repo, revision)) { - const git_error *e = giterr_last(); - - fprintf(stderr, "%s: %s\n", - git_repository_path(repo), e->message); - exit(1); - } - - if (git_object_type(obj) != GIT_OBJ_COMMIT) { - fprintf(stderr, "%s: not a commit\n", revision); - exit(1); - } - commit = (git_commit *) obj; - - if (git_commit_tree(&tree, commit)) { - const git_error *e = giterr_last(); - - fprintf(stderr, "%s: %s\n", revision, e->message); - exit(1); - } - - return tree; -} - - -static char *canonical_path_into_repo(const char *repo_dir, const char *path) -{ - struct stat repo_st, path_st; - char *tmp, *tmp2, *slash, *tail, *real; - char *to; - const char *end, *from; - - /* identify inode of repo root */ - - if (stat(repo_dir, &repo_st) < 0) { - perror(repo_dir); - exit(1); - } - if (!S_ISDIR(repo_st.st_mode)) { - fprintf(stderr, "%s: not a directory\n", repo_dir); - exit(1); - } - - /* convert relative paths to absolute */ - - if (*path == '/') { - tmp = stralloc(path); - } else { - char *cwd = get_current_dir_name(); - - tmp = alloc_size(strlen(cwd) + 1 + strlen(path) + 1); - sprintf(tmp, "%s/%s", cwd, path); - free(cwd); - } - - /* remove trailing / */ - - slash = strrchr(tmp, '/'); - if (slash && slash != tmp && !slash[1]) - *slash = 0; - - - /* - * If path does point to inexistent object, separate into the part that - * is valid on the current system and the tail containing dead things. - */ - end = tail = strchr(tmp, 0); - - while (1) { - if (verbose > 2) - fprintf(stderr, "probing \"%s\" tail \"%s\"\n", - tmp, tail); - if (stat(tmp, &path_st) == 0) - break; - if (!tmp[1]) { - fprintf(stderr, "%s: cannot resolve\n", path); - exit(1); - } - slash = strrchr(tmp, '/'); - if (tail != end) - tail[-1] = '/'; - tail = slash + 1; - *slash = 0; - } - - /* remove . and .. from tail */ - - if (verbose > 2) - fprintf(stderr, "input tail \"%s\"\n", tail); - from = to = tail; - while (1) { - if (!strncmp(from, "./", 2)) { - from += 2; - continue; - } - if (!strcmp(from, ".")) - break; - if (strncmp(from, "../", 3) && strcmp(from, "..")) { - while (*from) { - *to++ = *from++; - if (from[-1] == '/') - break; - } - if (!*from) - break; - } - if (to == tail) { - /* - * We have something like this: - * /home/repo/dead/../../foo - */ - fprintf(stderr, "%s: can't climb out of dead path\n", - path); - exit(1); - } - - /* - * We have something like - * "foo/" -> "" - * or - * "foo/bar/" -> "foo/" - * where "to" points to the end. - */ - to--; - while (to != tail && to[-1] != '/') - to--; - } - *to = 0; - if (verbose > 2) - fprintf(stderr, "output tail \"%s\"\n", tail); - - /* resolve all symlinks */ - - real = realpath(tmp, NULL); - if (verbose > 2) - fprintf(stderr, "realpath(\"%s\") = \"%s\"\n", tmp, real); - - /* append tail */ - - if (*tail) { - tmp2 = alloc_size(strlen(real) + 1 + strlen(tail) + 1); - sprintf(tmp2, "%s/%s", real, tail); - free(real); - } else { - tmp2 = real; - } - free(tmp); - tmp = tmp2; - - if (verbose > 1) - fprintf(stderr, "full object path \"%s\"\n", tmp); - - /* find which part of our path is inside the repo */ - - end = tail = strchr(tmp, 0); - while (1) { - if (verbose > 2) - fprintf(stderr, "trying \"%s\" tail \"%s\"\n", - tmp, tail); - - if (stat(tmp, &path_st) == 0 && - path_st.st_dev == repo_st.st_dev && - path_st.st_ino == repo_st.st_ino) - break; - - /* "this cannot happen" */ - if (tail == tmp) { - fprintf(stderr, - "divergent paths:\nrepo \"%s\"\nobject \"%s\"\n", - repo_dir, tmp); - exit(1); - } - - slash = strrchr(tmp, '/'); - if (tail != end) - tail[-1] = '/'; - tail = slash + 1; - *slash = 0; - } - - if (verbose > 1) - fprintf(stderr, "path in repo \"%s\"\n", tail); - - tmp2 = stralloc(tail); - free(tmp); - return tmp2; -} - - -static git_tree_entry *find_file(git_repository *repo, git_tree *tree, - const char *path) -{ - git_tree_entry *entry; - char *repo_path = stralloc(git_repository_path(repo)); - char *slash, *canon_path; - int len; - - /* remove trailing / from repo_path */ - slash = strrchr(repo_path, '/'); - if (slash && slash != repo_path && !slash[1]) - *slash = 0; - - len = strlen(repo_path); - if (len >= 5 && !strcmp(repo_path + len - 5, "/.git")) - repo_path[len == 5 ? 1 : len - 5] = 0; - - if (verbose > 1) - fprintf(stderr, "repo dir \"%s\"\n", repo_path); - - canon_path = canonical_path_into_repo(repo_path, path); - - if (git_tree_entry_bypath(&entry, tree, canon_path)) { - const git_error *e = giterr_last(); - - fprintf(stderr, "%s: %s\n", path, e->message); - exit(1); - } - free(canon_path); - - return entry; -} - - -static const void *get_data(git_repository *repo, git_tree_entry *entry, - unsigned *size) -{ - git_object *obj; - git_blob *blob; - - if (git_tree_entry_type(entry) != GIT_OBJ_BLOB) { - fprintf(stderr, "entry is not a blob\n"); - exit(1); - } - if (git_tree_entry_to_object(&obj, repo, entry)) { - const git_error *e = giterr_last(); - - fprintf(stderr, "%s\n", e->message); - exit(1); - } - - blob = (git_blob *) obj; - *size = git_blob_rawsize(blob); - return git_blob_rawcontent(blob); -} - - -static bool send_line(const char *s, unsigned len, - bool (*parse)(void *user, const char *line), void *user) -{ - char *tmp = alloc_size(len + 1); - bool res; - - memcpy(tmp, s, len); - tmp[len] = 0; - res = parse(user, tmp); - free(tmp); - return res; -} - - -static void send_data(const char *data, unsigned size, - bool (*parse)(void *user, const char *line), void *user) -{ - const char *end = data + size; - const char *p = data; - const char *nl; - - while (p != end) { - nl = memchr(p, '\n', end - p); - if (!nl) { - send_line(p, end - p, parse, user); - return; - } - if (!send_line(p, nl - p, parse, user)) - return; - p = nl + 1; - } -} - - -void git_read(const char *revision, const char *name, - bool (*parse)(void *user, const char *line), void *user) -{ - static bool initialized = 0; - git_repository *repo; - git_tree *tree; - git_tree_entry *entry; - const void *data; - unsigned size; - - if (!initialized) { - git_libgit2_init(); - initialized = 1; - } - - repo = select_repo(name); - if (!repo) { - fprintf(stderr, "%s:%s not found\n", revision, name); - exit(1); - } - if (verbose > 1) - fprintf(stderr, "using repository %s\n", - git_repository_path(repo)); - - tree = pick_revision(repo, revision); - entry = find_file(repo, tree, name); - if (verbose) - fprintf(stderr, "reading %s:%s\n", revision, name); - data = get_data(repo, entry, &size); - send_data(data, size, parse, user); -} diff --git a/sch2fig/git-file.h b/sch2fig/git-file.h deleted file mode 100644 index 4642528..0000000 --- a/sch2fig/git-file.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * git-file.h - Open and read a file from git - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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 GIT_FILE_H -#define GIT_FILE_H - -#include - - -void git_read(const char *revision, const char *name, - bool (*parse)(void *user, const char *line), void *user); - -#endif /* !GIT_FILE_H */ diff --git a/sch2fig/lib-parse.c b/sch2fig/lib-parse.c deleted file mode 100644 index 21d37ff..0000000 --- a/sch2fig/lib-parse.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * lib.c - Parse Eeschema .lib file - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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 -#include -#include - -#include "util.h" -#include "text.h" -#include "file.h" -#include "lib.h" - - -/* ----- Text -------------------------------------------------------------- */ - - -static enum text_style decode_style(const char *s) -{ - if (!strcmp(s, "Normal")) - return text_normal; - assert(0); -} - - -/* ----- Polygons ---------------------------------------------------------- */ - - -static bool parse_poly(struct lib_poly *poly, const char *line, int points) -{ - int i, n; - - poly->points = points; - poly->x = alloc_size(sizeof(int) * points); - poly->y = alloc_size(sizeof(int) * points); - for (i = 0; i != points; i++) { - if (sscanf(line, "%d %d %n", - poly->x + i, poly->y + i, &n) != 2) - return 0; - line += n; - } - if (sscanf(line, "%c", &poly->fill) != 1) - return 0; - return 1; -} - - -/* ----- Definitions ------------------------------------------------------- */ - - -static bool parse_def(struct lib *lib, const char *line) -{ - char *s; - char draw_num, draw_name; - unsigned name_offset; - unsigned units; - - if (sscanf(line, "DEF %ms %*s %*d %u %c %c %u", - &s, &name_offset, &draw_num, &draw_name, &units) != 5) - return 0; - - lib->curr_comp = alloc_type(struct comp); - if (*s == '~') - s++; - lib->curr_comp->name = s; - lib->curr_comp->units = units; - - lib->curr_comp->visible = 0; - lib->curr_comp->show_pin_name = draw_name == 'Y'; - lib->curr_comp->show_pin_num = draw_num == 'Y'; - lib->curr_comp->name_offset = name_offset; - - lib->curr_comp->objs = NULL; - lib->next_obj = &lib->curr_comp->objs; - - lib->curr_comp->next = NULL; - *lib->next_comp = lib->curr_comp; - lib->next_comp = &lib->curr_comp->next; - - return 1; -} - - -/* ----- Arcs -------------------------------------------------------------- */ - - -static bool parse_arc(struct lib_obj *obj, const char *line) -{ - struct lib_arc *arc = &obj->u.arc; - int a1, a2; - - if (sscanf(line, "A %d %d %d %d %d %u %u %u %c", - &arc->x, &arc->y, &arc->r, &a1, &a2, &obj->unit, &obj->convert, - &arc->thick, &arc->fill) != 9) - return 0; - - /* - * KiCad arcs can be clockwise or counter-clockwise. They must always - * be smaller than 180 degrees. - */ - - while (a1 < 0) - a1 += 3600; - while (a2 < 0) - a2 += 3600; - a1 %= 3600; - a2 %= 3600; - if (a2 < a1) - a2 += 3600; - assert(a2 - a1 != 1800); - if (a2 - a1 > 1800) - swap(a1, a2); - - arc->start_a = (a1 % 3600) / 10; - arc->end_a = (a2 % 3600) / 10; - - return 1; -} - - -/* ----- Library parser ---------------------------------------------------- */ - - -static bool lib_parse_line(void *user, const char *line) -{ - struct lib *lib = user; - int n = 0; - unsigned points; - struct lib_obj *obj; - char *style; - unsigned zero1, zero2; - char vis; - - lib->lineno++; - - switch (lib->state) { - case lib_skip: - if (parse_def(lib, line)) { - lib->state = lib_def; - return 1; - } - return 1; - case lib_def: - if (sscanf(line, "DRAW%n", &n) == 0 && n) { - lib->state = lib_draw; - return 1; - } - if (sscanf(line, "F%d \"\" %*d %*d %*d %*c %c", &n, &vis) == 2 - || sscanf(line, "F%d \"%*[^\"]\" %*d %*d %*d %*c %c", - &n, &vis) == 2) { - if (vis == 'V') - lib->curr_comp->visible |= 1 << n; - return 1; - } - /* @@@ explicitly ignore FPLIST */ - return 1; - case lib_draw: - if (sscanf(line, "ENDDRAW%n", &n) == 0 && n) { - lib->state = lib_skip; - return 1; - } - - obj = alloc_type(struct lib_obj); - obj->next = NULL; - *lib->next_obj = obj; - lib->next_obj = &obj->next; - - if (sscanf(line, "P %u %u %u %u %n", - &points, &obj->unit, &obj->convert, &obj->u.poly.thick, - &n) == 4) { - obj->type = lib_obj_poly; - if (parse_poly(&obj->u.poly, line + n, points)) - return 1; - break; - } - if (sscanf(line, "S %d %d %d %d %u %u %d %c", - &obj->u.rect.sx, &obj->u.rect.sy, &obj->u.rect.ex, - &obj->u.rect.ey, &obj->unit, &obj->convert, - &obj->u.rect.thick, &obj->u.rect.fill) == 8) { - obj->type = lib_obj_rect; - return 1; - } - if (sscanf(line, "C %d %d %d %u %u %d %c", - &obj->u.circ.x, &obj->u.circ.y, &obj->u.circ.r, - &obj->unit, &obj->convert, &obj->u.circ.thick, - &obj->u.circ.fill) == 7) { - obj->type = lib_obj_circ; - return 1; - } - if (parse_arc(obj, line)) { - obj->type = lib_obj_arc; - return 1; - } - n = sscanf(line, - "T %d %d %d %d %u %u %u \"%m[^\"]\" %ms %u %c %c", - &obj->u.text.orient, &obj->u.text.x, &obj->u.text.y, - &obj->u.text.dim, &zero1, &obj->unit, &obj->convert, - &obj->u.text.s, &style, &zero2, - &obj->u.text.hor_align, &obj->u.text.vert_align); - if (n != 12) { - n = sscanf(line, - "T %d %d %d %d %u %u %u %ms %ms %u %c %c", - &obj->u.text.orient, &obj->u.text.x, &obj->u.text.y, - &obj->u.text.dim, &zero1, &obj->unit, &obj->convert, - &obj->u.text.s, &style, &zero2, - &obj->u.text.hor_align, &obj->u.text.vert_align); - while (n == 12) { - char *tilde; - - tilde = strchr(obj->u.text.s, '~'); - if (!tilde) - break; - *tilde = ' '; - } - } - /* - * zero2 seems to be the font style: 0 = normal, 1 = bold ? - */ - if (n == 12) { - if (zero1) { - fprintf(stderr, "%u: only understand 0 x x\n" - "\"%s\"\n", lib->lineno, line); - exit(1); - } - obj->u.text.style = decode_style(style); - obj->type = lib_obj_text; - return 1; - } - if (sscanf(line, "X %ms %ms %d %d %d %c %d %d %u %u %c", - &obj->u.pin.name, &obj->u.pin.number, - &obj->u.pin.x, &obj->u.pin.y, &obj->u.pin.length, - &obj->u.pin.orient, - &obj->u.pin.number_size, &obj->u.pin.name_size, - &obj->unit, &obj->convert, &obj->u.pin.etype) == 11) { - obj->type = lib_obj_pin; - return 1; - } - break; - default: - abort(); - } - fprintf(stderr, "%u: cannot parse\n\"%s\"\n", lib->lineno, line); - exit(1); -} - - -void lib_parse(struct lib *lib, const char *file) -{ - lib->state = lib_skip; - lib->lineno = 0; - file_read(file, lib_parse_line, lib); -} - - -void lib_init(struct lib *lib) -{ - lib->comps = NULL; - lib->next_comp = &lib->comps; -} diff --git a/sch2fig/lib-render.c b/sch2fig/lib-render.c deleted file mode 100644 index fe20c9a..0000000 --- a/sch2fig/lib-render.c +++ /dev/null @@ -1,396 +0,0 @@ -/* - * lib.c - Render component from library - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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 -#include -#include - -#include "util.h" -#include "misc.h" -#include "style.h" -#include "gfx.h" -#include "text.h" -#include "sch.h" -#include "lib.h" - - -/* ----- Drawing ----------------------------------------------------------- */ - - -static void draw_poly(const struct lib_poly *poly, const int m[6]) -{ - int n = poly->points; - int x[n]; - int y[n]; - int i; - - for (i = 0; i != n; i++) { - x[i] = mx(poly->x[i], poly->y[i], m); - y[i] = my(poly->x[i], poly->y[i], m); - } - - gfx_poly(n, x, y, COLOR_COMP_DWG, COLOR_NONE, LAYER_COMP_DWG); - - switch (poly->fill) { - case 'N': - break; - case 'F': - gfx_poly(n, x, y, COLOR_NONE, COLOR_COMP_DWG, - LAYER_COMP_DWG_BG); - break; - case 'f': - gfx_poly(n, x, y, COLOR_NONE, COLOR_COMP_DWG_BG, - LAYER_COMP_DWG_BG); - break; - default: - abort(); - } -} - - -static void draw_rect(const struct lib_rect *rect, const int m[6]) -{ - int sx = mx(rect->sx, rect->sy, m); - int sy = my(rect->sx, rect->sy, m); - int ex = mx(rect->ex, rect->ey, m); - int ey = my(rect->ex, rect->ey, m); - - gfx_rect(sx, sy, ex, ey, COLOR_COMP_DWG, COLOR_NONE, LAYER_COMP_DWG); - - switch (rect->fill) { - case 'N': - break; - case 'F': - gfx_rect(sx, sy, ex, ey, COLOR_NONE, COLOR_COMP_DWG, - LAYER_COMP_DWG_BG); - break; - case 'f': - gfx_rect(sx, sy, ex, ey, COLOR_NONE, COLOR_COMP_DWG_BG, - LAYER_COMP_DWG_BG); - break; - default: - abort(); - } -} - - -static void draw_circ(const struct lib_circ *circ, const int m[6]) -{ - int x = mx(circ->x, circ->y, m); - int y = my(circ->x, circ->y, m); - int r = circ->r; - - gfx_circ(x, y, r, COLOR_COMP_DWG, COLOR_NONE, LAYER_COMP_DWG); - - switch (circ->fill) { - case 'N': - break; - case 'F': - gfx_circ(x, y, r, COLOR_NONE, COLOR_COMP_DWG, - LAYER_COMP_DWG_BG); - break; - case 'f': - gfx_circ(x, y, r, COLOR_NONE, COLOR_COMP_DWG_BG, - LAYER_COMP_DWG_BG); - break; - default: - abort(); - } -} - - -static void draw_arc(const struct lib_arc *arc, const int m[6]) -{ - int a = matrix_to_angle(m); - int x = mx(arc->x, arc->y, m); - int y = my(arc->x, arc->y, m); - int sa = angle_add(arc->start_a, a); - int ea = angle_add(arc->end_a, a); - - if (matrix_is_mirrored(m)) { - sa = 180 - sa; - ea = 180 - ea; - while (ea < sa) - ea += 360; - while (ea - sa > 360) - ea -= 360; - if (ea - sa >= 180) { - swap(sa, ea); - sa += 360; - } - } - - gfx_arc(x, y, arc->r, sa, ea, - COLOR_COMP_DWG, COLOR_NONE, LAYER_COMP_DWG); - - assert(arc->fill == 'N'); -} - - -static void draw_pin_name(const struct comp *comp, const struct lib_pin *pin, - const int m[6], int dx, int dy, int rot, enum text_align hor) -{ - int ox, oy, sx, sy; - - if (comp->name_offset) { - ox = dx * (pin->length + comp->name_offset); - oy = dy * (pin->length + comp->name_offset); - sx = sy = 0; - } else { - ox = dx * pin->length / 2; - oy = dy * pin->length / 2; - sx = mxr(-dy * PIN_NUM_OFFSET, dx * PIN_NUM_OFFSET, m); - sy = myr(-dy * PIN_NUM_OFFSET, dx * PIN_NUM_OFFSET, m); - if (sx > 0) - sx = -sx; - if (sy > 0) - sy = -sy; - } - - struct text txt = { - .s = pin->name, - .x = mx(pin->x + ox, pin->y + oy, m) + sx, - .y = my(pin->x + ox, pin->y + oy, m) + sy, - .size = pin->name_size, - .rot = rot, - .hor = comp->name_offset ? hor : text_mid, - .vert = comp->name_offset ? text_mid : text_min, - }; - - text_rot(&txt, matrix_to_angle(m)); - if (matrix_is_mirrored(m)) { - if ((txt.rot % 180) == 0) - txt.hor = text_flip(txt.hor); - else - txt.vert = text_flip(txt.vert); - } - - switch (txt.rot) { - case 180: - case 270: - text_flip_x(&txt); - break; - default: - break; - } - - text_fig(&txt, COLOR_PIN_NAME, LAYER_PIN_NAME); -} - - -static void draw_pin_num(const struct comp *comp, const struct lib_pin *pin, - const int m[6], int dx, int dy, int rot, enum text_align hor) -{ - int ox, oy, sx, sy; - - ox = dx * pin->length / 2; - oy = dy * pin->length / 2; - - sx = mxr(-dy * PIN_NUM_OFFSET, dx * PIN_NUM_OFFSET, m); - sy = myr(-dy * PIN_NUM_OFFSET, dx * PIN_NUM_OFFSET, m); - if (sx > 0) - sx = -sx; - if (sy > 0) - sy = -sy; - - if (!comp->name_offset) { - sx = -sx; - sy = -sy; - } - - struct text txt = { - .s = pin->number, - .x = mx(pin->x + ox, pin->y + oy, m) + sx, - .y = my(pin->x + ox, pin->y + oy, m) + sy, - .size = pin->number_size, - .rot = rot, - .hor = text_mid, - .vert = comp->name_offset ? text_min : text_max, - }; - - text_rot(&txt, matrix_to_angle(m) % 180); - if (matrix_is_mirrored(m)) { - switch (txt.rot) { - case 0: - txt.hor = text_flip(txt.hor); - break; - case 90: - break; - case 180: - txt.hor = text_flip(txt.hor); - break; - case 270: - break; - } - } - - switch (txt.rot) { - case 180: - case 270: - text_flip_x(&txt); - break; - default: - break; - } - - text_fig(&txt, COLOR_PIN_NUMBER, LAYER_PIN_NUMBER); -} - - -static void draw_pin(const struct comp *comp, const struct lib_pin *pin, - const int m[6]) -{ - int x[2], y[2]; - int dx = 0, dy = 0; - int rot; - enum text_align hor; - - switch (pin->orient) { - case 'U': - dy = 1; - rot = 90; - hor = text_min; - break; - case 'D': - dy = -1; - rot = 90; - hor = text_max; - break; - case 'R': - dx = 1; - rot = 0; - hor = text_min; - break; - case 'L': - dx = -1; - rot = 0; - hor = text_max; - break; - default: - abort(); - } - x[0] = mx(pin->x, pin->y, m); - y[0] = my(pin->x, pin->y, m); - x[1] = mx(pin->x + dx * pin->length, pin->y + dy * pin->length, m); - y[1] = my(pin->x + dx * pin->length, pin->y + dy * pin->length, m); - gfx_poly(2, x, y, COLOR_COMP_DWG, COLOR_NONE, LAYER_COMP_DWG); - - if (comp->show_pin_name) - draw_pin_name(comp, pin, m, dx, dy, rot, hor); - - if (comp->show_pin_num) - draw_pin_num(comp, pin, m, dx, dy, rot, hor); -} - - -static void draw_text(const struct lib_text *text, const int m[6]) -{ - struct text txt = { - .s = text->s, - .size = text->dim, - .x = mx(text->x, text->y, m), - .y = my(text->x, text->y, m), - .rot = angle_add(text->orient / 10, matrix_to_angle(m)), - }; - - decode_alignment(&txt, text->hor_align, text->vert_align); - - switch (txt.rot) { - case 180: - case 270: - /* @@@ consolidate this with text_flip_x */ - txt.rot = angle_add(txt.rot, 180); - txt.hor = text_flip(txt.hor); - txt.vert = text_flip(txt.vert); -// text_flip_x(&txt); - break; - default: - break; - } - - if (matrix_is_mirrored(m)) - switch (txt.rot) { - case 0: - case 180: - txt.hor = text_flip(txt.hor); - break; - case 90: - case 270: - txt.vert = text_flip(txt.vert); - break; - default: - abort(); - } - - text_fig(&txt, COLOR_COMP_DWG, WIDTH_COMP_DWG); -} - - -static void draw(const struct comp *comp, const struct lib_obj *obj, - const int m[6]) -{ - switch (obj->type) { - case lib_obj_poly: - draw_poly(&obj->u.poly, m); - break; - case lib_obj_rect: - draw_rect(&obj->u.rect, m); - break; - case lib_obj_circ: - draw_circ(&obj->u.circ, m); - break; - case lib_obj_arc: - draw_arc(&obj->u.arc, m); - break; - case lib_obj_text: - draw_text(&obj->u.text, m); - break; - case lib_obj_pin: - draw_pin(comp, &obj->u.pin, m); - break; - default: - abort(); - } -} - - -const struct comp *lib_find(const struct lib *lib, const char *name) -{ - const struct comp *comp; - - for (comp = lib->comps; comp; comp = comp->next) - if (!strcmp(comp->name, name)) - return comp; - fprintf(stderr, "\"%s\" not found\n", name); - exit(1); -} - - -bool lib_field_visible(const struct comp *comp, int n) -{ - return (comp->visible >> n) & 1; -} - - -void lib_render(const struct comp *comp, unsigned unit, const int m[4]) -{ - const struct lib_obj *obj; - - if (!unit) - unit = 1; - for (obj = comp->objs; obj; obj = obj->next) { - if (obj->unit && obj->unit != unit) - continue; - draw(comp, obj, m); - } -} diff --git a/sch2fig/lib.h b/sch2fig/lib.h deleted file mode 100644 index 4f1e9f0..0000000 --- a/sch2fig/lib.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * lib.h - Parse Eeschema .lib file - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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 LIB_H -#define LIB_H - -#include - - -enum lib_state { - lib_skip, /* before a definition */ - lib_def, /* in definition */ - lib_draw, /* in drawings */ -}; - -struct lib_obj { - enum lib_obj_type { - lib_obj_poly, - lib_obj_rect, - lib_obj_circ, - lib_obj_arc, - lib_obj_text, - lib_obj_pin, - } type; - unsigned unit; - unsigned convert; - union { - struct lib_poly { - int thick; - char fill; - int points; - int *x; - int *y; - } poly; - struct lib_rect { - int thick; - char fill; - int sx, sy; - int ex, ey; - } rect; - struct lib_circ { - int x, y; - int r; - int thick; - char fill; - } circ; - struct lib_arc { - int x, y; - int r; - int start_a, end_a; - int thick; - char fill; - } arc; - struct lib_text { - int orient; - int x, y; - int dim; - char *s; - enum text_style style; - char hor_align; - char vert_align; - } text; - struct lib_pin { - char *name; - char *number; - int x, y; - int length; - char orient; - int number_size; - int name_size; - char etype; - // @@@ shape - } pin; - } u; - struct lib_obj *next; -}; - -struct comp { - const char *name; - unsigned units; - - unsigned visible; /* visible fields, bit mask */ - bool show_pin_name; - bool show_pin_num; - unsigned name_offset; - - struct lib_obj *objs; - struct comp *next; -}; - -struct lib { - enum lib_state state; - unsigned lineno; - - struct comp *comps; - - struct comp *curr_comp; /* current component */ - struct comp **next_comp; - struct lib_obj **next_obj; - -}; - - -extern struct comp *comps; - - -const struct comp *lib_find(const struct lib *lib, const char *name); -bool lib_field_visible(const struct comp *comp, int n); -void lib_render(const struct comp *comp, unsigned unit, const int m[6]); - -void lib_parse(struct lib *lib, const char *file); -void lib_init(struct lib *lib); - -#endif /* !LIB_H */ diff --git a/sch2fig/main.c b/sch2fig/main.c deleted file mode 100644 index 7e02d0e..0000000 --- a/sch2fig/main.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * main.c - Convert Eeschema schematics to FIG - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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 -#include -#include -#include -#include - -#include "util.h" -#include "fig.h" -#include "cro.h" -#include "diff.h" -#include "gfx.h" -#include "file.h" -#include "lib.h" -#include "sch.h" -#include "main.h" - - -int verbose = 0; - - -static struct gfx_ops const *ops_list[] = { - &fig_ops, - &cro_png_ops, - &cro_pdf_ops, - &diff_ops, -}; - - -void usage(const char *name) -{ - fprintf(stderr, -"usage: %s [-r] [-v ...] [[rev:]file.lib ...] [rev:]file.sch\n" -" %*s-- driver_spec\n" -" %s [-v ...] -C [rev:]file\n" -"\n" -" rev git revision\n" -" -r recurse into sub-sheets\n" -" -v increase verbosity of diagnostic output\n" -" -C 'cat' the file to standard output\n" -"\n" -"FIG driver spec:\n" -" fig [-t template.fig] [var=value ...]\n" -"\n" -" var=value substitute \"\" with \"value\" in template\n" -" -t template.fig merge this file with generated output\n" -"\n" -"Cairo PNG driver spec:\n" -" png [-o output.png] [-s scale]\n" -"\n" -" -o output.png generate PNG output and write to specified file\n" -" -s scale scale by indicated factor (default: 1.0)\n" -"\n" -"Cairo PDF driver spec:\n" -" pdf [-o output.pdf] [-s scale]\n" -"\n" -" see PNG\n" -"\n" -"Diff driver spec:\n" -" diff [-o output.pdf] [-s scale] [file.lib ...] file.sch\n" -"\n" -" see PNG\n" - , name, (int) strlen(name) + 1, "", name); - exit(1); -} - - -int main(int argc, char *const *argv) -{ - struct lib lib; - struct sch_ctx sch_ctx; - bool recurse = 0; - const char *cat = NULL; - char c; - int arg, dashdash; - int gfx_argc; - char **gfx_argv; - const struct gfx_ops **ops = ops_list; - - for (dashdash = 1; dashdash != argc; dashdash++) - if (!strcmp(argv[dashdash], "--")) - break; - - while ((c = getopt(dashdash, argv, "rvC:")) != EOF) - switch (c) { - case 'r': - recurse = 1; - break; - case 'v': - verbose++; - break; - case 'C': - cat = optarg; - break; - default: - usage(*argv); - } - - if (cat) { - if (argc != optind) - usage(*argv); - file_read(cat, file_cat, NULL); - return 0; - } - - if (dashdash - optind < 1) - usage(*argv); - - lib_init(&lib); - for (arg = optind; arg != dashdash - 1; arg++) - lib_parse(&lib, argv[arg]); - - if (dashdash == argc) { - gfx_argc = 1; - gfx_argv = alloc_size(sizeof(const char *) * 2); - gfx_argv[0] = (char *) (*ops)->name; - gfx_argv[1] = NULL; - } else { - gfx_argc = argc - dashdash - 1; - if (!gfx_argc) - usage(*argv); - gfx_argv = alloc_size(sizeof(const char *) * (gfx_argc + 1)); - memcpy(gfx_argv, argv + dashdash + 1, - sizeof(const char *) * (gfx_argc + 1)); - - for (ops = ops_list; ops != ARRAY_END(ops_list); ops++) - if (!strcmp((*ops)->name, *gfx_argv)) - goto found; - fprintf(stderr, "graphics backend \"%s\" not found\n", - *gfx_argv); - exit(1); -found: - ; - } - - optind = 0; /* reset getopt */ - - sch_init(&sch_ctx, recurse); - sch_parse(&sch_ctx, argv[dashdash - 1], &lib); - gfx_init(*ops, gfx_argc, gfx_argv); - if (recurse) { - const struct sheet *sheet; - - if (!gfx_multi_sheet()) { - fprintf(stderr, - "graphics backend only supports single sheet\n"); - exit(1); - } - for (sheet = sch_ctx.sheets; sheet; sheet = sheet->next) { - sch_render(sheet); - if (sheet->next) - gfx_new_sheet(); - } - } else { - sch_render(sch_ctx.sheets); - } - gfx_end(); - - return 0; -} diff --git a/sch2fig/main.h b/sch2fig/main.h deleted file mode 100644 index 4a3bdc1..0000000 --- a/sch2fig/main.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * main.h - Convert Eeschema schematics to FIG - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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 MAIN_H -#define MAIN_H - -#include - - -/* - * 0: no progress indications - * 1: reasonable progress indications - * 2: verbose output - * > 2: go wild ! - */ - -extern int verbose; - - -void usage(const char *name); - -#endif /* !MAIN_H */ diff --git a/sch2fig/misc.c b/sch2fig/misc.c deleted file mode 100644 index 5e2401c..0000000 --- a/sch2fig/misc.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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 - -#include "misc.h" - - -static bool eq(const 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(const int m[6]) -{ - if (eq(m, 1, 0, 0, -1)) - return 0; - if (eq(m, 0, -1, -1, 0)) - return 90; - if (eq(m, -1, 0, 0, 1)) - return 180; - if (eq(m, 0, 1, 1, 0)) - return 270; - if (eq(m, -1, 0, 0, -1)) - return 0; - if (eq(m, 1, 0, 0, 1)) /* x-flipped */ - return 180; - if (eq(m, 0, 1, -1, 0)) /* x-flipped, 90 deg */ - return 90; - fprintf(stderr, "unrecognized matrix %d %d %d %d\n", - m[1], m[2], m[4], m[5]); - exit(1); -} - - -bool matrix_is_mirrored(const int m[6]) -{ - if (eq(m, 1, 0, 0, -1)) - return 0; - if (eq(m, 0, -1, -1, 0)) - return 0; - if (eq(m, -1, 0, 0, 1)) - return 0; - if (eq(m, 0, 1, 1, 0)) - return 0; - - if (eq(m, -1, 0, 0, -1)) - return 1; - if (eq(m, 1, 0, 0, 1)) - return 1; - if (eq(m, 0, 1, -1, 0)) - return 1; - assert(0); -} - - -int angle_add(int a, int b) -{ - a += b; - while (a < 0) - a += 360; - return a % 360; -} - - - -int rx(int x, int y, int rot) -{ - switch (rot) { - case 0: - return x; - case 90: - return y; - case 180: - return -x; - case 270: - return -y; - default: - assert(0); - - } -} - - -int ry(int x, int y, int rot) -{ - switch (rot) { - case 0: - return y; - case 90: - return -x; - case 180: - return -y; - case 270: - return x; - default: - assert(0); - - } -} diff --git a/sch2fig/misc.h b/sch2fig/misc.h deleted file mode 100644 index 40c15f0..0000000 --- a/sch2fig/misc.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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 mxr(int x, int y, const int m[6]) -{ - return x * m[1] + y * m[2]; -} - - -static inline int myr(int x, int y, const int m[6]) -{ - return x * m[4] + y * m[5]; -} - - -static inline int mx(int x, int y, const int m[6]) -{ - return m[0] + mxr(x, y, m); -} - - -static inline int my(int x, int y, const int m[6]) -{ - return m[3] + myr(x, y, m); -} - - -unsigned matrix_to_angle(const int m[6]); -bool matrix_is_mirrored(const int m[6]); -int angle_add(int a, int b); - -int rx(int x, int y, int rot); -int ry(int x, int y, int rot); - -#endif /* !MISC_H */ diff --git a/sch2fig/neo900-template.fig b/sch2fig/neo900-template.fig deleted file mode 100644 index 4371404..0000000 --- a/sch2fig/neo900-template.fig +++ /dev/null @@ -1,15 +0,0 @@ -#FIG 3.2 Produced by xfig version 3.2.5c -Landscape -Center -Metric -A4 -100.00 -Single --2 -1200 2 -0 32 #c0c0c0 -2 2 0 1 7 7 250 -1 -1 0.000 0 0 -1 0 0 5 - 225 450 19350 450 19350 13500 225 13500 225 450 -4 2 32 199 -1 18 150 0.0000 4 1890 13980 19305 13455 \001 -4 2 0 50 -1 18 24 0.0000 4 300 1635 19125 13140 \001 -4 0 0 250 -1 22 12 0.0000 4 180 3090 315 13410 CC-BY-SA (c) 2014-2016 Neo900 & GDC\001 diff --git a/sch2fig/record.c b/sch2fig/record.c deleted file mode 100644 index 03cf90c..0000000 --- a/sch2fig/record.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * record.c - Record graphics operations by layers and replay - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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 <limits.h> -#include <math.h> - -#include "util.h" -#include "style.h" -#include "gfx.h" -#include "text.h" -#include "record.h" - - -struct record_obj { - enum ro_type { - ro_line, - ro_rect, - ro_poly, - ro_circ, - ro_arc, - ro_text, - } type; - - int x, y; - int color, fill_color; - union { - struct { - int ex, ey; - } line; - struct { - int ex, ey; - } rect; - struct { - unsigned n; - int *vx, *vy; - } poly; - struct { - int r; - } circ; - struct { - int r; - int sa, ea; - } arc; - struct { - char *s; - unsigned size; - enum text_align align; - int rot; - } text; - } u; - struct record_obj *next; -}; - - -static void bb(struct record *rec, int x, int y) -{ - if (rec->xmin > x) - rec->xmin = x; - if (rec->ymin > y) - rec->ymin = y; - if (rec->xmax < x) - rec->xmax = x; - if (rec->ymax < y) - rec->ymax = y; -} - - -static void bb_rot(struct record *rec, int x, int y, int rot) -{ - double a = -rot / 180.0 * M_PI; - - // @@@ figure this out later -return; - bb(rec, cos(a) * x + sin(a) * y, cos(a) * y - sin(a) * x); -} - - -static struct record_obj *new_obj(struct record *rec, enum ro_type type, - int color, int fill_color, unsigned layer) -{ - struct record_layer **curr_layer; - struct record_layer *new_layer; - struct record_obj *new_obj; - - for (curr_layer = &rec->layers; *curr_layer; - curr_layer= &(*curr_layer)->next) { - if ((*curr_layer)->layer == layer) - goto this_layer; - if ((*curr_layer)->layer < layer) - break; - } - - new_layer = alloc_type(struct record_layer); - new_layer->layer = layer; - new_layer->objs = NULL; - new_layer->next_obj = &new_layer->objs; - new_layer->next = *curr_layer; - *curr_layer = new_layer; - -this_layer: - new_obj = alloc_type(struct record_obj); - new_obj->type = type; - new_obj->color = color; - new_obj->fill_color = fill_color; - new_obj->next = NULL; - - *(*curr_layer)->next_obj = new_obj; - (*curr_layer)->next_obj = &new_obj->next; - - return new_obj; -} - - -void record_line(void *ctx, int sx, int sy, int ex, int ey, - int color, unsigned layer) -{ - struct record *rec = ctx; - struct record_obj *obj = - new_obj(rec, ro_line, color, COLOR_NONE, layer); - - bb(rec, sx, sy); - bb(rec, ex, ey); - - obj->x = sx; - obj->y = sy; - obj->u.line.ex = ex; - obj->u.line.ey = ey; -} - - -void record_rect(void *ctx, int sx, int sy, int ex, int ey, - int color, int fill_color, unsigned layer) -{ - struct record *rec = ctx; - struct record_obj *obj = - new_obj(rec, ro_rect, color, fill_color, layer); - - bb(rec, sx, sy); - bb(rec, ex, ey); - - obj->x = sx; - obj->y = sy; - obj->u.rect.ex = ex; - obj->u.rect.ey = ey; -} - - -void record_poly(void *ctx, - int points, const int x[points], const int y[points], - int color, int fill_color, unsigned layer) -{ - struct record *rec = ctx; - struct record_obj *obj = - new_obj(ctx, ro_poly, color, fill_color, layer); - int i; - unsigned size; - - for (i = 0; i != points; i++) - bb(rec, x[i], y[i]); - - obj->u.poly.n = points; - size = sizeof(int) * points; - obj->u.poly.vx = alloc_size(size); - obj->u.poly.vy = alloc_size(size); - memcpy(obj->u.poly.vx, x, size); - memcpy(obj->u.poly.vy, y, size); -} - - -void record_circ(void *ctx, int x, int y, int r, - int color, int fill_color, unsigned layer) -{ - struct record *rec = ctx; - struct record_obj *obj = - new_obj(ctx, ro_circ, color, fill_color, layer); - - bb(rec, x - r, y - r); - bb(rec, x + r, y + r); - - obj->x = x; - obj->y = y; - obj->u.circ.r = r; -} - - -void record_arc(void *ctx, int x, int y, int r, int sa, int ea, - int color, int fill_color, unsigned layer) -{ - struct record *rec = ctx; - struct record_obj *obj = new_obj(ctx, ro_arc, color, fill_color, layer); - - bb(rec, x - r, y - r); - bb(rec, x + r, y + r); - - obj->x = x; - obj->y = y; - obj->u.arc.r = r; - obj->u.arc.sa = sa; - obj->u.arc.ea = ea; -} - - -void record_text(void *ctx, int x, int y, const char *s, unsigned size, - enum text_align align, int rot, unsigned color, unsigned layer) -{ - struct record *rec = ctx; - struct record_obj *obj = - new_obj(ctx, ro_text, color, COLOR_NONE, layer); - unsigned width = rec->ops->text_width(rec->user, s, size); - - bb_rot(rec, x, y - size, rot); - bb_rot(rec, x + width, y, rot); - - obj->x = x; - obj->y = y; - obj->u.text.s = stralloc(s); - obj->u.text.size = size; - obj->u.text.align = align; - obj->u.text.rot = rot; -} - - -void record_init(struct record *rec, const struct gfx_ops *ops, void *user) -{ - rec->ops = ops; - rec->user = user; - rec->xmin = rec->ymin = INT_MAX; - rec->xmax = rec->ymax = INT_MIN; - rec->layers = NULL; -} - - -void record_wipe(struct record *rec) -{ - rec->layers = NULL; -} - - -void record_replay(const struct record *rec) -{ - const struct gfx_ops *ops = rec->ops; - void *ctx = rec->user; - const struct record_layer *layer; - const struct record_obj *obj; - - for (layer = rec->layers; layer; layer = layer->next) - for (obj = layer->objs; obj; obj = obj->next) - switch (obj->type) { - case ro_line: - ops->line(ctx, obj->x, obj->y, - obj->u.line.ex, obj->u.line.ey, - obj->color, layer->layer); - break; - case ro_rect: - ops->rect(ctx, obj->x, obj->y, - obj->u.rect.ex, obj->u.rect.ey, - obj->color, obj->fill_color, layer->layer); - break; - case ro_poly: - ops->poly(ctx, obj->u.poly.n, - obj->u.poly.vx, obj->u.poly.vy, - obj->color, obj->fill_color, layer->layer); - break; - case ro_circ: - ops->circ(ctx, obj->x, obj->y, - obj->u.circ.r, - obj->color, obj->fill_color, layer->layer); - break; - case ro_arc: - ops->arc(ctx, obj->x, obj->y, obj->u.arc.r, - obj->u.arc.sa, obj->u.arc.ea, - obj->color, obj->fill_color, layer->layer); - break; - case ro_text: - ops->text(ctx, obj->x, obj->y, obj->u.text.s, - obj->u.text.size, obj->u.text.align, - obj->u.text.rot, - obj->color, layer->layer); - break; - default: - abort(); - } -} - - -void record_bbox(const struct record *rec, int *x, int *y, int *w, int *h) -{ - if (x) - *x = rec->xmin; - if (y) - *y = rec->ymin; - if (w) - *w = rec->xmax - rec->xmin + 1; - if (h) - *h = rec->ymax - rec->ymin + 1; -} - - -static void record_obj_destroy(struct record_obj *obj) -{ - switch (obj->type) { - case ro_poly: - free(obj->u.poly.vx); - free(obj->u.poly.vy); - break; - case ro_text: - free(obj->u.text.s); - break; - default: - break; - } - free(obj); -} - - -void record_destroy(struct record *rec) -{ - struct record_layer *next_layer; - struct record_obj *next_obj; - - while (rec->layers) { - next_layer = rec->layers->next; - while (rec->layers->objs) { - next_obj = rec->layers->objs->next; - record_obj_destroy(rec->layers->objs); - rec->layers->objs = next_obj; - } - free(rec->layers); - rec->layers = next_layer; - } -} diff --git a/sch2fig/record.h b/sch2fig/record.h deleted file mode 100644 index 3ff26f8..0000000 --- a/sch2fig/record.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * record.h - Record graphics operations by layers and replay - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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 RECORD_H -#define RECORD_H - -#include "gfx.h" - - -struct record_obj; - -struct record_layer { - unsigned layer; - struct record_obj *objs; - struct record_obj **next_obj; - struct record_layer *next; -}; - -struct record { - const struct gfx_ops *ops; - void *user; - int xmin, xmax; - int ymin, ymax; - struct record_layer *layers; -}; - - -void record_line(void *ctx, int sx, int sy, int ex, int ey, - int color, unsigned layer); -void record_rect(void *ctx, int sx, int sy, int ex, int ey, - int color, int fill_color, unsigned layer); -void record_poly(void *ctx, - int points, const int x[points], const int y[points], - int color, int fill_color, unsigned layer); -void record_circ(void *ctx, int x, int y, int r, - int color, int fill_color, unsigned layer); -void record_arc(void *ctx, int x, int y, int r, int sa, int ea, - int color, int fill_color, unsigned layer); -void record_text(void *ctx, int x, int y, const char *s, unsigned size, - enum text_align align, int rot, unsigned color, unsigned layer); - -void record_init(struct record *rec, const struct gfx_ops *ops, void *user); -void record_wipe(struct record *rec); -void record_replay(const struct record *rec); -void record_bbox(const struct record *rec, int *x, int *y, int *w, int *h); -void record_destroy(struct record *rec); - -#endif /* !RECORD_H */ diff --git a/sch2fig/sch-parse.c b/sch2fig/sch-parse.c deleted file mode 100644 index e47ac49..0000000 --- a/sch2fig/sch-parse.c +++ /dev/null @@ -1,562 +0,0 @@ -/* - * sch-parse.c - Parse Eeschema .sch file - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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 <stddef.h> -#include <stdbool.h> -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <assert.h> - -#include "util.h" -#include "dwg.h" -#include "file.h" -#include "lib.h" -#include "sch.h" - - -/* ----- (Global) Labels --------------------------------------------------- */ - - -static enum dwg_shape do_decode_shape(const char *s) -{ - if (!strcmp(s, "UnSpc")) - return dwg_unspec; - if (!strcmp(s, "Input")) - return dwg_in; - if (!strcmp(s, "Output")) - return dwg_out; - if (!strcmp(s, "3State")) - return dwg_tri; - if (!strcmp(s, "BiDi")) - return dwg_bidir; - fprintf(stderr, "unknown shape: \"%s\"\n", s); - exit(1); -} - - -static enum dwg_shape decode_shape(const char *s) -{ - enum dwg_shape res; - - res = do_decode_shape(s); - free((void *) s); - return res; -} - - -/* ----- Component fields -------------------------------------------------- */ - - -void decode_alignment(struct text *txt, char hor, char vert) -{ - switch (hor) { - case 'L': - txt->hor = text_min; - break; - case 'C': - txt->hor = text_mid; - break; - case 'R': - txt->hor = text_max; - break; - default: - assert(0); - } - - switch (vert) { - case 'B': - txt->vert = text_min; - break; - case 'C': - txt->vert = text_mid; - break; - case 'T': - txt->vert = text_max; - break; - default: - assert(0); - } -} - - -static bool parse_field(struct sch_ctx *ctx, const char *line) -{ - struct sch_comp *comp = &ctx->obj.u.comp; - int n; - unsigned flags; - char hv, hor, vert, italic, bold; - struct comp_field *field; - struct text *txt; - - field = alloc_type(struct comp_field); - txt = &field->txt; - - if (sscanf(line, "F %d \"\" %c %d %d %u %u %c %c%c%c", - &n, &hv, &txt->x, &txt->y, &txt->size, &flags, &hor, &vert, - &italic, &bold) == 10) { - free(field); - return 1; - } - if (sscanf(line, "F %d \"%m[^\"]\" %c %d %d %u %u %c %c%c%c", - &n, &txt->s, &hv, &txt->x, &txt->y, &txt->size, &flags, - &hor, &vert, &italic, &bold) != 11) - return 0; - - if (flags || !lib_field_visible(comp->comp, n)) { - free(field); - return 1; - } - - if (n == 0 && comp->comp->units > 1) { - int len = strlen(txt->s); - char *s; - - s = realloc((void *) txt->s, len + 3); - if (!s) { - perror("realloc"); - exit(1); - } - if (comp->unit <= 26) - sprintf(s + len, "%c", 'A' + comp->unit - 1); - else - sprintf(s + len, "%c%c", - 'A' + (comp->unit - 1) / 26 - 1, - 'A' + (comp->unit - 1) % 26); - txt->s = s; - } - - field->next = comp->fields; - comp->fields = field; - - switch (hv) { - case 'H': - txt->rot = 0; - break; - case 'V': - txt->rot = 90; - break; - default: - assert(0); - } - - decode_alignment(txt, hor, vert); - - // @@@ decode font - - return 1; -} - - -/* ----- Sheet field ------------------------------------------------------- */ - - -static enum dwg_shape decode_form(char form) -{ - switch (form) { - case 'O': - return dwg_in; - case 'I': - return dwg_out; - case 'B': - /* fall through */ - case 'T': - return dwg_bidir; - case 'U': - return dwg_unspec; - default: - fprintf(stderr, "unknown form: \"%c\"\n", form); - exit(1); - } -} - - -static int decode_side(char side) -{ - switch (side) { - case 'L': - return 2; /* left */ - case 'B': - return 1; /* up */ - case 'R': - return 0; /* right */ - case 'T': - return 3; /* down */ - default: - fprintf(stderr, "unknown side: \"%c\"\n", side); - exit(1); - } -} - - -static bool parse_hsheet_field(struct sch_ctx *ctx, const char *line) -{ - struct sch_sheet *sheet = &ctx->obj.u.sheet; - char *s; - char form, side; - unsigned n, dim; - struct sheet_field *field; - - if (sscanf(line, "F%d \"%m[^\"]\" %u", &n, &s, &dim) == 3) { - switch (n) { - case 0: - sheet->sheet = s; - sheet->sheet_dim = dim; - return 1; - case 1: - sheet->file = s; - sheet->file_dim = dim; - return 1; - default: - assert(0); - } - } - - field = alloc_type(struct sheet_field); - if (sscanf(line, "F%d \"%m[^\"]\" %c %c %d %d %u", - &n, &field->s, &form, &side, &field->x, &field->y, &field->dim) - != 7) { - free(field); - return 0; - } - assert(n >= 2); - - if (side == 'B' || side == 'T') { - /* - * This is beautiful: since there is no indication for rotation - * on the hsheet, or the sheet or file fields, we need to look - * at whether the imported sheet pins go left or right (no - * rotation) or whether they go top or bottom (rotation). - * - * A sheet with no imported pins lacks these hints, and is - * therefore always assumed to be without rotation. - * - * Eeschema is careful to be consistent, and does not allow - * sheets with no imported pins to be rotated. Even better, it - * flips rotated sheets where the last imported pin is deleted - * back. - */ - sheet->rotated = 1; - } - field->shape = decode_form(form); - field->side = decode_side(side); - - field->next = sheet->fields; - sheet->fields = field; - - return 1; -} - - -/* ----- 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 = NULL; - - *ctx->next_obj = obj; - ctx->next_obj = &obj->next; -} - - -static struct sheet *new_sheet(struct sch_ctx *ctx) -{ - struct sheet *sheet; - - sheet = alloc_type(struct sheet); - sheet->objs = NULL; - sheet->next = NULL; - - ctx->next_obj = &sheet->objs; - - *ctx->next_sheet = sheet; - ctx->next_sheet = &sheet->next; - - return sheet; -} - - -static bool parse_line(void *user, const char *line); - - -static void recurse_sheet(struct sch_ctx *ctx) -{ - struct sch_obj **saved_next_obj = ctx->next_obj; - const char *parent = ctx->file->name; - char *tmp = NULL; - struct sch_file dsc = { - .name = ctx->obj.u.sheet.file, - .lineno = 0, - .parent = ctx->file, - }; - - /* @@@ clean this up */ - - if (access(dsc.name, R_OK)) { - const char *slash; - - slash = strrchr(parent, '/'); - if (slash) { - unsigned len = slash + 1 - parent; - - tmp = alloc_size(len + strlen(dsc.name) + 1); - memcpy(tmp, parent, len); - strcpy(tmp + len, dsc.name); - dsc.name = tmp; - } - } - - new_sheet(ctx); - ctx->file = &dsc; - ctx->state = sch_descr; - file_read(dsc.name, parse_line, ctx); - ctx->file = dsc.parent; - ctx->next_obj = saved_next_obj; - free(tmp); -} - - -static bool parse_line(void *user, const char *line) -{ - struct sch_ctx *ctx = user; - struct sch_obj *obj = &ctx->obj; - int n = 0; - char *s; - - ctx->file->lineno++; - - switch (ctx->state) { - case sch_basic: - if (sscanf(line, "$Comp%n", &n) == 0 && n) { - ctx->state = sch_comp; - obj->u.comp.fields = NULL; - return 1; - } - if (sscanf(line, "$Sheet%n", &n) == 0 && n) { - ctx->state = sch_sheet; - obj->u.sheet.sheet = NULL; - obj->u.sheet.file = NULL; - obj->u.sheet.rotated = 0; - obj->u.sheet.fields = NULL; - return 1; - } - - /* Text */ - - struct sch_text *text = &obj->u.text; - - if (sscanf(line, "Text Notes %d %d %d %d", - &obj->x, &obj->y, &text->dir, &text->dim) == 4) { - ctx->state = sch_text; - obj->u.text.fn = dwg_text; - return 1; - } - if (sscanf(line, "Text GLabel %d %d %d %d %ms", - &obj->x, &obj->y, &text->dir, &text->dim, &s) == 5) { - ctx->state = sch_text; - obj->u.text.fn = dwg_glabel; - obj->u.text.shape = decode_shape(s); - return 1; - } - if (sscanf(line, "Text HLabel %d %d %d %d %ms", - &obj->x, &obj->y, &text->dir, &text->dim, &s) == 5) { - ctx->state = sch_text; - obj->u.text.fn = dwg_hlabel; - obj->u.text.shape = decode_shape(s); - return 1; - } - if (sscanf(line, "Text Label %d %d %d %d", - &obj->x, &obj->y, &text->dir, &text->dim) == 4) { - ctx->state = sch_text; - obj->u.text.fn = dwg_label; - return 1; - } - - /* Connection */ - - if (sscanf(line, "Connection ~ %d %d", &obj->x, &obj->y) == 2) { - submit_obj(ctx, sch_obj_junction); - return 1; - } - - /* NoConn */ - - if (sscanf(line, "NoConn ~ %d %d", &obj->x, &obj->y) == 2) { - submit_obj(ctx, sch_obj_noconn); - return 1; - } - - /* Wire */ - - if (sscanf(line, "Wire Wire Line%n", &n) == 0 && n) { - ctx->state = sch_wire; - obj->u.wire.fn = dwg_wire; - return 1; - } - if (sscanf(line, "Wire Bus Line%n", &n) == 0 && n) { - ctx->state = sch_wire; - obj->u.wire.fn = dwg_bus; - return 1; - } - if (sscanf(line, "Wire Notes Line%n", &n) == 0 && n) { - ctx->state = sch_wire; - obj->u.wire.fn = dwg_line; - return 1; - } - - /* Entry */ - - /* - * Documentation mentions the following additional variants: - * - * - Entry Wire Line equivalent: - * Wire Wire Bus - * Entry Wire Bus - * - * - Entry Bus Bus equivalent: - * Wire Bus Bus - */ - if (sscanf(line, "Entry Wire Line%n", &n) == 0 && n) { - ctx->state = sch_wire; - obj->u.wire.fn = dwg_wire; - return 1; - } - if (sscanf(line, "Entry Bus Bus%n", &n) == 0 && n) { - ctx->state = sch_wire; - obj->u.wire.fn = dwg_bus; - return 1; - } - - /* EndSCHEMATC */ - - if (sscanf(line, "$EndSCHEMATC%n", &n) == 0 && n) - return 0; - break; - case sch_descr: - if (sscanf(line, "$EndDescr%n", &n) || !n) - return 1; - ctx->state = sch_basic; - return 1; - case sch_comp: - if (sscanf(line, "$EndComp%n", &n) == 0 && n) { - ctx->state = sch_basic; - submit_obj(ctx, sch_obj_comp); - return 1; - } - if (sscanf(line, "L %ms", &s) == 1) { - obj->u.comp.comp = lib_find(ctx->lib, s); - free(s); - return 1; - } - if (sscanf(line, "U %u", &obj->u.comp.unit) == 1) - return 1; - if (sscanf(line, "P %d %d", &obj->x, &obj->y) == 2) - return 1; - if (parse_field(ctx, line)) - return 1; - if (sscanf(line, "AR %n", &n) == 0 && n) - return 1; /* @@@ what is "AR" ? */ - 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) - return 1; - if (n == 4) { - obj->u.comp.m[0] = obj->x; - obj->u.comp.m[3] = obj->y; - return 1; - } - break; - case sch_sheet: - if (sscanf(line, "$EndSheet%n", &n) == 0 && n) { - submit_obj(ctx, sch_obj_sheet); - if (ctx->recurse) - recurse_sheet(ctx); - ctx->state = sch_basic; - return 1; - } - if (sscanf(line, "S %d %d %u %u", - &obj->x, &obj->y, &obj->u.sheet.w, &obj->u.sheet.h) == 4) - return 1; - if (sscanf(line, "U %*x%n", &n) == 0 && n) - return 1; - if (parse_hsheet_field(ctx, line)) - return 1; - break; - case sch_text: - ctx->state = sch_basic; - { - const char *from; - char *to; - - s = alloc_size(strlen(line) + 1); - from = line; - to = s; - while (*from) { - if (from[0] != '\\' || from[1] != 'n') { - *to++ = *from++; - continue; - } - *to++ = '\n'; - from += 2; - } - *to = 0; - obj->u.text.s = s; - submit_obj(ctx, sch_obj_text); - } - return 1; - case sch_wire: - if (sscanf(line, "%d %d %d %d", &obj->x, &obj->y, - &obj->u.wire.ex, &obj->u.wire.ey) != 4) - break; - submit_obj(ctx, sch_obj_wire); - ctx->state = sch_basic; - return 1; - default: - abort(); - } - fprintf(stderr, "%s:%u: cannot parse\n\"%s\"\n", - ctx->file->name, ctx->file->lineno, line); - exit(1); -} - - -void sch_parse(struct sch_ctx *ctx, const char *file, const struct lib *lib) -{ - struct sch_file dsc = { - .name = file, - .lineno = 0, - .parent = NULL, - }; - - ctx->file = &dsc; - ctx->lib = lib; - file_read(file, parse_line, ctx); -} - - -void sch_init(struct sch_ctx *ctx, bool recurse) -{ - ctx->state = sch_descr; - ctx->recurse = recurse; - ctx->sheets = NULL; - ctx->next_sheet = &ctx->sheets; - new_sheet(ctx); -} diff --git a/sch2fig/sch-render.c b/sch2fig/sch-render.c deleted file mode 100644 index b1b9311..0000000 --- a/sch2fig/sch-render.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * sch-render.c - Render schematics - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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. - */ - - -#define _GNU_SOURCE /* for asprintf */ -#include <stdio.h> -#include <assert.h> - -#include "misc.h" -#include "style.h" -#include "gfx.h" -#include "dwg.h" -#include "lib.h" -#include "sch.h" - - -/* ----- Rendering --------------------------------------------------------- */ - - -static void dump_field(const struct comp_field *field, const 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 sheet *sheet) -{ - const struct sch_obj *obj; - - for (obj = sheet->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_render(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; - } -} diff --git a/sch2fig/sch.h b/sch2fig/sch.h deleted file mode 100644 index b1e2d70..0000000 --- a/sch2fig/sch.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * sch.h - Parse Eeschema .sch file - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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 SCH_H -#define SCH_H - -#include <stdbool.h> - -#include "dwg.h" -#include "text.h" -#include "lib.h" - - -enum sch_state { - sch_basic, /* basic state */ - sch_descr, /* prelude and description */ - sch_comp, /* component */ - sch_sheet, /* sub-sheet */ - sch_text, /* text or label */ - 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 sheet { - struct sch_obj *objs; - struct sheet *next; -}; - -struct sch_file { - const char *name; - int lineno; - struct sch_file *parent; -}; - -struct sch_ctx { - enum sch_state state; - - bool recurse; - - struct sch_obj obj; - struct sch_obj **next_obj; - - struct sheet *sheets; - struct sheet **next_sheet; - - const struct lib *lib; - - struct sch_file *file; -}; - - -void decode_alignment(struct text *txt, char hor, char vert); - -void sch_render(const struct sheet *sheet); -void sch_parse(struct sch_ctx *ctx, const char *file, const struct lib *lib); -void sch_init(struct sch_ctx *ctx, bool recurse); - -#endif /* !SCH_H */ diff --git a/sch2fig/sch2pdf b/sch2fig/sch2pdf deleted file mode 100755 index 823ab7e..0000000 --- a/sch2fig/sch2pdf +++ /dev/null @@ -1,92 +0,0 @@ -#!/bin/bash -# -# sch2pdf - Generate PDF from schematics, using sch2fig -# -# Written 2016 by Werner Almesberger -# Copyright 2016 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. -# - -# -# Known bugs: -# - expects first sheet to be index page -# - only renders sub-sheets -# - has all the limitations of sch2fig (see TODO) -# - - -usage() -{ - cat <<EOF 1>&2 -usage: $0 [-n first_num] [-o output.pdf] [-q] [-t template.fig ] - file.lib ... file.sch -EOF - exit 1 -} - - -out=out.pdf -quiet=false -template= -num=1 -while [ "$1" ]; do - case "$1" in - -n) num=$2 - shift 2;; - -o) out=$2 - shift 2;; - -q) quiet=true - shift;; - -t) template="-t $2" - shift 2;; - -*) usage;; - *) break;; - esac -done - -[ "$1" ] || usage - -libs= -while [ "$2" ]; do - libs="$libs $1" - shift -done - -./sch2fig $libs "$1" \ - -- fig $template "TITLE=`basename \"$1\" .sch`" NUMBER=$num | - fig2dev -L pdf >"$out" - -sheet=false -while read line; do - if ! $sheet; then - [ "${line#\$Sheet}" != "$line" ] && sheet=true - continue - else - if [ "${line#\$EndSheet}" != "$line" ]; then - sheet=false - continue - fi - fi - - if [ "${line#F0 \"}" != "$line" ]; then - name=${line#F0 \"} - name=${name%%\"*} - fi - [ "${line#F1 \"}" = "$line" ] && continue - file=${line#F1 \"} - file=${file%%\"*} - - num=`expr $num + 1` - - $quiet || echo "$file" 1>&2 - ./sch2fig $libs `dirname "$1"`/$file \ - -- fig $template "TITLE=$name" NUMBER=$num | - fig2dev -L pdf >_tmp.pdf - pdfunite "$out" _tmp.pdf _tmp2.pdf - mv _tmp2.pdf "$out" -done <"$1" -exit diff --git a/sch2fig/style.c b/sch2fig/style.c deleted file mode 100644 index 7f86798..0000000 --- a/sch2fig/style.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * style.c - Drawing style - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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 <stdint.h> - -#include "style.h" - - -uint32_t color_rgb[] = { - [COLOR_BLACK] = 0x000000, - [COLOR_BLUE] = 0x0000ff, - [COLOR_YELLOW] = 0xffff00, - [COLOR_WHITE] = 0xffffff, - [COLOR_GREEN4] = 0x009000, - [COLOR_CYAN4] = 0x009090, - [COLOR_CYAN3] = 0x00b0b0, - [COLOR_RED4] = 0x900000, - [COLOR_RED3] = 0xb00000, - [COLOR_MAGENTA4] = 0x900090, - [COLOR_BROWN2] = 0xc06000, - [COLOR_DARK_YELLOW] = 0x848400, -}; diff --git a/sch2fig/style.h b/sch2fig/style.h deleted file mode 100644 index 95e5e39..0000000 --- a/sch2fig/style.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * style.h - Drawing style - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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 STYLE_H -#define STYLE_H - -#include <stdint.h> - - -/* FIG colors */ - -#define COLOR_NONE -1 -#define COLOR_BLACK 0 -#define COLOR_BLUE 1 -#define COLOR_YELLOW 6 -#define COLOR_WHITE 7 -#define COLOR_GREEN4 12 -#define COLOR_CYAN4 15 -#define COLOR_CYAN3 16 -#define COLOR_RED4 18 -#define COLOR_RED3 19 -#define COLOR_MAGENTA4 21 -#define COLOR_BROWN2 26 - -#define COLOR_DARK_YELLOW 32 /* user-defined */ - -#define COLOR_COMP_DWG COLOR_RED4 -#define COLOR_COMP_DWG_BG COLOR_YELLOW -#define COLOR_SHEET_DWG COLOR_BLUE -#define COLOR_TEXT COLOR_BLUE -#define COLOR_WIRE COLOR_GREEN4 -#define COLOR_BUS COLOR_BLUE -#define COLOR_NOCONN COLOR_BLUE -#define COLOR_GLABEL COLOR_RED4 -#define COLOR_HLABEL COLOR_DARK_YELLOW -#define COLOR_HSHEET_BOX COLOR_MAGENTA4 -#define COLOR_HSHEET_SHEET COLOR_FIELD -#define COLOR_HSHEET_FILE COLOR_HLABEL -#define COLOR_LABEL COLOR_BLACK -#define COLOR_FIELD COLOR_CYAN4 -#define COLOR_PIN_NAME COLOR_FIELD -#define COLOR_PIN_NUMBER COLOR_RED4 - -#define FONT_HELVETICA_BOLD 18 - -#define LAYER_GLABEL 20 -#define LAYER_HLABEL LAYER_GLABEL -#define LAYER_LABEL LAYER_GLABEL -#define LAYER_TEXT 30 -#define LAYER_NOCONN 40 -#define LAYER_WIRES 50 -#define LAYER_BUSSES LAYER_WIRES -#define LAYER_FIELD 60 -#define LAYER_PIN_NAME LAYER_FIELD -#define LAYER_PIN_NUMBER LAYER_FIELD -#define LAYER_HSHEET_FIELD LAYER_FIELD -#define LAYER_HSHEET_BOX 70 -#define LAYER_LINES 100 -#define LAYER_COMP_DWG 120 -#define LAYER_COMP_DWG_BG 200 - -#define WIDTH_WIRE 2 -#define WIDTH_BUS WIDTH_WIRE -#define WIDTH_LINE 2 -#define WIDTH_COMP_DWG 2 - -#define JUNCTION_R 30 - -#define NOCONN_LEN 25 - -#define LABEL_OFFSET 15 // eeschema has more like 10 -#define GLABEL_OFFSET 20 -#define HLABEL_OFFSET_F 0.4 // * text size -#define PIN_NUM_OFFSET 15 // eeschema has more like 10 -#define HSHEET_FIELD_OFFSET 10 - -#define NEWLINE_SKIP 1.4 // * text size - - -extern uint32_t color_rgb[]; - -#endif /* !STYLE_H */ diff --git a/sch2fig/test.lib b/sch2fig/test.lib deleted file mode 100644 index 7714415..0000000 --- a/sch2fig/test.lib +++ /dev/null @@ -1,62 +0,0 @@ -EESchema-LIBRARY Version 2.3 -#encoding utf-8 -# -# TEST -# -DEF TEST U 0 40 Y Y 1 F N -F0 "U" -475 675 60 H V C CNN -F1 "TEST" -425 -675 60 H V C CNN -F2 "" 150 200 60 H I C CNN -F3 "" 150 200 60 H I C CNN -DRAW -T 900 1050 -550 100 0 0 0 BLT Normal 1 L T -T 0 900 450 100 0 0 0 NCC Normal 0 C C -T 900 925 -550 100 0 0 0 NCC Normal 0 C C -T 0 900 550 100 0 0 0 NLB Normal 0 L B -T 900 1275 -550 100 0 0 0 NRB Normal 0 R B -T 900 800 -550 100 0 0 0 NRC Normal 0 R C -T 0 900 350 100 0 0 0 NRT Normal 0 R T -P 2 0 0 0 750 -550 1325 -550 N -P 2 0 0 0 800 -425 800 -650 N -P 2 0 0 0 925 -425 925 -650 N -P 2 0 0 0 1050 -425 1050 -650 N -P 2 0 0 0 1275 -425 1275 -650 N -A 975 -50 150 1800 -900 0 1 0 N 825 -50 975 -200 -A 975 50 150 1800 900 0 1 0 N 825 50 975 200 -A 1075 -50 150 -900 0 0 1 0 N 1075 -200 1225 -50 -A 1075 50 150 900 0 0 1 0 N 1075 200 1225 50 -C 1025 0 150 0 1 0 N -S -550 600 550 -600 0 1 0 N -P 2 0 1 0 -100 -100 100 100 N -P 2 0 1 0 -100 100 100 -100 N -P 2 0 1 0 825 350 1150 350 N -P 2 0 1 0 825 450 1150 450 N -P 2 0 1 0 825 550 1150 550 N -P 2 0 1 0 900 600 900 275 N -P 3 0 1 0 250 550 450 550 450 400 N -P 10 0 1 0 775 0 775 200 825 250 1225 250 1275 200 1275 -200 1225 -250 825 -250 775 -200 775 0 N -X R_IN 1 -750 500 200 R 50 50 1 1 I -X R_OUT 2 -750 400 200 R 50 50 1 1 O -X R_BIDIR 3 -750 300 200 R 50 50 1 1 O -X R_TRI 4 -750 200 200 R 50 50 1 1 T -X R_PASS 5 -750 100 200 R 50 50 1 1 P -X R_UNSPEC 6 -750 0 200 R 50 50 1 1 U -X R_PIN 7 -750 -100 200 R 50 50 1 1 W -X R_POUT 8 -750 -200 200 R 50 50 1 1 w -X R_OC 9 -750 -300 200 R 50 50 1 1 w -X R_OE 10 -750 -400 200 R 50 50 1 1 w -X D_CLOW 20 0 800 200 D 50 50 1 1 I CL -X R_NC 11 -750 -500 200 R 50 50 1 1 N -X D_ILOW 21 -100 800 200 D 50 50 1 1 I L -X U_LINE 12 -50 -800 200 U 50 50 1 1 I -X U_INV 13 50 -800 200 U 50 50 1 1 I I -X U_CLK 14 150 -800 200 U 50 50 1 1 I C -X U_INVCLK 15 250 -800 200 U 50 50 1 1 I IC -X LEFT 16 750 -325 200 L 50 50 1 1 I -X D_NONLOGIC 17 300 800 200 D 50 50 1 1 I X -X D_FALLING 18 200 800 200 D 50 50 1 1 I F -X D_OLOW 19 100 800 200 D 50 50 1 1 I V -ENDDRAW -ENDDEF -# -#End Library diff --git a/sch2fig/test.pro b/sch2fig/test.pro deleted file mode 100644 index 4695c8c..0000000 --- a/sch2fig/test.pro +++ /dev/null @@ -1,34 +0,0 @@ -update=22/05/2015 07:44:53 -version=1 -last_client=kicad -[general] -version=1 -RootSch= -BoardNm= -[pcbnew] -version=1 -LastNetListRead= -UseCmpFile=1 -PadDrill=0.600000000000 -PadDrillOvalY=0.600000000000 -PadSizeH=1.500000000000 -PadSizeV=1.500000000000 -PcbTextSizeV=1.500000000000 -PcbTextSizeH=1.500000000000 -PcbTextThickness=0.300000000000 -ModuleTextSizeV=1.000000000000 -ModuleTextSizeH=1.000000000000 -ModuleTextSizeThickness=0.150000000000 -SolderMaskClearance=0.000000000000 -SolderMaskMinWidth=0.000000000000 -DrawSegmentWidth=0.200000000000 -BoardOutlineThickness=0.100000000000 -ModuleOutlineThickness=0.150000000000 -[cvpcb] -version=1 -NetIExt=net -[eeschema] -version=1 -LibDir= -[eeschema/libraries] -LibName1=test diff --git a/sch2fig/test.sch b/sch2fig/test.sch deleted file mode 100644 index 11c5613..0000000 --- a/sch2fig/test.sch +++ /dev/null @@ -1,372 +0,0 @@ -EESchema Schematic File Version 2 -LIBS:test -LIBS:test-cache -EELAYER 25 0 -EELAYER END -$Descr A4 11693 8268 -encoding utf-8 -Sheet 1 3 -Title "" -Date "" -Rev "" -Comp "" -Comment1 "" -Comment2 "" -Comment3 "" -Comment4 "" -$EndDescr -Text Notes 1450 1300 0 100 ~ 0 -Text, Right, Normal, 100 mil -Wire Notes Line - 1400 1300 1250 1300 -Wire Notes Line - 1450 1350 1450 1500 -Text Notes 3750 1500 2 100 ~ 20 -Text, Left, Bold, 100 mil -Wire Notes Line - 3800 1500 3950 1500 -Wire Notes Line - 3750 1550 3750 1700 -Text Notes 1050 1550 1 100 Italic 0 -Up, Italic -Wire Notes Line - 1100 1550 1250 1550 -Wire Notes Line - 1050 1600 1050 1750 -Text Notes 4300 700 3 100 Italic 20 -Down, Bold italic -Wire Notes Line - 4350 700 4500 700 -Wire Notes Line - 4300 650 4300 500 -Wire Wire Line - 4800 1100 5300 1100 -Wire Wire Line - 5050 850 5050 1350 -Wire Wire Line - 5550 850 5550 1100 -Wire Wire Line - 5550 1100 5550 1350 -Wire Wire Line - 6050 1100 5550 1100 -Connection ~ 5550 1100 -Wire Bus Line - 6750 600 6750 650 -Wire Bus Line - 6750 650 6750 800 -Wire Bus Line - 6750 800 6750 900 -Wire Bus Line - 6750 900 6750 1000 -Wire Bus Line - 6750 1000 6750 1050 -Wire Bus Line - 6750 1050 6750 1100 -Wire Bus Line - 6750 1100 6750 1250 -Wire Bus Line - 6750 1250 6750 1350 -Wire Bus Line - 6750 1350 6750 1400 -Entry Bus Bus - 6650 1250 6750 1350 -Wire Bus Line - 6200 1250 6650 1250 -Wire Wire Line - 6650 950 6200 950 -Entry Wire Line - 6650 950 6750 1050 -NoConn ~ 5050 850 -NoConn ~ 5050 1350 -NoConn ~ 5300 1100 -NoConn ~ 4800 1100 -Wire Wire Line - 1300 2400 2800 2400 -Text Label 1300 2400 0 60 ~ 0 -LOCAL_RIGHT_NORMAL -Wire Wire Line - 1300 2600 2800 2600 -Text Label 2800 2600 2 60 ~ 12 -LOCAL_LEFT_BOLD -Wire Wire Line - 3400 1800 3400 2900 -Text Label 3400 2900 1 60 ~ 12 -LOCAL_UP_ITALIC -Wire Wire Line - 3700 1800 3700 2900 -Text Label 3700 1800 3 60 Italic 12 -LOCAL_DOWN_BI -Wire Wire Line - 4650 2400 5350 2400 -Wire Wire Line - 4650 2700 5350 2700 -Text GLabel 4650 2400 0 60 Input ~ 0 -G_R_IN -Text GLabel 5350 2700 2 60 Input ~ 0 -G_L_IN -Text GLabel 4650 2700 0 60 Output ~ 0 -G_R_OUT -Text GLabel 5350 2400 2 60 Output ~ 0 -G_L_OUT -Wire Wire Line - 6100 2200 6100 2900 -Wire Wire Line - 6400 2200 6400 2900 -Text GLabel 6100 2200 1 60 BiDi ~ 0 -G_UP_BI -Wire Wire Line - 4650 3000 4850 3000 -Wire Wire Line - 4850 3000 5350 3000 -Text GLabel 4650 3000 0 60 BiDi ~ 0 -G_R_BIDIR -Text GLabel 5350 3000 2 60 UnSpc ~ 0 -G_LEFT_PASS -Text GLabel 4650 3150 0 60 UnSpc ~ 0 -G_R_TRI -Wire Wire Line - 4650 3150 4850 3150 -Wire Wire Line - 4850 3150 4850 3000 -Connection ~ 4850 3000 -Text GLabel 6100 2900 3 60 Input ~ 0 -G_DOWN_IN -Text GLabel 6400 2200 1 60 Output ~ 0 -G_UP_OUT -Text GLabel 6400 2900 3 60 UnSpc ~ 0 -G_DOWN_PASS -Wire Wire Line - 7250 2700 7950 2700 -Wire Wire Line - 8750 2200 8750 2900 -Wire Wire Line - 9050 2200 9050 2900 -Wire Wire Line - 7250 3150 7450 3150 -Wire Wire Line - 7450 3150 7450 3000 -Connection ~ 7450 3000 -Text HLabel 7250 2400 0 60 Input ~ 0 -H_R_IN -Text HLabel 7250 2700 0 60 Output ~ 0 -H_R_OUT -Text HLabel 7250 3000 0 60 BiDi ~ 0 -H_R_BIDIR -Text HLabel 7250 3150 0 60 UnSpc ~ 0 -H_R_TRI -Text HLabel 7950 2400 2 60 Output ~ 0 -H_L_OUT -Text HLabel 7950 2700 2 60 Input ~ 0 -H_L_IN -Wire Wire Line - 7250 2400 7950 2400 -Text HLabel 7950 3000 2 60 UnSpc ~ 0 -H_LEFT_PASS -Text HLabel 8750 2200 1 60 BiDi ~ 0 -H_UP_BI -Text HLabel 8750 2900 3 60 Input ~ 0 -H_DOWN_IN -Text HLabel 9050 2200 1 60 Output ~ 0 -H_UP_OUT -Text HLabel 9050 2900 3 60 UnSpc ~ 0 -H_DOWN_PASS -Wire Wire Line - 7250 3000 7450 3000 -Wire Wire Line - 7450 3000 7950 3000 -Text Notes 1300 3400 0 60 ~ 0 -60 mil Text -Wire Notes Line - 1300 3150 1300 3550 -Wire Notes Line - 1850 3550 1850 3150 -Wire Notes Line - 1150 3300 2000 3300 -Wire Notes Line - 1150 3400 2000 3400 -Text GLabel 1400 3750 2 60 Output ~ 0 -GLOBAL -Text GLabel 1800 3950 0 60 Output ~ 0 -GLOBAL -Wire Notes Line - 1400 3550 1400 4150 -Wire Notes Line - 1800 3550 1800 4150 -Wire Notes Line - 1250 3700 1950 3700 -Wire Notes Line - 1250 3800 1950 3800 -Wire Notes Line - 1250 3900 1950 3900 -Wire Notes Line - 1250 4000 1950 4000 -Text HLabel 2950 3600 0 60 Input ~ 0 -HIERARCHICAL -Text HLabel 2250 3750 2 60 Input ~ 0 -HIERARCHICAL -Wire Notes Line - 2250 3400 2250 3950 -Wire Notes Line - 2100 3700 3100 3700 -Wire Notes Line - 2100 3650 3100 3650 -Wire Notes Line - 2100 3550 3100 3550 -Wire Notes Line - 2100 3800 3100 3800 -Wire Notes Line - 2950 3400 2950 3950 -$Comp -L TEST U? -U 1 1 57933A17 -P 1650 5200 -F 0 "U?" H 1175 5875 60 0000 C CNN -F 1 "TEST" H 1225 4525 60 0000 C CNN -F 2 "" H 1800 5400 60 0001 C CNN -F 3 "" H 1800 5400 60 0001 C CNN - 1 1650 5200 - 1 0 0 -1 -$EndComp -$Comp -L TEST U? -U 1 1 57933A5F -P 4650 4750 -F 0 "U?" H 4175 5425 60 0000 C CNN -F 1 "TEST" H 4225 4075 60 0000 C CNN -F 2 "" H 4800 4950 60 0001 C CNN -F 3 "" H 4800 4950 60 0001 C CNN - 1 4650 4750 - 0 1 1 0 -$EndComp -$Comp -L TEST U? -U 1 1 57933A97 -P 7450 4900 -F 0 "U?" H 6975 5575 60 0000 C CNN -F 1 "TEST" H 7025 4225 60 0000 C CNN -F 2 "" H 7600 5100 60 0001 C CNN -F 3 "" H 7600 5100 60 0001 C CNN - 1 7450 4900 - -1 0 0 1 -$EndComp -$Comp -L TEST U? -U 1 1 57933ACD -P 9750 5250 -F 0 "U?" H 9275 5925 60 0000 C CNN -F 1 "TEST" H 9325 4575 60 0000 C CNN -F 2 "" H 9900 5450 60 0001 C CNN -F 3 "" H 9900 5450 60 0001 C CNN - 1 9750 5250 - 0 -1 -1 0 -$EndComp -$Comp -L TEST U? -U 1 1 57933B03 -P 2450 6950 -F 0 "U?" H 1975 7625 60 0000 C CNN -F 1 "TEST" H 2025 6275 60 0000 C CNN -F 2 "" H 2600 7150 60 0001 C CNN -F 3 "" H 2600 7150 60 0001 C CNN - 1 2450 6950 - 1 0 0 1 -$EndComp -$Comp -L TEST U? -U 1 1 57933B47 -P 5950 6900 -F 0 "U?" H 5475 7575 60 0000 C CNN -F 1 "TEST" H 5525 6225 60 0000 C CNN -F 2 "" H 6100 7100 60 0001 C CNN -F 3 "" H 6100 7100 60 0001 C CNN - 1 5950 6900 - -1 0 0 -1 -$EndComp -Text Notes 900 7000 0 60 ~ 0 -X-flip -Text Notes 4250 6900 0 60 ~ 0 -Y-flip -$Comp -L TEST U? -U 1 1 57933BAB -P 10200 2400 -F 0 "U?" H 9725 3075 60 0000 C CNN -F 1 "TEST" H 9775 1725 60 0000 C CNN -F 2 "" H 10350 2600 60 0001 C CNN -F 3 "" H 10350 2600 60 0001 C CNN - 1 10200 2400 - 0 1 -1 0 -$EndComp -Text Notes 10000 850 0 60 ~ 0 -R+X -$Sheet -S 7250 790 800 560 -U 579BE133 -F0 "Sheet579BE132" 60 -F1 "file579BE132.sch" 60 -$EndSheet -$Sheet -S 7190 1790 770 400 -U 579BE13D -F0 "Sheet579BE13C" 60 -F1 "file579BE13C.sch" 60 -$EndSheet -Wire Bus Line - 6200 1200 6650 1200 -Entry Bus Bus - 6650 1200 6750 1100 -Wire Wire Line - 6650 900 6200 900 -Entry Wire Line - 6650 900 6750 800 -Wire Wire Line - 6850 750 7100 750 -Wire Wire Line - 6850 800 7100 800 -Entry Wire Line - 6750 900 6850 800 -Entry Wire Line - 6750 650 6850 750 -Entry Bus Bus - 6750 1250 6850 1150 -Entry Bus Bus - 6750 1000 6850 1100 -Wire Bus Line - 7100 1100 6850 1100 -Wire Bus Line - 7100 1150 6850 1150 -Wire Bus Line - 4750 1950 5700 1950 -Wire Wire Line - 4850 1850 4850 1500 -Wire Bus Line - 4950 1850 4950 1500 -Wire Wire Line - 5400 1850 5400 1500 -Wire Bus Line - 5500 1500 5500 1850 -Wire Wire Line - 4800 2250 4800 2050 -Wire Wire Line - 5300 2250 5300 2050 -Wire Bus Line - 5450 2250 5450 2050 -Wire Bus Line - 4900 2250 4900 2050 -Entry Wire Line - 4850 1850 4950 1950 -Entry Wire Line - 5200 1950 5300 2050 -Entry Wire Line - 4800 2050 4900 1950 -Entry Wire Line - 5300 1950 5400 1850 -Entry Bus Bus - 4950 1850 5050 1950 -Entry Bus Bus - 4900 2050 5000 1950 -Entry Bus Bus - 5400 1950 5500 1850 -Entry Bus Bus - 5350 1950 5450 2050 -$EndSCHEMATC diff --git a/sch2fig/test/README b/sch2fig/test/README deleted file mode 100644 index fdc81f2..0000000 --- a/sch2fig/test/README +++ /dev/null @@ -1,24 +0,0 @@ -Setup ------ - -git clone https://neo900.org/git/ee.git neo900-ee -cd neo900-ee -git reset --hard 57eebdcf573311c049bc57527bc03a517aff0fef - -cd .. - -git clone git://projects.qi-hardware.com/kicad-libs.git -cd kicad-libs -git reset --hard 143fa7fe10cabbfe1cb12d010c7426d482d7e6f4 - -cd .. - -./genpng ref - - -Run test --------- - -./genpng -./comp -qiv -t _diff*.png diff --git a/sch2fig/test/comp b/sch2fig/test/comp deleted file mode 100755 index b406607..0000000 --- a/sch2fig/test/comp +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/sh - -usage() -{ - echo "usage: $0 [dir]" 1>&2 - exit 1 -} - - -[ "$2" ] && usage -[ "${1#-}" != "$1" ] && usage - -dir=${1:-.} - -diffs=0 -rm -f $dir/_diff*png -for n in $dir/out*.png; do - out=`basename "$n"` - ref=$dir/ref${out#out} - diff=$dir/_diff${out#out} - if ! compare -metric AE $ref $n - >/dev/null; then - diffs=`expr $diffs + 1` - compare -metric AE $ref $n $diff - fi -done -echo -[ $diffs = 0 ] && exit 0 -echo "$diffs difference(s)" 1>&2 -exit 1 diff --git a/sch2fig/test/genpng b/sch2fig/test/genpng deleted file mode 100755 index 77275b9..0000000 --- a/sch2fig/test/genpng +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh - -usage() -{ - echo "usage: $0 [[dir] prefix]" 1>&2 - exit 1 -} - - -[ "$3" ] && usage -[ "${1#-}" != "$1" ] && usage - -dir=. -if [ "$2" ]; then - dir=$1 - shift -fi -prefix=${1:-out} - -sheet=1 -while [ $sheet -le 38 ]; do - echo -n . - sn=`printf '%02d' $sheet` - file=$dir/$prefix$sn.png - if [ $sheet = 1 ]; then - in=$dir/neo900-ee/hw/neo900.sch - else - in=$dir/neo900-ee/hw/neo900_SS_`expr $sheet - 1`.sch - fi - file=$dir/$prefix$sn.png - $dir/../sch2fig $dir/neo900-ee/hw/neo900.lib \ - $dir/kicad-libs/components/powered.lib "$in" \ - -- fig -t $dir/frame.fig SHEET=$sn | - fig2dev -L png -m 2 >$file - sheet=`expr $sheet + 1` -done -echo diff --git a/sch2fig/text.c b/sch2fig/text.c deleted file mode 100644 index 68754c8..0000000 --- a/sch2fig/text.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * text.c - FIG text object - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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 <stddef.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#include "util.h" -#include "misc.h" -#include "style.h" -#include "gfx.h" -#include "text.h" - - -void text_init(struct text *txt) -{ - txt->s = NULL; - txt->size = 0; - txt->x = txt->y = 0; - txt->rot = 0; - txt->hor = text_mid; - txt->vert = text_mid; -} - - -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 = stralloc(s); -} - - -void text_rot(struct text *txt, int deg) -{ - txt->rot = angle_add(txt->rot, deg); -} - - -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_min; - default: - abort(); - } -} - - -void text_flip_x(struct text *txt) -{ - txt->rot = angle_add(txt->rot, 180); - txt->hor = text_flip(txt->hor); - // @@@ flip vert, too ? -} - - -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) -{ - char *buf = stralloc(txt->s); - char *tmp = buf; - const char *s; - int x = txt->x; - int y = txt->y; - - x += rx(0, align(txt->size, txt->vert), txt->rot); - y += ry(0, align(txt->size, txt->vert), txt->rot); - while (1) { - s = strtok(tmp, "\n"); - if (!s) - break; - tmp = NULL; - gfx_text(x, y, s, txt->size, txt->hor, txt->rot, color, layer); - x += rx(0, NEWLINE_SKIP * txt->size, txt->rot); - y += ry(0, NEWLINE_SKIP * txt->size, txt->rot); - } - free(buf); -} - - -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) -{ - int width = gfx_text_width(txt->s, txt->size); - - dx -= align(width, txt->hor); - dy += align(txt->size, txt->vert); - dx += align(width, 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 deleted file mode 100644 index 05f1ffb..0000000 --- a/sch2fig/text.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * text.h - FIG text object - * - * Written 2016 by Werner Almesberger - * Copyright 2016 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 TEXT_H -#define TEXT_H - - -/* use constants of FIG text sub_type */ - -enum text_align { - text_min = 0, // left or bottom - text_mid = 1, // center - text_max = 2, // right or top -}; - -enum text_style { - text_normal, -}; - -struct text { - const char *s; - int size; - int x, y; - int rot; - enum text_align hor; - enum text_align vert; -}; - -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); -void text_flip_x(struct text *txt); -enum text_align text_flip(enum text_align align); - -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 deleted file mode 100644 index ea40ce5..0000000 --- a/sch2fig/util.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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 <stdio.h> -#include <stdlib.h> -#include <string.h> - - -#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 ARRAY_ELEMENTS(a) (sizeof(a) / sizeof(a[0])) -#define ARRAY_END(a) ((a) + ARRAY_ELEMENTS(a)) - - -#define swap(a, b) \ - ({ typeof(a) _tmp = (a); a = (b); b = _tmp; }) - - -#define unsupported(s) \ - fprintf(stderr, __FILE__ ":%d: unsupported: " s "\n", __LINE__) - -#endif /* !UTIL_H */