OSDN Git Service

fd217d578286bd0fc6aa8b32e7232c9fec43c857
[putex/putex.git] / src / texsourc / tex4.c
1 /* Copyright 2014 Clerk Ma
2
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.
7
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.
12
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
16    02110-1301 USA.  */
17
18 #define EXTERN extern
19
20 #include "texd.h"
21
22 /* sec 0581 */
23 void char_warning_(internal_font_number f, eight_bits c)
24
25   if (tracing_lost_chars > 0)
26   {
27     if (show_missing == 0)
28       begin_diagnostic();
29
30     if (show_missing) /* add ! before 94/June/10 */
31     {
32       print_nl("! ");
33       prints("Missing character: there is no ");
34     }
35     else
36       print_nl("Missing character: there is no ");
37
38     print(c);
39
40     if (show_numeric) /* bkph 93/Dec/21 */
41     {
42       print_char(' ');
43       print_char('(');
44
45       if (c / 100 > 0)
46       {
47         print_char('0' + c / 100);
48         c = c - (c / 100) * 100;
49         print_char('0' + c / 10);
50       }
51       else
52       {
53         c = c - (c / 100) * 100;
54         if (c / 10 > 0)
55           print_char('0' + c / 10);
56       }
57       print_char('0' + c % 10);
58       print_char(')');
59     }
60
61     prints(" in font ");
62     slow_print(font_name[f]);
63     print_char('!');
64
65     if (show_missing)
66     {
67       if (f != 0)
68         show_context();     /* not if its the nullfont */
69     }
70
71     if (show_missing == 0)
72       end_diagnostic(false);
73
74     missing_characters++;           /* bkph 93/Dec/16 */
75   }
76 }
77 /* sec 0582 */
78 halfword new_character_(internal_font_number f, eight_bits c)
79 {
80   halfword p;
81
82   if (font_bc[f] <= c)
83     if (font_ec[f] >= c)
84       if (char_exists(char_info(f, c)))
85       {
86         p = get_avail();
87         font(p) = f;
88         character(p) = c;
89         return p;
90       }
91
92   char_warning(f, c);
93   return 0;
94 }
95 /* sec 0598 */
96 void dvi_swap (void)
97
98   if (trace_flag)
99   {
100     show_char('\n');
101     sprintf(log_line, "dvi_swap() %lld", dvi_gone);
102     show_line(log_line, 0);
103   }
104
105   if (dvi_limit == dvi_buf_size)
106   {
107     write_dvi(0, half_buf - 1);
108     dvi_limit = half_buf;
109     dvi_offset = dvi_offset + dvi_buf_size;
110     dvi_ptr = 0;
111   }
112   else
113   {
114     write_dvi(half_buf, dvi_buf_size - 1);
115     dvi_limit = dvi_buf_size;
116   }
117
118   dvi_gone = dvi_gone + half_buf;
119 }
120 /* sec 0600 */
121 void dvi_four_(integer x)
122
123   if (x >= 0)
124     dvi_out(x / 0100000000);
125   else
126   {
127     x = x + 010000000000;
128     x = x + 010000000000;
129     dvi_out((x / 0100000000) + 128);
130   }
131
132   x = x % 0100000000;
133   dvi_out(x / 0200000);
134   x = x % 0200000;
135   dvi_out(x / 0400);
136   dvi_out(x % 0400);
137 }
138 /* sec 0601 */
139 void dvi_pop_(integer l)
140 {
141   if ((l == dvi_offset + dvi_ptr) && (dvi_ptr > 0))
142     decr(dvi_ptr);
143   else
144     dvi_out(pop);
145 }
146 /* sec 0602 */
147 void dvi_font_def_(internal_font_number f)
148 {
149   pool_pointer k;
150
151 #ifdef INCREASEFONTS
152   if (f <= 256)
153   {
154     dvi_out(fnt_def1);
155     dvi_out(f - 1);
156   }
157   else
158   {
159     dvi_out(fnt_def2);
160     dvi_out(((f - 1) >> 8));
161     dvi_out(((f - 1) & 255));
162   }
163 #else
164   dvi_out(fnt_def1);
165   dvi_out(f - 1);
166 #endif
167
168   dvi_out(font_check[f].b0);
169   dvi_out(font_check[f].b1);
170   dvi_out(font_check[f].b2);
171   dvi_out(font_check[f].b3);
172   dvi_four(font_size[f]); 
173   dvi_four(font_dsize[f]);
174   dvi_out(length(font_area[f]));
175   dvi_out(length(font_name[f]));
176
177   for (k = str_start[font_area[f]]; k <= str_start[font_area[f] + 1] - 1; k++)
178     dvi_out(str_pool[k]);
179
180   for (k = str_start[font_name[f]]; k <= str_start[font_name[f] + 1] - 1; k++)
181     dvi_out(str_pool[k]);
182 }
183 /* sec 0607 */
184 void zmovement(scaled w, eight_bits o)
185 {
186   small_number mstate;
187   halfword p, q;
188   integer k;
189
190   q = get_node(movement_node_size);
191   width(q) = w;
192   location(q) = dvi_offset + dvi_ptr;
193
194   if (o == down1)
195   {
196     link(q) = down_ptr;
197     down_ptr = q;
198   }
199   else
200   {
201     link(q) = right_ptr;
202     right_ptr = q;
203   }
204
205   p = link(q);
206   mstate = none_seen;
207
208   while (p != 0)
209   {
210     if (width(p) == w)
211       switch(mstate + info(p))
212       {
213         case none_seen + yz_OK:
214         case none_seen + y_OK:
215         case z_seen + yz_OK:
216         case z_seen + y_OK:
217           if (location(p) < dvi_gone)
218             goto not_found;
219           else
220           {
221             k = location(p) - dvi_offset;
222
223             if (k < 0)
224               k = k + dvi_buf_size;
225
226             dvi_buf[k] = dvi_buf[k] + y1 - down1;
227             info(p) = y_here;
228             goto found;
229           }
230           break;
231
232         case none_seen + z_OK:
233         case y_seen + yz_OK:
234         case y_seen + z_OK:
235           if (location(p) < dvi_gone)
236             goto not_found;
237           else
238           {
239             k = location(p) - dvi_offset;
240
241             if (k < 0)
242               k = k + dvi_buf_size;
243
244             dvi_buf[k] = dvi_buf[k] + z1 - down1;
245             info(p) = z_here;
246             goto found;
247           }
248           break;
249
250         case none_seen + y_here:
251         case none_seen + z_here:
252         case y_seen + z_here:
253         case z_seen + y_here:
254           goto found;
255           break;
256
257         default:
258           break;
259       }
260     else
261       switch (mstate + info(p))
262       {
263         case none_seen + y_here:
264           mstate = y_seen;
265           break;
266
267         case none_seen + z_here:
268           mstate = z_seen;
269           break;
270
271         case y_seen + z_here:
272         case z_seen + y_here:
273           goto not_found;
274           break;
275
276         default:
277           break;
278       }
279
280     p = link(p);
281   }
282 not_found:
283
284   info(q) = yz_OK;
285
286   if (abs(w) >= 8388608L) /* 2^23 */
287   {
288     dvi_out(o + 3);
289     dvi_four(w);
290     return;
291   }
292
293   if (abs(w) >= 32768L)
294   {
295     dvi_out(o + 2);
296
297     if (w < 0)
298       w = w + 16777216L;  /* 2^24 */
299     //dvi_out(w / 65536L);
300     dvi_out((w >> 16));
301 /*    w = w % 65536L; */
302     w = w & 65535L;
303     goto lab2;
304   }
305
306   if (abs(w)>= 128)
307   {
308     dvi_out(o + 1);
309
310     if (w < 0)
311       w = w + 65536L;
312
313     goto lab2;
314   }
315
316   dvi_out(o);
317
318   if (w < 0)
319     w = w + 256;
320
321   goto lab1;
322
323 lab2:
324   dvi_out(w / 256);
325
326 lab1:
327   dvi_out(w % 256);
328   return;
329
330 found:
331   info(q) = info(p);
332
333   if (info(q) == y_here)
334   {
335     dvi_out(o + y0 - down1);
336
337     while (link(q) != p)
338     {
339       q = link(q);
340
341       switch (info(q))
342       {
343         case yz_OK:
344           info(q) = z_OK;
345           break;
346
347         case y_OK:
348           info(q) = d_fixed;
349           break;
350
351         default:
352           break;
353       }
354     }
355   }
356   else
357   {
358     dvi_out(o + z0 - down1);
359
360     while (link(q) != p)
361     {
362       q = link(q);
363
364       switch (info(q))
365       {
366         case yz_OK:
367           info(q) = y_OK;
368           break;
369
370         case z_OK:
371           info(q) = d_fixed;
372           break;
373
374         default:
375           break;
376       }
377     }
378   }
379 }
380 /* sec 0615 */
381 void prune_movements_(integer l)
382 {
383   halfword p;
384
385   while (down_ptr != 0)
386   {
387     if (location(down_ptr) < l)
388       goto done;
389
390     p = down_ptr;
391     down_ptr = link(p);
392     free_node(p, movement_node_size);
393   }
394
395 done:
396   while (right_ptr != 0)
397   {
398     if (location(right_ptr) < l)
399       return;
400
401     p = right_ptr;
402     right_ptr = link(p);
403     free_node(p, movement_node_size);
404   }
405 }
406 /* sec 1368 */
407 void special_out_(pointer p)
408 {
409   char old_setting;
410   pool_pointer k;
411
412   synch_h();
413   synch_v();
414   old_setting = selector;
415   selector = new_string;
416
417 #ifdef ALLOCATESTRING
418   if (pool_ptr + 32000 > current_pool_size)
419     str_pool = realloc_str_pool (increment_pool_size);
420
421   show_token_list(link(write_tokens(p)), 0, 10000000L);
422 #else
423   show_token_list(link(write_tokens(p)), 0, pool_size - pool_ptr);
424 #endif
425
426   selector = old_setting;
427   str_room(1);
428
429   if (cur_length < 256)
430   {
431     dvi_out(xxx1);
432     dvi_out(cur_length);
433   }
434   else
435   {
436     dvi_out(xxx4);
437     dvi_four(cur_length); 
438   } 
439
440   for (k = str_start[str_ptr]; k <= pool_ptr - 1; k++)
441     dvi_out(str_pool[k]);
442
443   pool_ptr = str_start[str_ptr];
444 }
445 /* sec 1370 */
446 void write_out_(pointer p)
447 {
448   char old_setting;
449 /*  integer oldmode;  */
450   int oldmode;          /* 1995/Jan/7 */
451 /*  small_number j;  */
452   int j;              /* 1995/Jan/7 */
453   halfword q, r;
454
455   q = get_avail();
456   info(q) = right_brace_token + '}';
457   r = get_avail();
458   link(q) = r;
459   info(r) = end_write_token;
460   ins_list(q);
461   begin_token_list(write_tokens(p), write_text);
462   q = get_avail();
463   info(q) = left_brace_token + '{';
464   ins_list(q);
465   oldmode = mode;
466   mode = 0;
467   cur_cs = write_loc;
468   q = scan_toks(false, true);
469   get_token();
470
471   if (cur_tok != end_write_token)
472   {
473     print_err("Unbalanced write command");
474     help2("On this page there's a \\write with fewer real {'s than }'s.",
475         "I can't handle that very well; good luck.");
476     error();
477
478     do
479       {
480         get_token();
481       }
482     while (!(cur_tok == end_write_token));
483   }
484
485   mode = oldmode;
486   end_token_list();
487   old_setting = selector;
488   j = write_stream(p);
489
490   if (write_open[j])
491     selector = j;
492   else
493   {
494     if ((j == 17) && (selector == term_and_log))
495       selector = log_only;
496
497     print_nl("");
498   }
499
500   token_show(def_ref);
501   print_ln();
502   flush_list(def_ref);
503   selector = old_setting;
504 }
505 /* sec 1373 */
506 void out_what_(pointer p)
507 {
508 /*  small_number j;  */
509   int j;            /* 1995/Jan/7 */
510
511   switch (subtype(p))
512   {
513     case open_node:
514     case write_node:
515     case close_node:
516       if (!doing_leaders)
517       {
518         j = write_stream(p);
519
520         if (subtype(p) == write_node)
521         {
522           write_out(p);
523         }
524         else
525         {
526           if (write_open[j])
527             a_close(write_file[j]); 
528
529           if (subtype(p) == close_node)
530             write_open[j]= false;
531           else if (j < 16)
532           {
533             cur_name = open_name(p);
534             cur_area = open_area(p);
535             cur_ext = open_ext(p); 
536
537             if (cur_ext == 335)  /* "" */
538               cur_ext = 785;  /* => ".tex" */
539
540             pack_file_name(cur_name, cur_area, cur_ext);
541
542             while (!a_open_out(write_file[j]))
543               prompt_file_name("output file name", ".tex");
544
545             write_open[j] = true;
546           }
547         }
548       }
549       break; 
550
551     case special_node:
552       special_out(p); 
553       break;
554
555     case language_node:
556       ;
557       break;
558
559     default:
560       {
561         confusion("ext4");
562         return;
563       }
564       break;
565   }
566 }
567 /* sec 0619 */
568 void hlist_out (void)
569 {
570   scaled base_line;
571   scaled left_edge;
572   scaled save_h, save_v;
573   halfword this_box;
574 /*  glue_ord g_order;  */
575   int g_order;
576 /*  char g_sign;  */
577   int g_sign;
578   halfword p;
579   integer save_loc;
580   halfword leader_box;
581   scaled leader_wd;
582   scaled lx;
583   boolean outer_doing_leaders;
584   scaled edge;
585   real glue_temp;
586   real cur_glue;
587   scaled cur_g;
588
589   cur_g = 0;
590   cur_glue = 0.0;
591   this_box = temp_ptr;
592   g_order = glue_order(this_box);
593   g_sign = glue_sign(this_box);
594   p = list_ptr(this_box);
595   incr(cur_s);
596
597   if (cur_s > 0)
598     dvi_out(push);
599
600   if (cur_s > max_push)
601     max_push = cur_s;
602
603   save_loc = dvi_offset + dvi_ptr;
604   base_line = cur_v;
605   left_edge = cur_h;
606
607   while (p != 0)
608 reswitch:
609     if (is_char_node(p))
610     {
611       synch_h();
612       synch_v();
613
614       do
615         {
616           f = font(p);
617           c = character(p);
618
619           if (f != dvi_f)
620           {
621             if (!font_used[f])
622             {
623               dvi_font_def(f);
624               font_used[f] = true;
625             }
626
627             if (f <= 64 + font_base)
628               dvi_out(f - font_base - 1 + fnt_num_0);
629 #ifdef INCREASEFONTS
630             /* if we allow greater than 256 fonts */
631             else if (f <= 256)
632             {
633               dvi_out(fnt1);
634               dvi_out(f - 1);
635             }
636 #else
637             else
638             {
639               dvi_out(fnt1);
640               dvi_out(f - 1);
641             }
642 #endif
643
644 #ifdef INCREASEFONTS
645             else
646             {
647               dvi_out(fnt2);
648               dvi_out(((f - 1) >> 8));  /* top byte */
649               dvi_out(((f - 1) & 255)); /* bottom byte */
650             }
651 #endif
652
653             dvi_f = f;
654           }
655
656           if (c >= 128)
657             dvi_out(set1);
658
659           dvi_out(c);
660           cur_h = cur_h + char_width(f, char_info(f, c));
661           p = link(p);
662         }
663       while (!(!is_char_node(p)));
664
665       dvi_h = cur_h;
666   }
667   else
668   {
669     switch (type(p))
670     {
671       case hlist_node:
672       case vlist_node:
673         if (list_ptr(p) == 0)
674           cur_h = cur_h + width(p);
675         else
676         {
677           save_h = dvi_h;
678           save_v = dvi_v;
679           cur_v = base_line + shift_amount(p);
680           temp_ptr = p;
681           edge = cur_h;
682
683           if (type(p) == vlist_node)
684             vlist_out();
685           else
686             hlist_out();
687
688           dvi_h = save_h;
689           dvi_v = save_v;
690           cur_h = edge + width(p);
691           cur_v = base_line;
692         }
693         break;
694
695       case rule_node:
696         {
697           rule_ht = height(p);
698           rule_dp = depth(p);
699           rule_wd = width(p);
700           goto fin_rule;
701         }
702         break;
703
704       case whatsit_node:
705         out_what(p);
706         break;
707
708       case glue_node:
709         {
710           g = glue_ptr(p);
711           rule_wd = width(g) - cur_g;
712
713           if (g_sign != normal)
714           {
715             if (g_sign == stretching)
716             {
717               if (stretch_order(g) == g_order)
718               {
719                 cur_glue = cur_glue + stretch(g);
720                 vet_glue(glue_set(this_box) * cur_glue);
721                 cur_g = round(glue_temp);
722               }
723             }
724             else if (shrink_order(g) == g_order)
725             {
726               cur_glue = cur_glue - shrink(g);
727               vet_glue(glue_set(this_box) * cur_glue);
728               cur_g = round(glue_temp);
729             }
730           }
731
732           rule_wd = rule_wd + cur_g;
733
734           if (subtype(p) >= a_leaders)
735           {
736             leader_box = leader_ptr(p);
737
738             if (type(leader_box) == rule_node)
739             {
740               rule_ht = height(leader_box);
741               rule_dp = depth(leader_box);
742               goto fin_rule;
743             }
744
745             leader_wd = width(leader_box);
746
747             if ((leader_wd > 0) && (rule_wd > 0))
748             {
749               rule_wd = rule_wd + 10;
750               edge = cur_h + rule_wd;
751               lx = 0;
752
753               if (subtype(p) == a_leaders)
754               {
755                 save_h = cur_h;
756                 cur_h = left_edge + leader_wd * ((cur_h - left_edge) / leader_wd);
757
758                 if (cur_h < save_h)
759                   cur_h = cur_h + leader_wd;
760               }
761               else
762               {
763                 lq = rule_wd / leader_wd;
764                 lr = rule_wd % leader_wd;
765
766                 if (subtype(p) == c_leaders)
767                   cur_h = cur_h + (lr / 2);
768                 else
769                 {
770                   lx =(2 * lr + lq + 1) / (2 * lq + 2);
771                   cur_h = cur_h + ((lr - (lq - 1)* lx) / 2);
772                 }
773               }
774
775               while (cur_h + leader_wd <= edge)
776               {
777                 cur_v = base_line + shift_amount(leader_box);
778                 synch_v();
779                 save_v = dvi_v;
780                 synch_h();
781                 save_h = dvi_h;
782                 temp_ptr = leader_box;
783                 outer_doing_leaders = doing_leaders;
784                 doing_leaders = true;
785
786                 if (type(leader_box) == vlist_node)
787                   vlist_out();
788                 else
789                   hlist_out();
790
791                 doing_leaders = outer_doing_leaders;
792                 dvi_v = save_v;
793                 dvi_h = save_h;
794                 cur_v = base_line;
795                 cur_h = save_h + leader_wd + lx;
796               }
797
798               cur_h = edge - 10;
799               goto next_p;
800             }
801           }
802
803           goto move_past;
804         }
805         break;
806
807       case kern_node:
808       case math_node:
809         cur_h = cur_h + width(p);
810         break;
811
812       case ligature_node:
813         {
814           mem[lig_trick] = mem[lig_char(p)];
815           link(lig_trick) = link(p);
816           p = lig_trick;
817           goto reswitch;
818         }
819         break;
820
821       default:
822         break;
823     }
824
825     goto next_p;
826
827 fin_rule:
828     if (is_running(rule_ht))
829       rule_ht = height(this_box);
830
831     if (is_running(rule_dp))
832       rule_dp = depth(this_box);
833
834     rule_ht = rule_ht + rule_dp;
835
836     if ((rule_ht > 0) && (rule_wd > 0))
837     {
838       synch_h();
839       cur_v = base_line + rule_dp;
840       synch_v();
841       dvi_out(set_rule);
842       dvi_four(rule_ht);
843       dvi_four(rule_wd);
844       cur_v = base_line;
845       dvi_h = dvi_h + rule_wd;
846     }
847
848 move_past:
849     cur_h = cur_h + rule_wd;
850
851 next_p:
852     p = link(p);
853   }
854
855   prune_movements(save_loc);
856
857   if (cur_s > 0)
858     dvi_pop(save_loc);
859
860   decr(cur_s);
861 }
862 /* sec 0629 */
863 void vlist_out (void)
864 {
865   scaled left_edge;
866   scaled top_edge;
867   scaled save_h, save_v;
868   halfword this_box;
869 /*  glue_ord g_order;  */
870   int g_order;         /* 95/Jan/7 */
871 /*  char g_sign;  */
872   int g_sign;          /* 95/Jan/7 */
873   halfword p;
874   integer save_loc;
875   halfword leader_box;
876   scaled leader_ht;
877   scaled lx;
878   boolean outer_doing_leaders;
879   scaled edge;
880   real glue_temp;
881   real cur_glue;
882   scaled cur_g;
883
884   cur_g = 0;
885   cur_glue = 0.0;
886   this_box = temp_ptr;
887   g_order = glue_order(this_box);
888   g_sign = glue_sign(this_box);
889   p = list_ptr(this_box);
890   incr(cur_s);
891
892   if (cur_s > 0)
893     dvi_out(push);
894
895   if (cur_s > max_push)
896     max_push = cur_s;
897
898   save_loc = dvi_offset + dvi_ptr;
899   left_edge = cur_h;
900   cur_v = cur_v - height(this_box);
901   top_edge = cur_v;
902
903   while (p != 0)
904   {
905     if (is_char_node(p))
906     {
907       confusion("vlistout");
908       return;
909     }
910     else
911     {
912       switch (type(p))
913       {
914         case hlist_node:
915         case vlist_node:
916           if (list_ptr(p) == 0)
917             cur_v = cur_v + height(p) + depth(p);
918           else
919           {
920             cur_v = cur_v + height(p);
921             synch_v();
922             save_h = dvi_h;
923             save_v = dvi_v;
924             cur_h = left_edge + shift_amount(p);
925             temp_ptr = p;
926
927             if (type(p) == vlist_node)
928               vlist_out();
929             else
930               hlist_out();
931
932             dvi_h = save_h;
933             dvi_v = save_v;
934             cur_v = save_v + depth(p);
935             cur_h = left_edge;
936           }
937           break;
938
939         case rule_node:
940           {
941             rule_ht = height(p);
942             rule_dp = depth(p);
943             rule_wd = width(p);
944             goto fin_rule;
945           }
946           break;
947
948         case whatsit_node:
949           out_what(p);
950           break;
951
952         case glue_node:
953           {
954             g = glue_ptr(p);
955             rule_ht = width(g) - cur_g;
956
957             if (g_sign != normal)
958             {
959               if (g_sign == stretching)
960               {
961                 if (stretch_order(g) == g_order)
962                 {
963                   cur_glue = cur_glue + stretch(g);
964                   vet_glue(glue_set(this_box) * cur_glue);
965                   cur_g = round(glue_temp);
966                 }
967               }
968               else if (shrink_order(g) == g_order)   /* BUG FIX !!! */
969               {
970                 cur_glue = cur_glue - shrink(g);
971                 vet_glue(glue_set(this_box) * cur_glue);
972                 cur_g = round(glue_temp);
973               }
974             }
975
976             rule_ht = rule_ht + cur_g;
977
978             if (subtype(p) >= a_leaders)
979             {
980               leader_box = leader_ptr(p);
981
982               if (type(leader_box) == rule_node)
983               {
984                 rule_wd = width(leader_box);
985                 rule_dp = 0;
986                 goto fin_rule;
987               }
988
989               leader_ht = height(leader_box) + depth(leader_box);
990
991               if ((leader_ht > 0) && (rule_ht > 0))
992               {
993                 rule_ht = rule_ht + 10;
994                 edge = cur_v + rule_ht;
995                 lx = 0;
996
997                 if (subtype(p) == a_leaders)
998                 {
999                   save_v = cur_v;
1000                   cur_v = top_edge + leader_ht * ((cur_v - top_edge) / leader_ht);
1001
1002                   if (cur_v < save_v)
1003                     cur_v = cur_v + leader_ht;
1004                 }
1005                 else
1006                 {
1007                   lq = rule_ht / leader_ht;
1008                   lr = rule_ht % leader_ht;
1009
1010                   if (subtype(p) == c_leaders)
1011                     cur_v = cur_v + (lr / 2);
1012                   else
1013                   {
1014                     lx = (2 * lr + lq + 1) / (2 * lq + 2);
1015                     cur_v = cur_v + ((lr - (lq - 1) * lx) / 2);
1016                   }
1017                 }
1018
1019                 while (cur_v + leader_ht <= edge)
1020                 {
1021                   cur_h = left_edge + shift_amount(leader_box);
1022                   synch_h();
1023                   save_h = dvi_h;
1024                   cur_v = cur_v + height(leader_box);
1025                   synch_v();
1026                   save_v = dvi_v;
1027                   temp_ptr = leader_box;
1028                   outer_doing_leaders = doing_leaders;
1029                   doing_leaders = true;
1030
1031                   if (type(leader_box) == vlist_node)
1032                     vlist_out();
1033                   else
1034                     hlist_out();
1035
1036                   doing_leaders = outer_doing_leaders;
1037                   dvi_v = save_v;
1038                   dvi_h = save_h;
1039                   cur_h = left_edge;
1040                   cur_v = save_v - height(leader_box) + leader_ht + lx;
1041                 }
1042
1043                 cur_v = edge - 10;
1044                 goto next_p;
1045               }
1046             }
1047
1048             goto move_past;
1049           }
1050           break;
1051
1052         case kern_node:
1053           cur_v = cur_v + width(p);
1054           break;
1055
1056         default:
1057           break;
1058       }
1059
1060       goto next_p;
1061
1062 fin_rule:
1063       if (is_running(rule_wd))
1064         rule_wd = width(this_box);
1065
1066       rule_ht = rule_ht + rule_dp;
1067       cur_v = cur_v + rule_ht;
1068
1069       if ((rule_ht > 0) && (rule_wd > 0))
1070       {
1071         synch_h();
1072         synch_v();
1073         dvi_out(put_rule);
1074         dvi_four(rule_ht);
1075         dvi_four(rule_wd);
1076       }
1077
1078       goto next_p;
1079
1080 move_past:
1081       cur_v = cur_v + rule_ht;
1082     }
1083
1084 next_p:
1085     p = link(p);
1086   }
1087
1088   prune_movements(save_loc);
1089
1090   if (cur_s > 0)
1091     dvi_pop(save_loc);
1092
1093   decr(cur_s);
1094 }
1095 /* sec 0638 */
1096 void dvi_ship_out_(halfword p)
1097 {
1098   integer page_loc;
1099   char j, k;
1100   pool_pointer s;
1101   char old_setting;
1102
1103   if (tracing_output > 0)
1104   {
1105     print_nl("");
1106     print_ln();
1107     prints("Completed box being shipped out");
1108   }
1109
1110   if (term_offset > max_print_line - 9)
1111     print_ln();
1112   else if ((term_offset > 0) || (file_offset > 0))
1113     print_char(' ');
1114
1115   print_char('[');
1116   j = 9;
1117
1118   while ((count(j) == 0) && (j > 0))
1119     decr(j);
1120
1121   for (k = 0; k <= j; k++)
1122   {
1123     print_int(count(k));
1124
1125     if (k < j)
1126       print_char('.');
1127   }
1128   
1129   update_terminal();
1130
1131   if (tracing_output > 0)
1132   {
1133     print_char(']');
1134     begin_diagnostic();
1135     show_box(p);
1136     end_diagnostic(true);
1137   }
1138
1139   if ((height(p) > max_dimen) || (depth(p) > max_dimen) ||
1140       (height(p) + depth(p) + v_offset > max_dimen) ||
1141       (width(p) + h_offset > max_dimen))
1142   {
1143     print_err("Huge page cannot be shipped out");
1144     help2("The page just created is more than 18 feet tall or",
1145         "more than 18 feet wide, so I suspect something went wrong.");
1146     error();
1147
1148     if (tracing_output <= 0)
1149     {
1150       begin_diagnostic();
1151       print_nl("The following box has been deleted:");
1152       show_box(p);
1153       end_diagnostic(true);
1154     }
1155
1156     goto done;
1157   }
1158
1159   if (height(p) + depth(p) + v_offset > max_v)
1160     max_v = height(p) + depth(p) + v_offset;
1161
1162   if (width(p) + h_offset > max_h)
1163     max_h = width(p) + h_offset;
1164
1165   dvi_h = 0;
1166   dvi_v = 0;
1167   cur_h = h_offset;
1168   dvi_f = null_font;
1169   ensure_dvi_open();
1170
1171   if (total_pages == 0)
1172   {
1173     dvi_out(pre);
1174     dvi_out(id_byte);
1175     dvi_four(25400000L);
1176     dvi_four(473628672L);
1177     prepare_mag();
1178     dvi_four(mag);
1179     old_setting = selector;
1180     selector = new_string;
1181     prints(" TeX output ");
1182     print_int(year);
1183     print_char('.');
1184     print_two(month);
1185     print_char('.');
1186     print_two(day);
1187     print_char(':');
1188     print_two(tex_time / 60);
1189     print_two(tex_time % 60);
1190     selector = old_setting;
1191     dvi_out(cur_length);
1192
1193     for (s = str_start[str_ptr]; s <= pool_ptr - 1; s++)
1194       dvi_out(str_pool[s]);
1195
1196     pool_ptr = str_start[str_ptr];
1197   }
1198
1199   page_loc = dvi_offset + dvi_ptr;
1200   dvi_out(bop);
1201
1202   for (k = 0; k <= 9; k++)
1203     dvi_four(count(k));
1204
1205   dvi_four(last_bop);
1206   last_bop = page_loc;
1207   cur_v = height(p) + v_offset;
1208   temp_ptr = p;
1209
1210   if (type(p) == vlist_node)
1211     vlist_out();
1212   else
1213     hlist_out();
1214
1215   dvi_out(eop);
1216   incr(total_pages);
1217   cur_s = -1;
1218
1219 done:;
1220   if (tracing_output <= 0)
1221     print_char(']');
1222
1223   dead_cycles = 0;
1224   update_terminal();
1225
1226 #ifdef STAT
1227   if (tracing_stats > 1)
1228   {
1229     print_nl("Memory usage before: ");
1230     print_int(var_used);
1231     print_char('&');
1232     print_int(dyn_used);
1233     print_char(';');
1234   }
1235 #endif
1236
1237   flush_node_list(p);
1238
1239 #ifdef STAT
1240   if (tracing_stats > 1)
1241   {
1242     prints(" after: ");
1243     print_int(var_used);
1244     print_char('&');
1245     print_int(dyn_used);
1246     prints("; still utouched: ");
1247     print_int(hi_mem_min - lo_mem_max - 1);
1248     print_ln();
1249   }
1250 #endif
1251 }
1252 void ship_out_(halfword p)
1253 {
1254   switch (shipout_flag)
1255   {
1256     case out_dvi_flag:
1257     case out_xdv_flag:
1258       dvi_ship_out_(p);
1259       break;
1260   }
1261 }
1262 /* sec 0645 */
1263 void scan_spec_(group_code c, boolean three_codes)
1264 {
1265   integer s;
1266   char spec_code;
1267
1268   if (three_codes)
1269     s = saved(0);
1270
1271   if (scan_keyword("to"))
1272     spec_code = exactly;
1273   else if (scan_keyword("spread"))
1274     spec_code = additional;
1275   else
1276   {
1277     spec_code = additional;
1278     cur_val = 0;
1279     goto found;
1280   }
1281
1282   scan_dimen(false, false, false);
1283
1284 found:
1285   if (three_codes)
1286   {
1287     saved(0) = s;
1288     incr(save_ptr);
1289   }
1290
1291   saved(0) = spec_code;
1292   saved(1) = cur_val;
1293   save_ptr = save_ptr + 2;
1294   new_save_level(c);
1295   scan_left_brace();
1296 }
1297 /* sec 0649 */
1298 halfword hpack_(halfword p, scaled w, small_number m)
1299 {
1300   halfword r;
1301   halfword q;
1302   scaled h, d, x;
1303   scaled s;
1304   halfword g;
1305 /*  glue_ord o;  */
1306   int o;              /* 95/Jan/7 */
1307   internal_font_number f;
1308   four_quarters i;
1309   eight_bits hd;
1310
1311   last_badness = 0;
1312   r = get_node(box_node_size);
1313   type(r) = hlist_node;
1314   subtype(r) = 0;
1315   shift_amount(r) = 0;
1316   q = r + list_offset;
1317   link(q) = p;
1318   h = 0;
1319   d = 0;
1320   x = 0;
1321   total_stretch[normal] = 0;
1322   total_shrink[normal] = 0;
1323   total_stretch[fil] = 0;
1324   total_shrink[fil] = 0;
1325   total_stretch[fill] = 0;
1326   total_shrink[fill] = 0;
1327   total_stretch[filll] = 0;
1328   total_shrink[filll] = 0;
1329
1330   while (p != 0)
1331   {
1332 reswitch:
1333     while (is_char_node(p))
1334     {
1335       f = font(p);
1336       i = char_info(f, character(p));
1337       hd = height_depth(i);
1338       x = x + char_width(f, i);
1339       s = char_height(f, hd);
1340
1341       if (s > h)
1342         h = s;
1343
1344       s = char_depth(f, hd);
1345
1346       if (s > d)
1347         d = s;
1348
1349       p = link(p);
1350     }
1351
1352     if (p != 0)
1353     {
1354       switch (type(p))
1355       {
1356         case hlist_node:
1357         case vlist_node:
1358         case rule_node:
1359         case unset_node:
1360           {
1361             x = x + width(p);
1362
1363             if (type(p) >= rule_node)
1364               s = 0;
1365             else
1366               s = shift_amount(p);
1367
1368             if (height(p) - s > h)
1369               h = height(p) - s;
1370
1371             if (depth(p) + s > d)
1372               d = depth(p) + s;
1373           }
1374           break;
1375
1376         case ins_node:
1377         case mark_node:
1378         case adjust_node:
1379           if (adjust_tail != 0)
1380           {
1381             while (link(q) != p)
1382               q = link(q);
1383
1384             if (type(p) == adjust_node)
1385             {
1386               link(adjust_tail) = adjust_ptr(p);
1387
1388               while (link(adjust_tail) != 0)
1389                 adjust_tail = link(adjust_tail);
1390
1391               p = link(p);
1392               free_node(link(q), small_node_size);
1393             }
1394             else
1395             {
1396               link(adjust_tail) = p;
1397               adjust_tail = p;
1398               p = link(p);
1399             }
1400
1401             link(q) = p;
1402             p = q;
1403           }
1404           break;
1405
1406         case whatsit_node:
1407           break;
1408
1409         case glue_node:
1410           {
1411             g = glue_ptr(p);
1412             x = x + width(g);
1413             o = stretch_order(g);
1414             total_stretch[o] = total_stretch[o] + stretch(g);
1415             o = shrink_order(g);
1416             total_shrink[o] = total_shrink[o] + shrink(g);
1417
1418             if (subtype(p) >= a_leaders)
1419             {
1420               g = leader_ptr(p);
1421
1422               if (height(g) > h)
1423                 h = height(g);
1424
1425               if (depth(g) > d)
1426                 d = depth(g);
1427             }
1428           }
1429           break;
1430
1431         case kern_node:
1432         case math_node:
1433           x = x + width(p);
1434           break;
1435
1436         case ligature_node:
1437           {
1438             mem[lig_trick] = mem[lig_char(p)];
1439             link(lig_trick) = link(p);
1440             p = lig_trick;
1441             goto reswitch;
1442           }
1443           break;
1444
1445         default:
1446           break;
1447       }
1448       p = link(p);
1449     }
1450   }
1451
1452   if (adjust_tail != 0)
1453     link(adjust_tail) = 0;
1454
1455   height(r) = h;
1456   depth(r) = d;
1457
1458   if (m == additional)
1459     w = x + w;
1460
1461   width(r) = w;
1462   x = w - x;
1463
1464   if (x == 0)
1465   {
1466     glue_sign(r) = normal;
1467     glue_order(r) = normal;
1468     glue_set(r) = 0.0;
1469     goto exit;
1470   }
1471   else if (x > 0)
1472   {
1473     if (total_stretch[filll] != 0)
1474       o = filll;
1475     else if (total_stretch[fill] != 0)
1476       o = fill;
1477     else if (total_stretch[fil] != 0)
1478       o = fil;
1479     else
1480       o = normal;
1481
1482     glue_order(r) = o;
1483     glue_sign(r) = stretching;
1484
1485     if (total_stretch[o] != 0)
1486       glue_set(r) = x / ((double) total_stretch[o]);
1487     else
1488     {
1489       glue_sign(r) = normal;
1490       glue_set(r) = 0.0;
1491     }
1492
1493     if (o == normal)
1494       if (list_ptr(r) != 0)
1495       {
1496         last_badness = badness(x, total_stretch[normal]);
1497
1498         if (last_badness > hbadness)
1499         {
1500           print_ln();
1501
1502           if (last_badness > 100)
1503             print_nl("Underfull");
1504           else
1505             print_nl("Loose");
1506
1507           prints(" \\hbox (badness ");
1508           print_int(last_badness);
1509
1510           if (last_badness > 100) /* Y&Y TeX */
1511             underfull_hbox++;
1512
1513           goto common_ending;
1514         }
1515       }
1516       goto exit;
1517   }
1518   else
1519   {
1520     if (total_shrink[filll] != 0)
1521       o = filll;
1522     else if (total_shrink[fill] != 0)
1523       o = fill;
1524     else if (total_shrink[fil] != 0)
1525       o = fil;
1526     else
1527       o = normal;
1528
1529     glue_order(r) = o;
1530     glue_sign(r) = shrinking;
1531
1532     if (total_shrink[o] != 0)
1533       glue_set(r) = ((- (integer) x) / ((double) total_shrink[o]));
1534     else
1535     {
1536       glue_sign(r) = normal;
1537       glue_set(r) = 0.0;
1538     }
1539
1540     if ((total_shrink[o] < - (integer) x) && (o == 0) && (list_ptr(r) != 0))
1541     {
1542       last_badness = 1000000L;
1543       glue_set(r) = 1.0;
1544
1545       if ((- (integer) x - total_shrink[normal] > hfuzz) || (hbadness < 100))
1546       {
1547           if ((overfull_rule > 0) && (- (integer) x - total_shrink[0] > hfuzz))
1548           {
1549               while (link(q) != 0)
1550                 q = link(q);
1551  
1552               link(q) = new_rule();
1553               width(link(q)) = overfull_rule;
1554           }
1555
1556           print_ln();
1557           print_nl("Overfull \\hbox (");
1558           print_scaled(- (integer) x - total_shrink[normal]);
1559           prints("pt too wide");
1560
1561           overfull_hbox++;
1562
1563           goto common_ending;
1564       }
1565     }
1566     else if (o == normal)
1567       if (list_ptr(r) != 0)
1568       {
1569         last_badness = badness(- (integer) x, total_shrink[normal]);
1570
1571         if (last_badness > hbadness)
1572         {
1573           print_ln();
1574           print_nl("Tight \\hbox (badness ");
1575           print_int(last_badness);
1576           goto common_ending;
1577         }
1578       }
1579       goto exit;
1580   }
1581
1582 common_ending:
1583   if (output_active)
1584     prints(") has occurred while \\output is active");
1585   else
1586   {
1587     if (pack_begin_line != 0)
1588     {
1589       if (pack_begin_line > 0)
1590         prints(") in paragraph at lines ");
1591       else
1592         prints(") in alignment at lines ");
1593
1594       print_int(abs(pack_begin_line));
1595       prints("--");
1596     }
1597     else
1598       prints(") detected at line ");
1599
1600     print_int(line);
1601   }
1602
1603   print_ln();
1604   font_in_short_display = null_font;
1605   short_display(list_ptr(r));
1606   print_ln();
1607   begin_diagnostic();
1608   show_box(r);
1609   end_diagnostic(true);
1610
1611 exit:
1612   return r;
1613 }
1614 /* sec 0668 */
1615 halfword vpackage_(halfword p, scaled h, small_number m, scaled l)
1616 {
1617   halfword r;
1618   scaled w, d, x;
1619   scaled s;
1620   halfword g;
1621 /*  glue_ord o;  */
1622   int o;              /* 95/Jan/7 */
1623
1624   last_badness = 0;
1625   r = get_node(box_node_size);
1626   type(r) = vlist_node;
1627   subtype(r) = min_quarterword;
1628   shift_amount(r) = 0;
1629   list_ptr(r) = p;
1630   w = 0;
1631   d = 0;
1632   x = 0;
1633   total_stretch[normal] = 0;
1634   total_shrink[normal] = 0;
1635   total_stretch[fil] = 0;
1636   total_shrink[fil] = 0;
1637   total_stretch[fill] = 0;
1638   total_shrink[fill] = 0;
1639   total_stretch[filll] = 0;
1640   total_shrink[filll] = 0;
1641
1642   while (p != 0)
1643   {
1644     if (is_char_node(p))
1645     {
1646       confusion("vpack");
1647       return 0;
1648     }
1649     else switch (type(p))
1650     {
1651       case hlist_node:
1652       case vlist_node:
1653       case rule_node:
1654       case unset_node:
1655         {
1656           x = x + d + height(p);
1657           d = depth(p);
1658
1659           if (type(p) >= rule_node)
1660             s = 0;
1661           else
1662             s = shift_amount(p);
1663
1664           if (width(p) + s > w)
1665             w = width(p) + s;
1666         }
1667         break;
1668
1669       case whatsit_node:
1670         break;
1671
1672       case glue_node:
1673         {
1674           x = x + d;
1675           d = 0;
1676           g = glue_ptr(p);
1677           x = x + width(g);
1678           o = stretch_order(g);
1679           total_stretch[o] = total_stretch[o] + stretch(g);
1680           o = shrink_order(g);
1681           total_shrink[o] = total_shrink[o] + shrink(g);
1682
1683           if (subtype(p) >= a_leaders)
1684           {
1685             g = leader_ptr(p);
1686
1687             if (width(g) > w)
1688               w = width(g);
1689           }
1690         }
1691         break;
1692
1693       case kern_node:
1694         {
1695           x = x + d + width(p);
1696           d = 0;
1697         }
1698         break;
1699
1700       default:
1701         break;
1702     }
1703     p = link(p);
1704   }
1705
1706   width(r) = w;
1707
1708   if (d > l)
1709   {
1710     x = x + d - l;
1711     depth(r) = l;
1712   }
1713   else
1714     depth(r) = d;
1715
1716   if (m == additional)
1717     h = x + h;
1718
1719   height(r) = h;
1720   x = h - x;
1721
1722   if (x == 0)
1723   {
1724     glue_sign(r) = normal;
1725     glue_order(r) = normal;
1726     glue_set(r) = 0.0;
1727     goto exit;
1728   }
1729   else if (x > 0)
1730   {
1731     if (total_stretch[filll] != 0)
1732       o = filll;
1733     else if (total_stretch[fill] != 0)
1734       o = fill;
1735     else if (total_stretch[fil] != 0)
1736       o = fil;
1737     else
1738       o = normal;
1739
1740     glue_order(r) = o;
1741     glue_sign(r) = stretching;
1742
1743     if (total_stretch[o] != 0)
1744       glue_set(r) = x / ((double) total_stretch[o]);
1745     else
1746     {
1747       glue_sign(r) = normal;
1748       glue_set(r) = 0.0;
1749     }
1750
1751     if (o == normal)
1752       if (list_ptr(r) != 0)
1753       {
1754         last_badness = badness(x, total_stretch[normal]);
1755
1756         if (last_badness > vbadness)
1757         {
1758           print_ln();
1759
1760           if (last_badness > 100)
1761             print_nl("Underfull");
1762           else
1763             print_nl("Loose");
1764
1765           prints(" \\vbox (badness ");
1766           print_int(last_badness);
1767
1768           if (last_badness > 100)
1769             underfull_vbox++; /* 1996/Feb/9 */
1770
1771           goto common_ending;
1772         }
1773       }
1774       goto exit;
1775   }
1776   else
1777   {
1778     if (total_shrink[filll] != 0)
1779       o = filll;
1780     else if (total_shrink[fill] != 0)
1781       o = fill;
1782     else if (total_shrink[fil] != 0)
1783       o = fil;
1784     else
1785       o = normal;
1786
1787     glue_order(r) = o;
1788     glue_sign(r) = shrinking;
1789
1790     if (total_shrink[o] != 0)
1791       glue_set(r) =(- (integer) x)/ ((double) total_shrink[o]);
1792     else
1793     {
1794       glue_sign(r) = normal;
1795       glue_set(r) = 0.0;
1796     }
1797
1798     if ((total_shrink[o] < - (integer) x) && (o == 0) && (list_ptr(r) != 0))
1799     {
1800       last_badness = 1000000L;
1801       glue_set(r) = 1.0;
1802
1803       if ((- (integer) x - total_shrink[0] > vfuzz) || (vbadness < 100))
1804       {
1805         print_ln();
1806         print_nl("Overfull \\vbox (");
1807         print_scaled(- (integer) x - total_shrink[0]);
1808         prints("pt too high");
1809
1810         overfull_vbox++;    /* 1996/Feb/9 */
1811
1812         goto common_ending;
1813       }
1814     }
1815     else if (o == 0)
1816       if (list_ptr(r) != 0)
1817       {
1818         last_badness = badness(- (integer) x, total_shrink[normal]);
1819         if (last_badness > vbadness)
1820         {
1821           print_ln();
1822           print_nl("Tight \\vbox (badness ");
1823           print_int(last_badness);
1824           goto common_ending;
1825         }
1826       }
1827     goto exit;
1828   }
1829
1830 common_ending:
1831   if (output_active)
1832     prints(") has occurred while \\output is active");
1833   else
1834   {
1835     if (pack_begin_line != 0)
1836     {
1837       prints(") in alignment at lines ");
1838       print_int(abs(pack_begin_line));
1839       prints("--");
1840     }
1841     else
1842       prints(") detected at line ");
1843
1844     print_int(line);
1845     print_ln();
1846   }
1847
1848   begin_diagnostic();
1849   show_box(r);
1850   end_diagnostic(true);
1851
1852 exit:
1853   return r;
1854 }
1855 /* sec 0679 */
1856 void append_to_vlist_(halfword b)
1857 {
1858   scaled d;
1859   halfword p;
1860
1861   if (prev_depth > ignore_depth)
1862   {
1863     d = width(baseline_skip) - prev_depth - height(b);
1864
1865     if (d < line_skip_limit)
1866       p = new_param_glue(line_skip_code);
1867     else
1868     {
1869       p = new_skip_param(baseline_skip_code);
1870       width(temp_ptr) = d;
1871     }
1872
1873     link(tail) = p;
1874     tail = p;
1875   }
1876
1877   link(tail) = b;
1878   tail = b;
1879   prev_depth = depth(b);
1880 }
1881 /* sec 0686 */
1882 halfword new_noad (void)
1883 {
1884   halfword p;
1885
1886   p = get_node(noad_size);
1887   type(p) = ord_noad;
1888   subtype(p) = normal;
1889   mem[nucleus(p)].hh = empty_field;
1890   mem[subscr(p)].hh = empty_field;
1891   mem[supscr(p)].hh = empty_field;
1892
1893   return p;
1894 }
1895 /* sec 0688 */
1896 halfword new_style_(small_number s)
1897 {
1898   halfword p;
1899
1900   p = get_node(style_node_size);
1901   type(p) = style_node;
1902   subtype(p) = s;
1903   width(p) = 0;
1904   depth(p) = 0;
1905
1906   return p;
1907 }
1908 /* sec 0689 */
1909 halfword new_choice (void)
1910 {
1911   halfword p;
1912
1913   p = get_node(style_node_size);
1914   type(p) = choice_node;
1915   subtype(p) = 0;
1916   display_mlist(p) = 0;
1917   text_mlist(p) = 0;
1918   script_mlist(p) = 0;
1919   script_script_mlist(p) = 0;
1920
1921   return p;
1922 }
1923 /* sec 0693 */
1924 void show_info (void)
1925 {
1926   show_node_list(info(temp_ptr));
1927 }
1928 /* sec 0704 */
1929 halfword fraction_rule_(scaled t)
1930 {
1931   halfword p;
1932
1933   p = new_rule();
1934   height(p) = t;
1935   depth(p) = 0;
1936
1937   return p;
1938 }
1939 /* sec 0705 */
1940 halfword overbar_(halfword b, scaled k, scaled t)
1941 {
1942   halfword p, q;
1943
1944   p = new_kern(k);
1945   link(p) = b;
1946   q = fraction_rule(t);
1947   link(q) = p;
1948   p = new_kern(t);
1949   link(p) = q;
1950   return vpackage(p, 0, 1, 1073741823L); /* 2^30 - 1 */
1951 }
1952 /* sec 0709 */
1953 halfword char_box_(internal_font_number f, quarterword c)
1954 {
1955   four_quarters q;
1956   eight_bits hd;
1957   halfword b, p;
1958
1959   q = char_info(f, c);
1960   hd = height_depth(q);
1961   b = new_null_box();
1962   width(b) = char_width(f, q) + char_italic(f, q);
1963   height(b) = char_height(f, hd);
1964   depth(b) = char_depth(f, hd);
1965   p = get_avail();
1966   character(p) = c;
1967   font(p) = f;
1968   list_ptr(b) = p;
1969
1970   return b;
1971 }
1972 /* sec 0711 */
1973 void stack_into_box_(halfword b, internal_font_number f, quarterword c)
1974 {
1975   halfword p;
1976
1977   p = char_box(f, c);
1978   link(p) = list_ptr(b);
1979   list_ptr(b) = p;
1980   height(b) = height(p);
1981 }
1982 /* sec 0712 */
1983 scaled height_plus_depth_(internal_font_number f, quarterword c)
1984 {
1985   four_quarters q;
1986   eight_bits hd;
1987
1988   q = char_info(f, c);
1989   hd = height_depth(q);
1990   return char_height(f, hd) + char_depth(f, hd);
1991 }
1992 /* sec 0706 */
1993 halfword var_delimiter_(halfword d, small_number s, scaled v)
1994 {
1995   halfword b;
1996   internal_font_number f, g;
1997   quarterword c, x, y;
1998   integer m, n;
1999   scaled u;
2000   scaled w;
2001   four_quarters q;
2002   four_quarters r;
2003   eight_bits hd;
2004 /*  small_number z;  */
2005   int z;                  /* 95/Jan/7 */
2006 /*  boolean large_attempt;  */
2007   int large_attempt;           /* 95/Jan/7 */
2008
2009   f = null_font;
2010   w = 0;
2011   large_attempt = false;
2012   z = small_fam(d);
2013   x = small_char(d);
2014
2015   while (true)
2016   {
2017     if ((z != 0) || (x != 0))
2018     {
2019       z = z + s + 16;
2020
2021       do
2022         {
2023           z = z - 16;
2024           g = fam_fnt(z);
2025
2026           if (g != null_font)
2027           {
2028             y = x;
2029
2030             if ((y >= font_bc[g]) && (y <= font_ec[g]))
2031             {
2032 continu:
2033               q = char_info(g, y);
2034               
2035               if ((q.b0 > 0))
2036               {
2037                 if (char_tag(q) == ext_tag)
2038                 {
2039                   f = g;
2040                   c = y;
2041                   goto found;
2042                 }
2043
2044                 hd = height_depth(q);
2045                 u = char_height(g, hd) + char_depth(g, hd);
2046
2047                 if (u > w)
2048                 {
2049                   f = g;
2050                   c = y;
2051                   w = u;
2052
2053                   if (u >= v)
2054                     goto found;
2055                 }
2056
2057                 if (char_tag(q) == list_tag)
2058                 {
2059                   y = rem_byte(q);
2060                   goto continu;
2061                 }
2062               }
2063             }
2064           }
2065         }
2066       while (!(z < 16));
2067     }
2068
2069     if (large_attempt)
2070       goto found;
2071
2072     large_attempt = true;
2073     z = large_fam(d);
2074     x = large_char(d);
2075   }
2076
2077 found:
2078   if (f != null_font)
2079     if (char_tag(q) == ext_tag)
2080     {
2081       b = new_null_box();
2082       type(b) = vlist_node;
2083       r = font_info[exten_base[f] + rem_byte(q)].qqqq;
2084       c = ext_rep(r);
2085       u = height_plus_depth(f, c);
2086       w = 0;
2087       q = char_info(f, c);
2088       width(b) = char_width(f, q) + char_italic(f, q);
2089       c = ext_bot(r);
2090
2091       if (c != min_quarterword)
2092         w = w + height_plus_depth(f, c);
2093
2094       c = ext_mid(r);
2095
2096       if (c != min_quarterword)
2097         w = w + height_plus_depth(f, c);
2098
2099       c = ext_top(r);
2100
2101       if (c != min_quarterword)
2102         w = w + height_plus_depth(f, c);
2103
2104       n = 0;
2105
2106       if (u > 0)
2107         while (w < v)
2108         {
2109           w = w + u;
2110           incr(n);
2111
2112           if (ext_mid(r) != min_quarterword)
2113             w = w + u;
2114         }
2115
2116       c = ext_bot(r);
2117
2118       if (c != min_quarterword)
2119         stack_into_box(b, f, c);
2120
2121       c = ext_rep(r);
2122
2123       for (m = 1; m <= n; m++)
2124         stack_into_box(b, f, c);
2125
2126       c = ext_mid(r);
2127
2128       if (c != min_quarterword)
2129       {
2130         stack_into_box(b, f, c);
2131         c = ext_rep(r);
2132
2133         for (m = 1; m <= n; m++)
2134           stack_into_box(b, f, c);
2135       }
2136
2137       c = ext_top(r);
2138
2139       if (c != 0)
2140         stack_into_box(b, f, c);
2141       
2142       depth(b) = w - height(b);
2143     }
2144     else
2145       b = char_box(f, c);
2146   else
2147   {
2148     b = new_null_box();
2149     width(b) = null_delimiter_space;
2150   }
2151
2152   shift_amount(b) = half(height(b) - depth(b)) - axis_height(s);
2153
2154   return b;
2155 }
2156 /* rebox_ etc used to follow here in tex4.c */