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/>. */
20
/* $Id: packaging.h 3261 2009-12-18 11:38:21Z taco $ */
25
/* We define some constants used when calling |hpack| to deal with font expansion. */
28
exactly = 0, /*a box dimension is pre-specified */
29
additional, /*a box dimension is increased from the natural one */
30
cal_expand_ratio, /* calculate amount for font expansion after breaking
31
paragraph into lines */
32
subst_ex_font /* substitute fonts */
35
# define substituted 3 /* |subtype| of kern nodes that should be substituted */
37
extern void scan_spec(group_code c);
38
extern void scan_full_spec(group_code c, int spec_direction);
40
extern scaled total_stretch[5];
41
extern scaled total_shrink[5]; /* glue found by |hpack| or |vpack| */
42
extern int last_badness; /* badness of the most recently packaged box */
43
extern halfword adjust_tail; /* tail of adjustment list */
44
extern halfword pre_adjust_tail;
45
extern int font_expand_ratio; /* current expansion ratio */
46
extern halfword last_leftmost_char;
47
extern halfword last_rightmost_char;
48
extern halfword next_char_p; /* pointer to the next char of an implicit kern */
49
extern halfword prev_char_p; /* pointer to the previous char of an implicit kern */
51
extern void set_prev_char_p(halfword p);
52
extern scaled char_stretch(halfword p);
53
extern scaled char_shrink(halfword p);
54
extern scaled kern_stretch(halfword p);
55
extern scaled kern_shrink(halfword p);
56
extern void do_subst_font(halfword p, int ex_ratio);
57
extern scaled char_pw(halfword p, int side);
58
extern halfword new_margin_kern(scaled w, halfword p, int side);
60
# define update_adjust_list(A) do { \
61
vlink(A) = adjust_ptr(p); \
62
while (vlink(A) != null) \
66
extern halfword hpack(halfword p, scaled w, int m, int d);
67
extern halfword filtered_hpack(halfword p, halfword qt, scaled w, int m,
70
extern scaled_whd natural_sizes(halfword p, halfword pp, glue_ratio g_mult,
71
int g_sign, int g_order, int d);
73
extern int pack_begin_line;
75
# define vpack(A,B,C,D) vpackage(A,B,C,max_dimen,D) /* special case of unconstrained depth */
77
extern halfword vpackage(halfword p, scaled h, int m, scaled l, int d);
78
extern halfword filtered_vpackage(halfword p, scaled h, int m, scaled l,
80
extern void finish_vcenter(void);
81
extern void package(int c);
82
extern void append_to_vlist(halfword b);
84
extern halfword prune_page_top(halfword p, boolean s);
85
extern scaled active_height[10]; /* distance from first active node to~|cur_p| */
87
# define cur_height active_height[1] /* the natural height */
88
# define awful_bad 07777777777 /* more than a billion demerits */
89
# define deplorable 100000 /* more than |inf_bad|, but less than |awful_bad| */
91
extern scaled best_height_plus_depth; /* height of the best box, without stretching or shrinking */
93
extern halfword vert_break(halfword p, scaled h, scaled d);
94
extern halfword vsplit(halfword n, scaled h); /* extracts a page of height |h| from box |n| */
96
# define box_code 0 /* |chr_code| for `\.{\\box}' */
97
# define copy_code 1 /* |chr_code| for `\.{\\copy}' */
98
# define last_box_code 2 /* |chr_code| for `\.{\\lastbox}' */
99
# define vsplit_code 3 /* |chr_code| for `\.{\\vsplit}' */
100
# define vtop_code 4 /* |chr_code| for `\.{\\vtop}' */
102
# define tail_page_disc disc_ptr[copy_code] /* last item removed by page builder */
103
# define page_disc disc_ptr[last_box_code] /* first item removed by page builder */
104
# define split_disc disc_ptr[vsplit_code] /* first item removed by \.{\\vsplit} */
106
extern halfword disc_ptr[(vsplit_code + 1)]; /* list pointers */
109
Now let's turn to the question of how \.{\\hbox} is treated. We actually
110
need to consider also a slightly larger context, since constructions like
111
`\.{\\setbox3=}\penalty0\.{\\hbox...}' and
112
`\.{\\leaders}\penalty0\.{\\hbox...}' and
113
`\.{\\lower3.8pt\\hbox...}'
114
are supposed to invoke quite
115
different actions after the box has been packaged. Conversely,
116
constructions like `\.{\\setbox3=}' can be followed by a variety of
117
different kinds of boxes, and we would like to encode such things in an
120
In other words, there are two problems: To represent the context of a box,
121
and to represent its type.
123
The first problem is solved by putting a ``context code'' on the |save_stack|,
124
just below the two entries that give the dimensions produced by |scan_spec|.
125
The context code is either a (signed) shift amount, or it is a large
126
integer |>=box_flag|, where |box_flag=@t$2^{30}$@>|. Codes |box_flag| through
127
|box_flag+biggest_reg| represent `\.{\\setbox0}' through
128
`\.{\\setbox}|biggest_reg|'; codes |box_flag+biggest_reg+1| through
129
|box_flag+2*biggest_reg| represent `\.{\\global\\setbox0}'
130
through `\.{\\global\\setbox}|biggest_reg|'; code |box_flag+2*number_regs|
131
represents `\.{\\shipout}'; and codes |box_flag+2*number_regs+1|
132
through |box_flag+2*number_regs+3| represent `\.{\\leaders}', `\.{\\cleaders}',
133
and `\.{\\xleaders}'.
135
The second problem is solved by giving the command code |make_box| to all
136
control sequences that produce a box, and by using the following |chr_code|
137
values to distinguish between them: |box_code|, |copy_code|, |last_box_code|,
138
|vsplit_code|, |vtop_code|, |vtop_code+vmode|, and |vtop_code+hmode|,
139
where the 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);