diff options
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/pdf/pdfshipout.w')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/pdf/pdfshipout.w | 332 |
1 files changed, 332 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfshipout.w b/Build/source/texk/web2c/luatexdir/pdf/pdfshipout.w new file mode 100644 index 00000000000..70809ef1b0f --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfshipout.w @@ -0,0 +1,332 @@ +% pdfshipout.w + +% Copyright 2010 Taco Hoekwater <taco@@luatex.org> + +% This file is part of LuaTeX. + +% LuaTeX is free software; you can redistribute it and/or modify it under +% the terms of the GNU General Public License as published by the Free +% Software Foundation; either version 2 of the License, or (at your +% option) any later version. + +% LuaTeX is distributed in the hope that it will be useful, but WITHOUT +% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +% License for more details. + +% You should have received a copy of the GNU General Public License along +% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +@ @c +static const char _svn_version[] = + "$Id: pdfshipout.w 3571 2010-04-02 13:50:45Z taco $" + "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/pdf/pdfshipout.w $"; + +#include "ptexlib.h" + +@ @c +#define count(A) eqtb[count_base+(A)].cint +#define h_offset dimen_par(h_offset_code) +#define mag int_par(mag_code) +#define page_bottom_offset dimen_par(page_bottom_offset_code) +#define page_direction int_par(page_direction_code) +#define page_height dimen_par(page_height_code) +#define page_left_offset dimen_par(page_left_offset_code) +#define page_right_offset dimen_par(page_right_offset_code) +#define page_top_offset dimen_par(page_top_offset_code) +#define page_width dimen_par(page_width_code) +#define pdf_h_origin dimen_par(pdf_h_origin_code) +#define pdf_v_origin dimen_par(pdf_v_origin_code) +#define tracing_output int_par(tracing_output_code) +#define tracing_stats int_par(tracing_stats_code) +#define v_offset dimen_par(v_offset_code) + +scaledpos shipbox_refpos; + +@ |ship_out| is used to shipout a box to PDF or DVI mode. +If |shipping_page| is not set then the output will be a Form object +(only PDF), otherwise it will be a Page object. + +@c +void ship_out(PDF pdf, halfword p, boolean shipping_page) +{ + /* output the box |p| */ + int j, k; /* indices to first ten count registers */ + int post_callback_id; + int pre_callback_id; + posstructure refpoint; /* the origin pos. on the page */ + scaledpos cur = { 0, 0 }; + refpoint.pos.h = 0; + refpoint.pos.v = 0; + + ensure_output_state(pdf, ST_HEADER_WRITTEN); + fix_o_mode(pdf); /* this is only for complaining if \.{\\pdfoutput} has changed */ + init_backend_functionpointers(pdf->o_mode); + + pdf->f_cur = null_font; + + /* Start sheet {\sl Sync\TeX} information record */ + /* {\sl Sync\TeX}: we assume that |pdf_output| is properly set up */ + if (int_par(synctex_code)) + synctexsheet(mag); + + pre_callback_id = callback_defined(start_page_number_callback); + post_callback_id = callback_defined(stop_page_number_callback); + if ((tracing_output > 0) && (pre_callback_id == 0)) { + tprint_nl(""); + print_ln(); + tprint("Completed box being shipped out"); + } + is_shipping_page = shipping_page; + if (shipping_page) { + if (pre_callback_id > 0) + (void) run_callback(pre_callback_id, "->"); + else if (pre_callback_id == 0) { + if (term_offset > max_print_line - 9) + print_ln(); + else if ((term_offset > 0) || (file_offset > 0)) + print_char(' '); + print_char('['); + j = 9; + while ((count(j) == 0) && (j > 0)) + decr(j); + for (k = 0; k <= j; k++) { + print_int(count(k)); + if (k < j) + print_char('.'); + } + } + } + if ((tracing_output > 0) && shipping_page) { + print_char(']'); + update_terminal(); + begin_diagnostic(); + show_box(p); + end_diagnostic(true); + } + + /* Ship box |p| out */ + if (shipping_page && box_dir(p) != page_direction) + pdf_warning("\\shipout", + "\\pagedir != \\bodydir; " + "\\box\\outputbox may be placed wrongly on the page.", true, + true); + /* Update the values of |max_h| and |max_v|; but if the page is too large, |goto done| */ + /* Sometimes the user will generate a huge page because other error messages + are being ignored. Such pages are not output to the \.{dvi} file, since they + may confuse the printing software. */ + + if ((height(p) > max_dimen) || (depth(p) > max_dimen) + || (height(p) + depth(p) + v_offset > max_dimen) + || (width(p) + h_offset > max_dimen)) { + const char *hlp[] = + { "The page just created is more than 18 feet tall or", + "more than 18 feet wide, so I suspect something went wrong.", + NULL + }; + tex_error("Huge page cannot be shipped out", hlp); + if (tracing_output <= 0) { + begin_diagnostic(); + tprint_nl("The following box has been deleted:"); + show_box(p); + end_diagnostic(true); + } + goto DONE; + } + if (height(p) + depth(p) + v_offset > max_v) + max_v = height(p) + depth(p) + v_offset; + if (width(p) + h_offset > max_h) + max_h = width(p) + h_offset; + + /* Calculate page dimensions and margins */ + if (is_shipping_page) { + if (page_width > 0) + cur_page_size.h = page_width; + else { + switch (page_direction) { + case dir_TLT: + cur_page_size.h = width(p) + 2 * page_left_offset; + break; + case dir_TRT: + cur_page_size.h = width(p) + 2 * page_right_offset; + break; + case dir_LTL: + cur_page_size.h = height(p) + depth(p) + 2 * page_left_offset; + break; + case dir_RTT: + cur_page_size.h = height(p) + depth(p) + 2 * page_right_offset; + break; + } + } + if (page_height > 0) + cur_page_size.v = page_height; + else { + switch (page_direction) { + case dir_TLT: + case dir_TRT: + cur_page_size.v = height(p) + depth(p) + 2 * page_top_offset; + break; + case dir_LTL: + case dir_RTT: + cur_page_size.v = width(p) + 2 * page_top_offset; + break; + } + } + + /* Think in upright page/paper coordinates (page origin = lower left edge). + First preset |refpoint.pos| to the DVI origin (near upper left page edge). */ + + switch (pdf->o_mode) { + case OMODE_DVI: + refpoint.pos.h = one_true_inch; + refpoint.pos.v = cur_page_size.v - one_true_inch; + dvi = refpoint.pos; + break; + case OMODE_PDF: + case OMODE_LUA: + refpoint.pos.h = pdf_h_origin; + refpoint.pos.v = cur_page_size.v - pdf_v_origin; + break; + default: + assert(0); + } + + /* Then shift |refpoint.pos| of the DVI origin depending on the + |page_direction| within the upright (TLT) page coordinate system */ + + switch (page_direction) { + case dir_TLT: + case dir_LTL: + refpoint.pos.h += h_offset; + refpoint.pos.v -= v_offset; + break; + case dir_TRT: + case dir_RTT: + refpoint.pos.h += + cur_page_size.h - page_right_offset - one_true_inch; + refpoint.pos.v -= v_offset; + break; + } + + /* Then switch to page box coordinate system; do |height(p)| movement, + to get the location of the box origin. */ + + pdf->posstruct->dir = page_direction; + cur.h = 0; + cur.v = height(p); + synch_pos_with_cur(pdf->posstruct, &refpoint, cur); + } else { /* shipping a /Form */ + assert(pdf->o_mode == OMODE_PDF); + pdf->posstruct->dir = box_dir(p); + switch (pdf->posstruct->dir) { + case dir_TLT: + case dir_TRT: + cur_page_size.h = width(p); + cur_page_size.v = height(p) + depth(p); + break; + case dir_LTL: + case dir_RTT: + cur_page_size.h = height(p) + depth(p); + cur_page_size.v = width(p); + break; + } + switch (pdf->posstruct->dir) { + case dir_TLT: + pdf->posstruct->pos.h = 0; + pdf->posstruct->pos.v = depth(p); + break; + case dir_TRT: + pdf->posstruct->pos.h = width(p); + pdf->posstruct->pos.v = depth(p); + break; + case dir_LTL: + pdf->posstruct->pos.h = height(p); + pdf->posstruct->pos.v = width(p); + break; + case dir_RTT: + pdf->posstruct->pos.h = depth(p); + pdf->posstruct->pos.v = width(p); + break; + } + } + + /* Now we are at the point on the page where the origin of the page box should go. */ + + shipbox_refpos = pdf->posstruct->pos; /* for \.{\\gleaders} */ + + switch (pdf->o_mode) { + case OMODE_DVI: + assert(shipping_page); + dvi_begin_page(pdf); + break; + case OMODE_PDF: + pdf_begin_page(pdf, shipping_page); + break; + case OMODE_LUA: + assert(shipping_page); + lua_begin_page(pdf); + break; + default: + assert(0); + } + + switch (type(p)) { + case vlist_node: + vlist_out(pdf, p); + break; + case hlist_node: + hlist_out(pdf, p); + break; + default: + assert(0); + } + + if (shipping_page) + incr(total_pages); + cur_s = -1; + + /* Finish shipping */ + + switch (pdf->o_mode) { + case OMODE_DVI: + dvi_end_page(pdf); + break; + case OMODE_PDF: + pdf_end_page(pdf, shipping_page); + break; + case OMODE_LUA: + lua_end_page(pdf); + break; + default: + assert(0); + } + + DONE: + if ((tracing_output <= 0) && (post_callback_id == 0) && shipping_page) { + print_char(']'); + update_terminal(); + } + dead_cycles = 0; + /* Flush the box from memory, showing statistics if requested */ + if ((tracing_stats > 1) && (pre_callback_id == 0)) { + tprint_nl("Memory usage before: "); + print_int(var_used); + print_char('&'); + print_int(dyn_used); + print_char(';'); + } + flush_node_list(p); + if ((tracing_stats > 1) && (post_callback_id == 0)) { + tprint(" after: "); + print_int(var_used); + print_char('&'); + print_int(dyn_used); + print_ln(); + } + if (shipping_page && (post_callback_id > 0)) + (void) run_callback(post_callback_id, "->"); + + /* Finish sheet {\sl Sync\TeX} information record */ + if (int_par(synctex_code)) + synctexteehs(); +} |