fix getsup (HH)
[luatex.git] / source / texk / web2c / luatexdir / pdf / pdfobj.w
blobe5ca09de624f238cc0ce3f9260c5eac2b2912097
1 % pdfobj.w
3 % Copyright 2009-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/>.
20 @ @c
21 #include "ptexlib.h"
22 #include "lua/luatex-api.h"
24 @ write a raw PDF object
27 void pdf_write_obj(PDF pdf, int k)
29 lstring data;
30 const_lstring st;
31 size_t li; /* index into |data.s| */
32 int saved_compress_level ;
33 int os_threshold = OBJSTM_ALWAYS; /* gives compressed objects for \.{\\pdfvariable objcompresslevel} >= |OBJSTM_ALWAYS| */
34 int l = 0; /* possibly a lua registry reference */
35 int ll = 0;
36 data.s = NULL;
37 /* we can have an immediate object before we are initialized */
38 ensure_output_state(pdf, ST_HEADER_WRITTEN);
39 saved_compress_level = pdf->compress_level;
40 /* end of ugly hack */
41 if (obj_obj_pdfcompresslevel(pdf, k) > -1) { /* -1 = "unset" */
42 pdf->compress_level = obj_obj_pdfcompresslevel(pdf, k);
43 if (pdf->compress_level == 0) {
44 pdf->objcompresslevel = 0;
47 if (obj_obj_objstm_threshold(pdf, k) != OBJSTM_UNSET)
48 os_threshold = obj_obj_objstm_threshold(pdf, k);
49 if (obj_obj_is_stream(pdf, k)) {
50 pdf_begin_obj(pdf, k, OBJSTM_NEVER);
51 pdf_begin_dict(pdf);
52 l = obj_obj_stream_attr(pdf, k);
53 if (l != LUA_NOREF) {
54 lua_rawgeti(Luas, LUA_REGISTRYINDEX, l);
55 if (lua_type(Luas,-1) != LUA_TSTRING)
56 normal_error("pdf backend","invalid object");
57 st.s = lua_tolstring(Luas, -1, &li);
58 st.l = li;
59 pdf_out_block(pdf, st.s, st.l);
60 if (st.s[st.l - 1] != '\n')
61 pdf_out(pdf, '\n');
62 luaL_unref(Luas, LUA_REGISTRYINDEX, l);
63 obj_obj_stream_attr(pdf, k) = LUA_NOREF;
65 pdf_dict_add_streaminfo(pdf);
66 pdf_end_dict(pdf);
67 pdf_begin_stream(pdf);
68 } else
69 pdf_begin_obj(pdf, k, os_threshold);
70 l = obj_obj_data(pdf, k);
71 lua_rawgeti(Luas, LUA_REGISTRYINDEX, l);
72 if (lua_type(Luas,-1) != LUA_TSTRING)
73 normal_error("pdf backend","invalid object");
74 st.s = lua_tolstring(Luas, -1, &li);
75 st.l = li;
76 lua_pop(Luas, 1);
77 if (obj_obj_is_file(pdf, k)) {
78 boolean res = false; /* callback status value */
79 const char *fnam = NULL; /* callback found filename */
80 int callback_id;
81 /* st.s is also |\0|-terminated, even as lstring */
82 fnam = luatex_find_file(st.s, find_data_file_callback);
83 callback_id = callback_defined(read_data_file_callback);
84 if (fnam && callback_id > 0) {
85 boolean file_opened = false;
86 res = run_callback(callback_id, "S->bSd", fnam, &file_opened, &data.s, &ll);
87 data.l = (size_t) ll;
88 if (!file_opened)
89 normal_error("pdf backend", "cannot open file for embedding");
90 } else {
91 byte_file f; /* the data file's FILE* */
92 if (!fnam)
93 fnam = st.s;
94 if (!luatex_open_input(&f, fnam, kpse_tex_format, FOPEN_RBIN_MODE, true))
95 normal_error("pdf backend", "cannot open file for embedding");
96 res = read_data_file(f, &data.s, &ll);
97 data.l = (size_t) ll;
98 close_file(f);
100 if (data.l == 0L)
101 normal_error("pdf backend", "empty file for embedding");
102 if (!res)
103 normal_error("pdf backend", "error reading file for embedding");
104 tprint("<<");
105 tprint(st.s);
106 pdf_out_block(pdf, (const char *) data.s, data.l);
107 xfree(data.s);
108 tprint(">>");
109 } else {
110 pdf_out_block(pdf, st.s, st.l);
112 if (obj_obj_is_stream(pdf, k)) {
113 pdf_end_stream(pdf);
114 pdf_end_obj(pdf);
115 } else /* here we do the \n */
116 pdf_end_obj(pdf);
117 luaL_unref(Luas, LUA_REGISTRYINDEX, l);
118 obj_obj_data(pdf, k) = LUA_NOREF;
119 pdf->compress_level = saved_compress_level;
122 @ @c
123 void init_obj_obj(PDF pdf, int k)
125 obj_obj_stream_attr(pdf, k) = LUA_NOREF;
126 obj_obj_data(pdf, k) = LUA_NOREF;
127 unset_obj_obj_is_stream(pdf, k);
128 unset_obj_obj_is_file(pdf, k);
129 obj_obj_pdfcompresslevel(pdf, k) = -1; /* unset */
130 obj_obj_objstm_threshold(pdf, k) = OBJSTM_UNSET; /* unset */
133 @ The \.{\\pdfextension obj} primitive is used to create a ``raw'' object in the
134 PDF output file. The object contents will be hold in memory and will be written
135 out only when the object is referenced by \.{\\pdfextension refobj}. When
136 \.{\\pdfextension obj} is used with \.{\\immediate}, the object contents will be
137 written out immediately. Objects referenced in the current page are appended into
138 |pdf_obj_list|.
141 void scan_obj(PDF pdf)
143 int k;
144 lstring *st = NULL;
145 if (scan_keyword("reserveobjnum")) {
146 get_x_token();
147 if (cur_cmd != spacer_cmd)
148 back_input();
149 pdf->obj_count++;
150 k = pdf_create_obj(pdf, obj_type_obj, 0);
151 } else {
152 if (scan_keyword("useobjnum")) {
153 scan_int();
154 k = cur_val;
155 check_obj_type(pdf, obj_type_obj, k);
156 if (is_obj_scheduled(pdf, k) || obj_data_ptr(pdf, k) != 0)
157 luaL_error(Luas, "object in use");
158 } else {
159 pdf->obj_count++;
160 k = pdf_create_obj(pdf, obj_type_obj, 0);
162 obj_data_ptr(pdf, k) = pdf_get_mem(pdf, pdfmem_obj_size);
163 init_obj_obj(pdf, k);
164 if (scan_keyword("uncompressed")) {
165 obj_obj_pdfcompresslevel(pdf, k) = 0;
166 obj_obj_objstm_threshold(pdf, k) = OBJSTM_NEVER;
168 if (scan_keyword("stream")) {
169 set_obj_obj_is_stream(pdf, k);
170 if (scan_keyword("attr")) {
171 scan_toks(false, true);
172 st = tokenlist_to_lstring(def_ref, true);
173 flush_list(def_ref);
174 lua_pushlstring(Luas, (char *) st->s, st->l);
175 obj_obj_stream_attr(pdf, k) = luaL_ref(Luas, LUA_REGISTRYINDEX);
176 free_lstring(st);
177 st = NULL;
180 if (scan_keyword("file"))
181 set_obj_obj_is_file(pdf, k);
182 scan_toks(false, true);
183 st = tokenlist_to_lstring(def_ref, true);
184 flush_list(def_ref);
185 lua_pushlstring(Luas, (char *) st->s, st->l);
186 obj_obj_data(pdf, k) = luaL_ref(Luas, LUA_REGISTRYINDEX);
187 free_lstring(st);
188 st = NULL;
190 pdf_last_obj = k;
193 @ @c
194 void scan_refobj(PDF pdf)
196 scan_int();
197 check_obj_type(pdf, obj_type_obj, cur_val);
198 new_whatsit(pdf_refobj_node);
199 pdf_obj_objnum(tail_par) = cur_val;
202 void scan_refobj_lua(PDF pdf, int k)
204 check_obj_type(pdf, obj_type_obj, k);
205 new_whatsit(pdf_refobj_node);
206 pdf_obj_objnum(tail_par) = k;
209 @ @c
210 void pdf_ref_obj(PDF pdf, halfword p)
212 if (!is_obj_scheduled(pdf, pdf_obj_objnum(p)))
213 addto_page_resources(pdf, obj_type_obj, pdf_obj_objnum(p));
216 @ @c
217 void pdf_ref_obj_lua(PDF pdf, int k)
219 if (!is_obj_scheduled(pdf, k))
220 addto_page_resources(pdf, obj_type_obj, k);