From 93537be3964b8f38d69cf6cadca27d485344511d Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Mon, 1 Aug 2016 00:37:32 -0300 Subject: [PATCH] sch2fig/: add Cairo PDF driver --- sch2fig/cairo.c | 97 +++++++++++++++++++++++++++++++++++++++++++------ sch2fig/cairo.h | 3 +- sch2fig/main.c | 5 ++- 3 files changed, 91 insertions(+), 14 deletions(-) diff --git a/sch2fig/cairo.c b/sch2fig/cairo.c index dc051fa..023cefd 100644 --- a/sch2fig/cairo.c +++ b/sch2fig/cairo.c @@ -18,6 +18,7 @@ #include #include +#include #include "util.h" #include "style.h" @@ -220,7 +221,7 @@ static const struct gfx_ops real_cairo_ops = { }; -static void *cr_init(int argc, char *const *argv) +static struct cairo_ctx *init_common(int argc, char *const *argv) { struct cairo_ctx *cc; char c; @@ -244,6 +245,16 @@ static void *cr_init(int argc, char *const *argv) layer_init(&cc->layer, &real_cairo_ops, cc); + return cc; +} + + +static void *cr_png_init(int argc, char *const *argv) +{ + struct cairo_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); @@ -253,22 +264,45 @@ static void *cr_init(int argc, char *const *argv) } -static void cr_end(void *ctx) +static void *cr_pdf_init(int argc, char *const *argv) { - struct cairo_ctx *cc = ctx; - int x, y, w, h; + struct cairo_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 cairo_ctx *cc, int *w, int *h) +{ + int x, y; cairo_surface_destroy(cc->s); cairo_destroy(cc->cr); - layer_bbox(&cc->layer, &x, &y, &w, &h); + layer_bbox(&cc->layer, &x, &y, w, h); -// fprintf(stderr, "%dx%d%+d%+d\n", w, h, x, y); +// 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); + *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 cairo_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); @@ -288,10 +322,37 @@ static void cr_end(void *ctx) } +static void cr_pdf_end(void *ctx) +{ + struct cairo_ctx *cc = ctx; + int w, h; + + 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); + + layer_replay(&cc->layer); + layer_destroy(&cc->layer); + + cairo_show_page(cc->cr); + + cairo_surface_destroy(cc->s); + cairo_destroy(cc->cr); +} + + /* ----- Operations -------------------------------------------------------- */ -const struct gfx_ops cairo_ops = { +const struct gfx_ops cairo_png_ops = { .name = "png", // .line = cr_line, @@@ later .poly = layer_poly, @@ -299,6 +360,18 @@ const struct gfx_ops cairo_ops = { .arc = layer_arc, .text = layer_text, .text_width = cr_text_width, - .init = cr_init, - .end = cr_end, + .init = cr_png_init, + .end = cr_png_end, +}; + +const struct gfx_ops cairo_pdf_ops = { + .name = "pdf", + // .line = cr_line, @@@ later + .poly = layer_poly, + .circ = layer_circ, + .arc = layer_arc, + .text = layer_text, + .text_width = cr_text_width, + .init = cr_pdf_init, + .end = cr_pdf_end, }; diff --git a/sch2fig/cairo.h b/sch2fig/cairo.h index 5b38783..93af9e3 100644 --- a/sch2fig/cairo.h +++ b/sch2fig/cairo.h @@ -17,6 +17,7 @@ #include "gfx.h" -extern const struct gfx_ops cairo_ops; +extern const struct gfx_ops cairo_png_ops; +extern const struct gfx_ops cairo_pdf_ops; #endif /* !CAIRO_H */ diff --git a/sch2fig/main.c b/sch2fig/main.c index 0ba4cb5..8831595 100644 --- a/sch2fig/main.c +++ b/sch2fig/main.c @@ -29,7 +29,8 @@ static struct gfx_ops const *ops_list[] = { &fig_ops, - &cairo_ops, + &cairo_png_ops, + &cairo_pdf_ops, }; @@ -47,6 +48,8 @@ void usage(const char *name) " fig [-t template.fig] [var=value ...]\n" " Cairo PNG driver spec:\n" " png [-o output.png] [-s scale]\n" +" Cairo PDF driver spec:\n" +" pdf [-o output.pdf] [-s scale]\n" , name); exit(1); }