texpackaging.h /size: 11 Kb    last modification: 2024-01-16 10:22
1/*
2    See license.txt in the root of this project.
3*/
4
5# ifndef LMT_PACKAGING_H
6# define LMT_PACKAGING_H
7
8# include "luametatex.h"
9
10/* We define some constants used when calling |hpack| to deal with font expansion. */
11
12typedef enum hpack_subtypes {
13    packing_exactly,    /*tex a box dimension is pre-specified */
14    packing_additional, /*tex a box dimension is increased from the natural one */
15    packing_expanded,   /*tex calculate amount for font expansion after breaking paragraph into lines */
16    packing_substitute, /*tex substitute fonts */
17    packing_adapted, 
18    packing_linebreak,  /*tex signals that we need to take the frozen adjust properties */
19} hpack_subtypes;
20
21typedef enum box_codes {
22    box_code,      /*tex |chr_code| for |\box| */
23    copy_code,     /*tex |chr_code| for |\copy| */
24    unpack_code,
25    last_box_code, /*tex |chr_code| for |\lastbox| */
26    tsplit_code,   
27    vsplit_code,   /*tex |chr_code| for |\vsplit| */
28    dsplit_code,   
29 /* hsplit_code, */ 
30    tpack_code,    
31    vpack_code,    /*tex |chr_code| for |\vpack| */
32    dpack_code,
33    hpack_code,
34    vtop_code,     
35    vbox_code,     /*tex |chr_code| for |\vbox| */
36    dbox_code,
37    hbox_code,
38    insert_box_code,
39    insert_copy_code,
40    local_left_box_box_code,
41    local_right_box_box_code,
42    local_middle_box_box_code,
43    page_discards_code,
44    split_discards_code,
45} box_codes;
46
47// typedef enum saved_full_spec_items {
48//     saved_full_spec_item_context     =  0,
49//     saved_full_spec_item_packaging   =  1,
50//     saved_full_spec_item_direction   =  2,
51//     saved_full_spec_item_attr_list   =  3,
52//     saved_full_spec_item_only_pack   =  4,
53//     saved_full_spec_item_orientation =  5,
54//     saved_full_spec_item_anchor      =  6,
55//     saved_full_spec_item_geometry    =  7,
56//     saved_full_spec_item_xoffset     =  8,
57//     saved_full_spec_item_yoffset     =  9,
58//     saved_full_spec_item_xmove       = 10,
59//     saved_full_spec_item_ymove       = 11,
60//     saved_full_spec_item_reverse     = 12,
61//     saved_full_spec_item_container   = 13,
62//     saved_full_spec_item_shift       = 14, /* cleaner than passing it as context */
63//     saved_full_spec_item_source      = 15,
64//     saved_full_spec_item_target      = 16,
65//     saved_full_spec_item_axis        = 17,
66//     saved_full_spec_item_class       = 18,
67//     saved_full_spec_item_state       = 19,
68//     saved_full_spec_item_retain      = 20,
69//     saved_full_spec_item_callback    = 21,
70//     saved_full_spec_n_of_items       = 22,
71// } saved_full_spec_items;
72
73typedef enum holding_migration_options {
74    holding_none_option    = 0x00,
75    holding_marks_option   = 0x01,
76    holding_inserts_option = 0x02,
77    holding_adjusts_option = 0x04,
78} holding_migration_options  ;  
79
80# define retain_marks(r)   (((r | holding_migrations_par) & holding_marks_option  ) == holding_marks_option  )
81# define retain_inserts(r) (((r | holding_migrations_par) & holding_inserts_option) == holding_inserts_option)
82# define retain_adjusts(r) (((r | holding_migrations_par) & holding_adjusts_option) == holding_adjusts_option)
83
84typedef struct packaging_state_info {
85    scaled   total_stretch[6];       /*tex with one for padding, the results are also used in alignments */
86    scaled   total_shrink[6];        /*tex glue found by |hpack| or |vpack|, the results are also used in alignments */
87    int      last_badness;           /*tex badness of the most recently packaged box */
88    scaled   last_overshoot;
89    halfword post_adjust_tail;       /*tex tail of adjustment list */
90    halfword pre_adjust_tail;
91    halfword post_migrate_tail;       /*tex tail of adjustment list */
92    halfword pre_migrate_tail;
93    halfword last_leftmost_char;
94    halfword last_rightmost_char;
95    int      pack_begin_line;
96    scaled   best_height_plus_depth; /*tex The height of the best box, without stretching or shrinking: */
97    halfword previous_char_ptr;
98    scaled   font_expansion_ratio;
99    halfword page_discards_tail;
100    halfword page_discards_head;
101    halfword split_discards_head;
102    halfword padding;
103} packaging_state_info;
104
105typedef enum box_limit_modes {
106    box_limit_none  = 0x00,
107    box_limit_hlist = 0x01,
108    box_limit_vlist = 0x02,
109    box_limit_line  = 0x04,
110} box_limit_modes;
111
112extern packaging_state_info lmt_packaging_state;
113
114extern scaled    tex_char_stretch          (halfword p);
115extern scaled    tex_char_shrink           (halfword p);
116/*     void      tex_get_char_expansion    (halfword p, halfword *stretch, halfword *shrink); */ /* no gain */
117extern scaled    tex_kern_stretch          (halfword p);
118extern scaled    tex_kern_shrink           (halfword p);
119extern scaled    tex_char_protrusion       (halfword p, int side);
120/*     void      tex_kern_protrusion       (halfword p, int side, halfword *stretch, halfword *shrink); */
121                                           
122extern scaled    tex_left_marginkern       (halfword p);
123extern scaled    tex_right_marginkern      (halfword p);
124                                           
125extern halfword  tex_filtered_hpack        (halfword p, halfword qt, scaled w, int m, int grp, halfword d, int just_pack, halfword attr, int state, int retain);
126extern halfword  tex_filtered_vpack        (halfword p, scaled h, int m, scaled maxdepth, int grp, halfword direction, int just_pack, halfword attr, int state, int retain, int *excess);
127                                           
128extern scaledwhd tex_natural_hsizes        (halfword p, halfword pp, glueratio g_mult, int g_sign, int g_order);
129extern scaledwhd tex_natural_vsizes        (halfword p, halfword pp, glueratio g_mult, int g_sign, int g_order);
130extern halfword  tex_natural_width         (halfword p, halfword pp, glueratio g_mult, int g_sign, int g_order);
131extern halfword  tex_natural_hsize         (halfword p, halfword *correction);
132extern halfword  tex_natural_vsize         (halfword p);
133                                           
134extern halfword  tex_hpack                 (halfword p, scaled w, int m, singleword d, int retain, int limit);
135extern halfword  tex_vpack                 (halfword p, scaled h, int m, scaled l, singleword d, int retain, int *excess);
136                                           
137extern void      tex_repack                (halfword p, scaled w, int m);
138extern void      tex_limit                 (halfword p);
139extern void      tex_freeze                (halfword p, int recurse, int limitate, halfword factor);
140extern scaled    tex_stretch               (halfword p);
141extern scaled    tex_shrink                (halfword p);
142                                           
143extern void      tex_package               (singleword nature);
144extern void      tex_run_unpackage         (void);
145                                           
146extern void      tex_append_to_vlist       (halfword b, int location, const line_break_properties *properties);
147                                           
148extern halfword  tex_prune_page_top        (halfword p, int s);
149extern halfword  tex_vert_break            (halfword p, scaled h, scaled d);
150extern halfword  tex_vsplit                (halfword n, scaled h, int m);
151                                           
152extern void      tex_finish_vcenter_group  (void);
153extern void      tex_run_vcenter           (void);
154                                           
155extern void      tex_show_packaging_group  (const char *package);
156extern int       tex_show_packaging_record (void);
157
158extern int       tex_get_packaging_context (void);
159extern int       tex_get_packaging_shift   (void);
160
161//# define vpack(A,B,C,D) tex_vpackage(A,B,C,max_dimension,D)
162
163# define first_un_box_code box_code
164# define last_un_box_code  unpack_code
165# define first_nu_box_code box_code
166# define last_nu_box_code  local_middle_box_box_code /*tex needs checking */
167
168/*tex
169
170    Now let's turn to the question of how |\hbox| is treated. We actually need to consider also a
171    slightly larger context, since constructions like
172
173    \starttyping
174    \setbox3={\\hbox...
175    \leaders\hbox...
176    \lower3.8pt\hbox...
177    \stoptyping
178
179    are supposed to invoke quite different actions after the box has been packaged. Conversely,
180    constructions like |\setbox 3 =| can be followed by a variety of different kinds of boxes, and
181    we would like to encode such things in an efficient way.
182
183    In other words, there are two problems: To represent the context of a box, and to represent its
184    type. The first problem is solved by putting a \quote {context code} on the |save_stack|, just
185    below the two entries that give the dimensions produced by |scan_spec|. The context code is
186    either a (signed) shift amount, or it is a large integer |>= box_flag|, where |box_flag = |
187    $2^{30}$. Codes |box_flag| through |box_flag + biggest_reg| represent |\setbox0| through
188    |\setbox biggest_reg|; codes |box_flag + biggest_reg + 1| through |box_flag + 2 * biggest_reg|
189    represent |\global \setbox 0| through |\global\setbox| |biggest_reg|; code |box_flag + 2 *
190    number_regs| represents |\shipout|; and codes |box_flag + 2 * number_regs + 1| through |box_flag
191    + 2 * number_regs + 3| represent |\leaders|, |\cleaders|, and |\xleaders|.
192
193    The second problem is solved by giving the command code |make_box| to all control sequences that
194    produce a box, and by using the following |chr_code| values to distinguish between them:
195    |box_code|, |copy_code|, |last_box_code|, |vsplit_code|, |vtop_code|, |vtop_code + vmode|, and
196    |vtop_code + hmode|, where the latter two are used denote |\vbox| and |\hbox|, respectively.
197
198    Originally the shift was encoded in the box context in case of a move. In fact even the local 
199    and global register assignments were in that property but this is no longer the case. This
200    actually makes implementing a |\boxspecdef| cleaner (a discarded experiment). The intermediate 
201    cleasned up flags can be found in the history. 
202
203*/
204
205# define biggest_reg 65535  /*tex This could be in |textypes.h|. */
206
207typedef enum box_flags {
208    direct_box_flag     = 0x00,
209 /* moved_box_flag      = 0x01, */
210 /* vcenter_box_flag    = 0x02, */ 
211    box_flag            = 0x02, /*tex context code for |\setbox0| */
212    global_box_flag     = 0x03, /*tex context code for |\global\setbox0| */
213    left_box_flag       = 0x04, /*tex context code for |\localleftbox| */
214    right_box_flag      = 0x05, /*tex context code for |\localrightbox| */
215    middle_box_flag     = 0x06, /*tex context code for |\localrightbox| */
216    shipout_flag        = 0x07, /*tex context code for |\shipout| */
217    lua_scan_flag       = 0x08, /*tex context code for |scan_list| */
218    a_leaders_flag      = 0x09, /*tex context code for |\leaders| */
219    c_leaders_flag      = 0x0A, /*tex context code for |\cleaders| */
220    x_leaders_flag      = 0x0B, /*tex context code for |\xleaders| */
221    g_leaders_flag      = 0x0C, /*tex context code for |\gleaders| */
222    u_leaders_flag      = 0x0D, /*tex context code for |\uleaders| */
223
224} box_flags;
225
226# define box_leaders_flag(f) (f >= a_leaders_flag && f <= u_leaders_flag)
227
228extern void tex_begin_box        (int boxcontext, scaled shift, halfword slot, halfword callback);
229extern int  tex_ignore_math_skip (halfword p);
230
231static inline scaled tex_aux_checked_dimension1(halfword v)
232{
233    if (v > max_dimension) {
234        return max_dimension;
235    } else if (v < -max_dimension) {
236        return -max_dimension;
237    } else {
238        return v;
239    }
240}
241
242static inline scaled tex_aux_checked_dimension2(halfword v)
243{
244    if (v > max_dimension) {
245        return max_dimension;
246    } else if (v < 0) {
247        return 0;
248    } else {
249        return v;
250    }
251}
252
253# endif
254