From a03e79de7c04724cb5c2ae4c0a7b01b22e3a28e1 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Mon, 1 Aug 2016 11:32:22 -0300 Subject: [PATCH] sch2fig/: rename "layer" to "record", and use "layer" for layers in recordings Clearing up massively confusing naming. --- sch2fig/Makefile | 2 +- sch2fig/cairo.c | 48 +++---- sch2fig/layer.c | 336 ---------------------------------------------- sch2fig/layer.h | 57 -------- sch2fig/record.c | 342 +++++++++++++++++++++++++++++++++++++++++++++++ sch2fig/record.h | 58 ++++++++ 6 files changed, 425 insertions(+), 418 deletions(-) delete mode 100644 sch2fig/layer.c delete mode 100644 sch2fig/layer.h create mode 100644 sch2fig/record.c create mode 100644 sch2fig/record.h diff --git a/sch2fig/Makefile b/sch2fig/Makefile index b09e2d1..b7c40f9 100644 --- a/sch2fig/Makefile +++ b/sch2fig/Makefile @@ -13,7 +13,7 @@ NAME = sch2fig OBJS = main.o sch-parse.o sch-render.o lib-parse.o lib-render.o \ file.o \ - style.o fig.o layer.o cairo.o gfx.o dwg.o text.o misc.o + style.o fig.o record.o cairo.o gfx.o dwg.o text.o misc.o CFLAGS = -g -O -Wall -Wextra -Wno-unused-parameter -Wshadow \ -Wmissing-prototypes -Wmissing-declarations \ diff --git a/sch2fig/cairo.c b/sch2fig/cairo.c index 07a21ac..ede963f 100644 --- a/sch2fig/cairo.c +++ b/sch2fig/cairo.c @@ -25,7 +25,7 @@ #include "style.h" #include "text.h" #include "gfx.h" -#include "layer.h" +#include "record.h" #include "main.h" #include "cairo.h" @@ -40,7 +40,7 @@ struct cairo_ctx { - struct layer layer; /* must be first */ + struct record record; /* must be first */ int xo, yo; float scale; @@ -48,7 +48,7 @@ struct cairo_ctx { cairo_t *cr; cairo_surface_t *s; - struct layer *sheets; /* for PDF */ + struct record *sheets; /* for PDF */ unsigned n_sheets; const char *output_name; @@ -266,7 +266,7 @@ static struct cairo_ctx *init_common(int argc, char *const *argv) usage(*argv); } - layer_init(&cc->layer, &real_cairo_ops, cc); + record_init(&cc->record, &real_cairo_ops, cc); return cc; } @@ -309,7 +309,7 @@ static void end_common(struct cairo_ctx *cc, int *w, int *h) cairo_surface_destroy(cc->s); cairo_destroy(cc->cr); - layer_bbox(&cc->layer, &x, &y, w, h); + record_bbox(&cc->record, &x, &y, w, h); // fprintf(stderr, "%dx%d%+d%+d\n", *w, *h, x, y); cc->xo = -cd(cc, x); @@ -337,8 +337,8 @@ static void cr_png_end(void *ctx) CAIRO_FONT_WEIGHT_BOLD); cairo_set_line_width(cc->cr, 2); - layer_replay(&cc->layer); - layer_destroy(&cc->layer); + record_replay(&cc->record); + record_destroy(&cc->record); if (cc->output_name) cairo_surface_write_to_png(cc->s, cc->output_name); @@ -350,13 +350,13 @@ 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); + 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->layer; - layer_wipe(&cc->layer); + cc->sheets[cc->n_sheets - 1] = cc->record; + record_wipe(&cc->record); } @@ -379,14 +379,14 @@ static void cr_pdf_end(void *ctx) set_color(cc->cr, COLOR_WHITE); cairo_paint(cc->cr); - layer_replay(cc->sheets + i); - layer_destroy(cc->sheets + i); + record_replay(cc->sheets + i); + record_destroy(cc->sheets + i); cairo_show_page(cc->cr); } - layer_replay(&cc->layer); - layer_destroy(&cc->layer); + record_replay(&cc->record); + record_destroy(&cc->record); cairo_show_page(cc->cr); @@ -400,11 +400,11 @@ static void cr_pdf_end(void *ctx) const struct gfx_ops cairo_png_ops = { .name = "png", - .line = layer_line, - .poly = layer_poly, - .circ = layer_circ, - .arc = layer_arc, - .text = layer_text, + .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, @@ -412,11 +412,11 @@ const struct gfx_ops cairo_png_ops = { const struct gfx_ops cairo_pdf_ops = { .name = "pdf", - .line = layer_line, - .poly = layer_poly, - .circ = layer_circ, - .arc = layer_arc, - .text = layer_text, + .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, diff --git a/sch2fig/layer.c b/sch2fig/layer.c deleted file mode 100644 index 598dbbb..0000000 --- a/sch2fig/layer.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * layer.h - Separate 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 -#include -#include - -#include "util.h" -#include "style.h" -#include "gfx.h" -#include "text.h" -#include "layer.h" - - -struct layer_obj { - enum lo_type { - lo_line, - lo_rect, - lo_poly, - lo_circ, - lo_arc, - lo_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 layer_obj *next; -}; - - -static void bb(struct layer *layer, int x, int y) -{ - if (layer->xmin > x) - layer->xmin = x; - if (layer->ymin > y) - layer->ymin = y; - if (layer->xmax < x) - layer->xmax = x; - if (layer->ymax < y) - layer->ymax = y; -} - - -static void bb_rot(struct layer *layer, int x, int y, int rot) -{ - double a = -rot / 180.0 * M_PI; - - // @@@ figure this out later -return; - bb(layer, cos(a) * x + sin(a) * y, cos(a) * y - sin(a) * x); -} - - -static struct layer_obj *new_obj(struct layer *lc, enum lo_type type, - int color, int fill_color, unsigned layer) -{ - struct layer_objs **objs; - struct layer_objs *new_objs; - struct layer_obj *new_obj; - - for (objs = &lc->objs; *objs; objs = &(*objs)->next) { - if ((*objs)->layer == layer) - goto this_layer; - if ((*objs)->layer < layer) - break; - } - - new_objs = alloc_type(struct layer_objs); - new_objs->layer = layer; - new_objs->obj = NULL; - new_objs->next_obj = &new_objs->obj; - new_objs->next = *objs; - *objs = new_objs; - -this_layer: - new_obj = alloc_type(struct layer_obj); - new_obj->type = type; - new_obj->color = color; - new_obj->fill_color = fill_color; - new_obj->next = NULL; - - *(*objs)->next_obj = new_obj; - (*objs)->next_obj = &new_obj->next; - - return new_obj; -} - - -void layer_line(void *ctx, int sx, int sy, int ex, int ey, - int color, unsigned layer) -{ - struct layer *lc = ctx; - struct layer_obj *obj = new_obj(ctx, lo_line, color, COLOR_NONE, layer); - - bb(lc, sx, sy); - bb(lc, ex, ey); - - obj->x = sx; - obj->y = sy; - obj->u.line.ex = ex; - obj->u.line.ey = ey; -} - - -void layer_rect(void *ctx, int sx, int sy, int ex, int ey, - int color, int fill_color, unsigned layer) -{ - struct layer *lc = ctx; - struct layer_obj *obj = new_obj(ctx, lo_rect, color, fill_color, layer); - - bb(lc, sx, sy); - bb(lc, ex, ey); - - obj->x = sx; - obj->y = sy; - obj->u.rect.ex = ex; - obj->u.rect.ey = ey; -} - - -void layer_poly(void *ctx, - int points, const int x[points], const int y[points], - int color, int fill_color, unsigned layer) -{ - struct layer *lc = ctx; - struct layer_obj *obj = new_obj(ctx, lo_poly, color, fill_color, layer); - int i; - unsigned size; - - for (i = 0; i != points; i++) - bb(lc, 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 layer_circ(void *ctx, int x, int y, int r, - int color, int fill_color, unsigned layer) -{ - struct layer *lc = ctx; - struct layer_obj *obj = new_obj(ctx, lo_circ, color, fill_color, layer); - - bb(lc, x - r, y - r); - bb(lc, x + r, y + r); - - obj->x = x; - obj->y = y; - obj->u.circ.r = r; -} - - -void layer_arc(void *ctx, int x, int y, int r, int sa, int ea, - int color, int fill_color, unsigned layer) -{ - struct layer *lc = ctx; - struct layer_obj *obj = new_obj(ctx, lo_arc, color, fill_color, layer); - - bb(lc, x - r, y - r); - bb(lc, 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 layer_text(void *ctx, int x, int y, const char *s, unsigned size, - enum text_align align, int rot, unsigned color, unsigned layer) -{ - struct layer *lc = ctx; - struct layer_obj *obj = new_obj(ctx, lo_text, color, COLOR_NONE, layer); - unsigned width = lc->ops->text_width(lc->user, s, size); - - bb_rot(lc, x, y - size, rot); - bb_rot(lc, 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 layer_init(struct layer *layer, const struct gfx_ops *ops, void *user) -{ - layer->ops = ops; - layer->user = user; - layer->xmin = layer->ymin = INT_MAX; - layer->xmax = layer->ymax = INT_MIN; - layer->objs = NULL; -} - - -void layer_wipe(struct layer *layer) -{ - layer->objs = NULL; -} - - -void layer_replay(const struct layer *layer) -{ - const struct gfx_ops *ops = layer->ops; - void *ctx = layer->user; - const struct layer_objs *objs; - const struct layer_obj *obj; - - for (objs = layer->objs; objs; objs = objs->next) - for (obj = objs->obj; obj; obj = obj->next) - switch (obj->type) { - case lo_line: - ops->line(ctx, obj->x, obj->y, - obj->u.line.ex, obj->u.line.ey, - obj->color, objs->layer); - break; - case lo_rect: - ops->rect(ctx, obj->x, obj->y, - obj->u.rect.ex, obj->u.rect.ey, - obj->color, obj->fill_color, objs->layer); - break; - case lo_poly: - ops->poly(ctx, obj->u.poly.n, - obj->u.poly.vx, obj->u.poly.vy, - obj->color, obj->fill_color, objs->layer); - break; - case lo_circ: - ops->circ(ctx, obj->x, obj->y, - obj->u.circ.r, - obj->color, obj->fill_color, objs->layer); - break; - case lo_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, objs->layer); - break; - case lo_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, objs->layer); - break; - default: - abort(); - } -} - - -void layer_bbox(const struct layer *layer, int *x, int *y, int *w, int *h) -{ - if (x) - *x = layer->xmin; - if (y) - *y = layer->ymin; - if (w) - *w = layer->xmax - layer->xmin + 1; - if (h) - *h = layer->ymax - layer->ymin + 1; -} - - -static void layer_obj_destroy(struct layer_obj *obj) -{ - switch (obj->type) { - case lo_poly: - free(obj->u.poly.vx); - free(obj->u.poly.vy); - break; - case lo_text: - free(obj->u.text.s); - break; - default: - break; - } - free(obj); -} - - -void layer_destroy(struct layer *layer) -{ - struct layer_objs *next_objs; - struct layer_obj *next_obj; - - while (layer->objs) { - next_objs = layer->objs->next; - while (layer->objs->obj) { - next_obj = layer->objs->obj->next; - layer_obj_destroy(layer->objs->obj); - layer->objs->obj = next_obj; - } - free(layer->objs); - layer->objs = next_objs; - } -} diff --git a/sch2fig/layer.h b/sch2fig/layer.h deleted file mode 100644 index d265111..0000000 --- a/sch2fig/layer.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * layer.h - Separate 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 LAYER_H -#define LAYER_H - -#include "gfx.h" - - -struct layer_obj; - -struct layer_objs { - unsigned layer; - struct layer_obj *obj; - struct layer_obj **next_obj; - struct layer_objs *next; -}; - -struct layer { - const struct gfx_ops *ops; - void *user; - int xmin, xmax; - int ymin, ymax; - struct layer_objs *objs; -}; - - -void layer_line(void *ctx, int sx, int sy, int ex, int ey, - int color, unsigned layer); -void layer_rect(void *ctx, int sx, int sy, int ex, int ey, - int color, int fill_color, unsigned layer); -void layer_poly(void *ctx, int points, const int x[points], const int y[points], - int color, int fill_color, unsigned layer); -void layer_circ(void *ctx, int x, int y, int r, - int color, int fill_color, unsigned layer); -void layer_arc(void *ctx, int x, int y, int r, int sa, int ea, - int color, int fill_color, unsigned layer); -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); - -#endif /* !LAYER_H */ diff --git a/sch2fig/record.c b/sch2fig/record.c new file mode 100644 index 0000000..03cf90c --- /dev/null +++ b/sch2fig/record.c @@ -0,0 +1,342 @@ +/* + * 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 +#include +#include + +#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 new file mode 100644 index 0000000..3ff26f8 --- /dev/null +++ b/sch2fig/record.h @@ -0,0 +1,58 @@ +/* + * 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 */