sync with experimental
[luatex.git] / source / texk / web2c / luatexdir / lua / lpdflib.c
blob4037bacd81b05c3fc3e1d3443a1cba82f7d51951
1 /* lpdflib.c
3 Copyright 2006-2011 Taco Hoekwater <taco@luatex.org>
5 This file is part of LuaTeX.
7 LuaTeX is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2 of the License, or (at your
10 option) any later version.
12 LuaTeX is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License along
18 with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
21 #include "ptexlib.h"
22 #include "lua/luatex-api.h"
23 #include "pdf/pdftables.h"
25 static int luapdfprint(lua_State * L)
27 int n;
28 const_lstring st;
29 const char *modestr_s;
30 ctm_transform_modes literal_mode;
31 st.s = modestr_s = NULL;
32 n = lua_gettop(L);
33 if (!lua_isstring(L, -1)) { /* or number */
34 luaL_error(L, "no string to print");
36 literal_mode = set_origin;
37 if (n == 2) {
38 if (lua_type(L,-2) != LUA_TSTRING) {
39 luaL_error(L, "invalid first argument for print literal mode");
40 } else {
41 modestr_s = lua_tostring(L, -2);
42 if (lua_key_eq(modestr_s,direct))
43 literal_mode = direct_always;
44 else if (lua_key_eq(modestr_s,page))
45 literal_mode = direct_page;
46 else {
47 luaL_error(L, "invalid first argument for print literal mode");
50 } else if (n != 1) {
51 luaL_error(L, "invalid number of arguments");
53 check_o_mode(static_pdf, "pdf.print()", 1 << OMODE_PDF, true);
54 switch (literal_mode) {
55 case (set_origin):
56 pdf_goto_pagemode(static_pdf);
57 pdf_set_pos(static_pdf, static_pdf->posstruct->pos);
58 (void) calc_pdfpos(static_pdf->pstruct, static_pdf->posstruct->pos);
59 break;
60 case (direct_page):
61 pdf_goto_pagemode(static_pdf);
62 (void) calc_pdfpos(static_pdf->pstruct, static_pdf->posstruct->pos);
63 break;
64 case (direct_always):
65 pdf_end_string_nl(static_pdf);
66 break;
67 default:
68 assert(0);
70 st.s = lua_tolstring(L, n, &st.l);
71 pdf_out_block(static_pdf, st.s, st.l);
72 return 0;
75 static unsigned char *fread_to_buf(lua_State * L, const char *filename, size_t * len)
77 int ilen = 0;
78 FILE *f;
79 unsigned char *buf = NULL;
80 if ((f = fopen(filename, "rb")) == NULL)
81 luaL_error(L, "pdf.immediateobj() cannot open input file");
82 if (readbinfile(f, &buf, &ilen) == 0)
83 luaL_error(L, "pdf.immediateobj() cannot read input file");
84 fclose(f);
85 *len = (size_t) ilen;
86 return buf;
89 static int l_immediateobj(lua_State * L)
91 int n, first_arg = 1;
92 int k;
93 lstring buf;
94 const_lstring st1,st2, st3;
95 const char *st1_s = NULL;
96 st1.s = st2.s = st3.s = NULL;
97 check_o_mode(static_pdf, "immediateobj()", 1 << OMODE_PDF, true);
98 if (global_shipping_mode != NOT_SHIPPING)
99 luaL_error(L, "pdf.immediateobj() can not be used with \\latelua");
100 n = lua_gettop(L);
101 if ((n > 0) && (lua_type(L, 1) == LUA_TNUMBER)) {
102 first_arg++;
103 k = (int) lua_tointeger(L, 1);
104 check_obj_type(static_pdf, obj_type_obj, k);
105 if (is_obj_scheduled(static_pdf, k) || obj_data_ptr(static_pdf, k) != 0)
106 luaL_error(L, "pdf.immediateobj() object in use");
107 } else {
108 static_pdf->obj_count++;
109 k = pdf_create_obj(static_pdf, obj_type_obj, static_pdf->obj_ptr + 1);
111 pdf_last_obj = k;
112 switch (n - first_arg + 1) {
113 case 0:
114 luaL_error(L, "pdf.immediateobj() needs at least one argument");
115 break;
116 case 1:
117 if (!lua_isstring(L, first_arg)) /* or number */
118 luaL_error(L, "pdf.immediateobj() 1st argument must be string");
119 pdf_begin_obj(static_pdf, k, OBJSTM_ALWAYS);
120 st1.s = lua_tolstring(L, first_arg, &st1.l);
121 pdf_out_block(static_pdf, st1.s, st1.l);
122 pdf_end_obj(static_pdf);
123 break;
124 case 2:
125 case 3:
126 if (lua_type(L,first_arg) != LUA_TSTRING)
127 luaL_error(L, "pdf.immediateobj() 1st argument must be string");
128 if (!lua_isstring(L, first_arg + 1)) /* or number */
129 luaL_error(L, "pdf.immediateobj() 2nd argument must be string");
130 st1_s = lua_tostring(L, first_arg);
131 st2.s = lua_tolstring(L, first_arg + 1, &st2.l);
132 if (lua_key_eq(st1_s, file)) {
133 if (n == first_arg + 2)
134 luaL_error(L, "pdf.immediateobj() 3rd argument forbidden in file mode");
135 pdf_begin_obj(static_pdf, k, OBJSTM_ALWAYS);
136 buf.s = fread_to_buf(L, st2.s, &buf.l);
137 pdf_out_block(static_pdf, (const char *) buf.s, buf.l);
138 xfree(buf.s);
139 pdf_end_obj(static_pdf);
140 } else {
141 pdf_begin_obj(static_pdf, k, OBJSTM_NEVER); /* not an object stream candidate! */
142 pdf_begin_dict(static_pdf);
143 if (n == first_arg + 2) { /* write attr text */
144 if (!lua_isstring(L, first_arg + 2)) /* or number (maybe only string as it's an attr) */
145 luaL_error(L, "pdf.immediateobj() 3rd argument must be string");
146 st3.s = lua_tolstring(L, first_arg + 2, &st3.l);
147 pdf_out_block(static_pdf, st3.s, st3.l);
148 if (st3.s[st3.l - 1] != '\n')
149 pdf_out(static_pdf, '\n');
151 pdf_dict_add_streaminfo(static_pdf);
152 pdf_end_dict(static_pdf);
153 pdf_begin_stream(static_pdf);
154 if (lua_key_eq(st1_s, stream)) {
155 pdf_out_block(static_pdf, st2.s, st2.l);
156 } else if (lua_key_eq(st1_s, streamfile)) {
157 buf.s = fread_to_buf(L, st2.s, &buf.l);
158 pdf_out_block(static_pdf, (const char *) buf.s, buf.l);
159 xfree(buf.s);
160 } else
161 luaL_error(L, "pdf.immediateobj() invalid argument");
162 pdf_end_stream(static_pdf);
163 pdf_end_obj(static_pdf);
165 break;
166 default:
167 luaL_error(L, "pdf.immediateobj() allows max. 3 arguments");
169 lua_pushinteger(L, k);
170 return 1;
173 static int table_obj(lua_State * L)
175 const char *type;
176 int k, obj_compression;
177 int compress_level = -1; /* unset */
178 int os_threshold = OBJSTM_ALWAYS; /* default: put non-stream objects into object streams */
179 int saved_compress_level = static_pdf->compress_level;
180 const_lstring attr, st;
181 lstring buf;
182 int immediate = 0; /* default: not immediate */
183 attr.s = st.s = NULL;
184 attr.l = 0;
185 assert(lua_istable(L, 1)); /* t */
186 lua_key_rawgeti(type);
187 if (lua_isnil(L, -1)) /* !vs t */
188 luaL_error(L, "pdf.obj(): object \"type\" missing");
189 if (lua_type(L,-1) != LUA_TSTRING) /* !vs t */
190 luaL_error(L, "pdf.obj(): object \"type\" must be string");
191 type = lua_tostring(L, -1);
192 if (! (lua_key_eq(type, raw) || lua_key_eq(type, stream))) {
193 luaL_error(L, "pdf.obj(): \"%s\" is not a valid object type", type); /* i vs t */
195 lua_pop(L, 1); /* t */
196 lua_key_rawgeti(immediate);
197 if (!lua_isnil(L, -1)) { /* b? t */
198 if (!lua_isboolean(L, -1)) /* !b t */
199 luaL_error(L, "pdf.obj(): \"immediate\" must be boolean");
200 immediate = lua_toboolean(L, -1); /* 0 or 1 */
202 lua_pop(L, 1); /* t */
204 /* is a reserved object referenced by "objnum"? */
206 lua_key_rawgeti(objnum);
207 if (!lua_isnil(L, -1)) { /* vi? t */
208 if (lua_type(L,-1) != LUA_TNUMBER) /* !vi t */
209 luaL_error(L, "pdf.obj(): \"objnum\" must be integer");
210 k = (int) lua_tointeger(L, -1); /* vi t */
211 check_obj_type(static_pdf, obj_type_obj, k);
212 if (is_obj_scheduled(static_pdf, k) || obj_data_ptr(static_pdf, k) != 0)
213 luaL_error(L, "pdf.obj() object in use");
214 } else {
215 static_pdf->obj_count++;
216 k = pdf_create_obj(static_pdf, obj_type_obj, static_pdf->obj_ptr + 1);
218 pdf_last_obj = k;
219 if (immediate == 0) {
220 obj_data_ptr(static_pdf, k) = pdf_get_mem(static_pdf, pdfmem_obj_size);
221 init_obj_obj(static_pdf, k);
223 lua_pop(L, 1); /* t */
225 /* get optional "attr" (allowed only for stream case) */
227 lua_key_rawgeti(attr);
228 if (!lua_isnil(L, -1)) { /* attr-s? t */
229 if (! lua_key_eq(type, stream))
230 luaL_error(L, "pdf.obj(): \"attr\" key not allowed for non-stream object");
231 if (!lua_isstring(L, -1)) /* or number */ /* !attr-s t */
232 luaL_error(L, "pdf.obj(): object \"attr\" must be string");
233 if (immediate == 1) {
234 attr.s = lua_tolstring(L, -1, &attr.l); /* attr-s t */
235 lua_pop(L, 1); /* t */
236 } else
237 obj_obj_stream_attr(static_pdf, k) = luaL_ref(Luas, LUA_REGISTRYINDEX); /* t */
238 } else {
239 lua_pop(L, 1); /* t */
242 /* get optional "compresslevel" (allowed only for stream case) */
244 lua_key_rawgeti(compresslevel);
245 if (!lua_isnil(L, -1)) { /* vi? t */
246 if (lua_key_eq(type, raw))
247 luaL_error(L, "pdf.obj(): \"compresslevel\" key not allowed for raw object");
248 if (lua_type(L, -1) != LUA_TNUMBER) /* !vi t */
249 luaL_error(L, "pdf.obj(): \"compresslevel\" must be integer");
250 compress_level = (int) lua_tointeger(L, -1); /* vi t */
251 if (compress_level > 9)
252 luaL_error(L, "pdf.obj(): \"compresslevel\" must be <= 9");
253 else if (compress_level < 0)
254 luaL_error(L, "pdf.obj(): \"compresslevel\" must be >= 0");
255 if (immediate == 0)
256 obj_obj_pdfcompresslevel(static_pdf, k) = compress_level;
258 lua_pop(L, 1); /* t */
260 /* get optional "objcompression" (allowed only for non-stream case) */
262 lua_key_rawgeti(objcompression);
263 if (!lua_isnil(L, -1)) { /* b? t */
264 if (lua_key_eq(type, stream))
265 luaL_error(L, "pdf.obj(): \"objcompression\" key not allowed for stream object");
266 if (!lua_isboolean(L, -1)) /* !b t */
267 luaL_error(L, "pdf.obj(): \"objcompression\" must be boolean");
268 obj_compression = lua_toboolean(L, -1); /* 0 or 1 */
269 /* OBJSTM_NEVER: never into object stream; OBJSTM_ALWAYS: depends then on \pdfobjcompresslevel */
270 if (obj_compression > 0)
271 os_threshold = OBJSTM_ALWAYS;
272 else
273 os_threshold = OBJSTM_NEVER;
274 if (immediate == 0)
275 obj_obj_objstm_threshold(static_pdf, k) = os_threshold;
277 lua_pop(L, 1); /* t */
279 /* now the object contents for all cases are handled */
281 lua_key_rawgeti(string);
282 lua_key_rawgeti_n(file,-2);
284 if (!lua_isnil(L, -1) && !lua_isnil(L, -2)) /* file-s? string-s? t */
285 luaL_error(L, "pdf.obj(): \"string\" and \"file\" must not be given together");
286 if (lua_isnil(L, -1) && lua_isnil(L, -2)) /* nil nil t */
287 luaL_error(L, "pdf.obj(): no \"string\" or \"file\" given");
289 if (lua_key_eq(type, raw)) {
290 if (immediate == 1)
291 pdf_begin_obj(static_pdf, k, os_threshold);
292 if (!lua_isnil(L, -2)) { /* file-s? string-s? t */
293 /* from string */
294 lua_pop(L, 1); /* string-s? t */
295 if (!lua_isstring(L, -1)) /* or number */ /* !string-s t */
296 luaL_error(L, "pdf.obj(): \"string\" must be string for raw object");
297 if (immediate == 1) {
298 st.s = lua_tolstring(L, -1, &st.l);
299 pdf_out_block(static_pdf, st.s, st.l);
300 } else
301 obj_obj_data(static_pdf, k) = luaL_ref(L, LUA_REGISTRYINDEX); /* t */
302 } else {
303 /* from file */
304 if (lua_type(L, -1) != LUA_TSTRING) /* !file-s nil t */
305 luaL_error(L, "pdf.obj(): \"file\" name must be string for raw object");
306 if (immediate == 1) {
307 st.s = lua_tolstring(L, -1, &st.l); /* file-s nil t */
308 buf.s = fread_to_buf(L, st.s, &buf.l);
309 pdf_out_block(static_pdf, (const char *) buf.s, buf.l);
310 /* already in pdf_end_obj:
311 if (buf.s[buf.l - 1] != '\n')
312 pdf_out(static_pdf, '\n');
314 xfree(buf.s);
315 } else {
316 set_obj_obj_is_file(static_pdf, k);
317 obj_obj_data(static_pdf, k) = luaL_ref(L, LUA_REGISTRYINDEX); /* nil t */
320 if (immediate == 1)
321 pdf_end_obj(static_pdf);
322 } else {
323 if (immediate == 1) {
324 pdf_begin_obj(static_pdf, k, OBJSTM_NEVER); /* 0 = not an object stream candidate! */
325 pdf_begin_dict(static_pdf);
326 if (attr.s != NULL) {
327 pdf_out_block(static_pdf, attr.s, attr.l);
328 if (attr.s[attr.l - 1] != '\n')
329 pdf_out(static_pdf, '\n');
331 if (compress_level > -1)
332 static_pdf->compress_level = compress_level;
333 pdf_dict_add_streaminfo(static_pdf);
334 pdf_end_dict(static_pdf);
335 pdf_begin_stream(static_pdf);
336 } else {
337 set_obj_obj_is_stream(static_pdf, k);
338 if (compress_level > -1)
339 obj_obj_pdfcompresslevel(static_pdf, k) = compress_level;
341 if (!lua_isnil(L, -2)) { /* file-s? string-s? t */
342 /* from string */
343 lua_pop(L, 1); /* string-s? t */
344 if (!lua_isstring(L, -1)) /* or number */ /* !string-s t */
345 luaL_error(L, "pdf.obj(): \"string\" must be string for stream object");
346 if (immediate == 1) {
347 st.s = lua_tolstring(L, -1, &st.l); /* string-s t */
348 pdf_out_block(static_pdf, st.s, st.l);
349 } else
350 obj_obj_data(static_pdf, k) = luaL_ref(L, LUA_REGISTRYINDEX); /* t */
351 } else {
352 /* from file */
353 if (lua_type(L, -1) != LUA_TSTRING) /* !file-s nil t */
354 luaL_error(L, "pdf.obj(): \"file\" name must be string for stream object");
355 if (immediate == 1) {
356 st.s = lua_tolstring(L, -1, &st.l); /* file-s nil t */
357 buf.s = fread_to_buf(L, st.s, &buf.l);
358 pdf_out_block(static_pdf, (const char *) buf.s, buf.l);
359 xfree(buf.s);
360 } else {
361 set_obj_obj_is_file(static_pdf, k);
362 obj_obj_data(static_pdf, k) = luaL_ref(L, LUA_REGISTRYINDEX); /* nil t */
365 if (immediate == 1) {
366 pdf_end_stream(static_pdf);
367 pdf_end_obj(static_pdf);
370 static_pdf->compress_level = saved_compress_level;
371 return k;
374 static int orig_obj(lua_State * L)
376 int n, first_arg = 1;
377 int k;
378 const char *st_s = NULL ;
379 n = lua_gettop(L);
380 if ((n > 0) && (lua_type(L, 1) == LUA_TNUMBER)) {
381 first_arg++;
382 k = (int) lua_tointeger(L, 1);
383 check_obj_type(static_pdf, obj_type_obj, k);
384 if (is_obj_scheduled(static_pdf, k) || obj_data_ptr(static_pdf, k) != 0)
385 luaL_error(L, "pdf.obj() object in use");
386 } else {
387 static_pdf->obj_count++;
388 k = pdf_create_obj(static_pdf, obj_type_obj, static_pdf->obj_ptr + 1);
390 pdf_last_obj = k;
391 obj_data_ptr(static_pdf, k) = pdf_get_mem(static_pdf, pdfmem_obj_size);
392 init_obj_obj(static_pdf, k);
393 switch (n - first_arg + 1) {
394 case 0:
395 luaL_error(L, "pdf.obj() needs at least one argument");
396 break;
397 case 1:
398 if (!lua_isstring(L, first_arg)) /* or number */
399 luaL_error(L, "pdf.obj() 1st argument must be string");
400 break;
401 case 2:
402 case 3:
403 if (lua_type(L, first_arg) != LUA_TSTRING)
404 luaL_error(L, "pdf.obj() 1st argument must be string");
405 if (!lua_isstring(L, first_arg + 1)) /* or number */
406 luaL_error(L, "pdf.obj() 2nd argument must be string");
407 st_s = lua_tostring(L, first_arg);
408 if (lua_key_eq(st_s, file)) {
409 if (n == first_arg + 2)
410 luaL_error(L, "pdf.obj() 3rd argument forbidden in file mode");
411 set_obj_obj_is_file(static_pdf, k);
412 } else {
413 if (n == first_arg + 2) { /* write attr text */
414 if (!lua_isstring(L, -1)) /* or number */
415 luaL_error(L, "pdf.obj() 3rd argument must be string");
416 obj_obj_stream_attr(static_pdf, k) =
417 luaL_ref(Luas, LUA_REGISTRYINDEX);
419 if (lua_key_eq(st_s, stream)) {
420 set_obj_obj_is_stream(static_pdf, k);
421 } else if (lua_key_eq(st_s, streamfile)) {
422 set_obj_obj_is_stream(static_pdf, k);
423 set_obj_obj_is_file(static_pdf, k);
424 } else
425 luaL_error(L, "pdf.obj() invalid argument");
427 break;
428 default:
429 luaL_error(L, "pdf.obj() allows max. 3 arguments");
431 obj_obj_data(static_pdf, k) = luaL_ref(L, LUA_REGISTRYINDEX);
432 return k;
435 static int l_obj(lua_State * L)
437 int k, n;
438 ensure_output_state(static_pdf, ST_HEADER_WRITTEN);
439 n = lua_gettop(L);
440 if (n == 1 && lua_istable(L, 1))
441 k = table_obj(L); /* new */
442 else
443 k = orig_obj(L);
444 lua_pushinteger(L, k);
445 return 1;
448 static int l_refobj(lua_State * L)
450 int k, n;
451 n = lua_gettop(L);
452 if (n != 1)
453 luaL_error(L, "pdf.refobj() needs exactly 1 argument");
454 k = (int) luaL_checkinteger(L, 1);
455 if (global_shipping_mode == NOT_SHIPPING)
456 scan_refobj_lua(static_pdf, k);
457 else
458 pdf_ref_obj_lua(static_pdf, k);
459 return 0;
462 static int l_reserveobj(lua_State * L)
464 int n;
465 const char *st_s = NULL;
466 n = lua_gettop(L);
467 switch (n) {
468 case 0:
469 static_pdf->obj_count++;
470 pdf_last_obj = pdf_create_obj(static_pdf, obj_type_obj, static_pdf->obj_ptr + 1);
471 break;
472 case 1:
473 if (lua_type(L, -1) != LUA_TSTRING)
474 luaL_error(L, "pdf.reserveobj() optional argument must be string");
475 st_s = luaL_checkstring(L, 1);
476 if (lua_key_eq(st_s, annot)) {
477 pdf_last_annot = pdf_create_obj(static_pdf, obj_type_annot, 0);
478 } else {
479 luaL_error(L, "pdf.reserveobj() optional string must be \"annot\"");
481 lua_pop(L, 1);
482 break;
483 default:
484 luaL_error(L, "pdf.reserveobj() allows max. 1 argument");
486 lua_pushinteger(L, static_pdf->obj_ptr);
487 return 1;
490 static int l_registerannot(lua_State * L)
492 int n, i;
493 n = lua_gettop(L);
494 switch (n) {
495 case 1:
496 if (global_shipping_mode == NOT_SHIPPING)
497 luaL_error(L, "pdf.registerannot() can only be used in late lua");
498 i = (int) luaL_checkinteger(L, 1);
499 if (i <= 0)
500 luaL_error(L, "pdf.registerannot() can only register positive object numbers");
501 addto_page_resources(static_pdf, obj_type_annot, i);
502 break;
503 default:
504 luaL_error(L, "pdf.registerannot() needs exactly 1 argument");
506 return 0;
511 # define valid_pdf_key ( \
512 lua_key_eq(s,pageresources) \
513 lua_key_eq(s,pageattributes) || \
514 lua_key_eq(s,pagesattributes) || \
515 lua_key_eq(s,catalog) || \
516 lua_key_eq(s,info) || \
517 lua_key_eq(s,names) || \
518 lua_key_eq(s,trailer) || \
519 lua_key_eq(s,xformresources) || \
520 lua_key_eq(s,xformattributes) || \
521 lua_key_eq(s,trailerid) \
526 #define l_get_pdf_value(key) \
527 lua_get_metatablelua(pdf_data); \
528 lua_key_rawgeti(key); \
529 return 1;
531 static int l_get_pageresources (lua_State * L) { l_get_pdf_value(pageresources); }
532 static int l_get_pageattributes (lua_State * L) { l_get_pdf_value(pageattributes); }
533 static int l_get_pagesattributes(lua_State * L) { l_get_pdf_value(pagesattributes); }
534 static int l_get_catalog (lua_State * L) { l_get_pdf_value(catalog); }
535 static int l_get_info (lua_State * L) { l_get_pdf_value(info); }
536 static int l_get_names (lua_State * L) { l_get_pdf_value(names); }
537 static int l_get_trailer (lua_State * L) { l_get_pdf_value(trailer); }
538 static int l_get_xformresources (lua_State * L) { l_get_pdf_value(xformresources); }
539 static int l_get_xformattributes(lua_State * L) { l_get_pdf_value(xformattributes); }
540 static int l_get_trailerid (lua_State * L) { l_get_pdf_value(trailerid); }
544 static int getpdf(lua_State * L)
546 const char *s ;
547 if (lua_gettop(L) != 2) {
548 return 0;
550 if (lua_type(L,-1) == LUA_TSTRING) {
551 s = lua_tostring(L, -1);
552 if (lua_key_eq(s,h)) {
553 lua_pushinteger(L, static_pdf->posstruct->pos.h);
554 return 1;
555 } else if (lua_key_eq(s,v)) {
556 lua_pushinteger(L, static_pdf->posstruct->pos.v);
557 return 1;
558 } else if (valid_pdf_key) {
559 lua_get_metatablelua(pdf_data);
560 lua_replace(L, -3);
561 lua_rawget(L, -2);
562 return 1;
565 return 0;
569 #define l_set_pdf_value(key) \
570 if (lua_type(L,-1) == LUA_TSTRING) { \
571 lua_get_metatablelua(pdf_data); \
572 lua_rawgeti(L, LUA_REGISTRYINDEX, lua_key_index(key)); \
573 lua_pushvalue(L, -3); \
574 lua_rawset(L,-3); \
576 return 0;
578 static int l_set_pageresources (lua_State * L) { l_set_pdf_value(pageresources); }
579 static int l_set_pageattributes (lua_State * L) { l_set_pdf_value(pageattributes); }
580 static int l_set_pagesattributes(lua_State * L) { l_set_pdf_value(pagesattributes); }
581 static int l_set_catalog (lua_State * L) { l_set_pdf_value(catalog); }
582 static int l_set_info (lua_State * L) { l_set_pdf_value(info); }
583 static int l_set_names (lua_State * L) { l_set_pdf_value(names); }
584 static int l_set_trailer (lua_State * L) { l_set_pdf_value(trailer); }
585 static int l_set_xformresources (lua_State * L) { l_set_pdf_value(xformresources); }
586 static int l_set_xformattributes(lua_State * L) { l_set_pdf_value(xformattributes); }
587 static int l_set_trailerid (lua_State * L) { l_set_pdf_value(trailerid); }
591 static int setpdf(lua_State * L)
593 const char *s ;
594 if (lua_gettop(L) != 3) {
595 return 0;
597 if (lua_type(L, -2) == LUA_TSTRING) {
598 s = lua_tostring(L, -1);
599 if (valid_pdf_key) {
600 lua_get_metatablelua(pdf_data);
601 lua_replace(L, -4);
604 lua_rawset(L, -3);
605 return 0;
610 static int l_objtype(lua_State * L)
612 int n = lua_gettop(L);
613 if (n != 1)
614 luaL_error(L, "pdf.objtype() needs exactly 1 argument");
615 n = (int) luaL_checkinteger(L, 1);
616 if (n < 0 || n > static_pdf->obj_ptr)
617 lua_pushnil(L);
618 else
619 lua_pushstring(L, pdf_obj_typenames[obj_type(static_pdf, n)]);
620 return 1;
623 static int l_maxobjnum(lua_State * L)
625 int n = lua_gettop(L);
626 if (n != 0)
627 luaL_error(L, "pdf.maxobjnum() needs 0 arguments");
628 lua_pushinteger(L, static_pdf->obj_ptr);
629 return 1;
632 static int l_mapfile(lua_State * L)
634 char *s;
635 const char *st;
636 if ((lua_type(L,-1) == LUA_TSTRING) && (st = lua_tostring(L, -1)) != NULL) {
637 s = xstrdup(st);
638 process_map_item(s, MAPFILE);
639 free(s);
641 return 0;
644 static int l_mapline(lua_State * L)
646 char *s;
647 const char *st;
648 if ((lua_type(L,-1) == LUA_TSTRING) && (st = lua_tostring(L, -1)) != NULL) {
649 s = xstrdup(st);
650 process_map_item(s, MAPLINE);
651 free(s);
653 return 0;
656 static int l_pageref(lua_State * L)
658 int n = lua_gettop(L);
659 if (n != 1)
660 luaL_error(L, "pdf.pageref() needs exactly 1 argument");
661 n = (int) luaL_checkinteger(L, 1);
662 if (n <= 0)
663 luaL_error(L, "pdf.pageref() needs page number > 0");
664 n = pdf_get_obj(static_pdf, obj_type_page, n, false);
665 lua_pushinteger(L, n);
666 return 1;
669 static int l_getpos(lua_State * L)
671 lua_pushinteger(L, static_pdf->posstruct->pos.h);
672 lua_pushinteger(L, static_pdf->posstruct->pos.v);
673 return 2;
676 static int l_gethpos(lua_State * L)
678 lua_pushinteger(L, static_pdf->posstruct->pos.h);
679 return 1;
682 static int l_getvpos(lua_State * L)
684 lua_pushinteger(L, static_pdf->posstruct->pos.v);
685 return 1;
688 static int l_getmatrix(lua_State * L)
690 if (matrix_stack_used > 0) {
691 matrix_entry *m = &matrix_stack[matrix_stack_used - 1];
692 lua_pushnumber(L, m->a);
693 lua_pushnumber(L, m->b);
694 lua_pushnumber(L, m->c);
695 lua_pushnumber(L, m->d);
696 lua_pushnumber(L, m->e);
697 lua_pushnumber(L, m->f);
698 } else {
699 lua_pushinteger(L, 1);
700 lua_pushinteger(L, 0);
701 lua_pushinteger(L, 0);
702 lua_pushinteger(L, 1);
703 lua_pushinteger(L, 0);
704 lua_pushinteger(L, 0);
706 return 6 ;
709 static int l_hasmatrix(lua_State * L)
711 lua_pushboolean(L, (matrix_stack_used > 0));
712 return 1 ;
715 static int l_get_lastlink(lua_State * L)
717 lua_pushinteger(L, (pdf_last_link));
718 return 1 ;
721 static int l_get_retval(lua_State * L)
723 lua_pushinteger(L, (pdf_retval));
724 return 1 ;
727 static int l_get_lastobj(lua_State * L)
729 lua_pushinteger(L, (pdf_last_obj));
730 return 1 ;
733 static int l_get_lastannot(lua_State * L)
735 lua_pushinteger(L, (pdf_last_annot));
736 return 1 ;
739 /* maybe:
741 get_fontname : set_ff(i) obj_info(static_pdf, pdf_font_num(ff))
742 get_fontobjnum : set_ff(i) pdf_font_num(ff)
743 get_fontsize : font_size(i)
744 get_xformname : obj_info(static_pdf, i)
748 static int l_get_compress_level(lua_State * L)
750 lua_pushinteger(L, (pdf_compress_level));
751 return 1 ;
754 static int l_get_obj_compress_level(lua_State * L)
756 lua_pushinteger(L, (pdf_obj_compress_level));
757 return 1 ;
760 static int l_set_compress_level(lua_State * L)
762 if (lua_type(L, 1) == LUA_TNUMBER) {
763 int c = (int) lua_tointeger(L, 1);
764 if (c<0)
765 c = 0 ;
766 else if (c>9)
767 c = 9 ;
768 set_pdf_compress_level(c);
770 return 0 ;
773 static int l_set_obj_compress_level(lua_State * L)
775 if (lua_type(L, 1) == LUA_TNUMBER) {
776 int c = (int) lua_tointeger(L, 1);
777 if (c<0)
778 c = 0 ;
779 else if (c>9)
780 c = 9 ;
781 set_pdf_obj_compress_level(c);
783 return 0 ;
786 /* accuracy */
788 static int l_get_decimal_digits(lua_State * L)
790 lua_pushinteger(L, (pdf_decimal_digits));
791 return 1 ;
794 static int l_set_decimal_digits(lua_State * L)
796 if (lua_type(L, 1) == LUA_TNUMBER) {
797 int c = (int) lua_tointeger(L, 1);
798 if (c<0) {
799 c = 0 ;
801 set_pdf_decimal_digits(c);
803 return 0 ;
806 /* pk */
808 static int l_get_pk_resolution(lua_State * L)
810 lua_pushinteger(L, (pdf_pk_resolution));
811 lua_pushinteger(L, (pdf_pk_fixed_dpi));
812 return 2 ;
815 static int l_set_pk_resolution(lua_State * L)
817 if (lua_type(L, 1) == LUA_TNUMBER) {
818 int c = (int) lua_tointeger(L, 1);
819 if (c < 72) {
820 c = 72 ;
821 } else if (c > 8000) {
822 c = 8000 ;
824 set_pdf_pk_resolution(c);
826 if (lua_type(L, 2) == LUA_TNUMBER) {
827 set_pdf_pk_fixed_dpi(lua_tointeger(L, 1));
829 return 0 ;
832 /* pdf stuff */
834 static int getpdffontname(lua_State * L)
836 int c, ff ;
837 if (lua_type(L, 1) == LUA_TNUMBER) {
838 c = (int) lua_tointeger(L, 1);
839 pdf_check_vf(c);
840 if (!font_used(c))
841 pdf_init_font(static_pdf,c);
842 set_ff(c);
843 lua_pushinteger(L, (obj_info(static_pdf, pdf_font_num(ff))));
844 } else {
845 lua_pushnil(L);
847 return 1 ;
850 static int getpdffontobjnum(lua_State * L)
852 if (lua_type(L, 1) == LUA_TNUMBER) {
853 int ff;
854 int c = (int) lua_tointeger(L, 1);
855 pdf_check_vf(c);
856 if (!font_used(c))
857 pdf_init_font(static_pdf,c);
858 set_ff(c);
859 lua_pushinteger(L, (pdf_font_num(ff)));
860 } else {
861 lua_pushnil(L);
863 return 1 ;
866 static int getpdffontsize(lua_State * L)
868 if (lua_type(L, 1) == LUA_TNUMBER) {
869 int c = (int) lua_tointeger(L, 1);
870 lua_pushinteger(L, (font_size(c)));
871 } else {
872 lua_pushnil(L);
874 return 1 ;
879 static int getpdfpageref(lua_State * L)
881 if (lua_type(L, 1) == LUA_TNUMBER) {
882 int c = (int) lua_tointeger(L, 1);
883 lua_pushinteger(L, (pdf_get_obj(static_pdf, obj_type_page, c, false)));
884 } else {
885 lua_pushnil(L);
887 return 1 ;
892 static int getpdfxformname(lua_State * L)
894 if (lua_type(L, 1) == LUA_TNUMBER) {
895 int c = (int) lua_tointeger(L, 1);
896 check_obj_type(static_pdf, obj_type_xform, c);
897 lua_pushinteger(L, (obj_info(static_pdf, c)));
898 } else {
899 lua_pushnil(L);
901 return 1 ;
904 static int getpdfversion(lua_State * L)
906 lua_pushinteger(L,1);
907 return 1 ;
910 static int getpdfcreationdate(lua_State * L)
912 initialize_start_time(static_pdf);
913 lua_pushstring(L,static_pdf->start_time_str);
914 return 1 ;
917 static int getpdfminorversion(lua_State * L)
919 /* lua_pushinteger(L,static_pdf->minor_version); */
920 lua_pushinteger(L,pdf_minor_version);
921 return 1 ;
924 static int setpdfminorversion(lua_State * L)
926 if (lua_type(L, 1) == LUA_TNUMBER) {
927 int c = (int) lua_tointeger(L, 1);
928 if ((c >= 0) && (c <= 9)) {
929 static_pdf->minor_version = c;
930 set_pdf_minor_version(c);
933 return 0 ;
936 static int setpdforigin(lua_State * L)
938 int h = 0 ;
939 int v = 0 ;
940 if (lua_type(L, 1) == LUA_TNUMBER) {
941 h = (int) lua_tointeger(L, 1);
942 if (lua_type(L, 2) == LUA_TNUMBER) {
943 v = (int) lua_tointeger(L, 1);
944 } else {
945 v = h;
948 set_tex_extension_dimen_register(d_pdf_h_origin,h);
949 set_tex_extension_dimen_register(d_pdf_v_origin,v);
950 return 0 ;
953 static int getpdforigin(lua_State * L)
955 lua_pushinteger(L,get_tex_extension_dimen_register(d_pdf_h_origin));
956 lua_pushinteger(L,get_tex_extension_dimen_register(d_pdf_v_origin));
957 return 2 ;
960 static int setpdfimageresolution(lua_State * L)
962 if (lua_type(L, 1) == LUA_TNUMBER) {
963 set_tex_extension_count_register(c_pdf_image_resolution,lua_tointeger(L, 1));
965 return 0;
968 static int getpdfimageresolution(lua_State * L)
970 lua_pushinteger(L,get_tex_extension_count_register(c_pdf_image_resolution));
971 return 1 ;
974 static int setpdfthreadmargin(lua_State * L) {
975 if (lua_type(L, 1) == LUA_TNUMBER) {
976 set_tex_extension_dimen_register(d_pdf_thread_margin,lua_tointeger(L, 1));
978 return 0;
981 static int setpdfdestmargin(lua_State * L) {
982 if (lua_type(L, 1) == LUA_TNUMBER) {
983 set_tex_extension_dimen_register(d_pdf_dest_margin,lua_tointeger(L, 1));
985 return 0;
988 static int setpdflinkmargin(lua_State * L) {
989 if (lua_type(L, 1) == LUA_TNUMBER) {
990 set_tex_extension_dimen_register(d_pdf_link_margin,lua_tointeger(L, 1));
992 return 0;
995 static int setpdfxformmargin(lua_State * L) {
996 if (lua_type(L, 1) == LUA_TNUMBER) {
997 set_tex_extension_dimen_register(d_pdf_xform_margin,lua_tointeger(L, 1));
999 return 0;
1002 static int getpdfthreadmargin(lua_State * L) {
1003 lua_pushinteger(L,get_tex_extension_dimen_register(d_pdf_thread_margin));
1004 return 1;
1007 static int getpdfdestmargin(lua_State * L) {
1008 lua_pushinteger(L,get_tex_extension_dimen_register(d_pdf_dest_margin));
1009 return 1;
1012 static int getpdflinkmargin(lua_State * L) {
1013 lua_pushinteger(L,get_tex_extension_dimen_register(d_pdf_link_margin));
1014 return 1;
1017 static int getpdfxformmargin(lua_State * L) {
1018 lua_pushinteger(L,get_tex_extension_dimen_register(d_pdf_xform_margin));
1019 return 1;
1022 static int setpdfinclusionerrorlevel(lua_State * L) {
1023 if (lua_type(L, 1) == LUA_TNUMBER) {
1024 set_tex_extension_count_register(c_pdf_inclusion_errorlevel,lua_tointeger(L, 1));
1026 return 0;
1029 static int setpdfignoreunknownimages(lua_State * L) {
1030 if (lua_type(L, 1) == LUA_TNUMBER) {
1031 set_tex_extension_count_register(c_pdf_ignore_unknown_images,lua_tointeger(L, 1));
1033 return 0;
1036 static int getpdfinclusionerrorlevel(lua_State * L) {
1037 lua_pushinteger(L,get_tex_extension_count_register(c_pdf_inclusion_errorlevel));
1038 return 1;
1041 static int getpdfignoreunknownimages(lua_State * L) {
1042 lua_pushinteger(L,get_tex_extension_count_register(c_pdf_ignore_unknown_images));
1043 return 1;
1046 static int l_set_suppress_optional_info(lua_State * L) {
1047 if (lua_type(L, 1) == LUA_TNUMBER) {
1048 set_tex_extension_count_register(c_pdf_suppress_optional_info,lua_tointeger(L, 1));
1050 return 0;
1053 static int l_get_suppress_optional_info(lua_State * L) {
1054 lua_pushinteger(L,get_tex_extension_count_register(c_pdf_suppress_optional_info));
1055 return 1;
1058 static int newpdfcolorstack(lua_State * L)
1060 const char *s = NULL;
1061 const char *l = NULL;
1062 int literal_mode = 0; /* set_origin */
1063 boolean page_start = false;
1064 int id ;
1065 if (lua_type(L,1) != LUA_TSTRING) {
1066 luaL_error(L, "pdf.newcolorstack() expects a string as first argument");
1068 s = lua_tostring(L, 1);
1069 if (lua_type(L,2) == LUA_TSTRING) {
1070 l = lua_tostring(L, 2);
1071 if (lua_key_eq(l,origin)) {
1072 literal_mode = 0;
1073 } else if (lua_key_eq(l,page)) {
1074 literal_mode = 1; /* direct_page */
1075 } else if (lua_key_eq(l,direct)) {
1076 literal_mode = 2; /* direct_always */
1077 } else {
1078 luaL_error(L, "invalid literal mode in pdf.newcolorstack()");
1081 if (lua_isboolean(L, 3)) {
1082 page_start = lua_toboolean(L, 3);
1084 id = newcolorstack(s, literal_mode, page_start);
1085 lua_pushinteger(L, id);
1086 return 1 ;
1090 static int l_set_font_attributes(lua_State * L)
1092 int f = luaL_checkinteger(L, -2);
1093 int i ;
1094 /*char *s;*/
1095 const char *st;
1096 if ((lua_type(L,-1) == LUA_TSTRING) && (st = lua_tostring(L, -1)) != NULL) {
1097 /* is this dup needed? */
1098 /*s = xstrdup(st);*/
1099 i = maketexstring(st); /* brrr */
1100 set_pdf_font_attr(f, i);
1101 /*free(s);*/
1103 return 0;
1107 static const struct luaL_Reg pdflib[] = {
1108 { "gethpos", l_gethpos },
1109 { "getvpos", l_getvpos },
1110 { "obj", l_obj },
1111 { "immediateobj", l_immediateobj },
1112 { "refobj", l_refobj },
1113 { "registerannot", l_registerannot },
1114 { "reserveobj", l_reserveobj },
1115 { "getpos", l_getpos },
1116 /* { "pageref", getpdfpageref }, */
1117 { "maxobjnum", l_maxobjnum },
1118 { "pageref", l_pageref },
1119 { "print", luapdfprint },
1120 { "objtype", l_objtype },
1121 { "getmatrix", l_getmatrix },
1122 { "hasmatrix", l_hasmatrix },
1123 { "setfontattributes", l_set_font_attributes },
1124 { "setcatalog", l_set_catalog },
1125 { "setinfo", l_set_info },
1126 { "setnames", l_set_names },
1127 { "settrailer", l_set_trailer },
1128 { "setpageresources", l_set_pageresources },
1129 { "setpageattributes", l_set_pageattributes },
1130 { "setpagesattributes", l_set_pagesattributes },
1131 { "setxformresources", l_set_xformresources },
1132 { "setxformattributes", l_set_xformattributes },
1133 { "settrailerid", l_set_trailerid },
1134 { "getcatalog", l_get_catalog },
1135 { "getinfo", l_get_info },
1136 { "getnames", l_get_names },
1137 { "gettrailer", l_get_trailer },
1138 { "getpageresources", l_get_pageresources },
1139 { "getpageattributes", l_get_pageattributes },
1140 { "getpagesattributes", l_get_pagesattributes },
1141 { "getxformresources", l_get_xformresources },
1142 { "getxformattributes", l_get_xformattributes },
1143 { "gettrailerid", l_get_trailerid },
1144 { "getlastlink", l_get_lastlink },
1145 { "getretval", l_get_retval },
1146 { "getlastobj", l_get_lastobj },
1147 { "getlastannot", l_get_lastannot },
1148 { "getcompresslevel", l_get_compress_level },
1149 { "getobjcompresslevel", l_get_obj_compress_level },
1150 { "setcompresslevel", l_set_compress_level },
1151 { "setobjcompresslevel", l_set_obj_compress_level },
1152 { "getdecimaldigits", l_get_decimal_digits },
1153 { "setdecimaldigits", l_set_decimal_digits },
1154 { "getpkresolution", l_get_pk_resolution },
1155 { "setpkresolution", l_set_pk_resolution },
1156 { "getsuppressoptionalinfo", l_get_suppress_optional_info },
1157 { "setsuppressoptionalinfo", l_set_suppress_optional_info },
1158 /* moved from tex table */
1159 { "fontname", getpdffontname },
1160 { "fontobjnum", getpdffontobjnum },
1161 { "fontsize", getpdffontsize },
1162 { "xformname", getpdfxformname },
1163 { "getversion", getpdfversion },
1164 { "getcreationdate", getpdfcreationdate },
1165 { "getminorversion", getpdfminorversion },
1166 { "setminorversion", setpdfminorversion },
1167 { "newcolorstack", newpdfcolorstack },
1168 { "setorigin", setpdforigin },
1169 { "getorigin", getpdforigin },
1170 { "setimageresolution", setpdfimageresolution },
1171 { "getimageresolution", getpdfimageresolution },
1172 { "setthreadmargin", setpdfthreadmargin },
1173 { "setdestmargin", setpdfdestmargin },
1174 { "setlinkmargin", setpdflinkmargin },
1175 { "setxformmargin", setpdfxformmargin },
1176 { "getthreadmargin", getpdfthreadmargin },
1177 { "getdestmargin", getpdfdestmargin },
1178 { "getlinkmargin", getpdflinkmargin },
1179 { "getxformmargin", getpdfxformmargin },
1180 { "getinclusionerrorlevel", getpdfinclusionerrorlevel },
1181 { "getignoreunknownimages", getpdfignoreunknownimages },
1182 { "setinclusionerrorlevel", setpdfinclusionerrorlevel },
1183 { "setignoreunknownimages", setpdfignoreunknownimages },
1184 { "mapfile", l_mapfile },
1185 { "mapline", l_mapline },
1186 /* sentinel */
1187 {NULL, NULL}
1190 int luaopen_pdf(lua_State * L)
1192 lua_pushstring(L,"pdf.data");
1193 lua_newtable(L);
1194 lua_settable(L,LUA_REGISTRYINDEX);
1195 /* */
1196 luaL_register(L, "pdf", pdflib);
1198 luaL_newmetatable(L, "pdf.meta");
1199 lua_pushstring(L, "__index");
1200 lua_pushcfunction(L, getpdf);
1201 lua_settable(L, -3);
1202 lua_pushstring(L, "__newindex");
1203 lua_pushcfunction(L, setpdf);
1204 lua_settable(L, -3);
1205 lua_setmetatable(L, -2);
1207 return 1;