3 % Copyright
2010-2012 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 #define count
(A
) eqtb
[count_base
+(A
)].cint
27 #define mag int_par
(mag_code
)
28 #define h_offset dimen_par
(h_offset_code
)
29 #define page_bottom_offset dimen_par
(page_bottom_offset_code
)
30 #define page_height dimen_par
(page_height_code
)
31 #define page_left_offset dimen_par
(page_left_offset_code
)
32 #define page_right_offset dimen_par
(page_right_offset_code
)
33 #define page_top_offset dimen_par
(page_top_offset_code
)
34 #define page_width dimen_par
(page_width_code
)
35 #define tracing_output int_par
(tracing_output_code
)
36 #define tracing_stats int_par
(tracing_stats_code
)
37 #define v_offset dimen_par
(v_offset_code
)
39 scaledpos shipbox_refpos
;
41 @ |ship_out| is used to shipout a box to PDF or DVI mode. If |shipping_mode| is
42 set to |SHIPPING_FORM| then the output will be a Form object
(only PDF
), and if
43 it is set to |SHIPPING_PAGE| it will be a Page object.
46 void ship_out
(PDF pdf
, halfword p
, shipping_mode_e shipping_mode
)
48 int j
, k
; /* indices to first ten count registers
*/
51 posstructure refpoint
; /* the origin pos. on the page
*/
52 int rule_callback_id
= 0;
53 scaledpos cur
= { 0, 0 };
56 ensure_output_state
(pdf
, ST_HEADER_WRITTEN
);
57 fix_o_mode
(); /* this is only for complaining if \.
{\\outputmode
} has changed
*/
58 init_backend_functionpointers
(output_mode_used
);
59 pdf-
>f_cur
= null_font
;
61 Start sheet
{\sl Sync\TeX
} information record
; we assume that |pdf_output| is
64 if
(int_par
(synctex_code
))
66 pre_callback_id
= callback_defined
(start_page_number_callback
);
67 post_callback_id
= callback_defined
(stop_page_number_callback
);
68 if
((tracing_output
> 0) && (pre_callback_id == 0)) {
71 tprint
("Completed box being shipped out");
73 global_shipping_mode
= shipping_mode
;
74 if
(shipping_mode
== SHIPPING_PAGE
) {
75 if
(pre_callback_id
> 0)
76 (void
) run_callback
(pre_callback_id
, "->");
77 else if
(pre_callback_id
== 0) {
78 if
(term_offset
> max_print_line
- 9)
80 else if
((term_offset
> 0) ||
(file_offset
> 0))
84 while
((count
(j
) == 0) && (j > 0))
86 for
(k
= 0; k
<= j
; k
++) {
93 if
((tracing_output
> 0) && shipping_mode == SHIPPING_PAGE) {
100 /* Ship box |p| out
*/
101 if
(shipping_mode
== SHIPPING_PAGE
&& box_dir(p) != page_direction)
102 normal_warning
("backend","pagedir differs from bodydir, the output may be placed wrongly on the page");
104 Update the values of |max_h| and |max_v|
; but if the page is too large
,
105 |goto done|. Sometimes the user will generate a huge page because other
106 error messages are being ignored. Such pages are not output to the
107 \.
{dvi
} file
, since they may confuse the printing software.
109 if
((height
(p
) > max_dimen
) ||
(depth
(p
) > max_dimen
) ||
(height
(p
) + depth
(p
) + v_offset
> max_dimen
) ||
(width
(p
) + h_offset
> max_dimen
)) {
110 const char
*hlp
[] = {
111 "The page just created is more than 18 feet tall or",
112 "more than 18 feet wide, so I suspect something went wrong.",
115 tex_error
("Huge page cannot be shipped out", hlp
);
116 if
(tracing_output
<= 0) {
118 tprint_nl
("The following box has been deleted:");
120 end_diagnostic
(true
);
124 if
(height
(p
) + depth
(p
) + v_offset
> max_v
)
125 max_v
= height
(p
) + depth
(p
) + v_offset
;
126 if
(width
(p
) + h_offset
> max_h
)
127 max_h
= width
(p
) + h_offset
;
128 /* Calculate page dimensions and margins
*/
129 if
(global_shipping_mode
== SHIPPING_PAGE
) {
131 pdf-
>page_size.h
= page_width
;
133 switch
(page_direction
) {
135 pdf-
>page_size.h
= width
(p
) + 2 * page_left_offset
;
138 pdf-
>page_size.h
= width
(p
) + 2 * page_right_offset
;
141 pdf-
>page_size.h
= height
(p
) + depth
(p
) + 2 * page_left_offset
;
144 pdf-
>page_size.h
= height
(p
) + depth
(p
) + 2 * page_right_offset
;
147 pdf-
>page_size.h
= width
(p
) + 2 * page_left_offset
;
148 normal_warning
("pdf backend","bad page direction, assuming TLT, case 1");
152 pdf-
>page_size.v
= page_height
;
154 switch
(page_direction
) {
157 pdf-
>page_size.v
= height
(p
) + depth
(p
) + 2 * page_top_offset
;
161 pdf-
>page_size.v
= width
(p
) + 2 * page_top_offset
;
164 pdf-
>page_size.v
= height
(p
) + depth
(p
) + 2 * page_top_offset
;
165 normal_warning
("pdf backend","bad page direction, assuming TLT, case 2");
169 Think in upright page
/paper coordinates
(page origin
= lower left edge
).
170 First preset |refpoint.pos| to the DVI origin
(near upper left page edge
).
172 switch
(output_mode_used
) {
174 /* hh
: how can we end up here?
*/
175 refpoint.pos.h
= one_true_inch
;
176 refpoint.pos.v
= pdf-
>page_size.v
- one_true_inch
;
180 refpoint.pos.h
= pdf_h_origin
;
181 refpoint.pos.v
= pdf-
>page_size.v
- pdf_v_origin
;
184 normal_error
("pdf backend", "unknown output mode");
188 Then shift |refpoint.pos| of the DVI origin depending on the
189 |page_direction| within the upright
(TLT
) page coordinate system
191 switch
(page_direction
) {
194 refpoint.pos.h
+= h_offset
;
195 refpoint.pos.v
-= v_offset
;
199 refpoint.pos.h
+= pdf-
>page_size.h
- page_right_offset
- one_true_inch
;
200 refpoint.pos.v
-= v_offset
;
203 refpoint.pos.h
+= h_offset
;
204 refpoint.pos.v
-= v_offset
;
205 normal_warning
("pdf backend","bad page direction, assuming TLT, case 3");
208 Then switch to page box coordinate system
; do |height
(p
)| movement
,
209 to get the location of the box origin.
211 pdf-
>posstruct-
>dir
= page_direction
;
214 synch_pos_with_cur
(pdf-
>posstruct
, &refpoint, cur);
216 /* shipping a
/Form
*/
217 pdf-
>posstruct-
>dir
= box_dir
(p
);
218 switch
(pdf-
>posstruct-
>dir
) {
221 pdf-
>page_size.h
= width
(p
);
222 pdf-
>page_size.v
= height
(p
) + depth
(p
);
226 pdf-
>page_size.h
= height
(p
) + depth
(p
);
227 pdf-
>page_size.v
= width
(p
);
230 pdf-
>page_size.h
= width
(p
);
231 pdf-
>page_size.v
= height
(p
) + depth
(p
);
232 normal_warning
("pdf backend","bad page direction, assuming TLT, case 4");
234 switch
(pdf-
>posstruct-
>dir
) {
236 pdf-
>posstruct-
>pos.h
= 0;
237 pdf-
>posstruct-
>pos.v
= depth
(p
);
240 pdf-
>posstruct-
>pos.h
= width
(p
);
241 pdf-
>posstruct-
>pos.v
= depth
(p
);
244 pdf-
>posstruct-
>pos.h
= height
(p
);
245 pdf-
>posstruct-
>pos.v
= width
(p
);
248 pdf-
>posstruct-
>pos.h
= depth
(p
);
249 pdf-
>posstruct-
>pos.v
= width
(p
);
252 pdf-
>posstruct-
>pos.h
= 0;
253 pdf-
>posstruct-
>pos.v
= depth
(p
);
254 normal_warning
("pdf backend","bad page direction, assuming TLT, case 5");
257 /* Now we are at the point on the page where the origin of the page box should go.
*/
258 shipbox_refpos
= pdf-
>posstruct-
>pos
; /* for \.
{\\gleaders
} */
259 switch
(output_mode_used
) {
267 normal_error
("pdf backend", "unknown output mode");
269 rule_callback_id
= callback_defined
(process_rule_callback
);
272 vlist_out
(pdf
, p
, rule_callback_id
);
275 hlist_out
(pdf
, p
, rule_callback_id
);
278 normal_error
("pdf backend", "no vlist or hlist in (xform) shipout");
280 if
(shipping_mode
== SHIPPING_PAGE
)
283 /* Finish shipping
*/
284 switch
(output_mode_used
) {
292 normal_error
("pdf backend", "unknown output mode");
295 if
((tracing_output
<= 0) && (post_callback_id == 0) && shipping_mode == SHIPPING_PAGE) {
300 /* Flush the box from memory
, showing statistics if requested
*/
301 if
((tracing_stats
> 1) && (pre_callback_id == 0)) {
302 tprint_nl
("Memory usage before: ");
309 if
((tracing_stats
> 1) && (post_callback_id == 0)) {
316 if
(shipping_mode
== SHIPPING_PAGE
&& (post_callback_id > 0))
317 (void
) run_callback
(post_callback_id
, "->");
318 /* Finish sheet
{\sl Sync\TeX
} information record
*/
319 if
(int_par
(synctex_code
))
321 global_shipping_mode
= NOT_SHIPPING
;