summaryrefslogtreecommitdiff
path: root/source/luametatex/source/tex/texbuildpage.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/luametatex/source/tex/texbuildpage.c')
-rw-r--r--source/luametatex/source/tex/texbuildpage.c286
1 files changed, 149 insertions, 137 deletions
diff --git a/source/luametatex/source/tex/texbuildpage.c b/source/luametatex/source/tex/texbuildpage.c
index 947ef1776..be75042eb 100644
--- a/source/luametatex/source/tex/texbuildpage.c
+++ b/source/luametatex/source/tex/texbuildpage.c
@@ -337,14 +337,32 @@ static halfword tex_aux_page_badness(scaled goal)
}
}
+static halfword tex_aux_insert_topskip(halfword height, int contribution)
+{
+ if (lmt_page_builder_state.contents != contribute_nothing) {
+ lmt_page_builder_state.contents = contribution;
+ } else {
+ tex_aux_freeze_page_specs(contribution);
+ }
+ {
+ halfword glue = tex_new_param_glue_node(top_skip_code, top_skip_glue);
+ if (glue_amount(glue) > height) {
+ glue_amount(glue) -= height;
+ } else {
+ glue_amount(glue) = 0;
+ }
+ return glue;
+ }
+}
+
void tex_build_page(void)
{
if (node_next(contribute_head) && ! lmt_page_builder_state.output_active) {
/*tex The (upcoming) penalty to be added to the badness: */
- int pi = 0;
+ int penalty = 0;
do {
- halfword p = node_next(contribute_head);
- halfword last_type = node_type(p);
+ halfword current = node_next(contribute_head);
+ halfword type = node_type(current);
/*tex Update the values of |last_glue|, |last_penalty|, and |last_kern|. */
if (lmt_page_builder_state.last_glue != max_halfword) {
tex_flush_node(lmt_page_builder_state.last_glue);
@@ -353,21 +371,21 @@ void tex_build_page(void)
lmt_page_builder_state.last_penalty = 0;
lmt_page_builder_state.last_kern = 0;
lmt_page_builder_state.last_boundary = 0;
- lmt_page_builder_state.last_node_type = last_type;
- lmt_page_builder_state.last_node_subtype = node_subtype(p);
+ lmt_page_builder_state.last_node_type = type;
+ lmt_page_builder_state.last_node_subtype = node_subtype(current);
lmt_page_builder_state.last_extra_used = 0;
- switch (last_type) {
+ switch (type) {
case glue_node:
- lmt_page_builder_state.last_glue = tex_new_glue_node(p, node_subtype(p));
+ lmt_page_builder_state.last_glue = tex_new_glue_node(current, node_subtype(current));
break;
case penalty_node:
- lmt_page_builder_state.last_penalty = penalty_amount(p);
+ lmt_page_builder_state.last_penalty = penalty_amount(current);
break;
case kern_node:
- lmt_page_builder_state.last_kern = kern_amount(p);
+ lmt_page_builder_state.last_kern = kern_amount(current);
break;
case boundary_node:
- lmt_page_builder_state.last_boundary = boundary_data(p);
+ lmt_page_builder_state.last_boundary = boundary_data(current);
break;
}
/*tex
@@ -392,102 +410,96 @@ void tex_build_page(void)
the contribution list will not be contributed until we know its successor.
*/
- switch (last_type) {
+ switch (type) {
case hlist_node:
case vlist_node:
- if (auto_migrating_mode_permitted(auto_migration_mode_par, auto_migrate_post)) {
- halfword h = box_post_migrated(p);
- if (h) {
- halfword t = tex_tail_of_node_list(h);
- if (node_next(p)) {
- tex_couple_nodes(t, node_next(p));
- } else {
- contribute_tail = t;
+ {
+ if (auto_migrating_mode_permitted(auto_migration_mode_par, auto_migrate_post)) {
+ halfword head = box_post_migrated(current);
+ if (head) {
+ halfword tail = tex_tail_of_node_list(head);
+ if (tracing_adjusts_par > 1) {
+ tex_begin_diagnostic();
+ tex_print_format("[adjust: post, mvl]");
+ tex_print_node_list(head,"post",show_box_depth_par, show_box_breadth_par);
+ tex_end_diagnostic();
+ }
+ if (node_next(current)) {
+ tex_couple_nodes(tail, node_next(current));
+ } else {
+ contribute_tail = tail;
+ }
+ tex_couple_nodes(current, head);
+ box_post_migrated(current) = null;
}
- tex_couple_nodes(p, h);
- box_post_migrated(p) = null;
}
- }
- if (auto_migrating_mode_permitted(auto_migration_mode_par, auto_migrate_pre)) {
- halfword h = box_pre_migrated(p);
- if (h) {
- halfword t = tex_tail_of_node_list(h);
- tex_couple_nodes(t, p);
- tex_couple_nodes(contribute_head, h);
- box_pre_migrated(p) = null;
- continue;
- }
- }
- /* common with rule */
- if (lmt_page_builder_state.contents < contribute_box) { // nothing or insert
- /*tex
- Initialize the current page, insert the |\topskip| glue ahead of |p|,
- and |goto continue|.
- */
- halfword q;
- if (lmt_page_builder_state.contents != contribute_nothing) {
- lmt_page_builder_state.contents = contribute_box;
- } else {
- tex_aux_freeze_page_specs(contribute_box);
+ if (auto_migrating_mode_permitted(auto_migration_mode_par, auto_migrate_pre)) {
+ halfword head = box_pre_migrated(current);
+ if (head) {
+ halfword tail = tex_tail_of_node_list(head);
+ if (tracing_adjusts_par > 1) {
+ tex_begin_diagnostic();
+ tex_print_format("[adjust: pre, mvl]");
+ tex_print_node_list(head,"pre",show_box_depth_par, show_box_breadth_par);
+ tex_end_diagnostic();
+ }
+ tex_couple_nodes(tail, current);
+ tex_couple_nodes(contribute_head, current);
+ // if (contribute_head == contribute_tail) {
+ // contribute_tail = tail;
+ // }
+ box_pre_migrated(current) = null;
+ continue;
+ }
}
- q = tex_new_param_glue_node(top_skip_code, top_skip_glue);
- if (glue_amount(q) > box_height(p)) {
- glue_amount(q) -= box_height(p);
+ if (lmt_page_builder_state.contents < contribute_box) {
+ /*tex
+ Initialize the current page, insert the |\topskip| glue ahead of |p|,
+ and |goto continue|.
+ */
+ halfword gluenode = tex_aux_insert_topskip(box_height(current), contribute_box);
+ tex_couple_nodes(gluenode, current);
+ tex_couple_nodes(contribute_head, gluenode);
+ continue;
} else {
- glue_amount(q) = 0;
+ /*tex Move a box to the current page, then |goto contribute|. */
+ page_total += page_depth + box_height(current);
+ page_depth = box_depth(current);
+ goto CONTRIBUTE;
}
- tex_couple_nodes(q, p);
- tex_couple_nodes(contribute_head, q);
- continue;
- } else {
- /*tex Move a box to the current page, then |goto contribute|. */
- page_total += page_depth + box_height(p);
- page_depth = box_depth(p);
- goto CONTRIBUTE;
}
case rule_node:
/* common with box */
if (lmt_page_builder_state.contents < contribute_box) {
- halfword q;
- if (lmt_page_builder_state.contents != contribute_nothing) {
- lmt_page_builder_state.contents = contribute_rule;
- } else {
- tex_aux_freeze_page_specs(contribute_rule);
- }
- q = tex_new_param_glue_node(top_skip_code, top_skip_glue);
- if (glue_amount(q) > rule_height(p)) {
- glue_amount(q) -= rule_height(p);
- } else {
- glue_amount(q) = 0;
- }
- tex_couple_nodes(q, p);
- tex_couple_nodes(contribute_head, q);
+ halfword gluenode = tex_aux_insert_topskip(rule_height(current), contribute_rule);
+ tex_couple_nodes(gluenode, current);
+ tex_couple_nodes(contribute_head, gluenode);
continue;
} else {
- page_total += page_depth + rule_height(p);
- page_depth = rule_depth(p);
+ page_total += page_depth + rule_height(current);
+ page_depth = rule_depth(current);
goto CONTRIBUTE;
}
case boundary_node:
if (lmt_page_builder_state.contents < contribute_box) {
goto DISCARD;
- } else if (node_subtype(p) == page_boundary) {
+ } else if (node_subtype(current) == page_boundary) {
/*tex
We just triggered the pagebuilder for which we needed a contribution. We fake
a zero penalty so that all gets processed. The main rationale is that we get
a better indication of what we do. Of course a callback can remove this node
so that it is never seen. Triggering from the callback is not doable.
*/
- halfword n = tex_new_node(penalty_node, user_penalty_subtype);
+ halfword penaltynode = tex_new_node(penalty_node, user_penalty_subtype);
/* todo: copy attributes */
tex_page_boundary_message("processed as penalty", 0);
- tex_try_couple_nodes(node_prev(p), n);
- tex_try_couple_nodes(n, node_next(p));
- tex_flush_node(p);
- penalty_amount(n) = boundary_data(p);
- p = n;
- node_next(contribute_head) = p;
- pi = 0;
+ tex_try_couple_nodes(node_prev(current), penaltynode);
+ tex_try_couple_nodes(penaltynode, node_next(current));
+ tex_flush_node(current);
+ penalty_amount(penaltynode) = boundary_data(current);
+ current = penaltynode;
+ node_next(contribute_head) = current;
+ penalty = 0;
break;
} else {
goto DISCARD;
@@ -498,7 +510,7 @@ void tex_build_page(void)
if (lmt_page_builder_state.contents < contribute_box) {
goto DISCARD;
} else if (precedes_break(lmt_page_builder_state.page_tail)) {
- pi = 0;
+ penalty = 0;
break;
} else {
goto UPDATEHEIGHTS;
@@ -506,10 +518,10 @@ void tex_build_page(void)
case kern_node:
if (lmt_page_builder_state.contents < contribute_box) {
goto DISCARD;
- } else if (! node_next(p)) {
+ } else if (! node_next(current)) {
return;
- } else if (node_type(node_next(p)) == glue_node) {
- pi = 0;
+ } else if (node_type(node_next(current)) == glue_node) {
+ penalty = 0;
break;
} else {
goto UPDATEHEIGHTS;
@@ -518,7 +530,7 @@ void tex_build_page(void)
if (lmt_page_builder_state.contents < contribute_box) {
goto DISCARD;
} else {
- pi = penalty_amount(p);
+ penalty = penalty_amount(current);
break;
}
case mark_node:
@@ -529,7 +541,7 @@ void tex_build_page(void)
Append an insertion to the current page and |goto contribute|. The insertion
number (index) is registered in the subtype (not any more for a while).
*/
- halfword index = insert_index(p); /* initially 65K */
+ halfword index = insert_index(current); /* initially 65K */
halfword location = page_insert_head;
halfword multiplier = tex_get_insert_multiplier(index);
halfword content = tex_get_insert_content(index);
@@ -568,13 +580,13 @@ void tex_build_page(void)
general).
*/
- halfword q = tex_new_node(split_node, normal_split_subtype);
+ halfword splitnode = tex_new_node(split_node, normal_split_subtype);
scaled advance = 0;
halfword distance = lmt_get_insert_distance(index, slot); /*tex Callback: we get a copy! */
- split_insert_index(q) = index;
- tex_try_couple_nodes(q, node_next(location));
- tex_couple_nodes(location, q);
- location = q;
+ split_insert_index(splitnode) = index;
+ tex_try_couple_nodes(splitnode, node_next(location));
+ tex_couple_nodes(location, splitnode);
+ location = splitnode;
if (! tex_aux_valid_insert_content(content)) {
content = tex_aux_delete_box_content(content);
tex_set_insert_content(index, content);
@@ -612,19 +624,19 @@ void tex_build_page(void)
}
/*tex I really need to check this logic with the original \LUATEX\ code. */
if (node_type(location) == split_node && node_subtype(location) == insert_split_subtype) {
- lmt_page_builder_state.insert_penalties += insert_float_cost(p);
+ lmt_page_builder_state.insert_penalties += insert_float_cost(current);
} else {
scaled delta = page_goal - page_total - page_depth + page_shrink;
- scaled needed = insert_total_height(p);
- split_last_insert(location) = p;
+ scaled needed = insert_total_height(current);
+ split_last_insert(location) = current;
/*tex This much room is left if we shrink the maximum. */
if (multiplier != 1000) {
/*tex This much room is needed. */
needed = tex_x_over_n(needed, 1000) * multiplier;
}
- if ((needed <= 0 || needed <= delta) && (insert_total_height(p) + box_height(location) <= limit)) {
- update_page_goal(index, insert_total_height(p), needed);
- box_height(location) += insert_total_height(p);
+ if ((needed <= 0 || needed <= delta) && (insert_total_height(current) + box_height(location) <= limit)) {
+ update_page_goal(index, insert_total_height(current), needed);
+ box_height(location) += insert_total_height(current);
} else {
/*tex
@@ -645,7 +657,7 @@ void tex_build_page(void)
*/
scaled height;
- halfword brk, penalty;
+ halfword breaknode, penalty;
if (multiplier <= 0) {
height = max_dimen;
} else {
@@ -657,9 +669,9 @@ void tex_build_page(void)
if (height > limit - box_height(location)) {
height = limit - box_height(location);
}
- brk = tex_vert_break(insert_list(p), height, insert_max_depth(p));
+ breaknode = tex_vert_break(insert_list(current), height, insert_max_depth(current));
box_height(location) += lmt_packaging_state.best_height_plus_depth;
- penalty = brk ? (node_type(brk) == penalty_node ? penalty_amount(brk) : 0) : eject_penalty;
+ penalty = breaknode ? (node_type(breaknode) == penalty_node ? penalty_amount(breaknode) : 0) : eject_penalty;
if (tracing_pages_par > 0) {
tex_aux_display_insertion_split_cost(index, height, penalty);
}
@@ -668,15 +680,15 @@ void tex_build_page(void)
}
update_page_goal(index, lmt_packaging_state.best_height_plus_depth, lmt_packaging_state.best_height_plus_depth);
node_subtype(location) = insert_split_subtype;
- split_broken(location) = brk;
- split_broken_insert(location) = p;
+ split_broken(location) = breaknode;
+ split_broken_insert(location) = current;
lmt_page_builder_state.insert_penalties += penalty;
}
}
goto CONTRIBUTE;
}
default:
- tex_formatted_error("pagebuilder", "invalid node of type %d in vertical mode", node_type(p));
+ tex_formatted_error("pagebuilder", "invalid node of type %d in vertical mode", node_type(current));
break;
}
/*tex
@@ -684,7 +696,7 @@ void tex_build_page(void)
prepare for output, and either fire up the users output routine and |return| or
ship out the page and |goto done|.
*/
- if (pi < infinite_penalty) {
+ if (penalty < infinite_penalty) {
/*tex
Compute the badness, |b|, of the current page, using |awful_bad| if the box is
too full. The |c| variable holds the costs.
@@ -714,10 +726,10 @@ void tex_build_page(void)
}
if (badness >= awful_bad) {
criterium = badness;
- } else if (pi <= eject_penalty) {
- criterium = pi;
+ } else if (penalty <= eject_penalty) {
+ criterium = penalty;
} else if (badness < infinite_bad) {
- criterium = badness + pi + lmt_page_builder_state.insert_penalties;
+ criterium = badness + penalty + lmt_page_builder_state.insert_penalties;
} else {
criterium = deplorable;
}
@@ -726,24 +738,24 @@ void tex_build_page(void)
}
{
int moveon = criterium <= lmt_page_builder_state.least_cost;
- int fireup = criterium == awful_bad || pi <= eject_penalty;
+ int fireup = criterium == awful_bad || penalty <= eject_penalty;
if (tracing_pages_par > 0) {
- tex_aux_display_page_break_cost(badness, pi, criterium, moveon, fireup);
+ tex_aux_display_page_break_cost(badness, penalty, criterium, moveon, fireup);
}
if (moveon) {
- halfword r = node_next(page_insert_head);
- lmt_page_builder_state.best_break = p;
+ halfword insert = node_next(page_insert_head);
+ lmt_page_builder_state.best_break = current;
lmt_page_builder_state.best_size = page_goal;
lmt_page_builder_state.insert_penalties = 0;
lmt_page_builder_state.least_cost = criterium;
- while (r != page_insert_head) {
- split_best_insert(r) = split_last_insert(r);
- r = node_next(r);
+ while (insert != page_insert_head) {
+ split_best_insert(insert) = split_last_insert(insert);
+ insert = node_next(insert);
}
}
if (fireup) {
/*tex Output the current page at the best place. */
- tex_aux_fire_up(p);
+ tex_aux_fire_up(current);
if (lmt_page_builder_state.output_active) {
/*tex User's output routine will act. */
return;
@@ -759,19 +771,19 @@ void tex_build_page(void)
Go here to record glue in the |active_height| table. Update the current page
measurements with respect to the glue or kern specified by node~|p|.
*/
- switch(node_type(p)) {
+ switch(node_type(current)) {
case kern_node:
- page_total += page_depth + kern_amount(p);
+ page_total += page_depth + kern_amount(current);
page_depth = 0;
goto APPEND;
case glue_node:
- if (glue_stretch_order(p) > 1) {
- page_stretch_1(glue_stretch_order(p)) += glue_stretch(p);
+ if (glue_stretch_order(current) > 1) {
+ page_stretch_1(glue_stretch_order(current)) += glue_stretch(current);
} else {
- page_stretch_2(glue_stretch_order(p)) += glue_stretch(p);
+ page_stretch_2(glue_stretch_order(current)) += glue_stretch(current);
}
- page_shrink += glue_shrink(p);
- if (glue_shrink_order(p) != normal_glue_order && glue_shrink(p)) {
+ page_shrink += glue_shrink(current);
+ if (glue_shrink_order(current) != normal_glue_order && glue_shrink(current)) {
tex_handle_error(
normal_error_type,
"Infinite glue shrinkage found on current page",
@@ -779,10 +791,10 @@ void tex_build_page(void)
"'\\vss' or '\\vskip 0pt minus 1fil'. Such glue doesn't belong there; but you can\n"
"safely proceed, since the offensive shrinkability has been made finite."
);
- tex_reset_glue_to_zero(p);
- glue_shrink_order(p) = normal_glue_order;
+ tex_reset_glue_to_zero(current);
+ glue_shrink_order(current) = normal_glue_order;
}
- page_total += page_depth + glue_amount(p);
+ page_total += page_depth + glue_amount(current);
page_depth = 0;
goto APPEND;
}
@@ -796,25 +808,25 @@ void tex_build_page(void)
page_depth = lmt_page_builder_state.max_depth;
}
APPEND:
- /*tex Link node |p| into the current page and |goto done|. We assume a positive depth. */
- tex_couple_nodes(lmt_page_builder_state.page_tail, p);
- lmt_page_builder_state.page_tail = p;
- tex_try_couple_nodes(contribute_head, node_next(p));
- node_next(p) = null;
- continue;
+ /*tex Link node |p| into the current page and |goto done|. We assume a positive depth. */
+ tex_couple_nodes(lmt_page_builder_state.page_tail, current);
+ lmt_page_builder_state.page_tail = current;
+ tex_try_couple_nodes(contribute_head, node_next(current));
+ node_next(current) = null;
+ continue; // or: break;
DISCARD:
/*tex Recycle node |p|. */
- tex_try_couple_nodes(contribute_head, node_next(p));
- node_next(p) = null;
+ tex_try_couple_nodes(contribute_head, node_next(current));
+ node_next(current) = null;
if (saving_vdiscards_par > 0) {
if (lmt_packaging_state.page_discards_head) {
- tex_couple_nodes(lmt_packaging_state.page_discards_tail, p);
+ tex_couple_nodes(lmt_packaging_state.page_discards_tail, current);
} else {
- lmt_packaging_state.page_discards_head = p;
+ lmt_packaging_state.page_discards_head = current;
}
- lmt_packaging_state.page_discards_tail = p;
+ lmt_packaging_state.page_discards_tail = current;
} else {
- tex_flush_node_list(p);
+ tex_flush_node_list(current);
}
} while (node_next(contribute_head));
/*tex Make the contribution list empty by setting its tail to |contribute_head|. */