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