From 50242899d3c245c65107f96d0fae9caed2fc9135 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Sun, 31 Jul 2016 00:04:43 -0300 Subject: [PATCH] sch2fig/: add Cairo (PNG) back-end (WIP) --- sch2fig/Makefile | 7 +- sch2fig/cairo.c | 190 +++++++++++++++++++++++++++++++++++++++++++++++ sch2fig/cairo.h | 22 ++++++ sch2fig/main.c | 4 +- 4 files changed, 219 insertions(+), 4 deletions(-) create mode 100644 sch2fig/cairo.c create mode 100644 sch2fig/cairo.h diff --git a/sch2fig/Makefile b/sch2fig/Makefile index 2bff7a7..0101b08 100644 --- a/sch2fig/Makefile +++ b/sch2fig/Makefile @@ -11,10 +11,11 @@ # NAME = sch2fig -OBJS = main.o sch.o lib.o style.o fig.o gfx.o dwg.o text.o misc.o +OBJS = main.o sch.o lib.o style.o fig.o cairo.o gfx.o dwg.o text.o misc.o -CFLAGS = -g -O -Wall -Wextra -Wno-unused-parameter -Wshadow -LIBS = -lm +CFLAGS = -g -O -Wall -Wextra -Wno-unused-parameter -Wshadow \ + `pkg-config --cflags cairo` +LIBS = -lm `pkg-config --libs cairo` include ../common/Makefile.c-common diff --git a/sch2fig/cairo.c b/sch2fig/cairo.c new file mode 100644 index 0000000..c2caac6 --- /dev/null +++ b/sch2fig/cairo.c @@ -0,0 +1,190 @@ +/* + * cairo.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 "util.h" +#include "style.h" +#include "gfx.h" +#include "cairo.h" + +#if 0 +#include +#include +#include + +#include "util.h" +#include "style.h" +#include "text.h" +#include "fig.h" +#endif + + +struct cairo_ctx { + cairo_t *cr; + cairo_surface_t *s; +}; + +/* + * FIG works with 1/1200 in + * KiCad works with mil + * 1 point = 1/72 in + */ + + +static inline int cx(int x) +{ + return x / 5; +} + + +static inline int cy(int y) +{ + return y / 5; +} + + +static inline float pt(int x) +{ + return cx(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 ----------------------------------------------------- */ + + +void cr_poly(void *ctx, int points, int x[points], int y[points], + int color, int fill_color, unsigned layer) +{ + struct cairo_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(x[0]), cy(y[0])); + + for (i = 1; i != points - closed; i++) + cairo_line_to(cc->cr, cx(x[i]), cy(y[i])); + if (closed) + cairo_close_path(cc->cr); + + paint(cc->cr, color, fill_color); +} + + +void cr_circ(void *ctx, int x, int y, int r, + int color, int fill_color, unsigned layer) +{ + struct cairo_ctx *cc = ctx; + + cairo_new_path(cc->cr); + cairo_arc(cc->cr, cx(x), cy(y), cx(r), 0, 2 * M_PI); + paint(cc->cr, color, fill_color); +} + + +void cr_arc(void *ctx, int x, int y, int r, int sa, int ea, + int color, int fill_color, unsigned layer) +{ + struct cairo_ctx *cc = ctx; + + cairo_new_path(cc->cr); + cairo_arc(cc->cr, cx(x), cy(y), cx(r), + -ea / 180.0 * M_PI, -sa / 180.0 * M_PI); + paint(cc->cr, color, fill_color); +} + + +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 cairo_ctx *cc = ctx; +} + + +/* ----- Initializatio and termination ------------------------------------- */ + + +void *cr_init(const char *template, int n_vars, const char **vars) +{ + struct cairo_ctx *cc; + + cc = alloc_type(struct cairo_ctx); + cc->s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 2000, 1414); + cc->cr = cairo_create(cc->s); + set_color(cc->cr, COLOR_WHITE); + cairo_paint(cc->cr); + + cairo_set_line_width(cc->cr, 3); + + return cc; +} + + +void cr_end(void *ctx) +{ + struct cairo_ctx *cc = ctx; + + cairo_surface_write_to_png(cc->s, "test.png"); + cairo_surface_destroy(cc->s); +} + + +/* ----- Operations -------------------------------------------------------- */ + + +const struct gfx_ops cairo_ops = { + // .line = cr_line, @@@ later + .poly = cr_poly, + .circ = cr_circ, + .arc = cr_arc, + .text = cr_text, + .init = cr_init, + .end = cr_end, +}; diff --git a/sch2fig/cairo.h b/sch2fig/cairo.h new file mode 100644 index 0000000..5b38783 --- /dev/null +++ b/sch2fig/cairo.h @@ -0,0 +1,22 @@ +/* + * cairo.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 CAIRO_H +#define CAIRO_H + +#include "gfx.h" + + +extern const struct gfx_ops cairo_ops; + +#endif /* !CAIRO_H */ diff --git a/sch2fig/main.c b/sch2fig/main.c index 2d96c9f..6467ad0 100644 --- a/sch2fig/main.c +++ b/sch2fig/main.c @@ -17,6 +17,7 @@ #include #include "fig.h" +#include "cairo.h" #include "gfx.h" #include "lib.h" #include "sch.h" @@ -93,7 +94,8 @@ int main(int argc, char **argv) if (argc - optind < 1) usage(*argv); - gfx_init(&fig_ops, template, n_vars, vars); + //gfx_init(&fig_ops, template, n_vars, vars); + gfx_init(&cairo_ops, template, n_vars, vars); for (arg = optind; arg != argc; arg++) { if (arg == argc - 1) { struct sch_ctx ctx;