OSDN Git Service

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