summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/tex
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/tex')
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/align.w36
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/buildpage.w63
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/directions.w1
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/dumpdata.w2
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/equivalents.w4
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/linebreak.h2
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/linebreak.w52
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/mainbody.w15
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/maincontrol.h1
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/maincontrol.w154
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/mlist.w27
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/packaging.w73
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/postlinebreak.w32
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/scanning.w77
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texmath.w13
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texnodes.h83
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texnodes.w128
17 files changed, 450 insertions, 313 deletions
diff --git a/Build/source/texk/web2c/luatexdir/tex/align.w b/Build/source/texk/web2c/luatexdir/tex/align.w
index cd8086af301..d54eabac131 100644
--- a/Build/source/texk/web2c/luatexdir/tex/align.w
+++ b/Build/source/texk/web2c/luatexdir/tex/align.w
@@ -518,7 +518,7 @@ void init_row(void)
space_factor = 0;
else
prev_depth = 0;
- tail_append(new_glue(preamble));
+ tail_append(new_glue(glue_ptr(preamble)));
subtype(cur_list.tail_field) = tab_skip_code + 1;
cur_align = vlink(preamble);
cur_tail = cur_head;
@@ -650,7 +650,7 @@ boolean fin_col(void)
v_part(p) = token_link(hold_token_head);
cur_loop = vlink(cur_loop);
- r = new_glue(cur_loop);
+ r = new_glue(glue_ptr(cur_loop));
vlink(p) = r;
} else {
const char *hlp[] =
@@ -719,7 +719,7 @@ boolean fin_col(void)
cur_list.tail_field = u;
/* Copy the tabskip glue between columns */
- tail_append(new_glue(vlink(cur_align)));
+ tail_append(new_glue(glue_ptr(vlink(cur_align))));
subtype(cur_list.tail_field) = tab_skip_code + 1;
if (extra_info(cur_align) >= cr_code) {
@@ -803,13 +803,13 @@ set so that the columns line up, taking due account of spanned columns.
@c
void fin_align(void)
{
- pointer p, q, r, s, u, rr; /* registers for the list operations */
+ pointer p, q, r, s, u, v, rr; /* registers for the list operations */
scaled t, w; /* width of column */
scaled o; /* shift offset for unset boxes */
halfword n; /* matching span amount */
scaled rule_save; /* temporary storage for |overfull_rule| */
halfword pd; /* temporary storage for |prev_depth| */
- halfword ng; /* temporary storage for |new_glue| */
+ halfword ng; /* temporary storage for |new_glue| */
if (cur_group != align_group)
confusion("align1");
unsave(); /* that |align_group| was for individual entries */
@@ -856,7 +856,12 @@ value is changed to zero and so is the next tabskip.
/* Nullify |width(q)| and the tabskip glue following this column */
width(q) = 0;
r = vlink(q);
- reset_glue_to_zero(r); /* is a lready copy */
+ s = glue_ptr(r);
+ if (s != zero_glue) {
+ add_glue_ref(zero_glue);
+ delete_glue_ref(s);
+ glue_ptr(r) = zero_glue;
+ }
}
if (span_ptr(q) != end_span) {
/* Merge the widths in the span nodes of |q| with those of |p|,
@@ -869,7 +874,7 @@ value is changed to zero and so is the next tabskip.
have been processed, and the successor of |s| matches |r| or precedes |r|
or follows |r|, according as |link(r)=n| or |link(r)>n| or |link(r)<n|.
*/
- t = width(q) + width(vlink(q));
+ t = width(q) + width(glue_ptr(vlink(q)));
r = span_ptr(q);
s = end_span;
span_ptr(s) = p;
@@ -982,17 +987,22 @@ value is changed to zero and so is the next tabskip.
and update |s| and |t| as the prototype nodes are passed */
s = vlink(s);
- ng = new_glue(s);
+ v = glue_ptr(s);
+ ng = new_glue(v);
vlink(u) = ng;
u = vlink(u);
subtype(u) = tab_skip_code + 1;
- t = t + width(s);
+ t = t + width(v);
if (glue_sign(p) == stretching) {
- if (stretch_order(s) == glue_order(p))
- t = t + round(float_cast(glue_set(p)) * float_cast(stretch(s)));
+ if (stretch_order(v) == glue_order(p))
+ t = t +
+ round(float_cast(glue_set(p)) *
+ float_cast(stretch(v)));
} else if (glue_sign(p) == shrinking) {
- if (shrink_order(s) == glue_order(p))
- t = t - round(float_cast(glue_set(p)) * float_cast(shrink(s)));
+ if (shrink_order(v) == glue_order(p))
+ t = t -
+ round(float_cast(glue_set(p)) *
+ float_cast(shrink(v)));
}
s = vlink(s);
rr = new_null_box();
diff --git a/Build/source/texk/web2c/luatexdir/tex/buildpage.w b/Build/source/texk/web2c/luatexdir/tex/buildpage.w
index 104566f790b..4c61a510a9c 100644
--- a/Build/source/texk/web2c/luatexdir/tex/buildpage.w
+++ b/Build/source/texk/web2c/luatexdir/tex/buildpage.w
@@ -316,14 +316,15 @@ void build_page(void)
p = vlink(contrib_head);
/* Update the values of |last_glue|, |last_penalty|, and |last_kern| */
if (last_glue != max_halfword) {
- flush_node(last_glue);
+ delete_glue_ref(last_glue);
last_glue = max_halfword;
}
last_penalty = 0;
last_kern = 0;
last_node_type = type(p) + 1;
if (type(p) == glue_node) {
- last_glue = new_glue(p);
+ last_glue = glue_ptr(p);
+ add_glue_ref(last_glue);
} else if (type(p) == penalty_node) {
last_penalty = penalty(p);
} else if (type(p) == kern_node) {
@@ -359,17 +360,17 @@ void build_page(void)
freeze_page_specs(box_there);
else
page_contents = box_there;
- q = new_skip_param(top_skip_code);
+ q = new_skip_param(top_skip_code); /* now |temp_ptr=glue_ptr(q)| */
if ((type(p) == hlist_node) && is_mirrored(body_direction)) {
- if (width(q) > depth(p))
- width(q) = width(q) - depth(p);
+ if (width(temp_ptr) > depth(p))
+ width(temp_ptr) = width(temp_ptr) - depth(p);
else
- width(q) = 0;
+ width(temp_ptr) = 0;
} else {
- if (width(q) > height(p))
- width(q) = width(q) - height(p);
+ if (width(temp_ptr) > height(p))
+ width(temp_ptr) = width(temp_ptr) - height(p);
else
- width(q) = 0;
+ width(temp_ptr) = 0;
}
couple_nodes(q, p);
couple_nodes(contrib_head, q);
@@ -632,24 +633,32 @@ void build_page(void)
/* Update the current page measurements with respect to the
glue or kern specified by node~|p| */
- if (type(p) != kern_node) {
- if (stretch_order(p) > 1)
- page_so_far[1 + stretch_order(p)] = page_so_far[1 + stretch_order(p)] + stretch(p);
+ if (type(p) == kern_node) {
+ q = p;
+ } else {
+ q = glue_ptr(p);
+ if (stretch_order(q) > 1)
+ page_so_far[1 + stretch_order(q)] =
+ page_so_far[1 + stretch_order(q)] + stretch(q);
else
- page_so_far[2 + stretch_order(p)] = page_so_far[2 + stretch_order(p)] + stretch(p);
- page_shrink = page_shrink + shrink(p);
- if ((shrink_order(p) != normal) && (shrink(p) != 0)) {
+ page_so_far[2 + stretch_order(q)] =
+ page_so_far[2 + stretch_order(q)] + stretch(q);
+ page_shrink = page_shrink + shrink(q);
+ if ((shrink_order(q) != normal) && (shrink(q) != 0)) {
print_err("Infinite glue shrinkage found on current page");
help4("The page about to be output contains some infinitely",
"shrinkable glue, e.g., `\\vss' or `\\vskip 0pt minus 1fil'.",
"Such glue doesn't belong there; but you can safely proceed,",
"since the offensive shrinkability has been made finite.");
error();
- reset_glue_to_zero(p);
- shrink_order(p) = normal;
+ r = new_spec(q);
+ shrink_order(r) = normal;
+ delete_glue_ref(q);
+ glue_ptr(p) = r;
+ q = r;
}
}
- page_total = page_total + page_depth + width(p);
+ page_total = page_total + page_depth + width(q);
page_depth = 0;
CONTRIBUTE: /* go here to link a node into the current page */
@@ -805,7 +814,6 @@ void fire_up(halfword c)
s = last_ins_ptr(r);
vlink(s) = ins_ptr(p);
if (best_ins_ptr(r) == p) {
- halfword t; /* was a global temp_ptr */
/* Wrap up the box specified by node |r|, splitting node |p| if
called for; set |wait:=true| if node |p| holds a remainder after
splitting */
@@ -818,20 +826,22 @@ void fire_up(halfword c)
ins_ptr(p) =
prune_page_top(broken_ptr(r), false);
if (ins_ptr(p) != null) {
- t = vpack(ins_ptr(p), 0, additional, -1);
- height(p) = height(t) + depth(t);
- list_ptr(t) = null;
- flush_node(t);
+ temp_ptr =
+ vpack(ins_ptr(p), 0, additional, -1);
+ height(p) =
+ height(temp_ptr) + depth(temp_ptr);
+ list_ptr(temp_ptr) = null;
+ flush_node(temp_ptr);
wait = true;
}
}
}
best_ins_ptr(r) = null;
n = subtype(r);
- t = list_ptr(box(n));
+ temp_ptr = list_ptr(box(n));
list_ptr(box(n)) = null;
flush_node(box(n));
- box(n) = vpack(t, 0, additional, body_direction);
+ box(n) = vpack(temp_ptr, 0, additional, body_direction);
} else {
while (vlink(s) != null)
@@ -900,7 +910,7 @@ void fire_up(halfword c)
vbadness = save_vbadness;
vfuzz = save_vfuzz;
if (last_glue != max_halfword)
- flush_node(last_glue);
+ delete_glue_ref(last_glue);
/* Start a new current page */
start_new_page(); /* this sets |last_glue:=max_halfword| */
if (q != hold_head) {
@@ -911,7 +921,6 @@ void fire_up(halfword c)
/* Delete the page-insertion nodes */
r = vlink(page_ins_head);
while (r != page_ins_head) {
- /* todo: couple */
q = vlink(r);
flush_node(r);
r = q;
diff --git a/Build/source/texk/web2c/luatexdir/tex/directions.w b/Build/source/texk/web2c/luatexdir/tex/directions.w
index 20d46606d6a..7af25187999 100644
--- a/Build/source/texk/web2c/luatexdir/tex/directions.w
+++ b/Build/source/texk/web2c/luatexdir/tex/directions.w
@@ -86,6 +86,7 @@ halfword new_dir(int s)
{
halfword p = new_node(dir_node, 0);
dir_dir(p) = s;
+ dir_dvi_ptr(p) = -1;
dir_level(p) = cur_level;
return p;
}
diff --git a/Build/source/texk/web2c/luatexdir/tex/dumpdata.w b/Build/source/texk/web2c/luatexdir/tex/dumpdata.w
index be5f0074639..ac4f96f2f0e 100644
--- a/Build/source/texk/web2c/luatexdir/tex/dumpdata.w
+++ b/Build/source/texk/web2c/luatexdir/tex/dumpdata.w
@@ -27,7 +27,7 @@
/* we start with 907: the sum of the values of the bytes of "don knuth" */
-#define FORMAT_ID (907+14)
+#define FORMAT_ID (907+13)
#if ((FORMAT_ID>=0) && (FORMAT_ID<=256))
#error Wrong value for FORMAT_ID.
#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/equivalents.w b/Build/source/texk/web2c/luatexdir/tex/equivalents.w
index cc709c1bd7e..d88b7322a76 100644
--- a/Build/source/texk/web2c/luatexdir/tex/equivalents.w
+++ b/Build/source/texk/web2c/luatexdir/tex/equivalents.w
@@ -567,8 +567,6 @@ within |save_stack|, so these counts must be handled carefully.
@^reference counts@>
@c
-/* we don't need to destroy when an assignment has the same node */
-
void eq_destroy(memory_word w)
{ /* gets ready to forget |w| */
halfword q; /* |equiv| field of |w| */
@@ -580,7 +578,7 @@ void eq_destroy(memory_word w)
delete_token_ref(equiv_field(w));
break;
case glue_ref_cmd:
- flush_node(equiv_field(w));
+ delete_glue_ref(equiv_field(w));
break;
case shape_ref_cmd:
q = equiv_field(w); /* we need to free a \.{\\parshape} block */
diff --git a/Build/source/texk/web2c/luatexdir/tex/linebreak.h b/Build/source/texk/web2c/luatexdir/tex/linebreak.h
index 99560ebed2e..1b5d1da96ca 100644
--- a/Build/source/texk/web2c/luatexdir/tex/linebreak.h
+++ b/Build/source/texk/web2c/luatexdir/tex/linebreak.h
@@ -82,7 +82,7 @@ extern halfword find_protchar_right(halfword l, halfword r);
)
# define cp_skipable(a) ( (! is_char_node((a))) && ( \
- ((type((a)) == glue_node) && (glue_is_zero((a)))) \
+ ((type((a)) == glue_node) && (glue_ptr((a)) == zero_glue)) \
|| (type((a)) == penalty_node) \
|| ((type((a)) == disc_node) && empty_disc(a)) \
|| ((type((a)) == kern_node) && ((width((a)) == 0) || (subtype((a)) == normal))) \
diff --git a/Build/source/texk/web2c/luatexdir/tex/linebreak.w b/Build/source/texk/web2c/luatexdir/tex/linebreak.w
index 8b8f47bc9d5..6560192da93 100644
--- a/Build/source/texk/web2c/luatexdir/tex/linebreak.w
+++ b/Build/source/texk/web2c/luatexdir/tex/linebreak.w
@@ -108,10 +108,11 @@ void line_break(boolean d, int line_break_context)
} else if (type(cur_list.tail_field) != glue_node) {
tail_append(new_penalty(inf_penalty));
} else {
- halfword t = alink(cur_list.tail_field);
- flush_node(cur_list.tail_field);
- cur_list.tail_field = t;
- tail_append(new_penalty(inf_penalty));
+ type(cur_list.tail_field) = penalty_node;
+ delete_glue_ref(glue_ptr(cur_list.tail_field));
+ if (leader_ptr(cur_list.tail_field) != null)
+ flush_node_list(leader_ptr(cur_list.tail_field));
+ penalty(cur_list.tail_field) = inf_penalty;
}
final_par_glue = new_param_glue(par_fill_skip_code);
couple_nodes(cur_list.tail_field, final_par_glue);
@@ -209,6 +210,7 @@ static boolean no_shrink_error_yet; /*have we complained about infinite shri
static halfword finite_shrink(halfword p)
{ /* recovers from infinite shrinkage */
+ halfword q; /*new glue specification */
const char *hlp[] = {
"The paragraph just ended includes some glue that has",
"infinite shrinkability, e.g., `\\hskip 0pt minus 1fil'.",
@@ -221,8 +223,10 @@ static halfword finite_shrink(halfword p)
no_shrink_error_yet = false;
tex_error("Infinite glue shrinkage found in a paragraph", hlp);
}
- shrink_order(p) = normal;
- return p;
+ q = new_spec(p);
+ shrink_order(q) = normal;
+ delete_glue_ref(p);
+ return q;
}
@ A pointer variable |cur_p| runs through the given horizontal list as we look
@@ -896,7 +900,7 @@ static void compute_break_width(int break_type, int line_break_dir, int adjust_s
switch (type(s)) {
case math_node:
/* begin mathskip code */
- if (glue_is_zero(math_skip)) {
+ if (math_skip == zero_glue) {
break_width[1] -= surround(s);
break;
} else {
@@ -905,9 +909,12 @@ static void compute_break_width(int break_type, int line_break_dir, int adjust_s
/* end mathskip code */
case glue_node:
/*Subtract glue from |break_width|; */
- break_width[1] -= width(s);
- break_width[2 + stretch_order(s)] -= stretch(s);
- break_width[7] -= shrink(s);
+ {
+ halfword v = glue_ptr(s);
+ break_width[1] -= width(v);
+ break_width[2 + stretch_order(v)] -= stretch(v);
+ break_width[7] -= shrink(v);
+ }
break;
case penalty_node:
break;
@@ -1691,7 +1698,7 @@ void ext_do_line_break(int paragraph_dir,
*/
do_last_line_fit = false;
if (last_line_fit > 0) {
- q = last_line_fill;
+ q = glue_ptr(last_line_fill);
if ((stretch(q) > 0) && (stretch_order(q) > normal)) {
if ((background[3] == 0) && (background[4] == 0) &&
(background[5] == 0) && (background[6] == 0)) {
@@ -1838,7 +1845,7 @@ void ext_do_line_break(int paragraph_dir,
case math_node:
auto_breaking = (subtype(cur_p) == after);
/* begin mathskip code */
- if (glue_is_zero(math_skip)) {
+ if (math_skip == zero_glue) {
kern_break();
break;
} else {
@@ -1879,10 +1886,16 @@ void ext_do_line_break(int paragraph_dir,
}
}
/* *INDENT-ON* */
- check_shrinkage(cur_p);
- active_width[1] += width(cur_p);
- active_width[2 + stretch_order(cur_p)] += stretch(cur_p);
- active_width[7] += shrink(cur_p);
+ check_shrinkage(glue_ptr(cur_p));
+ q = glue_ptr(cur_p);
+ active_width[1] += width(q);
+ active_width[2 + stretch_order(q)] += stretch(q);
+ active_width[7] += shrink(q);
+ /* begin mathskip code */
+ if (type(cur_p)==math_node) {
+ active_width[1]+=surround(cur_p);
+ }
+ /* end mathskip code */
break;
case kern_node:
if (subtype(cur_p) == explicit_kern || subtype(cur_p) == italic_kern) {
@@ -2109,8 +2122,11 @@ void ext_do_line_break(int paragraph_dir,
if (active_short(best_bet) == 0) {
do_last_line_fit = false;
} else {
- width(last_line_fill) += (active_short(best_bet) - active_glue(best_bet));
- stretch(last_line_fill) = 0;
+ q = new_spec(glue_ptr(last_line_fill));
+ delete_glue_ref(glue_ptr(last_line_fill));
+ width(q) += (active_short(best_bet) - active_glue(best_bet));
+ stretch(q) = 0;
+ glue_ptr(last_line_fill) = q;
}
}
diff --git a/Build/source/texk/web2c/luatexdir/tex/mainbody.w b/Build/source/texk/web2c/luatexdir/tex/mainbody.w
index ad0bb783a1f..a8d35d7ac56 100644
--- a/Build/source/texk/web2c/luatexdir/tex/mainbody.w
+++ b/Build/source/texk/web2c/luatexdir/tex/mainbody.w
@@ -549,8 +549,7 @@ been scanned and |its_all_over|\kern-2pt.
void final_cleanup(void)
{
int c; /* 0 for \.{\\end}, 1 for \.{\\dump} */
- halfword i; /* for looping marks */
- halfword t; /* was a global temp_ptr */
+ halfword i; /* for looping marks */
c = cur_chr;
if (job_name == 0)
open_log_file();
@@ -579,16 +578,17 @@ void final_cleanup(void)
tprint(" was incomplete)");
if_line = if_line_field(cond_ptr);
cur_if = subtype(cond_ptr);
- t = cond_ptr;
+ temp_ptr = cond_ptr;
cond_ptr = vlink(cond_ptr);
- flush_node(t);
+ flush_node(temp_ptr);
}
if (callback_defined(stop_run_callback) == 0)
if (history != spotless)
if ((history == warning_issued) || (interaction < error_stop_mode))
if (selector == term_and_log) {
selector = term_only;
- tprint_nl("(see the transcript file for additional information)");
+ tprint_nl
+ ("(see the transcript file for additional information)");
selector = term_and_log;
}
if (c == 1) {
@@ -602,9 +602,8 @@ void final_cleanup(void)
}
for (c = last_box_code; c <= vsplit_code; c++)
flush_node_list(disc_ptr[c]);
- if (last_glue != max_halfword) {
- flush_node(last_glue);
- }
+ if (last_glue != max_halfword)
+ delete_glue_ref(last_glue);
while (pseudo_files != null)
pseudo_close(); /* flush pseudo files */
store_fmt_file();
diff --git a/Build/source/texk/web2c/luatexdir/tex/maincontrol.h b/Build/source/texk/web2c/luatexdir/tex/maincontrol.h
index c42dcc93aa4..ea22ff80dc7 100644
--- a/Build/source/texk/web2c/luatexdir/tex/maincontrol.h
+++ b/Build/source/texk/web2c/luatexdir/tex/maincontrol.h
@@ -176,6 +176,7 @@ extern void fixup_directions(void);
extern void get_r_token(void);
extern void assign_internal_value(int a, halfword p, int cur_val);
+extern void trap_zero_glue(void);
extern void do_register_command(int a);
extern void alter_aux(void);
extern void alter_prev_graf(void);
diff --git a/Build/source/texk/web2c/luatexdir/tex/maincontrol.w b/Build/source/texk/web2c/luatexdir/tex/maincontrol.w
index af89da9d5d7..bf432e308da 100644
--- a/Build/source/texk/web2c/luatexdir/tex/maincontrol.w
+++ b/Build/source/texk/web2c/luatexdir/tex/maincontrol.w
@@ -130,7 +130,11 @@ and kerns, is part of \TeX's ``inner loop''; the whole program runs
efficiently when its inner loop is fast, so this part has been written
with particular care.
-We leave the |space_factor| unchanged if |sf_code(cur_chr)=0|; otherwise we
+@c
+static halfword main_p; /* temporary register for list manipulation */
+static halfword main_s; /* space factor value */
+
+@ We leave the |space_factor| unchanged if |sf_code(cur_chr)=0|; otherwise we
set it equal to |sf_code(cur_chr)|, except that it should never change
from a value less than 1000 to a value exceeding 1000. The most common
case is |sf_code(cur_chr)=1000|, so we want that case to be fast.
@@ -138,16 +142,16 @@ case is |sf_code(cur_chr)=1000|, so we want that case to be fast.
@c
void adjust_space_factor(void)
{
- halfword s = get_sf_code(cur_chr);
- if (s == 1000) {
+ main_s = get_sf_code(cur_chr);
+ if (main_s == 1000) {
space_factor = 1000;
- } else if (s < 1000) {
- if (s > 0)
- space_factor = s;
+ } else if (main_s < 1000) {
+ if (main_s > 0)
+ space_factor = main_s;
} else if (space_factor < 1000) {
space_factor = 1000;
} else {
- space_factor = s;
+ space_factor = main_s;
}
}
@@ -156,6 +160,10 @@ both time and memory.'' That may be true, but it also punches through
the API wall for fonts, so I removed that -- Taco. But a bit of caching
is very welcome, which is why I need to have the next two globals:
+@c
+internal_font_number space_spec_font;
+halfword space_spec_cache;
+
@ To handle the execution state of |main_control|'s eternal loop,
an extra global variable is used, along with a macro to define
its values.
@@ -200,32 +208,38 @@ is zero or~not.
@c
static void run_app_space (void) {
- halfword p; /* was a global temp_ptr */
int method = int_par(disable_space_code) ;
if (method == 1) {
/* don't inject anything, not even zero skip */
} else if (method == 2) {
- p = new_glue(zero_glue);
- couple_nodes(tail,p);
- tail = p;
+ temp_ptr = new_glue(zero_glue);
+ couple_nodes(tail,temp_ptr);
+ tail = temp_ptr;
} else if ((abs(mode) + cur_cmd == hmode + spacer_cmd) && (!(space_factor == 1000))) {
app_space();
} else {
/* Append a normal inter-word space to the current list */
- if (glue_is_zero(space_skip)) {
- /* Find the glue specification for text spaces in the current font */
- p = new_glue(zero_glue);
- width(p) = space(cur_font);
- stretch(p) = space_stretch(cur_font);
- shrink(p) = space_shrink(cur_font);
-
+ if (space_skip == zero_glue) {
+ /* Find the glue specification, |main_p|, for
+ text spaces in the current font */
+ if (cur_font != space_spec_font) {
+ if (space_spec_cache != zero_glue)
+ delete_glue_ref(space_spec_cache);
+ space_spec_cache = new_spec(zero_glue);
+ width(space_spec_cache) = space(cur_font);
+ stretch(space_spec_cache) = space_stretch(cur_font);
+ shrink(space_spec_cache) = space_shrink(cur_font);
+ space_spec_font = cur_font;
+ }
+ main_p = space_spec_cache;
+ temp_ptr = new_glue(main_p);
} else {
- p = new_param_glue(space_skip_code);
+ temp_ptr = new_param_glue(space_skip_code);
}
- /* so from now we have a subtype with spaces: */
- subtype(p) = space_skip_code + 1 ;
- couple_nodes(tail,p);
- tail = p;
+/* so from now we have a subtype with spaces: */
+subtype(temp_ptr) = space_skip_code + 1 ;
+ couple_nodes(tail,temp_ptr);
+ tail = temp_ptr;
}
}
@@ -987,27 +1001,28 @@ void main_control(void)
void app_space(void)
{ /* handle spaces when |space_factor<>1000| */
halfword q; /* glue node */
- if ((space_factor >= 2000) && (! glue_is_zero(xspace_skip))) {
+ if ((space_factor >= 2000) && (xspace_skip != zero_glue)) {
q = new_param_glue(xspace_skip_code);
- /* so from now we have a subtype with spaces: */
- subtype(q) = xspace_skip_code + 1;
+/* so from now we have a subtype with spaces: */
+subtype(q) = xspace_skip_code + 1;
} else {
- if (!glue_is_zero(space_skip)) {
- q = new_glue(space_skip);
+ if (space_skip != zero_glue) {
+ main_p = new_spec(space_skip);
} else {
- q = new_glue(zero_glue);
- width(q) = space(cur_font);
- stretch(q) = space_stretch(cur_font);
- shrink(q) = space_shrink(cur_font);
+ main_p = new_spec(zero_glue);
+ width(main_p) = space(cur_font);
+ stretch(main_p) = space_stretch(cur_font);
+ shrink(main_p) = space_shrink(cur_font);
}
- /* Modify the glue specification in |q| according to the space factor */
+ /* Modify the glue specification in |main_p| according to the space factor */
if (space_factor >= 2000)
- width(q) = width(q) + extra_space(cur_font);
- stretch(q) = xn_over_d(stretch(q), space_factor, 1000);
- shrink(q) = xn_over_d(shrink(q), 1000, space_factor);
-
- /* so from now we have a subtype with spaces: */
- subtype(q) = space_skip_code + 1;
+ width(main_p) = width(main_p) + extra_space(cur_font);
+ stretch(main_p) = xn_over_d(stretch(main_p), space_factor, 1000);
+ shrink(main_p) = xn_over_d(shrink(main_p), 1000, space_factor);
+ q = new_glue(main_p);
+ glue_ref_count(main_p) = null;
+/* so from now we have a subtype with spaces: */
+subtype(q) = space_skip_code + 1;
}
couple_nodes(tail, q);
tail = q;
@@ -1121,19 +1136,20 @@ used in at least one place where that would be a mistake.
@c
void append_glue(void)
{
- int s = cur_chr;
+ int s; /* modifier of skip command */
+ s = cur_chr;
switch (s) {
case fil_code:
- cur_val = new_glue(fil_glue);
+ cur_val = fil_glue;
break;
case fill_code:
- cur_val = new_glue(fill_glue);
+ cur_val = fill_glue;
break;
case ss_code:
- cur_val = new_glue(ss_glue);
+ cur_val = ss_glue;
break;
case fil_neg_code:
- cur_val = new_glue(fil_neg_glue);
+ cur_val = fil_neg_glue;
break;
case skip_code:
scan_glue(glue_val_level);
@@ -1141,12 +1157,12 @@ void append_glue(void)
case mskip_code:
scan_glue(mu_val_level);
break;
- }
- /* now |cur_val| points to the glue specification */
+ } /* now |cur_val| points to the glue specification */
tail_append(new_glue(cur_val));
- flush_node(cur_val);
- if (s > skip_code) {
- subtype(tail) = mu_glue;
+ if (s >= skip_code) {
+ decr(glue_ref_count(cur_val));
+ if (s > skip_code)
+ subtype(tail) = mu_glue;
}
}
@@ -1271,7 +1287,8 @@ void handle_right_brace(void)
break;
case insert_group:
end_graf(insert_group);
- q = new_glue(split_top_skip);
+ q = split_top_skip;
+ add_glue_ref(q);
d = split_max_depth;
f = floating_penalty;
unsave();
@@ -1289,7 +1306,7 @@ void handle_right_brace(void)
} else if (saved_type(0) == saved_adjust) {
tail_append(new_node(adjust_node, saved_value(0)));
adjust_ptr(tail) = list_ptr(p);
- flush_node(q);
+ delete_glue_ref(q);
} else {
confusion("insert_group");
}
@@ -2522,6 +2539,7 @@ void prefixed_command(void)
scan_glue(mu_val_level);
else
scan_glue(glue_val_level);
+ trap_zero_glue();
define(p, glue_ref_cmd, cur_val);
break;
case def_char_code_cmd:
@@ -2620,6 +2638,7 @@ void prefixed_command(void)
scan_dimen(false, false, false);
} else {
scan_glue(mu_val_level);
+ trap_zero_glue();
if (cur_val == glue_par(thin_mu_skip_code))
cur_val = thin_mu_skip_code;
else if (cur_val == glue_par(med_mu_skip_code))
@@ -2973,6 +2992,21 @@ void assign_internal_value(int a, halfword p, int val)
}
}
+@ When a glue register or parameter becomes zero, it will always point to
+|zero_glue| because of the following procedure. (Exception: The tabskip
+glue isn't trapped while preambles are being scanned.)
+
+@c
+void trap_zero_glue(void)
+{
+ if ((width(cur_val) == 0) && (stretch(cur_val) == 0)
+ && (shrink(cur_val) == 0)) {
+ add_glue_ref(zero_glue);
+ delete_glue_ref(cur_val);
+ cur_val = zero_glue;
+ }
+}
+
@ We use the fact that |register<advance<multiply<divide|
Compute the register location |l| and its type |p|; but |return| if invalid
@@ -3031,20 +3065,20 @@ void do_register_command(int a)
if (q == advance_cmd)
cur_val = cur_val + eqtb[l].cint;
} else {
- /* we can probably save a copy */
scan_glue(p);
if (q == advance_cmd) {
/* Compute the sum of two glue specs */
halfword r = equiv(l);
q = new_spec(cur_val);
- flush_node(cur_val);
+ delete_glue_ref(cur_val);
width(q) = width(q) + width(r);
if (stretch(q) == 0) {
stretch_order(q) = normal;
}
if (stretch_order(q) == stretch_order(r)) {
stretch(q) = stretch(q) + stretch(r);
- } else if ((stretch_order(q) < stretch_order(r)) && (stretch(r) != 0)) {
+ } else if ((stretch_order(q) < stretch_order(r))
+ && (stretch(r) != 0)) {
stretch(q) = stretch(r);
stretch_order(q) = stretch_order(r);
}
@@ -3053,7 +3087,8 @@ void do_register_command(int a)
}
if (shrink_order(q) == shrink_order(r)) {
shrink(q) = shrink(q) + shrink(r);
- } else if ((shrink_order(q) < shrink_order(r)) && (shrink(r) != 0)) {
+ } else if ((shrink_order(q) < shrink_order(r))
+ && (shrink(r) != 0)) {
shrink(q) = shrink(r);
shrink_order(q) = shrink_order(r);
}
@@ -3093,7 +3128,7 @@ void do_register_command(int a)
help2("I can't carry out that multiplication or division,",
"since the result is out of range.");
if (p >= glue_val_level)
- flush_node(cur_val);
+ delete_glue_ref(cur_val);
error();
return;
}
@@ -3108,6 +3143,7 @@ void do_register_command(int a)
else
word_define(l, cur_val);
} else {
+ trap_zero_glue();
define(l, glue_ref_cmd, cur_val);
}
}
@@ -3563,9 +3599,11 @@ void initialize(void)
set_equiv(glue_base, zero_glue);
set_eq_level(glue_base, level_one);
set_eq_type(glue_base, glue_ref_cmd);
- for (k = glue_base + 1; k <= local_base - 1; k++) {
+ for (k = glue_base + 1; k <= local_base - 1; k++)
eqtb[k] = eqtb[glue_base];
- }
+ glue_ref_count(zero_glue) =
+ glue_ref_count(zero_glue) + local_base - glue_base;
+
par_shape_ptr = null;
set_eq_type(par_shape_loc, shape_ref_cmd);
set_eq_level(par_shape_loc, level_one);
diff --git a/Build/source/texk/web2c/luatexdir/tex/mlist.w b/Build/source/texk/web2c/luatexdir/tex/mlist.w
index 0fc21de7ceb..5932a9f9dbe 100644
--- a/Build/source/texk/web2c/luatexdir/tex/mlist.w
+++ b/Build/source/texk/web2c/luatexdir/tex/mlist.w
@@ -1063,15 +1063,17 @@ static scaled stack_into_box(pointer b, internal_font_number f, int c)
}
static void stack_glue_into_box(pointer b, scaled min, scaled max) {
- halfword p = new_glue(zero_glue);
- width(p) = min;
- stretch(p) = max - min;
+ pointer p, q; /* new node placed into |b| */
+ q = new_spec(zero_glue);
+ width(q) = min;
+ stretch(q) = max-min;
+ p = new_glue(q);
reset_attributes(p, node_attr(b));
if (type(b) == vlist_node) {
try_couple_nodes(p,list_ptr(b));
list_ptr(b) = p;
} else {
- halfword q = list_ptr(b);
+ q = list_ptr(b);
if (q == null) {
list_ptr(b) = p;
} else {
@@ -1541,7 +1543,7 @@ static pointer math_glue(pointer g, scaled m)
decr(n);
f = f + unity;
}
- p = new_node(glue_node, 0);
+ p = new_node(glue_spec_node, 0);
width(p) = mu_mult(width(g)); /* convert \.{mu} to \.{pt} */
stretch_order(p) = stretch_order(g);
if (stretch_order(p) == normal)
@@ -1949,12 +1951,12 @@ static pointer wrapup_over_under_delimiter(pointer x, pointer y, pointer q, scal
#define fixup_widths(q,x,y) do { \
if (width(y) >= width(x)) { \
- if (radicalwidth(q) != 0) { \
+ if (radicalwidth(q) != zero_glue) { \
shift_amount(x) += half(width(y)-width(x)) ; \
} \
width(x) = width(y); \
} else { \
- if (radicalwidth(q) != 0) { \
+ if (radicalwidth(q) != zero_glue) { \
shift_amount(y) += half(width(x)-width(y)) ; \
} \
width(y) = width(x); \
@@ -1963,7 +1965,7 @@ static pointer wrapup_over_under_delimiter(pointer x, pointer y, pointer q, scal
#define check_radical(q,stack,r,t) do { \
- if (!stack && (width(r) >= width(t)) && (radicalwidth(q) != 0) && (radicalwidth(q) != width(r))) { \
+ if (!stack && (width(r) >= width(t)) && (radicalwidth(q) != zero_glue) && (radicalwidth(q) != width(r))) { \
if (radicalleft(q)) { \
halfword p = new_kern(radicalwidth(q)-width(r)); \
reset_attributes(p, node_attr(q)); \
@@ -1988,7 +1990,7 @@ static pointer wrapup_over_under_delimiter(pointer x, pointer y, pointer q, scal
} while (0)
#define check_widths(q,p) do { \
- if (radicalwidth(q) != 0) { \
+ if (radicalwidth(q) != zero_glue) { \
wd = radicalwidth(q); \
} else { \
wd = width(p); \
@@ -3708,11 +3710,13 @@ static pointer math_spacing_glue(int l_type, int r_type, int mstyle, scaled mmu)
/* trap thin/med/thick settings cf. old TeX */
y = math_glue(glue_par(x), mmu);
z = new_glue(y);
+ glue_ref_count(y) = null;
/* store a symbolic subtype */
subtype(z) = (quarterword) (x + 1);
} else {
y = math_glue(x, mmu);
z = new_glue(y);
+ glue_ref_count(y) = null;
}
}
return z;
@@ -3964,9 +3968,10 @@ void mlist_to_hlist(pointer mlist, boolean penalties, int cur_style)
*/
if (subtype(q) == mu_glue) {
- x = q; /* was ptr */
+ x = glue_ptr(q);
y = math_glue(x, cur_mu);
- q = y; /* we can get rid of the indirect */
+ delete_glue_ref(x);
+ glue_ptr(q) = y;
subtype(q) = normal;
} else if ((cur_size != text_size) && (subtype(q) == cond_math_glue)) {
p = vlink(q);
diff --git a/Build/source/texk/web2c/luatexdir/tex/packaging.w b/Build/source/texk/web2c/luatexdir/tex/packaging.w
index 5b9aa8b8995..0c474a50add 100644
--- a/Build/source/texk/web2c/luatexdir/tex/packaging.w
+++ b/Build/source/texk/web2c/luatexdir/tex/packaging.w
@@ -625,6 +625,7 @@ halfword hpack(halfword p, scaled w, int m, int pack_direction)
scaled x = 0; /* natural width */
scaled_whd whd;
scaled s; /* shift amount */
+ halfword g; /* points to a glue specification */
int o; /* order of infinity */
halfword dir_ptr1 = null; /* for managing the direction stack */
int hpack_dir; /* the current direction */
@@ -757,13 +758,14 @@ halfword hpack(halfword p, scaled w, int m, int pack_direction)
/* */
case glue_node:
/* Incorporate glue into the horizontal totals */
- x += width(p);
- o = stretch_order(p);
- total_stretch[o] = total_stretch[o] + stretch(p);
- o = shrink_order(p);
- total_shrink[o] = total_shrink[o] + shrink(p);
+ g = glue_ptr(p);
+ x += width(g);
+ o = stretch_order(g);
+ total_stretch[o] = total_stretch[o] + stretch(g);
+ o = shrink_order(g);
+ total_shrink[o] = total_shrink[o] + shrink(g);
if (subtype(p) >= a_leaders) {
- halfword g = leader_ptr(p);
+ g = leader_ptr(p);
if (height(g) > h)
h = height(g);
if (depth(g) > d)
@@ -815,7 +817,7 @@ halfword hpack(halfword p, scaled w, int m, int pack_direction)
break;
case math_node:
/* begin mathskip code */
- if (glue_is_zero(p)) {
+ if (glue_ptr(p) == zero_glue) {
x += surround(p);
break;
} else {
@@ -1196,7 +1198,7 @@ scaled_whd natural_sizes(halfword p, halfword pp, glue_ratio g_mult,
/* */
case math_node:
/* begin mathskip code */
- if (glue_is_zero(p)) {
+ if (glue_ptr(p) == zero_glue) {
siz.wd += surround(p);
break;
} else {
@@ -1204,14 +1206,15 @@ scaled_whd natural_sizes(halfword p, halfword pp, glue_ratio g_mult,
}
/* end mathskip code */
case glue_node:
- siz.wd += width(p);
+ g = glue_ptr(p);
+ siz.wd += width(g);
if (g_sign != normal) {
if (g_sign == stretching) {
- if (stretch_order(p) == g_order) {
- siz.wd += float_round(float_cast(g_mult) * float_cast(stretch(p)));
+ if (stretch_order(g) == g_order) {
+ siz.wd += float_round(float_cast(g_mult) * float_cast(stretch(g)));
}
- } else if (shrink_order(p) == g_order) {
- siz.wd -= float_round(float_cast(g_mult) * float_cast(shrink(p)));
+ } else if (shrink_order(g) == g_order) {
+ siz.wd -= float_round(float_cast(g_mult) * float_cast(shrink(g)));
}
}
if (subtype(p) >= a_leaders) {
@@ -1273,6 +1276,7 @@ halfword vpackage(halfword p, scaled h, int m, scaled l, int pack_direction)
scaled x = 0; /* natural height */
scaled_whd whd;
scaled s; /* shift amount */
+ halfword g; /* points to a glue specification */
int o; /* order of infinity */
last_badness = 0;
r = new_node(vlist_node, 0);
@@ -1343,13 +1347,14 @@ halfword vpackage(halfword p, scaled h, int m, scaled l, int pack_direction)
/* Incorporate glue into the vertical totals */
x += d;
d = 0;
- x += width(p);
- o = stretch_order(p);
- total_stretch[o] = total_stretch[o] + stretch(p);
- o = shrink_order(p);
- total_shrink[o] = total_shrink[o] + shrink(p);
+ g = glue_ptr(p);
+ x += width(g);
+ o = stretch_order(g);
+ total_stretch[o] = total_stretch[o] + stretch(g);
+ o = shrink_order(g);
+ total_shrink[o] = total_shrink[o] + shrink(g);
if (subtype(p) >= a_leaders) {
- halfword g = leader_ptr(p);
+ g = leader_ptr(p);
if (width(g) > w)
w = width(g);
}
@@ -1638,7 +1643,8 @@ void append_to_vlist(halfword b, int location)
p = new_param_glue(line_skip_code);
} else {
p = new_skip_param(baseline_skip_code);
- width(p) = d;
+ /* |temp_ptr=glue_ptr(p)| */
+ width(temp_ptr) = d;
}
couple_nodes(cur_list.tail_field, p);
cur_list.tail_field = p;
@@ -1696,10 +1702,11 @@ halfword prune_page_top(halfword p, boolean s)
q = new_skip_param(split_top_skip_code);
vlink(prev_p) = q;
vlink(q) = p;
- if (width(q) > height(p))
- width(q) = width(q) - height(p);
+ /* now |temp_ptr=glue_ptr(q)| */
+ if (width(temp_ptr) > height(p))
+ width(temp_ptr) = width(temp_ptr) - height(p);
else
- width(q) = 0;
+ width(temp_ptr) = 0;
p = null;
break;
case boundary_node:
@@ -1768,6 +1775,7 @@ halfword vert_break(halfword p, scaled h, scaled d)
{
halfword prev_p = p; /* if |p| is a glue node, |type(prev_p)| determines whether |p| is a
legal breakpoint, an initial glue node is not a legal breakpoint */
+ halfword q, r; /* glue specifications */
int pi = 0; /* penalty value */
int b; /* badness at a trial breakpoint */
int t; /* |type| of the node following a kern */
@@ -1873,20 +1881,27 @@ halfword vert_break(halfword p, scaled h, scaled d)
contain infinite shrinkability, since that would permit any amount of
information to ``fit'' on one page. */
- if (type(p) != kern_node) {
- active_height[2 + stretch_order(p)] += stretch(p);
- active_height[7] += shrink(p);
- if ((shrink_order(p) != normal) && (shrink(p) != 0)) {
+ if (type(p) == kern_node) {
+ q = p;
+ } else {
+ q = glue_ptr(p);
+ active_height[2 + stretch_order(q)] += stretch(q);
+ active_height[7] += shrink(q);
+ if ((shrink_order(q) != normal) && (shrink(q) != 0)) {
print_err("Infinite glue shrinkage found in box being split");
help4("The box you are \\vsplitting contains some infinitely",
"shrinkable glue, e.g., `\\vss' or `\\vskip 0pt minus 1fil'.",
"Such glue doesn't belong there; but you can safely proceed,",
"since the offensive shrinkability has been made finite.");
error();
- shrink_order(p) = normal;
+ r = new_spec(q);
+ shrink_order(r) = normal;
+ delete_glue_ref(q);
+ glue_ptr(p) = r;
+ q = r;
}
}
- cur_height = cur_height + prev_dp + width(p);
+ cur_height = cur_height + prev_dp + width(q);
prev_dp = 0;
NOT_FOUND:
if (prev_dp > d) {
diff --git a/Build/source/texk/web2c/luatexdir/tex/postlinebreak.w b/Build/source/texk/web2c/luatexdir/tex/postlinebreak.w
index fe11d76d0b1..43ceadcca28 100644
--- a/Build/source/texk/web2c/luatexdir/tex/postlinebreak.w
+++ b/Build/source/texk/web2c/luatexdir/tex/postlinebreak.w
@@ -163,7 +163,10 @@ void ext_post_line_break(int paragraph_dir,
while(q != null) {
if (type(q) == math_node) {
surround(q) = 0 ;
- reset_glue_to_zero(q);
+ if (glue_ptr(q) != zero_glue) {
+ delete_glue_ref(glue_ptr(q));
+ glue_ptr(q) = zero_glue;
+ }
break;
} else if ((type(q) == hlist_node) && (subtype(q) == indent_list)) {
/* go on */
@@ -199,11 +202,16 @@ void ext_post_line_break(int paragraph_dir,
} else if (type(r) == math_node) {
surround(r) = 0;
/* begin mathskip code */
- reset_glue_to_zero(r);
+ if (glue_ptr(r) != zero_glue) {
+ delete_glue_ref(glue_ptr(r));
+ glue_ptr(r) = zero_glue;
+ }
/* end mathskip code */
} else if (type(r) == glue_node) {
- copy_glue_values(r,right_skip);
+ delete_glue_ref(glue_ptr(r));
+ glue_ptr(r) = right_skip;
subtype(r) = right_skip_code + 1;
+ incr(glue_ref_count(right_skip));
glue_break = true;
/* |q| refers to the last node of the line */
q = r;
@@ -349,8 +357,9 @@ void ext_post_line_break(int paragraph_dir,
then we append |rightskip| after |q| now */
if (!glue_break) {
/* Put the \.{\\rightskip} glue after node |q|; */
- halfword r1 = new_glue((right_skip == null ? zero_glue : right_skip));
- subtype(r1) = right_skip_code+1;
+ halfword r1 = new_glue((right_skip == null ? null : copy_node(right_skip)));
+ glue_ref_count(glue_ptr(r1)) = null;
+ subtype(r1) = right_skip_code+1;
try_couple_nodes(r1,vlink(q));
delete_attribute_ref(node_attr(r1));
node_attr(r1) = node_attr(q);
@@ -390,7 +399,7 @@ void ext_post_line_break(int paragraph_dir,
}
/*at this point |q| is the leftmost node; all discardable nodes have been discarded */
if (protrude_chars > 0) {
- halfword p;
+ halfword p;
p = q;
p = find_protchar_left(p, false); /* no more discardables */
w = char_pw(p, left_side);
@@ -403,8 +412,9 @@ void ext_post_line_break(int paragraph_dir,
q = k;
}
}
- if (! glue_is_zero(left_skip)) {
- r = new_glue(left_skip);
+ if (left_skip != zero_glue) {
+ r = new_glue(copy_node(left_skip));
+ glue_ref_count(glue_ptr(r)) = null;
subtype(r) = left_skip_code+1;
delete_attribute_ref(node_attr(r));
node_attr(r) = node_attr(q);
@@ -552,7 +562,11 @@ void ext_post_line_break(int paragraph_dir,
if (type(q) == math_node) {
/* begin mathskip code */
surround(q) = 0 ;
- reset_glue_to_zero(q);
+ if (glue_ptr(q) != zero_glue) {
+ delete_glue_ref(glue_ptr(q));
+ glue_ptr(q) = zero_glue;
+ add_glue_ref(glue_ptr(q));
+ }
/* end mathskip code */
}
if (q == cur_break(cur_p)) {
diff --git a/Build/source/texk/web2c/luatexdir/tex/scanning.w b/Build/source/texk/web2c/luatexdir/tex/scanning.w
index 907d25f5bac..90499e8b4e5 100644
--- a/Build/source/texk/web2c/luatexdir/tex/scanning.w
+++ b/Build/source/texk/web2c/luatexdir/tex/scanning.w
@@ -139,10 +139,10 @@ int cur_val; /* value returned by numeric scanners */
int cur_val1; /* delcodes are sometimes 51 digits */
int cur_val_level; /* the ``level'' of this value */
-#define scanned_result(A,B) do { \
- cur_val=A; \
- cur_val_level=B; \
-} while (0)
+#define scanned_result(A,B) do { \
+ cur_val=A; \
+ cur_val_level=B; \
+ } while (0)
@ When a |glue_val| changes to a |dimen_val|, we use the width component
of the glue; there is no need to decrease the reference count, since it
@@ -158,7 +158,7 @@ static void downgrade_cur_val(boolean delete_glue)
m = cur_val;
cur_val = width(m);
if (delete_glue)
- flush_node(m);
+ delete_glue_ref(m);
} else if (cur_val_level == mu_val_level) {
mu_error();
}
@@ -172,7 +172,7 @@ static void negate_cur_val(boolean delete_glue)
m = cur_val;
cur_val = new_spec(m);
if (delete_glue)
- flush_node(m);
+ delete_glue_ref(m);
/* Negate all three glue components of |cur_val| */
negate(width(cur_val));
negate(stretch(cur_val));
@@ -215,11 +215,9 @@ static boolean short_scan_something_internal(int cmd, int chr, int level,
break;
case assign_glue_cmd:
scanned_result(equiv(m), glue_val_level);
-// cur_val = new_spec(cur_val);
break;
case assign_mu_glue_cmd:
scanned_result(equiv(m), mu_val_level);
-// cur_val = new_spec(cur_val);
break;
case math_style_cmd:
scanned_result(m, int_val_level);
@@ -403,7 +401,7 @@ static boolean short_scan_something_internal(int cmd, int chr, int level,
cur_val = stretch(q);
else
cur_val = shrink(q);
- flush_node(q);
+ delete_glue_ref(q);
break;
} /* there are no other cases */
cur_val_level = dimen_val_level;
@@ -480,7 +478,7 @@ static boolean short_scan_something_internal(int cmd, int chr, int level,
cur_val = stretch_order(q);
else
cur_val = shrink_order(q);
- flush_node(q);
+ delete_glue_ref(q);
break;
} /* there are no other cases */
cur_val_level = int_val_level;
@@ -512,7 +510,7 @@ static boolean short_scan_something_internal(int cmd, int chr, int level,
break;
case lastskip_code:
if (type(cur_list.tail_field) == glue_node)
- cur_val = new_glue(cur_list.tail_field);
+ cur_val = glue_ptr(cur_list.tail_field);
if (subtype(cur_list.tail_field) == mu_glue)
cur_val_level = mu_val_level;
break;
@@ -531,7 +529,7 @@ static boolean short_scan_something_internal(int cmd, int chr, int level,
break;
case lastskip_code:
if (last_glue != max_halfword)
- cur_val = last_glue; /* maybe new_glue */
+ cur_val = last_glue;
break;
case last_node_type_code:
cur_val = last_node_type;
@@ -556,8 +554,9 @@ static boolean short_scan_something_internal(int cmd, int chr, int level,
*/
if (negative) {
negate_cur_val(false);
- } else if ((cur_val_level >= glue_val_level) && (cur_val_level <= mu_val_level)) {
- cur_val = new_glue(cur_val);
+ } else if ((cur_val_level >= glue_val_level)
+ && (cur_val_level <= mu_val_level)) {
+ add_glue_ref(cur_val);
}
}
return succeeded;
@@ -854,8 +853,9 @@ void scan_something_internal(int level, boolean negative)
*/
if (negative) {
negate_cur_val(false);
- } else if ((cur_val_level >= glue_val_level) && (cur_val_level <= mu_val_level)) {
- cur_val = new_glue(cur_val);
+ } else if ((cur_val_level >= glue_val_level) &&
+ (cur_val_level <= mu_val_level)) {
+ add_glue_ref(cur_val);
}
}
}
@@ -1103,7 +1103,7 @@ static void coerce_glue(void)
int v;
if (cur_val_level >= glue_val_level) {
v = width(cur_val);
- flush_node(cur_val);
+ delete_glue_ref(cur_val);
cur_val = v;
}
}
@@ -1513,18 +1513,36 @@ void scan_glue(int level)
Create a new glue specification whose width is |cur_val|; scan for its
stretch and shrink components.
*/
- q = new_spec(zero_glue);
- width(q) = cur_val;
+ /*
+ In several places there is a test for zero glue, for instance in protrusion
+ left/right node detection. In that case a \hskip\dimen<n> with the dimen being
+ zero will not be seen as zero glue. Therefore we delay the allocation of
+ glue till we know for sure that there are no fils involved. (!!)
+ */
+ if (cur_val != 0) { /* !! new test */
+ q = new_spec(zero_glue);
+ width(q) = cur_val;
+ }
if (scan_keyword("plus")) {
+ if (q == null) { /* !! new test */
+ q = new_spec(zero_glue);
+ }
scan_dimen(mu, true, false);
stretch(q) = cur_val;
stretch_order(q) = (quarterword) cur_order;
}
if (scan_keyword("minus")) {
+ if (q == null) { /* !! new test */
+ q = new_spec(zero_glue);
+ }
scan_dimen(mu, true, false);
shrink(q) = cur_val;
shrink_order(q) = (quarterword) cur_order;
}
+ if (q == null) { /* !! new test */
+ q = zero_glue ;
+ add_glue_ref(zero_glue);
+ }
cur_val = q;
}
@@ -1680,11 +1698,11 @@ halfword the_toks(void)
break;
case glue_val_level:
print_spec(cur_val, "pt");
- flush_node(cur_val);
+ delete_glue_ref(cur_val);
break;
case mu_val_level:
print_spec(cur_val, "mu");
- flush_node(cur_val);
+ delete_glue_ref(cur_val);
break;
} /* there are no other cases */
selector = old_setting;
@@ -1726,11 +1744,11 @@ str_number the_scanned_result(void)
break;
case glue_val_level:
print_spec(cur_val, "pt");
- flush_node(cur_val);
+ delete_glue_ref(cur_val);
break;
case mu_val_level:
print_spec(cur_val, "mu");
- flush_node(cur_val);
+ delete_glue_ref(cur_val);
break;
} /* there are no other cases */
r = make_string();
@@ -2185,7 +2203,8 @@ typedef enum {
@c
#define glue_error(A) do { \
arith_error=true; \
- reset_glue_to_zero(A); \
+ delete_glue_ref(A); \
+ A=new_spec(zero_glue); \
} while (0)
#define normalize_glue(A) do { \
@@ -2491,11 +2510,9 @@ static void scan_expr(void)
unless the next operator is a right parenthesis; this allows us later on
to simply modify the glue components.
*/
- t = f;
if ((l >= glue_val_level) && (o != expr_none)) {
- /* do we really need to copy here ? */
t = new_spec(f);
- flush_node(f);
+ delete_glue_ref(f);
normalize_glue(t);
} else {
t = f;
@@ -2571,7 +2588,7 @@ static void scan_expr(void)
shrink(e) = shrink(t);
shrink_order(e) = shrink_order(t);
}
- flush_node(t);
+ delete_glue_ref(t);
normalize_glue(e);
}
r = o;
@@ -2600,7 +2617,9 @@ static void scan_expr(void)
"since the result is out of range.");
error();
if (l >= glue_val_level) {
- reset_glue_to_zero(e);
+ delete_glue_ref(e);
+ e = zero_glue;
+ add_glue_ref(e);
} else {
e = 0;
}
diff --git a/Build/source/texk/web2c/luatexdir/tex/texmath.w b/Build/source/texk/web2c/luatexdir/tex/texmath.w
index 5067764fbf9..216d2364984 100644
--- a/Build/source/texk/web2c/luatexdir/tex/texmath.w
+++ b/Build/source/texk/web2c/luatexdir/tex/texmath.w
@@ -2454,8 +2454,9 @@ void after_math(void)
}
tail_append(new_math(math_surround, before));
/* begin mathskip code */
- if (! glue_is_zero(math_skip)) {
- copy_glue_values(tail,math_skip);
+ if (math_skip != zero_glue) {
+ glue_ptr(tail) = math_skip;
+ add_glue_ref(math_skip);
}
/* end mathskip code */
if (dir_math_save) {
@@ -2463,17 +2464,17 @@ void after_math(void)
}
run_mlist_to_hlist(p, (mode > 0), text_style);
vlink(tail) = vlink(temp_head);
- while (vlink(tail) != null) {
+ while (vlink(tail) != null)
tail = vlink(tail);
- }
if (dir_math_save) {
tail_append(new_dir(math_direction - dir_swap));
}
dir_math_save = false;
tail_append(new_math(math_surround, after));
/* begin mathskip code */
- if (! glue_is_zero(math_skip)) {
- copy_glue_values(tail,math_skip);
+ if (math_skip != zero_glue) {
+ glue_ptr(tail) = math_skip;
+ add_glue_ref(math_skip);
}
/* end mathskip code */
space_factor = 1000;
diff --git a/Build/source/texk/web2c/luatexdir/tex/texnodes.h b/Build/source/texk/web2c/luatexdir/tex/texnodes.h
index 0da84945184..1f1a4e82964 100644
--- a/Build/source/texk/web2c/luatexdir/tex/texnodes.h
+++ b/Build/source/texk/web2c/luatexdir/tex/texnodes.h
@@ -68,6 +68,8 @@ extern void undump_node_mem(void);
# define rlink(a) vlink((a)+1) /* aka alink() */
# define tlink(a) vinfo((a)+1) /* overlaps with node_attr() */
+# define add_glue_ref(a) glue_ref_count(a)++ /* new reference to a glue spec */
+
/* really special head node pointers that only need links */
# define temp_node_size 2
@@ -104,6 +106,15 @@ extern void update_attribute_cache(void);
extern halfword copy_attribute_list(halfword n);
extern halfword do_set_attribute(halfword p, int i, int val);
+/* a glue spec */
+# define glue_spec_size 4
+# define stretch(a) vlink((a)+1)
+/* width == a+2 */
+# define shrink(a) vinfo((a)+1)
+# define stretch_order(a) type((a)+3)
+# define shrink_order(a) subtype((a)+3)
+# define glue_ref_count(a) vlink((a)+3)
+
# define width_offset 2
# define depth_offset 3
# define height_offset 4
@@ -127,53 +138,11 @@ typedef enum {
# define penalty_node_size 3
# define penalty(a) vlink((a)+2)
-/*
# define glue_node_size 4
# define glue_ptr(a) vinfo((a)+2)
# define leader_ptr(a) vlink((a)+2)
# define synctex_tag_glue(a) vinfo((a)+3)
# define synctex_line_glue(a) vlink((a)+3)
-*/
-
-# define glue_node_size 7
-# define glue_spec_size 5
-/* define width(a) vinfo((a)+2) */
-/* define leader_ptr(a) vlink((a)+2) */
-# define shrink(a) vinfo((a)+3)
-# define stretch(a) vlink((a)+3)
-# define stretch_order(a) vinfo((a)+4)
-# define shrink_order(a) vlink((a)+4)
-# define leader_ptr(a) vlink((a)+5) /* should be in vlink((a)+2) but fails */
-# define synctex_tag_glue(a) vinfo((a)+6)
-# define synctex_line_glue(a) vlink((a)+6)
-
-#define glue_is_zero(p) \
- ((p == null) || (width(p) == 0 && stretch(p) == 0 && shrink(p) == 0))
-
-#define reset_glue_to_zero(p) \
- if (p != null) { \
- width(p) = 0; \
- stretch(p) = 0; \
- shrink(p) = 0; \
- stretch_order(p) = 0; \
- shrink_order(p) = 0; \
- }
-
-#define copy_glue_values(p,q) \
- if (q == null) { \
- width(p) = 0; \
- stretch(p) = 0; \
- shrink(p) = 0; \
- stretch_order(p) = 0; \
- shrink_order(p) = 0; \
- } else { \
- width(p) = width(q); \
- stretch(p) = stretch(q); \
- shrink(p) = shrink(q); \
- stretch_order(p) = stretch_order(q); \
- shrink_order(p) = shrink_order(q); \
- }
-
/*
disc nodes could eventually be smaller, because the indirect
@@ -313,17 +282,11 @@ typedef enum {
# define before 0 /* |subtype| for math node that introduces a formula */
# define after 1 /* |subtype| for math node that winds up a formula */
-# define math_node_size 7
-/* define width(a) vinfo((a)+2) */
-/* overlaps width */
-/* define shrink(a) vinfo((a)+3) */
-/* define stretch(a) vlink((a)+3) */
-/* define stretch_order(a) vinfo((a)+4) */
-/* define shrink_order(a) vlink((a)+4) */
-/* leader_ptr slot */
-# define surround(a) vinfo((a)+5)
-# define synctex_tag_math(a) vinfo((a)+6)
-# define synctex_line_math(a) vlink((a)+6)
+# define math_node_size 4
+# define surround(a) vlink((a)+2)
+/* also: glue_ptr(a) vinfo((a)+2) */
+# define synctex_tag_math(a) vinfo((a)+3)
+# define synctex_line_math(a) vlink((a)+3)
# define ins_node_size 6
# define float_cost(a) varmem[(a)+2].cint
@@ -657,13 +620,15 @@ typedef enum {
# define special_node_size 3
-# define dir_node_size 5
+# define dir_node_size 6
# define dir_dir(a) vinfo((a)+2)
# define dir_level(a) vlink((a)+2)
-# define dir_refpos_h(a) vinfo((a)+3)
-# define dir_refpos_v(a) vlink((a)+3)
-# define dir_cur_h(a) vinfo((a)+4)
-# define dir_cur_v(a) vlink((a)+4)
+# define dir_dvi_ptr(a) vinfo((a)+3)
+# define dir_dvi_h(a) vlink((a)+3) /* obsolete */
+# define dir_refpos_h(a) vinfo((a)+4)
+# define dir_refpos_v(a) vlink((a)+4)
+# define dir_cur_h(a) vinfo((a)+5)
+# define dir_cur_v(a) vlink((a)+5)
# define write_node_size 3
# define close_node_size 3
@@ -945,8 +910,10 @@ typedef enum {
# define is_running(A) ((A)==null_flag) /* tests for a running dimension */
extern halfword tail_of_list(halfword p);
+extern void delete_glue_ref(halfword p);
extern int var_used;
+extern halfword temp_ptr;
# define cache_disabled max_halfword
diff --git a/Build/source/texk/web2c/luatexdir/tex/texnodes.w b/Build/source/texk/web2c/luatexdir/tex/texnodes.w
index 77610988d95..a201c6da714 100644
--- a/Build/source/texk/web2c/luatexdir/tex/texnodes.w
+++ b/Build/source/texk/web2c/luatexdir/tex/texnodes.w
@@ -89,10 +89,10 @@ const char *node_fields_disc[] = {
"attr", "pre", "post", "replace", "penalty", NULL
};
const char *node_fields_math[] = {
- "attr", "surround", "width", "stretch", "shrink", "stretch_order", "shrink_order", NULL
+ "attr", "surround", NULL
};
const char *node_fields_glue[] = {
- "attr", "leader", "width", "stretch", "shrink", "stretch_order", "shrink_order", NULL
+ "attr", "spec", "leader", NULL
};
const char *node_fields_kern[] = {
"attr", "kern", "expansion_factor", NULL
@@ -112,8 +112,7 @@ const char *node_fields_glyph[] = {
"xoffset", "yoffset", "width", "height", "depth", "expansion_factor", NULL
};
const char *node_fields_inserting[] = {
- "height", "last_ins_ptr", "best_ins_ptr",
- "width", "stretch", "shrink", "stretch_order", "shrink_order", NULL
+ "height", "last_ins_ptr", "best_ins_ptr", NULL
};
const char *node_fields_splitup[] = {
"height", "last_ins_ptr", "best_ins_ptr", "broken_ptr", "broken_ins", NULL
@@ -122,7 +121,8 @@ const char *node_fields_attribute[] = {
"number", "value", NULL
};
const char *node_fields_glue_spec[] = {
- "width", "stretch", "shrink", "stretch_order", "shrink_order", NULL
+ "width", "stretch", "shrink", "stretch_order", "shrink_order", "ref_count",
+ "writable", NULL
};
const char *node_fields_attribute_list[] = {
NULL
@@ -132,7 +132,7 @@ const char *node_fields_local_par[] = {
"box_right", "box_right_width", NULL
};
const char *node_fields_dir[] = {
- "attr", "dir", "level", NULL
+ "attr", "dir", "level", "dvi_ptr", "dvi_h", NULL
};
const char *node_fields_boundary[] = {
"attr", "value", NULL
@@ -620,6 +620,7 @@ static int test_count = 1;
} } while (0)
#define check_action_ref(a) { dorangetest(p,a,var_mem_max); }
+#define check_glue_ref(a) { dorangetest(p,a,var_mem_max); }
#define check_attribute_ref(a) { dorangetest(p,a,var_mem_max); }
#define check_token_ref(a) { confusion("fuzzy token cleanup in node"); }
@@ -1077,6 +1078,7 @@ halfword copy_node(const halfword p)
copy_sub_list(lig_ptr(r),lig_ptr(p)) ;
break;
case glue_node:
+ add_glue_ref(glue_ptr(p));
copy_sub_list(leader_ptr(r),leader_ptr(p)) ;
break;
case hlist_node:
@@ -1114,8 +1116,12 @@ halfword copy_node(const halfword p)
}
break;
case math_node:
+ if (glue_ptr(p) != zero_glue) {
+ add_glue_ref(glue_ptr(p));
+ }
break;
case ins_node:
+ add_glue_ref(split_top_ptr(p));
copy_sub_list(ins_ptr(r),ins_ptr(p)) ;
break;
case margin_kern_node:
@@ -1167,6 +1173,8 @@ halfword copy_node(const halfword p)
copy_sub_node(right_delimiter(r),right_delimiter(p)) ;
break;
case glue_spec_node:
+ glue_ref_count(r) = null;
+ break;
case dir_node:
case local_par_node:
case boundary_node:
@@ -1312,6 +1320,7 @@ void flush_node(halfword p)
free_sub_list(lig_ptr(p));
break;
case glue_node:
+ delete_glue_ref(glue_ptr(p));
free_sub_list(leader_ptr(p));
break;
case hlist_node:
@@ -1328,14 +1337,24 @@ void flush_node(halfword p)
case rule_node:
case kern_node:
case penalty_node:
+ break;
case math_node:
+ /* begin mathskip code */
+ if (glue_ptr(p) != zero_glue) {
+ delete_glue_ref(glue_ptr(p));
+ }
+ /* end mathskip code */
break;
case glue_spec_node:
/* this allows free-ing of lua-allocated glue specs */
-//if (valid_node(p)) {
-// free_node(p, subtype(p));
-//}
-// return ;
+ if (valid_node(p)) {
+ if (glue_ref_count(p)!=null) {
+ decr(glue_ref_count(p));
+ } else {
+ free_node(p, get_node_size(type(p), subtype(p)));
+ }
+ }
+ return ;
break ;
case dir_node:
case local_par_node:
@@ -1353,6 +1372,7 @@ void flush_node(halfword p)
break;
case ins_node:
flush_node_list(ins_ptr(p));
+ delete_glue_ref(split_top_ptr(p));
break;
case margin_kern_node:
flush_node(margin_char(p));
@@ -1559,6 +1579,7 @@ void check_node(halfword p)
dorangetest(p, lig_ptr(p), var_mem_max);
break;
case glue_node:
+ check_glue_ref(glue_ptr(p));
dorangetest(p, leader_ptr(p), var_mem_max);
break;
case hlist_node:
@@ -1569,6 +1590,7 @@ void check_node(halfword p)
break;
case ins_node:
dorangetest(p, ins_ptr(p), var_mem_max);
+ check_glue_ref(split_top_ptr(p));
break;
case whatsit_node:
w = subtype(p) ;
@@ -1584,6 +1606,11 @@ void check_node(halfword p)
check_node(margin_char(p));
break;
case math_node:
+ /* begin mathskip code */
+ if (glue_ptr(p) != zero_glue) {
+ check_glue_ref(glue_ptr(p));
+ }
+ /* end mathskip code */
break;
case disc_node:
dorangetest(p, vlink(pre_break(p)), var_mem_max);
@@ -1777,6 +1804,7 @@ void init_node_mem(int t)
node_size(rover) = (t - rover);
var_used = 0;
/* initialize static glue specs */
+ glue_ref_count(zero_glue) = null + 1;
width(zero_glue) = 0;
type(zero_glue) = glue_spec_node;
vlink(zero_glue) = null;
@@ -1784,6 +1812,7 @@ void init_node_mem(int t)
stretch_order(zero_glue) = normal;
shrink(zero_glue) = 0;
shrink_order(zero_glue) = normal;
+ glue_ref_count(sfi_glue) = null + 1;
width(sfi_glue) = 0;
type(sfi_glue) = glue_spec_node;
vlink(sfi_glue) = null;
@@ -1791,6 +1820,7 @@ void init_node_mem(int t)
stretch_order(sfi_glue) = sfi;
shrink(sfi_glue) = 0;
shrink_order(sfi_glue) = normal;
+ glue_ref_count(fil_glue) = null + 1;
width(fil_glue) = 0;
type(fil_glue) = glue_spec_node;
vlink(fil_glue) = null;
@@ -1798,6 +1828,7 @@ void init_node_mem(int t)
stretch_order(fil_glue) = fil;
shrink(fil_glue) = 0;
shrink_order(fil_glue) = normal;
+ glue_ref_count(fill_glue) = null + 1;
width(fill_glue) = 0;
type(fill_glue) = glue_spec_node;
vlink(fill_glue) = null;
@@ -1805,6 +1836,7 @@ void init_node_mem(int t)
stretch_order(fill_glue) = fill;
shrink(fill_glue) = 0;
shrink_order(fill_glue) = normal;
+ glue_ref_count(ss_glue) = null + 1;
width(ss_glue) = 0;
type(ss_glue) = glue_spec_node;
vlink(ss_glue) = null;
@@ -1812,6 +1844,7 @@ void init_node_mem(int t)
stretch_order(ss_glue) = fil;
shrink(ss_glue) = unity;
shrink_order(ss_glue) = fil;
+ glue_ref_count(fil_neg_glue) = null + 1;
width(fil_neg_glue) = 0;
type(fil_neg_glue) = glue_spec_node;
vlink(fil_neg_glue) = null;
@@ -2474,7 +2507,7 @@ void print_short_node_contents(halfword p)
print_char('|');
break;
case glue_node:
- if (! glue_is_zero(p))
+ if (glue_ptr(p) != zero_glue)
print_char(' ');
break;
case math_node:
@@ -3015,7 +3048,7 @@ void show_node_list(int p)
normal_warning("nodes","weird glue leader subtype ignored");
}
tprint("leaders ");
- print_spec(p, NULL);
+ print_spec(glue_ptr(p), NULL);
node_list_display(leader_ptr(p)); /* recursive call */
} else {
tprint_esc("glue");
@@ -3037,9 +3070,9 @@ void show_node_list(int p)
if (subtype(p) != cond_math_glue) {
print_char(' ');
if (subtype(p) < cond_math_glue)
- print_spec(p, NULL);
+ print_spec(glue_ptr(p), NULL);
else
- print_spec(p, "mu");
+ print_spec(glue_ptr(p), "mu");
}
}
break;
@@ -3136,6 +3169,7 @@ void show_node_list(int p)
@c
pointer actual_box_width(pointer r, scaled base_width)
{
+ pointer q; /* glue specification when calculating |pre_display_size| */
scaled d; /* increment to |v| */
scaled w = -max_dimen; /* calculated |size| */
scaled v = shift_amount(r) + base_width; /* |w| plus possible glue amount */
@@ -3160,7 +3194,7 @@ pointer actual_box_width(pointer r, scaled base_width)
break;
case math_node:
/* begin mathskip code */
- if (glue_is_zero(p)) {
+ if (glue_ptr(p) == zero_glue) {
d = surround(p);
break;
} else {
@@ -3174,12 +3208,15 @@ pointer actual_box_width(pointer r, scaled base_width)
|pre_display_size|, since \TeX82 is supposed to make the same decisions on all
machines.
*/
- d = width(p);
+ q = glue_ptr(p);
+ d = width(q);
if (glue_sign(r) == stretching) {
- if ((glue_order(r) == stretch_order(p)) && (stretch(p) != 0))
+ if ((glue_order(r) == stretch_order(q))
+ && (stretch(q) != 0))
v = max_dimen;
} else if (glue_sign(r) == shrinking) {
- if ((glue_order(r) == shrink_order(p)) && (shrink(p) != 0))
+ if ((glue_order(r) == shrink_order(q))
+ && (shrink(q) != 0))
v = max_dimen;
}
if (subtype(p) >= a_leaders)
@@ -3215,10 +3252,26 @@ halfword tail_of_list(halfword p)
return q;
}
+@ |delete_glue_ref| is called when a pointer to a glue
+ specification is being withdrawn.
+@c
+void delete_glue_ref(halfword p)
+{ /* |p| points to a glue specification */
+ if (type(p) == glue_spec_node) {
+ if (glue_ref_count(p) == null) {
+ flush_node(p);
+ } else {
+ decr(glue_ref_count(p));
+ }
+ } else {
+ normal_error("nodes","invalid glue spec node");
+ }
+}
@ @c
int var_used;
+halfword temp_ptr; /* a pointer variable for occasional emergency use */
@ Attribute lists need two extra globals to increase processing efficiency.
|max_used_attr| limits the test loop that checks for set attributes, and
@@ -3532,8 +3585,10 @@ to be exactly one reference to the new specification.
@c
halfword new_spec(halfword p)
-{
- return copy_node(p == null ? zero_glue : p);
+{ /* duplicates a glue specification */
+ halfword q = copy_node(p);
+ glue_ref_count(q) = null;
+ return q;
}
@ And here's a function that creates a glue node for a given parameter
@@ -3546,11 +3601,8 @@ halfword new_param_glue(int n)
{
halfword p = new_node(glue_node, n + 1);
halfword q = glue_par(n);
- width(p) = width(q);
- stretch(p) = stretch(q);
- shrink(p) = shrink(q);
- stretch_order(p) = stretch_order(q);
- shrink_order(p) = shrink_order(q);
+ glue_ptr(p) = q;
+ incr(glue_ref_count(q));
return p;
}
@@ -3561,11 +3613,8 @@ whose argument points to a glue specification.
halfword new_glue(halfword q)
{
halfword p = new_node(glue_node, normal);
- width(p) = width(q);
- stretch(p) = stretch(q);
- shrink(p) = shrink(q);
- stretch_order(p) = stretch_order(q);
- shrink_order(p) = shrink_order(q);
+ glue_ptr(p) = q;
+ incr(glue_ref_count(q));
return p;
}
@@ -3573,22 +3622,17 @@ halfword new_glue(halfword q)
of |new_param_glue| and |new_glue|. It creates a glue node for one of
the current glue parameters, but it makes a fresh copy of the glue
specification, since that specification will probably be subject to change,
-while the parameter will stay put.
-
-/*
- The global variable |temp_ptr| is set to the address of the new spec.
-*/
+while the parameter will stay put. The global variable |temp_ptr| is
+set to the address of the new spec.
@c
halfword new_skip_param(int n)
{
- halfword p = new_node(glue_node, n + 1);
- halfword q = glue_par(n);
- width(p) = width(q);
- stretch(p) = stretch(q);
- shrink(p) = shrink(q);
- stretch_order(p) = stretch_order(q);
- shrink_order(p) = shrink_order(q);
+ halfword p; /* the new node */
+ temp_ptr = new_spec(glue_par(n));
+ p = new_glue(temp_ptr);
+ glue_ref_count(temp_ptr) = null;
+ subtype(p) = (quarterword) (n + 1);
return p;
}