diff options
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/pdf')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/pdf/pdfaction.c (renamed from Build/source/texk/web2c/luatexdir/pdf/pdfaction.w) | 50 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/pdf/pdfannot.c (renamed from Build/source/texk/web2c/luatexdir/pdf/pdfannot.w) | 51 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.c (renamed from Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.w) | 127 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/pdf/pdfdest.c (renamed from Build/source/texk/web2c/luatexdir/pdf/pdfdest.w) | 125 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/pdf/pdffont.c (renamed from Build/source/texk/web2c/luatexdir/pdf/pdffont.w) | 153 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/pdf/pdfgen.c (renamed from Build/source/texk/web2c/luatexdir/pdf/pdfgen.w) | 1638 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/pdf/pdfglyph.c (renamed from Build/source/texk/web2c/luatexdir/pdf/pdfglyph.w) | 165 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/pdf/pdfimage.c (renamed from Build/source/texk/web2c/luatexdir/pdf/pdfimage.w) | 142 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/pdf/pdflink.c (renamed from Build/source/texk/web2c/luatexdir/pdf/pdflink.w) | 91 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/pdf/pdflistout.c (renamed from Build/source/texk/web2c/luatexdir/pdf/pdflistout.w) | 748 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/pdf/pdfliteral.c (renamed from Build/source/texk/web2c/luatexdir/pdf/pdfliteral.w) | 111 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/pdf/pdfobj.c (renamed from Build/source/texk/web2c/luatexdir/pdf/pdfobj.w) | 104 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/pdf/pdfoutline.c (renamed from Build/source/texk/web2c/luatexdir/pdf/pdfoutline.w) | 86 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/pdf/pdfpage.c (renamed from Build/source/texk/web2c/luatexdir/pdf/pdfpage.w) | 104 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/pdf/pdfpagetree.c (renamed from Build/source/texk/web2c/luatexdir/pdf/pdfpagetree.w) | 150 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/pdf/pdfrule.c (renamed from Build/source/texk/web2c/luatexdir/pdf/pdfrule.w) | 68 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/pdf/pdfsaverestore.c (renamed from Build/source/texk/web2c/luatexdir/pdf/pdfsaverestore.w) | 49 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/pdf/pdfsetmatrix.c (renamed from Build/source/texk/web2c/luatexdir/pdf/pdfsetmatrix.w) | 124 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/pdf/pdfshipout.c (renamed from Build/source/texk/web2c/luatexdir/pdf/pdfshipout.w) | 137 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/pdf/pdftables.c (renamed from Build/source/texk/web2c/luatexdir/pdf/pdftables.w) | 92 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/pdf/pdfthread.c (renamed from Build/source/texk/web2c/luatexdir/pdf/pdfthread.w) | 61 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/pdf/pdfxform.c (renamed from Build/source/texk/web2c/luatexdir/pdf/pdfxform.w) | 55 |
22 files changed, 2274 insertions, 2157 deletions
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfaction.w b/Build/source/texk/web2c/luatexdir/pdf/pdfaction.c index bb0d6e06d50..2909ac6ad74 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfaction.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfaction.c @@ -1,29 +1,29 @@ -% pdfaction.w -% -% Copyright 2009-2011 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 +Copyright 2009-2011 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/>. + +*/ #include "ptexlib.h" -@ read an action specification +/*tex Read an action specification. */ -@c halfword scan_action(PDF pdf) +halfword scan_action(PDF pdf) { int p = new_node(whatsit_node, pdf_action_node); (void) pdf; @@ -73,13 +73,13 @@ } if (scan_keyword("newwindow")) { set_pdf_action_new_window(p, pdf_window_new); - /* Scan an optional space */ + /*tex Scan an optional space. */ get_x_token(); if (cur_cmd != spacer_cmd) back_input(); } else if (scan_keyword("nonewwindow")) { set_pdf_action_new_window(p, pdf_window_nonew); - /* Scan an optional space */ + /*tex Scan an optional space. */ get_x_token(); if (cur_cmd != spacer_cmd) back_input(); @@ -94,9 +94,9 @@ return p; } -@ write an action specification +/*tex Write an action specification. */ -@c void write_action(PDF pdf, halfword p) +void write_action(PDF pdf, halfword p) { char *s; int d = 0; diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfannot.w b/Build/source/texk/web2c/luatexdir/pdf/pdfannot.c index 43ee3692bd1..e501947c78f 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfannot.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfannot.c @@ -1,27 +1,26 @@ -% pdfannot.w -% -% Copyright 2009-2011 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 +Copyright 2009-2011 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/>. + +*/ #include "ptexlib.h" -@ @c void do_annot(PDF pdf, halfword p, halfword parent_box, scaledpos cur) { scaled_whd alt_rule; @@ -43,13 +42,13 @@ void do_annot(PDF pdf, halfword p, halfword parent_box, scaledpos cur) addto_page_resources(pdf, obj_type_annot, pdf_annot_objnum(p)); } -@ create a new whatsit node for annotation +/*tex Create a new whatsit node for annotation. */ -@c void new_annot_whatsit(small_number w) +void new_annot_whatsit(small_number w) { scaled_whd alt_rule; new_whatsit(w); - alt_rule = scan_alt_rule(); /* scans |<rule spec>| to |alt_rule| */ + alt_rule = scan_alt_rule(); set_width(tail_par, alt_rule.wd); set_height(tail_par, alt_rule.ht); set_depth(tail_par, alt_rule.dp); @@ -63,14 +62,14 @@ void do_annot(PDF pdf, halfword p, halfword parent_box, scaledpos cur) } } -@ scanning at the \TeX\ end +/*tex Scanning at the \TEX\ end: */ -@c void scan_annot(PDF pdf) +void scan_annot(PDF pdf) { int k; if (scan_keyword("reserveobjnum")) { k = pdf_create_obj(pdf, obj_type_annot, 0); - /* Scan an optional space */ + /*tex Scan an optional space. */ get_x_token(); if (cur_cmd != spacer_cmd) back_input(); diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.w b/Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.c index ac117d6ba05..fbb88692fe9 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfcolorstack.c @@ -1,43 +1,53 @@ -% pdfcolorstack.w -% -% Copyright 2009-2011 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 +/* -#include "ptexlib.h" +Copyright 2009-2011 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. -@* Color Stack and Matrix Transformation Support. +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. -@ In the following array and especially stack data structures are used. +You should have received a copy of the GNU General Public License along +with LuaTeX; if not, see <http://www.gnu.org/licenses/>. -They have the following properties: +*/ + +#include "ptexlib.h" -\item{-} They automatically grow dynamically. -\item{-} The size never decreases. -\item{-} The variable with name ending in "size" contains the number how many - entries the data structure can hold. -\item{-} The variable with name ending in "used" contains the number of - actually used entries. -\item{-} Memory of strings in stack entries must be allocated and - freed if the stack is cleared. +/*tex + + This module implements color stack support. The following array and + especially stack data structures are used. + + \startitemize + \startitem + They automatically grow dynamically. + \stopitem + \startitem + The size never decreases. + \stopitem + \startitem + The variable with name ending in "size" contains the number how many + entries the data structure can hold. + \stopitem + \startitem + The variable with name ending in "used" contains the number of + actually used entries. + \stopitem + \startitem + Memory of strings in stack entries must be allocated and freed if the + stack is cleared. + \stopitem + \stopitemize -@ Color Stack -@c +*/ #define MAX_COLORSTACKS 32768 @@ -66,10 +76,13 @@ static colstack_type *colstacks = NULL; static int colstacks_size = 0; static int colstacks_used = 0; -@ Initialization is done, if the color stacks are used, |init_colorstacks()| is defined -as macro to avoid unnecessary procedure calls. +/*tex + + Initialization is done, if the color stacks are used, |init_colorstacks()| is + defined as macro to avoid unnecessary procedure calls. + +*/ -@c #define init_colorstacks() if (colstacks_size == 0) colstacks_first_init(); static void colstacks_first_init(void) @@ -90,38 +103,40 @@ static void colstacks_first_init(void) colstacks[0].page_start = true; } -@ @c int colorstackused(void) { init_colorstacks(); return colstacks_used; } -@ A new color stack is setup with the given parameters. The stack number is returned -or -1 in case of error (no room). +/*tex + + A new color stack is setup with the given parameters. The stack number is + returned or -1 in case of error (no room). + +*/ -@c int newcolorstack(const char *str, int literal_mode, boolean page_start) { colstack_type *colstack; int colstack_num; init_colorstacks(); - /* make room */ + /*tex Make room: */ if (colstacks_used == MAX_COLORSTACKS) { return -1; } if (colstacks_used == colstacks_size) { colstacks_size += STACK_INCREMENT; - /* + /*tex If |(MAX_COLORSTACKS mod STACK_INCREMENT = 0)| then we don't need to check the case that size overruns |MAX_COLORSTACKS|. */ colstacks = xreallocarray(colstacks, colstack_type, (unsigned) colstacks_size); } - /* claim new color stack */ + /*tex Claim new color stack. */ colstack_num = colstacks_used++; colstack = &colstacks[colstack_num]; - /* configure the new color stack */ + /*tex Configure the new color stack. */ colstack->page_stack = NULL; colstack->form_stack = NULL; colstack->page_size = 0; @@ -141,12 +156,11 @@ int newcolorstack(const char *str, int literal_mode, boolean page_start) return colstack_num; } -@ @c #define get_colstack(n) (&colstacks[n]) -@ Puts a string on top of the string pool and updates |pool_ptr|. +/*tex Put a string on top of the string pool and updates |pool_ptr|. */ -@c static void put_cstring_on_str_pool(char *str) +static void put_cstring_on_str_pool(char *str) { int save_selector = selector; selector = new_string; @@ -157,7 +171,6 @@ int newcolorstack(const char *str, int literal_mode, boolean page_start) selector = save_selector; } -@ @c static int colorstackset(int colstack_no, str_number s) { colstack_type *colstack = get_colstack(colstack_no); @@ -172,7 +185,6 @@ static int colorstackset(int colstack_no, str_number s) return colstack->literal_mode; } -@ @c int colorstackcurrent(int colstack_no) { colstack_type *colstack = get_colstack(colstack_no); @@ -185,7 +197,6 @@ int colorstackcurrent(int colstack_no) return colstack->literal_mode; } -@ @c static int colorstackpush(int colstack_no, str_number s) { colstack_type *colstack = get_colstack(colstack_no); @@ -220,7 +231,6 @@ static int colorstackpush(int colstack_no, str_number s) return colstack->literal_mode; } -@ @c int colorstackpop(int colstack_no) { colstack_type *colstack = get_colstack(colstack_no); @@ -244,16 +254,13 @@ int colorstackpop(int colstack_no) return colstack->literal_mode; } -@ @c void colorstackpagestart(void) { int i, j; colstack_type *colstack; if (global_shipping_mode == SHIPPING_PAGE) { - /* see procedure |pdf_out_colorstack_startpage| */ return; } - for (i = 0; i < colstacks_used; i++) { colstack = &colstacks[i]; for (j = 0; j < colstack->form_used; j++) { @@ -269,7 +276,6 @@ void colorstackpagestart(void) } } -@ @c int colorstackskippagestart(int colstack_no) { colstack_type *colstack = get_colstack(colstack_no); @@ -285,8 +291,6 @@ int colorstackskippagestart(int colstack_no) return 0; } - -@ @c void pdf_out_colorstack(PDF pdf, halfword p) { int old_setting; @@ -295,11 +299,7 @@ void pdf_out_colorstack(PDF pdf, halfword p) int stack_no = pdf_colorstack_stack(p); int literal_mode = 0; if (stack_no >= colorstackused()) { - tprint_nl(""); - tprint("Color stack "); - print_int(stack_no); - tprint(" is not initialized for use!"); - tprint_nl(""); + formatted_warning("pdf backend","color stack %u is not initialized",(unsigned int) stack_no); return; } switch (cmd) { @@ -335,7 +335,6 @@ void pdf_out_colorstack(PDF pdf, halfword p) } } -@ @c void pdf_out_colorstack_startpage(PDF pdf) { int start_status; diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfdest.w b/Build/source/texk/web2c/luatexdir/pdf/pdfdest.c index 74e8e4b1f13..346cd26e031 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfdest.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfdest.c @@ -1,37 +1,40 @@ -% pdfdest.w -% -% Copyright 2009-2011 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 +Copyright 2009-2011 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/>. + +*/ #include "ptexlib.h" -@ Here we implement subroutines for work with objects and related things. Some of -them are used in former parts too, so we need to declare them forward. +/*tex + + Here we implement subroutines for work with objects and related things. Some + of them are used in former parts too, so we need to declare them forward. + Memory will grow dynamically. + +*/ -@c void init_dest_names(PDF pdf) { pdf->dest_names_size = inf_dest_names_size; - pdf->dest_names = xmallocarray(dest_name_entry, inf_dest_names_size); /* will grow dynamically */ + pdf->dest_names = xmallocarray(dest_name_entry, inf_dest_names_size); } -@ @c void append_dest_name(PDF pdf, char *s, int n) { int a; @@ -50,10 +53,13 @@ void append_dest_name(PDF pdf, char *s, int n) pdf->dest_names_ptr++; } -@ When a destination is created we need to check whether another destination -with the same identifier already exists and give a warning if needed. +/*tex + + When a destination is created we need to check whether another destination + with the same identifier already exists and give a warning if needed. + +*/ -@c static void warn_dest_dup(int id, small_number byname) { if (byname > 0) { @@ -62,10 +68,8 @@ static void warn_dest_dup(int id, small_number byname) } else { formatted_warning("pdf backend", "ignoring duplicate destination with the num '%d'",id); } - /* no longer the annoying context */ } -@ @c void do_dest(PDF pdf, halfword p, halfword parent_box, scaledpos cur) { scaledpos pos = pdf->posstruct->pos; @@ -85,7 +89,10 @@ void do_dest(PDF pdf, halfword p, halfword parent_box, scaledpos cur) alt_rule.wd = width(p); alt_rule.ht = height(p); alt_rule.dp = depth(p); - /* the different branches for matrixused is somewhat strange and should always be used */ + /*tex + The different branches for matrixused is somewhat strange and should + always be used + */ switch (pdf_dest_type(p)) { case pdf_dest_xyz: if (matrixused()) @@ -117,7 +124,6 @@ void do_dest(PDF pdf, halfword p, halfword parent_box, scaledpos cur) } } -@ @c void write_out_pdf_mark_destinations(PDF pdf) { pdf_object_list *k; @@ -143,12 +149,11 @@ void write_out_pdf_mark_destinations(PDF pdf) if (pdf_dest_xyz_zoom(i) == null) { pdf_add_null(pdf); } else { - if (pdf->cave == 1) - pdf_out(pdf, ' '); + pdf_check_space(pdf); pdf_print_int(pdf, pdf_dest_xyz_zoom(i) / 1000); pdf_out(pdf, '.'); pdf_print_int(pdf, (pdf_dest_xyz_zoom(i) % 1000)); - pdf->cave = 1; + pdf_set_space(pdf); } break; case pdf_dest_fit: @@ -191,7 +196,6 @@ void write_out_pdf_mark_destinations(PDF pdf) } } -@ @c void scan_pdfdest(PDF pdf) { halfword q; @@ -242,13 +246,12 @@ void scan_pdfdest(PDF pdf) } else { normal_error("pdf backend", "destination type missing"); } - /* Scan an optional space */ + /*tex Scan an optional space. */ get_x_token(); if (cur_cmd != spacer_cmd) back_input(); - if (pdf_dest_type(cur_list.tail_field) == pdf_dest_fitr) { - alt_rule = scan_alt_rule(); /* scans |<rule spec>| to |alt_rule| */ + alt_rule = scan_alt_rule(); set_width(cur_list.tail_field, alt_rule.wd); set_height(cur_list.tail_field, alt_rule.ht); set_depth(cur_list.tail_field, alt_rule.dp); @@ -268,8 +271,8 @@ void scan_pdfdest(PDF pdf) } } -@ sorts |dest_names| by names -@c +/*tex Sort |dest_names| by names: */ + static int dest_cmp(const void *a, const void *b) { dest_name_entry aa = *(const dest_name_entry *) a; @@ -277,24 +280,30 @@ static int dest_cmp(const void *a, const void *b) return strcmp(aa.objname, bb.objname); } -@ @c void sort_dest_names(PDF pdf) { qsort(pdf->dest_names, (size_t) pdf->dest_names_ptr, sizeof(dest_name_entry), dest_cmp); } -@ Output the name tree. The tree nature of the destination list forces the -storing of intermediate data in |obj_info| and |obj_aux| fields, which -is further uglified by the fact that |obj_tab| entries do not accept char -pointers. +/*tex + + Output the name tree. The tree nature of the destination list forces the + storing of intermediate data in |obj_info| and |obj_aux| fields, which is + further uglified by the fact that |obj_tab| entries do not accept char + pointers. + +*/ -@c int output_name_tree(PDF pdf) { - boolean is_names = true; /* flag for name tree output: is it Names or Kids? */ - int k = 0; /* index of current child of |l|; if |k < pdf_dest_names_ptr| - then this is pointer to |dest_names| array; - otherwise it is the pointer to |obj_tab| (object number) */ + /*tex A flag for name tree output: is it |/Names| or |/Kids|: */ + boolean is_names = true; + /*tex + The index of current child of |l|; if |k < pdf_dest_names_ptr| then this + is pointer to |dest_names| array; otherwise it is the pointer to + |obj_tab| (object number). + */ + int k = 0; int b = 0; int m, j, l; int dests = 0; @@ -306,9 +315,12 @@ int output_name_tree(PDF pdf) sort_dest_names(pdf); while (true) { do { - l = pdf_create_obj(pdf, obj_type_others, 0); /* create a new node */ - if (b == 0) - b = l; /* first in this level */ + /*tex Create a new node: */ + l = pdf_create_obj(pdf, obj_type_others, 0); + if (b == 0) { + /*tex First in this level: */ + b = l; + } if (names_head == 0) { names_head = l; names_tail = l; @@ -317,7 +329,7 @@ int output_name_tree(PDF pdf) names_tail = l; } set_obj_link(pdf, names_tail, 0); - /* Output the current node in this level */ + /*tex Output the current node in this level. */ pdf_begin_obj(pdf, l, OBJSTM_ALWAYS); pdf_begin_dict(pdf); j = 0; @@ -332,13 +344,13 @@ int output_name_tree(PDF pdf) k++; } while (j != name_tree_kids_max && k != pdf->dest_names_ptr); pdf_end_array(pdf); - set_obj_stop(pdf, l, pdf->dest_names[k - 1].objname); /* for later */ + /*tex For later use: */ + set_obj_stop(pdf, l, pdf->dest_names[k - 1].objname); if (k == pdf->dest_names_ptr) { is_names = false; k = names_head; b = 0; } - } else { set_obj_start(pdf, l, obj_start(pdf, k)); pdf_add_name(pdf, "Kids"); @@ -362,7 +374,6 @@ int output_name_tree(PDF pdf) pdf_end_dict(pdf); pdf_end_obj(pdf); } while (b != 0); - if (k == l) { dests = l; goto DONE; diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdffont.w b/Build/source/texk/web2c/luatexdir/pdf/pdffont.c index 278efa9d6fa..1e1f0f8d9da 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdffont.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdffont.c @@ -1,48 +1,50 @@ -% pdffont.w -% -% Copyright 2009-2014 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/>. - -\def\pdfTeX{pdf\TeX} - -@ @c +/* + +Copyright 2009-2014 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/>. + +*/ #include "ptexlib.h" -@ As \pdfTeX{} should also act as a back-end driver, it needs to support virtual -fonts too. Information about virtual fonts can be found in the source of some -\.{DVI}-related programs. +/*tex -Whenever we want to write out a character in a font to PDF output, we -should check whether the used character is a virtual or real character. -The |has_packet()| C macro checks for this condition. + As \LUATEX\ should also act as a back-end driver, it needs to support virtual + fonts too. Information about virtual fonts can be found in the source of some + \DVI-related programs. -@ The following code typesets a character to PDF output + Whenever we want to write out a character in a font to \PDF\ output, we + should check whether the used character is a virtual or real character. The + |has_packet| C macro checks for this condition. + + The following code typesets a character to \PDF\ output + +*/ -@c scaled_whd output_one_char(PDF pdf, halfword p) { internal_font_number f = font(p); int c = character(p); int ex_glyph = ex_glyph(p)/1000; - scaled_whd ci = get_charinfo_whd(f, c); /* the real width, height and depth of the character */ + /*tex The real width, height and depth of the character: */ + scaled_whd ci = get_charinfo_whd(f, c); if (!(char_exists(f,c))) { lua_glyph_not_found_callback(f,c); - /* char_warning(f,c); */ + /*tex Not here |char_warning(f,c);| */ return ci; } ci.wd = ext_xn_over_d(ci.wd, 1000000 + ex_glyph(p), 1000000); @@ -66,14 +68,18 @@ scaled_whd output_one_char(PDF pdf, halfword p) if (has_packet(f, c)) { do_vf_packet(pdf, f, c, ex_glyph); } else { - /* |pdf_place_glyph(pdf, f, c, ex_glyph);| */ backend_out[glyph_node] (pdf, f, c, ex_glyph); } return ci; } -@ Mark |f| as a used font; set |font_used(f)|, |font_size(f)| and |pdf_font_num(f)| -@c +/*tex + + Mark |f| as a used font; set |font_used(f)|, |font_size(f)| and + |pdf_font_num(f)|. + +*/ + static void pdf_use_font(internal_font_number f, int fontnum) { set_font_used(f, true); @@ -84,19 +90,24 @@ static void pdf_use_font(internal_font_number f, int fontnum) } } -@ To set PDF font we need to find out fonts with the same name, because \TeX\ can -load the same font several times for various sizes. For such fonts we define only -one font resource. The array |pdf_font_num| holds the object number of font -resource. A negative value of an entry of |pdf_font_num| indicates that the -corresponding font shares the font resource with the font +/*tex + + To set PDF font we need to find out fonts with the same name, because \TeX\ + can load the same font several times for various sizes. For such fonts we + define only one font resource. The array |pdf_font_num| holds the object + number of font resource. A negative value of an entry of |pdf_font_num| + indicates that the corresponding font shares the font resource with the font. + +*/ -@c #define same(n,f,k) (n(f) != NULL && n(k) != NULL && strcmp(n(f), n(k)) == 0) -/* - For some lua-loaded (for instance AFM) fonts, it is normal to have - a zero cidregistry, and such fonts do not have a fontmap entry yet - at this point, so the test should use the other branch +/*tex + + For some \LUA-loaded (for instance \AFM) fonts, it is normal to have a zero + cidregistry, and such fonts do not have a fontmap entry yet at this point, so + the test should use the other branch. + */ static boolean font_shareable(internal_font_number f, internal_font_number k) @@ -111,8 +122,21 @@ static boolean font_shareable(internal_font_number f, internal_font_number k) return 0; } -@ create a font object -@c +/*tex + + We will create a font object. We check whether |f| can share the font object + with some |k|: we have 2 cases here: |f| and |k| have the same tfm name, so + they have been loaded at different sizes, eg 'cmr10' and 'cmr10 at 11pt'. + + We optionally take over slant and extend from map entry, if not already set; + this should also be the only place where getfontmap() may be called. + + Beware, \LUATEX\ is different from \PDFTEX\ in dealing with expanded and + slanted fonts and expansion and protrusion as it will use the same font but a + different transformation which is way more efficient and also cleaner. + +*/ + void pdf_init_font(PDF pdf, internal_font_number f) { internal_font_number k; @@ -121,15 +145,6 @@ void pdf_init_font(PDF pdf, internal_font_number f) if (font_used(f)) { formatted_error("pdf backend","font %i gets initialized twice",(int) f); } - /* - check whether |f| can share the font object with some |k|: we have 2 cases - here: 1) |f| and |k| have the same tfm name (so they have been loaded at - different sizes, eg 'cmr10' and 'cmr10 at 11pt'); 2) |f| has been auto - expanded from |k| - - take over slant and extend from map entry, if not already set; - this should also be the only place where getfontmap() may be called. - */ fm = getfontmap(font_name(f)); if (font_map(f) == NULL && fm != NULL) { font_map(f) = fm; @@ -150,38 +165,42 @@ void pdf_init_font(PDF pdf, internal_font_number f) } i = obj_link(pdf, i); } - /* create a new font object for |f| */ + /*tex Create a new font object for |f|: */ l = pdf_create_obj(pdf, obj_type_font, f); pdf_use_font(f, l); } -@ set the actual font on PDF page; sets |ff| to the tfm number of the base font -sharing the font object with |f|; |ff| is either |f| itself (then it is its own -base font), or some font with the same tfm name at different size and/or -expansion. +/*tex + + Set the actual font on PDF page; sets |ff| to the tfm number of the base font + sharing the font object with |f|; |ff| is either |f| itself (then it is its + own base font), or some font with the same tfm name at different size and/or + expansion. + +*/ -@c internal_font_number pdf_set_font(PDF pdf, internal_font_number f) { - int ff; /* for use with |set_ff| */ + /*tex For use with |set_ff|: */ + int ff; if (!font_used(f)) pdf_init_font(pdf, f); - ff = pdf_font_num(f) < 0 ? -pdf_font_num(f) : f; /* aka |set_ff(f)| */ + /*tex Also known as |set_ff(f)|: */ + ff = pdf_font_num(f) < 0 ? -pdf_font_num(f) : f; addto_page_resources(pdf, obj_type_font, pdf_font_num(ff)); return ff; } -@ @c void pdf_include_chars(PDF pdf) { str_number s; - unsigned char *k, *j; /* running index */ + unsigned char *k, *j; internal_font_number f; scan_font_ident(); f = cur_val; if (f == null_font) normal_error("pdf backend", "invalid font identifier for 'includechars'"); - pdf_check_vf(cur_val); + /* pdf_check_vf(c); */ if (!font_used(f)) pdf_init_font(pdf, f); scan_toks(false, true); diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfgen.w b/Build/source/texk/web2c/luatexdir/pdf/pdfgen.c index 26b7112ed09..0409dbc33dc 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfgen.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfgen.c @@ -1,26 +1,26 @@ -% pdfgen.w -% -% Copyright 2009-2013 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 +/* + +Copyright 2009-2013 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/>. + +*/ + #include "ptexlib.h" -@ @c #include <kpathsea/c-dir.h> #include <kpathsea/c-ctype.h> #include "lua/luatex-api.h" @@ -32,43 +32,60 @@ PDF static_pdf = NULL; -@ commandline interface +/*tex The commandline interface: */ -@c int output_mode_used; int output_mode_option; int output_mode_value; int draft_mode_option; int draft_mode_value; -halfword pdf_info_toks; /* additional keys of Info dictionary */ -halfword pdf_catalog_toks; /* additional keys of Catalog dictionary */ +/*tex Additional keys of the |/Info| dictionary: */ + +halfword pdf_info_toks; + +/*tex Additional keys of the |/Catalog| and its |/OpenAction| dictionary: */ + +halfword pdf_catalog_toks; + halfword pdf_catalog_openaction; -halfword pdf_names_toks; /* additional keys of Names dictionary */ -halfword pdf_trailer_toks; /* additional keys of Trailer dictionary */ -shipping_mode_e global_shipping_mode = NOT_SHIPPING; /* set to |shipping_mode| when |ship_out| starts */ +/*tex Additional keys of the |/Names| dictionary: */ + +halfword pdf_names_toks; + +/*tex Additional keys of the |/Trailer| dictionary" */ + +halfword pdf_trailer_toks; + +/*tex Set to |shipping_mode| when |ship_out| starts */ + +shipping_mode_e global_shipping_mode = NOT_SHIPPING; + +/*tex + + Create a new buffer |strbuf_s| of size |size| and maximum allowed size + |limit|. Initialize it and set |p| to begin of data. -@ Create a new buffer |strbuf_s| of size |size| and maximum allowed size |limit|. -Initialize it and set |p| to begin of data. +*/ -@c strbuf_s *new_strbuf(size_t size, size_t limit) { strbuf_s *b; b = xtalloc(1, strbuf_s); b->size = size; b->limit = limit; - if (size > 0) + if (size > 0) { b->p = b->data = xtalloc(b->size, unsigned char); - else - b->p = b->data = NULL; /* for other alloc */ + } else { + /*tex For other alloc: */ + b->p = b->data = NULL; + } return b; } -@ Check that |n| bytes more fit into buffer; increase it if required. +/*tex Check that |n| bytes more fit into buffer; increase it if required. */ -@c static void strbuf_room(strbuf_s * b, size_t n) { unsigned int a; @@ -88,25 +105,22 @@ static void strbuf_room(strbuf_s * b, size_t n) } } -@ Seek to position |offset| within buffer. Position must be valid. +/*tex Seek to position |offset| within buffer. Position must be valid. */ -@c void strbuf_seek(strbuf_s * b, off_t offset) { b->p = b->data + offset; } -@ Get the current buffer fill level, the number of characters. +/*tex Get the current buffer fill level, the number of characters.*/ -@c size_t strbuf_offset(strbuf_s * b) { return (size_t) (b->p - b->data); } -@ Put one character into buffer. Make room before if needed. +/*tex Put one character into buffer. Make room before if needed. */ -@c void strbuf_putchar(strbuf_s * b, unsigned char c) { if ((size_t) (b->p - b->data + 1) > b->size) @@ -114,81 +128,71 @@ void strbuf_putchar(strbuf_s * b, unsigned char c) *b->p++ = c; } -@ Dump filled buffer part to PDF. +/*tex Dump filled buffer part to the \PDF\ file. */ -@c void strbuf_flush(PDF pdf, strbuf_s * b) { pdf_out_block(pdf, (const char *) b->data, strbuf_offset(b)); strbuf_seek(b, 0); } -@ Free all dynamically allocated buffer structures. +/*tex We free all dynamically allocated buffer structures. */ -@c void strbuf_free(strbuf_s * b) { xfree(b->data); xfree(b); } -@ |init_pdf_struct()| is called early, only once, from maincontrol.w +/*tex This |init_pdf_struct| is called early and only once. */ -@c PDF init_pdf_struct(PDF pdf) { os_struct *os; pdf = xtalloc(1, pdf_output_file); memset(pdf, 0, sizeof(pdf_output_file)); pdf->job_name = makecstring(job_name); - - output_mode_used = OMODE_NONE; /* will be set by |fix_o_mode()| */ - pdf->o_mode = output_mode_used; /* used by synctex, we need to use output_mode_used there */ + /*tex This will be set by |fix_o_mode|: */ + output_mode_used = OMODE_NONE; + /*tex Used by synctex, we need to use output_mode_used there. */ + pdf->o_mode = output_mode_used; pdf->o_state = ST_INITIAL; - - /* init PDF and object stream writing */ + /*tex Initialize \PDF\ and object stream writing */ pdf->os = os = xtalloc(1, os_struct); memset(pdf->os, 0, sizeof(os_struct)); os->buf[PDFOUT_BUF] = new_strbuf(inf_pdfout_buf_size, sup_pdfout_buf_size); os->buf[OBJSTM_BUF] = new_strbuf(inf_objstm_buf_size, sup_objstm_buf_size); os->obj = xtalloc(PDF_OS_MAX_OBJS, os_obj_data); os->cur_objstm = 0; - os->curbuf = PDFOUT_BUF; pdf->buf = os->buf[os->curbuf]; - /* - Later ttf_seek_outbuf(TABDIR_OFF + n * 4 * TTF_ULONG_SIZE); in ttf_init_font - we need 236 bytes, so we start with 256 bytes as in pdftex. + /*tex + Later ttf_seek_outbuf(TABDIR_OFF + n * 4 * TTF_ULONG_SIZE); in + ttf_init_font we need 236 bytes, so we start with 256 bytes as in \PDFTEX. */ pdf->fb = new_strbuf(256, 100000000); - pdf->stream_deflate = false; pdf->stream_writing = false; - - /* + /*tex Sometimes it is neccesary to allocate memory for PDF output that cannot be deallocated then, so we use |mem| for this purpose. */ pdf->mem_size = inf_pdf_mem_size; pdf->mem = xtalloc(pdf->mem_size, int); - /* + /*tex The first word is not used so we can use zero as a value for testing whether a pointer to |mem| is valid. */ pdf->mem_ptr = 1; - pdf->pstruct = NULL; - pdf->posstruct = xtalloc(1, posstructure); pdf->posstruct->pos.h = 0; pdf->posstruct->pos.v = 0; pdf->posstruct->dir = dir_TLT; - - /* allocated size of |obj_tab| array */ + /*tex Allocated size of |obj_tab| array> */ pdf->obj_tab_size = (unsigned) inf_obj_tab_size; pdf->obj_tab = xtalloc(pdf->obj_tab_size + 1, obj_entry); memset(pdf->obj_tab, 0, sizeof(obj_entry)); - pdf->minor_version = -1; pdf->major_version = -1; pdf->decimal_digits = 4; @@ -198,25 +202,22 @@ PDF init_pdf_struct(PDF pdf) pdf->image_apply_gamma = 0; pdf->objcompresslevel = 0; pdf->compress_level = 0; + pdf->force_file = 0; + pdf->recompress = 0; pdf->draftmode = 0; pdf->inclusion_copy_font = 1; pdf->pk_resolution = 0; pdf->pk_fixed_dpi = 0; pdf->pk_scale_factor = 0; - init_dest_names(pdf); pdf->page_resources = NULL; - init_pdf_pagecalculations(pdf); - pdf->vfstruct = new_vfstruct(); - return pdf; } -@ We use |pdf_get_mem| to allocate memory in |mem|. +/*tex We use |pdf_get_mem| to allocate memory in |mem|. */ -@c int pdf_get_mem(PDF pdf, int s) { int a; @@ -239,39 +240,19 @@ int pdf_get_mem(PDF pdf, int s) return ret; } -@ there are defined in |luatex-api.h|, so we need |luatex-api.c|: - -@c -output_mode get_o_mode(void) -{ - output_mode o_mode; - if (output_mode_par > 0) { - o_mode = OMODE_PDF; - } else - o_mode = OMODE_DVI; - return o_mode; -} +/*tex -void fix_o_mode(void) -{ - output_mode o_mode = get_o_mode(); - if (output_mode_used == OMODE_NONE) { - output_mode_used = o_mode; - static_pdf->o_mode = output_mode_used; /* used by synctex, we need to use output_mode_used there */ - } else if (output_mode_used != o_mode) { - normal_error("pdf backend", "\\outputmode can only be changed before anything is written to the output"); - } -} + This ensures that |pdfmajorversion| and |pdfminorversion| are set only before + any bytes have been written to the generated \PDF\ file. Here also all + variables for \PDF\ output are initialized, the \PDF\ file is opened by + |ensure_pdf_open|, and the \PDF\ header is written. -@ This ensures that |pdfmajorversion| and |pdfminorversion| are set only before any -bytes have been written to the generated \.{PDF} file. Here also all variables for -\.{PDF} output are initialized, the \.{PDF} file is opened by |ensure_pdf_open|, and -the \.{PDF} header is written. +*/ -@c void fix_pdf_version(PDF pdf) { - if (pdf->major_version < 0) { /* unset */ + if (pdf->major_version < 0) { + /*tex It is unset. */ if (pdf_major_version == 0) { normal_warning("pdf backend","unset major version, using 1 instead"); pdf->major_version = 1; @@ -284,7 +265,8 @@ void fix_pdf_version(PDF pdf) } else if (pdf->major_version != pdf_major_version) { normal_warning("pdf backend", "the major version cannot be changed after data is written to the PDF file"); } - if (pdf->minor_version < 0) { /* unset */ + if (pdf->minor_version < 0) { + /*tex It is unset. */ if ((pdf_minor_version < 0) || (pdf_minor_version > 9)) { formatted_warning("pdf backend","illegal minor version %d, using 4 instead",pdf_minor_version); pdf->minor_version = 4; @@ -301,19 +283,18 @@ static void fix_pdf_draftmode(PDF pdf) if (pdf->draftmode != draft_mode_par) normal_warning("pdf backend", "draftmode cannot be changed after data is written to the PDF file"); if (pdf->draftmode != 0) { - pdf->compress_level = 0; /* re-fix it, might have been changed inbetween */ + /*tex Fix these as they might have been changed in between. */ + pdf->compress_level = 0; pdf->objcompresslevel = 0; } } -@ @c #define ZIP_BUF_SIZE 32768 #define check_err(f, fn) \ if (f != Z_OK) \ formatted_error("pdf backend","zlib %s() failed (error code %d)", fn, f) -@ @c static void write_zip(PDF pdf) { int flush, err = Z_OK; @@ -363,7 +344,6 @@ static void write_zip(PDF pdf) pdf->stream_length = (off_t) s->total_out; } -@ @c void zip_free(PDF pdf) { if (pdf->zipbuf != NULL) { @@ -373,7 +353,6 @@ void zip_free(PDF pdf) xfree(pdf->c_stream); } -@ @c static void write_nozip(PDF pdf) { strbuf_s *buf = pdf->buf; @@ -385,12 +364,15 @@ static void write_nozip(PDF pdf) pdf->last_byte = *(buf->p - 1); } -@ The PDF buffer is flushed by calling |pdf_flush|, which checks the -variable |zip_write_state| and will compress the buffer before flushing if -neccesary. We call |pdf_begin_stream| to begin a stream and |pdf_end_stream| -to finish it. The stream contents will be compressed if compression is turn on. +/*tex + + The PDF buffer is flushed by calling |pdf_flush|, which checks the variable + |zip_write_state| and will compress the buffer before flushing if neccesary. + We call |pdf_begin_stream| to begin a stream and |pdf_end_stream| to finish + it. The stream contents will be compressed if compression is turn on. + +*/ -@c void pdf_flush(PDF pdf) { os_struct *os = pdf->os; @@ -422,20 +404,25 @@ void pdf_flush(PDF pdf) } } -@ @c static void pdf_buffer_select(PDF pdf, buffer_e buf) { os_struct *os = pdf->os; - if (pdf->os_enable && buf == OBJSTM_BUF) - os->curbuf = OBJSTM_BUF; /* switch to object stream */ - else - os->curbuf = PDFOUT_BUF; /* switch to PDF stream */ + if (pdf->os_enable && buf == OBJSTM_BUF) { + /*tex Switch to object stream: */ + os->curbuf = OBJSTM_BUF; + } else { + /*tex Switch to \PDF\ stream: */ + os->curbuf = PDFOUT_BUF; + } pdf->buf = os->buf[pdf->os->curbuf]; } -@ create new \.{/ObjStm} object if required, and set up cross reference info +/*tex + + We create new |/ObjStm| object if required, and set up cross reference info. + +*/ -@c static void pdf_prepare_obj(PDF pdf, int k, int pdf_os_threshold) { os_struct *os = pdf->os; @@ -447,15 +434,18 @@ static void pdf_prepare_obj(PDF pdf, int k, int pdf_os_threshold) switch (os->curbuf) { case PDFOUT_BUF: obj_offset(pdf, k) = pdf_offset(pdf); - obj_os_idx(pdf, k) = PDF_OS_MAX_OBJS; /* mark it as not included in any ObjStm */ + /*tex Mark it as not included in any |ObjStm|. */ + obj_os_idx(pdf, k) = PDF_OS_MAX_OBJS; break; case OBJSTM_BUF: if (os->cur_objstm == 0) { os->cur_objstm = (unsigned int) pdf_create_obj(pdf, obj_type_objstm, 0); os->idx = 0; - obuf->p = obuf->data; /* start fresh object stream */ - os->ostm_ctr++; /* only for statistics */ + /*tex Start a fresh object stream. */ + obuf->p = obuf->data; + /*tex Keep some statistics. */ + os->ostm_ctr++; } obj_os_idx(pdf, k) = (int) os->idx; obj_os_objnum(pdf, k) = (int) os->cur_objstm; @@ -467,12 +457,13 @@ static void pdf_prepare_obj(PDF pdf, int k, int pdf_os_threshold) } } -@* Low-level buffer checkers. +/*tex + + We set the active buffer pointer and make sure that there are at least |n| + bytes free in that buffer, flushing happens if needed. -@ Set the active buffer pointer. Make sure that there are at least |n| bytes free -in that buffer, flush if needed. +*/ -@c inline void pdf_room(PDF pdf, int n) { strbuf_s *buf = pdf->buf; @@ -490,7 +481,6 @@ inline void pdf_room(PDF pdf, int n) } } -@ @c void pdf_out_block(PDF pdf, const char *s, size_t n) { size_t l; @@ -507,7 +497,6 @@ void pdf_out_block(PDF pdf, const char *s, size_t n) } while (n > 0); } -@ @c __attribute__ ((format(printf, 2, 3))) void pdf_printf(PDF pdf, const char *fmt, ...) { @@ -521,9 +510,6 @@ void pdf_printf(PDF pdf, const char *fmt, ...) va_end(args); } -@ print out a string to PDF buffer - -@c void pdf_print(PDF pdf, str_number s) { const char *ss; @@ -537,9 +523,6 @@ void pdf_print(PDF pdf, str_number s) } } -@ print out a integer to PDF buffer - -@c void pdf_print_int(PDF pdf, longinteger n) { char s[24]; @@ -549,33 +532,6 @@ void pdf_print_int(PDF pdf, longinteger n) pdf_out_block(pdf, (const char *) s, (size_t) w); } -@ @c -/* -void print_pdffloat(PDF pdf, pdffloat f) -{ - char a[24]; - int e = f.e, i, l; - int64_t m = f.m; - if (m < 0) { - pdf_out(pdf, '-'); - m *= -1; - } - l = m / ten_pow[e]; - pdf_print_int(pdf, l); - l = m % ten_pow[e]; - if (l != 0) { - pdf_out(pdf, '.'); - snprintf(a, 23, "%d", l + ten_pow[e]); - for (i = e; i > 0; i--) { - if (a[i] != '0') - break; - a[i] = '\0'; - } - pdf_puts(pdf, (a + 1)); - } -} -*/ - void print_pdffloat(PDF pdf, pdffloat f) { int64_t m = f.m; @@ -584,7 +540,7 @@ void print_pdffloat(PDF pdf, pdffloat f) } else { int e = f.e; if (e == 0) { - /* division by ten_pow[0] == 1 */ + /*tex division by |ten_pow[0] == 1| */ if (m == 1) { pdf_out(pdf, '1'); } else { @@ -622,18 +578,19 @@ void print_pdffloat(PDF pdf, pdffloat f) } } -@ print out |s| as string in PDF output - -@c void pdf_print_str(PDF pdf, const char *s) { const char *orig = s; - int l = (int) strlen(s) - 1; /* last string index */ + /*tex This initializes at the last string index. */ + int l = (int) strlen(s) - 1; if (l < 0) { pdf_puts(pdf, "()"); return; } - /* the next is not really safe, the string could be "(a)xx(b)" */ + /*tex + The next might not really be safe as the string could be ``(a)xx(b)'' but + so far we never had an issue. + */ if ((s[0] == '(') && (s[l] == ')')) { pdf_puts(pdf, s); return; @@ -653,12 +610,11 @@ void pdf_print_str(PDF pdf, const char *s) pdf_out(pdf, ')'); return; } - pdf_puts(pdf, orig); /* it was a hex string after all */ + pdf_puts(pdf, orig); } -@ begin a stream (needs to have a stream dictionary also) +/*tex A stream needs to have a stream dictionary also. */ -@c void pdf_begin_stream(PDF pdf) { pdf_puts(pdf, "\nstream\n"); @@ -672,9 +628,6 @@ void pdf_begin_stream(PDF pdf) pdf->last_byte = 0; } -@ end a stream - -@c void pdf_end_stream(PDF pdf) { os_struct *os = pdf->os; @@ -682,7 +635,8 @@ void pdf_end_stream(PDF pdf) case PDFOUT_BUF: if (pdf->zip_write_state == ZIP_WRITING) pdf->zip_write_state = ZIP_FINISH; - pdf_flush(pdf); /* sets pdf->last_byte */ + /*tex This sets| pdf->last_byte|. */ + pdf_flush(pdf); break; case OBJSTM_BUF: normal_error("pdf backend", "bad buffer in end stream, case 1"); @@ -692,43 +646,71 @@ void pdf_end_stream(PDF pdf) } pdf->stream_deflate = false; pdf->stream_writing = false; - pdf_out(pdf, '\n'); /* doesn't really belong to the stream */ + /*tex This doesn't really belong to the stream: */ + pdf_out(pdf, '\n'); pdf_puts(pdf, "endstream"); - /* write stream /Length */ + /*tex Write the stream |/Length|. */ + if (pdf->seek_write_length && pdf->draftmode == 0) { + xfseeko(pdf->file, (off_t)pdf->stream_length_offset+12, SEEK_SET, pdf->job_name); + fprintf(pdf->file, " "); xfseeko(pdf->file, (off_t)pdf->stream_length_offset, SEEK_SET, pdf->job_name); - fprintf(pdf->file, "%" LONGINTEGER_PRI "i", (LONGINTEGER_TYPE) pdf->stream_length); + fprintf(pdf->file, "%" LONGINTEGER_PRI "i >>", (LONGINTEGER_TYPE) pdf->stream_length); xfseeko(pdf->file, 0, SEEK_END, pdf->job_name); } pdf->seek_write_length = false; } -@ To print |scaled| value to PDF output we need some subroutines to ensure -accurary. +/*tex + + To print |scaled| value to \PDF\ output we need some subroutines to ensure + accurary. -@c -#define max_integer 0x7FFFFFFF /* $2^{31}-1$ */ +*/ -scaled one_hundred_inch = 7227 * 65536; /* scaled value corresponds to 100in, exact, 473628672 */ -scaled one_inch = (7227 * 65536 + 50) / 100; /* scaled value corresponds to 1in (rounded to 4736287) */ -scaled one_true_inch = (7227 * 65536 + 50) / 100; /* scaled value corresponds to 1truein (rounded!) */ -scaled one_hundred_bp = (7227 * 65536) / 72; /* scaled value corresponds to 100bp */ -scaled one_bp = 65781; /* scaled value corresponds to 1bp (rounded to 65782) */ -/* - one_bp is changed on 20110411 to be exactly 65781, as in tex itself, because this value - is also used for \pdfpxdimen +/*tex We max out at $2^{31}-1$. */ + +#define max_integer 0x7FFFFFFF + +/*tex scaled value corresponds to 100in, exact, 473628672 */ + +scaled one_hundred_inch = 7227 * 65536; + +/*tex scaled value corresponds to 1in (rounded to 4736287) */ + +scaled one_inch = (7227 * 65536 + 50) / 100; + +/*tex scaled value corresponds to 1truein (rounded!) */ + +scaled one_true_inch = (7227 * 65536 + 50) / 100; + +/*tex scaled value corresponds to 100bp */ + +scaled one_hundred_bp = (7227 * 65536) / 72; + +/*tex scaled value corresponds to 1bp (rounded to 65782) */ + +scaled one_bp = 65781; + +/*tex + + One basepoint is set to exactly 65781, as in \TEX\ itself, because this value + is also used for |\pdfpxdimen|. + */ int ten_pow[10] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 /* $10^0..10^9$ */ }; -@ The function |divide_scaled| divides |s| by |m| using |dd| decimal -digits of precision. It is defined in C because it is a good candidate -for optimizations that are not possible in pascal. +/*tex + + The function |divide_scaled| divides |s| by |m| using |dd| decimal digits of + precision. + +*/ -@c scaled round_xn_over_d(scaled x, int n, unsigned int d) { boolean positive = true; @@ -757,28 +739,22 @@ scaled round_xn_over_d(scaled x, int n, unsigned int d) return (-(scaled) u); } -@ @c void pdf_add_bp(PDF pdf, scaled s) { pdffloat a; pdfstructure *p = pdf->pstruct; a.m = i64round(s * p->k1); a.e = pdf->decimal_digits; - if (pdf->cave > 0) - pdf_out(pdf, ' '); + pdf_check_space(pdf); print_pdffloat(pdf, a); - pdf->cave = 1; + pdf_set_space(pdf); } -@* handling page resources. - -@c typedef struct { int obj_type; pdf_object_list *list; } pr_entry; -@ @c static int comp_page_resources(const void *pa, const void *pb, void *p) { int a = ((const pr_entry *) pa)->obj_type; @@ -791,7 +767,6 @@ static int comp_page_resources(const void *pa, const void *pb, void *p) return 0; } -@ @c void addto_page_resources(PDF pdf, pdf_obj_type t, int k) { pdf_resource_struct *re; @@ -819,8 +794,10 @@ void addto_page_resources(PDF pdf, pdf_obj_type t, int k) item->link = NULL; item->info = k; pr->list = item; - if (obj_type(pdf, k) == (int)t) - set_obj_scheduled(pdf, k); /* k is an object number */ + if (obj_type(pdf, k) == (int)t) { + /*tex |k| is an object number. */ + set_obj_scheduled(pdf, k); + } } else { for (p = pr->list; p->info != k && p->link != NULL; p = p->link); if (p->info != k) { @@ -834,7 +811,6 @@ void addto_page_resources(PDF pdf, pdf_obj_type t, int k) } } -@ @c pdf_object_list *get_page_resources_list(PDF pdf, pdf_obj_type t) { pdf_resource_struct *re = pdf->page_resources; @@ -848,7 +824,6 @@ pdf_object_list *get_page_resources_list(PDF pdf, pdf_obj_type t) return pr->list; } -@ @c static void reset_page_resources(PDF pdf) { pdf_resource_struct *re = pdf->page_resources; @@ -864,19 +839,18 @@ static void reset_page_resources(PDF pdf) l2 = l1->link; free(l1); } - p->list = NULL; /* but the AVL tree remains */ + /*tex We reset but the AVL tree remains! */ + p->list = NULL; } } } -@ @c static void destroy_pg_res_tree(void *pa, void *param) { (void) param; xfree(pa); } -@ @c static void destroy_page_resources_tree(PDF pdf) { pdf_resource_struct *re = pdf->page_resources; @@ -886,11 +860,6 @@ static void destroy_page_resources_tree(PDF pdf) re->resources_tree = NULL; } -@* Subroutines to print out various PDF objects. - -@ print out an integer |n| with fixed width |w|; used for outputting cross-reference table. The -specification says that an offset must take 10 bytes. -@c static void pdf_print_fw_int(PDF pdf, longinteger n) { unsigned char digits[11]; @@ -901,20 +870,26 @@ static void pdf_print_fw_int(PDF pdf, longinteger n) digits[k] = (unsigned char) ('0' + (n % 10)); n /= 10; } while (k != 0); - if (n!=0) - /* the absolute value of $n$ is greater than 9999999999 */ - normal_error("pdf backend", "offset exceeds 10 bytes, try enabling object compression."); + if (n!=0) { + /*tex The absolute value of $n$ is greater than 9999999999. */ + normal_error("pdf backend", "offset exceeds 10 bytes, try enabling object compression."); + } digits[10]='\0'; pdf_puts(pdf, (const char *) digits); } -@ print out an integer |n| as a fixed number |w| of bytes; used for outputting \.{/XRef} cross-reference stream -@c +/*tex + + We print out an integer |n| as a fixed number |w| of bytes,. This is used in + the |XRef| cross-reference stream creator. + +*/ + static void pdf_out_bytes(PDF pdf, longinteger n, size_t w) { - int k; - unsigned char bytes[8]; /* digits in a number being output */ - k = (int) w; + /*tex The number of digits in a number being output. */ + unsigned char bytes[8]; + int k = (int) w; do { k--; bytes[k] = (unsigned char) (n % 256); @@ -923,32 +898,24 @@ static void pdf_out_bytes(PDF pdf, longinteger n, size_t w) pdf_out_block(pdf, (const char *) bytes, w); } -@ print out |s| as string in PDF output - -@c void pdf_print_str_ln(PDF pdf, const char *s) { pdf_print_str(pdf, s); pdf_out(pdf, '\n'); } -@ @c void pdf_print_toks(PDF pdf, halfword p) { int len = 0; char *s = tokenlist_to_cstring(p, true, &len); if (len > 0) { - if (pdf->cave > 0) - pdf_out(pdf, ' '); + pdf_check_space(pdf); pdf_puts(pdf, s); - pdf->cave = 1; + pdf_set_space(pdf); } xfree(s); } -@ prints a rect spec - -@c void pdf_add_rect_spec(PDF pdf, halfword r) { pdf_add_bp(pdf, pdf_ann_left(r)); @@ -957,9 +924,6 @@ void pdf_add_rect_spec(PDF pdf, halfword r) pdf_add_bp(pdf, pdf_ann_top(r)); } -@ output a rectangle specification to PDF file - -@c void pdf_rectangle(PDF pdf, halfword r) { pdf_add_name(pdf, "Rect"); @@ -968,7 +932,6 @@ void pdf_rectangle(PDF pdf, halfword r) pdf_end_array(pdf); } -@ @c static void init_pdf_outputparameters(PDF pdf) { int pk_mode; @@ -980,6 +943,7 @@ static void init_pdf_outputparameters(PDF pdf) pdf->image_hicolor = fix_int(pdf_image_hicolor, 0, 1); pdf->image_apply_gamma = fix_int(pdf_image_apply_gamma, 0, 1); pdf->objcompresslevel = fix_int(pdf_obj_compress_level, 0, MAX_OBJ_COMPRESS_LEVEL); + pdf->recompress = fix_int(pdf_recompress, 0, 1); pdf->inclusion_copy_font = fix_int(pdf_inclusion_copy_font, 0, 1); pdf->pk_resolution = fix_int(pdf_pk_resolution, 72, 8000); pdf->pk_fixed_dpi = fix_int(pdf_pk_fixed_dpi, 0, 1); @@ -992,19 +956,19 @@ static void init_pdf_outputparameters(PDF pdf) } pdf->os_enable = false; } - if (pdf->pk_resolution == 0) /* if not set from format file or by user */ - pdf->pk_resolution = pk_dpi; /* take it from \.{texmf.cnf} */ + if (pdf->pk_resolution == 0) { + /*tex If not set from format file or by user take it from \.{texmf.cnf}. */ + pdf->pk_resolution = pk_dpi; + } pdf->pk_scale_factor = divide_scaled(72, pdf->pk_resolution, pk_decimal_digits(pdf,5)); if (!callback_defined(read_pk_file_callback)) { - pk_mode = pdf_pk_mode; /* lookup once */ + pk_mode = pdf_pk_mode; if (pk_mode != null) { char *s = tokenlist_to_cstring(pk_mode, true, NULL); - /* This will become LUATEX in 1.0. */ - kpse_init_prog("PDFTEX", (unsigned) pdf->pk_resolution, s, nil); + kpse_init_prog("LUATEX", (unsigned) pdf->pk_resolution, s, nil); xfree(s); } else { - /* This will become LUATEX in 1.0. */ - kpse_init_prog("PDFTEX", (unsigned) pdf->pk_resolution, nil, nil); + kpse_init_prog("LUATEX", (unsigned) pdf->pk_resolution, nil, nil); } if (!kpse_var_value("MKTEXPK")) kpse_set_program_enabled(kpse_pk_format, 1, kpse_src_cmdline); @@ -1014,75 +978,54 @@ static void init_pdf_outputparameters(PDF pdf) pdf->resname_prefix = get_resname_prefix(pdf); } -@ Checks that we have a name for the generated PDF file and that it's open. +/*tex -@c -static void ensure_output_file_open(PDF pdf, const char *ext) -{ - char *fn; - if (pdf->file_name != NULL) - return; - if (job_name == 0) - open_log_file(); - fn = pack_job_name(ext); - if (pdf->draftmode == 0 || output_mode_used == OMODE_DVI) { - while (!lua_b_open_out(&pdf->file, fn)) - fn = prompt_file_name("file name for output", ext); - } - pdf->file_name = fn; -} + This checks that we have a name for the generated PDF file and that it's + open. -@ @c -static void ensure_pdf_header_written(PDF pdf) +*/ + +void pdf_write_header(PDF pdf) { - /* Initialize variables for \.{PDF} output */ + /*tex Initialize variables for \PDF\ output. */ fix_pdf_version(pdf); init_pdf_outputparameters(pdf); fix_pdf_draftmode(pdf); - /* Write \.{PDF} header */ + /*tex Write \PDF\ header */ pdf_printf(pdf, "%%PDF-%d.%d\n", pdf->major_version, pdf->minor_version); - /* The next blob will be removed 1.0. */ + /* Some binary crap. */ pdf_out(pdf, '%'); - pdf_out(pdf, 'P' + 128); + pdf_out(pdf, 'L' + 128); + pdf_out(pdf, 'U' + 128); + pdf_out(pdf, 'A' + 128); pdf_out(pdf, 'T' + 128); pdf_out(pdf, 'E' + 128); pdf_out(pdf, 'X' + 128); + pdf_out(pdf, 'P' + 128); + pdf_out(pdf, 'D' + 128); + pdf_out(pdf, 'F' + 128); pdf_out(pdf, '\n'); } -@ @c +void pdf_open_file(PDF pdf) { + ensure_output_file_open(pdf, ".pdf"); +} + void ensure_output_state(PDF pdf, output_state s) { if (pdf->o_state < s) { - if (s > ST_INITIAL) + if (s > ST_INITIAL) { ensure_output_state(pdf, s - 1); + } switch (s - 1) { case ST_INITIAL: fix_o_mode(); break; case ST_OMODE_FIX: - switch (output_mode_used) { - case OMODE_DVI: - ensure_output_file_open(pdf, ".dvi"); - break; - case OMODE_PDF: - ensure_output_file_open(pdf, ".pdf"); - break; - default: - normal_error("pdf backend","weird output state"); - } + backend_out_control[backend_control_open_file](pdf); break; case ST_FILE_OPEN: - switch (output_mode_used) { - case OMODE_DVI: - ensure_dvi_header_written(pdf); - break; - case OMODE_PDF: - ensure_pdf_header_written(pdf); - break; - default: - normal_error("pdf backend","weird output state"); - } + backend_out_control[backend_control_write_header](pdf); break; case ST_HEADER_WRITTEN: break; @@ -1095,29 +1038,37 @@ void ensure_output_state(PDF pdf, output_state s) } } -@ Write out an accumulated object stream. +/*tex -First the object number and byte offset pairs are generated and appended to the -ready buffered object stream. By this the value of \.{/First} can be calculated. -Then a new \.{/ObjStm} object is generated, and everything is copied to the PDF -output buffer, where also compression is done. When calling this procedure, -|pdf_os_mode| must be |true|. + Write out an accumulated object stream. The object number and byte offset + pairs are generated and appended to the ready buffered object stream. By this + the value of \.{/First} can be calculated. Then a new \.{/ObjStm} object is + generated, and everything is copied to the PDF output buffer, where also + compression is done. When calling this procedure, |pdf_os_mode| must be + |true|. + +*/ -@c static void pdf_os_write_objstream(PDF pdf) { os_struct *os = pdf->os; - unsigned int i, j, n1, n2; /* n1, n2: ObjStm buffer may be reallocated! */ + /*tex |n1|, |n2|: |ObjStm| buffer may be reallocated! */ + unsigned int i, j, n1, n2; strbuf_s *obuf = os->buf[OBJSTM_BUF]; - if (os->cur_objstm == 0) /* no object stream started */ + if (os->cur_objstm == 0) { + /*tex No object stream started. */ return; - n1 = (unsigned int) strbuf_offset(obuf); /* remember end of collected object stream contents */ - /* this is needed here to calculate /First for the ObjStm dict */ - for (i = 0, j = 0; i < os->idx; i++) { /* add object-number/byte-offset list to buffer */ + } + /*tex Remember end of collected object stream contents. */ + n1 = (unsigned int) strbuf_offset(obuf); + /*tex This is needed here to calculate |/First| for the |ObjStm| dict */ + for (i = 0, j = 0; i < os->idx; i++) { + /*tex Add object-number/byte-offset list to buffer. */ pdf_print_int(pdf, (int) os->obj[i].num); pdf_out(pdf, ' '); pdf_print_int(pdf, (int) os->obj[i].off); - if (j == 9 || i == os->idx - 1) { /* print out in groups of ten for better readability */ + if (j == 9 || i == os->idx - 1) { + /*tex Print out in groups of ten for better readability. */ pdf_out(pdf, '\n'); j = 0; } else { @@ -1125,192 +1076,168 @@ static void pdf_os_write_objstream(PDF pdf) j++; } } - n2 = (unsigned int) strbuf_offset(obuf); /* remember current buffer end */ - pdf_begin_obj(pdf, (int) os->cur_objstm, OBJSTM_NEVER); /* switch to PDF stream writing */ + /*tex Remember current buffer end. */ + n2 = (unsigned int) strbuf_offset(obuf); + /*tex Switch to \PDF\ stream writing. */ + pdf_begin_obj(pdf, (int) os->cur_objstm, OBJSTM_NEVER); pdf_begin_dict(pdf); pdf_dict_add_name(pdf, "Type", "ObjStm"); - pdf_dict_add_int(pdf, "N", (int) os->idx); /* number of objects in ObjStm */ + /*tex The number of objects in |ObjStm|. */ + pdf_dict_add_int(pdf, "N", (int) os->idx); pdf_dict_add_int(pdf, "First", (int) (n2 - n1)); pdf_dict_add_streaminfo(pdf); pdf_end_dict(pdf); pdf_begin_stream(pdf); - /* write object-number/byte-offset list */ + /*tex Write object-number/byte-offset list. */ pdf_out_block(pdf, (const char *) (obuf->data + n1), (size_t) (n2 - n1)); - /* write collected object stream contents */ + /*tex Write collected object stream contents. */ pdf_out_block(pdf, (const char *) obuf->data, (size_t) n1); pdf_end_stream(pdf); pdf_end_obj(pdf); - os->cur_objstm = 0; /* to force object stream generation next time */ + /*tex We force object stream generation next time. */ + os->cur_objstm = 0; } -@ begin a PDF dictionary +/*tex Here comes a bunch of flushers: */ -@c void pdf_begin_dict(PDF pdf) { + pdf_check_space(pdf); pdf_puts(pdf, "<<"); - pdf->cave = 0; + pdf_set_space(pdf); } -@ end a PDF dictionary - -@c void pdf_end_dict(PDF pdf) { + pdf_check_space(pdf); pdf_puts(pdf, ">>"); - pdf->cave = 0; + pdf_set_space(pdf); } -@ add integer object to dict - -@c void pdf_dict_add_bool(PDF pdf, const char *key, int i) { pdf_add_name(pdf, key); pdf_add_bool(pdf, i); } -@ add integer object to dict - -@c void pdf_dict_add_int(PDF pdf, const char *key, int i) { pdf_add_name(pdf, key); pdf_add_int(pdf, i); } -@ add name object to dict - -@c void pdf_dict_add_name(PDF pdf, const char *key, const char *val) { pdf_add_name(pdf, key); pdf_add_name(pdf, val); } -@ add string object to dict - -@c void pdf_dict_add_string(PDF pdf, const char *key, const char *val) { if (val == NULL) return; pdf_add_name(pdf, key); - if (pdf->cave > 0) - pdf_out(pdf, ' '); - pdf->cave = 0; + pdf_check_space(pdf); pdf_print_str(pdf, val); + pdf_set_space(pdf); } -@ add name reference to dict - -@c void pdf_dict_add_ref(PDF pdf, const char *key, int num) { pdf_add_name(pdf, key); pdf_add_ref(pdf, num); } -@ add objects of different types - -@c void pdf_add_null(PDF pdf) { - if (pdf->cave > 0) - pdf_out(pdf, ' '); + pdf_check_space(pdf); pdf_puts(pdf, "null"); - pdf->cave = 1; + pdf_set_space(pdf); } void pdf_add_bool(PDF pdf, int i) { - if (pdf->cave > 0) - pdf_out(pdf, ' '); + pdf_check_space(pdf); if (i == 0) pdf_puts(pdf, "false"); else pdf_puts(pdf, "true"); - pdf->cave = 1; + pdf_set_space(pdf); } void pdf_add_int(PDF pdf, int i) { - if (pdf->cave > 0) - pdf_out(pdf, ' '); + pdf_check_space(pdf); pdf_print_int(pdf, i); - pdf->cave = 1; + pdf_set_space(pdf); } void pdf_add_longint(PDF pdf, longinteger n) { - if (pdf->cave > 0) - pdf_out(pdf, ' '); + pdf_check_space(pdf); pdf_print_int(pdf, n); - pdf->cave = 1; + pdf_set_space(pdf); } void pdf_add_string(PDF pdf, const char *s) { - if (pdf->cave > 0) - pdf_out(pdf, ' '); + pdf_check_space(pdf); pdf_print_str(pdf, s); - pdf->cave = 1; + pdf_set_space(pdf); } void pdf_add_name(PDF pdf, const char *name) { + pdf_check_space(pdf); pdf_out(pdf, '/'); pdf_puts(pdf, name); - pdf->cave = 1; + pdf_set_space(pdf); } void pdf_add_ref(PDF pdf, int num) { - if (pdf->cave > 0) - pdf_out(pdf, ' '); + pdf_check_space(pdf); pdf_print_int(pdf, num); pdf_puts(pdf, " 0 R"); - pdf->cave = 1; + pdf_set_space(pdf); } -@ add stream length and filter entries to a stream dictionary, -remember file position for seek +/*tex + + When we add the stream length and filter entries to a stream dictionary, + remember file position for seek. + +*/ -@c void pdf_dict_add_streaminfo(PDF pdf) { - pdf_add_name(pdf, "Length"); - pdf->stream_length_offset = pdf_offset(pdf) + 1; - pdf->seek_write_length = true; /* fill in length at |pdf_end_stream| call */ - pdf_puts(pdf, " x "); /* space for 10 decimal digits */ - pdf->cave = 1; if (pdf->compress_level > 0) { pdf_dict_add_name(pdf, "Filter", "FlateDecode"); pdf->stream_deflate = true; } + pdf_add_name(pdf, "Length"); + pdf->stream_length_offset = pdf_offset(pdf) + 1; + /*tex Fill in length at |pdf_end_stream| call. */ + pdf->seek_write_length = true; + /*tex We reserve space for 10 decimal digits plus space. */ + pdf_puts(pdf, " x "); + pdf_set_space(pdf); } -@ begin a PDF array - -@c void pdf_begin_array(PDF pdf) { + pdf_check_space(pdf); pdf_out(pdf, '['); - pdf->cave = 0; + pdf_set_space(pdf); } -@ end a PDF array - -@c void pdf_end_array(PDF pdf) { + pdf_check_space(pdf); pdf_out(pdf, ']'); - pdf->cave = 0; + pdf_set_space(pdf); } -@ begin a PDF object - -@c void pdf_begin_obj(PDF pdf, int i, int pdf_os_threshold) { os_struct *os = pdf->os; @@ -1321,45 +1248,90 @@ void pdf_begin_obj(PDF pdf, int i, int pdf_os_threshold) pdf_printf(pdf, "%d 0 obj\n", (int) i); break; case OBJSTM_BUF: - if (pdf->compress_level == 0) - pdf_printf(pdf, "%% %d 0 obj\n", (int) i); /* debugging help */ + if (pdf->compress_level == 0) { + /*tex Some debugging help. */ + pdf_printf(pdf, "%% %d 0 obj\n", (int) i); + } break; default: normal_error("pdf backend","weird begin object"); } - pdf->cave = 0; + pdf_reset_space(pdf); } -@ end a PDF object - -@c void pdf_end_obj(PDF pdf) { os_struct *os = pdf->os; switch (os->curbuf) { case PDFOUT_BUF: - pdf_puts(pdf, "\nendobj\n"); /* end a PDF object */ + /*tex End a \PDF\ object. */ + pdf_puts(pdf, "\nendobj\n"); break; case OBJSTM_BUF: - os->idx++; /* = number of objects collected so far in ObjStm */ - os->o_ctr++; /* only for statistics */ - if (os->idx == PDF_OS_MAX_OBJS) + /*tex Tthe number of objects collected so far in ObjStm: */ + os->idx++; + /*tex Only for statistics: */ + os->o_ctr++; + if (os->idx == PDF_OS_MAX_OBJS) { pdf_os_write_objstream(pdf); - else - pdf_out(pdf, '\n'); /* Adobe Reader seems to need this */ + } else { + /*tex Adobe Reader seems to need this. */ + pdf_out(pdf, '\n'); + } break; default: normal_error("pdf backend","weird end object"); } } -@ Converts any string given in in in an allowed PDF string which can be - handled by printf et.al.: \.{\\} is escaped to \.{\\\\}, parenthesis are escaped and - control characters are octal encoded. - This assumes that the string does not contain any already escaped - characters! +/* + Needed for embedding fonts. + +*/ + +pdf_obj *pdf_new_stream(void) +{ + pdf_obj *stream = xmalloc(sizeof(pdf_obj)); + stream->length = 0; + stream->data = NULL; + return stream; +} + +void pdf_add_stream(pdf_obj * stream, unsigned char *buf, long len) +{ + int i; + assert(stream != NULL); + if (stream->data == NULL) { + stream->data = xmalloc((unsigned) len); + } else { + stream->data = + xrealloc(stream->data, (unsigned) len + (unsigned) stream->length); + } + for (i = 0; i < len; i++) { + *(stream->data + stream->length + i) = *(buf + i); + } + stream->length += (unsigned) len; +} + +void pdf_release_obj(pdf_obj * stream) +{ + if (stream != NULL) { + if (stream->data != NULL) { + xfree(stream->data); + } + xfree(stream); + } +} + +/* + + This one converts any string given in in in an allowed PDF string which can + be handled by printf et.al.: \.{\\} is escaped to \.{\\\\}, parenthesis are + escaped and control characters are octal encoded. This assumes that the + string does not contain any already escaped characters! + +*/ -@c char *convertStringToPDFString(const char *in, int len) { static char pstrbuf[MAX_PSTRING_LEN]; @@ -1370,7 +1342,7 @@ char *convertStringToPDFString(const char *in, int len) for (i = 0; i < len; i++) { check_buf((unsigned) j + sizeof(buf), MAX_PSTRING_LEN); if (((unsigned char) in[i] < '!') || ((unsigned char) in[i] > '~')) { - /* convert control characters into oct */ + /*tex Convert control characters into octal. */ k = snprintf(buf, sizeof(buf), "\\%03o", (unsigned int) (unsigned char) in[i]); check_nprintf(k, sizeof(buf)); out[j++] = buf[0]; @@ -1378,15 +1350,15 @@ char *convertStringToPDFString(const char *in, int len) out[j++] = buf[2]; out[j++] = buf[3]; } else if ((in[i] == '(') || (in[i] == ')')) { - /* escape paranthesis */ + /*tex Escape parenthesis: */ out[j++] = '\\'; out[j++] = in[i]; } else if (in[i] == '\\') { - /* escape backslash */ + /*tex Escape backslash: */ out[j++] = '\\'; out[j++] = '\\'; } else { - /* copy char :-) */ + /* Copy char : */ out[j++] = in[i]; } } @@ -1394,10 +1366,13 @@ char *convertStringToPDFString(const char *in, int len) return pstrbuf; } -@ Converts any string given in in in an allowed PDF string which is hexadecimal -encoded; |sizeof(out)| should be at least $|lin|*2+1$. +/*tex + + This one converts any string given in in in an allowed PDF string which is + hexadecimal encoded; |sizeof(out)| should be at least $|lin|*2+1$. + +*/ -@c static void convertStringToHexString(const char *in, char *out, int lin) { int i, k; @@ -1412,40 +1387,18 @@ static void convertStringToHexString(const char *in, char *out, int lin) out[j] = '\0'; } -@ Compute the ID string as per PDF1.4 9.3: - -File identifers are defined by the optional ID entry in a PDF file's trailer -dictionary (see Section 3.4.4, "File Trailer"; see also implementation note 105 -in Appendix H). The value of this entry is an array of two strings. The first -string is a permanent identifier based on the contents of the file at the time it -was originally created, and does not change when the file is incrementally -updated. The second string is a changing identifier based on the file's contents -at the time it was last updated. When a file is first written, both identifiers -are set to the same value. If both identifiers match when a file reference is -resolved, it is very likely that the correct file has been found; if only the -first identifier matches, then a different version of the correct file has been -found. To help ensure the uniqueness of file identifiers, it is recommend that -they be computed using a message digest algorithm such as MD5 (described in -Internet RFC 1321, The MD5 Message-Digest Algorithm; see the Bibliography), using -the following information (see implementation note 106 in Appendix H): - The -current time - -- A string representation of the file's location, usually a pathname -- The size of the file in bytes -- The values of all entries in the file's document information - dictionary (see Section 9.2.1, Document Information Dictionary ) - -This stipulates only that the two IDs must be identical when the file is created -and that they should be reasonably unique. Since it's difficult to get the file -size at this point in the execution of pdfTeX and scanning the info dict is also -difficult, we start with a simpler implementation using just the first two items. +/*tex + We compute the ID string as per PDF specification 1.4 9.3 that stipulates + only that the two IDs must be identical when the file is created and that + they should be reasonably unique. Since it's difficult to get the file size + at this point in the execution of pdfTeX and scanning the info dict is also + difficult, we start with a simpler implementation using just the first two + items. -@c - -/* A user supplied trailerid had better be an array! So maybe we need to check - for [] and error otherwise. + for |[]| and error otherwise. + */ static void print_ID(PDF pdf) @@ -1457,10 +1410,10 @@ static void print_ID(PDF pdf) if (p && strlen(p) > 0) { pdf_puts(pdf,p); } else if (pdf_trailer_id != 0) { - /* user provided one */ + /*tex The user provided one: */ pdf_print_toks(pdf, pdf_trailer_id); } else { - /* system provided one */ + /*tex The system provided one: */ time_t t; size_t size; char time_str[32]; @@ -1468,13 +1421,10 @@ static void print_ID(PDF pdf) md5_byte_t digest[16]; char id[64]; char pwd[4096]; - /* start md5 */ md5_init(&state); - /* get the time */ t = pdf->start_time; size = strftime(time_str, sizeof(time_str), "%Y%m%dT%H%M%SZ", gmtime(&t)); md5_append(&state, (const md5_byte_t *) time_str, (int) size); - /* get the file name */ if (getcwd(pwd, sizeof(pwd)) == NULL) { formatted_error("pdf backend","getcwd() failed (%s), (path too long?)", strerror(errno)); } @@ -1492,63 +1442,27 @@ static void print_ID(PDF pdf) md5_append(&state, (const md5_byte_t *) pwd, (int) strlen(pwd)); md5_append(&state, (const md5_byte_t *) "/", 1); md5_append(&state, (const md5_byte_t *) pdf->file_name, (int) strlen(pdf->file_name)); - /* finish md5 */ md5_finish(&state, digest); - /* write the IDs */ convertStringToHexString((char *) digest, id, 16); pdf_begin_array(pdf); + pdf_check_space(pdf); pdf_printf(pdf, "<%s> <%s>", id, id); + pdf_set_space(pdf); pdf_end_array(pdf); } } } -@ Print the /CreationDate entry. - -PDF Reference, third edition says about the expected date format: - -3.8.2 Dates - -PDF defines a standard date format, which closely follows that of the -international standard ASN.1 (Abstract Syntax Notation One), defined in ISO/IEC -8824 (see the Bibliography). A date is a string of the form - -(D:YYYYMMDDHHmmSSOHH'mm') - -where - -YYYY is the year -MM is the month -DD is the day (01-31) -HH is the hour (00-23) -mm is the minute (00-59) -SS is the second (00-59) -O is the relationship of local time to Universal Time (UT), denoted by one - of the characters +, -, or Z (see below) -HH followed by ' is the absolute value of the offset from UT in hours (00-23) -mm followed by ' is the absolute value of the offset from UT in minutes (00-59) - -The apostrophe character (') after HH and mm is part of the syntax. All fields -after the year are optional. (The prefix D:, although also optional, is strongly -recommended.) The default values for MM and DD are both 01; all other numerical -fields default to zero values. A plus sign (+) as the value of the O field -signifies that local time is later than UT, a minus sign (-) that local time is -earlier than UT, and the letter Z that local time is equal to UT. If no UT -information is specified, the relationship of the specified time to UT is -considered to be unknown. Whether or not the time zone is known, the rest of the -date should be specified in local time. +/*tex -For example, December 23, 1998, at 7:52 PM, U.S. Pacific Standard Time, is -represented by the string + Here we print the |/CreationDate| entry in the form + |(D:YYYYMMDDHHmmSSOHH'mm')|. The main difficulty is get the time zone offset. + |strftime()| does this in ISO C99 (e.g. newer glibc) with \%z, but we have to + work with other systems (e.g. Solaris 2.5). -D:199812231952-08'00' - -The main difficulty is get the time zone offset. |strftime()| does this in ISO -C99 (e.g. newer glibc) with \%z, but we have to work with other systems (e.g. -Solaris 2.5). +*/ -@c -#define TIME_STR_SIZE 30 /* minimum size for |time_str| is 24: |"D:YYYYmmddHHMMSS+HH'MM'"| */ +#define TIME_STR_SIZE 30 static void makepdftime(PDF pdf) { @@ -1557,32 +1471,31 @@ static void makepdftime(PDF pdf) int i, off, off_hours, off_mins; time_t t = pdf->start_time; char *time_str = pdf->start_time_str; - /* get the time */ + /*tex Get the time. */ if (utc_option) { lt = *gmtime(&t); } else { lt = *localtime(&t); } size = strftime(time_str, TIME_STR_SIZE, "D:%Y%m%d%H%M%S", <); - /* expected format: "YYYYmmddHHMMSS" */ + /*tex Expected format: |YYYYmmddHHMMSS|. */ if (size == 0) { - /* unexpected, contents of |time_str| is undefined */ + /*tex Unexpected, contents of |time_str| is undefined .*/ time_str[0] = '\0'; return; } - /* - correction for seconds: \%S can be in range 00..61, the PDF reference - expects 00..59, therefore we map "60" and "61" to "59" + /*tex + A correction for seconds. the PDF reference expects 00..59, therefore we + map 60 and 61 to 59. */ if (time_str[14] == '6') { time_str[14] = '5'; time_str[15] = '9'; - /* for safety */ + /*tex For safety: */ time_str[16] = '\0'; } - /* get the time zone offset */ + /*tex Get the time zone offset. */ gmt = *gmtime(&t); - /* this calculation method was found in exim's tod.c */ off = 60 * (lt.tm_hour - gmt.tm_hour) + lt.tm_min - gmt.tm_min; if (lt.tm_year != gmt.tm_year) { off += (lt.tm_year > gmt.tm_year) ? 1440 : -1440; @@ -1601,7 +1514,6 @@ static void makepdftime(PDF pdf) pdf->start_time = t; } -@ @c void initialize_start_time(PDF pdf) { if (pdf->start_time == 0) { @@ -1611,14 +1523,12 @@ void initialize_start_time(PDF pdf) } } -@ @c char *getcreationdate(PDF pdf) { initialize_start_time(pdf); return pdf->start_time_str; } -@ @c void remove_pdffile(PDF pdf) { if (pdf != NULL) { @@ -1629,10 +1539,9 @@ void remove_pdffile(PDF pdf) } } -@ Use |check_o_mode()| in the backend-specific "Implement..." chunks +/*tex We use this checker in other modules. It is not pdf specific. */ -@c -void check_o_mode(PDF pdf, const char *s, int o_mode_bitpattern, boolean strict) /* s ignored now */ +void check_o_mode(PDF pdf, const char *s, int o_mode_bitpattern, boolean strict) { output_mode o_mode; @@ -1641,16 +1550,13 @@ void check_o_mode(PDF pdf, const char *s, int o_mode_bitpattern, boolean strict) normal_error("lua only","no backend present, needed for what you asked for"); return ; } - /* - in warn mode (strict == false): only check, don't do |fix_o_mode()| here! |output_mode_used| - is left in possibly wrong state until real output, ok. - */ if (output_mode_used == OMODE_NONE) o_mode = get_o_mode(); else o_mode = output_mode_used; - pdf->o_mode = output_mode_used; /* used by synctex, we need to use output_mode_used there */ - if (!((1 << o_mode) & o_mode_bitpattern)) { /* warning or error */ + /*tex This is used by synctex, we need to use output_mode_used there. */ + pdf->o_mode = output_mode_used; + if (!((1 << o_mode) & o_mode_bitpattern)) { switch (o_mode) { case OMODE_DVI: m = "DVI"; @@ -1669,7 +1575,23 @@ void check_o_mode(PDF pdf, const char *s, int o_mode_bitpattern, boolean strict) ensure_output_state(pdf, ST_HEADER_WRITTEN); } -@ @c +void ensure_output_file_open(PDF pdf, const char *ext) +{ + char *fn; + if (pdf->file_name != NULL) + return; + if (job_name == 0) + open_log_file(); + fn = pack_job_name(ext); + if (pdf->draftmode == 0 || output_mode_used == OMODE_DVI) { + while (!lua_b_open_out(&pdf->file, fn)) + fn = prompt_file_name("file name for output", ext); + } + pdf->file_name = fn; +} + +/*tex till here */ + void set_job_id(PDF pdf, int year, int month, int day, int time) { char *name_string, *format_string, *s; @@ -1681,7 +1603,7 @@ void set_job_id(PDF pdf, int year, int month, int day, int time) format_string = makecstring(format_ident); slen = SMALL_BUF_SIZE + strlen(name_string) + strlen(format_string) + strlen(luatex_banner); s = xtalloc(slen, char); - /* The Web2c version string starts with a space. */ + /*tex The \WEBC\ version string starts with a space. (Really?) */ i = snprintf(s, slen, "%.4d/%.2d/%.2d %.2d:%.2d %s %s %s", year, month, day, time / 60, time % 60, name_string, format_string, luatex_banner); check_nprintf(i, slen); pdf->job_id_string = xstrdup(s); @@ -1690,11 +1612,11 @@ void set_job_id(PDF pdf, int year, int month, int day, int time) xfree(format_string); } -@ @c char *get_resname_prefix(PDF pdf) { static char name_str[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - static char prefix[7]; /* make a tag of 6 chars long */ + /*tex We make a tag of 6 characters long. */ + static char prefix[7]; short i; size_t base = strlen(name_str); unsigned long crc = crc32(0L, Z_NULL, 0); @@ -1707,12 +1629,11 @@ char *get_resname_prefix(PDF pdf) return prefix; } -@ @c void pdf_begin_page(PDF pdf) { int xform_attributes; int xform_type = 0; - scaled form_margin = pdf_xform_margin; /* was one_bp until SVN4066 */ + scaled form_margin = pdf_xform_margin; ensure_output_state(pdf, ST_HEADER_WRITTEN); init_pdf_pagecalculations(pdf); if (pdf->page_resources == NULL) { @@ -1724,7 +1645,8 @@ void pdf_begin_page(PDF pdf) if (global_shipping_mode == SHIPPING_PAGE) { pdf->last_page = pdf_get_obj(pdf, obj_type_page, total_pages + 1, 0); - set_obj_aux(pdf, pdf->last_page, 1); /* mark that this page has been created */ + /*tex Mark that this page has been created. */ + set_obj_aux(pdf, pdf->last_page, 1); pdf->last_stream = pdf_create_obj(pdf, obj_type_pagestream, 0); pdf_begin_obj(pdf, pdf->last_stream, OBJSTM_NEVER); pdf->last_thread = null; @@ -1733,15 +1655,16 @@ void pdf_begin_page(PDF pdf) xform_type = obj_xform_type(pdf, pdf_cur_form) ; pdf_begin_obj(pdf, pdf_cur_form, OBJSTM_NEVER); pdf->last_stream = pdf_cur_form; - /* Write out Form stream header */ + /*tex Write out the |Form| stream header */ pdf_begin_dict(pdf); if (xform_type == 0) { pdf_dict_add_name(pdf, "Type", "XObject"); pdf_dict_add_name(pdf, "Subtype", "Form"); pdf_dict_add_int(pdf, "FormType", 1); } - xform_attributes = pdf_xform_attr; /* lookup once */ - form_margin = obj_xform_margin(pdf, pdf_cur_form); /* now stored in object */ + xform_attributes = pdf_xform_attr; + /*tex Now stored in the object: */ + form_margin = obj_xform_margin(pdf, pdf_cur_form); if (xform_attributes != null) pdf_print_toks(pdf, xform_attributes); if (obj_xform_attr(pdf, pdf_cur_form) != null) { @@ -1750,7 +1673,7 @@ void pdf_begin_page(PDF pdf) set_obj_xform_attr(pdf, pdf_cur_form, null); } if (obj_xform_attr_str(pdf, pdf_cur_form) != null) { - lua_pdf_literal(pdf, obj_xform_attr_str(pdf, pdf_cur_form)); + lua_pdf_literal(pdf, obj_xform_attr_str(pdf, pdf_cur_form),1); luaL_unref(Luas, LUA_REGISTRYINDEX, obj_xform_attr_str(pdf, pdf_cur_form)); set_obj_xform_attr_str(pdf, pdf_cur_form, null); } @@ -1776,11 +1699,12 @@ void pdf_begin_page(PDF pdf) } pdf_dict_add_ref(pdf, "Resources", pdf->page_resources->last_resources); } - /* Start stream of page/form contents */ + /*tex Start a stream of page or form contents: */ pdf_dict_add_streaminfo(pdf); pdf_end_dict(pdf); pdf_begin_stream(pdf); - pos_stack_used = 0; /* start with empty stack */ + /*tex Start with an empty stack: */ + pos_stack_used = 0; if (global_shipping_mode == SHIPPING_PAGE) { colorstackpagestart(); } @@ -1788,40 +1712,37 @@ void pdf_begin_page(PDF pdf) pdf_out_colorstack_startpage(pdf); } -@ @c void print_pdf_table_string(PDF pdf, const char *s) { size_t len; const char *ls; lua_rawgeti(Luas, LUA_REGISTRYINDEX, lua_key_index(pdf_data)); lua_rawget(Luas, LUA_REGISTRYINDEX); - lua_pushstring(Luas, s); /* s t ... */ - lua_rawget(Luas, -2); /* s? t ... */ - if (lua_type(Luas, -1) == LUA_TSTRING) { /* s t ... */ + lua_pushstring(Luas, s); + lua_rawget(Luas, -2); + if (lua_type(Luas, -1) == LUA_TSTRING) { ls = lua_tolstring(Luas, -1, &len); if (len > 0) { - if (pdf->cave == 1) - pdf_out(pdf, ' '); + pdf_check_space(pdf); pdf_out_block(pdf, ls, len); - pdf->cave = 1; + pdf_set_space(pdf); } } lua_pop(Luas, 2); } -@ @c const char *get_pdf_table_string(const char *s) { const_lstring ls; lua_rawgeti(Luas, LUA_REGISTRYINDEX, lua_key_index(pdf_data)); lua_rawget(Luas, LUA_REGISTRYINDEX); - lua_pushstring(Luas, s); /* s t ... */ - lua_rawget(Luas, -2); /* s? t ... */ - if (lua_type(Luas, -1) == LUA_TSTRING) { /* s t ... */ + lua_pushstring(Luas, s); + lua_rawget(Luas, -2); + if (lua_type(Luas, -1) == LUA_TSTRING) { ls.s = lua_tolstring(Luas, -1, &ls.l); - /* - s is supposed to be anchored (e.g in the registry) - so it's not garbage collected + /*tex + Here |s| is supposed to be anchored (e.g.\ in the registry) so it's + not garbage collected. */ lua_pop(Luas, 2); return ls.s; @@ -1830,7 +1751,6 @@ const char *get_pdf_table_string(const char *s) return NULL ; } -@ @c void pdf_end_page(PDF pdf) { char s[64], *p; @@ -1838,12 +1758,14 @@ void pdf_end_page(PDF pdf) pdf_resource_struct *res_p = pdf->page_resources; pdf_resource_struct local_page_resources; pdf_object_list *annot_list, *bead_list, *link_list, *ol, *ol1; - scaledpos save_cur_page_size; /* to save |pdf->page_size| during flushing pending forms */ + /*tex We save |pdf->page_size| during flushing pending forms: */ + scaledpos save_cur_page_size; shipping_mode_e save_shipping_mode; + int save_pdf_cur_form; int xform_resources; int page_resources, page_attributes; int procset = PROCSET_PDF; - /* Finish stream of page/form contents */ + /*tex Finish the stream of page or form contents: */ pdf_goto_pagemode(pdf); if (pos_stack_used > 0) { formatted_error("pdf backend","%u unmatched 'save' after %s shipout", (unsigned int) pos_stack_used, @@ -1856,7 +1778,7 @@ void pdf_end_page(PDF pdf) run_callback(callback_id, "b->",(global_shipping_mode == SHIPPING_PAGE)); if (global_shipping_mode == SHIPPING_PAGE) { pdf->last_pages = pdf_do_page_divert(pdf, pdf->last_page, 0); - /* Write out /Page object */ + /*tex Write out the |/Page| object. */ pdf_begin_obj(pdf, pdf->last_page, OBJSTM_ALWAYS); pdf_begin_dict(pdf); pdf_dict_add_name(pdf, "Type", "Page"); @@ -1869,7 +1791,7 @@ void pdf_end_page(PDF pdf) pdf_add_bp(pdf, pdf->page_size.h); pdf_add_bp(pdf, pdf->page_size.v); pdf_end_array(pdf); - page_attributes = pdf_page_attr ; /* lookup once */ + page_attributes = pdf_page_attr ; if (page_attributes != null) pdf_print_toks(pdf, page_attributes); print_pdf_table_string(pdf, "pageattributes"); @@ -1891,7 +1813,7 @@ void pdf_end_page(PDF pdf) pdf_end_dict(pdf); pdf_end_obj(pdf); pdf->img_page_group_val = 0; - /* Generate array of annotations or beads in page */ + /*tex Generate an array of annotations or beads in page. */ if (annot_list != NULL || link_list != NULL) { pdf_begin_obj(pdf, annots, OBJSTM_ALWAYS); pdf_begin_array(pdf); @@ -1917,37 +1839,38 @@ void pdf_end_page(PDF pdf) pdf_end_obj(pdf); } } - /* Write out resource lists and pending raw objects */ + /*tex Write out the resource lists and pending raw objects. */ ol = get_page_resources_list(pdf, obj_type_obj); while (ol != NULL) { if (!is_obj_written(pdf, ol->info)) pdf_write_obj(pdf, ol->info); ol = ol->link; } - - /* + /*tex When flushing pending forms we need to save and restore resource lists which are also used by page shipping. Saving and restoring - |pdf->page_size| is needed for proper writing out pending PDF marks. + |pdf->page_size| is needed for proper writing out pending \PDF\ marks. */ ol = get_page_resources_list(pdf, obj_type_xform); while (ol != NULL) { if (!is_obj_written(pdf, ol->info)) { + save_pdf_cur_form = pdf_cur_form; pdf_cur_form = ol->info; save_cur_page_size = pdf->page_size; save_shipping_mode = global_shipping_mode; pdf->page_resources = &local_page_resources; local_page_resources.resources_tree = NULL; ship_out(pdf, obj_xform_box(pdf, pdf_cur_form), SHIPPING_FORM); - /* Restore page size and page resources */ + /*tex Restore the page size and page resources. */ pdf->page_size = save_cur_page_size; global_shipping_mode = save_shipping_mode; destroy_page_resources_tree(pdf); pdf->page_resources = res_p; + pdf_cur_form = save_pdf_cur_form; } ol = ol->link; } - /* Write out pending images */ + /*tex Write out pending images. */ ol = get_page_resources_list(pdf, obj_type_ximage); while (ol != NULL) { if (!is_obj_written(pdf, ol->info)) @@ -1955,11 +1878,12 @@ void pdf_end_page(PDF pdf) ol = ol->link; } if (global_shipping_mode == SHIPPING_PAGE) { - /* Write out pending PDF marks and annotations */ + /*tex Write out pending \PDF\ marks and annotations. */ ol = get_page_resources_list(pdf, obj_type_annot); while (ol != NULL) { if (ol->info > 0 && obj_type(pdf, ol->info) == obj_type_annot) { - j = obj_annot_ptr(pdf, ol->info); /* |j| points to |pdf_annot_node| */ + /*tex Here |j| points to |pdf_annot_node|: */ + j = obj_annot_ptr(pdf, ol->info); pdf_begin_obj(pdf, ol->info, OBJSTM_ALWAYS); pdf_begin_dict(pdf); pdf_dict_add_name(pdf, "Type", "Annot"); @@ -1970,7 +1894,7 @@ void pdf_end_page(PDF pdf) } ol = ol->link; } - /* Write out PDF link annotations */ + /*tex Write out PDF link annotations. */ if ((ol = get_page_resources_list(pdf, obj_type_link)) != NULL) { while (ol != NULL) { j = obj_annot_ptr(pdf, ol->info); @@ -1989,49 +1913,52 @@ void pdf_end_page(PDF pdf) pdf_end_obj(pdf); ol = ol->link; } - /* Flush |pdf_start_link_node|'s created by |append_link| */ + /*tex Flush |pdf_start_link_node|'s created by |append_link|. */ ol = get_page_resources_list(pdf, obj_type_link); while (ol != NULL) { j = obj_annot_ptr(pdf, ol->info); - /* - nodes with |subtype = pdf_link_data_node| were created by |append_link| and - must be flushed here, as they are not linked in any list + /*tex + Nodes with |subtype = pdf_link_data_node| were created by + |append_link| and must be flushed here, as they are not + linked in any list. */ if (subtype(j) == pdf_link_data_node) flush_node(j); ol = ol->link; } } - /* Write out PDF mark destinations */ + /*tex Write out \PDF\ mark destinations. */ write_out_pdf_mark_destinations(pdf); - /* Write out PDF bead rectangle specifications */ + /*tex Write out \PDF\ bead rectangle specifications. */ print_bead_rectangles(pdf); } - /* Write out resources dictionary */ + /*tex Write out resources dictionary. */ pdf_begin_obj(pdf, res_p->last_resources, OBJSTM_ALWAYS); pdf_begin_dict(pdf); - /* Print additional resources */ + /*tex Print additional resources. */ if (global_shipping_mode == SHIPPING_PAGE) { - page_resources = pdf_page_resources; /* lookup once */ - if (page_resources != null) + page_resources = pdf_page_resources; + if (page_resources != null) { pdf_print_toks(pdf, page_resources); + } print_pdf_table_string(pdf, "pageresources"); } else { - xform_resources = pdf_xform_resources; /* lookup once */ - if (xform_resources != null) + xform_resources = pdf_xform_resources; + if (xform_resources != null) { pdf_print_toks(pdf, xform_resources); + } if (obj_xform_resources(pdf, pdf_cur_form) != null) { pdf_print_toks(pdf, obj_xform_resources(pdf, pdf_cur_form)); delete_token_ref(obj_xform_resources(pdf, pdf_cur_form)); set_obj_xform_resources(pdf, pdf_cur_form, null); } if (obj_xform_resources_str(pdf, pdf_cur_form) != null) { - lua_pdf_literal(pdf, obj_xform_resources_str(pdf, pdf_cur_form)); + lua_pdf_literal(pdf, obj_xform_resources_str(pdf, pdf_cur_form),1); luaL_unref(Luas, LUA_REGISTRYINDEX, obj_xform_resources_str(pdf, pdf_cur_form)); set_obj_xform_resources_str(pdf, pdf_cur_form, null); } } - /* Generate font resources */ + /*tex Generate font resources. */ if ((ol = get_page_resources_list(pdf, obj_type_font)) != NULL) { pdf_add_name(pdf, "Font"); pdf_begin_dict(pdf); @@ -2046,7 +1973,7 @@ void pdf_end_page(PDF pdf) pdf_end_dict(pdf); procset |= PROCSET_TEXT; } - /* Generate XObject resources */ + /*tex Generate |XObject| resources. */ ol = get_page_resources_list(pdf, obj_type_xform); ol1 = get_page_resources_list(pdf, obj_type_ximage); if (ol != NULL || ol1 != NULL) { @@ -2071,7 +1998,7 @@ void pdf_end_page(PDF pdf) } pdf_end_dict(pdf); } - /* Generate ProcSet */ + /*tex Generate |ProcSet| in version 1.*/ if (pdf->major_version == 1) { pdf_add_name(pdf, "ProcSet"); pdf_begin_array(pdf); @@ -2091,13 +2018,15 @@ void pdf_end_page(PDF pdf) pdf_end_obj(pdf); } -@* Finishing the PDF output file. +/*tex -@ Destinations that have been referenced but don't exists have -|obj_dest_ptr=null|. Leaving them undefined might cause troubles for PDF -browsers, so we need to fix them; they point to the last page. + We're now ready to wrap up the output file. Destinations that have been + referenced but don't exists have |obj_dest_ptr=null|. Leaving them undefined + might cause troubles for PDF browsers, so we need to fix them; they point to + the last page. + +*/ -@c static void check_nonexisting_destinations(PDF pdf) { int k; @@ -2120,25 +2049,27 @@ static void check_nonexisting_destinations(PDF pdf) } } -@ @c static void check_nonexisting_pages(PDF pdf) { struct avl_traverser t; oentry *p; struct avl_table *page_tree = pdf->obj_tree[obj_type_page]; avl_t_init(&t, page_tree); - /* search from the end backward until the last real page is found */ + /*tex Search from the end backward until the last real page is found. */ for (p = avl_t_last(&t, page_tree); p != NULL && obj_aux(pdf, p->objptr) == 0; p = avl_t_prev(&t)) { formatted_warning("pdf backend", "page %d has been referenced but does not exist",obj_info(pdf, p->objptr)); } } -@ If the same keys in a dictionary are given several times, then it is not -defined which value is choosen by an application. Therefore the keys |/Producer| -and |/Creator| are only set if the token list |pdf_info_toks| converted to a -string does not contain these key strings. +/*tex + + If the same keys in a dictionary are given several times, then it is not + defined which value is choosen by an application. Therefore the keys + |/Producer| and |/Creator| are only set if the token list |pdf_info_toks| + converted to a string does not contain these key strings. + +*/ -@c static boolean substr_of_str(const char *s, const char *t) { if (strstr(t, s) == NULL) @@ -2146,9 +2077,8 @@ static boolean substr_of_str(const char *s, const char *t) return true; } -static int pdf_print_info(PDF pdf, int luatexversion, - str_number luatexrevision) -{ /* print info object */ +static int pdf_print_info(PDF pdf, int luatexversion, str_number luatexrevision) +{ boolean creator_given = false; boolean producer_given = false; boolean creationdate_given = false; @@ -2158,7 +2088,7 @@ static int pdf_print_info(PDF pdf, int luatexversion, const char *p = NULL; int k, len = 0; k = pdf_create_obj(pdf, obj_type_info, 0); - pdf_begin_obj(pdf, k, 3); /* keep Info readable unless explicitely forced */ + pdf_begin_obj(pdf, k, 3); pdf_begin_dict(pdf); if (pdf_info_toks != 0) { s = tokenlist_to_cstring(pdf_info_toks, true, &len); @@ -2178,18 +2108,18 @@ static int pdf_print_info(PDF pdf, int luatexversion, } if (pdf_info_toks != null) { if (len > 0) { - pdf_out(pdf, '\n'); + pdf_check_space(pdf); pdf_puts(pdf, s); - pdf_out(pdf, '\n'); + pdf_set_space(pdf); xfree(s); } delete_token_ref(pdf_info_toks); pdf_info_toks = null; } if (p && strlen(p) > 0) { - pdf_out(pdf, '\n'); - pdf_puts(pdf, p); /* no free, pointer */ - pdf_out(pdf, '\n'); + pdf_check_space(pdf); + pdf_puts(pdf, p); + pdf_set_space(pdf); } if ((pdf_suppress_optional_info & 128) == 0 && !producer_given) { pdf_add_name(pdf, "Producer"); @@ -2223,7 +2153,8 @@ static void build_free_object_list(PDF pdf) { int k; int l = 0; - set_obj_fresh(pdf, l); /* null object at begin of list of free objects */ + /*tex A |null| object at the begin of a list of free objects. */ + set_obj_fresh(pdf, l); for (k = 1; k <= pdf->obj_ptr; k++) { if (!is_obj_written(pdf, k)) { set_obj_link(pdf, l, k); @@ -2233,272 +2164,297 @@ static void build_free_object_list(PDF pdf) set_obj_link(pdf, l, 0); } -@ Now the finish of PDF output file. At this moment all Page objects -are already written completely to PDF output file. +/*tex -@c -void finish_pdf_file(PDF pdf, int luatexversion, str_number luatexrevision) -{ - int i, j, k; - int root, info, xref_stm = 0, outlines, threads, names_tree; - size_t xref_offset_width; - int callback_id = callback_defined(stop_run_callback); - int callback_id1 = callback_defined(finish_pdffile_callback); - if (total_pages == 0) { - if (callback_id == 0) { - normal_warning("pdf backend","no pages of output."); - } else if (callback_id > 0) { - run_callback(callback_id, "->"); - } - if (pdf->gone > 0) - normal_error("pdf backend","dangling objects discarded, no output file produced."); + Now we can the finish of \PDF\ output file. At this moment all |/Page| + objects are already written completely to \PDF\ output file. + +*/ + +void pdf_finish_file(PDF pdf, int fatal_error) { + if (fatal_error) { + remove_pdffile(static_pdf); /* will become remove_output_file */ + print_err(" ==> Fatal error occurred, no output PDF file produced!"); } else { - if (pdf->draftmode == 0) { - pdf_flush(pdf); /* to make sure that the output file name has been already created */ - flush_jbig2_page0_objects(pdf); /* flush page 0 objects from JBIG2 images, if any */ - if (callback_id1 > 0) - run_callback(callback_id1, "->"); - check_nonexisting_pages(pdf); - check_nonexisting_destinations(pdf); - /* Output fonts definition */ - for (k = 1; k <= max_font_id(); k++) { - if (font_used(k) && (pdf_font_num(k) < 0)) { - i = -pdf_font_num(k); - for (j = font_bc(k); j <= font_ec(k); j++) - if (quick_char_exists(k, j) && pdf_char_marked(k, j)) - pdf_mark_char(i, j); - if ((pdf_font_attr(i) == 0) && (pdf_font_attr(k) != 0)) { - set_pdf_font_attr(i, pdf_font_attr(k)); - } else if ((pdf_font_attr(k) == 0) && (pdf_font_attr(i) != 0)) { - set_pdf_font_attr(k, pdf_font_attr(i)); - } else if ((pdf_font_attr(i) != 0) && (pdf_font_attr(k) != 0) && (!str_eq_str(pdf_font_attr(i), pdf_font_attr(k)))) { - formatted_warning("pdf backend","fontattr of font %d and %d are conflicting, %k is used",i,k,i); - } - } + int i, j, k; + int root, info; + int xref_stm = 0; + int outlines = 0; + int threads = 0; + int names_tree = 0; + size_t xref_offset_width; + int luatexversion = luatex_version; + str_number luatexrevision = get_luatexrevision(); + int callback_id = callback_defined(stop_run_callback); + int callback_id1 = callback_defined(finish_pdffile_callback); + if (total_pages == 0 && !pdf->force_file) { + if (callback_id == 0) { + normal_warning("pdf backend","no pages of output."); + } else if (callback_id > 0) { + run_callback(callback_id, "->"); } - pdf->gen_tounicode = pdf_gen_tounicode; - pdf->omit_cidset = pdf_omit_cidset; - k = pdf->head_tab[obj_type_font]; - while (k != 0) { - int f = obj_info(pdf, k); - do_pdf_font(pdf, f); - k = obj_link(pdf, k); + if (pdf->gone > 0) { + /* number of bytes gone */ + normal_error("pdf backend","already written content discarded, no output file produced."); } - write_fontstuff(pdf); - pdf->last_pages = output_pages_tree(pdf); - /* Output outlines */ - outlines = print_outlines(pdf); - /* - Output name tree. The name tree is very similiar to Pages tree so - its construction should be certain from Pages tree construction. - For intermediate node |obj_info| will be the first name and - |obj_link| will be the last name in \.{\\Limits} array. Note that - |pdf_dest_names_ptr| will be less than |obj_ptr|, so we test if - |k < pdf_dest_names_ptr| then |k| is index of leaf in - |dest_names|; else |k| will be index in |obj_tab| of some - intermediate node. - */ - names_tree = output_name_tree(pdf); - - /* Output article threads */ - if (pdf->head_tab[obj_type_thread] != 0) { - threads = pdf_create_obj(pdf, obj_type_others, 0); - pdf_begin_obj(pdf, threads, OBJSTM_ALWAYS); - pdf_begin_array(pdf); - k = pdf->head_tab[obj_type_thread]; - while (k != 0) { - pdf_add_ref(pdf, k); - k = obj_link(pdf, k); + } else { + if (pdf->draftmode == 0) { + /*tex We make sure that the output file name has been already created. */ + pdf_flush(pdf); + /*tex Flush page 0 objects from JBIG2 images, if any. */ + flush_jbig2_page0_objects(pdf); + if (callback_id1 > 0) { + run_callback(callback_id1, "->"); } - pdf_end_array(pdf); - pdf_end_obj(pdf); - k = pdf->head_tab[obj_type_thread]; + if (total_pages > 0) { + check_nonexisting_pages(pdf); + check_nonexisting_destinations(pdf); + } + /*tex Output fonts definition. */ + for (k = 1; k <= max_font_id(); k++) { + if (font_used(k) && (pdf_font_num(k) < 0)) { + i = -pdf_font_num(k); + for (j = font_bc(k); j <= font_ec(k); j++) + if (quick_char_exists(k, j) && pdf_char_marked(k, j)) + pdf_mark_char(i, j); + if ((pdf_font_attr(i) == 0) && (pdf_font_attr(k) != 0)) { + set_pdf_font_attr(i, pdf_font_attr(k)); + } else if ((pdf_font_attr(k) == 0) && (pdf_font_attr(i) != 0)) { + set_pdf_font_attr(k, pdf_font_attr(i)); + } else if ((pdf_font_attr(i) != 0) && (pdf_font_attr(k) != 0) && (!str_eq_str(pdf_font_attr(i), pdf_font_attr(k)))) { + formatted_warning("pdf backend","fontattr of font %d and %d are conflicting, %k is used",i,k,i); + } + } + } + pdf->gen_tounicode = pdf_gen_tounicode; + pdf->omit_cidset = pdf_omit_cidset; + pdf->omit_charset = pdf_omit_charset; + k = pdf->head_tab[obj_type_font]; while (k != 0) { - out_thread(pdf, k); + int f = obj_info(pdf, k); + do_pdf_font(pdf, f); k = obj_link(pdf, k); } - } else { - threads = 0; - } - /* Output the /Catalog object */ - root = pdf_create_obj(pdf, obj_type_catalog, 0); - pdf_begin_obj(pdf, root, OBJSTM_ALWAYS); - pdf_begin_dict(pdf); - pdf_dict_add_name(pdf, "Type", "Catalog"); - pdf_dict_add_ref(pdf, "Pages", pdf->last_pages); - if (threads != 0) - pdf_dict_add_ref(pdf, "Threads", threads); - if (outlines != 0) - pdf_dict_add_ref(pdf, "Outlines", outlines); - if (names_tree != 0) - pdf_dict_add_ref(pdf, "Names", names_tree); - if (pdf_catalog_toks != null) { - pdf_print_toks(pdf, pdf_catalog_toks); - delete_token_ref(pdf_catalog_toks); - pdf_catalog_toks = null; - } - print_pdf_table_string(pdf, "catalog"); - if (pdf_catalog_openaction != 0) - pdf_dict_add_ref(pdf, "OpenAction", pdf_catalog_openaction); - pdf_end_dict(pdf); - pdf_end_obj(pdf); - /* last candidate for object stream */ - info = pdf_print_info(pdf, luatexversion, luatexrevision); - /* final object for pdf->os_enable == false */ - if (pdf->os_enable) { - pdf_buffer_select(pdf, OBJSTM_BUF); - pdf_os_write_objstream(pdf); - pdf_flush(pdf); - pdf_buffer_select(pdf, PDFOUT_BUF); - /* Output the cross-reference stream dictionary */ - xref_stm = pdf_create_obj(pdf, obj_type_others, 0); - pdf_begin_obj(pdf, xref_stm, OBJSTM_NEVER); /* final object for pdf->os_enable == true */ - if ((obj_offset(pdf, pdf->obj_ptr) / 256) > 16777215) - xref_offset_width = 5; - else if (obj_offset(pdf, pdf->obj_ptr) > 16777215) - xref_offset_width = 4; - else if (obj_offset(pdf, pdf->obj_ptr) > 65535) - xref_offset_width = 3; - else - xref_offset_width = 2; - /* Build a linked list of free objects */ - build_free_object_list(pdf); + write_fontstuff(pdf); + if (total_pages > 0) { + pdf->last_pages = output_pages_tree(pdf); + /*tex Output outlines. */ + outlines = print_outlines(pdf); + /*tex + The name tree is very similiar to Pages tree so its construction + should be certain from Pages tree construction. For intermediate + node |obj_info| will be the first name and |obj_link| will be the + last name in \.{\\Limits} array. Note that |pdf_dest_names_ptr| + will be less than |obj_ptr|, so we test if |k < + pdf_dest_names_ptr| then |k| is index of leaf in |dest_names|; + else |k| will be index in |obj_tab| of some intermediate node. + */ + names_tree = output_name_tree(pdf); + /*tex Output article threads. */ + if (pdf->head_tab[obj_type_thread] != 0) { + threads = pdf_create_obj(pdf, obj_type_others, 0); + pdf_begin_obj(pdf, threads, OBJSTM_ALWAYS); + pdf_begin_array(pdf); + k = pdf->head_tab[obj_type_thread]; + while (k != 0) { + pdf_add_ref(pdf, k); + k = obj_link(pdf, k); + } + pdf_end_array(pdf); + pdf_end_obj(pdf); + k = pdf->head_tab[obj_type_thread]; + while (k != 0) { + out_thread(pdf, k); + k = obj_link(pdf, k); + } + } else { + threads = 0; + } + } + /*tex Output the |/Catalog| object. */ + root = pdf_create_obj(pdf, obj_type_catalog, 0); + pdf_begin_obj(pdf, root, OBJSTM_ALWAYS); pdf_begin_dict(pdf); - pdf_dict_add_name(pdf, "Type", "XRef"); - pdf_add_name(pdf, "Index"); - pdf_begin_array(pdf); - pdf_add_int(pdf, 0); - pdf_add_int(pdf, pdf->obj_ptr + 1); - pdf_end_array(pdf); - pdf_dict_add_int(pdf, "Size", pdf->obj_ptr + 1); - pdf_add_name(pdf, "W"); - pdf_begin_array(pdf); - pdf_add_int(pdf, 1); - pdf_add_int(pdf, (int) xref_offset_width); - pdf_add_int(pdf, 1); - pdf_end_array(pdf); - pdf_dict_add_ref(pdf, "Root", root); - pdf_dict_add_ref(pdf, "Info", info); - if (pdf_trailer_toks != null) { - pdf_print_toks(pdf, pdf_trailer_toks); - delete_token_ref(pdf_trailer_toks); - pdf_trailer_toks = null; + pdf_dict_add_name(pdf, "Type", "Catalog"); + if (total_pages > 0) { + pdf_dict_add_ref(pdf, "Pages", pdf->last_pages); + if (threads != 0) { + pdf_dict_add_ref(pdf, "Threads", threads); + } + if (outlines != 0) { + pdf_dict_add_ref(pdf, "Outlines", outlines); + } + if (names_tree != 0) { + pdf_dict_add_ref(pdf, "Names", names_tree); + } + if (pdf_catalog_toks != null) { + pdf_print_toks(pdf, pdf_catalog_toks); + delete_token_ref(pdf_catalog_toks); + pdf_catalog_toks = null; + } } - print_pdf_table_string(pdf, "trailer"); - print_ID(pdf); - pdf_dict_add_streaminfo(pdf); + if (pdf_catalog_openaction != 0) { + pdf_dict_add_ref(pdf, "OpenAction", pdf_catalog_openaction); + } + print_pdf_table_string(pdf, "catalog"); pdf_end_dict(pdf); - pdf_begin_stream(pdf); - for (k = 0; k <= pdf->obj_ptr; k++) { - if (!is_obj_written(pdf, k)) { /* a free object */ - pdf_out(pdf, 0); - pdf_out_bytes(pdf, obj_link(pdf, k), xref_offset_width); - pdf_out(pdf, 255); - } else if (obj_os_idx(pdf, k) == PDF_OS_MAX_OBJS) { /* object not in object stream */ - pdf_out(pdf, 1); - pdf_out_bytes(pdf, obj_offset(pdf, k), - xref_offset_width); - pdf_out(pdf, 0); - } else { /* object in object stream */ - pdf_out(pdf, 2); - pdf_out_bytes(pdf, obj_offset(pdf, k), - xref_offset_width); - pdf_out(pdf, obj_os_idx(pdf, k)); + pdf_end_obj(pdf); + info = pdf_print_info(pdf, luatexversion, luatexrevision); + if (pdf->os_enable) { + pdf_buffer_select(pdf, OBJSTM_BUF); + pdf_os_write_objstream(pdf); + pdf_flush(pdf); + pdf_buffer_select(pdf, PDFOUT_BUF); + /*tex Output the cross-reference stream dictionary. */ + xref_stm = pdf_create_obj(pdf, obj_type_others, 0); + pdf_begin_obj(pdf, xref_stm, OBJSTM_NEVER); + if ((obj_offset(pdf, pdf->obj_ptr) / 256) > 16777215) + xref_offset_width = 5; + else if (obj_offset(pdf, pdf->obj_ptr) > 16777215) + xref_offset_width = 4; + else if (obj_offset(pdf, pdf->obj_ptr) > 65535) + xref_offset_width = 3; + else + xref_offset_width = 2; + /*tex Build a linked list of free objects. */ + build_free_object_list(pdf); + pdf_begin_dict(pdf); + pdf_dict_add_name(pdf, "Type", "XRef"); + pdf_add_name(pdf, "Index"); + pdf_begin_array(pdf); + pdf_add_int(pdf, 0); + pdf_add_int(pdf, pdf->obj_ptr + 1); + pdf_end_array(pdf); + pdf_dict_add_int(pdf, "Size", pdf->obj_ptr + 1); + pdf_add_name(pdf, "W"); + pdf_begin_array(pdf); + pdf_add_int(pdf, 1); + pdf_add_int(pdf, (int) xref_offset_width); + pdf_add_int(pdf, 1); + pdf_end_array(pdf); + pdf_dict_add_ref(pdf, "Root", root); + pdf_dict_add_ref(pdf, "Info", info); + if (pdf_trailer_toks != null) { + pdf_print_toks(pdf, pdf_trailer_toks); + delete_token_ref(pdf_trailer_toks); + pdf_trailer_toks = null; + } + print_pdf_table_string(pdf, "trailer"); + print_ID(pdf); + pdf_dict_add_streaminfo(pdf); + pdf_end_dict(pdf); + pdf_begin_stream(pdf); + for (k = 0; k <= pdf->obj_ptr; k++) { + if (!is_obj_written(pdf, k)) { + /*tex A free object: */ + pdf_out(pdf, 0); + pdf_out_bytes(pdf, obj_link(pdf, k), xref_offset_width); + pdf_out(pdf, 255); + } else if (obj_os_idx(pdf, k) == PDF_OS_MAX_OBJS) { + /*tex An object not in object stream: */ + pdf_out(pdf, 1); + pdf_out_bytes(pdf, obj_offset(pdf, k), xref_offset_width); + pdf_out(pdf, 0); + } else { + /*tex An object in object stream: */ + pdf_out(pdf, 2); + pdf_out_bytes(pdf, obj_offset(pdf, k), xref_offset_width); + pdf_out(pdf, obj_os_idx(pdf, k)); + } + } + pdf_end_stream(pdf); + pdf_end_obj(pdf); + pdf_flush(pdf); + } else { + /*tex Output the |obj_tab| and build a linked list of free objects. */ + build_free_object_list(pdf); + pdf_save_offset(pdf); + pdf_puts(pdf, "xref\n"); + pdf_puts(pdf, "0 "); + pdf_print_int_ln(pdf, pdf->obj_ptr + 1); + pdf_print_fw_int(pdf, obj_link(pdf, 0)); + pdf_puts(pdf, " 65535 f \n"); + for (k = 1; k <= pdf->obj_ptr; k++) { + if (!is_obj_written(pdf, k)) { + pdf_print_fw_int(pdf, obj_link(pdf, k)); + pdf_puts(pdf, " 00000 f \n"); + } else { + pdf_print_fw_int(pdf, obj_offset(pdf, k)); + pdf_puts(pdf, " 00000 n \n"); + } } } - pdf_end_stream(pdf); - pdf_end_obj(pdf); - pdf_flush(pdf); - } else { - /* Output the |obj_tab| and build a linked list of free objects */ - build_free_object_list(pdf); - pdf_save_offset(pdf); - pdf_puts(pdf, "xref\n"); - pdf_puts(pdf, "0 "); - pdf_print_int_ln(pdf, pdf->obj_ptr + 1); - pdf_print_fw_int(pdf, obj_link(pdf, 0)); - pdf_puts(pdf, " 65535 f \n"); - for (k = 1; k <= pdf->obj_ptr; k++) { - if (!is_obj_written(pdf, k)) { - pdf_print_fw_int(pdf, obj_link(pdf, k)); - pdf_puts(pdf, " 00000 f \n"); - } else { - pdf_print_fw_int(pdf, obj_offset(pdf, k)); - pdf_puts(pdf, " 00000 n \n"); + /*tex Output the trailer. */ + if (!pdf->os_enable) { + pdf_puts(pdf, "trailer\n"); + pdf_reset_space(pdf); + pdf_begin_dict(pdf); + pdf_dict_add_int(pdf, "Size", pdf->obj_ptr + 1); + pdf_dict_add_ref(pdf, "Root", root); + pdf_dict_add_ref(pdf, "Info", info); + if (pdf_trailer_toks != null) { + pdf_print_toks(pdf, pdf_trailer_toks); + delete_token_ref(pdf_trailer_toks); + pdf_trailer_toks = null; } + print_ID(pdf); + pdf_end_dict(pdf); + pdf_out(pdf, '\n'); } - } - /* Output the trailer */ - if (!pdf->os_enable) { - pdf_puts(pdf, "trailer\n"); - pdf_begin_dict(pdf); - pdf_dict_add_int(pdf, "Size", pdf->obj_ptr + 1); - pdf_dict_add_ref(pdf, "Root", root); - pdf_dict_add_ref(pdf, "Info", info); - if (pdf_trailer_toks != null) { - pdf_print_toks(pdf, pdf_trailer_toks); - delete_token_ref(pdf_trailer_toks); - pdf_trailer_toks = null; + pdf_puts(pdf, "startxref\n"); + pdf_reset_space(pdf); + if (pdf->os_enable) + pdf_add_longint(pdf, (longinteger) obj_offset(pdf, xref_stm)); + else + pdf_add_longint(pdf, (longinteger) pdf->save_offset); + pdf_puts(pdf, "\n%%EOF\n"); + pdf_flush(pdf); + if (callback_id == 0) { + tprint_nl("Output written on "); + tprint(pdf->file_name); + tprint(" ("); + print_int(total_pages); + tprint(" page"); + if (total_pages != 1) + print_char('s'); + tprint(", "); + print_int(pdf_offset(pdf)); + tprint(" bytes)."); + print_ln(); + } else if (callback_id > 0) { + run_callback(callback_id, "->"); } - print_ID(pdf); - pdf_end_dict(pdf); - pdf_out(pdf, '\n'); - } - pdf_puts(pdf, "startxref\n"); - pdf->cave = 0; - if (pdf->os_enable) - pdf_add_longint(pdf, (longinteger) obj_offset(pdf, xref_stm)); - else - pdf_add_longint(pdf, (longinteger) pdf->save_offset); - pdf_puts(pdf, "\n%%EOF\n"); - pdf_flush(pdf); - if (callback_id == 0) { - tprint_nl("Output written on "); - tprint(pdf->file_name); - tprint(" ("); - print_int(total_pages); - tprint(" page"); - if (total_pages != 1) - print_char('s'); - tprint(", "); - print_int(pdf_offset(pdf)); - tprint(" bytes)."); - print_ln(); - } else if (callback_id > 0) { - run_callback(callback_id, "->"); - } - } else { - if (callback_id > 0) { - run_callback(callback_id, "->"); + libpdffinish(pdf); + close_file(pdf->file); + } else { + if (callback_id > 0) { + run_callback(callback_id, "->"); + } + libpdffinish(pdf); + normal_warning("pdf backend","draftmode enabled, not changing output pdf"); } } - libpdffinish(pdf); - if (pdf->draftmode == 0) - close_file(pdf->file); - else - normal_warning("pdf backend","draftmode enabled, not changing output pdf"); - } - if (callback_id == 0) { - if (log_opened_global) { - fprintf(log_file, "\nPDF statistics: %d PDF objects out of %d (max. %d)\n", - (int) pdf->obj_ptr, (int) pdf->obj_tab_size, - (int) sup_obj_tab_size); - if (pdf->os->ostm_ctr > 0) { - fprintf(log_file, " %d compressed objects within %d object stream%s\n", - (int) pdf->os->o_ctr, (int) pdf->os->ostm_ctr, - (pdf->os->ostm_ctr > 1 ? "s" : "")); + if (callback_id == 0) { + if (log_opened_global) { + fprintf(log_file, "\nPDF statistics: %d PDF objects out of %d (max. %d)\n", + (int) pdf->obj_ptr, (int) pdf->obj_tab_size, + (int) sup_obj_tab_size); + if (pdf->os->ostm_ctr > 0) { + fprintf(log_file, " %d compressed objects within %d object stream%s\n", + (int) pdf->os->o_ctr, (int) pdf->os->ostm_ctr, + (pdf->os->ostm_ctr > 1 ? "s" : "")); + } + fprintf(log_file, " %d named destinations out of %d (max. %d)\n", + (int) pdf->dest_names_ptr, (int) pdf->dest_names_size, + (int) sup_dest_names_size); + fprintf(log_file, " %d words of extra memory for PDF output out of %d (max. %d)\n", + (int) pdf->mem_ptr, (int) pdf->mem_size, + (int) sup_pdf_mem_size); } - fprintf(log_file, " %d named destinations out of %d (max. %d)\n", - (int) pdf->dest_names_ptr, (int) pdf->dest_names_size, - (int) sup_dest_names_size); - fprintf(log_file, " %d words of extra memory for PDF output out of %d (max. %d)\n", - (int) pdf->mem_ptr, (int) pdf->mem_size, - (int) sup_pdf_mem_size); } } } -@ @c void scan_pdfcatalog(PDF pdf) { halfword p; @@ -2518,3 +2474,43 @@ void scan_pdfcatalog(PDF pdf) } } } + +/*tex + + This function converts double to pdffloat; very small and very large numbers + are {\em not} converted to scientific notation. Here n must be a number or + real conforming to the implementation limits of \PDF\ as specified in + appendix C.1 of the \PDF\ standard. The maximum value of ints is |+2^32|, the + maximum value of reals is |+2^15| and the smallest values of reals is + |1/(2^16)|. + +*/ + +static pdffloat conv_double_to_pdffloat(double n) +{ + pdffloat a; + a.e = 6; + a.m = i64round(n * ten_pow[a.e]); + return a; +} + +void pdf_add_real(PDF pdf, double d) +{ + pdf_check_space(pdf); + print_pdffloat(pdf, conv_double_to_pdffloat(d)); + pdf_set_space(pdf); +} + +void pdf_push_list(PDF pdf, scaledpos *saved_pos, int *saved_loc) { + /* nothing */ +} + +void pdf_pop_list(PDF pdf, scaledpos *saved_pos, int *saved_loc) { + /* nothing */ +} + +extern void pdf_set_reference_point(PDF pdf, posstructure *refpoint) +{ + refpoint->pos.h = pdf_h_origin; + refpoint->pos.v = pdf->page_size.v - pdf_v_origin; +} diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfglyph.w b/Build/source/texk/web2c/luatexdir/pdf/pdfglyph.c index 0703beed22c..c7cf0439212 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfglyph.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfglyph.c @@ -1,40 +1,47 @@ -% pdfglyph.w -% -% Copyright 2009-2011 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 +/* + +Copyright 2009-2011 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/>. + +*/ #include "ptexlib.h" #include "pdf/pdfpage.h" -@ eternal constants +/*tex -@c -#define e_tj 3 /* must be 3; movements in []TJ are in fontsize/$10^3$ units */ + The |e_tj| step must be 3 because movements in |[]TJ| are in fontsize/$10^3$ + units. + +*/ + +#define e_tj 3 + +/*tex + + Use exactly this formula also for calculating the |/Width| array values. + +*/ -@ @c static int64_t pdf_char_width(pdfstructure * p, internal_font_number f, int i) { - /* use exactly this formula also for calculating the /Width array values */ return i64round((double) char_width(f, i) / font_size(f) * ten_pow[e_tj + p->cw.e]); } -@ @c void pdf_print_charwidth(PDF pdf, internal_font_number f, int i) { pdffloat cw; @@ -44,13 +51,11 @@ void pdf_print_charwidth(PDF pdf, internal_font_number f, int i) print_pdffloat(pdf, cw); } -@ @c static void setup_fontparameters(PDF pdf, internal_font_number f, int ex_glyph) { - float slant, extend, expand, scale = 1.0; + float slant, extend, squeeze, expand, scale = 1.0; float u = 1.0; pdfstructure *p = pdf->pstruct; - /* fix mantis bug \# 0000200 (acroread "feature") */ if ((font_format(f) == opentype_format || (font_format(f) == type1_format && font_encodingbytes(f) == 2)) && font_units_per_em(f) > 0) u = font_units_per_em(f) / 1000.0; pdf->f_cur = f; @@ -58,35 +63,55 @@ static void setup_fontparameters(PDF pdf, internal_font_number f, int ex_glyph) p->fs.m = i64round(font_size(f) / u / by_one_bp * ten_pow[p->fs.e]); slant = font_slant(f) / 1000.0; extend = font_extend(f) / 1000.0; + squeeze = font_squeeze(f) / 1000.0; expand = 1.0 + (ex_glyph/1) / 1000.0; - p->tj_delta.e = p->cw.e - 1; /* "- 1" makes less corrections inside []TJ */ - /* no need to be more precise than TeX (1sp) */ - while (p->tj_delta.e > 0 && (double) font_size(f) / ten_pow[p->tj_delta.e + e_tj] < 0.5) - p->tj_delta.e--; /* happens for very tiny fonts */ + /*tex The |-1| makes less corrections inside |[]TJ|: */ + p->tj_delta.e = p->cw.e - 1; + /*tex There is no need to be more precise than \TEX\ (1sp). */ + while (p->tj_delta.e > 0 && (double) font_size(f) / ten_pow[p->tj_delta.e + e_tj] < 0.5) { + /*tex This happens for very tiny fonts. */ + p->tj_delta.e--; + } p->tm[0].m = i64round(scale * expand * extend * ten_pow[p->tm[0].e]); p->tm[2].m = i64round(slant * ten_pow[p->tm[2].e]); - p->tm[3].m = i64round(scale * ten_pow[p->tm[3].e]); + p->tm[3].m = i64round(scale * squeeze * ten_pow[p->tm[3].e]); p->k2 = ten_pow[e_tj + p->cw.e] * scale / (ten_pow[p->pdf.h.e] * pdf2double(p->fs) * pdf2double(p->tm[0])); - p->cur_ex = ex_glyph ; /* we keep track of the state of ex */ + /*tex We keep track of the state of ex. */ + p->cur_ex = ex_glyph ; + p->need_width = font_width(f); + p->need_mode = font_mode(f); } - -@ @c static void set_font(PDF pdf) { pdfstructure *p = pdf->pstruct; + + if (p->need_width != 0) { + pdf_printf(pdf, "%0.3f w\n",((7227.0/7200.0)/1000.0) * p->need_width ); + p->done_width = 1; + } else if (p->done_width) { + pdf_puts(pdf, "0 w\n"); + p->done_width = 0; + } + if (p->need_mode != 0) { + pdf_printf(pdf, "%d Tr\n", (int) p->need_mode); + p->done_mode = 1; + } else if (p->done_mode) { + pdf_puts(pdf, "0 Tr\n"); + p->done_mode = 0; + } pdf_printf(pdf, "/F%d", (int) p->f_pdf); pdf_print_resname_prefix(pdf); pdf_out(pdf, ' '); print_pdffloat(pdf, p->fs); - pdf_puts(pdf, " Tf "); + pdf_puts(pdf, " Tf\n"); p->f_pdf_cur = p->f_pdf; p->fs_cur.m = p->fs.m; p->need_tf = false; - p->need_tm = true; /* always follow Tf by Tm */ + /*tex Always follow |Tf| by |Tm|: */ + p->need_tm = true; } -@ @c static void set_textmatrix(PDF pdf, scaledpos pos) { boolean move; @@ -97,24 +122,27 @@ static void set_textmatrix(PDF pdf, scaledpos pos) if (p->need_tm || move) { print_pdf_matrix(pdf, p->tm); pdf_puts(pdf, " Tm "); - p->pdf.h.m = p->pdf_bt_pos.h.m + p->tm[4].m; /* Tm replaces */ + /*tex |Tm| replaces */ + p->pdf.h.m = p->pdf_bt_pos.h.m + p->tm[4].m; p->pdf.v.m = p->pdf_bt_pos.v.m + p->tm[5].m; p->need_tm = false; } p->tm0_cur.m = p->tm[0].m; } -@ Print out a character to PDF buffer; the character will be printed in octal -form in the following cases: chars <= 32, backslash (92), left parenthesis -(40), and right parenthesis (41). +/*tex + + Print out a character to PDF buffer; the character will be printed in octal + form in the following cases: chars <= 32, backslash (92), left parenthesis + (40), and right parenthesis (41). + +*/ -@c static void pdf_print_char(PDF pdf, int c) { - if (c > 255) + if (c > 255) { return; - /* pdf_print_escaped(c) */ - if (c <= 32 || c == '\\' || c == '(' || c == ')' || c > 127) { + } else if (c <= 32 || c == '\\' || c == '(' || c == ')' || c > 127) { pdf_room(pdf, 4); pdf_quick_out(pdf, '\\'); pdf_quick_out(pdf, (unsigned char) ('0' + ((c >> 6) & 0x3))); @@ -131,7 +159,6 @@ static void pdf_print_wide_char(PDF pdf, int c) pdf_out_block(pdf, (const char *) hex, 4); } -@ @c static void begin_charmode(PDF pdf, internal_font_number f, pdfstructure * p) { if (!is_chararraymode(p)) @@ -146,7 +173,6 @@ static void begin_charmode(PDF pdf, internal_font_number f, pdfstructure * p) p->mode = PMODE_CHAR; } -@ @c void end_charmode(PDF pdf) { pdfstructure *p = pdf->pstruct; @@ -161,7 +187,6 @@ void end_charmode(PDF pdf) p->mode = PMODE_CHARARRAY; } -@ @c static void begin_chararray(PDF pdf) { pdfstructure *p = pdf->pstruct; @@ -173,7 +198,6 @@ static void begin_chararray(PDF pdf) p->mode = PMODE_CHARARRAY; } -@ @c void end_chararray(PDF pdf) { pdfstructure *p = pdf->pstruct; @@ -184,23 +208,32 @@ void end_chararray(PDF pdf) p->mode = PMODE_TEXT; } -@ We need to adapt the tm when a font changes. A change can be a change in id -(frontend) or pdf reference (backend, as we share font resources). At such a -change we also need to adapt to the slant and extend. Initially we also need to -take the exfactor of a glyph into account. When the font is unchanged, we still -need to check each glyph for a change in exfactor. We store the current one on -the state record so that we can minimize testing. +/*tex + + We need to adapt the tm when a font changes. A change can be a change in id + (frontend) or pdf reference (backend, as we share font resources). At such a + change we also need to adapt to the slant and extend. Initially we also need + to take the exfactor of a glyph into account. When the font is unchanged, we + still need to check each glyph for a change in exfactor. We store the current + one on the state record so that we can minimize testing. + +*/ -@c void pdf_place_glyph(PDF pdf, internal_font_number f, int c, int ex) { boolean move; pdfstructure *p = pdf->pstruct; scaledpos pos = pdf->posstruct->pos; - /* already done: + /*tex + + This is already done: + + \startyping if (!char_exists(f, c)) { return; } + \stoptyping + */ if (font_writingmode(f) == vertical_writingmode) { if (p->wmode != WMODE_V) { @@ -221,8 +254,8 @@ void pdf_place_glyph(PDF pdf, internal_font_number f, int c, int ex) setup_fontparameters(pdf, f, ex); p->need_tm = true; } - /* all movements */ - move = calc_pdfpos(p, pos); /* within text or chararray or char mode */ + /*tex All movements within text or chararray or char mode: */ + move = calc_pdfpos(p, pos); if (move || p->need_tm) { if (p->need_tm || (p->wmode == WMODE_H && (p->pdf_bt_pos.v.m + p->tm[5].m) != p->pdf.v.m) @@ -231,7 +264,8 @@ void pdf_place_glyph(PDF pdf, internal_font_number f, int c, int ex) pdf_goto_textmode(pdf); set_textmatrix(pdf, pos); begin_chararray(pdf); - move = calc_pdfpos(p, pos); /* for fine adjustment */ + /*tex For fine adjustment: */ + move = calc_pdfpos(p, pos); } if (move) { if (is_charmode(p)) @@ -240,7 +274,7 @@ void pdf_place_glyph(PDF pdf, internal_font_number f, int c, int ex) p->cw.m -= p->tj_delta.m * ten_pow[p->cw.e - p->tj_delta.e]; } } - /* glyph output */ + /*tex Glyph output: */ if (is_chararraymode(p)) begin_charmode(pdf, f, p); else if (!is_charmode(p)) @@ -250,5 +284,6 @@ void pdf_place_glyph(PDF pdf, internal_font_number f, int c, int ex) pdf_print_wide_char(pdf, char_index(f, c)); else pdf_print_char(pdf, c); - p->cw.m += pdf_char_width(p, p->f_pdf, c); /* aka |adv_char_width()| */ + /*tex Also known as |adv_char_width()|: */ + p->cw.m += pdf_char_width(p, p->f_pdf, c); } diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfimage.w b/Build/source/texk/web2c/luatexdir/pdf/pdfimage.c index fd364243804..a8cffb0c871 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfimage.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfimage.c @@ -1,38 +1,39 @@ -% pdfimage.w -% -% Copyright 2009-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 +Copyright 2009-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/>. + +*/ #include "ptexlib.h" -@ @c void place_img(PDF pdf, image_dict * idict, scaled_whd dim, int transform) { - float a[6]; /* transformation matrix */ + /*tex A transformation matrix: */ + float a[6]; float xoff, yoff, tmp; pdfstructure *p = pdf->pstruct; scaledpos pos = pdf->posstruct->pos; - int r; /* number of digits after the decimal point */ + /*tex The number of digits after the decimal point: */ + int r; int k; scaledpos tmppos; pdffloat cm[6]; - int groupref; /* added from web for 1.40.8 */ + int groupref; a[0] = a[3] = 1.0e6; a[1] = a[2] = 0; if (img_type(idict) == IMG_TYPE_PDF || img_type(idict) == IMG_TYPE_PDFMEMSTREAM @@ -43,48 +44,51 @@ void place_img(PDF pdf, image_dict * idict, scaled_whd dim, int transform) yoff = (float) img_yorig(idict) / (float) img_ysize(idict); r = 6; } else { - /* added from web for 1.40.8 */ if (img_type(idict) == IMG_TYPE_PNG) { groupref = img_group_ref(idict); if ((groupref > 0) && (pdf->img_page_group_val == 0)) pdf->img_page_group_val = groupref; } - /* /added from web */ a[0] /= (float) one_hundred_bp; a[3] = a[0]; xoff = yoff = 0; r = 4; } - if ((transform & 7) > 3) { /* mirror cases */ + if ((transform & 7) > 3) { + /*tex Mirror cases: */ a[0] *= -1; xoff *= -1; } switch ((transform + img_rotation(idict)) & 3) { - case 0: /* no transform */ - break; - case 1: /* rot. 90 deg. (counterclockwise) */ - a[1] = a[0]; - a[2] = -a[3]; - a[3] = a[0] = 0; - tmp = yoff; - yoff = xoff; - xoff = -tmp; - break; - case 2: /* rot. 180 deg. (counterclockwise) */ - a[0] *= -1; - a[3] *= -1; - xoff *= -1; - yoff *= -1; - break; - case 3: /* rot. 270 deg. (counterclockwise) */ - a[1] = -a[0]; - a[2] = a[3]; - a[3] = a[0] = 0; - tmp = yoff; - yoff = -xoff; - xoff = tmp; - break; - default:; + case 0: + /*tex No transform. */ + break; + case 1: + /*tex rotation over 90 degrees (counterclockwise) */ + a[1] = a[0]; + a[2] = -a[3]; + a[3] = a[0] = 0; + tmp = yoff; + yoff = xoff; + xoff = -tmp; + break; + case 2: + /*tex rotation over 180 degrees (counterclockwise) */ + a[0] *= -1; + a[3] *= -1; + xoff *= -1; + yoff *= -1; + break; + case 3: + /*tex rotation over 270 degrees (counterclockwise) */ + a[1] = -a[0]; + a[2] = a[3]; + a[3] = a[0] = 0; + tmp = yoff; + yoff = -xoff; + xoff = tmp; + break; + default:; } xoff *= (float) dim.wd; yoff *= (float) (dim.ht + dim.dp); @@ -98,21 +102,24 @@ void place_img(PDF pdf, image_dict * idict, scaled_whd dim, int transform) if ((transform & 7) > 3) k++; switch (k & 3) { - case 0: /* no transform */ - break; - case 1: /* rot. 90 deg. (counterclockwise) */ - a[4] += (float) dim.wd; - break; - case 2: /* rot. 180 deg. */ - a[4] += (float) dim.wd; - a[5] += (float) (dim.ht + dim.dp); - break; - case 3: /* rot. 270 deg. */ - a[5] += (float) (dim.ht + dim.dp); - break; - default:; + case 0: + /*tex No transform */ + break; + case 1: + /*tex rotation over 90 degrees (counterclockwise) */ + a[4] += (float) dim.wd; + break; + case 2: + /*tex rotation over 180 degrees (counterclockwise) */ + a[4] += (float) dim.wd; + a[5] += (float) (dim.ht + dim.dp); + break; + case 3: + /*tex rotation over 270 degrees (counterclockwise) */ + a[5] += (float) (dim.ht + dim.dp); + break; + default:; } - /* the following is a kludge, TODO: use pdfpage.c functions */ setpdffloat(cm[0], i64round(a[0]), r); setpdffloat(cm[1], i64round(a[1]), r); setpdffloat(cm[2], i64round(a[2]), r); @@ -124,7 +131,7 @@ void place_img(PDF pdf, image_dict * idict, scaled_whd dim, int transform) cm[4] = p->cm[4]; cm[5] = p->cm[5]; if (pdf->img_page_group_val == 0) - pdf->img_page_group_val = img_group_ref(idict); /* added from web for 1.40.8 */ + pdf->img_page_group_val = img_group_ref(idict); pdf_puts(pdf, "q\n"); pdf_print_cm(pdf, cm); pdf_puts(pdf, "/Im"); @@ -136,9 +143,8 @@ void place_img(PDF pdf, image_dict * idict, scaled_whd dim, int transform) img_state(idict) = DICT_OUTIMG; } -@ for normal output, see \.{pdflistout.w} +/*tex For normal output see |pdflistout.c|: */ -@c void pdf_place_image(PDF pdf, halfword p) { scaled_whd dim; diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdflink.w b/Build/source/texk/web2c/luatexdir/pdf/pdflink.c index b21d0774ecd..55521b17692 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdflink.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdflink.c @@ -1,31 +1,34 @@ -% pdflink.w -% -% Copyright 2009-2012 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 +/* + +Copyright 2009-2012 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/>. + +*/ #include "ptexlib.h" -@ To implement nested link annotations, we need a stack to hold copy of -|pdf_start_link_node|'s that are being written out, together with their box -nesting level. +/*tex + + To implement nested link annotations, we need a stack to hold copy of + |pdf_start_link_node|'s that are being written out, together with their box + nesting level. + +*/ -@c void push_link_level(PDF pdf, halfword p) { if (pdf->link_stack_ptr >= pdf_max_link_level) @@ -36,14 +39,12 @@ void push_link_level(PDF pdf, halfword p) pdf->link_stack[pdf->link_stack_ptr].ref_link_node = p; } -@ @c void pop_link_level(PDF pdf) { flush_node_list(pdf->link_stack[pdf->link_stack_ptr].link_node); pdf->link_stack_ptr--; } -@ @c void do_link(PDF pdf, halfword p, halfword parent_box, scaledpos cur) { scaled_whd alt_rule; @@ -59,13 +60,13 @@ void do_link(PDF pdf, halfword p, halfword parent_box, scaledpos cur) alt_rule.ht = height(p); alt_rule.dp = depth(p); set_rect_dimens(pdf, p, parent_box, cur, alt_rule, pdf_link_margin); - obj_annot_ptr(pdf, pdf_link_objnum(p)) = p; /* the reference for the pdf annot object must be set here */ + /*tex The reference for the annot object must be set here. */ + obj_annot_ptr(pdf, pdf_link_objnum(p)) = p; k = pdf_link_objnum(p); set_obj_scheduled(pdf, pdf_link_objnum(p)); addto_page_resources(pdf, obj_type_link, k); } -@ @c void end_link(PDF pdf, halfword p) { halfword q; @@ -76,10 +77,10 @@ void end_link(PDF pdf, halfword p) normal_error("pdf backend","pdf link_stack empty, 'endlink' used without 'startlink'"); if (pdf->link_stack[pdf->link_stack_ptr].nesting_level != cur_s) normal_error("pdf backend","'endlink' ended up in different nesting level than 'startlink'"); - /* - NOTA BENE: test for running link must be done on |link_node| and not + /*tex + The test for running link must be done on |link_node| and not |ref_link_node|, as |ref_link_node| can be set by |do_link| or - |append_link| already + |append_link| already. */ if (is_running(width(pdf->link_stack[pdf->link_stack_ptr].link_node))) { q = pdf->link_stack[pdf->link_stack_ptr].ref_link_node; @@ -110,15 +111,16 @@ void end_link(PDF pdf, halfword p) pop_link_level(pdf); } -@ For ``running'' annotations we must append a new node when the end of -annotation is in other box than its start. The new created node is identical to -corresponding whatsit node representing the start of annotation, but its |info| -field is |max_halfword|. We set |info| field just before destroying the node, in -order to use |flush_node_list| to do the job. +/*tex + + For ``running'' annotations we must append a new node when the end of + annotation is in other box than its start. The new created node is identical + to corresponding whatsit node representing the start of annotation, but its + |info| field is |max_halfword|. We set |info| field just before destroying + the node, in order to use |flush_node_list| to do the job. -@ Append a new pdf annot to |pdf_link_list|. +*/ -@c void append_link(PDF pdf, halfword parent_box, scaledpos cur, small_number i) { halfword p; @@ -126,7 +128,8 @@ void append_link(PDF pdf, halfword parent_box, scaledpos cur, small_number i) scaled_whd alt_rule; p = copy_node(pdf->link_stack[(int) i].link_node); pdf->link_stack[(int) i].ref_link_node = p; - subtype(p) = pdf_link_data_node; /* this node is not a normal link node */ + /*tex This node is not a normal link node. */ + subtype(p) = pdf_link_data_node; alt_rule.wd = width(p); alt_rule.ht = height(p); alt_rule.dp = depth(p); @@ -137,7 +140,6 @@ void append_link(PDF pdf, halfword parent_box, scaledpos cur, small_number i) addto_page_resources(pdf, obj_type_link, k); } -@ @c void scan_startlink(PDF pdf) { int k; @@ -155,10 +157,9 @@ void scan_startlink(PDF pdf) set_pdf_link_action(cur_list.tail_field, r); set_pdf_link_objnum(cur_list.tail_field, k); pdf_last_link = k; - /* - NOTA BENE: although it is possible to set |obj_annot_ptr(k) := tail| - here, it is not safe if nodes are later copied/destroyed/moved; a better - place to do this is inside |do_link|, when the whatsit node is written - out + /*tex + Although it is possible to set |obj_annot_ptr(k) := tail| here, it is not + safe if nodes are later copied/destroyed/moved; a better place to do this + is inside |do_link|, when the whatsit node is written out. */ } diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdflistout.w b/Build/source/texk/web2c/luatexdir/pdf/pdflistout.c index 53ed24af64a..9dbdaeefa28 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdflistout.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdflistout.c @@ -1,120 +1,48 @@ -% pdflistout.w -% -% Copyright 2009-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/>. +/* -\def\pdfTeX{pdf\TeX} +Copyright 2009-2010 Taco Hoekwater <taco@luatex.org> -@ @c -#include "ptexlib.h" +This file is part of LuaTeX. -@ @c -#define kern_width(q) width(q) + ex_kern(q) +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. -/* - ext_xn_over_d(width(q), 1000000+ex_kern(q), 1000000); -*/ +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. -@ @c -pos_info_structure pos_info; /* to be accessed from Lua */ +You should have received a copy of the GNU General Public License along +with LuaTeX; if not, see <http://www.gnu.org/licenses/>. -static backend_struct *backend = NULL; -backend_function *backend_out, *backend_out_whatsit; +*/ -@ @c -static void missing_backend_function(PDF pdf, halfword p) -{ - const char *n = get_node_name(type(p), subtype(p)); - if (type(p) == whatsit_node) - formatted_error("pdf backend","no output function for whatsit %s",n); - else - formatted_error("pdf backend","no output function for node %s",n); -} +#include "ptexlib.h" -@ @c -static void init_none_backend_functions(void) -{ - backend_struct *p = &backend[OMODE_NONE]; - p->name = strdup("(None)"); -} +#define kern_width(q) width(q) + ex_kern(q) -@ @c -static void init_pdf_backend_functions(void) -{ - backend_struct *p = &backend[OMODE_PDF]; - p->name = strdup("PDF"); - p->node_fu[rule_node] = &pdf_place_rule; - p->node_fu[glyph_node] = &pdf_place_glyph; - p->whatsit_fu[special_node] = &pdf_special; - p->whatsit_fu[pdf_literal_node] = &pdf_out_literal; - p->whatsit_fu[pdf_refobj_node] = &pdf_ref_obj; - p->whatsit_fu[pdf_annot_node] = &do_annot; - p->whatsit_fu[pdf_start_link_node] = &do_link; - p->whatsit_fu[pdf_end_link_node] = &end_link; - p->whatsit_fu[pdf_dest_node] = &do_dest; - p->whatsit_fu[pdf_thread_node] = &do_thread; - p->whatsit_fu[pdf_end_thread_node] = &end_thread; - p->whatsit_fu[late_lua_node] = &late_lua; - p->whatsit_fu[pdf_colorstack_node] = &pdf_out_colorstack; - p->whatsit_fu[pdf_setmatrix_node] = &pdf_out_setmatrix; - p->whatsit_fu[pdf_save_node] = &pdf_out_save; - p->whatsit_fu[pdf_restore_node] = &pdf_out_restore; -} +#define billion 1000000000.0 -@ @c -static void init_dvi_backend_functions(void) -{ - backend_struct *p = &backend[OMODE_DVI]; - p->name = strdup("DVI"); - p->node_fu[rule_node] = &dvi_place_rule; - p->node_fu[glyph_node] = &dvi_place_glyph; - p->whatsit_fu[special_node] = &dvi_special; - p->whatsit_fu[late_lua_node] = &late_lua; -} +#define vet_glue(A) do { \ + glue_temp=A; \ + if (glue_temp>billion) \ + glue_temp=billion; \ + else if (glue_temp<-billion) \ + glue_temp=-billion; \ + } while (0) -@ @c -void init_backend_functionpointers(output_mode o_mode) -{ - int i, j; - if (backend == NULL) { - backend = xmalloc((MAX_OMODE + 1) * sizeof(backend_struct)); - for (i = 0; i <= MAX_OMODE; i++) { - backend[i].node_fu = xmalloc((MAX_NODE_TYPE + 1) * sizeof(backend_function)); - backend[i].whatsit_fu = xmalloc((MAX_WHATSIT_TYPE + 1) * sizeof(backend_function)); - for (j = 0; j < MAX_NODE_TYPE + 1; j++) - backend[i].node_fu[j] = &missing_backend_function; - for (j = 0; j < MAX_WHATSIT_TYPE + 1; j++) - backend[i].whatsit_fu[j] = &missing_backend_function; - } - init_none_backend_functions(); - init_dvi_backend_functions(); - init_pdf_backend_functions(); - } - backend_out = backend[o_mode].node_fu; - backend_out_whatsit = backend[o_mode].whatsit_fu; -} +/*tex + + This code scans forward to the ending |dir_node| while keeping track of the + needed width in |w|. When it finds the node that will end this segment, it + stores the accumulated with in the |dir_dvi_h| field of that end node, so + that when that node is found later in the processing, the correct glue + correction can be applied (obsolete). -@ This code scans forward to the ending |dir_node| while keeping -track of the needed width in |w|. When it finds the node that will end -this segment, it stores the accumulated with in the |dir_dvi_h| field -of that end node, so that when that node is found later in the -processing, the correct glue correction can be applied (obsolete). +*/ -@c static scaled simple_advance_width(halfword p) { halfword q = p; @@ -124,8 +52,6 @@ static scaled simple_advance_width(halfword p) switch (type(q)) { case glyph_node: w += glyph_width(q); -/* experimental */ -w += x_advance(q); break; case hlist_node: case vlist_node: @@ -134,11 +60,11 @@ w += x_advance(q); w += width(q); break; case kern_node: - /* officially we should check the subtype */ + /*tex Officially we should check the subtype. */ w += kern_width(q); break; case disc_node: - /* hh: the frontend should append already */ + /* (HH): The frontend should append already. */ if (vlink(no_break(q)) != null) w += simple_advance_width(no_break(q)); default: @@ -148,13 +74,13 @@ w += x_advance(q); return w; } -@ @c static halfword calculate_width_to_enddir(halfword p, real cur_glue, scaled cur_g, halfword this_box) { int dir_nest = 1; halfword q = p, enddir_ptr = p; scaled w = 0; - real glue_temp; /* glue value before rounding */ + /*tex The glue value before rounding: */ + real glue_temp; int g_sign = glue_sign(this_box); int g_order = glue_order(this_box); while ((q != null) && (vlink(q) != null)) { @@ -172,18 +98,18 @@ static halfword calculate_width_to_enddir(halfword p, real cur_glue, scaled cur_ w += width(q); break; case kern_node: - /* officially we should check the subtype */ + /*tex Officially we should check the subtype. */ w += kern_width(q); break; case math_node: - /* begin mathskip code */ + /*tex Begin of |mathskip| code. */ if (glue_is_zero(q)) { w += surround(q); break; } else { - /* fall through: mathskip */ + /*tex Fall through |mathskip|. */ } - /* end mathskip code */ + /*tex End of |mathskip| code. */ case glue_node: w += width(q) - cur_g; if (g_sign != normal) { @@ -202,12 +128,12 @@ static halfword calculate_width_to_enddir(halfword p, real cur_glue, scaled cur_ w += cur_g; break; case disc_node: - /* hh: the frontend should append already */ + /* (HH): The frontend should append already. */ if (vlink(no_break(q)) != null) w += simple_advance_width(no_break(q)); break; case dir_node: - if (dir_dir(q) >= 0) + if (subtype(q) == normal_dir) dir_nest++; else dir_nest--; @@ -223,123 +149,115 @@ static halfword calculate_width_to_enddir(halfword p, real cur_glue, scaled cur_ } } if (enddir_ptr == p) - /* no enddir found, just transport w by begindir */ + /*tex No enddir found, just transport |w| by |begindir|. */ dir_cur_h(enddir_ptr) = w; return enddir_ptr; } -@ The |out_what| procedure takes care of outputting the whatsit nodes for -|vlist_out| and |hlist_out|, which are similar for either case. +/*tex + + The |out_what| procedure takes care of outputting the whatsit nodes for + |vlist_out| and |hlist_out|, which are similar for either case. -We don't implement \.{\\write} inside of leaders. (The reason is that -the number of times a leader box appears might be different in different -implementations, due to machine-dependent rounding in the glue calculations.) -@^leaders@> + We don't implement \.{\\write} inside of leaders. (The reason is that the + number of times a leader box appears might be different in different + implementations, due to machine-dependent rounding in the glue calculations.) + +*/ -@c -void out_what(PDF pdf, halfword p) +static void handle_backend_whatsit(PDF pdf, halfword p, halfword parent_box, scaledpos cur) { - switch (subtype(p)) { - case special_node: /* |pdf_special(pdf, p)|; */ - case late_lua_node: /* |late_lua(pdf, p)|; */ - case pdf_save_node: /* |pdf_out_save(pdf, p)|; */ - case pdf_restore_node: /* |pdf_out_restore(pdf, p)|; */ - case pdf_end_link_node: /* |end_link(pdf, p)|; */ - case pdf_end_thread_node: /* |end_thread(pdf, p)|; */ - case pdf_literal_node: /* |pdf_out_literal(pdf, p)|; */ - case pdf_colorstack_node: /* |pdf_out_colorstack(pdf, p)|; */ - case pdf_setmatrix_node: /* |pdf_out_setmatrix(pdf, p)|; */ - case pdf_refobj_node: /* |pdf_ref_obj(pdf, p)| */ - backend_out_whatsit[subtype(p)] (pdf, p); - break; - case open_node: - case write_node: - case close_node: - /* do some work that has been queued up for \.{\\write} */ - if (!doing_leaders) { - int j = write_stream(p); - if (subtype(p) == write_node) { - write_out(p); - } else if (subtype(p) == close_node) { - close_write_file(j); - } else if (valid_write_file(j)) { - char *fn; - close_write_file(j); - cur_name = open_name(p); - cur_area = open_area(p); - cur_ext = open_ext(p); - if (cur_ext == get_nullstr()) - cur_ext = maketexstring(".tex"); - fn = pack_file_name(cur_name, cur_area, cur_ext); - while (! open_write_file(j,fn)) { - fn = prompt_file_name("output file name", ".tex"); - } - } - } - break; - case user_defined_node: - break; - default: - /* this should give an error about missing whatsit backend function */ - backend_out_whatsit[subtype(p)] (pdf, p); + if (output_mode_used == OMODE_PDF) { + switch (subtype(p)) { + case pdf_literal_node: + case pdf_save_node: + case pdf_restore_node: + case pdf_setmatrix_node: + case pdf_colorstack_node: + case pdf_refobj_node: + case pdf_end_link_node: + case pdf_end_thread_node: + backend_out_whatsit[subtype(p)](pdf, p); + break; + case pdf_annot_node: + case pdf_start_link_node: + case pdf_dest_node: + case pdf_start_thread_node: + case pdf_thread_node: + backend_out_whatsit[subtype(p)](pdf, p, parent_box, cur); + break; + default: + /*tex We ignore bad ones. */ + break; + } } } -@ @c void hlist_out(PDF pdf, halfword this_box, int rule_callback_id) { - posstructure localpos; /* the position structure local within this function */ - posstructure *refpos; /* the list origin pos. on the page, provided by the caller */ + /*tex the position structure local within this function */ + posstructure localpos; + /*tex the list origin pos. on the page, provided by the caller */ + posstructure *refpos; + /*tex A few status variables. */ scaledpos cur = { 0, 0 }, tmpcur, basepoint; - scaledpos size = { 0, 0 }; /* rule dimensions */ + /*tex rule dimensions */ + scaledpos size = { 0, 0 }; scaled effective_horizontal; - scaled save_h; /* what |cur.h| should pop to */ - scaled edge; /* right edge of sub-box or leader space */ - halfword enddir_ptr; /* temporary pointer to enddir node */ - int g_order; /* applicable order of infinity for glue */ - int g_sign; /* selects type of glue */ - halfword p, q; /* current position in the hlist */ - halfword leader_box; /* the leader box being replicated */ - scaled leader_wd; /* width of leader box being replicated */ - scaled lx; /* extra space between leader boxes */ - boolean outer_doing_leaders; /* were we doing leaders? */ - real glue_temp; /* glue value before rounding */ - real cur_glue = 0.0; /* glue seen so far */ - scaled cur_g = 0; /* rounded equivalent of |cur_glue| times the glue ratio */ + /*tex what |cur.h| should pop to */ + scaled save_h; + /*tex right edge of sub-box or leader space */ + scaled edge; + /*tex temporary pointer to enddir node */ + halfword enddir_ptr; + /*tex applicable order of infinity for glue */ + int g_order; + /*tex selects type of glue */ + int g_sign; + /*tex glue variables */ + int lq, lr; + /*tex current position in the hlist */ + halfword p, q; + /*tex the leader box being replicated */ + halfword leader_box; + /*tex width of leader box being replicated */ + scaled leader_wd; + /*tex extra space between leader boxes */ + scaled lx; + /*tex were we doing leaders? */ + boolean outer_doing_leaders; + /*tex glue value before rounding */ + real glue_temp; + /*tex glue seen so far */ + real cur_glue = 0.0; + /*tex rounded equivalent of |cur_glue| times the glue ratio */ + scaled cur_g = 0; scaled_whd rule, ci; - int i; /* index to scan |pdf_link_stack| */ - int save_loc = 0; /* DVI! \.{DVI} byte location upon entry */ - scaledpos save_dvi = { 0, 0 }; /* DVI! what |dvi| should pop to */ + /*tex index to scan |pdf_link_stack| */ + int i; + /*tex DVI! \.{DVI} byte location upon entry */ + int saved_loc = 0; + /*tex DVI! what |dvi| should pop to */ + scaledpos saved_pos = { 0, 0 }; int synctex = synctex_par ; - + scaled rleft, rright; g_order = glue_order(this_box); g_sign = glue_sign(this_box); p = list_ptr(this_box); - refpos = pdf->posstruct; - pdf->posstruct = &localpos; /* use local structure for recursion */ + /*tex use local structure for recursion */ + pdf->posstruct = &localpos; localpos.pos = refpos->pos; localpos.dir = box_dir(this_box); - cur_s++; - if (cur_s > max_push) - max_push = cur_s; - - if (output_mode_used == OMODE_DVI) { - if (cur_s > 0) { - dvi_push(); - save_dvi = dvi; - } - save_loc = dvi_offset + dvi_ptr; - } - + backend_out_control[backend_control_push_list](pdf,&saved_pos,&saved_loc); for (i = 1; i <= pdf->link_stack_ptr; i++) { if (pdf->link_stack[i].nesting_level == cur_s) append_link(pdf, this_box, cur, (small_number) i); } - - if (synctex) + if (synctex) { synctexhlist(this_box); + } while (p != null) { if (is_char_node(p)) { do { @@ -351,8 +269,6 @@ void hlist_out(PDF pdf, halfword this_box, int rule_callback_id) ci = output_one_char(pdf, p); if (textdir_parallel(localpos.dir, dir_TLT)) { cur.h += ci.wd; -/* experimental */ -cur.h += x_advance(p); } else { cur.h += ci.ht + ci.dp; } @@ -362,7 +278,10 @@ cur.h += x_advance(p); if (synctex) synctexcurrent(); } else { - /* output the non-|char_node| |p| for |hlist_out| and move to the next node */ + /*tex + Output the non-|char_node| |p| for |hlist_out| and move to the + next node. + */ switch (type(p)) { case hlist_node: case vlist_node: @@ -387,26 +306,36 @@ cur.h += x_advance(p); basepoint.h = height(p); } if (is_rotated(localpos.dir)) { - if (partextdir_eq(localpos.dir, box_dir(p))) - basepoint.v = -width(p) / 2; /* up */ - else - basepoint.v = width(p) / 2; /* down */ + if (partextdir_eq(localpos.dir, box_dir(p))) { + /*tex up */ + basepoint.v = -width(p) / 2; + } else { + /*tex down */ + basepoint.v = width(p) / 2; + } } else if (is_mirrored(localpos.dir)) { - if (partextdir_eq(localpos.dir, box_dir(p))) + if (partextdir_eq(localpos.dir, box_dir(p))) { basepoint.v = 0; - else - basepoint.v = width(p); /* down */ + } else { + /*tex down */ + basepoint.v = width(p); + } } else { - if (partextdir_eq(localpos.dir, box_dir(p))) - basepoint.v = -width(p); /* up */ - else + if (partextdir_eq(localpos.dir, box_dir(p))) { + /*tex up */ + basepoint.v = -width(p); + } else { basepoint.v = 0; + } } } - if (!is_mirrored(localpos.dir)) - basepoint.v = basepoint.v + shift_amount(p); /* shift the box down */ - else - basepoint.v = basepoint.v - shift_amount(p); /* shift the box up */ + if (!is_mirrored(localpos.dir)) { + /*tex Shift the box down. */ + basepoint.v = basepoint.v + shift_amount(p); + } else { + /*tex Shift the box up. */ + basepoint.v = basepoint.v - shift_amount(p); + } if (list_ptr(p) == null) { if (synctex) { if (type(p) == vlist_node) @@ -426,10 +355,11 @@ cur.h += x_advance(p); cur.h += effective_horizontal; break; case disc_node: - /* hh: the frontend should append already */ + /*tex (HH): the frontend should append already */ if (vlink(no_break(p)) != null) { if (subtype(p) != select_disc) { - q = tail_of_list(vlink(no_break(p))); /* this could be a tlink */ + /*tex This could be a |tlink|. */ + q = tail_of_list(vlink(no_break(p))); vlink(q) = vlink(p); q = vlink(no_break(p)); vlink(no_break(p)) = null; @@ -441,17 +371,20 @@ cur.h += x_advance(p); if (synctex) { synctexmath(p, this_box); } - /* begin mathskip code */ + /*tex Begin |mathskip| code. */ if (glue_is_zero(p)) { cur.h += surround(p); break; } else { - /* fall through: mathskip */ + /*tex Fall through |mathskip|. */ } - /* end mathskip code */ + /*tex End |mathskip| code. */ case glue_node: { - /* move right or output leaders, we use real multiplication */ + /*tex + Move right or output leaders, we use real + multiplication. + */ rule.wd = width(p) - cur_g; if (g_sign != normal) { if (g_sign == stretching) { @@ -468,11 +401,16 @@ cur.h += x_advance(p); } rule.wd = rule.wd + cur_g; if (subtype(p) >= a_leaders) { - /* output leaders in an hlist, |goto fin_rule| if a rule or to |next_p| if done */ + /*tex + Output leaders in an hlist, |goto fin_rule| if a rule + or to |next_p| if done. + */ leader_box = leader_ptr(p); if (type(leader_box) == rule_node) { rule.ht = height(leader_box); rule.dp = depth(leader_box); + rleft = 0; + rright = 0; goto FIN_RULE; } if (textdir_parallel(box_dir(leader_box), localpos.dir)) @@ -480,12 +418,14 @@ cur.h += x_advance(p); else leader_wd = height(leader_box) + depth(leader_box); if ((leader_wd > 0) && (rule.wd > 0)) { - rule.wd = rule.wd + 10; /* compensate for floating-point rounding */ + /*tex Compensate for floating-point rounding. */ + rule.wd = rule.wd + 10; edge = cur.h + rule.wd; lx = 0; - /* - let |cur.h| be the position of the first box, and set |leader_wd+lx| - to the spacing between corresponding parts of boxes + /*tex + Let |cur.h| be the position of the first box, and + set |leader_wd+lx| to the spacing between + corresponding parts of boxes. */ if (subtype(p) == g_leaders) { save_h = cur.h; @@ -522,8 +462,10 @@ cur.h += x_advance(p); if (cur.h < save_h) cur.h += leader_wd; } else { - lq = rule.wd / leader_wd; /* the number of box copies */ - lr = rule.wd % leader_wd; /* the remaining space */ + /*tex The number of box copies: */ + lq = rule.wd / leader_wd; + /*tex The remaining space: */ + lr = rule.wd % leader_wd; if (subtype(p) == c_leaders) { cur.h += lr / 2; } else { @@ -532,7 +474,10 @@ cur.h += x_advance(p); } } while (cur.h + leader_wd <= edge) { - /* output a leader box at |cur.h|, then advance |cur.h| by |leader_wd+lx| */ + /*tex + Output a leader box at |cur.h|, then advance + |cur.h| by |leader_wd+lx|. + */ if (pardir_parallel(box_dir(leader_box), localpos.dir)) { basepoint.v = 0; if (textdir_opposite(box_dir(leader_box), localpos.dir)) @@ -582,7 +527,7 @@ cur.h += x_advance(p); case kern_node: if (synctex) synctexkern(p, this_box); - /* officially we should check the subtype */ + /*tex officially we should check the subtype */ cur.h += kern_width(p); break; case rule_node: @@ -597,14 +542,18 @@ cur.h += x_advance(p); rule.dp = width(p) / 2; rule.wd = height(p) + depth(p); } + rleft = rule_left(p); + rright = rule_right(p); goto FIN_RULE; break; case dir_node: - /* output a reflection instruction if the direction has changed */ - if (dir_dir(p) >= 0) { - /* + /*tex + Output a reflection instruction if the direction has changed. + */ + if (subtype(p) == normal_dir) { + /*tex Calculate the needed width to the matching |enddir|, return the - |enddir| node, with width info + |enddir| node, with width info. */ enddir_ptr = calculate_width_to_enddir(p, cur_glue, cur_g, this_box); if (textdir_parallel(dir_dir(p), localpos.dir)) { @@ -614,14 +563,14 @@ cur.h += x_advance(p); } else dir_cur_h(enddir_ptr) = cur.h; if (enddir_ptr != p) { - /* only if it is an enddir */ + /*tex Only if it is an |enddir|. */ dir_cur_v(enddir_ptr) = cur.v; dir_refpos_h(enddir_ptr) = refpos->pos.h; dir_refpos_v(enddir_ptr) = refpos->pos.v; - /* negative: mark it as |enddir| */ - dir_dir(enddir_ptr) = localpos.dir - dir_swap; + /*tex Negative: mark it as |enddir|. */ + dir_dir(enddir_ptr) = localpos.dir; } - /* fake a nested |hlist_out| */ + /*tex fake a nested |hlist_out|. */ synch_pos_with_cur(pdf->posstruct, refpos, cur); refpos->pos = pdf->posstruct->pos; localpos.dir = dir_dir(p); @@ -630,32 +579,44 @@ cur.h += x_advance(p); } else { refpos->pos.h = dir_refpos_h(p); refpos->pos.v = dir_refpos_v(p); - localpos.dir = dir_dir(p) + dir_swap; + localpos.dir = dir_dir(p); cur.h = dir_cur_h(p); cur.v = dir_cur_v(p); } break; case whatsit_node: - /* output the whatsit node |p| in |hlist_out| */ - switch (subtype(p)) { - case save_pos_node: - last_position = pdf->posstruct->pos; - pos_info.curpos = pdf->posstruct->pos; - pos_info.boxpos.pos = refpos->pos; - pos_info.boxpos.dir = localpos.dir; - pos_info.boxdim.wd = width(this_box); - pos_info.boxdim.ht = height(this_box); - pos_info.boxdim.dp = depth(this_box); - break; - case pdf_annot_node: - case pdf_start_link_node: - case pdf_dest_node: - case pdf_start_thread_node: - case pdf_thread_node: - backend_out_whatsit[subtype(p)] (pdf, p, this_box, cur); - break; - default: - out_what(pdf, p); + /*tex Output the whatsit node |p| in |hlist_out|. */ + if (subtype(p) <= last_common_whatsit) { + switch (subtype(p)) { + case save_pos_node: + last_position = pdf->posstruct->pos; + /* + pos_info.curpos = pdf->posstruct->pos; + pos_info.boxpos.pos = refpos->pos; + pos_info.boxpos.dir = localpos.dir; + pos_info.boxdim.wd = width(this_box); + pos_info.boxdim.ht = height(this_box); + pos_info.boxdim.dp = depth(this_box); + */ + break; + case user_defined_node: + break; + case open_node: + case write_node: + case close_node: + wrapup_leader(p); + break; + case special_node: + /*tex |pdf_special(pdf, p)| */ + case late_lua_node: + /*tex |late_lua(pdf, p)| */ + backend_out_whatsit[subtype(p)] (pdf, p); + break; + default: + break; + } + } else { + handle_backend_whatsit(pdf, p, this_box, cur); } break; case margin_kern_node: @@ -666,12 +627,21 @@ cur.h += x_advance(p); } goto NEXTP; FIN_RULE: - /* output a rule in an hlist */ - if (is_running(rule.ht)) + /*tex Output a rule in an hlist. */ + if (is_running(rule.ht)) { rule.ht = height(this_box); - if (is_running(rule.dp)) + } + if (rleft != 0) { + rule.ht -= rleft; + pos_down(-rleft); + } + if (is_running(rule.dp)) { rule.dp = depth(this_box); - /* we don't output empty rules */ + } + if (rright != 0) { + rule.dp -= rright; + } + /*tex We don't output empty rules. */ if ((rule.ht + rule.dp) > 0 && rule.wd > 0) { switch (localpos.dir) { case dir_TLT: @@ -725,92 +695,85 @@ cur.h += x_advance(p); synch_pos_with_cur(pdf->posstruct, refpos, cur); } } - if (synctex) + if (synctex) { synctextsilh(this_box); - if (output_mode_used == OMODE_DVI) { - prune_movements(save_loc); - if (cur_s > 0) { - dvi_pop(save_loc); - dvi = save_dvi; - } } + backend_out_control[backend_control_pop_list](pdf,&saved_pos,&saved_loc); cur_s--; pdf->posstruct = refpos; } -@ @c void vlist_out(PDF pdf, halfword this_box, int rule_callback_id) { - posstructure localpos; /* the position structure local within this function */ - posstructure *refpos; /* the list origin pos. on the page, provided by the caller */ - + /*tex The position structure local within this function: */ + posstructure localpos; + /*tex The list origin pos. on the page, provided by the caller: */ + posstructure *refpos; + /*tex a few status variables */ scaledpos cur, tmpcur, basepoint; - scaledpos size = { 0, 0 }; /* rule dimensions */ + /*tex rule dimensions */ + scaledpos size = { 0, 0 }; scaled effective_vertical; - scaled save_v; /* what |cur.v| should pop to */ - scaled top_edge; /* the top coordinate for this box */ - scaled edge; /* bottom boundary of leader space */ - glue_ord g_order; /* applicable order of infinity for glue */ - int g_sign; /* selects type of glue */ - halfword p; /* current position in the vlist */ - halfword q; /* temp */ - halfword leader_box; /* the leader box being replicated */ - scaled leader_ht; /* height of leader box being replicated */ - scaled lx; /* extra space between leader boxes */ - boolean outer_doing_leaders; /* were we doing leaders? */ - real glue_temp; /* glue value before rounding */ - real cur_glue = 0.0; /* glue seen so far */ - scaled cur_g = 0; /* rounded equivalent of |cur_glue| times the glue ratio */ + /*tex what |cur.v| should pop to */ + scaled save_v; + /*tex the top coordinate for this box */ + scaled top_edge; + /*tex bottom boundary of leader space */ + scaled edge; + /*tex applicable order of infinity for glue */ + glue_ord g_order; + /*tex selects type of glue */ + int g_sign; + /*tex glue variables */ + int lq, lr; + /*tex current position in the vlist */ + halfword p; + /*tex temp */ + halfword q; + /*tex the leader box being replicated */ + halfword leader_box; + /*tex height of leader box being replicated */ + scaled leader_ht; + /*tex extra space between leader boxes */ + scaled lx; + /*tex were we doing leaders? */ + boolean outer_doing_leaders; + /*tex glue value before rounding */ + real glue_temp; + /*tex glue seen so far */ + real cur_glue = 0.0; + /*tex rounded equivalent of |cur_glue| times the glue ratio */ + scaled cur_g = 0; scaled_whd rule; - int save_loc = 0; /* DVI byte location upon entry */ - scaledpos save_dvi = { 0, 0 }; /* DVI! what |dvi| should pop to */ + /*tex \DVI\ byte location upon entry */ + int saved_loc = 0; + /*tex \DVI\ what |dvi| should pop to */ + scaledpos saved_pos = { 0, 0 }; int synctex = synctex_par ; - + int rleft, rright; g_order = (glue_ord) glue_order(this_box); g_sign = glue_sign(this_box); p = list_ptr(this_box); - cur.h = 0; cur.v = -height(this_box); top_edge = cur.v; - refpos = pdf->posstruct; - pdf->posstruct = &localpos; /* use local structure for recursion */ + /*tex Use local structure for recursion. */ + pdf->posstruct = &localpos; localpos.dir = box_dir(this_box); synch_pos_with_cur(pdf->posstruct, refpos, cur); - cur_s++; - if (cur_s > max_push) - max_push = cur_s; - - if (output_mode_used == OMODE_DVI) { - if (cur_s > 0) { - dvi_push(); - save_dvi = dvi; - } - save_loc = dvi_offset + dvi_ptr; - } - - if (synctex) + backend_out_control[backend_control_push_list](pdf,&saved_pos,&saved_loc); + if (synctex) { synctexvlist(this_box); - - /* create thread for the current vbox if needed */ + } + /*tex Create thread for the current vbox if needed. */ check_running_thread(pdf, this_box, cur); - while (p != null) { switch (type(p)) { case hlist_node: case vlist_node: - /* - output a box in a vlist: - - todo: the direct test to switch between |width(p)| and |-width(p)| - is definately wrong, because it does not nest properly. But at least - it fixes a very obvious problem that otherwise occured with - \.{\\pardir TLT} in a document with \.{\\bodydir TRT}, and so it - will have to do for now. (hh: is this still true?) - - */ + /*tex Output a box in a vlist. */ if (pardir_parallel(box_dir(p), localpos.dir)) { effective_vertical = height(p) + depth(p); if ((type(p) == hlist_node) && is_mirrored(box_dir(p))) @@ -839,7 +802,8 @@ void vlist_out(PDF pdf, halfword this_box, int rule_callback_id) else basepoint.v = width(p); } - basepoint.h = basepoint.h + shift_amount(p); /* shift the box right */ + /*tex Shift the box right. */ + basepoint.h = basepoint.h + shift_amount(p); if (list_ptr(p) == null) { cur.v += effective_vertical; if (synctex) { @@ -872,11 +836,15 @@ void vlist_out(PDF pdf, halfword this_box, int rule_callback_id) rule.dp = width(p) / 2; rule.wd = height(p) + depth(p); } + rleft = rule_left(p); + rright = rule_right(p); goto FIN_RULE; break; case glue_node: { - /* move down or output leaders, we use real multiplication */ + /*tex + Move down or output leaders, we use real multiplication. + */ rule.ht = width(p) - cur_g; if (g_sign != normal) { if (g_sign == stretching) { @@ -893,25 +861,38 @@ void vlist_out(PDF pdf, halfword this_box, int rule_callback_id) } rule.ht = rule.ht + cur_g; if (subtype(p) >= a_leaders) { - /* output leaders in a vlist, |goto fin_rulefin_rule| if a rule or to |next_p| if done */ + /*tex + Output leaders in a vlist, |goto fin_rulefin_rule| if a + rule or to |next_p| if done. + */ leader_box = leader_ptr(p); if (type(leader_box) == rule_node) { rule.wd = width(leader_box); rule.dp = 0; + rleft = 0; + rright = 0; goto FIN_RULE; } leader_ht = height(leader_box) + depth(leader_box); if ((leader_ht > 0) && (rule.ht > 0)) { - rule.ht = rule.ht + 10; /* compensate for floating-point rounding */ + /*tex Compensate for floating-point rounding: */ + rule.ht = rule.ht + 10; edge = cur.v + rule.ht; lx = 0; - /* - let |cur.v| be the position of the first box, and set |leader_ht+lx| - to the spacing between corresponding parts of boxes + /*tex + Let |cur.v| be the position of the first box, and set + |leader_ht+lx| to the spacing between corresponding + parts of boxes. */ if (subtype(p) == g_leaders) { save_v = cur.v; switch (localpos.dir) { + case dir_TLT: + case dir_TRT: + cur.v = refpos->pos.v - shipbox_refpos.v - cur.v; + cur.v = leader_ht * (cur.v / leader_ht); + cur.v = refpos->pos.v - shipbox_refpos.v - cur.v; + break; case dir_LTL: cur.v += refpos->pos.h - shipbox_refpos.h; cur.v = leader_ht * (cur.v / leader_ht); @@ -922,12 +903,6 @@ void vlist_out(PDF pdf, halfword this_box, int rule_callback_id) cur.v = leader_ht * (cur.v / leader_ht); cur.v = refpos->pos.h - shipbox_refpos.h - cur.v; break; - case dir_TLT: - case dir_TRT: - cur.v = refpos->pos.v - shipbox_refpos.v - cur.v; - cur.v = leader_ht * (cur.v / leader_ht); - cur.v = refpos->pos.v - shipbox_refpos.v - cur.v; - break; default: formatted_warning("pdf backend","forcing bad dir %i to TLT in vlist case 1",localpos.dir); localpos.dir = dir_TLT; @@ -944,8 +919,10 @@ void vlist_out(PDF pdf, halfword this_box, int rule_callback_id) if (cur.v < save_v) cur.v += leader_ht; } else { - lq = rule.ht / leader_ht; /* the number of box copies */ - lr = rule.ht % leader_ht; /* the remaining space */ + /*tex The number of box copies. */ + lq = rule.ht / leader_ht; + /*tex The remaining space. */ + lr = rule.ht % leader_ht; if (subtype(p) == c_leaders) { cur.v += lr / 2; } else { @@ -953,9 +930,11 @@ void vlist_out(PDF pdf, halfword this_box, int rule_callback_id) cur.v += (lr - (lq - 1) * lx) / 2; } } - while (cur.v + leader_ht <= edge) { - /* output a leader box at |cur.v|, then advance |cur.v| by |leader_ht+lx| */ + /*tex + Output a leader box at |cur.v|, then advance + |cur.v| by |leader_ht+lx|. + */ tmpcur.h = shift_amount(leader_box); tmpcur.v = cur.v + height(leader_box); synch_pos_with_cur(pdf->posstruct, refpos, tmpcur); @@ -979,41 +958,62 @@ void vlist_out(PDF pdf, halfword this_box, int rule_callback_id) cur.v += width(p); break; case whatsit_node: - /* output the whatsit node |p| in |vlist_out| */ - switch (subtype(p)) { - case save_pos_node: - last_position = pdf->posstruct->pos; - pos_info.curpos = pdf->posstruct->pos; - pos_info.boxpos.pos = refpos->pos; - pos_info.boxpos.dir = localpos.dir; - pos_info.boxdim.wd = width(this_box); - pos_info.boxdim.ht = height(this_box); - pos_info.boxdim.dp = depth(this_box); - break; - case pdf_annot_node: - case pdf_start_link_node: - case pdf_dest_node: - case pdf_start_thread_node: - case pdf_thread_node: - backend_out_whatsit[subtype(p)] (pdf, p, this_box, cur); - break; - default: - out_what(pdf, p); + /*tex Output the whatsit node |p| in |vlist_out|. */ + if (subtype(p) <= last_common_whatsit) { + switch (subtype(p)) { + case save_pos_node: + last_position = pdf->posstruct->pos; + /* + pos_info.curpos = pdf->posstruct->pos; + pos_info.boxpos.pos = refpos->pos; + pos_info.boxpos.dir = localpos.dir; + pos_info.boxdim.wd = width(this_box); + pos_info.boxdim.ht = height(this_box); + pos_info.boxdim.dp = depth(this_box); + */ + break; + case user_defined_node: + break; + case open_node: + case write_node: + case close_node: + wrapup_leader(p); + break; + case special_node: + /*tex |pdf_special(pdf, p)|; */ + case late_lua_node: + /*tex |late_lua(pdf, p)|; */ + backend_out_whatsit[subtype(p)] (pdf, p); + break; + default: + break; + } + } else { + handle_backend_whatsit(pdf, p, this_box, cur); } break; case glyph_node: case disc_node: - confusion("vlistout"); /* this can't happen */ + /*tex This can't happen unless one messes up in \LUA. */ + confusion("vlistout"); break; default: break; } goto NEXTP; FIN_RULE: - /* output a rule in a vlist, |goto next_p| */ - if (is_running(rule.wd)) + /*tex Output a rule in a vlist and |goto next_p|. */ + if (is_running(rule.wd)) { rule.wd = width(this_box); - /* we don't output empty rules */ + } + if (rleft != 0) { + rule.wd -= rleft; + pos_left(-rleft); + } + if (rright != 0) { + rule.wd -= rright; + } + /*tex We don't output empty rules. */ if ((rule.ht + rule.dp) > 0 && rule.wd > 0) { switch (localpos.dir) { case dir_TLT: @@ -1063,16 +1063,10 @@ void vlist_out(PDF pdf, halfword this_box, int rule_callback_id) p = vlink(p); synch_pos_with_cur(pdf->posstruct, refpos, cur); } - if (synctex) + if (synctex) { synctextsilv(this_box); - - if (output_mode_used == OMODE_DVI) { - prune_movements(save_loc); - if (cur_s > 0) { - dvi_pop(save_loc); - dvi = save_dvi; - } } + backend_out_control[backend_control_pop_list](pdf,&saved_pos,&saved_loc); cur_s--; pdf->posstruct = refpos; } diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.w b/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.c index 94bb2c93c4a..e8b00a64ef5 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.c @@ -1,27 +1,26 @@ -% pdfliteral.w -% -% Copyright 2009-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 +/* + +Copyright 2009-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/>. + +*/ #include "ptexlib.h" -@ @c void pdf_special(PDF pdf, halfword p) { int old_setting = selector; @@ -34,18 +33,22 @@ void pdf_special(PDF pdf, halfword p) flush_str(s); } -@ To ship out a \TeX\ box to PDF page description we need to implement -|hlist_out|, |vlist_out| and |ship_out|, which are equivalent to the \TeX' -original |hlist_out|, |vlist_out| and |ship_out| resp. But first we need to -declare some procedures needed in |hlist_out| and |vlist_out|. +/*tex + + To ship out a \TeX\ box to PDF page description we need to implement + |hlist_out|, |vlist_out| and |ship_out|, which are equivalent to the \TeX' + original |hlist_out|, |vlist_out| and |ship_out| resp. But first we need to + declare some procedures needed in |hlist_out| and |vlist_out|. + +*/ -@c void pdf_out_literal(PDF pdf, halfword p) { - int old_setting; /* holds print |selector| */ + int old_setting; str_number s; + int t = pdf_literal_type(p); pdfstructure *ps = pdf->pstruct; - if (pdf_literal_type(p) == normal) { + if (t == normal) { old_setting = selector; selector = new_string; show_token_list(token_link(pdf_literal_data(p)), null, -1); @@ -53,7 +56,7 @@ void pdf_out_literal(PDF pdf, halfword p) s = make_string(); pdf_literal(pdf, s, pdf_literal_mode(p), false); flush_str(s); - } else { + } else if (t == lua_refid_literal) { switch (pdf_literal_mode(p)) { case set_origin: pdf_goto_pagemode(pdf); @@ -79,12 +82,12 @@ void pdf_out_literal(PDF pdf, halfword p) normal_error("pdf backend","bad literal mode"); break; } - lua_pdf_literal(pdf, pdf_literal_data(p)); + lua_pdf_literal(pdf, pdf_literal_data(p), 0); } } -@ test equality of start of strings -@c +/*tex Test equality of start of strings: */ + static boolean str_in_cstr(str_number s, const char *r, unsigned i) { const unsigned char *k, *l; @@ -99,38 +102,50 @@ static boolean str_in_cstr(str_number s, const char *r, unsigned i) return true; } -@ @c void pdf_literal(PDF pdf, str_number s, int literal_mode, boolean warn) { unsigned char *ss; size_t l; - pool_pointer j = 0; /* current character code position, initialized to make the compiler happy */ + /*tex + The current character code position, initialized to make the compiler + happy: + */ + pool_pointer j = 0; pdfstructure *p = pdf->pstruct; if (s >= STRING_OFFSET) { - /* needed for |out_save| */ + /*tex Needed for |out_save|: */ j = 0; - /* unfortunately we always go through this when we have vf specials (and also via temp strings) */ + /*tex + Unfortunately we always go through this when we have vf specials (and + also via temp strings): + */ if (literal_mode == scan_special) { if (!(str_in_cstr(s, "pdf:", 0) || str_in_cstr(s, "PDF:", 0))) { if (warn && ((!(str_in_cstr(s, "src:", 0) || str_in_cstr(s, "SRC:", 0))) || (str_length(s) == 0))) tprint_nl("Non-PDF special ignored!"); return; } - j = j + (pool_pointer) 4; /* strlen("PDF:") */ - if (str_in_cstr(s, "direct:", 4)) { /* strlen("PDF:") */ - j = j + (pool_pointer) 7; /* strlen("direct:") */ + /*tex |strlen("PDF:")| */ + j = j + (pool_pointer) 4; + if (str_in_cstr(s, "direct:", 4)) { + /*tex |strlen("direct:")| */ + j = j + (pool_pointer) 7; literal_mode = direct_always; - } else if (str_in_cstr(s, "page:", 4)) { /* strlen("PDF:") */ - j = j + (pool_pointer) 5; /* strlen("page:") */ + } else if (str_in_cstr(s, "page:", 4)) { + /*tex |strlen("page:")| */ + j = j + (pool_pointer) 5; literal_mode = direct_page; - } else if (str_in_cstr(s, "text:", 4)) { /* strlen("PDF:") */ - j = j + (pool_pointer) 5; /* strlen("text:") */ + } else if (str_in_cstr(s, "text:", 4)) { + /*tex |strlen("text:")| */ + j = j + (pool_pointer) 5; literal_mode = direct_text; - } else if (str_in_cstr(s, "raw:", 4)) { /* strlen("PDF:") */ - j = j + (pool_pointer) 4; /* strlen("raw:") */ + } else if (str_in_cstr(s, "raw:", 4)) { + /*tex |strlen("raw:")| */ + j = j + (pool_pointer) 4; literal_mode = direct_raw; - } else if (str_in_cstr(s, "origin:", 4)) { /* strlen("PDF:") */ - j = j + (pool_pointer) 7; /* strlen("origin:") */ + } else if (str_in_cstr(s, "origin:", 4)) { + /*tex |strlen("origin:")| */ + j = j + (pool_pointer) 7; literal_mode = set_origin; } else { literal_mode = set_origin; @@ -147,7 +162,7 @@ void pdf_literal(PDF pdf, str_number s, int literal_mode, boolean warn) break; case direct_text: pdf_goto_fontmode(pdf); -// pdf_goto_textmode(pdf); + /*tex not: |pdf_goto_textmode(pdf);| */ break; case direct_always: pdf_end_string_nl(pdf); diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfobj.w b/Build/source/texk/web2c/luatexdir/pdf/pdfobj.c index e5ca09de624..71d6a943f57 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfobj.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfobj.c @@ -1,44 +1,48 @@ -% pdfobj.w -% -% Copyright 2009-2011 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 +/* + +Copyright 2009-2011 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/>. + +*/ + #include "ptexlib.h" #include "lua/luatex-api.h" -@ write a raw PDF object +/*tex Write a raw \PDF\ object: */ -@c void pdf_write_obj(PDF pdf, int k) { lstring data; const_lstring st; - size_t li; /* index into |data.s| */ + /*tex The index into |data.s|: */ + size_t li; int saved_compress_level ; - int os_threshold = OBJSTM_ALWAYS; /* gives compressed objects for \.{\\pdfvariable objcompresslevel} >= |OBJSTM_ALWAYS| */ - int l = 0; /* possibly a lua registry reference */ + /*tex Gives compressed objects for |\pdfvariable objcompresslevel| >= |OBJSTM_ALWAYS|: */ + int os_threshold = OBJSTM_ALWAYS; + /*tex Possibly a \LUA\ registry reference: */ + int l = 0; int ll = 0; data.s = NULL; - /* we can have an immediate object before we are initialized */ + /*tex We can have an immediate object before we are initialized. */ ensure_output_state(pdf, ST_HEADER_WRITTEN); saved_compress_level = pdf->compress_level; - /* end of ugly hack */ - if (obj_obj_pdfcompresslevel(pdf, k) > -1) { /* -1 = "unset" */ + /*tex End of a ugly hack. */ + if (obj_obj_pdfcompresslevel(pdf, k) > -1) { + /*tex A value of |-1| means ``unset''. */ pdf->compress_level = obj_obj_pdfcompresslevel(pdf, k); if (pdf->compress_level == 0) { pdf->objcompresslevel = 0; @@ -56,9 +60,10 @@ void pdf_write_obj(PDF pdf, int k) normal_error("pdf backend","invalid object"); st.s = lua_tolstring(Luas, -1, &li); st.l = li; + lua_pop(Luas,1); + pdf_check_space(pdf); pdf_out_block(pdf, st.s, st.l); - if (st.s[st.l - 1] != '\n') - pdf_out(pdf, '\n'); + pdf_set_space(pdf); luaL_unref(Luas, LUA_REGISTRYINDEX, l); obj_obj_stream_attr(pdf, k) = LUA_NOREF; } @@ -75,10 +80,12 @@ void pdf_write_obj(PDF pdf, int k) st.l = li; lua_pop(Luas, 1); if (obj_obj_is_file(pdf, k)) { - boolean res = false; /* callback status value */ - const char *fnam = NULL; /* callback found filename */ + /*tex The callback status value: */ + boolean res = false; + /*tex The callback found filename: */ + const char *fnam = NULL; int callback_id; - /* st.s is also |\0|-terminated, even as lstring */ + /*tex |st.s| is also |\0|-terminated, even as |lstring| */ fnam = luatex_find_file(st.s, find_data_file_callback); callback_id = callback_defined(read_data_file_callback); if (fnam && callback_id > 0) { @@ -88,7 +95,8 @@ void pdf_write_obj(PDF pdf, int k) if (!file_opened) normal_error("pdf backend", "cannot open file for embedding"); } else { - byte_file f; /* the data file's FILE* */ + /*tex The data file's |FILE*|: */ + byte_file f; if (!fnam) fnam = st.s; if (!luatex_open_input(&f, fnam, kpse_tex_format, FOPEN_RBIN_MODE, true)) @@ -112,32 +120,37 @@ void pdf_write_obj(PDF pdf, int k) if (obj_obj_is_stream(pdf, k)) { pdf_end_stream(pdf); pdf_end_obj(pdf); - } else /* here we do the \n */ + } else { + /*tex Here we do the |\n|. */ pdf_end_obj(pdf); + } luaL_unref(Luas, LUA_REGISTRYINDEX, l); obj_obj_data(pdf, k) = LUA_NOREF; pdf->compress_level = saved_compress_level; } -@ @c void init_obj_obj(PDF pdf, int k) { obj_obj_stream_attr(pdf, k) = LUA_NOREF; obj_obj_data(pdf, k) = LUA_NOREF; unset_obj_obj_is_stream(pdf, k); unset_obj_obj_is_file(pdf, k); + unset_obj_obj_no_length(pdf, k); obj_obj_pdfcompresslevel(pdf, k) = -1; /* unset */ obj_obj_objstm_threshold(pdf, k) = OBJSTM_UNSET; /* unset */ } -@ The \.{\\pdfextension obj} primitive is used to create a ``raw'' object in the -PDF output file. The object contents will be hold in memory and will be written -out only when the object is referenced by \.{\\pdfextension refobj}. When -\.{\\pdfextension obj} is used with \.{\\immediate}, the object contents will be -written out immediately. Objects referenced in the current page are appended into -|pdf_obj_list|. +/*tex + + The |\pdfextension obj| primitive is used to create a ``raw'' object in + the PDF output file. The object contents will be hold in memory and will be + written out only when the object is referenced by |\pdfextension refobj|. + When |\pdfextension obj| is used with |\immediate|, the object contents + will be written out immediately. Objects referenced in the current page are + appended into |pdf_obj_list|. + +*/ -@c void scan_obj(PDF pdf) { int k; @@ -154,7 +167,7 @@ void scan_obj(PDF pdf) k = cur_val; check_obj_type(pdf, obj_type_obj, k); if (is_obj_scheduled(pdf, k) || obj_data_ptr(pdf, k) != 0) - luaL_error(Luas, "object in use"); + normal_error("pdf backend", "scheduled object is already used"); } else { pdf->obj_count++; k = pdf_create_obj(pdf, obj_type_obj, 0); @@ -190,7 +203,6 @@ void scan_obj(PDF pdf) pdf_last_obj = k; } -@ @c void scan_refobj(PDF pdf) { scan_int(); @@ -206,14 +218,12 @@ void scan_refobj_lua(PDF pdf, int k) pdf_obj_objnum(tail_par) = k; } -@ @c void pdf_ref_obj(PDF pdf, halfword p) { if (!is_obj_scheduled(pdf, pdf_obj_objnum(p))) addto_page_resources(pdf, obj_type_obj, pdf_obj_objnum(p)); } -@ @c void pdf_ref_obj_lua(PDF pdf, int k) { if (!is_obj_scheduled(pdf, k)) diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfoutline.w b/Build/source/texk/web2c/luatexdir/pdf/pdfoutline.c index 6c0a30a88d9..ae17e29dac3 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfoutline.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfoutline.c @@ -1,36 +1,46 @@ -% pdfoutline.w -% -% Copyright 2009-2011 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 +/* + +Copyright 2009-2011 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/>. + +*/ #include "ptexlib.h" -@ Data structure of outlines; it's not able to write out outline entries before -all outline entries are defined, so memory allocated for outline entries can't -not be deallocated and will stay in memory. For this reason we will store data of -outline entries in |pdf->mem| instead of |mem| +/*tex + + Data structure of outlines; it's not able to write out outline entries before + all outline entries are defined, so memory allocated for outline entries + can't not be deallocated and will stay in memory. For this reason we will + store data of outline entries in |pdf->mem| instead of |mem|. + +*/ -@c -#define pdfmem_outline_size 8 /* size of memory in |pdf->mem| which |obj_outline_ptr| points to */ +/*tex The size of memory in |pdf->mem| which |obj_outline_ptr| points to: */ -#define obj_outline_count obj_info /* count of all opened children */ -#define obj_outline_ptr obj_aux /* pointer to |pdf->mem| */ +#define pdfmem_outline_size 8 + +/*tex The count of all opened children: */ + +#define obj_outline_count obj_info + +/*tex The pointer to |pdf->mem|: */ + +#define obj_outline_ptr obj_aux #define obj_outline_title(pdf,A) pdf->mem[obj_outline_ptr(pdf,A)] #define obj_outline_parent(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 1] @@ -38,7 +48,7 @@ outline entries in |pdf->mem| instead of |mem| #define obj_outline_next(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 3] #define obj_outline_first(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 4] #define obj_outline_last(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 5] -#define obj_outline_action_objnum(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 6] /* object number of action */ +#define obj_outline_action_objnum(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 6] #define obj_outline_attr(pdf,A) pdf->mem[obj_outline_ptr(pdf,A) + 7] #define set_obj_outline_count(pdf,A,B) obj_outline_count(pdf,A)=B @@ -52,7 +62,6 @@ outline entries in |pdf->mem| instead of |mem| #define set_obj_outline_parent(pdf,A,B) obj_outline_parent(pdf,A)=B #define set_obj_outline_attr(pdf,A,B) obj_outline_attr(pdf,A)=B -@ @c static int open_subentries(PDF pdf, halfword p) { int c, l, r; @@ -78,9 +87,8 @@ static int open_subentries(PDF pdf, halfword p) return k; } -@ return number of outline entries in the same level with |p| +/*tex Return the number of outline entries in the same level with |p|: */ -@c static int outline_list_count(PDF pdf, pointer p) { int k = 1; @@ -91,7 +99,6 @@ static int outline_list_count(PDF pdf, pointer p) return k; } -@ @c void scan_pdfoutline(PDF pdf) { halfword q, r; @@ -178,10 +185,13 @@ void scan_pdfoutline(PDF pdf) } } -@ In the end we must flush PDF objects that cannot be written out immediately -after shipping out pages. +/*tex + + In the end we must flush \PDF\F objects that cannot be written out + immediately after shipping out pages. + +*/ -@c int print_outlines(PDF pdf) { int k, l, a; @@ -206,8 +216,7 @@ int print_outlines(PDF pdf) pdf_dict_add_int(pdf, "Count", k); pdf_end_dict(pdf); pdf_end_obj(pdf); - /* Output PDF outline entries */ - + /*tex Output \PDF\ outline entries. */ k = pdf->head_tab[obj_type_outline]; while (k != 0) { if (obj_outline_parent(pdf, k) == pdf->parent_outline) { @@ -243,7 +252,6 @@ int print_outlines(PDF pdf) pdf_end_obj(pdf); k = obj_link(pdf, k); } - } else { outlines = 0; } diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfpage.w b/Build/source/texk/web2c/luatexdir/pdf/pdfpage.c index ecc51ddfd63..211248a02d3 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfpage.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfpage.c @@ -1,23 +1,23 @@ -% pdfpage.w -% -% Copyright 2006-2012 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 +Copyright 2006-2012 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/>. + +*/ #include "ptexlib.h" @@ -26,7 +26,6 @@ #include <assert.h> #include <math.h> -@ @c void init_pdf_pagecalculations(PDF pdf) { pdfstructure *p; @@ -37,23 +36,30 @@ void init_pdf_pagecalculations(PDF pdf) setpdffloat(p->pdf.h, 0, decimal_digits); setpdffloat(p->pdf.v, 0, decimal_digits); p->cw.e = 1; - p->fs_cur.e = p->fs.e = (decimal_digits < 4 ? 5 : 6); /* "+ 2" makes less corrections inside []TJ */ - /* for placement outside BT...ET */ + /*tex |+ 2| makes less corrections inside []TJ */ + p->fs_cur.e = p->fs.e = (decimal_digits < 4 ? 5 : 6); + /*tex for placement outside BT...ET */ setpdffloat(p->cm[0], 1, 0); setpdffloat(p->cm[1], 0, 0); setpdffloat(p->cm[2], 0, 0); setpdffloat(p->cm[3], 1, 0); - setpdffloat(p->cm[4], 0, decimal_digits); /* horizontal movement on page */ - setpdffloat(p->cm[5], 0, decimal_digits); /* vertical movement on page */ - /* for placement inside BT...ET */ - setpdffloat(p->tm0_cur, 0, 6); /* mantissa holds HZ expand * ExtendFont */ - setpdffloat(p->tm[0], ten_pow[6], 6); /* mantissa holds HZ expand * ExtendFont */ + /*tex horizontal movement on page */ + setpdffloat(p->cm[4], 0, decimal_digits); + /*tex vertical movement on page */ + setpdffloat(p->cm[5], 0, decimal_digits); + /*tex for placement inside BT...ET */ + /*tex mantissa holds HZ expand * ExtendFont */ + setpdffloat(p->tm0_cur, 0, 6); + /*tex mantissa holds HZ expand * ExtendFont */ + setpdffloat(p->tm[0], ten_pow[6], 6); setpdffloat(p->tm[1], 0, 0); - setpdffloat(p->tm[2], 0, 3); /* mantissa holds SlantFont, 0 = default */ + /*tex mantissa holds SlantFont, 0 = default */ + setpdffloat(p->tm[2], 0, 3); setpdffloat(p->tm[3], ten_pow[6], 6); - setpdffloat(p->tm[4], 0, decimal_digits); /* mantissa holds delta from |pdf_bt_pos.h| */ - setpdffloat(p->tm[5], 0, decimal_digits); /* mantissa holds delta from |pdf_bt_pos.v| */ - /* */ + /*tex mantissa holds delta from |pdf_bt_pos.h| */ + setpdffloat(p->tm[4], 0, decimal_digits); + /*tex mantissa holds delta from |pdf_bt_pos.v| */ + setpdffloat(p->tm[5], 0, decimal_digits); p->f_pdf_cur = p->f_pdf = null_font; p->fs_cur.m = p->fs.m = 0; p->wmode = WMODE_H; @@ -61,10 +67,11 @@ void init_pdf_pagecalculations(PDF pdf) p->ishex = 0; p->need_tf = false; p->need_tm = false; + p->done_width = false; + p->done_mode = false; p->k1 = ten_pow[p->pdf.h.e] / by_one_bp; } -@ @c void synch_pos_with_cur(posstructure * pos, posstructure * refpos, scaledpos cur) { switch (pos->dir) { @@ -93,7 +100,6 @@ void synch_pos_with_cur(posstructure * pos, posstructure * refpos, scaledpos cur } } -@ @c boolean calc_pdfpos(pdfstructure * p, scaledpos pos) { scaledpos new; @@ -102,7 +108,8 @@ boolean calc_pdfpos(pdfstructure * p, scaledpos pos) case PMODE_PAGE: new.h = i64round(pos.h * p->k1); new.v = i64round(pos.v * p->k1); - p->cm[4].m = new.h - p->pdf.h.m; /* cm is concatenated */ + /*tex cm is concatenated */ + p->cm[4].m = new.h - p->pdf.h.m; p->cm[5].m = new.v - p->pdf.v.m; if (new.h != p->pdf.h.m || new.v != p->pdf.v.m) move_pdfpos = true; @@ -110,7 +117,8 @@ boolean calc_pdfpos(pdfstructure * p, scaledpos pos) case PMODE_TEXT: new.h = i64round(pos.h * p->k1); new.v = i64round(pos.v * p->k1); - p->tm[4].m = new.h - p->pdf_bt_pos.h.m; /* Tm replaces */ + /*tex Tm replaces */ + p->tm[4].m = new.h - p->pdf_bt_pos.h.m; p->tm[5].m = new.v - p->pdf_bt_pos.v.m; if (new.h != p->pdf.h.m || new.v != p->pdf.v.m) move_pdfpos = true; @@ -122,14 +130,16 @@ boolean calc_pdfpos(pdfstructure * p, scaledpos pos) new.h = i64round((pos.h * p->k1 - (double) p->pdf_tj_pos.h.m) * p->k2); new.v = i64round(pos.v * p->k1); p->tj_delta.m = -i64round((double) ((new.h - p->cw.m) / ten_pow[p->cw.e - p->tj_delta.e])); - p->tm[5].m = new.v - p->pdf_bt_pos.v.m; /* p->tm[4] is meaningless */ + /*tex p->tm[4] is meaningless */ + p->tm[5].m = new.v - p->pdf_bt_pos.v.m; if (p->tj_delta.m != 0 || new.v != p->pdf.v.m) move_pdfpos = true; break; case WMODE_V: new.h = i64round(pos.h * p->k1); new.v = i64round(((double) p->pdf_tj_pos.v.m - pos.v * p->k1) * p->k2); - p->tm[4].m = new.h - p->pdf_bt_pos.h.m; /* p->tm[5] is meaningless */ + /*tex p->tm[5] is meaningless */ + p->tm[4].m = new.h - p->pdf_bt_pos.h.m; p->tj_delta.m = -i64round((double) ((new.v - p->cw.m) / ten_pow[p->cw.e - p->tj_delta.e])); if (p->tj_delta.m != 0 || new.h != p->pdf.h.m) move_pdfpos = true; @@ -145,7 +155,6 @@ boolean calc_pdfpos(pdfstructure * p, scaledpos pos) return move_pdfpos; } -@ @c void print_pdf_matrix(PDF pdf, pdffloat * tm) { int i; @@ -156,14 +165,12 @@ void print_pdf_matrix(PDF pdf, pdffloat * tm) print_pdffloat(pdf, tm[i]); } -@ @c void pdf_print_cm(PDF pdf, pdffloat * cm) { print_pdf_matrix(pdf, cm); pdf_puts(pdf, " cm\n"); } -@ @c void pdf_set_pos(PDF pdf, scaledpos pos) { boolean move; @@ -178,7 +185,6 @@ void pdf_set_pos(PDF pdf, scaledpos pos) } } -@ @c void pdf_set_pos_temp(PDF pdf, scaledpos pos) { boolean move; @@ -191,7 +197,6 @@ void pdf_set_pos_temp(PDF pdf, scaledpos pos) } } -@ @c static void begin_text(PDF pdf) { pdfstructure *p = pdf->pstruct; @@ -201,6 +206,8 @@ static void begin_text(PDF pdf) pdf_puts(pdf, "BT\n"); p->mode = PMODE_TEXT; p->need_tf = true; + p->need_width = 0; + p->need_mode = 0; } static void end_text(PDF pdf) @@ -208,6 +215,16 @@ static void end_text(PDF pdf) pdfstructure *p = pdf->pstruct; if (!is_textmode(p)) normal_error("pdf backend","text mode expected in end_text"); + + if (p->done_width != 0) { + pdf_puts(pdf, "0 w\n"); + p->done_width = 0; + } + if (p->done_mode != 0) { + pdf_puts(pdf, "0 Tr\n"); + p->done_mode = 0; + } + pdf_puts(pdf, "ET\n"); p->pdf = p->pdf_bt_pos; p->mode = PMODE_PAGE; @@ -222,7 +239,6 @@ void pdf_end_string_nl(PDF pdf) end_chararray(pdf); } -@ @c void pdf_goto_pagemode(PDF pdf) { pdfstructure *p = pdf->pstruct; @@ -245,7 +261,7 @@ void pdf_goto_textmode(PDF pdf) 0, 0 }; if (is_pagemode(p)) { - /* reset to page origin */ + /*tex Reset to the page origin: */ pdf_set_pos(pdf, origin); begin_text(pdf); } else if (!is_textmode(p)) { diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfpagetree.w b/Build/source/texk/web2c/luatexdir/pdf/pdfpagetree.c index 76d008c4359..4fcd48e341f 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfpagetree.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfpagetree.c @@ -1,38 +1,39 @@ -% pdfpagetree.w -% -% Copyright 2006-2011 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 +/* -#include "ptexlib.h" +Copyright 2006-2011 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. -@* Page diversions. +You should have received a copy of the GNU General Public License along +with LuaTeX; if not, see <http://www.gnu.org/licenses/>. -@ @c -# define PAGES_TREE_KIDSMAX 10 +*/ + +#include "ptexlib.h" + +#define PAGES_TREE_KIDSMAX 10 static struct avl_table *divert_list_tree = NULL; typedef struct pages_entry_ { - int objnum; /* object number of this /Pages object */ - int number_of_pages; /* total number of all pages below */ - int number_of_kids; /* number of direct kid objects */ - int kids[PAGES_TREE_KIDSMAX]; /* array of kid object numbers */ + /*tex The object number of this |/Pages| object. */ + int objnum; + /*tex The total number of all pages below. */ + int number_of_pages; + /*tex The number of direct kid objects. */ + int number_of_kids; + /*tex The array of kid object numbers. */ + int kids[PAGES_TREE_KIDSMAX]; struct pages_entry_ *next; } pages_entry; @@ -52,7 +53,6 @@ static int comp_divert_list_entry(const void *pa, const void *pb, void *p) return 0; } -@ @c static pages_entry *new_pages_entry(PDF pdf) { int i; @@ -65,7 +65,6 @@ static pages_entry *new_pages_entry(PDF pdf) return p; } -@ @c static divert_list_entry *new_divert_list_entry(void) { divert_list_entry *d; @@ -74,7 +73,6 @@ static divert_list_entry *new_divert_list_entry(void) return d; } -@ @c static void ensure_list_tree(void) { if (divert_list_tree == NULL) { @@ -82,7 +80,6 @@ static void ensure_list_tree(void) } } -@ @c static divert_list_entry *get_divert_list(int divnum) { divert_list_entry *d, tmp; @@ -92,7 +89,7 @@ static divert_list_entry *get_divert_list(int divnum) if (d == NULL) { d = new_divert_list_entry(); d->divnum = divnum; - /* the next bit of code can actually be removed */ + /*tex The next bit of code can actually be removed. */ aa = avl_probe(divert_list_tree, d); if (aa==NULL) { normal_error("pdf backend","page list lookup error"); @@ -101,18 +98,18 @@ static divert_list_entry *get_divert_list(int divnum) return d; } -@ |pdf_do_page_divert()| returns the current /Parent object number -@c +/*tex |pdf_do_page_divert| returns the current |/Parent| object number. */ + int pdf_do_page_divert(PDF pdf, int objnum, int divnum) { divert_list_entry *d; pages_entry *p; - /* initialize the tree */ + /*tex Initialize the tree. */ ensure_list_tree(); - /* make sure we have a list for this diversion */ + /*tex Make sure we have a list for this diversion. */ d = get_divert_list(divnum); if (d->first == NULL || d->last->number_of_kids == PAGES_TREE_KIDSMAX) { - /* append a new |pages_entry| */ + /*tex Append a new |pages_entry|. */ p = new_pages_entry(pdf); if (d->first == NULL) d->first = p; @@ -126,33 +123,32 @@ int pdf_do_page_divert(PDF pdf, int objnum, int divnum) return p->objnum; } -@ @c static void movelist(divert_list_entry * d, divert_list_entry * dto) { if (d != NULL && d->first != NULL && d->divnum != dto->divnum) { - /* no undivert of empty list or into self */ + /*tex No undivert of empty list or into self. */ if (dto->first == NULL) dto->first = d->first; else dto->last->next = d->first; dto->last = d->last; - /* one could as well remove this |divert_list_entry| */ + /*tex One could as well remove this |divert_list_entry|. */ d->first = d->last = NULL; } } -@ undivert from diversion |divnum| into diversion |curdivnum| -@c +/*tex Undivert from diversion |divnum| into diversion |curdivnum|. */ + void pdf_do_page_undivert(int divnum, int curdivnum) { divert_list_entry *d, *dto, tmp; struct avl_traverser t; - /* initialize the tree */ + /*tex Initialize the tree. */ ensure_list_tree(); - /* find the diversion |curdivnum| list where diversion |divnum| should go */ + /*tex Find the diversion |curdivnum| list where diversion |divnum| should go. */ dto = get_divert_list(curdivnum); if (divnum == 0) { - /* 0 = special case: undivert {\it all\/} lists */ + /*tex Zero is a special case: undivert {\em all} lists. */ avl_t_init(&t, divert_list_tree); for (d = avl_t_first(&t, divert_list_tree); d != NULL; d = avl_t_next(&t)) @@ -164,10 +160,9 @@ void pdf_do_page_undivert(int divnum, int curdivnum) } } -@ write a /Pages object -@c +/*tex Write a |/Pages| object. */ -static void write_pages(PDF pdf, pages_entry * p, int parent) +static void write_pages(PDF pdf, pages_entry * p, int parent, int callback_id) { int i; int pages_attributes ; @@ -175,39 +170,57 @@ static void write_pages(PDF pdf, pages_entry * p, int parent) pdf_begin_dict(pdf); pdf_dict_add_name(pdf, "Type", "Pages"); if (parent == 0) { - /* it's root */ - pages_attributes = pdf_pages_attr; /* lookup once */ + /*tex It's root. Lookup the attributes once. */ + pages_attributes = pdf_pages_attr; if (pages_attributes != null) { pdf_print_toks(pdf, pages_attributes); pdf_out(pdf, ' '); } print_pdf_table_string(pdf, "pagesattributes"); pdf_out(pdf, ' '); - } else + } else { pdf_dict_add_ref(pdf, "Parent", parent); + } pdf_dict_add_int(pdf, "Count", (int) p->number_of_pages); pdf_add_name(pdf, "Kids"); pdf_begin_array(pdf); - for (i = 0; i < p->number_of_kids; i++) - pdf_add_ref(pdf, (int) p->kids[i]); + for (i = 0; i < p->number_of_kids; i++) { + if (callback_id) { + /* new */ + int objnum = (int) p->kids[i]; + if (obj_type(pdf, objnum) == obj_type_page) { + run_callback(callback_id, "d->d", objnum, &objnum); + check_obj_exists(pdf, objnum); + pdf_add_ref(pdf, (int) objnum); + } else { + pdf_add_ref(pdf, (int) p->kids[i]); + } + } else { + pdf_add_ref(pdf, (int) p->kids[i]); + } + } pdf_end_array(pdf); pdf_end_dict(pdf); pdf_end_obj(pdf); } -@ loop over all /Pages objects, output them, create their parents, -recursing bottom up, return the /Pages root object number +/*tex + + Loop over all |/Pages| objects, output them, create their parents, recursing + bottom up, return the |/Pages| root object number. + +*/ -@c -static int output_pages_list(PDF pdf, pages_entry * pe) +static int output_pages_list(PDF pdf, pages_entry * pe, int callback_id) { pages_entry *p, *q, *r; if (pe->next == NULL) { - /* everything fits into one |pages_entry| */ - write_pages(pdf, pe, 0); /* /Pages root found */ + /*tex Everything fits into one |pages_entry|. */ + write_pages(pdf, pe, 0, callback_id); return pe->objnum; } - q = r = new_pages_entry(pdf); /* one level higher needed */ + /*tex One level higher needed. */ + q = r = new_pages_entry(pdf); for (p = pe; p != NULL; p = p->next) { if (q->number_of_kids == PAGES_TREE_KIDSMAX) { q->next = new_pages_entry(pdf); @@ -215,16 +228,19 @@ static int output_pages_list(PDF pdf, pages_entry * pe) } q->kids[q->number_of_kids++] = p->objnum; q->number_of_pages += p->number_of_pages; - write_pages(pdf, p, q->objnum); + write_pages(pdf, p, q->objnum, callback_id); } - return output_pages_list(pdf, r); /* recurse through next higher level */ + /*tex Recurse through next higher level. */ + return output_pages_list(pdf, r, callback_id); } -@ @c int output_pages_tree(PDF pdf) { + int callback_id = callback_defined(page_objnum_provider_callback); divert_list_entry *d; - pdf_do_page_undivert(0, 0); /* concatenate all diversions into diversion 0 */ - d = get_divert_list(0); /* get diversion 0 */ - return output_pages_list(pdf, d->first); + /*tex Concatenate all diversions into diversion 0. */ + pdf_do_page_undivert(0, 0); + /*tex Get diversion 0. */ + d = get_divert_list(0); + return output_pages_list(pdf, d->first, callback_id); } diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfrule.w b/Build/source/texk/web2c/luatexdir/pdf/pdfrule.c index df4979088c8..de689a1471f 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfrule.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfrule.c @@ -1,29 +1,26 @@ -% pdfrule.w -% -% Copyright 2010-2011 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 -#include "ptexlib.h" -#include "pdf/pdfpage.h" +Copyright 2010-2011 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. -@ @c +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. -/* maybe we should have an extra callback on normal rules or on any rule in 2.0+ */ +You should have received a copy of the GNU General Public License along +with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +*/ + +#include "ptexlib.h" +#include "pdf/pdfpage.h" void pdf_place_rule(PDF pdf, halfword q, scaledpos size, int callback_id) { @@ -31,7 +28,6 @@ void pdf_place_rule(PDF pdf, halfword q, scaledpos size, int callback_id) pdfstructure *p = pdf->pstruct; scaledpos pos = pdf->posstruct->pos; halfword s = subtype(q); - /* (void) q; */ if (s >= math_over_rule && s <= math_radical_rule) { if (callback_id == 0) { s = normal_rule; @@ -44,7 +40,7 @@ void pdf_place_rule(PDF pdf, halfword q, scaledpos size, int callback_id) } else if (s == image_rule) { pdf_place_image(pdf,q); } else if (s == empty_rule) { - /* place nothing, only take space */ + /*tex Place nothing, only take space. */ } else if (s == user_rule) { if (callback_id != 0) { pdf_goto_pagemode(pdf); @@ -54,7 +50,7 @@ void pdf_place_rule(PDF pdf, halfword q, scaledpos size, int callback_id) pdf_puts(pdf, "\nQ\n"); } } else { - /* normal_rule or >= 100 being a leader rule */ + /*tex |normal_rule| or >= 100 being a leader rule */ pdf_goto_pagemode(pdf); dim.h.m = i64round(size.h * p->k1); dim.h.e = p->pdf.h.e; @@ -64,7 +60,7 @@ void pdf_place_rule(PDF pdf, halfword q, scaledpos size, int callback_id) if (size.v <= one_bp) { pos.v += i64round(0.5 * size.v); pdf_set_pos_temp(pdf, pos); - pdf_puts(pdf, "[]0 d 0 J "); + pdf_puts(pdf, "[] 0 d 0 J "); print_pdffloat(pdf, dim.v); pdf_puts(pdf, " w 0 0 m "); print_pdffloat(pdf, dim.h); @@ -72,18 +68,32 @@ void pdf_place_rule(PDF pdf, halfword q, scaledpos size, int callback_id) } else if (size.h <= one_bp) { pos.h += i64round(0.5 * size.h); pdf_set_pos_temp(pdf, pos); - pdf_puts(pdf, "[]0 d 0 J "); + pdf_puts(pdf, "[] 0 d 0 J "); print_pdffloat(pdf, dim.h); pdf_puts(pdf, " w 0 0 m 0 "); print_pdffloat(pdf, dim.v); pdf_puts(pdf, " l S\n"); } else { pdf_set_pos_temp(pdf, pos); + if (s == outline_rule) { + pdf_puts(pdf, "[] 0 d 0 J "); + if (rule_transform(q) > 0) { + pdfpos temp ; + temp.h.m = i64round(rule_transform(q) * p->k1); + temp.h.e = p->pdf.h.e; + print_pdffloat(pdf, temp.h); + pdf_puts(pdf, " w "); + } + } pdf_puts(pdf, "0 0 "); print_pdffloat(pdf, dim.h); pdf_out(pdf, ' '); print_pdffloat(pdf, dim.v); - pdf_puts(pdf, " re f\n"); + if (s == outline_rule) { + pdf_puts(pdf, " re S\n"); + } else { + pdf_puts(pdf, " re f\n"); + } } pdf_puts(pdf, "Q\n"); } diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfsaverestore.w b/Build/source/texk/web2c/luatexdir/pdf/pdfsaverestore.c index 0d91de54496..abfb4814201 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfsaverestore.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfsaverestore.c @@ -1,32 +1,30 @@ -% pdfsaverestore.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 +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/>. + +*/ #include "ptexlib.h" -@ @c -pos_entry *pos_stack = 0; /* the stack */ -int pos_stack_size = 0; /* initially empty */ -int pos_stack_used = 0; /* used entries */ +pos_entry *pos_stack = 0; +int pos_stack_size = 0; +int pos_stack_used = 0; -@ @c static void checkpdfsave(scaledpos pos) { pos_entry *new_stack; @@ -45,7 +43,6 @@ static void checkpdfsave(scaledpos pos) pos_stack_used++; } -@ @c static void checkpdfrestore(scaledpos pos) { scaledpos diff; @@ -64,7 +61,6 @@ static void checkpdfrestore(scaledpos pos) } } -@ @c void pdf_out_save(PDF pdf, halfword p) { (void) p; @@ -72,7 +68,6 @@ void pdf_out_save(PDF pdf, halfword p) pdf_literal(pdf, 'q', set_origin, false); } -@ @c void pdf_out_restore(PDF pdf, halfword p) { (void) p; diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfsetmatrix.w b/Build/source/texk/web2c/luatexdir/pdf/pdfsetmatrix.c index b107033b984..f19c1721d5d 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfsetmatrix.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfsetmatrix.c @@ -1,34 +1,36 @@ -% pdfsetmatrix.w -% -% Copyright 2009 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 +/* + +Copyright 2009 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/>. + +*/ #include "ptexlib.h" -@ stack for \.{\\pdfextension setmatrix} +/*tex + + We keep a stack for |pdfextension setmatrix|: + +*/ -@c matrix_entry *matrix_stack = NULL; int matrix_stack_size = 0; int matrix_stack_used = 0; -@ @c boolean matrixused(void) { return matrix_stack_used > 0; @@ -46,40 +48,40 @@ static void matrix_stack_room(void) } } -@ \.{\\pdfextension setmatrix{a b c d}} - -|e| := pos.h +/*tex -|f| := pos.v + The matrix specification has four entries and gets translated to |e| being + |pos.h and |f| being pos.v. The current active matrix at the top of the + matrix stack is kept in |M_top|. -|M_top|: current active matrix at the top of the matrix stack + The origin of \.{\\pdfextension setmatrix} is the current point. The + annotation coordinate system is the original page coordinate system. When + pdfTeX calculates annotation rectangles it does not take into account this + transformations, it uses the original coordinate system. To get the corrected + values, first we go back to the origin, perform the transformation and go + back: -The origin of \.{\\pdfextension setmatrix} is the current point. The annotation -coordinate system is the original page coordinate system. When pdfTeX calculates -annotation rectangles it does not take into account this transformations, it uses -the original coordinate system. To get the corrected values, first we go back to -the origin, perform the transformation and go back: + \starttyping + ( 1 0 0 ) ( a b 0 ) ( 1 0 0 ) + ( 0 1 0 ) x ( c d 0 ) x ( 0 1 0 ) x M\_top + ( -e -f 1 ) ( 0 0 1 ) ( e f 1 ) -{\obeylines\obeyspaces\tt - ( 1 0 0 ) ( a b 0 ) ( 1 0 0 ) - ( 0 1 0 ) x ( c d 0 ) x ( 0 1 0 ) x M\_top - ( -e -f 1 ) ( 0 0 1 ) ( e f 1 ) + ( 1 0 0 ) ( a b 0 ) + = ( 0 1 0 ) x ( c d 0 ) x M\_top + ( e f 1 ) ( -e -f 1 ) - ( 1 0 0 ) ( a b 0 ) - = ( 0 1 0 ) x ( c d 0 ) x M\_top - ( e f 1 ) ( -e -f 1 ) + ( a b 0 ) + = ( c d 0 ) x M\_top + ( e(1-a)-fc f(1-d)-eb 1 ) + \stoptyping - ( a b 0 ) - = ( c d 0 ) x M\_top - ( e(1-a)-fc f(1-d)-eb 1 ) -} +*/ -@c static void pdfsetmatrix(const char *in, scaledpos pos) { - /* - Argument of \.{\\pdfextension setmatrix} starts with |str_pool[in]| and ends - before |str_pool[pool_ptr]|. + /*tex + The argument of |pdfextension setmatrix| starts with |str_pool[in]| + and ends before |str_pool[pool_ptr]|. */ matrix_entry x, *y, *z; if (global_shipping_mode == SHIPPING_PAGE) { @@ -87,7 +89,7 @@ static void pdfsetmatrix(const char *in, scaledpos pos) formatted_warning("pdf backend","unrecognized format of setmatrix: %s", in); return; } - /* calculate this transformation matrix */ + /*tex Calculate this transformation matrix. */ x.e = (double) pos.h * (1.0 - x.a) - (double) pos.v * x.c; x.f = (double) pos.v * (1.0 - x.d) - (double) pos.h * x.b; matrix_stack_room(); @@ -112,19 +114,21 @@ static void pdfsetmatrix(const char *in, scaledpos pos) } } -@ Apply matrix to point (x,y) +/*tex -{\obeylines\obeyspaces\tt - ( a b 0 ) - ( x y 1 ) x ( c d 0 ) = ( xa+yc+e xb+yd+f 1 ) - ( e f 1 ) -} + Apply matrix to point (x,y) + + \starttyping + ( a b 0 ) + ( x y 1 ) x ( c d 0 ) = ( xa+yc+e xb+yd+f 1 ) + ( e f 1 ) + \stoptyping -If \.{\\pdfextension setmatrix} wasn't used, then return the value unchanged. + If \.{\\pdfextension setmatrix} wasn't used, then return the value unchanged. + The return values for matrix tranform functions are: -@ Return values for matrix tranform functions: +*/ -@c static scaled ret_llx; static scaled ret_lly; static scaled ret_urx; @@ -150,7 +154,6 @@ scaled getury(void) return ret_ury; } -@ @c static int last_llx; static int last_lly; static int last_urx; @@ -210,11 +213,10 @@ void matrixrecalculate(scaled urx) matrixtransformrect(last_llx, last_lly, urx, last_ury); } -@ @c void pdf_out_setmatrix(PDF pdf, halfword p) { scaledpos pos = pdf->posstruct->pos; - int old_setting; /* holds print |selector| */ + int old_setting; str_number s; old_setting = selector; selector = new_string; diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfshipout.w b/Build/source/texk/web2c/luatexdir/pdf/pdfshipout.c index 8665f685e1f..084efc08626 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfshipout.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfshipout.c @@ -1,51 +1,55 @@ -% pdfshipout.w -% -% Copyright 2010-2012 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 +Copyright 2010-2012 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/>. + +*/ #include "ptexlib.h" -@ @c scaledpos shipbox_refpos; -@ |ship_out| is used to shipout a box to PDF or DVI mode. If |shipping_mode| is -set to |SHIPPING_FORM| then the output will be a Form object (only PDF), and if -it is set to |SHIPPING_PAGE| it will be a Page object. +/*tex + + |ship_out| is used to shipout a box to PDF or DVI mode. If |shipping_mode| is + set to |SHIPPING_FORM| then the output will be a |Form| object (only PDF), and + if it is set to |SHIPPING_PAGE| it will be a |Page| object. + +*/ -@c void ship_out(PDF pdf, halfword p, shipping_mode_e shipping_mode) { - int j, k; /* indices to first ten count registers */ + /*tex Indices to first ten count registers: */ + int j, k; int post_callback_id; int pre_callback_id; - posstructure refpoint; /* the origin pos. on the page */ + /*tex The origin position on the page: */ + posstructure refpoint; int rule_callback_id = 0; scaledpos cur = { 0, 0 }; refpoint.pos.h = 0; refpoint.pos.v = 0; ensure_output_state(pdf, ST_HEADER_WRITTEN); - fix_o_mode(); /* this is only for complaining if \.{\\outputmode} has changed */ - init_backend_functionpointers(output_mode_used); + /*tex This is only for complaining if \.{\\outputmode} has changed: */ + fix_o_mode(); pdf->f_cur = null_font; - /* - Start sheet {\sl Sync\TeX} information record; we assume that |pdf_output| is - properly set up. + /*tex + Start sheet {\sl Sync\TeX} information record. We assume that + |pdf_output| is properly set up. */ if (synctex_par) { if (output_mode_used == OMODE_DVI) { @@ -82,16 +86,18 @@ void ship_out(PDF pdf, halfword p, shipping_mode_e shipping_mode) } } if ((tracing_output_par > 0) && shipping_mode == SHIPPING_PAGE) { - print_char(']'); + if (pre_callback_id == 0) { + print_char(']'); + } update_terminal(); begin_diagnostic(); show_box(p); end_diagnostic(true); } - /* Ship box |p| out */ + /*tex Ship out box |p|:*/ if (shipping_mode == SHIPPING_PAGE && box_dir(p) != page_direction_par) normal_warning("backend","pagedir differs from bodydir, the output may be placed wrongly on the page"); - /* + /*tex 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 @@ -116,7 +122,7 @@ void ship_out(PDF pdf, halfword p, shipping_mode_e shipping_mode) max_v = height(p) + depth(p) + v_offset_par; if (width(p) + h_offset_par > max_h) max_h = width(p) + h_offset_par; - /* Calculate page dimensions and margins */ + /*tex Calculate page dimensions and margins. */ if (global_shipping_mode == SHIPPING_PAGE) { if (page_width_par > 0) pdf->page_size.h = page_width_par; @@ -156,28 +162,14 @@ void ship_out(PDF pdf, halfword p, shipping_mode_e shipping_mode) normal_warning("pdf backend","bad page direction, assuming TLT, case 2"); } } - /* + /*tex 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 (output_mode_used) { - case OMODE_DVI: - /* hh: how can we end up here? */ - refpoint.pos.h = one_true_inch; - refpoint.pos.v = pdf->page_size.v - one_true_inch; - dvi = refpoint.pos; - break; - case OMODE_PDF: - refpoint.pos.h = pdf_h_origin; - refpoint.pos.v = pdf->page_size.v - pdf_v_origin; - break; - default: - normal_error("pdf backend", "unknown output mode"); - } - - /* + backend_out_control[backend_control_set_reference_point](pdf,&refpoint); + /*tex Then shift |refpoint.pos| of the DVI origin depending on the - |page_direction| within the upright (TLT) page coordinate system + |page_direction| within the upright (TLT) page coordinate system. */ switch (page_direction_par) { case dir_TLT: @@ -195,7 +187,7 @@ void ship_out(PDF pdf, halfword p, shipping_mode_e shipping_mode) refpoint.pos.v -= v_offset_par; normal_warning("pdf backend","bad page direction, assuming TLT, case 3"); } - /* + /*tex Then switch to page box coordinate system; do |height(p)| movement, to get the location of the box origin. */ @@ -204,7 +196,7 @@ void ship_out(PDF pdf, halfword p, shipping_mode_e shipping_mode) cur.v = height(p); synch_pos_with_cur(pdf->posstruct, &refpoint, cur); } else { - /* shipping a /Form */ + /*tex We're shipping out a |/Form|. */ pdf->posstruct->dir = box_dir(p); switch (pdf->posstruct->dir) { case dir_TLT: @@ -245,18 +237,12 @@ void ship_out(PDF pdf, halfword p, shipping_mode_e shipping_mode) normal_warning("pdf backend","bad page direction, assuming TLT, case 5"); } } - /* 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 (output_mode_used) { - case OMODE_DVI: - dvi_begin_page(pdf); - break; - case OMODE_PDF: - pdf_begin_page(pdf); - break; - default: - normal_error("pdf backend", "unknown output mode"); - } + /*tex + Now we are at the point on the page where the origin of the page box + should go. First we register the poisition for \.{\\gleaders}. + */ + shipbox_refpos = pdf->posstruct->pos; + backend_out_control[backend_control_begin_page](pdf); rule_callback_id = callback_defined(process_rule_callback); switch (type(p)) { case vlist_node: @@ -271,24 +257,15 @@ void ship_out(PDF pdf, halfword p, shipping_mode_e shipping_mode) if (shipping_mode == SHIPPING_PAGE) total_pages++; cur_s = -1; - /* Finish shipping */ - switch (output_mode_used) { - case OMODE_DVI: - dvi_end_page(pdf); - break; - case OMODE_PDF: - pdf_end_page(pdf); - break; - default: - normal_error("pdf backend", "unknown output mode"); - } + /*tex Finish shipping */ + backend_out_control[backend_control_end_page](pdf); DONE: if ((tracing_output_par <= 0) && (post_callback_id == 0) && shipping_mode == SHIPPING_PAGE) { print_char(']'); update_terminal(); } dead_cycles = 0; - /* Flush the box from memory, showing statistics if requested */ + /*tex Flush the box from memory, showing statistics if requested. */ if ((tracing_stats_par > 1) && (pre_callback_id == 0)) { tprint_nl("Memory usage before: "); print_int(var_used); @@ -306,7 +283,7 @@ void ship_out(PDF pdf, halfword p, shipping_mode_e shipping_mode) } if (shipping_mode == SHIPPING_PAGE && (post_callback_id > 0)) (void) run_callback(post_callback_id, "->"); - /* Finish sheet {\sl Sync\TeX} information record */ + /*tex Finish sheet {\sl Sync\TeX} information record. */ if (synctex_par) synctexteehs(); global_shipping_mode = NOT_SHIPPING; diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdftables.w b/Build/source/texk/web2c/luatexdir/pdf/pdftables.c index 31fc2c9ad4e..180c232341d 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdftables.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdftables.c @@ -1,27 +1,26 @@ -% pdftables.w -% -% Copyright 2009-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 +Copyright 2009-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/>. + +*/ #include "ptexlib.h" -@ @c const char *pdf_obj_typenames[PDF_OBJ_TYPE_MAX + 1] = { "font", "outline", "dest", "obj", "xform", "ximage", "thread", "pagestream", "page", "pages", "catalog", "info", "link", "annot", "annots", @@ -31,21 +30,26 @@ const char *pdf_obj_typenames[PDF_OBJ_TYPE_MAX + 1] = { int pdf_last_annot; int pdf_last_link; int pdf_last_obj; -int pdf_retval; /* global multi-purpose return value */ -int pdf_cur_form; /* the form being output */ +int pdf_retval; +int pdf_cur_form; + +/*tex + + AVL sort entry into |avl_table[]|. +*/ -@ AVL sort entry into |avl_table[]| -@c static int compare_info(const void *pa, const void *pb, void *param) { const oentry *a = (const oentry *) pa; const oentry *b = (const oentry *) pb; (void) param; if (a->u_type == b->u_type) { - if (a->u_type == union_type_int) + if (a->u_type == union_type_int) { return ((a->u.int0 < b->u.int0 ? -1 : (a->u.int0 > b->u.int0 ? 1 : 0))); - else /* string type */ + } else { + /*tex String type: */ return strcmp(a->u.str0, b->u.str0); + } } else if (a->u_type == union_type_int) { return -1; } else { @@ -78,7 +82,8 @@ static void avl_put_int_obj(PDF pdf, int int0, int objptr, int t) static void avl_put_str_obj(PDF pdf, char *str0, int objptr, int t) { oentry *oe = xtalloc(1, oentry); - oe->u.str0 = str0; /* no xstrdup() here */ + /*tex No |xstrdup| here! */ + oe->u.str0 = str0; oe->u_type = union_type_cstring; oe->objptr = objptr; avl_put_obj(pdf, t, oe); @@ -112,9 +117,8 @@ static int avl_find_str_obj(PDF pdf, int t, char *s) return p->objptr; } -@ Create an object with type |t| and identifier |i| +/*tex Create an object with type |t| and identifier |i|: */ -@c int pdf_create_obj(PDF pdf, int t, int i) { int a; @@ -148,7 +152,6 @@ int pdf_create_obj(PDF pdf, int t, int i) return pdf->obj_ptr; } -@ @c int find_obj(PDF pdf, int t, int i, boolean byname) { char *ss = NULL; @@ -163,14 +166,17 @@ int find_obj(PDF pdf, int t, int i, boolean byname) return ret; } -@ The following function finds an object with identifier |i| and type |t|. -Identifier |i| is either an integer or a token list index. If no such object -exists then it will be created. This function is used mainly to find destination -for link annotations and outlines; however it is also used in |ship_out| (to -check whether a Page object already exists) so we need to declare it together -with subroutines needed in |hlist_out| and |vlist_out|. +/*tex + + The following function finds an object with identifier |i| and type |t|. + Identifier |i| is either an integer or a token list index. If no such object + exists then it will be created. This function is used mainly to find + destination for link annotations and outlines; however it is also used in + |ship_out| (to check whether a Page object already exists) so we need to + declare it together with subroutines needed in |hlist_out| and |vlist_out|. + +*/ -@c int pdf_get_obj(PDF pdf, int t, int i, boolean byname) { int r; @@ -197,8 +203,8 @@ int pdf_get_obj(PDF pdf, int t, int i, boolean byname) return r; } -@ object checking -@c +/*tex Some object checking: */ + void check_obj_exists(PDF pdf, int objnum) { if (objnum < 0 || objnum > pdf->obj_ptr) @@ -216,14 +222,15 @@ void check_obj_type(PDF pdf, int t, int objnum) } } -@ @c void set_rect_dimens(PDF pdf, halfword p, halfword parent_box, scaledpos cur, scaled_whd alt_rule, scaled margin) { - scaledpos ll, ur; /* positions relative to cur */ + /*tex The positions relative to cur: */ + scaledpos ll, ur; scaledpos pos_ll, pos_ur, tmp; posstructure localpos; localpos.dir = pdf->posstruct->dir; - ll.h = 0; /* pdf contains current point on page */ + /*tex |pdf| contains current point on page: */ + ll.h = 0; if (is_running(alt_rule.dp)) ll.v = depth(parent_box) - cur.v; else @@ -263,7 +270,6 @@ void set_rect_dimens(PDF pdf, halfword p, halfword parent_box, scaledpos cur, sc pdf_ann_top(p) = pos_ur.v + margin; } -@ @c void libpdffinish(PDF pdf) { strbuf_free(pdf->fb); diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfthread.w b/Build/source/texk/web2c/luatexdir/pdf/pdfthread.c index 6b3dd4b9432..20cc7bf0a45 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfthread.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfthread.c @@ -1,28 +1,32 @@ -% pdfthread.w -% -% Copyright 2009-2012 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 +Copyright 2009-2012 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/>. + +*/ #include "ptexlib.h" -@ Threads are handled in similar way as link annotations -@c +/*tex + + Threads are handled in similar way as link annotations. + +*/ + void append_bead(PDF pdf, halfword p) { int a, b, c, t; @@ -52,7 +56,6 @@ void append_bead(PDF pdf, halfword p) addto_page_resources(pdf, obj_type_bead, b); } -@ @c void do_thread(PDF pdf, halfword p, halfword parent_box, scaledpos cur) { scaled_whd alt_rule; @@ -78,7 +81,6 @@ void do_thread(PDF pdf, halfword p, halfword parent_box, scaledpos cur) pdf->last_thread = p; } -@ @c void append_thread(PDF pdf, halfword parent_box, scaledpos cur) { scaled_whd alt_rule; @@ -102,7 +104,6 @@ void append_thread(PDF pdf, halfword parent_box, scaledpos cur) pdf->last_thread = p; } -@ @c void end_thread(PDF pdf, halfword p) { scaledpos pos = pdf->posstruct->pos; @@ -131,8 +132,8 @@ void end_thread(PDF pdf, halfword p) pdf->last_thread = null; } -@ The following function are needed for outputing article thread. -@c +/*tex The following function are needed for outputing article thread. */ + void thread_title(PDF pdf, int t) { pdf_add_name(pdf, "Title"); @@ -224,7 +225,6 @@ void out_thread(PDF pdf, int t) } while (a != b); } -@ @c void scan_thread_id(void) { if (scan_keyword("num")) { @@ -251,7 +251,6 @@ void check_running_thread(PDF pdf, halfword this_box, scaledpos cur) append_thread(pdf, this_box, cur); } -@ @c void print_bead_rectangles(PDF pdf) { halfword i; @@ -262,13 +261,15 @@ void print_bead_rectangles(PDF pdf) l = pdf_create_obj(pdf, obj_type_others, 0); pdf_begin_obj(pdf, l, OBJSTM_ALWAYS); pdf_begin_array(pdf); - i = obj_bead_data(pdf, k->info); /* pointer to a whatsit or whatsit-like node */ + /*tex A pointer to a whatsit or whatsit-like node: */ + i = obj_bead_data(pdf, k->info); pdf_add_rect_spec(pdf, i); if (subtype(i) == pdf_thread_data_node) flush_node(i); pdf_end_array(pdf); pdf_end_obj(pdf); - set_obj_bead_rect(pdf, k->info, l); /* rewrite |obj_bead_data| */ + /*tex Rewrite |obj_bead_data|: */ + set_obj_bead_rect(pdf, k->info, l); k = k->link; } } diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfxform.w b/Build/source/texk/web2c/luatexdir/pdf/pdfxform.c index 731dc229080..7fd4eef1d82 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfxform.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfxform.c @@ -1,28 +1,30 @@ -% pdfxform.w -% -% Copyright 2009-2011 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/>. +/* + +Copyright 2009-2011 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 #include "ptexlib.h" #include "pdf/pdfpage.h" -@ @c -int pdf_cur_form; /* the form being output */ +/*tex The form being output: */ + +int pdf_cur_form; void pdf_place_form(PDF pdf, halfword p) { @@ -35,7 +37,7 @@ void pdf_place_form(PDF pdf, halfword p) nat.wd = obj_xform_width(pdf, objnum); nat.ht = obj_xform_height(pdf, objnum); nat.dp = obj_xform_depth(pdf, objnum); - /* no transform yet */ + /*tex No transform yet: */ tex.wd = width(p); tex.ht = height(p); tex.dp = depth(p); @@ -60,9 +62,8 @@ void pdf_place_form(PDF pdf, halfword p) addto_page_resources(pdf, obj_type_xform, objnum); } -/* we will store token lists as strings too */ +/*tex We will store token lists as strings too. */ -@ @c void scan_pdfxform(PDF pdf) { int k; @@ -100,7 +101,8 @@ void scan_pdfxform(PDF pdf) p = box(cur_val); if (p == null) normal_error("pdf backend", "xforms cannot be used with a void box"); - set_obj_xform_box(pdf, k, p); /* save pointer to the box */ + /*tex Save the pointer to the box: */ + set_obj_xform_box(pdf, k, p); set_obj_xform_width(pdf, k, width(p)); set_obj_xform_height(pdf, k, height(p)); set_obj_xform_depth(pdf, k, depth(p)); @@ -108,11 +110,10 @@ void scan_pdfxform(PDF pdf) last_saved_box_index = k; } -@ @c void scan_pdfrefxform(PDF pdf) { scaled_whd alt_rule, dim, nat; - alt_rule = scan_alt_rule(); /* scans |<rule spec>| to |alt_rule| */ + alt_rule = scan_alt_rule(); scan_int(); check_obj_type(pdf, obj_type_xform, cur_val); tail_append(new_rule(box_rule)); |