1 /* Copyright 2014 Clerk Ma
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or
6 (at your option) any later version.
8 This program is distributed in the hope that it will be useful, but
9 WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 halfword rebox_(halfword b, scaled w)
26 internal_font_number f;
29 if ((width(b) != w) && (list_ptr(b) != 0))
31 if (type(b) == vlist_node)
36 if ((is_char_node(p)) && (link(p) == 0))
39 v = char_width(f, char_info(f, character(p)));
42 link(p) = new_kern(width(b) - v);
45 free_node(b, box_node_size);
46 b = new_glue(ss_glue);
52 link(p) = new_glue(ss_glue);
53 return hpack(b, w, exactly);
61 /* This is to be the start of tex5.c */
63 halfword math_glue_(halfword g, scaled m)
69 n = x_over_n(m, 65536L);
78 p = get_node(glue_spec_size);
79 width(p) = mult_and_add(n, width(g), xn_over_d(width(g), f, 65536L), 1073741823L); /* 2^30 - 1 */
80 stretch_order(p) = stretch_order(g);
82 if (stretch_order(p) == normal)
83 stretch(p) = mult_and_add(n, stretch(g), xn_over_d(stretch(g), f, 65536L), 1073741823L); /* 2^30 - 1 */
85 stretch(p) = stretch(g);
87 shrink_order(p) = shrink_order(g);
89 if (shrink_order(p) == normal)
90 shrink(p) = mult_and_add(n, shrink(g), xn_over_d(shrink(g), f, 65536L), 1073741823L); /* 2^30 - 1 */
92 shrink(p) = shrink(g);
97 void math_kern_ (halfword p, scaled m)
102 if (subtype(p) == mu_glue)
104 n = x_over_n(m, 65536L);
113 width(p) = mult_and_add(n, width(p), xn_over_d(width(p), f, 65536L), 1073741823L); /* 2^30 - 1 */
114 subtype(p) = explicit;
118 void flush_math (void)
120 flush_node_list(link(head));
121 flush_node_list(incompleat_noad);
127 halfword clean_box_(halfword p, small_number s)
130 small_number save_style;
138 cur_mlist = new_noad();
139 mem[nucleus(cur_mlist)] = mem[p];
162 save_style = cur_style;
164 mlist_penalties = false;
167 cur_style = save_style;
170 if (cur_style < script_style)
171 cur_size = text_size;
173 cur_size = 16 * ((cur_style - text_style) / 2);
175 cur_mu = x_over_n(math_quad(cur_size), 18);
178 if (is_char_node(q) || (q == 0))
180 else if ((link(q) == 0) && (type(q) <= vlist_node) && (shift_amount(q) == 0))
193 if (!is_char_node(r))
194 if (type(r) == kern_node)
196 free_node(r, small_node_size);
204 void fetch_(halfword a)
206 cur_c = character(a);
207 cur_f = fam_fnt(fam(a) + cur_size);
209 if (cur_f == null_font)
212 print_size(cur_size);
215 print_string(" is undefined (character ");
218 help4("Somewhere in the math formula just ended, you used the",
219 "stated character from an undefined font family. For example,",
220 "plain TeX doesn't allow \\it or \\sl in subscripts. Proceed,",
221 "and I'll try to forget that I needed that character.");
223 cur_i = null_character;
228 if ((cur_c >= font_bc[cur_f]) && (cur_c <= font_ec[cur_f]))
229 cur_i = char_info(cur_f, cur_c);
231 cur_i = null_character;
233 if (!((cur_i.b0 > 0)))
235 char_warning(cur_f, cur_c);
241 void make_over_(halfword q)
243 info(nucleus(q)) = overbar(clean_box(nucleus(q), 2 * (cur_style / 2) + 1),
244 3 * default_rule_thickness, default_rule_thickness);
245 math_type(nucleus(q)) = sub_box;
248 void make_under_(halfword q)
253 x = clean_box(nucleus(q), cur_style);
254 p = new_kern(3 * default_rule_thickness);
256 link(p) = fraction_rule(default_rule_thickness);
257 y = vpackage(x, 0, 1, 1073741823L); /* 2^30 - 1 */
258 delta = height(y) + depth(y) + default_rule_thickness;
259 height(y) = height(x);
260 depth(y) = delta - height(y);
261 info(nucleus(q)) = y;
262 math_type(nucleus(q)) = sub_box;
265 void make_vcenter_(halfword q)
270 v = info(nucleus(q));
272 if (type(v) != vlist_node)
274 confusion("vcenter");
275 return; // abort_flag set
278 delta = height(v) + depth(v);
279 height(v) = axis_height(cur_size) + half(delta);
280 depth(v) = delta - height(v);
283 void make_radical_(halfword q)
288 x = clean_box(nucleus(q), 2 * (cur_style / 2) + 1);
290 if (cur_style < text_style)
291 clr = default_rule_thickness + (abs(math_x_height(cur_size)) / 4);
294 clr = default_rule_thickness;
295 clr = clr + (abs(clr) / 4);
298 y = var_delimiter(left_delimiter(q), cur_size, height(x) + depth(x) + clr + default_rule_thickness);
299 delta = depth(y) -(height(x) + depth(x) + clr);
302 clr = clr + half(delta);
304 shift_amount(y) = - (integer) (height(x) + clr);
305 link(y) = overbar(x, clr, height(y));
306 info(nucleus(q)) = hpack(y, 0, 1);
307 math_type(nucleus(q)) = sub_box;
310 void make_math_accent_(halfword q)
315 internal_font_number f;
322 fetch(accent_chr(q));
331 if (math_type(nucleus(q)) == math_char)
335 if (char_tag(cur_i) == lig_tag)
337 a = lig_kern_start(cur_f, cur_i);
338 cur_i = font_info[a].qqqq;
340 if (skip_byte(cur_i) > stop_flag)
342 a = lig_kern_restart(cur_f, cur_i);
343 cur_i = font_info[a].qqqq;
348 if (next_char(cur_i) == skew_char[cur_f])
350 if (op_byte(cur_i) >= kern_flag)
351 if (skip_byte(cur_i) <= stop_flag)
352 s = char_kern(cur_f, cur_i);
356 if (skip_byte(cur_i) >= stop_flag)
359 a = a + skip_byte(cur_i) + 1;
360 cur_i = font_info[a].qqqq;
365 x = clean_box(nucleus(q), cramped_style(cur_style));
371 if (char_tag(i) != list_tag)
380 if (char_width(f, i) > w)
391 if ((math_type(supscr(q)) != 0) || (math_type(subscr(q)) != 0))
392 if (math_type(nucleus(q)) == math_char)
396 mem[nucleus(x)]= mem[nucleus(q)];
397 mem[supscr(x)]= mem[supscr(q)];
398 mem[subscr(x)]= mem[subscr(q)];
399 mem[supscr(q)].hh = empty_field;
400 mem[subscr(q)].hh = empty_field;
401 math_type(nucleus(q)) = sub_mlist;
402 info(nucleus(q)) = x;
403 x = clean_box(nucleus(q), cur_style);
404 delta = delta + height(x) - h;
409 shift_amount(y) = s + half(w - width(y));
411 p = new_kern(- (integer) delta);
414 y = vpackage(y, 0, 1, 1073741823L); /* 2^30 - 1 */
419 p = new_kern(h - height(y));
420 link(p) = list_ptr(y);
425 info(nucleus(q)) = y;
426 math_type(nucleus(q)) = sub_box;
430 void make_fraction_(halfword q)
432 halfword p, v, x, y, z;
433 scaled delta, delta1, delta2, shift_up, shift_down, clr;
435 if (thickness(q) == default_code) /* 2^30 */
436 thickness(q) = default_rule_thickness;
438 x = clean_box(numerator(q), num_style(cur_style));
439 z = clean_box(denominator(q), denom_style(cur_style));
441 if (width(x) < width(z))
442 x = rebox(x, width(z));
444 z = rebox(z, width(x));
446 if (cur_style < text_style)
448 shift_up = num1(cur_size);
449 shift_down = denom1(cur_size);
453 shift_down = denom2(cur_size);
455 if (thickness(q) != 0)
456 shift_up = num2(cur_size);
458 shift_up = num3(cur_size);
461 if (thickness(q) == 0)
463 if (cur_style < text_style)
464 clr = 7 * default_rule_thickness;
466 clr = 3 * default_rule_thickness;
468 delta = half(clr - ((shift_up - depth(x)) - (height(z) - shift_down)));
472 shift_up = shift_up + delta;
473 shift_down = shift_down + delta;
478 if (cur_style < text_style)
479 clr = 3 * thickness(q);
483 delta = half(thickness(q));
484 delta1 = clr - ((shift_up - depth(x)) - (axis_height(cur_size) + delta));
485 delta2 = clr -((axis_height(cur_size) - delta) - (height(z) - shift_down));
488 shift_up = shift_up + delta1;
491 shift_down = shift_down + delta2;
495 type(v) = vlist_node;
496 height(v) = shift_up + height(x);
497 depth(v) = depth(z) + shift_down;
500 if (thickness(q) == 0)
502 p = new_kern((shift_up - depth(x)) - (height(z) - shift_down));
507 y = fraction_rule(thickness(q));
508 p = new_kern((axis_height(cur_size) - delta) - (height(z) - shift_down));
511 p = new_kern((shift_up - depth(x)) - (axis_height(cur_size) + delta));
518 if (cur_style < text_style)
519 delta = delim1(cur_size);
521 delta = delim2(cur_size);
523 x = var_delimiter(left_delimiter(q), cur_size, delta);
525 z = var_delimiter(right_delimiter(q), cur_size, delta);
527 new_hlist(q) = hpack(x, 0, 1);
529 /***************************************************************************/
530 scaled make_op_ (halfword);
531 /***************************************************************************/
533 void make_ord_(halfword q)
539 if (math_type(subscr(q)) == 0)
540 if (math_type(supscr(q)) == 0)
541 if (math_type(nucleus(q)) == math_char)
546 if ((type(p) >= ord_noad) && (type(p) <= punct_noad))
547 if (math_type(nucleus(p)) == math_char)
548 if (fam(nucleus(p)) == fam(nucleus(q)))
550 math_type(nucleus(q)) = math_text_char;
553 if (char_tag(cur_i) == lig_tag)
555 a = lig_kern_start(cur_f, cur_i);
556 cur_c = character(nucleus(p));
557 cur_i = font_info[a].qqqq;
559 if (skip_byte(cur_i) > stop_flag)
561 a = lig_kern_restart(cur_f, cur_i);
562 cur_i = font_info[a].qqqq;
567 if (next_char(cur_i) == cur_c)
568 if (skip_byte(cur_i) <= stop_flag)
569 if (op_byte(cur_i) >= kern_flag)
571 p = new_kern(char_kern(cur_f, cur_i));
581 pause_for_instructions();
585 switch (op_byte(cur_i))
589 character(nucleus(q)) = rem_byte(cur_i);
593 character(nucleus(p)) = rem_byte(cur_i);
600 character(nucleus(r)) = rem_byte(cur_i);
601 fam(nucleus(r)) = fam(nucleus(q));
605 if (op_byte(cur_i) < 11)
606 math_type(nucleus(r)) = math_char;
608 math_type(nucleus(r)) = math_text_char;
615 character(nucleus(q)) = rem_byte(cur_i);
616 mem[subscr(q)] = mem[subscr(p)];
617 mem[supscr(q)] = mem[supscr(p)];
618 free_node(p, noad_size);
623 if (op_byte(cur_i) > 3)
626 math_type(nucleus(q)) = math_char;
630 if (skip_byte(cur_i) >= stop_flag)
633 a = a + skip_byte(cur_i) + 1;
634 cur_i = font_info[a].qqqq;
640 /***************************************************************************/
641 void make_scripts_ (halfword, scaled);
642 /***************************************************************************/
644 small_number make_left_right_(halfword q, small_number style, scaled max_d, scaled max_h)
646 scaled delta, delta1, delta2;
648 if (style < script_style)
649 cur_size = text_size;
651 cur_size = 16 * ((style - text_style) / 2);
653 delta2 = max_d + axis_height(cur_size);
654 delta1 = max_h + max_d - delta2;
659 delta = (delta1 / 500) * delimiter_factor;
660 delta2 = delta1 + delta1 - delimiter_shortfall;
665 new_hlist(q) = var_delimiter(delimiter(q), cur_size, delta);
666 return type(q) - (left_noad - open_noad);
669 void mlist_to_hlist (void)
674 small_number save_style;
677 /* small_number r_type; */
678 int r_type; /* 95/Jan/7 */
679 /* small_number t; */
680 int t; /* 95/Jan/7 */
688 penalties = mlist_penalties;
697 if (cur_style < script_style)
698 cur_size = text_size;
700 cur_size = 16 * ((cur_style - text_style) / 2);
702 cur_mu = x_over_n(math_quad(cur_size), 18);
738 if (r_type == bin_noad)
741 if (type(q) == right_noad)
761 if (subtype(q) == limits)
797 cur_style = subtype(q);
800 if (cur_style < script_style)
801 cur_size = text_size;
803 cur_size = 16 * ((cur_style - text_style) / 2);
805 cur_mu = x_over_n(math_quad(cur_size), 18);
814 switch (cur_style / 2)
818 p = display_mlist(q);
819 display_mlist(q) = 0;
839 p = script_script_mlist(q);
840 script_script_mlist(q) = 0;
845 flush_node_list(display_mlist(q));
846 flush_node_list(text_mlist(q));
847 flush_node_list(script_mlist(q));
848 flush_node_list(script_script_mlist(q));
849 type(q) = style_node;
850 subtype(q) = cur_style;
879 if (height(q) > max_h)
882 if (depth(q) > max_d)
891 if (subtype(q) == mu_glue)
894 y = math_glue(x, cur_mu);
899 else if ((cur_size != text_size) && (subtype(q) == cond_math_glue))
904 if ((type(q) == glue_node) || (type(p) == kern_node))
917 math_kern(q, cur_mu);
925 return; // abort_flag set
930 switch (math_type(nucleus(q)))
939 delta = char_italic(cur_f, cur_i);
940 p = new_character(cur_f, cur_c);
942 if ((math_type(nucleus(q)) == math_text_char) && (space(cur_f) != 0))
945 if ((math_type(subscr(q)) == 0) && (delta != 0))
947 link(p) = new_kern(delta);
961 p = info(nucleus(q));
966 cur_mlist = info(nucleus(q));
967 save_style = cur_style;
968 mlist_penalties = false;
970 cur_style = save_style;
973 if (cur_style < script_style)
974 cur_size = text_size;
976 cur_size = 16 * ((cur_style - text_style) / 2);
978 cur_mu = x_over_n(math_quad(cur_size), 18);
981 p = hpack(link(temp_head), 0, 1);
988 return; // abort_flag set
995 if ((math_type(subscr(q)) == 0) && (math_type(supscr(q)) == 0))
998 make_scripts(q, delta);
1000 z = hpack(new_hlist(q), 0, 1);
1002 if (height(z) > max_h)
1005 if (depth(z) > max_d)
1008 free_node(z, box_node_size);
1016 if (r_type == bin_noad)
1026 if (cur_style < script_style)
1027 cur_size = text_size;
1029 cur_size = 16 *((cur_style - text_style) / 2);
1031 cur_mu = x_over_n(math_quad(cur_size), 18);
1053 pen = bin_op_penalty;
1072 s = radical_noad_size;
1076 s = accent_noad_size;
1082 s = fraction_noad_size;
1088 t = make_left_right(q, style, max_d, max_h);
1093 cur_style = subtype(q);
1094 s = style_node_size;
1097 if (cur_style < script_style)
1098 cur_size = text_size;
1100 cur_size = 16 *((cur_style - text_style) / 2);
1102 cur_mu = x_over_n(math_quad(cur_size), 18);
1129 confusion("mlist3");
1130 return; // abort_flag set
1137 switch (str_pool[r_type * 8 + t + magic_offset])
1144 if (cur_style < script_style)
1145 x = thin_mu_skip_code;
1151 x = thin_mu_skip_code;
1155 if (cur_style < script_style)
1156 x = med_mu_skip_code;
1162 if (cur_style < script_style)
1163 x = thick_mu_skip_code;
1170 confusion("mlist4");
1171 return; // abort_flag set
1178 y = math_glue(glue_par(x), cur_mu);
1180 glue_ref_count(y) = 0;
1187 if (new_hlist(q) != 0)
1189 link(p) = new_hlist(q);
1195 while (!(link(p) == 0));
1200 if (pen < inf_penalty)
1202 r_type = type(link(q));
1204 if (r_type != penalty_node)
1205 if (r_type != rel_noad)
1207 z = new_penalty(pen);
1222 void push_alignment (void)
1226 p = get_node(align_stack_node_size);
1227 link(p) = align_ptr;
1228 info(p) = cur_align;
1229 llink(p) = preamble;
1230 rlink(p) = cur_span;
1231 mem[p + 2].cint = cur_loop;
1232 mem[p + 3].cint = align_state;
1233 info(p + 4) = cur_head;
1234 link(p + 4) = cur_tail;
1236 cur_head = get_avail();
1239 void pop_alignment (void)
1243 free_avail(cur_head);
1245 cur_tail = link(p + 4);
1246 cur_head = info(p + 4);
1247 align_state = mem[p + 3].cint;
1248 cur_loop = mem[p + 2].cint;
1249 cur_span = rlink(p);
1250 preamble = llink(p);
1251 cur_align = info(p);
1252 align_ptr = link(p);
1253 free_node(p, align_stack_node_size);
1256 void get_preamble_token (void)
1261 while ((cur_chr == span_code) && (cur_cmd == tab_mark))
1265 if (cur_cmd > max_command)
1272 if (cur_cmd == endv)
1274 fatal_error("(interwoven alignment preambles are not allowed)");
1275 return; // abort_flag set
1278 if ((cur_cmd == assign_glue) && (cur_chr == glue_base + tab_skip_code))
1280 scan_optional_equals();
1281 scan_glue(glue_val);
1283 if (global_defs > 0)
1284 geq_define(glue_base + tab_skip_code, glue_ref, cur_val);
1286 eq_define(glue_base + tab_skip_code, glue_ref, cur_val);
1292 void init_align (void)
1294 halfword save_cs_ptr;
1297 save_cs_ptr = cur_cs;
1299 align_state = -1000000L;
1301 if ((mode == mmode) && ((tail != cur_list.head_field) || (incompleat_noad != 0)))
1303 print_err("Improper ");
1304 print_esc("halign");
1305 print_string(" inside $$'s");
1306 help3("Displays can use special alignments (like \\eqalignno)",
1307 "only if nothing but the alignment itself is between $$'s.",
1308 "So I've deleted the formulas that preceded this alignment.");
1318 prev_depth = nest[nest_ptr - 2].aux_field.cint;
1321 mode = - (integer) mode;
1323 scan_spec(align_group, false);
1325 cur_align = align_head;
1327 scanner_status = aligning;
1328 warning_index = save_cs_ptr;
1329 align_state = -1000000L;
1333 link(cur_align) = new_param_glue(tab_skip_code);
1334 cur_align = link(cur_align);
1336 if (cur_cmd == car_ret)
1344 get_preamble_token();
1346 if (cur_cmd == mac_param)
1349 if ((cur_cmd <= car_ret) && (cur_cmd >= tab_mark) && (align_state == -1000000L))
1350 if ((p == hold_head) && (cur_loop == 0) && (cur_cmd == tab_mark))
1351 cur_loop = cur_align;
1354 print_err("Missing # inserted in alignment preamble");
1355 help3("There should be exactly one # between &'s, when an",
1356 "\\halign or \\valign is being set up. In this case you had",
1357 "none, so I've put one in; maybe that will work.");
1361 else if ((cur_cmd != spacer) || (p != hold_head))
1363 link(p) = get_avail();
1370 link(cur_align) = new_null_box();
1371 cur_align = link(cur_align);
1372 info(cur_align) = end_span;
1373 width(cur_align) = null_flag; /* - 2^30 */
1374 u_part(cur_align) = link(hold_head);
1381 get_preamble_token();
1383 if ((cur_cmd <= car_ret) && (cur_cmd >= tab_mark) && (align_state == -1000000L))
1386 if (cur_cmd == mac_param)
1388 print_err("Only one # is allowed per tab");
1389 help3("There should be exactly one # between &'s, when an",
1390 "\\halign or \\valign is being set up. In this case you had",
1391 "more than one, so I'm ignoring all but the first.");
1396 link(p) = get_avail();
1402 link(p) = get_avail();
1404 info(p) = end_template_token;
1405 v_part(cur_align) = link(hold_head);
1410 new_save_level(align_group);
1413 begin_token_list(every_cr, every_cr_text);
1417 void init_span_ (halfword p)
1422 space_factor = 1000;
1425 cur_list.aux_field.cint = ignore_depth;
1432 void init_row (void)
1436 mode = (-hmode - vmode) - mode;
1441 cur_list.aux_field.cint = 0;
1443 tail_append(new_glue(glue_ptr(preamble)));
1444 subtype(tail) = tab_skip_code + 1;
1445 cur_align = link(preamble);
1446 cur_tail = cur_head;
1447 init_span(cur_align);
1450 void init_col (void)
1452 extra_info(cur_align) = cur_cmd;
1454 if (cur_cmd == omit)
1459 begin_token_list(u_part(cur_align), u_template);
1469 p = hpack(link(head), 0, 1);
1473 if (cur_head != cur_tail)
1475 link(tail) = link(cur_head);
1481 p = vpackage(link(head), 0, 1, 1073741823L); /* 2^30 - 1 */
1485 space_factor = 1000;
1488 type(p) = unset_node;
1489 glue_stretch(p) = 0;
1492 begin_token_list(every_cr, every_cr_text);
1497 void fin_align (void)
1499 halfword p, q, r, s, u, v;
1504 memory_word aux_save;
1506 if (cur_group != align_group)
1508 confusion("align1");
1509 return; // abort_flag set
1514 if (cur_group != align_group)
1516 confusion("align0");
1517 return; // abort_flag set
1522 if (nest[nest_ptr - 1].mode_field == mmode)
1531 flush_list(u_part(q));
1532 flush_list(v_part(q));
1535 if (width(q) == null_flag) /* - 2^30 */
1543 add_glue_ref(zero_glue);
1545 glue_ptr(c) = zero_glue;
1549 if (info(q) != end_span)
1551 t = width(q) + width(glue_ptr(link(q)));
1555 n = min_quarterword + 1;
1559 width(r) = width(r) - t;
1565 n = link(info(s)) + 1;
1577 if (width(r) > width(info(s)))
1578 width(info(s)) = width(r);
1580 free_node(r, span_node_size);
1585 while (!(r == end_span));
1588 type(q) = unset_node;
1589 span_count(q) = min_quarterword;
1592 glue_order(q) = normal;
1593 glue_sign(q) = normal;
1594 glue_stretch(q) = 0;
1600 save_ptr = save_ptr - 2;
1601 pack_begin_line = - (integer) mode_line;
1605 rule_save = overfull_rule;
1607 p = hpack(preamble, saved(1), saved(0));
1608 overfull_rule = rule_save;
1616 height(q) = width(q);
1622 p = vpackage(preamble, saved(1), saved(0), 1073741823L); /* 2^30 - 1 */
1627 width(q) = height(q);
1634 pack_begin_line = 0;
1640 if (!is_char_node(q))
1641 if (type(q) == unset_node)
1645 type(q) = hlist_node;
1646 width(q) = width(p);
1650 type(q) = vlist_node;
1651 height(q) = height(p);
1654 glue_order(q) = glue_order(p);
1655 glue_sign(q) = glue_sign(p);
1656 glue_set(q) = glue_set(p);
1657 shift_amount(q) = o;
1658 r = link(list_ptr(q));
1659 s = link(list_ptr(p));
1668 while (n > min_quarterword)
1673 link(u) = new_glue(v);
1675 subtype(u) = tab_skip_code + 1;
1678 if (glue_sign(p) == stretching)
1680 if (stretch_order(v) == glue_order(p))
1681 t = t + round(glue_set(p) * stretch(v));
1683 else if (glue_sign(p) == shrinking)
1685 if (shrink_order(v) == glue_order(p))
1686 t = t - round(glue_set(p) * shrink(v));
1690 link(u) = new_null_box();
1695 width(u) = width(s);
1698 type(u) = vlist_node;
1699 height(u) = width(s);
1706 height(r) = height(q);
1707 depth(r) = depth(q);
1711 glue_sign(r) = normal;
1712 glue_order(r) = normal;
1715 else if (t > width(r))
1717 glue_sign(r) = stretching;
1719 if (glue_stretch(r) == 0)
1722 glue_set(r) = (t - width(r)) / ((double) glue_stretch(r));
1726 glue_order(r) = glue_sign(r);
1727 glue_sign(r) = shrinking;
1729 if (glue_shrink(r) == 0)
1731 else if ((glue_order(r) == normal) && (width(r) - t > glue_shrink(r)))
1734 glue_set(r) = (width(r) - t)/ ((double) glue_shrink(r));
1738 type(r) = hlist_node;
1742 width(r) = width(q);
1746 glue_sign(r) = normal;
1747 glue_order(r) = normal;
1750 else if (t > height(r))
1752 glue_sign(r) = stretching;
1754 if (glue_stretch(r) == 0)
1757 glue_set(r) = (t - height(r)) / ((double) glue_stretch(r));
1761 glue_order(r) = glue_sign(r);
1762 glue_sign(r) = shrinking;
1764 if (glue_shrink(r) == 0)
1766 else if ((glue_order(r) == normal) && (height(r) - t > glue_shrink(r)))
1769 glue_set(r) = (height(r) - t) / ((double) glue_shrink(r));
1773 type(r) = vlist_node;
1776 shift_amount(r) = 0;
1781 link(r) = link(hold_head);
1790 else if (type(q) == rule_node)
1792 if ((width(q) == -1073741824L)) /* 2^30 */
1793 width(q) = width(p);
1795 if ((height(q) == -1073741824L)) /* 2^30 */
1796 height(q) = height(p);
1798 if ((depth(q) == -1073741824L)) /* 2^30 */
1799 depth(q) = depth(p);
1806 shift_amount(q) = o;
1817 aux_save = cur_list.aux_field;
1826 if (cur_cmd != math_shift)
1828 print_err("Missing $$ inserted");
1829 help2("Displays can use special alignments (like \\eqalignno)",
1830 "only if nothing but the alignment itself is between $$'s.");
1837 if (cur_cmd != math_shift)
1839 print_err("Display math should end with $$");
1840 help2("The `$' that I just saw supposedly matches a previous `$$'.",
1841 "So I shall assume that you typed `$$' both times.");
1847 tail_append(new_penalty(pre_display_penalty));
1848 tail_append(new_param_glue(above_display_skip_code));
1854 tail_append(new_penalty(post_display_penalty));
1855 tail_append(new_param_glue(below_display_skip_code));
1856 cur_list.aux_field.cint = aux_save.cint;
1857 resume_after_display();
1861 cur_list.aux_field = aux_save;
1873 /* used to be align_peek, zfintieshrink, etc in old tex5.c */
1874 /************************************************************************/
1875 /* moved down here to avoid questions about pragma optimize */
1876 /* #pragma optimize("g", off) */
1877 /* for MC VS compiler */
1878 /* Moved down here 96/Oct/12 in response to problem with texerror.tex */
1879 /* pragma optimize("a", off) not strong enough - this may slow things */
1881 boolean fin_col (void)
1894 return 0; // abort_flag set
1897 q = link(cur_align);
1902 return 0; // abort_flag set
1905 if (align_state < 500000L)
1907 fatal_error("(interwoven alignment preambles are not allowed)");
1908 return 0; // abort_flag set
1913 if ((p == 0) && (extra_info(cur_align) < cr_code))
1916 /* potential problem here if new_null_box causes memory reallocation ??? */
1917 /* compiler optimization does not refresh `mem' loaded in registers ? */
1918 link(q) = new_null_box();
1921 width(p) = null_flag;
1922 cur_loop = link(cur_loop);
1924 r = u_part(cur_loop);
1928 link(q) = get_avail();
1935 u_part(p) = link(hold_head);
1937 r = v_part(cur_loop);
1941 link(q) = get_avail();
1948 v_part(p) = link(hold_head);
1949 cur_loop = link(cur_loop);
1950 link(p) = new_glue(glue_ptr(cur_loop));
1954 print_err("Extra alignment tab has been changed to ");
1956 help3("You have given more \\span or & marks than there were",
1957 "in the preamble to the \\halign or \\valign now in progress.",
1958 "So I'll assume that you meant to type \\cr instead.");
1959 extra_info(cur_align) = cr_code;
1963 if (extra_info(cur_align) != span_code)
1967 new_save_level(align_group);
1972 adjust_tail = cur_tail;
1973 u = hpack(link(head), 0, 1);
1975 cur_tail = adjust_tail;
1980 u = vpackage(link(head), 0, 1, 0);
1984 n = min_quarterword;
1986 if (cur_span != cur_align)
1995 while (!(q == cur_align));
1997 if (n > max_quarterword)
1999 confusion("256 spans"); /* 256 spans --- message wrong now, but ... */
2000 return 0; // abort_flag set
2005 while (link(info(q)) < n)
2008 if (link(info(q)) > n)
2010 s = get_node(span_node_size);
2016 else if (width(info(q)) < w)
2019 else if (w > width(cur_align))
2020 width(cur_align) = w;
2022 type(u) = unset_node;
2025 if (total_stretch[filll] != 0)
2027 else if (total_stretch[fill] != 0)
2029 else if (total_stretch[fil] != 0)
2035 glue_stretch(u) = total_stretch[o];
2037 if (total_shrink[filll] != 0)
2039 else if (total_shrink[fill] != 0)
2041 else if (total_shrink[fil] != 0)
2047 glue_shrink(u) = total_shrink[o];
2053 tail_append(new_glue(glue_ptr(link(cur_align))));
2054 subtype(tail) = tab_skip_code + 1;
2056 if (extra_info(cur_align) >= cr_code)
2064 align_state = 1000000L;
2070 while (!(cur_cmd != spacer));
2078 scaled make_op_(halfword q)
2081 halfword p, v, x, y, z;
2084 scaled shift_up, shift_down;
2086 if ((subtype(q) == normal) && (cur_style < text_style))
2087 subtype(q) = limits;
2089 if (math_type(nucleus(q)) == math_char)
2093 if ((cur_style < text_style) && (char_tag(cur_i) == list_tag))
2095 c = rem_byte(cur_i);
2096 i = char_info(cur_f, c);
2102 character(nucleus(q)) = c;
2106 delta = char_italic(cur_f, cur_i);
2107 x = clean_box(nucleus(q), cur_style);
2109 if ((math_type(subscr(q)) != 0) && (subtype(q) != limits))
2110 width(x) = width(x) - delta;
2112 shift_amount(x) = half(height(x) - depth(x)) - axis_height(cur_size);
2113 math_type(nucleus(q)) = sub_box;
2114 info(nucleus(q)) = x;
2119 if (subtype(q) == limits)
2121 x = clean_box(supscr(q), sup_style(cur_style));
2122 y = clean_box(nucleus(q), cur_style);
2123 z = clean_box(subscr(q), sub_style(cur_style));
2125 type(v) = vlist_node;
2126 width(v) = width(y);
2128 if (width(x) > width(v))
2129 width(v) = width(x);
2131 if (width(z) > width(v))
2132 width(v) = width(z);
2134 x = rebox(x, width(v));
2135 y = rebox(y, width(v));
2136 z = rebox(z, width(v));
2137 shift_amount(x) = half(delta);
2138 shift_amount(z) = - (integer) shift_amount(x);
2139 height(v) = height(y);
2140 depth(v) = depth(y);
2142 if (math_type(supscr(q)) == 0)
2144 free_node(x, box_node_size);
2149 shift_up = big_op_spacing3 - depth(x);
2151 if (shift_up < big_op_spacing1)
2152 shift_up = big_op_spacing1;
2154 p = new_kern(shift_up);
2157 p = new_kern(big_op_spacing5);
2160 height(v) = height(v) + big_op_spacing5 + height(x) + depth(x) + shift_up;
2163 if (math_type(subscr(q)) == 0)
2164 free_node(z, box_node_size);
2167 shift_down = big_op_spacing4 - height(z);
2169 if (shift_down < big_op_spacing2)
2170 shift_down = big_op_spacing2;
2172 p = new_kern(shift_down);
2175 p = new_kern(big_op_spacing5);
2177 depth(v) = depth(v) + big_op_spacing5 + height(z) + depth(z) + shift_down;
2186 void make_scripts_(halfword q, scaled delta)
2188 halfword p, x, y, z;
2189 scaled shift_up, shift_down, clr;
2194 if (is_char_node(p))
2203 if (cur_style < script_style)
2206 t = script_script_size;
2208 shift_up = height(z) - sup_drop(t);
2209 shift_down = depth(z) + sub_drop(t);
2210 free_node(z, box_node_size);
2213 if (math_type(supscr(q)) == 0)
2215 x = clean_box(subscr(q), sub_style(cur_style));
2216 width(x) = width(x) + script_space;
2218 if (shift_down < sub1(cur_size))
2219 shift_down = sub1(cur_size);
2221 clr = height(x) -(abs(math_x_height(cur_size) * 4) / 5);
2223 if (shift_down < clr)
2226 shift_amount(x) = shift_down;
2231 x = clean_box(supscr(q), sup_style(cur_style));
2232 width(x) = width(x) + script_space;
2235 clr = sup3(cur_size);
2236 else if (cur_style < text_style)
2237 clr = sup1(cur_size);
2239 clr = sup2(cur_size);
2244 clr = depth(x) +(abs(math_x_height(cur_size)) / 4);
2250 if (math_type(subscr(q)) == 0)
2251 shift_amount(x) = - (integer) shift_up;
2254 y = clean_box(subscr(q), sub_style(cur_style));
2255 width(y) = width(y) + script_space;
2257 if (shift_down < sub2(cur_size))
2258 shift_down = sub2(cur_size);
2260 clr = 4 * default_rule_thickness - ((shift_up - depth(x)) - (height(y) - shift_down));
2264 shift_down = shift_down + clr;
2266 clr = (abs(math_x_height(cur_size) * 4) / 5) - (shift_up - depth(x));
2270 shift_up = shift_up + clr;
2271 shift_down = shift_down - clr;
2275 shift_amount(x) = delta;
2276 p = new_kern((shift_up - depth(x)) - (height(y) - shift_down));
2279 x = vpackage(x, 0, 1, 1073741823L); /* 2^30 - 1 */
2280 shift_amount(x) = shift_down;
2284 if (new_hlist(q) == 0)
2290 while (link(p) != 0)