OSDN Git Service

6d3a8842ef41432d2f0546abd02b78554d8473e0
[putex/putex.git] / src / texsourc / tex5.c
1 #ifdef _WINDOWS
2   #define NOCOMM
3   #define NOSOUND
4   #define NODRIVERS
5   #define STRICT
6   #pragma warning(disable:4115) // kill rpcasync.h complaint
7   #include <windows.h>
8   #define MYLIBAPI __declspec(dllexport)
9 #endif
10
11 #pragma warning(disable:4131) // old style declarator
12 #pragma warning(disable:4135) // conversion between different integral types 
13 #pragma warning(disable:4127) // conditional expression is constant
14
15 #include <setjmp.h>
16
17 #define EXTERN extern
18
19 #include "texd.h"
20
21 #pragma warning(disable:4244)       /* 96/Jan/10 */
22
23 /* rebox_ used to be in tex4.c */
24 /* sec 0715 */
25 halfword rebox_(halfword b, scaled w)
26 {
27   halfword p;
28   internal_font_number f;
29   scaled v;
30
31   if ((width(b) != w) && (list_ptr(b) != 0))
32   {
33     if (type(b) == vlist_node)
34       b = hpack(b, 0, 1);
35
36     p = list_ptr(b);
37
38     if (((p >= hi_mem_min)) && (link(p) == 0))
39     {
40       f = font(p);
41       v = char_width(f, char_info(f, character(p)));
42
43       if (v != width(b))
44         link(p) = new_kern(width(b) - v);
45     }
46
47     free_node(b, box_node_size);
48     b = new_glue(ss_glue);
49     link(b) = p;
50
51     while (link(p) != 0)
52       p = link(p);
53
54     link(p) = new_glue(ss_glue);
55     return hpack(b, w, exactly);
56   }
57   else
58   {
59     width(b) = w;
60     return b;
61   }
62 }
63 /* This is to be the start of tex5.c */
64 /* sec 0716 */
65 halfword math_glue_(halfword g, scaled m)
66 {
67   halfword p;
68   integer n;
69   scaled f;
70
71   n = x_over_n(m, 65536L);
72   f = tex_remainder;
73
74   if (f < 0)
75   {
76     decr(n);
77     f = f + 65536L;
78   }
79
80   p = get_node(glue_spec_size);
81   width(p) = mult_and_add(n, width(g), xn_over_d(width(g), f, 65536L), 1073741823L);  /* 2^30 - 1 */
82   stretch_order(p) = stretch_order(g);
83
84   if (stretch_order(p) == normal)
85     stretch(p) = mult_and_add(n, stretch(g), xn_over_d(stretch(g), f, 65536L), 1073741823L);  /* 2^30 - 1 */
86   else
87     stretch(p) = stretch(g);
88
89   shrink_order(p) = shrink_order(g);
90
91   if (shrink_order(p) == normal)
92     shrink(p) = mult_and_add(n, shrink(g), xn_over_d(shrink(g), f, 65536L), 1073741823L);  /* 2^30 - 1 */
93   else
94     shrink(p) = shrink(g);
95
96   return p;
97 }
98 /* sec 0717 */
99 void math_kern_ (halfword p, scaled m)
100 {
101   integer n;
102   scaled f;
103
104   if (subtype(p) == mu_glue)
105   {
106     n = x_over_n(m, 65536L);
107     f = tex_remainder;
108
109     if (f < 0)
110     {
111       decr(n);
112       f = f + 65536L;
113     }
114
115     width(p) = mult_and_add(n, width(p), xn_over_d(width(p), f, 65536L), 1073741823L);  /* 2^30 - 1 */
116     subtype(p) = explicit;
117   }
118 }
119 /* sec 0718 */
120 void flush_math (void)
121 {
122   flush_node_list(link(head));
123   flush_node_list(incompleat_noad);
124   link(head) = 0;
125   tail = head;
126   incompleat_noad = 0;
127 }
128 /* sec 0720 */
129 halfword clean_box_(halfword p, small_number s)
130 {
131   halfword q;
132   small_number save_style;
133   halfword x;
134   halfword r;
135
136   switch(math_type(p))
137   {
138     case math_char:
139       {
140         cur_mlist = new_noad();
141         mem[nucleus(cur_mlist)] = mem[p];
142       }
143       break;
144
145     case sub_box:
146       {
147         q = info(p);
148         goto lab40;
149       }
150       break;
151
152     case sub_mlist:
153       cur_mlist = info(p);
154       break;
155
156     default:
157       {
158         q = new_null_box();
159         goto lab40;
160       }
161     break;
162   }
163
164   save_style = cur_style;
165   cur_style = s;
166   mlist_penalties = false;
167   mlist_to_hlist();
168   q = link(temp_head);
169   cur_style = save_style;
170
171   {
172     if (cur_style < script_style)
173       cur_size = text_size;
174     else
175       cur_size = 16 * ((cur_style - text_style) / 2);
176
177     cur_mu = x_over_n(math_quad(cur_size), 18);
178   }
179 lab40:
180   if ((q >= hi_mem_min) || (q == 0))
181     x = hpack(q, 0, 1);
182   else if ((link(q) == 0) && (type(q) <= vlist_node) && (shift_amount(q) == 0))
183     x = q;
184   else
185     x = hpack(q, 0, 1);
186
187   q = list_ptr(x);
188
189   if ((q >= hi_mem_min))
190   {
191     r = link(q);
192
193     if (r != 0)
194       if (link(r) == 0)
195         if (!(r >= hi_mem_min))
196           if (type(r) == kern_node)
197           {
198             free_node(r, small_node_size);
199             link(q) = 0;
200           }
201   }
202
203   return x;
204 }
205 /* sec 0722 */
206 void fetch_(halfword a)
207 {
208   cur_c = character(a);
209   cur_f = fam_fnt(fam(a) + cur_size);
210
211   if (cur_f == null_font)
212   {
213     print_err("");
214     print_size(cur_size);
215     print_char(' ');
216     print_int(fam(a));
217     print_string(" is undefined (character ");
218     print(cur_c);
219     print_char(')');
220     help4("Somewhere in the math formula just ended, you used the",
221         "stated character from an undefined font family. For example,",
222         "plain TeX doesn't allow \\it or \\sl in subscripts. Proceed,",
223         "and I'll try to forget that I needed that character.");
224     error();
225     cur_i = null_character;
226     math_type(a) = 0;
227   }
228   else
229   {
230     if ((cur_c >= font_bc[cur_f]) && (cur_c <= font_ec[cur_f]))
231       cur_i = char_info(cur_f, cur_c);
232     else
233       cur_i = null_character;
234
235     if (!((cur_i.b0 > 0)))
236     {
237       char_warning(cur_f, cur_c);
238       math_type(a) = 0;
239     }
240   }
241 }
242 /* sec 0734 */
243 void make_over_(halfword q)
244 {
245   info(nucleus(q)) = overbar(clean_box(nucleus(q), 2 * (cur_style / 2) + 1),
246       3 * default_rule_thickness, default_rule_thickness);
247   math_type(nucleus(q)) = sub_box;
248 }
249 /* sec 0735 */
250 void make_under_(halfword q)
251 {
252   halfword p, x, y;
253   scaled delta;
254
255   x = clean_box(nucleus(q), cur_style);
256   p = new_kern(3 * default_rule_thickness);
257   link(x) = p;
258   link(p) = fraction_rule(default_rule_thickness);
259   y = vpackage(x, 0, 1, 1073741823L); /* 2^30 - 1 */
260   delta = height(y) + depth(y) + default_rule_thickness;
261   height(y) = height(x);
262   depth(y) = delta - height(y);
263   info(nucleus(q)) = y;
264   math_type(nucleus(q)) = sub_box;
265 }
266 /* sec 0736 */
267 void make_vcenter_(halfword q)
268
269   halfword v;
270   scaled delta;
271
272   v = info(nucleus(q));
273
274   if (type(v) != vlist_node)
275   {
276     confusion("vcenter");
277     return;         // abort_flag set
278   }
279   delta = height(v) + depth(v);
280   height(v) = axis_height(cur_size) + half(delta);
281   depth(v) = delta - height(v);
282 }
283 /* sec 0737 */
284 void make_radical_(halfword q)
285 {
286   halfword x, y;
287   scaled delta, clr;
288
289   x = clean_box(nucleus(q), 2 * (cur_style / 2) + 1);
290
291   if (cur_style < text_style)
292     clr = default_rule_thickness + (abs(math_x_height(cur_size)) / 4);
293   else
294   {
295     clr = default_rule_thickness;
296     clr = clr + (abs(clr) / 4);
297   }
298
299   y = var_delimiter(left_delimiter(q), cur_size, height(x) + depth(x) + clr + default_rule_thickness);
300   delta = depth(y) -(height(x) + depth(x) + clr);
301
302   if (delta > 0)
303     clr = clr + half(delta);
304
305   shift_amount(y) = - (integer) (height(x) + clr);
306   link(y) = overbar(x, clr, height(y));
307   info(nucleus(q)) = hpack(y, 0, 1);
308   math_type(nucleus(q)) = sub_box;
309 }
310 /* sec 0738 */
311 void make_math_accent_(halfword q)
312 {
313   halfword p, x, y;
314   integer a;
315   quarterword c;
316   internal_font_number f;
317   ffourquarters i;
318   scaled s;
319   scaled h;
320   scaled delta;
321   scaled w;
322
323   fetch(accent_chr(q));
324
325   if ((cur_i.b0 > 0))
326   {
327     i = cur_i;
328     c = cur_c;
329     f = cur_f;
330     s = 0;
331
332     if (math_type(nucleus(q)) == math_char)
333     {
334       fetch(nucleus(q));
335
336       if (char_tag(cur_i) == lig_tag)
337       {
338         a = lig_kern_start(cur_f, cur_i);
339         cur_i = font_info[a].qqqq;
340
341         if (skip_byte(cur_i) > stop_flag)
342         {
343           a = lig_kern_restart(cur_f, cur_i);
344           cur_i = font_info[a].qqqq;
345         }
346
347         while (true)
348         {
349           if (next_char(cur_i) == skew_char[cur_f])
350           {
351             if (op_byte(cur_i) >= kern_flag)
352               if (skip_byte(cur_i) <= stop_flag)
353                 s = char_kern(cur_f, cur_i);
354             goto lab31;
355           }
356
357           if (skip_byte(cur_i) >= stop_flag)
358             goto lab31;
359
360           a = a + skip_byte(cur_i) + 1;
361           cur_i = font_info[a].qqqq;
362         }
363       }
364     }
365 lab31:;
366     x = clean_box(nucleus(q), cramped_style(cur_style));
367     w = width(x);
368     h = height(x);
369
370     while (true)
371     {
372       if (char_tag(i) != list_tag)
373         goto lab30;
374
375       y = rem_byte(i);
376       i = char_info(f, y);
377
378       if (!(i.b0 > 0))
379         goto lab30;
380
381       if (char_width(f, i) > w)
382         goto lab30;
383
384       c = y;
385     }
386 lab30:;
387     if (h < x_height(f))
388       delta = h;
389     else
390       delta = x_height(f);
391
392     if ((math_type(supscr(q)) != 0) || (math_type(subscr(q)) != 0))
393       if (math_type(nucleus(q)) == math_char)
394       {
395         flush_node_list(x);
396         x = new_noad();
397         mem[nucleus(x)]= mem[nucleus(q)];
398         mem[supscr(x)]= mem[supscr(q)];
399         mem[subscr(x)]= mem[subscr(q)];
400         mem[supscr(q)].hh = empty_field;
401         mem[subscr(q)].hh = empty_field;
402         math_type(nucleus(q)) = sub_mlist;
403         info(nucleus(q)) = x;
404         x = clean_box(nucleus(q), cur_style);
405         delta = delta + height(x) - h;
406         h = height(x);
407       }
408
409     y = char_box(f, c);
410     shift_amount(y) = s + half(w - width(y));
411     width(y) = 0;
412     p = new_kern(- (integer) delta);
413     link(p) = x;
414     link(y) = p;
415     y = vpackage(y, 0, 1, 1073741823L);  /* 2^30 - 1 */
416     width(y) = width(x);
417
418     if (height(y) < h)
419     {
420       p = new_kern(h - height(y));
421       link(p) = list_ptr(y);
422       list_ptr(y) = p;
423       height(y) = h;
424     }
425
426     info(nucleus(q)) = y;
427     math_type(nucleus(q)) = sub_box;
428   }
429 }
430 /* sec 0743 */
431 void make_fraction_(halfword q)
432 {
433   halfword p, v, x, y, z;
434   scaled delta, delta1, delta2, shift_up, shift_down, clr;
435   
436   if (thickness(q) == default_code) /* 2^30 */
437     thickness(q) = default_rule_thickness;
438
439   x = clean_box(numerator(q), num_style(cur_style));
440   z = clean_box(denominator(q), denom_style(cur_style));
441
442   if (width(x) < width(z))
443     x = rebox(x, width(z));
444   else
445     z = rebox(z, width(x));
446
447   if (cur_style < text_style)
448   {
449     shift_up = num1(cur_size);
450     shift_down = denom1(cur_size);
451   }
452   else
453   {
454     shift_down = denom2(cur_size);
455
456     if (thickness(q) != 0)
457       shift_up = num2(cur_size);
458     else
459       shift_up = num3(cur_size);
460   }
461
462   if (thickness(q) == 0)
463   {
464     if (cur_style < text_style)
465       clr = 7 * default_rule_thickness;
466     else
467       clr = 3 * default_rule_thickness;
468
469     delta = half(clr - ((shift_up - depth(x)) - (height(z) - shift_down)));
470
471     if (delta > 0)
472     {
473       shift_up = shift_up + delta;
474       shift_down = shift_down + delta;
475     }
476   }
477   else
478   {
479     if (cur_style < text_style)
480       clr = 3 * thickness(q);
481     else
482       clr = thickness(q);
483
484     delta = half(thickness(q));
485     delta1 = clr - ((shift_up - depth(x)) - (axis_height(cur_size) + delta));
486     delta2 = clr -((axis_height(cur_size) - delta) - (height(z) - shift_down));
487
488     if (delta1 > 0)
489       shift_up = shift_up + delta1;
490
491     if (delta2 > 0)
492       shift_down = shift_down + delta2;
493   }
494
495   v = new_null_box();
496   type(v) = vlist_node;
497   height(v) = shift_up + height(x);
498   depth(v) = depth(z) + shift_down;
499   width(v) = width(x);
500
501   if (thickness(q) == 0)
502   {
503     p = new_kern((shift_up - depth(x)) - (height(z) - shift_down));
504     link(p) = z;
505   }
506   else
507   {
508     y = fraction_rule(thickness(q));
509     p = new_kern((axis_height(cur_size) - delta) - (height(z) - shift_down));
510     link(y) = p;
511     link(p) = z;
512     p = new_kern((shift_up - depth(x)) - (axis_height(cur_size) + delta));
513     link(p) = y;
514   }
515
516   link(x) = p;
517   list_ptr(v) = x;
518
519   if (cur_style < text_style)
520     delta = delim1(cur_size);
521   else
522     delta = delim2(cur_size);
523
524   x = var_delimiter(left_delimiter(q), cur_size, delta);
525   link(x) = v;
526   z = var_delimiter(right_delimiter(q), cur_size, delta);
527   link(v) = z;
528   new_hlist(q) = hpack(x, 0, 1);
529 }
530 /***************************************************************************/
531 /* moved to end to avoid questions about pragma optimize 96/Sep/12 */
532 scaled make_op_ (halfword);
533 /***************************************************************************/
534 /* sec 0752 */
535 void make_ord_(halfword q)
536 {
537   integer a;
538   halfword p, r;
539
540 lab20:
541   if (math_type(subscr(q)) == 0)
542     if (math_type(supscr(q)) == 0)
543       if (math_type(nucleus(q)) == math_char)
544       {
545         p = link(q);
546
547         if (p != 0)
548           if ((type(p) >= ord_noad) && (type(p) <= punct_noad))
549             if (math_type(nucleus(p)) == math_char)
550               if (fam(nucleus(p)) == fam(nucleus(q)))
551               {
552                 math_type(nucleus(q)) = math_text_char;
553                 fetch(nucleus(q));
554
555                 if (char_tag(cur_i) == lig_tag)
556                 {
557                   a = lig_kern_start(cur_f, cur_i);
558                   cur_c = character(nucleus(p));
559                   cur_i = font_info[a].qqqq;
560
561                   if (skip_byte(cur_i) > stop_flag)
562                   {
563                     a = lig_kern_restart(cur_f, cur_i);
564                     cur_i = font_info[a].qqqq;
565                   }
566
567                   while (true)
568                   {
569                     if (next_char(cur_i) == cur_c)
570                       if (skip_byte(cur_i) <= stop_flag)
571                         if (op_byte(cur_i) >= kern_flag)
572                         {
573                           p = new_kern(char_kern(cur_f, cur_i));
574                           link(p) = link(q);
575                           link(q) = p;
576                           return;
577                         }
578                         else
579                         {
580                           {
581                             if (interrupt != 0)
582                             {
583                               pause_for_instructions();
584                             }
585                           }
586
587                           switch (op_byte(cur_i))
588                           {
589                             case 1:
590                             case 5:
591                               character(nucleus(q)) = rem_byte(cur_i);
592                               break;
593                             case 2:
594                             case 6:
595                               character(nucleus(p)) = rem_byte(cur_i);
596                               break;
597                             case 3:
598                             case 7:
599                             case 11:
600                               {
601                                 r = new_noad();
602                                 character(nucleus(r)) = rem_byte(cur_i);
603                                 fam(nucleus(r)) = fam(nucleus(q));
604                                 link(q) = r;
605                                 link(r) = p;
606
607                                 if (op_byte(cur_i) < 11)
608                                   math_type(nucleus(r)) = math_char;
609                                 else
610                                   math_type(nucleus(r)) = math_text_char;
611                               }
612                               break;
613
614                             default:
615                               {
616                                 link(q) = link(p);
617                                 character(nucleus(q)) = rem_byte(cur_i);
618                                 mem[subscr(q)] = mem[subscr(p)];
619                                 mem[supscr(q)] = mem[supscr(p)];
620                                 free_node(p, noad_size);
621                               }
622                               break;
623                           }
624
625                           if (op_byte(cur_i) > 3)
626                             return;
627
628                           math_type(nucleus(q)) = math_char;
629                           goto lab20;
630                         }
631
632                     if (skip_byte(cur_i) >= stop_flag)
633                       return;
634
635                     a = a + skip_byte(cur_i) + 1;
636                     cur_i = font_info[a].qqqq;
637                   }
638                 }
639               }
640       }
641 }
642 /***************************************************************************/
643 /* moved to end to avoid questions about pragma optimize 96/Sep/12 */
644 void make_scripts_ (halfword, scaled);
645 /***************************************************************************/
646 /* sec 0762 */
647 small_number make_left_right_(halfword q, small_number style, scaled max_d, scaled max_h)
648 {
649   scaled delta, delta1, delta2;
650
651   if (style < script_style)
652     cur_size = text_size;
653   else
654     cur_size = 16 * ((style - text_style) / 2);
655
656   delta2 = max_d + axis_height(cur_size);
657   delta1 = max_h + max_d - delta2;
658
659   if (delta2 > delta1)
660     delta1 = delta2;
661
662   delta = (delta1 / 500) * delimiter_factor;
663   delta2 = delta1 + delta1 - delimiter_shortfall;
664
665   if (delta < delta2)
666     delta = delta2;
667
668   new_hlist(q) = var_delimiter(delimiter(q), cur_size, delta);
669   return type(q) - (left_noad - open_noad);
670 }
671 /* sec 0726 */
672 void mlist_to_hlist (void)
673 {
674   halfword mlist;
675   bool penalties;
676   small_number style;
677   small_number save_style;
678   halfword q;
679   halfword r;
680 /*  small_number r_type;  */
681   int r_type;            /* 95/Jan/7 */
682 /*  small_number t; */
683   int t;              /* 95/Jan/7 */
684   halfword p, x, y, z;
685   integer pen;
686   small_number s;
687   scaled max_h, max_d;
688   scaled delta;
689
690   mlist = cur_mlist;
691   penalties = mlist_penalties;
692   style = cur_style;
693   q = mlist;
694   r = 0;
695   r_type = op_noad;
696   max_h = 0;
697   max_d = 0;
698
699   {
700     if (cur_style < script_style)
701       cur_size = text_size;
702     else
703       cur_size = 16 * ((cur_style - text_style) / 2);
704
705     cur_mu = x_over_n(math_quad(cur_size), 18);
706   }
707
708   while (q != 0)
709   {
710 lab21:
711     delta = 0;
712
713     switch (type(q))
714     {
715       case bin_noad:
716         switch (r_type)
717         {
718           case bin_noad:
719           case op_noad:
720           case rel_noad:
721           case open_noad:
722           case punct_noad:
723           case left_noad:
724             {
725               type(q) = ord_noad;
726               goto lab21;
727             }
728             break;
729
730           default:
731             ;
732             break;
733         }
734         break;
735
736       case rel_noad:
737       case close_noad:
738       case punct_noad:
739       case right_noad:
740         {
741           if (r_type == bin_noad)
742             type(r) = ord_noad;
743
744           if (type(q) == right_noad)
745             goto lab80;
746         }
747         break;
748
749       case left_noad:
750         goto lab80;
751         break;
752
753       case fraction_noad:
754         {
755           make_fraction(q);
756           goto lab82;
757         }
758         break;
759
760       case op_noad:
761         {
762           delta = make_op(q);
763
764           if (subtype(q) == limits)
765             goto lab82;
766         }
767         break;
768
769       case ord_noad:
770         make_ord(q);
771         break;
772
773       case open_noad:
774       case inner_noad:
775         ;
776         break;
777
778       case radical_noad:
779         make_radical(q);
780         break;
781
782       case over_noad:
783         make_over(q);
784         break;
785
786       case under_noad:
787         make_under(q);
788         break;
789
790       case accent_noad:
791         make_math_accent(q);
792         break;
793
794       case vcenter_noad:
795         make_vcenter(q);
796         break;
797
798       case style_node:
799         {
800           cur_style = subtype(q);
801
802           {
803             if (cur_style < script_style)
804               cur_size = text_size;
805             else
806               cur_size = 16 * ((cur_style - text_style) / 2);
807
808             cur_mu = x_over_n(math_quad(cur_size), 18);
809           }
810
811           goto lab81;
812         }
813         break;
814
815       case choice_node:
816         {
817           switch (cur_style / 2)
818           {
819             case 0:
820               {
821                 p = display_mlist(q);
822                 display_mlist(q) = 0;
823               }
824               break;
825
826             case 1:
827               {
828                 p = text_mlist(q);
829                 text_mlist(q) = 0;
830               }
831               break;
832
833             case 2:
834               {
835                 p = script_mlist(q);
836                 script_mlist(q) = 0;
837               }
838               break;
839
840             case 3:
841               {
842                 p = script_script_mlist(q);
843                 script_script_mlist(q) = 0;
844               }
845               break;
846           }
847
848           flush_node_list(display_mlist(q));
849           flush_node_list(text_mlist(q));
850           flush_node_list(script_mlist(q));
851           flush_node_list(script_script_mlist(q));
852           type(q) = style_node;
853           subtype(q) = cur_style;
854           width(q) = 0;
855           depth(q) = 0;
856
857           if (p != 0)
858           {
859             z = link(q);
860             link(q) = p;
861
862             while (link(p) != 0)
863               p = link(p);
864
865             link(p) = z;
866           }
867           goto lab81;
868         }
869         break;
870
871       case ins_node:
872       case mark_node:
873       case adjust_node:
874       case whatsit_node:
875       case penalty_node:
876       case disc_node:
877         goto lab81;
878         break;
879
880       case rule_node:
881         {
882           if (height(q) > max_h)
883             max_h = height(q);
884
885           if (depth(q) > max_d)
886             max_d = depth(q);
887
888           goto lab81;
889         }
890         break;
891
892       case glue_node:
893         {
894           if (subtype(q) == mu_glue)
895           {
896             x = glue_ptr(q);
897             y = math_glue(x, cur_mu);
898             delete_glue_ref(x);
899             glue_ptr(q) = y;
900             subtype(q) = normal;
901           }
902           else if ((cur_size != text_size) && (subtype(q) == cond_math_glue))
903           {
904             p = link(q);
905
906             if (p != 0)
907               if ((type(q) == glue_node) || (type(p) == kern_node))
908               {
909                 link(q) = link(p);
910                 link(p) = 0;
911                 flush_node_list(p);
912               }
913           }
914           goto lab81;
915         }
916         break;
917
918       case kern_node:
919         {
920           math_kern(q, cur_mu);
921           goto lab81;
922         }
923         break;
924
925       default:
926         {
927           confusion("mlist1");
928           return;       // abort_flag set
929         }
930         break;
931     }
932
933     switch (math_type(nucleus(q)))
934     {
935       case math_char:
936       case math_text_char:
937         {
938           fetch(nucleus(q));
939
940           if ((cur_i.b0 > 0))
941           {
942             delta = char_italic(cur_f, cur_i);
943             p = new_character(cur_f, cur_c);
944
945             if ((math_type(nucleus(q)) == math_text_char) && (space(cur_f) != 0))
946               delta = 0;
947
948             if ((math_type(subscr(q)) == 0) && (delta != 0))
949             {
950               link(p) = new_kern(delta);
951               delta = 0;
952             }
953           }
954           else
955             p = 0;
956         }
957         break;
958
959       case 0:
960         p = 0;
961         break;
962
963       case sub_box:
964         p = info(nucleus(q));
965         break;
966
967       case sub_mlist:
968         {
969           cur_mlist = info(nucleus(q));
970           save_style = cur_style;
971           mlist_penalties = false;
972           mlist_to_hlist();
973           cur_style = save_style;
974
975           {
976             if (cur_style < script_style)
977               cur_size = text_size;
978             else
979               cur_size = 16 * ((cur_style - text_style) / 2);
980
981             cur_mu = x_over_n(math_quad(cur_size), 18);
982           }
983
984           p = hpack(link(temp_head), 0, 1);
985         }
986         break;
987
988       default:
989         {
990           confusion("mlist2");
991           return;       // abort_flag set
992         }
993         break;
994     }
995   
996     new_hlist(q) = p;
997
998     if ((math_type(subscr(q)) == 0) && (math_type(supscr(q)) == 0))
999       goto lab82;
1000
1001     make_scripts(q, delta);
1002 lab82:
1003     z = hpack(new_hlist(q), 0, 1);
1004
1005     if (height(z) > max_h)
1006       max_h = height(z);
1007
1008     if (depth(z) > max_d)
1009       max_d = depth(z);
1010
1011     free_node(z, box_node_size);
1012 lab80:
1013     r = q;
1014     r_type = type(r);
1015 lab81:
1016     q = link(q);
1017   }
1018
1019   if (r_type == bin_noad)
1020     type(r) = ord_noad;
1021
1022   p = temp_head;
1023   link(p) = 0;
1024   q = mlist;
1025   r_type = 0;
1026   cur_style = style;
1027
1028   {
1029     if (cur_style < script_style)
1030       cur_size = text_size;
1031     else
1032       cur_size = 16 *((cur_style - text_style) / 2);
1033
1034     cur_mu = x_over_n(math_quad(cur_size), 18);
1035   }
1036
1037   while (q != 0)
1038   {
1039     t = ord_noad;
1040     s = noad_size;
1041     pen = inf_penalty;
1042
1043     switch (type(q))
1044     {
1045       case op_noad:
1046       case open_noad:
1047       case close_noad:
1048       case punct_noad:
1049       case inner_noad:
1050         t = type(q);
1051         break;
1052
1053       case bin_noad:
1054         {
1055           t = bin_noad;
1056           pen = bin_op_penalty;
1057         }
1058         break;
1059
1060       case rel_noad:
1061         {
1062           t = rel_noad;
1063           pen = rel_penalty;
1064         }
1065         break;
1066
1067       case ord_noad:
1068       case vcenter_noad:
1069       case over_noad:
1070       case under_noad:
1071         ;
1072         break;
1073
1074       case radical_noad:
1075         s = radical_noad_size;
1076         break;
1077
1078       case accent_noad:
1079         s = accent_noad_size;
1080         break;
1081
1082       case fraction_noad:
1083         {
1084           t = inner_noad;
1085           s = fraction_noad_size;
1086         }
1087         break;
1088
1089       case left_noad:
1090       case right_noad:
1091         t = make_left_right(q, style, max_d, max_h);
1092         break;
1093
1094       case style_node:
1095         {
1096           cur_style = subtype(q);
1097           s = style_node_size;
1098
1099           {
1100             if (cur_style < script_style)
1101               cur_size = text_size;
1102             else
1103               cur_size = 16 *((cur_style - text_style) / 2);
1104
1105             cur_mu = x_over_n(math_quad(cur_size), 18);
1106           }
1107
1108           goto lab83;
1109         }
1110         break;
1111
1112       case whatsit_node:
1113       case penalty_node:
1114       case rule_node:
1115       case disc_node:
1116       case adjust_node:
1117       case ins_node:
1118       case mark_node:
1119       case glue_node:
1120       case kern_node:
1121         {
1122           link(p) = q;
1123           p = q;
1124           q = link(q);
1125           link(p) = 0;
1126           goto lab30;
1127         }
1128         break;
1129
1130       default:
1131         {
1132           confusion("mlist3");
1133           return;       // abort_flag set
1134         }
1135         break;
1136     }
1137
1138     if (r_type > 0)
1139     {
1140       switch (str_pool[r_type * 8 + t + magic_offset])
1141       {
1142         case '0':
1143           x = 0;
1144           break;
1145
1146         case '1':
1147           if (cur_style < script_style)
1148             x = thin_mu_skip_code;
1149           else
1150             x = 0;
1151           break;
1152
1153         case '2':
1154           x = thin_mu_skip_code;
1155           break;
1156
1157         case '3':
1158           if (cur_style < script_style)
1159             x = med_mu_skip_code;
1160           else
1161             x = 0;
1162           break;
1163
1164         case '4':
1165           if (cur_style < script_style)
1166             x = thick_mu_skip_code;
1167           else
1168             x = 0;
1169           break;
1170
1171         default:
1172           {
1173             confusion("mlist4");
1174             return;       // abort_flag set
1175           }
1176           break;
1177       }
1178
1179       if (x != 0)
1180       {
1181         y = math_glue(glue_par(x), cur_mu);
1182         z = new_glue(y);
1183         glue_ref_count(y) = 0;
1184         link(p) = z;
1185         p = z;
1186         subtype(z) = x + 1;
1187       }
1188     }
1189
1190     if (new_hlist(q) != 0)
1191     {
1192       link(p) = new_hlist(q);
1193
1194       do
1195         {
1196           p = link(p);
1197         }
1198       while (!(link(p) == 0));
1199     }
1200
1201     if (penalties)
1202       if (link(q) != 0)
1203         if (pen < inf_penalty)
1204         {
1205           r_type = type(link(q));
1206
1207           if (r_type != penalty_node)
1208             if (r_type != rel_noad)
1209             {
1210               z = new_penalty(pen);
1211               link(p) = z;
1212               p = z;
1213             }
1214         }
1215
1216     r_type = t;
1217 lab83:
1218     r = q;
1219     q = link(q);
1220     free_node(r, s);
1221 lab30:;
1222   }
1223 }
1224 /* sec 0772 */
1225 void push_alignment (void)
1226 {
1227   halfword p;
1228
1229   p = get_node(align_stack_node_size);
1230   link(p) = align_ptr;
1231   info(p) = cur_align;
1232   llink(p) = preamble;
1233   rlink(p) = cur_span;
1234   mem[p + 2].cint = cur_loop;
1235   mem[p + 3].cint = align_state;
1236   info(p + 4) = cur_head;
1237   link(p + 4) = cur_tail;
1238   align_ptr = p;
1239   cur_head = get_avail();
1240 }
1241 /* sec 0772 */
1242 void pop_alignment (void)
1243 {
1244   halfword p;
1245
1246   free_avail(cur_head);
1247   p = align_ptr;
1248   cur_tail = link(p + 4);
1249   cur_head = info(p + 4);
1250   align_state = mem[p + 3].cint;
1251   cur_loop = mem[p + 2].cint;
1252   cur_span = rlink(p);
1253   preamble = llink(p);
1254   cur_align = info(p);
1255   align_ptr = link(p);
1256   free_node(p, align_stack_node_size);
1257 }
1258 /* sec 0782 */
1259 void get_preamble_token (void)
1260 {
1261 lab20:
1262   get_token();
1263
1264   while ((cur_chr == span_code) && (cur_cmd == tab_mark))
1265   {
1266     get_token();
1267
1268     if (cur_cmd > max_command)
1269     {
1270       expand();
1271       get_token();
1272     }
1273   }
1274
1275   if (cur_cmd == endv)
1276   {
1277     fatal_error("(interwoven alignment preambles are not allowed)");
1278     return;     // abort_flag set
1279   }
1280
1281   if ((cur_cmd == assign_glue) && (cur_chr == glue_base + tab_skip_code))
1282   {
1283     scan_optional_equals();
1284     scan_glue(glue_val);
1285
1286     if (global_defs > 0)
1287       geq_define(glue_base + tab_skip_code, glue_ref, cur_val);
1288     else
1289       eq_define(glue_base + tab_skip_code, glue_ref, cur_val);
1290
1291     goto lab20;
1292   }
1293 }
1294 /* sec 0774 */
1295 void init_align (void)
1296 {
1297   halfword save_cs_ptr;
1298   halfword p;
1299
1300   save_cs_ptr = cur_cs;
1301   push_alignment();
1302   align_state = -1000000L;
1303
1304   if ((mode == mmode) && ((tail != cur_list.head_field) || (incompleat_noad != 0)))
1305   {
1306     print_err("Improper ");
1307     print_esc("halign");
1308     print_string(" inside $$'s");
1309     help3("Displays can use special alignments (like \\eqalignno)",
1310         "only if nothing but the alignment itself is between $$'s.",
1311         "So I've deleted the formulas that preceded this alignment.");
1312     error();
1313     flush_math();
1314   }
1315
1316   push_nest();
1317
1318   if (mode == mmode)
1319   {
1320     mode = -vmode;
1321     prev_depth = nest[nest_ptr - 2].aux_field.cint;
1322   }
1323   else if (mode > 0)
1324     mode = - (integer) mode;
1325
1326   scan_spec(align_group, false);
1327   preamble = 0;
1328   cur_align = align_head;
1329   cur_loop = 0;
1330   scanner_status = aligning;
1331   warning_index = save_cs_ptr;
1332   align_state = -1000000L;
1333
1334   while (true)
1335   {
1336     link(cur_align) = new_param_glue(tab_skip_code);
1337     cur_align = link(cur_align);
1338
1339     if (cur_cmd == car_ret)
1340       goto lab30;
1341
1342     p = hold_head;
1343     link(p) = 0;
1344
1345     while (true)
1346     {
1347       get_preamble_token();
1348
1349       if (cur_cmd == mac_param)
1350         goto lab31;
1351
1352       if ((cur_cmd <= car_ret) && (cur_cmd >= tab_mark) && (align_state == -1000000L))
1353         if ((p == hold_head) && (cur_loop == 0) && (cur_cmd == tab_mark))
1354           cur_loop = cur_align;
1355         else
1356         {
1357           print_err("Missing # inserted in alignment preamble");
1358           help3("There should be exactly one # between &'s, when an",
1359               "\\halign or \\valign is being set up. In this case you had",
1360               "none, so I've put one in; maybe that will work.");
1361           back_error();
1362           goto lab31;
1363         }
1364       else if ((cur_cmd != spacer) || (p != hold_head))
1365       {
1366         link(p) = get_avail();
1367         p = link(p);
1368         info(p) = cur_tok;
1369       }
1370     }
1371
1372 lab31:
1373     link(cur_align) = new_null_box();
1374     cur_align = link(cur_align);
1375     info(cur_align) = end_span;
1376     width(cur_align) = null_flag;  /* - 2^30 */
1377     u_part(cur_align) = link(hold_head);
1378     p = hold_head;
1379     link(p) = 0;
1380
1381     while (true)
1382     {
1383 lab22:
1384       get_preamble_token();
1385
1386       if ((cur_cmd <= car_ret) && (cur_cmd >= tab_mark) && (align_state == -1000000L))
1387         goto lab32;
1388
1389       if (cur_cmd == mac_param)
1390       {
1391         print_err("Only one # is allowed per tab");
1392         help3("There should be exactly one # between &'s, when an",
1393             "\\halign or \\valign is being set up. In this case you had",
1394             "more than one, so I'm ignoring all but the first.");
1395         error();
1396         goto lab22;
1397       }
1398
1399       link(p) = get_avail();
1400       p = link(p);
1401       info(p) = cur_tok;
1402     }
1403
1404 lab32:
1405     link(p) = get_avail();
1406     p = link(p);
1407     info(p) = end_template_token;
1408     v_part(cur_align) = link(hold_head);
1409   }
1410
1411 lab30:
1412   scanner_status = 0;
1413   new_save_level(align_group);
1414
1415   if (every_cr != 0)
1416     begin_token_list(every_cr, every_cr_text);
1417   align_peek();
1418 }
1419 /* sec 0787 */
1420 void init_span_ (halfword p)
1421 {
1422   push_nest();
1423
1424   if (mode == -hmode)
1425     space_factor = 1000;
1426   else
1427   {
1428     cur_list.aux_field.cint = ignore_depth;
1429     normal_paragraph();
1430   }
1431
1432   cur_span = p;
1433 }
1434 /* sec 0786 */
1435 void init_row (void)
1436 {
1437   push_nest();
1438
1439   mode = (-hmode - vmode) - mode;
1440
1441   if (mode == -hmode)
1442     space_factor = 0;
1443   else
1444     cur_list.aux_field.cint = 0;
1445
1446   tail_append(new_glue(glue_ptr(preamble)));
1447   subtype(tail) = tab_skip_code + 1;
1448   cur_align = link(preamble);
1449   cur_tail = cur_head;
1450   init_span(cur_align);
1451 }
1452 /* sec 0788 */
1453 void init_col (void)
1454 {
1455   extra_info(cur_align) = cur_cmd;
1456
1457   if (cur_cmd == omit)
1458     align_state = 0;
1459   else
1460   {
1461     back_input();
1462     begin_token_list(u_part(cur_align), u_template);
1463   }
1464 }
1465 /* fin_col() moved to end to hide in pragma (g, "off") */
1466 /* may need to move more ? everything calling new_null_box() ? */
1467 /* sec 0799 */
1468 void fin_row (void)
1469 {
1470   halfword p;
1471
1472   if (mode == -hmode)
1473   {
1474     p = hpack(link(head), 0, 1);
1475     pop_nest();
1476     append_to_vlist(p);
1477
1478     if (cur_head != cur_tail)
1479     {
1480       link(tail) = link(cur_head);
1481       tail = cur_tail;
1482     }
1483   }
1484   else
1485   {
1486     p = vpackage(link(head), 0, 1, 1073741823L);   /* 2^30 - 1 */
1487     pop_nest();
1488     link(tail) = p;
1489     tail = p;
1490     space_factor = 1000;
1491   }
1492
1493   type(p) = unset_node;
1494   glue_stretch(p) = 0;
1495
1496   if (every_cr != 0)
1497     begin_token_list(every_cr, every_cr_text);
1498
1499   align_peek();
1500 }
1501 /* sec 0800 */
1502 void fin_align (void)
1503 {
1504   halfword p, q, r, s, u, v;
1505   scaled t, w;
1506   scaled o;
1507   halfword n;
1508   scaled rule_save;
1509   memory_word aux_save;
1510
1511   if (cur_group != align_group)
1512   {
1513     confusion("align1");
1514     return;       // abort_flag set
1515   }
1516
1517   unsave();
1518
1519   if (cur_group != align_group)
1520   {
1521     confusion("align0");
1522     return;       // abort_flag set
1523   }
1524
1525   unsave();
1526
1527   if (nest[nest_ptr - 1].mode_field == mmode)
1528     o = display_indent;
1529   else
1530     o = 0;
1531
1532   q = link(preamble);
1533
1534   do
1535     {
1536       flush_list(u_part(q));
1537       flush_list(v_part(q));
1538       p = link(link(q));
1539
1540       if (width(q) == null_flag) /* - 2^30 */
1541       {
1542         width(q) = 0;
1543         r = link(q);
1544         s = glue_ptr(r);
1545
1546         if (s != zero_glue)
1547         {
1548           add_glue_ref(zero_glue);
1549           delete_glue_ref(s);
1550           glue_ptr(c) = zero_glue;
1551         }
1552       }
1553
1554       if (info(q) != end_span)
1555       {
1556         t = width(q) + width(glue_ptr(link(q)));
1557         r = info(q);
1558         s = end_span;
1559         info(s) = p;
1560         n = min_quarterword + 1;
1561
1562         do
1563           {
1564             width(r) = width(r) - t;
1565             u = info(r);
1566
1567             while (link(r) > n)
1568             {
1569               s = info(s);
1570               n = link(info(s)) + 1;
1571             }
1572
1573             if (link(r) < n)
1574             {
1575               info(r) = info(s);
1576               info(s) = r;
1577               decr(link(r));
1578               s = r;
1579             }
1580             else
1581             {
1582               if (width(r) > width(info(s)))
1583                 width(info(s)) = width(r);
1584
1585               free_node(r, span_node_size);
1586             }
1587
1588             r = u;
1589           }
1590         while (!(r == end_span));
1591       }
1592
1593       type(q) = unset_node;
1594       span_count(q) = min_quarterword;
1595       height(q) = 0;
1596       depth(q) = 0;
1597       glue_order(q) = normal;
1598       glue_sign(q) = normal;
1599       glue_stretch(q) = 0;
1600       glue_shrink(q) = 0;
1601       q = p;
1602     }
1603   while (!(q == 0));
1604
1605   save_ptr = save_ptr - 2;
1606   pack_begin_line = - (integer) mode_line;
1607
1608   if (mode == -vmode)
1609   {
1610     rule_save = overfull_rule;
1611     overfull_rule = 0;
1612     p = hpack(preamble, saved(1), saved(0));
1613     overfull_rule = rule_save;
1614   }
1615   else
1616   {
1617     q = link(preamble);
1618
1619     do
1620       {
1621         height(q) = width(q);
1622         width(q) = 0;
1623         q = link(link(q));
1624       }
1625     while (!(q == 0));
1626
1627     p = vpackage(preamble, saved(1), saved(0), 1073741823L);  /* 2^30 - 1 */
1628     q = link(preamble);
1629
1630     do
1631       {
1632         width(q) = height(q);
1633         height(q) = 0;
1634         q = link(link(q));
1635       }
1636     while (!(q == 0));
1637   }
1638
1639   pack_begin_line = 0;
1640   q = link(head);
1641   s = head;
1642
1643   while (q != 0)
1644   {
1645     if (!(q >= hi_mem_min))
1646       if (type(q) == unset_node)
1647       {
1648         if (mode == -vmode)
1649         {
1650           type(q) = hlist_node;
1651           width(q) = width(p);
1652         }
1653         else
1654         {
1655           type(q) = vlist_node;
1656           height(q) = height(p);
1657         }
1658
1659         glue_order(q) = glue_order(p);
1660         glue_sign(q) = glue_sign(p);
1661         glue_set(q) = glue_set(p);
1662         shift_amount(q) = o;
1663         r = link(list_ptr(q));
1664         s = link(list_ptr(p));
1665
1666         do
1667           {
1668             n = span_count(r);
1669             t = width(s);
1670             w = t;
1671             u = hold_head;
1672
1673             while (n > min_quarterword)
1674             {
1675               decr(n);
1676               s = link(s);
1677               v = glue_ptr(s);
1678               link(u) = new_glue(v);
1679               u = link(u);
1680               subtype(u) = tab_skip_code + 1;
1681               t = t + width(v);
1682
1683               if (glue_sign(p) == stretching)
1684               {
1685                 if (stretch_order(v) == glue_order(p))
1686                   t = t + round(glue_set(p) * stretch(v));
1687               }
1688               else if (glue_sign(p) == shrinking)
1689               {
1690                 if (shrink_order(v) == glue_order(p))
1691                   t = t - round(glue_set(p) * shrink(v));
1692               }
1693
1694               s = link(s);
1695               link(u) = new_null_box();
1696               u = link(u);
1697               t = t + width(s);
1698
1699               if (mode == -vmode)
1700                 width(u) = width(s);
1701               else
1702               {
1703                 type(u) = vlist_node;
1704                 height(u) = width(s);
1705               }
1706             }
1707             
1708
1709             if (mode == -vmode)
1710             {
1711               height(r) = height(q);
1712               depth(r) = depth(q);
1713
1714               if (t == width(r))
1715               {
1716                 glue_sign(r) = normal;
1717                 glue_order(r) = normal;
1718                 glue_set(r) = 0.0;
1719               }
1720               else if (t > width(r))
1721               {
1722                 glue_sign(r) = stretching;
1723
1724                 if (glue_stretch(r) == 0)
1725                   glue_set(r) = 0.0;
1726                 else
1727                   glue_set(r) = (t - width(r)) / ((double) glue_stretch(r));
1728               }
1729               else
1730               {
1731                 glue_order(r) = glue_sign(r);
1732                 glue_sign(r) = shrinking;
1733
1734                 if (glue_shrink(r) == 0)
1735                   glue_set(r) = 0.0;
1736                 else if ((glue_order(r) == normal) && (width(r) - t > glue_shrink(r)))
1737                   glue_set(r) = 1.0;
1738                 else
1739                   glue_set(r) = (width(r) - t)/ ((double) glue_shrink(r));
1740               }
1741
1742               width(r) = w;
1743               type(r) = hlist_node;
1744             }
1745             else
1746             {
1747               width(r) = width(q);
1748
1749               if (t == height(r))
1750               {
1751                 glue_sign(r) = normal;
1752                 glue_order(r) = normal;
1753                 glue_set(r) = 0.0;
1754               }
1755               else if (t > height(r))
1756               {
1757                 glue_sign(r) = stretching;
1758
1759                 if (glue_stretch(r) == 0)
1760                   glue_set(r) = 0.0;
1761                 else
1762                   glue_set(r) = (t - height(r)) / ((double) glue_stretch(r));
1763               }
1764               else
1765               {
1766                 glue_order(r) = glue_sign(r);
1767                 glue_sign(r) = shrinking;
1768
1769                 if (glue_shrink(r) == 0)
1770                   glue_set(r) = 0.0;
1771                 else if ((glue_order(r) == normal) && (height(r) - t > glue_shrink(r)))
1772                   glue_set(r) = 1.0;
1773                 else
1774                   glue_set(r) = (height(r) - t) / ((double) glue_shrink(r));
1775               }
1776
1777               height(r) = w;
1778               type(r) = vlist_node;
1779             }
1780
1781             shift_amount(r) = 0;
1782
1783             if (u != hold_head)
1784             {
1785               link(u) = link(r);
1786               link(r) = link(hold_head);
1787               r = u;
1788             }
1789
1790             r = link(link(r));
1791             s = link(link(s));
1792           }
1793         while(!(r == 0));
1794       }
1795       else if (type(q) == rule_node)
1796       {
1797         if ((width(q) == -1073741824L))  /* 2^30  */
1798           width(q) = width(p);
1799
1800         if ((height(q) == -1073741824L))  /* 2^30  */
1801           height(q) = height(p);
1802
1803         if ((depth(q) == -1073741824L))  /* 2^30  */
1804           depth(q) = depth(p);
1805
1806         if (o != 0)
1807         {
1808           r = link(q);
1809           link(q) = 0;
1810           q = hpack(q, 0, 1);
1811           shift_amount(q) = o;
1812           link(q) = r;
1813           link(s) = q;
1814         }
1815       }
1816     s = q;
1817     q = link(q);
1818   }
1819
1820   flush_node_list(p);
1821   pop_alignment();
1822   aux_save = cur_list.aux_field;
1823   p = link(head);
1824   q = tail;
1825   pop_nest();
1826
1827   if (mode == mmode)
1828   {
1829     do_assignments();
1830
1831     if (cur_cmd != math_shift)
1832     {
1833       print_err("Missing $$ inserted");
1834       help2("Displays can use special alignments (like \\eqalignno)",
1835           "only if nothing but the alignment itself is between $$'s.");
1836       back_error();
1837     }
1838     else
1839     {
1840       get_x_token();
1841
1842       if (cur_cmd != math_shift)
1843       {
1844         print_err("Display math should end with $$");
1845         help2("The `$' that I just saw supposedly matches a previous `$$'.",
1846             "So I shall assume that you typed `$$' both times.");
1847         back_error();
1848       }
1849     }
1850
1851     pop_nest();
1852     tail_append(new_penalty(pre_display_penalty));
1853     tail_append(new_param_glue(above_display_skip_code));
1854     link(tail) = p;
1855
1856     if (p != 0)
1857       tail = q;
1858
1859     tail_append(new_penalty(post_display_penalty));
1860     tail_append(new_param_glue(below_display_skip_code));
1861     cur_list.aux_field.cint = aux_save.cint;
1862     resume_after_display();
1863   }
1864   else
1865   {
1866     cur_list.aux_field = aux_save;
1867     link(tail) = p;
1868
1869     if (p != 0)
1870       tail = q;
1871
1872     if (mode == vmode)
1873     {
1874       build_page();
1875     }
1876   }
1877 }
1878 /* used to be align_peek, zfintieshrink, etc in old tex5.c */
1879 /************************************************************************/
1880 /* moved down here to avoid questions about pragma optimize */
1881 /* #pragma optimize("g", off) */
1882 /* for MC VS compiler */
1883 /* Moved down here 96/Oct/12 in response to problem with texerror.tex */
1884 /* pragma optimize("a", off) not strong enough - this may slow things */
1885 /* sec 0791 */
1886 bool fin_col (void)
1887 {
1888   halfword p;
1889   halfword q, r;
1890   halfword s;
1891   halfword u;
1892   scaled w;
1893   glue_ord o;
1894   halfword n;
1895
1896   if (cur_align == 0)
1897   {
1898     confusion("endv");
1899     return 0;       // abort_flag set
1900   }
1901
1902   q = link(cur_align);
1903
1904   if (q == 0)
1905   {
1906     confusion("endv");
1907     return 0;       // abort_flag set
1908   }
1909
1910   if (align_state < 500000L)
1911   {
1912     fatal_error("(interwoven alignment preambles are not allowed)");
1913     return 0;     // abort_flag set
1914   }
1915
1916   p = link(q);
1917
1918   if ((p == 0) && (extra_info(cur_align) < cr_code))
1919     if (cur_loop != 0)
1920     {
1921 /*  potential problem here if new_null_box causes memory reallocation ??? */
1922 /*  compiler optimization does not refresh `mem' loaded in registers ? */
1923       link(q) = new_null_box();
1924       p = link(q);
1925       info(p) = end_span;
1926       width(p) = null_flag;
1927       cur_loop = link(cur_loop);
1928       q = hold_head;
1929       r = u_part(cur_loop);
1930
1931       while (r != 0)
1932       {
1933         link(q) = get_avail();
1934         q = link(q);
1935         info(q) = info(r);
1936         r = link(r);
1937       }
1938
1939       link(q) = 0;
1940       u_part(p) = link(hold_head);
1941       q = hold_head;
1942       r = v_part(cur_loop);
1943
1944       while (r != 0)
1945       {
1946         link(q) = get_avail();
1947         q = link(q);
1948         info(q) = info(r);
1949         r = link(r);
1950       }
1951
1952       link(q) = 0;
1953       v_part(p) = link(hold_head);
1954       cur_loop = link(cur_loop);
1955       link(p) = new_glue(glue_ptr(cur_loop));
1956     }
1957     else
1958     {
1959       print_err("Extra alignment tab has been changed to ");
1960       print_esc("cr");
1961       help3("You have given more \\span or & marks than there were",
1962           "in the preamble to the \\halign or \\valign now in progress.",
1963           "So I'll assume that you meant to type \\cr instead.");
1964       extra_info(cur_align) = cr_code;
1965       error();
1966     }
1967
1968   if (extra_info(cur_align) != span_code)
1969   {
1970     unsave();
1971
1972     new_save_level(align_group);
1973
1974     {
1975       if (mode == -hmode)
1976       {
1977         adjust_tail = cur_tail;
1978         u = hpack(link(head), 0, 1);
1979         w = width(u);
1980         cur_tail = adjust_tail;
1981         adjust_tail = 0;
1982       }
1983       else
1984       {
1985         u = vpackage(link(head), 0, 1, 0);
1986         w = height(u);
1987       }
1988
1989       n = min_quarterword;
1990
1991       if (cur_span != cur_align)
1992       {
1993         q = cur_span;
1994
1995         do
1996           {
1997             incr(n);
1998             q = link(link(q));
1999           }
2000         while (!(q == cur_align));
2001
2002         if (n > max_quarterword)
2003         {
2004           confusion("256 spans");   /* 256 spans --- message wrong now, but ... */
2005           return 0;       // abort_flag set
2006         }
2007
2008         q = cur_span;
2009
2010         while (link(info(q)) < n)
2011           q = info(q);
2012
2013         if (link(info(q)) > n)
2014         {
2015           s = get_node(span_node_size);
2016           info(s) = info(q);
2017           link(s) = n;
2018           info(q) = s;
2019           width(s) = w;
2020         }
2021         else if (width(info(q)) < w)
2022           width(info(q)) = w;
2023       }
2024       else if (w > width(cur_align))
2025         width(cur_align) = w;
2026
2027       type(u) = unset_node;
2028       span_count(u) = n;
2029
2030       if (total_stretch[filll] != 0)
2031         o = filll;
2032       else if (total_stretch[fill] != 0)
2033         o = fill;
2034       else if (total_stretch[fil] != 0)
2035         o = fil;
2036       else
2037         o = normal;
2038
2039       glue_order(u) = o;
2040       glue_stretch(u) = total_stretch[o];
2041
2042       if (total_shrink[filll] != 0)
2043         o = filll;
2044       else if (total_shrink[fill] != 0)
2045         o = fill;
2046       else if (total_shrink[fil] != 0)
2047         o = fil;
2048       else
2049         o = normal;
2050
2051       glue_sign(u) = o;
2052       glue_shrink(u) = total_shrink[o];
2053       pop_nest();
2054       link(tail) = u;
2055       tail = u;
2056     }
2057
2058     tail_append(new_glue(glue_ptr(link(cur_align))));
2059     subtype(tail) = tab_skip_code + 1;
2060
2061     if (extra_info(cur_align) >= cr_code)
2062     {
2063       return true;
2064     }
2065
2066     init_span(p);
2067   }
2068
2069   align_state = 1000000L;
2070
2071   do
2072     {
2073       get_x_token();
2074     }
2075   while (!(cur_cmd != spacer));
2076
2077   cur_align = p;
2078   init_col();
2079
2080   return false;
2081 }
2082 /* #pragma optimize ("g", on) */        /* for MC VS compiler */
2083 /* #pragma optimize ("g",) */         /* 94/Jan/25 */
2084 /* #pragma optimize ("", on) */           /* 96/Sep/12 */
2085 /* #pragma optimize("g", off) */          /* for MC VS compiler */
2086 /* sec 0749 */
2087 scaled make_op_(halfword q)
2088 {
2089   scaled delta;
2090   halfword p, v, x, y, z;
2091   quarterword c;
2092   ffourquarters i;
2093   scaled shift_up, shift_down;
2094
2095   if ((subtype(q) == normal) && (cur_style < text_style))
2096     subtype(q) = limits;
2097
2098   if (math_type(nucleus(q)) == math_char)
2099   {
2100     fetch(nucleus(q));
2101
2102     if ((cur_style < text_style) && (char_tag(cur_i) == list_tag))
2103     {
2104       c = rem_byte(cur_i);
2105       i = char_info(cur_f, c);
2106
2107       if ((i.b0 > 0))
2108       {
2109         cur_c = c;
2110         cur_i = i;
2111         character(nucleus(q)) = c;
2112       }
2113     }
2114
2115     delta = char_italic(cur_f, cur_i);
2116     x = clean_box(nucleus(q), cur_style);
2117
2118     if ((math_type(subscr(q)) != 0) && (subtype(q) != limits))
2119       width(x) = width(x) - delta;
2120
2121     shift_amount(x) = half(height(x) - depth(x)) - axis_height(cur_size);
2122     math_type(nucleus(q)) = sub_box;
2123     info(nucleus(q)) = x;
2124   }
2125   else
2126     delta = 0;
2127
2128   if (subtype(q) == limits)
2129   {
2130     x = clean_box(supscr(q), sup_style(cur_style));
2131     y = clean_box(nucleus(q), cur_style);
2132     z = clean_box(subscr(q), sub_style(cur_style));
2133     v = new_null_box();
2134     type(v) = vlist_node;
2135     width(v) = width(y);
2136
2137     if (width(x) > width(v))
2138       width(v) = width(x);
2139
2140     if (width(z) > width(v))
2141       width(v) = width(z);
2142
2143     x = rebox(x, width(v));
2144     y = rebox(y, width(v));
2145     z = rebox(z, width(v));
2146     shift_amount(x) = half(delta);
2147     shift_amount(z) = - (integer) shift_amount(x);
2148     height(v) = height(y);
2149     depth(v) = depth(y);
2150
2151     if (math_type(supscr(q)) == 0)
2152     {
2153       free_node(x, box_node_size);
2154       list_ptr(v) = y;
2155     }
2156     else
2157     {
2158       shift_up = big_op_spacing3 - depth(x);
2159
2160       if (shift_up < big_op_spacing1)
2161         shift_up = big_op_spacing1;
2162
2163       p = new_kern(shift_up);
2164       link(p) = y;
2165       link(x) = p;
2166       p = new_kern(big_op_spacing5);
2167       link(p) = x;
2168       list_ptr(v) = p;
2169       height(v) = height(v) + big_op_spacing5 + height(x) + depth(x) + shift_up;
2170     }
2171
2172     if (math_type(subscr(q)) == 0)
2173       free_node(z, box_node_size);
2174     else
2175     {
2176       shift_down = big_op_spacing4 - height(z);
2177
2178       if (shift_down < big_op_spacing2)
2179         shift_down = big_op_spacing2;
2180
2181       p = new_kern(shift_down);
2182       link(y) = p;
2183       link(p) = z;
2184       p = new_kern(big_op_spacing5);
2185       link(z) = p;
2186       depth(v) = depth(v) + big_op_spacing5 + height(z) + depth(z) + shift_down;
2187     }
2188
2189     new_hlist(q) = v;
2190   }
2191
2192   return delta;
2193 }
2194 /* #pragma optimize ("g", on) */        /* for MC VS compiler */
2195 /* #pragma optimize ("g",) */         /* 94/Jan/25 */
2196 /* #pragma optimize ("", on) */           /* 96/Sep/12 */
2197 /* #pragma optimize ("g", off) */
2198 /* sec 0756 */
2199 void make_scripts_(halfword q, scaled delta)
2200 {
2201   halfword p, x, y, z;
2202   scaled shift_up, shift_down, clr;
2203   small_number t;
2204
2205   p = new_hlist(q);
2206
2207   if ((p >= hi_mem_min))
2208   {
2209     shift_up = 0;
2210     shift_down = 0;
2211   }
2212   else
2213   {
2214     z = hpack(p, 0, 1);
2215
2216     if (cur_style < script_style)
2217       t = script_size;
2218     else
2219       t = script_script_size;
2220
2221     shift_up = height(z) - sup_drop(t);
2222     shift_down = depth(z) + sub_drop(t);
2223     free_node(z, box_node_size);
2224   }
2225
2226   if (math_type(supscr(q)) == 0)
2227   {
2228     x = clean_box(subscr(q), sub_style(cur_style));
2229     width(x) = width(x) + script_space;
2230
2231     if (shift_down < sub1(cur_size))
2232       shift_down = sub1(cur_size);
2233
2234     clr = height(x) -(abs(math_x_height(cur_size) * 4) / 5);
2235
2236     if (shift_down < clr)
2237       shift_down = clr;
2238
2239     shift_amount(x) = shift_down;
2240   }
2241   else
2242   {
2243     {
2244       x = clean_box(supscr(q), sup_style(cur_style));
2245       width(x) = width(x) + script_space;
2246
2247       if (odd(cur_style))
2248         clr = sup3(cur_size);
2249       else if (cur_style < text_style)
2250         clr = sup1(cur_size);
2251       else
2252         clr = sup2(cur_size);
2253
2254       if (shift_up < clr)
2255         shift_up = clr;
2256
2257       clr = depth(x) +(abs(math_x_height(cur_size)) / 4);
2258
2259       if (shift_up < clr)
2260         shift_up = clr;
2261     }
2262
2263     if (math_type(subscr(q)) == 0)
2264       shift_amount(x) = - (integer) shift_up;
2265     else
2266     {
2267       y = clean_box(subscr(q), sub_style(cur_style));
2268       width(y) = width(y) + script_space;
2269
2270       if (shift_down < sub2(cur_size))
2271         shift_down = sub2(cur_size);
2272
2273       clr = 4 * default_rule_thickness - ((shift_up - depth(x)) - (height(y) - shift_down));
2274
2275       if (clr > 0)
2276       {
2277         shift_down = shift_down + clr;
2278
2279         clr = (abs(math_x_height(cur_size) * 4) / 5) - (shift_up - depth(x));
2280
2281         if (clr > 0)
2282         {
2283           shift_up = shift_up + clr;
2284           shift_down = shift_down - clr;
2285         }
2286       }
2287
2288       shift_amount(x) = delta;
2289       p = new_kern((shift_up - depth(x)) - (height(y) - shift_down));
2290       link(x) = p;
2291       link(p) = y;
2292       x = vpackage(x, 0, 1, 1073741823L);  /* 2^30 - 1 */
2293       shift_amount(x) = shift_down;
2294     }
2295   }
2296
2297   if (new_hlist(q) == 0)
2298     new_hlist(q) = x;
2299   else
2300   {
2301     p = new_hlist(q);
2302
2303     while (link(p) != 0)
2304       p = link(p);
2305
2306     link(p) = x;
2307   }
2308 }
2309 /* #pragma optimize ("g", on) */        /* 96/Sep/12 */
2310 /* #pragma optimize ("g") */          /* 94/Jan/25 */
2311 /* #pragma optimize ("", on) */           /* 96/Sep/12 */