From 55f10b87696cd22d42d30f41f1099dda1572b584 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Mon, 1 Aug 2016 01:34:27 -0300 Subject: [PATCH] sch2fig/: support multi-page PDF --- sch2fig/TODO | 1 - sch2fig/cairo.c | 37 ++++++++++++++++++++++++++++++++++--- sch2fig/layer.c | 6 ++++++ sch2fig/layer.h | 1 + 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/sch2fig/TODO b/sch2fig/TODO index c2d1725..0697dd1 100644 --- a/sch2fig/TODO +++ b/sch2fig/TODO @@ -14,7 +14,6 @@ - PDF TOC - let user set PNG size or zoom level - implement dashed lines in cairo.c -- implement multi-page PDF output in cairo.o - use correct color for hierarchical items, 0x848400 (or close) instead of COLOR_BROWN2 - directly pick versions out of git, without requiring checkout to file diff --git a/sch2fig/cairo.c b/sch2fig/cairo.c index 023cefd..536e357 100644 --- a/sch2fig/cairo.c +++ b/sch2fig/cairo.c @@ -11,6 +11,7 @@ */ +#include #include #include #include @@ -47,6 +48,9 @@ struct cairo_ctx { cairo_t *cr; cairo_surface_t *s; + struct layer *sheets; /* for PDF */ + unsigned n_sheets; + const char *output_name; }; @@ -230,6 +234,9 @@ static struct cairo_ctx *init_common(int argc, char *const *argv) 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) { @@ -322,23 +329,46 @@ static void cr_png_end(void *ctx) } +static void cr_pdf_new_sheet(void *ctx) +{ + struct cairo_ctx *cc = ctx; + + cc->n_sheets++; + cc->sheets = realloc(cc->sheets, sizeof(struct layer) * cc->n_sheets); + if (!cc->sheets) { + perror("realloc"); + exit(1); + } + cc->sheets[cc->n_sheets - 1] = cc->layer; + layer_wipe(&cc->layer); +} + + static void cr_pdf_end(void *ctx) { struct cairo_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); - 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, 3); + for (i = 0; i != cc->n_sheets; i++) { + set_color(cc->cr, COLOR_WHITE); + cairo_paint(cc->cr); + + layer_replay(cc->sheets + i); + layer_destroy(cc->sheets + i); + + cairo_show_page(cc->cr); + } + layer_replay(&cc->layer); layer_destroy(&cc->layer); @@ -373,5 +403,6 @@ const struct gfx_ops cairo_pdf_ops = { .text = layer_text, .text_width = cr_text_width, .init = cr_pdf_init, + .new_sheet = cr_pdf_new_sheet, .end = cr_pdf_end, }; diff --git a/sch2fig/layer.c b/sch2fig/layer.c index 73c2c06..7b3eb6c 100644 --- a/sch2fig/layer.c +++ b/sch2fig/layer.c @@ -234,6 +234,12 @@ void layer_init(struct layer *layer, const struct gfx_ops *ops, void *user) } +void layer_wipe(struct layer *layer) +{ + layer->objs = NULL; +} + + void layer_replay(const struct layer *layer) { const struct gfx_ops *ops = layer->ops; diff --git a/sch2fig/layer.h b/sch2fig/layer.h index 7a8cea7..e7caae4 100644 --- a/sch2fig/layer.h +++ b/sch2fig/layer.h @@ -49,6 +49,7 @@ void layer_text(void *ctx, int x, int y, const char *s, unsigned size, enum text_align align, int rot, unsigned color, unsigned layer); void layer_init(struct layer *layer, const struct gfx_ops *ops, void *user); +void layer_wipe(struct layer *layer); void layer_replay(const struct layer *layer); void layer_bbox(const struct layer *layer, int *x, int *y, int *w, int *h); void layer_destroy(struct layer *layer);