1 /* packaging.h 2 3 Copyright 2009 Taco Hoekwater <taco@luatex.org> 4 5 This file is part of LuaTeX. 6 7 LuaTeX is free software; you can redistribute it and/or modify it under 8 the terms of the GNU General Public License as published by the Free 9 Software Foundation; either version 2 of the License, or (at your 10 option) any later version. 11 12 LuaTeX is distributed in the hope that it will be useful, but WITHOUT 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15 License for more details. 16 17 You should have received a copy of the GNU General Public License along 18 with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ 19 20 21 #ifndef PACKAGING_H 22 # define PACKAGING_H 23 24 /* We define some constants used when calling |hpack| to deal with font expansion. */ 25 26 typedef enum { 27 exactly = 0, /*a box dimension is pre-specified */ 28 additional, /*a box dimension is increased from the natural one */ 29 cal_expand_ratio, /* calculate amount for font expansion after breaking 30 paragraph into lines */ 31 subst_ex_font /* substitute fonts */ 32 } hpack_subtypes; 33 34 # define substituted 3 /* |subtype| of kern nodes that should be substituted */ 35 36 extern void scan_spec(group_code c); 37 extern void scan_full_spec(group_code c, int spec_direction); 38 39 extern scaled total_stretch[5]; 40 extern scaled total_shrink[5]; /* glue found by |hpack| or |vpack| */ 41 extern int last_badness; /* badness of the most recently packaged box */ 42 extern halfword adjust_tail; /* tail of adjustment list */ 43 extern halfword pre_adjust_tail; 44 extern int font_expand_ratio; /* current expansion ratio */ 45 extern halfword last_leftmost_char; 46 extern halfword last_rightmost_char; 47 extern halfword next_char_p; /* pointer to the next char of an implicit kern */ 48 extern halfword prev_char_p; /* pointer to the previous char of an implicit kern */ 49 50 extern void set_prev_char_p(halfword p); 51 extern scaled char_stretch(halfword p); 52 extern scaled char_shrink(halfword p); 53 extern scaled kern_stretch(halfword p); 54 extern scaled kern_shrink(halfword p); 55 extern void do_subst_font(halfword p, int ex_ratio); 56 extern scaled char_pw(halfword p, int side); 57 extern halfword new_margin_kern(scaled w, halfword p, int side); 58 59 # define update_adjust_list(A) do { \ 60 if (A == null) \ 61 pdf_error("pre vadjust", "adjust_tail or pre_adjust_tail is null"); \ 62 vlink(A) = adjust_ptr(p); \ 63 while (vlink(A) != null) \ 64 A = vlink(A); \ 65 } while (0) 66 67 extern halfword hpack(halfword p, scaled w, int m, int d); 68 extern halfword filtered_hpack(halfword p, halfword qt, scaled w, int m, 69 int grp, int d); 70 71 extern scaled_whd natural_sizes(halfword p, halfword pp, glue_ratio g_mult, 72 int g_sign, int g_order, int d); 73 74 extern int pack_begin_line; 75 76 # define vpack(A,B,C,D) vpackage(A,B,C,max_dimen,D) /* special case of unconstrained depth */ 77 78 extern halfword vpackage(halfword p, scaled h, int m, scaled l, int d); 79 extern halfword filtered_vpackage(halfword p, scaled h, int m, scaled l, 80 int grp, int d); 81 extern void finish_vcenter(void); 82 extern void package(int c); 83 extern void append_to_vlist(halfword b); 84 85 extern halfword prune_page_top(halfword p, boolean s); 86 extern scaled active_height[10]; /* distance from first active node to~|cur_p| */ 87 88 # define cur_height active_height[1] /* the natural height */ 89 # define awful_bad 07777777777 /* more than a billion demerits */ 90 # define deplorable 100000 /* more than |inf_bad|, but less than |awful_bad| */ 91 92 extern scaled best_height_plus_depth; /* height of the best box, without stretching or shrinking */ 93 94 extern halfword vert_break(halfword p, scaled h, scaled d); 95 extern halfword vsplit(halfword n, scaled h); /* extracts a page of height |h| from box |n| */ 96 97 # define box_code 0 /* |chr_code| for `\.{\\box}' */ 98 # define copy_code 1 /* |chr_code| for `\.{\\copy}' */ 99 # define last_box_code 2 /* |chr_code| for `\.{\\lastbox}' */ 100 # define vsplit_code 3 /* |chr_code| for `\.{\\vsplit}' */ 101 # define vtop_code 4 /* |chr_code| for `\.{\\vtop}' */ 102 103 # define tail_page_disc disc_ptr[copy_code] /* last item removed by page builder */ 104 # define page_disc disc_ptr[last_box_code] /* first item removed by page builder */ 105 # define split_disc disc_ptr[vsplit_code] /* first item removed by \.{\\vsplit} */ 106 107 extern halfword disc_ptr[(vsplit_code + 1)]; /* list pointers */ 108 109 /* 110 Now let's turn to the question of how \.{\\hbox} is treated. We actually 111 need to consider also a slightly larger context, since constructions like 112 `\.{\\setbox3=}\penalty0\.{\\hbox...}' and 113 `\.{\\leaders}\penalty0\.{\\hbox...}' and 114 `\.{\\lower3.8pt\\hbox...}' 115 are supposed to invoke quite 116 different actions after the box has been packaged. Conversely, 117 constructions like `\.{\\setbox3=}' can be followed by a variety of 118 different kinds of boxes, and we would like to encode such things in an 119 efficient way. 120 121 In other words, there are two problems: To represent the context of a box, 122 and to represent its type. 123 124 The first problem is solved by putting a ``context code'' on the |save_stack|, 125 just below the two entries that give the dimensions produced by |scan_spec|. 126 The context code is either a (signed) shift amount, or it is a large 127 integer |>=box_flag|, where |box_flag=@t$2^{30}$@>|. Codes |box_flag| through 128 |box_flag+biggest_reg| represent `\.{\\setbox0}' through 129 `\.{\\setbox}|biggest_reg|'; codes |box_flag+biggest_reg+1| through 130 |box_flag+2*biggest_reg| represent `\.{\\global\\setbox0}' 131 through `\.{\\global\\setbox}|biggest_reg|'; code |box_flag+2*number_regs| 132 represents `\.{\\shipout}'; and codes |box_flag+2*number_regs+1| 133 through |box_flag+2*number_regs+3| represent `\.{\\leaders}', `\.{\\cleaders}', 134 and `\.{\\xleaders}'. 135 136 The second problem is solved by giving the command code |make_box| to all 137 control sequences that produce a box, and by using the following |chr_code| 138 values to distinguish between them: |box_code|, |copy_code|, |last_box_code|, 139 |vsplit_code|, |vtop_code|, |vtop_code+vmode|, and |vtop_code+hmode|, 140 where the latter two are used denote \.{\\vbox} and \.{\\hbox}, respectively. 141 */ 142 143 # define box_flag 010000000000 /* context code for `\.{\\setbox0}' */ 144 # define global_box_flag (box_flag+number_regs) /* context code for `\.{\\global\\setbox0}' */ 145 # define max_global_box_flag (global_box_flag+number_regs) 146 # define ship_out_flag (max_global_box_flag+1) /* context code for `\.{\\shipout}' */ 147 # define leader_flag ship_out_flag+1 /* context code for `\.{\\leaders}' */ 148 149 extern void begin_box(int box_context); 150 151 #endif 152