#ifndef PDF_H #define PDF_H #include #include #include "studio/geometry.h" #define PAGES 32 struct pdf { size_t (*write)(void *, const char *, va_list); void *device; const char *title; const char *author; size_t offset; struct { size_t parent; size_t number; size_t object[PAGES]; } page; struct { size_t number; size_t offset[PAGES * 4]; } object; } generate(struct pdf, const char *, ...); #undef PAGES static inline struct pdf point(const struct pdf pdf, const vector point) { return generate(pdf, "%.2f %.2f ", point.x, point.y); } static inline struct pdf ctm(const struct pdf pdf, const matrix CTM) { return generate(pdf, "%0.2f %0.2f %0.2f %0.2f %0.2f %0.2f cm\n", CTM.a, CTM.b, CTM.c, CTM.d, CTM.tx, CTM.ty); } struct pdf dictionary(struct pdf, const char *, ...); struct pdf endpage(struct pdf, struct pdf); struct pdf endpdf(struct pdf); struct pdf offset(struct pdf, size_t); struct pdf startpage(struct pdf, vector, size_t); struct pdf startpdf(struct pdf); #define mm * (72.0 / 25.4) extern const vector a0; extern const vector a1; extern const vector a2; extern const vector a3; extern const vector a4; extern const vector a5; extern const vector a6; extern const vector a7; extern const vector a8; extern const vector usletter; static inline vector portrait(const vector page) { return (page.x <= page.y) ? page : (vector){.x = page.y, .y = page.x}; } static inline vector landscape(const vector page) { return (page.x >= page.y) ? page : (vector){.x = page.y, .y = page.x}; } #endif