]> mj.ucw.cz Git - paperjam.git/blob - jam.h
fa1e13b164eb98d865112b45a59de4d414584f41
[paperjam.git] / jam.h
1 /*
2  *      PaperJam -- Common declarations
3  *
4  *      (c) 2018 Martin Mares <mj@ucw.cz>
5  */
6
7 #include <vector>
8 #include <list>
9 #include <unordered_map>
10 #include <cmath>
11
12 using namespace std;
13
14 typedef unsigned int uint;
15
16 #define NONRET __attribute__((noreturn))
17 #define UNUSED __attribute__((unused))
18 #define FORMAT_CHECK(x,y,z) __attribute__((format(x,y,z)))
19
20 static inline bool is_zero(double z)
21 {
22   return fabs(z) < 1e-6;
23 }
24
25 static inline bool is_equal(double x, double y)
26 {
27   return is_zero(x-y);
28 }
29
30 void debug(const char *msg, ...) FORMAT_CHECK(printf, 1, 2);
31 void warn(const char *msg, ...) FORMAT_CHECK(printf, 1, 2);
32 void die(const char *msg, ...) FORMAT_CHECK(printf, 1, 2) NONRET;
33
34 // This one is called during execution of commands and propagated as an exception
35 void err(const char *msg, ...) FORMAT_CHECK(printf, 1, 2) NONRET;
36
37 #include "pdf-tools.h"
38
39 /*** Representation of commands ***/
40
41 struct pipeline;
42 struct cmd;
43
44 enum arg_type {
45   AT_STRING,
46   AT_INT,
47   AT_DOUBLE,
48   AT_DIMEN,
49   AT_SWITCH,
50   AT_TYPE_MASK = 0xffff,
51   AT_MANDATORY = 0x10000,
52   AT_POSITIONAL = 0x20000,
53 };
54
55 struct arg_def {
56   const char *name;
57   uint type;
58   const char *help;
59 };
60
61 class arg_val {
62 public:
63   virtual bool given() { return false; }
64   virtual int as_int(int def) { return def; }
65   virtual double as_double(double def) { return def; }
66   virtual const string as_string(const string def) { return def; }
67   virtual string dump() { return "<undef>"; }
68 };
69
70 extern arg_val null_arg;
71
72 struct out_context {
73   QPDF *pdf;
74   QPDFObjectHandle resources;
75   QPDFObjectHandle xobjects;
76   QPDFObjectHandle egstates;
77   string contents;
78   int res_cnt;
79   string new_resource(const string type);
80   out_context() { res_cnt = 0; }
81 };
82
83 struct page {
84   int index;            // Position in the source PDF, 0 for synthesized pages
85   double width;         // Physical dimensions of media
86   double height;
87   BBox image_box;       // Bounds useful contents
88   virtual void render(out_context *out UNUSED, pdf_matrix xform UNUSED) { abort(); }
89   virtual void debug_dump() = 0;
90   page(double _w=0, double _h=0) : index(0), width(_w), height(_h), image_box() { }
91   page(page *p)
92     {
93       index = p->index;
94       width = p->width;
95       height = p->height;
96       image_box = p->image_box;
97     }
98 };
99
100 struct empty_page : public page {
101   void render(out_context *out UNUSED, pdf_matrix xform UNUSED) { }
102   void debug_dump() { debug("Empty page"); }
103   empty_page(double _w=0, double _h=0) : page(_w, _h) { };
104 };
105
106 struct cmd_exec {
107   virtual vector<page *> process(vector <page *> &pages UNUSED) = 0;
108 };
109
110 struct cmd_def {
111   const char *name;
112   const arg_def *arg_defs;
113   bool has_pipeline;
114   cmd_exec *(*constructor)(cmd *cmd);
115   const char *help;
116 };
117
118 struct cmd {
119   const cmd_def *def;
120   unordered_map<string, arg_val *> args;
121   pipeline *pipe;
122   cmd_exec *exec;
123   arg_val *arg(const string name)
124     {
125       auto it = args.find(name);
126       if (it != args.end())
127         return it->second;
128       else
129         return &null_arg;
130     }
131 };
132
133 struct pipeline_selector {
134   int from;
135   int to;
136 };
137
138 struct pipeline_branch {
139   vector<pipeline_selector> selectors;
140   list<cmd *> commands;
141 };
142
143 struct pipeline {
144   vector<pipeline_branch *> branches;
145 };
146
147 /*** Modules ***/
148
149 // paperjam.cc
150
151 extern const char *in_name, *out_name;
152 extern bool recalc_bbox;
153 extern int debug_level;
154 extern int debug_indent;
155
156 class paperjam_error : public exception {
157   string message;
158 public:
159   paperjam_error(string m) : message(m) { }
160   const char *what() const noexcept override { return message.c_str(); }
161 };
162
163 // parse.cc
164
165 void parse(const char *in, list<cmd *> &cmds);
166 void parser_help();
167
168 // cmds.cc
169
170 extern const cmd_def cmd_table[];
171
172 // pdf.cc
173
174 void debug_pages(vector<page *> &pages);
175 void process(list<cmd *> &cmds);
176 vector<page *> run_command_list(list<cmd *> &cmds, vector<page *> &pages);
177 vector<BBox> gs_bboxes(const char *in);
178
179 class xform_page : public page {
180   page *orig_page;
181   pdf_matrix xform;
182   const char *description;
183 public:
184   void render(out_context *out, pdf_matrix xform) override;
185   void debug_dump() override;
186   xform_page(page *p, const char *desc, pdf_matrix xf);
187 };