3 % Copyright
2009-2010 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
/>.
25 const char
*pdf_obj_typenames
[PDF_OBJ_TYPE_MAX
+ 1] = {
26 "font", "outline", "dest", "obj", "xform", "ximage", "thread",
27 "pagestream", "page", "pages", "catalog", "info", "link", "annot", "annots",
28 "bead", "beads", "objstm", "others"
34 int pdf_retval
; /* global multi-purpose return value
*/
36 @ AVL sort entry into |avl_table
[]|
38 static int compare_info
(const void
*pa
, const void
*pb
, void
*param
)
40 const oentry
*a
= (const oentry
*) pa
;
41 const oentry
*b
= (const oentry
*) pb
;
43 if
(a-
>u_type
== b-
>u_type
) {
44 if
(a-
>u_type
== union_type_int
)
45 return
((a-
>u.int0
< b-
>u.int0 ?
-1 : (a-
>u.int0
> b-
>u.int0 ?
1 : 0)));
46 else
/* string type
*/
47 return strcmp
(a-
>u.str0
, b-
>u.str0
);
48 } else if
(a-
>u_type
== union_type_int
) {
55 static void avl_put_obj
(PDF pdf
, int t
, oentry
* oe
)
58 if
(pdf-
>obj_tree
[t
] == NULL) {
59 pdf-
>obj_tree
[t
] = avl_create
(compare_info
, NULL, &avl_xallocator);
60 if
(pdf-
>obj_tree
[t
] == NULL)
61 formatted_error
("pdf backend","avl_create() pdf->obj_tree failed");
63 pp
= avl_probe
(pdf-
>obj_tree
[t
], oe
);
65 formatted_error
("pdf backend","avl_probe() out of memory in insertion");
68 static void avl_put_int_obj
(PDF pdf
, int int0
, int objptr
, int t
)
70 oentry
*oe
= xtalloc
(1, oentry
);
72 oe-
>u_type
= union_type_int
;
74 avl_put_obj
(pdf
, t
, oe
);
77 static void avl_put_str_obj
(PDF pdf
, char
*str0
, int objptr
, int t
)
79 oentry
*oe
= xtalloc
(1, oentry
);
80 oe-
>u.str0
= str0
; /* no xstrdup
() here
*/
81 oe-
>u_type
= union_type_cstring
;
83 avl_put_obj
(pdf
, t
, oe
);
86 static int avl_find_int_obj
(PDF pdf
, int t
, int i
)
91 tmp.u_type
= union_type_int
;
92 if
(pdf-
>obj_tree
[t
] == NULL)
94 p
= (oentry
*) avl_find
(pdf-
>obj_tree
[t
], &tmp);
100 static int avl_find_str_obj
(PDF pdf
, int t
, char
*s
)
105 tmp.u_type
= union_type_cstring
;
106 if
(pdf-
>obj_tree
[t
] == NULL)
108 p
= (oentry
*) avl_find
(pdf-
>obj_tree
[t
], &tmp);
114 @ Create an object with type |t| and identifier |i|
117 int pdf_create_obj
(PDF pdf
, int t
, int i
)
121 if
(pdf-
>obj_ptr
== sup_obj_tab_size
)
122 overflow
("indirect objects table size", (unsigned
) pdf-
>obj_tab_size
);
123 if
(pdf-
>obj_ptr
== pdf-
>obj_tab_size
) {
124 a
= pdf-
>obj_tab_size
/ 5;
125 if
(pdf-
>obj_tab_size
< sup_obj_tab_size
- a
)
126 pdf-
>obj_tab_size
= pdf-
>obj_tab_size
+ a
;
128 pdf-
>obj_tab_size
= sup_obj_tab_size
;
129 pdf-
>obj_tab
= xreallocarray
(pdf-
>obj_tab
, obj_entry
, (unsigned
) pdf-
>obj_tab_size
);
132 obj_info
(pdf
, pdf-
>obj_ptr
) = i
;
133 obj_type
(pdf
, pdf-
>obj_ptr
) = t
;
134 set_obj_fresh
(pdf
, pdf-
>obj_ptr
);
135 obj_aux
(pdf
, pdf-
>obj_ptr
) = 0;
137 ss
= makecstring
(-i
);
138 avl_put_str_obj
(pdf
, ss
, pdf-
>obj_ptr
, t
);
140 avl_put_int_obj
(pdf
, i
, pdf-
>obj_ptr
, t
);
141 if
(t
<= HEAD_TAB_MAX
) {
142 obj_link
(pdf
, pdf-
>obj_ptr
) = pdf-
>head_tab
[t
];
143 pdf-
>head_tab
[t
] = pdf-
>obj_ptr
;
144 if
((t
== obj_type_dest
) && (i < 0))
145 append_dest_name
(pdf
, makecstring
(-obj_info
(pdf
, pdf-
>obj_ptr
)), pdf-
>obj_ptr
); /* why not just
-i
*/
151 int find_obj
(PDF pdf
, int t
, int i
, boolean byname
)
157 ret
= avl_find_str_obj
(pdf
, t
, ss
);
160 ret
= avl_find_int_obj
(pdf
, t
, i
);
165 @ The following function finds an object with identifier |i| and type |t|.
166 Identifier |i| is either an integer or a token list index. If no such object
167 exists then it will be created. This function is used mainly to find destination
168 for link annotations and outlines
; however it is also used in |ship_out|
(to
169 check whether a Page object already exists
) so we need to declare it together
170 with subroutines needed in |hlist_out| and |vlist_out|.
173 int pdf_get_obj
(PDF pdf
, int t
, int i
, boolean byname
)
178 s
= tokens_to_string
(i
);
179 r
= find_obj
(pdf
, t
, s
, true
);
182 r
= find_obj
(pdf
, t
, i
, false
);
186 r
= pdf_create_obj
(pdf
, t
, -s
);
189 r
= pdf_create_obj
(pdf
, t
, i
);
191 if
(t
== obj_type_dest
)
192 set_obj_dest_ptr
(pdf
, r
, null
);
201 void check_obj_exists
(PDF pdf
, int objnum
)
203 if
(objnum
< 0 || objnum
> pdf-
>obj_ptr
)
204 normal_error
("pdf backend", "cannot find referenced object");
207 void check_obj_type
(PDF pdf
, int t
, int objnum
)
210 check_obj_exists
(pdf
, objnum
);
211 u
= obj_type
(pdf
, objnum
);
213 formatted_error
("pdf backend", "referenced object has wrong type %s; should be %s",
214 pdf_obj_typenames
[u
], pdf_obj_typenames
[t
]);
219 void set_rect_dimens
(PDF pdf
, halfword p
, halfword parent_box
, scaledpos cur
, scaled_whd alt_rule
, scaled margin
)
221 scaledpos ll
, ur
; /* positions relative to cur
*/
222 scaledpos pos_ll
, pos_ur
, tmp
;
223 posstructure localpos
;
224 localpos.dir
= pdf-
>posstruct-
>dir
;
225 ll.h
= 0; /* pdf contains current point on page
*/
226 if
(is_running
(alt_rule.dp
))
227 ll.v
= depth
(parent_box
) - cur.v
;
230 if
(is_running
(alt_rule.wd
))
231 ur.h
= width
(parent_box
) - cur.h
;
234 if
(is_running
(alt_rule.ht
))
235 ur.v
= -height
(parent_box
) - cur.v
;
238 synch_pos_with_cur
(&localpos, pdf->posstruct, ll);
239 pos_ll
= localpos.pos
;
240 synch_pos_with_cur
(&localpos, pdf->posstruct, ur);
241 pos_ur
= localpos.pos
;
242 if
(pos_ll.h
> pos_ur.h
) {
247 if
(pos_ll.v
> pos_ur.v
) {
252 if
(global_shipping_mode
== SHIPPING_PAGE
&& matrixused()) {
253 matrixtransformrect
(pos_ll.h
, pos_ll.v
, pos_ur.h
, pos_ur.v
);
259 pdf_ann_left
(p
) = pos_ll.h
- margin
;
260 pdf_ann_bottom
(p
) = pos_ll.v
- margin
;
261 pdf_ann_right
(p
) = pos_ur.h
+ margin
;
262 pdf_ann_top
(p
) = pos_ur.v
+ margin
;
266 void libpdffinish
(PDF pdf
)
268 strbuf_free
(pdf-
>fb
);
269 xfree
(pdf-
>job_id_string
);
276 glyph_unicode_free
();