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