summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gfx/cro.c41
-rw-r--r--gfx/diff.c38
-rw-r--r--gfx/fig.c14
-rw-r--r--gfx/gfx.c11
-rw-r--r--gfx/gfx.h7
-rw-r--r--gfx/pdftoc.c54
-rw-r--r--gfx/pdftoc.h3
-rw-r--r--gui/index.c4
-rw-r--r--gui/render.c6
-rw-r--r--main.c4
10 files changed, 115 insertions, 67 deletions
diff --git a/gfx/cro.c b/gfx/cro.c
index 5ac56bd..3e713a6 100644
--- a/gfx/cro.c
+++ b/gfx/cro.c
@@ -46,7 +46,7 @@ struct cro_ctx {
struct record record; /* must be first */
int xo, yo; /* offset in target (e.g., canvas) coord */
- float scale;
+ float scale, default_scale;
cairo_t *cr;
cairo_surface_t *s;
@@ -268,7 +268,7 @@ static struct cro_ctx *new_cc(void)
cc = alloc_type(struct cro_ctx);
cc->xo = cc->yo = 0;
- cc->scale = DEFAULT_SCALE;
+ cc->scale = cc->default_scale = DEFAULT_SCALE;
cc->sheets = NULL;
cc->n_sheets = 0;
@@ -289,9 +289,9 @@ static struct cro_ctx *new_cc(void)
}
-static struct cro_ctx *init_common(int argc, char *const *argv)
+static bool cr_args(void *ctx, int argc, char *const *argv)
{
- struct cro_ctx *cc = new_cc();
+ struct cro_ctx *cc = ctx;
char c;
while ((c = getopt(argc, argv, "o:s:T")) != EOF)
@@ -300,7 +300,7 @@ static struct cro_ctx *init_common(int argc, char *const *argv)
cc->output_name = optarg;
break;
case 's':
- cc->scale = atof(optarg) * DEFAULT_SCALE;
+ cc->scale = atof(optarg) * cc->default_scale;
break;
case 'T':
cc->add_toc = 0;
@@ -309,7 +309,7 @@ static struct cro_ctx *init_common(int argc, char *const *argv)
usage(*argv);
}
- return cc;
+ return 1;
}
@@ -375,13 +375,12 @@ static cairo_status_t stream_to_pdftoc(void *closure,
}
-static void *cr_pdf_init(int argc, char *const *argv)
+static void *cr_pdf_init(void)
{
- struct cro_ctx *cc;
-
- cc = init_common(argc, argv);
+ struct cro_ctx *cc = new_cc();
cc->scale *= 16;
+ cc->default_scale *= 16;
/* cr_text_width needs *something* to work with */
@@ -389,12 +388,24 @@ static void *cr_pdf_init(int argc, char *const *argv)
cc->cr = cairo_create(cc->s);
if (cc->add_toc)
- cc->toc = pdftoc_begin(cc->output_name);
+ cc->toc = pdftoc_begin();
return cc;
}
+static bool cr_pdf_args(void *ctx, int argc, char *const *argv)
+{
+ struct cro_ctx *cc = ctx;
+
+ if (!cr_args(cc, argc, argv))
+ return 0;
+ if (cc->add_toc && cc->output_name)
+ return pdftoc_set_file(cc->toc, cc->output_name);
+ return 1;
+}
+
+
static void cr_pdf_sheet_name(void *ctx, const char *name)
{
struct cro_ctx *cc = ctx;
@@ -469,11 +480,9 @@ static void cr_pdf_end(void *ctx)
/* ----- PNG (auto-sizing, using redraw) ----------------------------------- */
-static void *cr_png_init(int argc, char *const *argv)
+static void *cr_png_init(void)
{
- struct cro_ctx *cc;
-
- cc = init_common(argc, argv);
+ struct cro_ctx *cc = new_cc();
/* cr_text_width needs *something* to work with */
@@ -644,6 +653,7 @@ const struct gfx_ops cro_png_ops = {
.text = record_text,
.text_width = cr_text_width,
.init = cr_png_init,
+ .args = cr_args,
.end = cr_png_end,
};
@@ -656,6 +666,7 @@ const struct gfx_ops cro_pdf_ops = {
.text = record_text,
.text_width = cr_text_width,
.init = cr_pdf_init,
+ .args = cr_pdf_args,
.sheet_name = cr_pdf_sheet_name,
.new_sheet = cr_pdf_new_sheet,
.end = cr_pdf_end,
diff --git a/gfx/diff.c b/gfx/diff.c
index 24b2540..46d2669 100644
--- a/gfx/diff.c
+++ b/gfx/diff.c
@@ -16,6 +16,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
+#include <assert.h>
#include <cairo/cairo.h>
@@ -118,23 +119,33 @@ static unsigned diff_text_width(void *ctx, const char *s, unsigned size)
/* ----- Initialization ---------------------------------------------------- */
-static void *diff_init(int argc, char *const *argv)
+static void *diff_init(void)
{
struct diff *diff;
+
+ diff = alloc_type(struct diff);
+ diff->areas = NULL;
+
+ diff->output_name = NULL;
+ diff->frame_radius = DEFAULT_FRAME_RADIUS;
+ diff->gfx = NULL;
+
+ return diff;
+}
+
+
+static bool diff_args(void *ctx, int argc, char *const *argv)
+{
+ struct diff *diff = ctx;
char c;
int arg;
struct sch_ctx new_sch;
struct file sch_file;
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':
@@ -160,24 +171,27 @@ static void *diff_init(int argc, char *const *argv)
file_close(&sch_file);
optind = 0;
- diff->gfx = gfx_init(&cro_img_ops, argc, argv);
+ diff->gfx = gfx_init(&cro_img_ops);
+ if (!gfx_args(diff->gfx, argc, argv))
+ goto fail_open;
sch_render(new_sch.sheets, diff->gfx);
diff->new_img = cro_img_end(gfx_user(diff->gfx),
&diff->w, &diff->h, &diff->stride);
optind = 0;
- diff->gfx = gfx_init(&cro_img_ops, argc, argv);
+ diff->gfx = gfx_init(&cro_img_ops);
+ if (!gfx_args(diff->gfx, argc, argv))
+ goto fail_open;
//diff->gfx = cro_img_ops.init(argc, argv);
- return diff;
+ return 1;
fail_parse:
file_close(&sch_file);
fail_open:
sch_free(&new_sch);
lib_free(&new_lib);
- free(diff);
- return NULL;
+ return 0;
}
@@ -307,6 +321,7 @@ static void diff_end(void *ctx)
uint32_t *old_img;
int w, h, stride;
+ assert(diff->gfx);
old_img = cro_img_end(gfx_user(diff->gfx), &w, &h, &stride);
if (diff->w != w || diff->h != h)
fatal("%d x %d vs. %d x %d image\n", w, h, diff->w, diff->h);
@@ -415,5 +430,6 @@ const struct gfx_ops diff_ops = {
.text = diff_text,
.text_width = diff_text_width,
.init = diff_init,
+ .args = diff_args,
.end = diff_end,
};
diff --git a/gfx/fig.c b/gfx/fig.c
index 41d4933..d469a28 100644
--- a/gfx/fig.c
+++ b/gfx/fig.c
@@ -237,7 +237,14 @@ static bool apply_vars(char *buf, int n_vars, const char **vars)
-static void *fig_init(int argc, char *const *argv)
+static void *fig_init(void)
+{
+ /* @@@ this is asking for trouble ... */
+ return NULL;
+}
+
+
+static bool fig_args(void *ctx, int argc, char *const *argv)
{
static char *buf = NULL;
static size_t n = 0;
@@ -269,7 +276,7 @@ static void *fig_init(int argc, char *const *argv)
if (!template) {
fig_header();
fig_colors();
- return NULL;
+ return 1;
}
file = fopen(template, "r");
@@ -289,7 +296,7 @@ static void *fig_init(int argc, char *const *argv)
}
fclose(file);
- return NULL;
+ return 1;
}
@@ -307,4 +314,5 @@ const struct gfx_ops fig_ops = {
.tag = fig_tag,
.text_width = fig_text_width,
.init = fig_init,
+ .args = fig_args,
};
diff --git a/gfx/gfx.c b/gfx/gfx.c
index 0324cfd..4d79851 100644
--- a/gfx/gfx.c
+++ b/gfx/gfx.c
@@ -100,18 +100,23 @@ unsigned gfx_text_width(struct gfx *gfx, const char *s, unsigned size)
}
-struct gfx *gfx_init(const struct gfx_ops *ops,
- int argc, char *const *argv)
+struct gfx *gfx_init(const struct gfx_ops *ops)
{
struct gfx *new;
new = alloc_type(struct gfx);
- new->user = ops->init(argc, argv);
+ new->user = ops->init();
new->ops = ops;
return new;
}
+bool gfx_args(struct gfx *gfx, int argc, char *const *argv)
+{
+ return gfx->ops->args && gfx->ops->args(gfx->user, argc, argv);
+}
+
+
void gfx_sheet_name(struct gfx *gfx, const char *name)
{
if (gfx->ops->sheet_name)
diff --git a/gfx/gfx.h b/gfx/gfx.h
index c31495b..330a2fb 100644
--- a/gfx/gfx.h
+++ b/gfx/gfx.h
@@ -39,7 +39,8 @@ struct gfx_ops {
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 *(*init)(void);
+ bool (*args)(void *ctx, int argc, char *const *argv);
void (*sheet_name)(void *ctx, const char *name);
void (*new_sheet)(void *ctx);
void (*end)(void *ctx);
@@ -67,8 +68,8 @@ unsigned gfx_text_width(struct gfx *gfx, const char *s, unsigned size);
/* inititalization and termination */
-struct gfx *gfx_init(const struct gfx_ops *ops,
- int argc, char *const *argv);
+struct gfx *gfx_init(const struct gfx_ops *ops);
+bool gfx_args(struct gfx *gfx, int argc, char *const *argv);
void gfx_sheet_name(struct gfx *gfx, const char *name);
void gfx_new_sheet(struct gfx *gfx);
bool gfx_multi_sheet(struct gfx *gfx);
diff --git a/gfx/pdftoc.c b/gfx/pdftoc.c
index 39d59bd..1e6242a 100644
--- a/gfx/pdftoc.c
+++ b/gfx/pdftoc.c
@@ -41,7 +41,7 @@ struct object {
};
struct pdftoc {
- FILE *file;
+ FILE *file; /* NULL if not set / stdout */
enum state {
idle, /* between objects */
@@ -69,19 +69,12 @@ struct pdftoc {
};
-struct pdftoc *pdftoc_begin(const char *file)
+struct pdftoc *pdftoc_begin(void)
{
struct pdftoc *ctx;
ctx = alloc_type(struct pdftoc);
- if (file) {
- ctx->file = fopen(file, "w");
- if (!ctx->file)
- diag_pfatal(file);
- } else {
- ctx->file = stdout;
- }
-
+ ctx->file = NULL;
ctx->state = idle;
ctx->titles = NULL;
@@ -103,6 +96,17 @@ struct pdftoc *pdftoc_begin(const char *file)
}
+bool pdftoc_set_file(struct pdftoc *ctx, const char *file)
+{
+ assert(!ctx->file);
+ ctx->file = fopen(file, "w");
+ if (ctx->file)
+ return 1;
+ diag_perror(file);
+ return 0;
+}
+
+
static void add_object(struct pdftoc *ctx, int id, int gen, unsigned pos)
{
struct object *obj;
@@ -136,6 +140,7 @@ static bool parse_object(struct pdftoc *ctx, const char *s)
static void line(struct pdftoc *ctx, const char *s)
{
+ FILE *file = ctx->file ? ctx->file : stdout;
switch (ctx->state) {
case idle:
@@ -166,7 +171,7 @@ static void line(struct pdftoc *ctx, const char *s)
case catalog:
if (strbegins(s, ">>")) {
ctx->state = object;
- ctx->pos += fprintf(ctx->file,
+ ctx->pos += fprintf(file,
" /Outlines %u 0 R\n",
ctx->top + 1);
break;
@@ -188,6 +193,7 @@ static void line(struct pdftoc *ctx, const char *s)
static void parse_buffer(struct pdftoc *ctx, bool do_write)
{
+ FILE *file = ctx->file ? ctx->file : stdout;
unsigned size, wrote;
char *nl;
@@ -203,7 +209,7 @@ static void parse_buffer(struct pdftoc *ctx, bool do_write)
break;
if (do_write) {
wrote = fwrite(ctx->buf + ctx->offset, 1, size + 1,
- ctx->file);
+ file);
if (wrote != size + 1)
diag_pfatal("fwrite");
ctx->pos += size + 1;
@@ -247,6 +253,7 @@ void pdftoc_title(struct pdftoc *ctx, const char *title)
static void write_trailer(struct pdftoc *ctx)
{
+ FILE *file = ctx->file ? ctx->file : stdout;
unsigned n = ctx->top + 1;
const struct object *obj = ctx->objs;
const struct title *t;
@@ -257,7 +264,7 @@ static void write_trailer(struct pdftoc *ctx)
outline = n;
add_object(ctx, n, 0, ctx->pos);
- tail = fprintf(ctx->file,
+ tail = fprintf(file,
"%u 0 obj\n<<\n"
" /Count %u\n"
" /First %u 0 R\n"
@@ -276,18 +283,18 @@ static void write_trailer(struct pdftoc *ctx)
assert(i <= ctx->top);
}
add_object(ctx, n, 0, ctx->pos + tail);
- tail += fprintf(ctx->file,
+ tail += fprintf(file,
"%u 0 obj\n<<\n"
" /Title (%s)\n"
" /Parent %u 0 R\n",
n, t->s, outline);
if (t != ctx->titles)
- tail += fprintf(ctx->file,
+ tail += fprintf(file,
" /Prev %u 0 R\n", n - 1);
if (t->next)
- tail += fprintf(ctx->file,
+ tail += fprintf(file,
" /Next %u 0 R\n", n + 1);
- tail += fprintf(ctx->file,
+ tail += fprintf(file,
" /Dest [%d %u R /Fit]\n"
">>\nendobj\n",
i, ctx->objs[i].gen);
@@ -297,25 +304,26 @@ static void write_trailer(struct pdftoc *ctx)
/* xref table */
- fprintf(ctx->file, "xref\n0 %u\n", n);
+ fprintf(file, "xref\n0 %u\n", n);
for (obj = ctx->objs; obj != ctx->objs + ctx->top + 1; obj++)
- fprintf(ctx->file,
+ fprintf(file,
"%010u %05u %c \n",
obj->pos, obj->pos ? 0 : 65535, obj->pos ? 'n' : 'f');
- fprintf(ctx->file,
+ fprintf(file,
"trailer\n"
"<< /Size %u\n"
" /Root %u 0 R\n",
n, ctx->root);
if (ctx->info)
- fprintf(ctx->file, " /Info %u 0 R\n", ctx->info);
- fprintf(ctx->file, ">>\nstartxref\n%u\n%%%%EOF\n", ctx->pos + tail);
+ fprintf(file, " /Info %u 0 R\n", ctx->info);
+ fprintf(file, ">>\nstartxref\n%u\n%%%%EOF\n", ctx->pos + tail);
}
void pdftoc_end(struct pdftoc *ctx)
{
+ FILE *file = ctx->file ? ctx->file : stdout;
struct title *next;
assert(ctx->state == xref);
@@ -328,7 +336,7 @@ void pdftoc_end(struct pdftoc *ctx)
write_trailer(ctx);
- if (fclose(ctx->file) < 0)
+ if (fclose(file) < 0)
diag_pfatal("fclose");
while (ctx->titles) {
diff --git a/gfx/pdftoc.h b/gfx/pdftoc.h
index 8ccdbe5..aabc8ef 100644
--- a/gfx/pdftoc.h
+++ b/gfx/pdftoc.h
@@ -19,7 +19,8 @@
struct pdftoc;
-struct pdftoc *pdftoc_begin(const char *file);
+struct pdftoc *pdftoc_begin(void);
+bool pdftoc_set_file(struct pdftoc *ctx, const char *file);
bool pdftoc_write(struct pdftoc *ctx, const void *data, unsigned length);
void pdftoc_title(struct pdftoc *ctx, const char *title);
void pdftoc_end(struct pdftoc *ctx);
diff --git a/gui/index.c b/gui/index.c
index 8a6e4b5..f9ecc70 100644
--- a/gui/index.c
+++ b/gui/index.c
@@ -267,9 +267,7 @@ static void index_render_sheet(const struct gui_ctx *ctx,
int stride;
if (!sheet->gfx_thumb) {
- char *argv[] = { "index", NULL };
-
- sheet->gfx_thumb = gfx_init(&cro_canvas_ops, 1, argv);
+ sheet->gfx_thumb = gfx_init(&cro_canvas_ops);
sch_render(sheet->sch, sheet->gfx_thumb);
cro_canvas_end(gfx_user(sheet->gfx_thumb),
NULL, NULL, NULL, NULL);
diff --git a/gui/render.c b/gui/render.c
index a5eb8e4..2411fd6 100644
--- a/gui/render.c
+++ b/gui/render.c
@@ -250,9 +250,7 @@ static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr,
void render_sheet(struct gui_sheet *sheet)
{
- char *argv[] = { "gui", NULL };
-
- sheet->gfx = gfx_init(&cro_canvas_ops, 1, argv);
+ sheet->gfx = gfx_init(&cro_canvas_ops);
if (sheet->hist && sheet->hist->pl) /* @@@ no pl_render for delta */
pl_render(sheet->hist->pl, sheet->gfx,
sheet->hist->sch_ctx.sheets, sheet->sch);
@@ -260,7 +258,7 @@ void render_sheet(struct gui_sheet *sheet)
cro_canvas_end(gfx_user(sheet->gfx),
&sheet->w, &sheet->h, &sheet->xmin, &sheet->ymin);
- sheet->gfx_extra = gfx_init(&cro_canvas_ops, 1, argv);
+ sheet->gfx_extra = gfx_init(&cro_canvas_ops);
sch_render_extra(sheet->sch, sheet->gfx_extra);
cro_canvas_end(gfx_user(sheet->gfx_extra), NULL, NULL, NULL, NULL);
diff --git a/main.c b/main.c
index 10f6e72..0d7cf3e 100644
--- a/main.c
+++ b/main.c
@@ -290,7 +290,9 @@ found:
return 1;
file_close(&sch_file);
- gfx = gfx_init(*ops, gfx_argc, gfx_argv);
+ gfx = gfx_init(*ops);
+ if (!gfx_args(gfx, gfx_argc, gfx_argv))
+ return 1;
if (recurse) {
const struct sheet *sheet;