OSDN Git Service

9149cd6ef48dedaffb601c6bb0f4899105549d83
[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 "yandytex.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
55         if (c / 10 > 0)
56           print_char('0' + c / 10);
57       }
58
59       print_char('0' + c % 10);
60       print_char(')');
61     }
62
63     prints(" in font ");
64     slow_print(font_name[f]);
65     print_char('!');
66
67     if (show_missing)
68     {
69       if (f != null_font)
70         show_context();
71     }
72
73     if (show_missing == 0)
74       end_diagnostic(false);
75
76     missing_characters++;
77   }
78 }
79 /* sec 0582 */
80 pointer new_character_(internal_font_number f, eight_bits c)
81 {
82   pointer p;
83
84   if (font_bc[f] <= c)
85     if (font_ec[f] >= c)
86       if (char_exists(char_info(f, c)))
87       {
88         p = get_avail();
89         font(p) = f;
90         character(p) = c;
91         return p;
92       }
93
94   char_warning(f, c);
95   return 0;
96 }
97 /* sec 0598 */
98 void dvi_swap (void)
99
100   if (trace_flag)
101   {
102     wterm_cr();
103     printf("dvi_swap() %lld", dvi_gone);
104   }
105
106   if (dvi_limit == dvi_buf_size)
107   {
108     write_dvi(0, half_buf - 1);
109     dvi_limit = half_buf;
110     dvi_offset = dvi_offset + dvi_buf_size;
111     dvi_ptr = 0;
112   }
113   else
114   {
115     write_dvi(half_buf, dvi_buf_size - 1);
116     dvi_limit = dvi_buf_size;
117   }
118
119   dvi_gone = dvi_gone + half_buf;
120 }
121 /* sec 0600 */
122 void dvi_four_(integer x)
123
124   if (x >= 0)
125     dvi_out(x / 0100000000);
126   else
127   {
128     x = x + 010000000000;
129     x = x + 010000000000;
130     dvi_out((x / 0100000000) + 128);
131   }
132
133   x = x % 0100000000;
134   dvi_out(x / 0200000);
135   x = x % 0200000;
136   dvi_out(x / 0400);
137   dvi_out(x % 0400);
138 }
139 /* sec 0601 */
140 void dvi_pop_(integer l)
141 {
142   if ((l == dvi_offset + dvi_ptr) && (dvi_ptr > 0))
143     decr(dvi_ptr);
144   else
145     dvi_out(pop);
146 }
147 /* sec 0602 */
148 void dvi_font_def (internal_font_number f)
149 {
150   pool_pointer k;
151
152 #ifdef INCREASEFONTS
153   if (f <= 256)
154   {
155     dvi_out(fnt_def1);
156     dvi_out(f - 1);
157   }
158   else
159   {
160     dvi_out(fnt_def2);
161     dvi_out(((f - 1) >> 8));
162     dvi_out(((f - 1) & 255));
163   }
164 #else
165   dvi_out(fnt_def1);
166   dvi_out(f - 1);
167 #endif
168
169   dvi_out(font_check[f].b0);
170   dvi_out(font_check[f].b1);
171   dvi_out(font_check[f].b2);
172   dvi_out(font_check[f].b3);
173   dvi_four(font_size[f]); 
174   dvi_four(font_dsize[f]);
175   dvi_out(length(font_area[f]));
176   dvi_out(length(font_name[f]));
177
178   for (k = str_start[font_area[f]]; k <= str_start[font_area[f] + 1] - 1; k++)
179     dvi_out(str_pool[k]);
180
181   for (k = str_start[font_name[f]]; k <= str_start[font_name[f] + 1] - 1; k++)
182     dvi_out(str_pool[k]);
183 }
184 /* sec 0607 */
185 void movement (scaled w, eight_bits o)
186 {
187   small_number mstate;
188   pointer p, q;
189   integer k;
190
191   q = get_node(movement_node_size);
192   width(q) = w;
193   location(q) = dvi_offset + dvi_ptr;
194
195   if (o == down1)
196   {
197     link(q) = down_ptr;
198     down_ptr = q;
199   }
200   else
201   {
202     link(q) = right_ptr;
203     right_ptr = q;
204   }
205
206   p = link(q);
207   mstate = none_seen;
208
209   while (p != 0)
210   {
211     if (width(p) == w)
212       switch (mstate + info(p))
213       {
214         case none_seen + yz_OK:
215         case none_seen + y_OK:
216         case z_seen + yz_OK:
217         case z_seen + y_OK:
218           if (location(p) < dvi_gone)
219             goto not_found;
220           else
221           {
222             k = location(p) - dvi_offset;
223
224             if (k < 0)
225               k = k + dvi_buf_size;
226
227             dvi_buf[k] = dvi_buf[k] + y1 - down1;
228             info(p) = y_here;
229             goto found;
230           }
231           break;
232
233         case none_seen + z_OK:
234         case y_seen + yz_OK:
235         case y_seen + z_OK:
236           if (location(p) < dvi_gone)
237             goto not_found;
238           else
239           {
240             k = location(p) - dvi_offset;
241
242             if (k < 0)
243               k = k + dvi_buf_size;
244
245             dvi_buf[k] = dvi_buf[k] + z1 - down1;
246             info(p) = z_here;
247             goto found;
248           }
249           break;
250
251         case none_seen + y_here:
252         case none_seen + z_here:
253         case y_seen + z_here:
254         case z_seen + y_here:
255           goto found;
256           break;
257
258         default:
259           break;
260       }
261     else
262       switch (mstate + info(p))
263       {
264         case none_seen + y_here:
265           mstate = y_seen;
266           break;
267
268         case none_seen + z_here:
269           mstate = z_seen;
270           break;
271
272         case y_seen + z_here:
273         case z_seen + y_here:
274           goto not_found;
275           break;
276
277         default:
278           break;
279       }
280
281     p = link(p);
282   }
283
284 not_found:
285
286   info(q) = yz_OK;
287
288   if (abs(w) >= 8388608L) /* 2^23 */
289   {
290     dvi_out(o + 3);
291     dvi_four(w);
292     return;
293   }
294
295   if (abs(w) >= 32768L)
296   {
297     dvi_out(o + 2);
298
299     if (w < 0)
300       w = w + 16777216L;  /* 2^24 */
301     //dvi_out(w / 65536L);
302     dvi_out((w >> 16));
303     //w = w % 65536L;
304     w = w & 65535L;
305     goto lab2;
306   }
307
308   if (abs(w) >= 128)
309   {
310     dvi_out(o + 1);
311
312     if (w < 0)
313       w = w + 65536L;
314
315     goto lab2;
316   }
317
318   dvi_out(o);
319
320   if (w < 0)
321     w = w + 256;
322
323   goto lab1;
324
325 lab2:
326   dvi_out(w / 256);
327
328 lab1:
329   dvi_out(w % 256);
330   return;
331
332 found:
333   info(q) = info(p);
334
335   if (info(q) == y_here)
336   {
337     dvi_out(o + y0 - down1);
338
339     while (link(q) != p)
340     {
341       q = link(q);
342
343       switch (info(q))
344       {
345         case yz_OK:
346           info(q) = z_OK;
347           break;
348
349         case y_OK:
350           info(q) = d_fixed;
351           break;
352
353         default:
354           break;
355       }
356     }
357   }
358   else
359   {
360     dvi_out(o + z0 - down1);
361
362     while (link(q) != p)
363     {
364       q = link(q);
365
366       switch (info(q))
367       {
368         case yz_OK:
369           info(q) = y_OK;
370           break;
371
372         case z_OK:
373           info(q) = d_fixed;
374           break;
375
376         default:
377           break;
378       }
379     }
380   }
381 }
382 /* sec 0615 */
383 void prune_movements (integer l)
384 {
385   pointer p;
386
387   while (down_ptr != 0)
388   {
389     if (location(down_ptr) < l)
390       goto done;
391
392     p = down_ptr;
393     down_ptr = link(p);
394     free_node(p, movement_node_size);
395   }
396
397 done:
398   while (right_ptr != 0)
399   {
400     if (location(right_ptr) < l)
401       return;
402
403     p = right_ptr;
404     right_ptr = link(p);
405     free_node(p, movement_node_size);
406   }
407 }
408 /* sec 1368 */
409 void special_out (pointer p)
410 {
411   char old_setting;
412   pool_pointer k;
413
414   synch_h();
415   synch_v();
416   old_setting = selector;
417   selector = new_string;
418
419 #ifdef ALLOCATESTRING
420   if (pool_ptr + 32000 > current_pool_size)
421     str_pool = realloc_str_pool (increment_pool_size);
422
423   show_token_list(link(write_tokens(p)), 0, 10000000L);
424 #else
425   show_token_list(link(write_tokens(p)), 0, pool_size - pool_ptr);
426 #endif
427
428   selector = old_setting;
429   str_room(1);
430   graphics_mode();
431   spc_exec_special(str_pool + str_start[str_ptr], cur_length, cur_h * 0.000015202, -cur_v * 0.000015202, 1.0);
432 /*
433   if (cur_length < 256)
434   {
435     dvi_out(xxx1);
436     dvi_out(cur_length);
437   }
438   else
439   {Mag
440     dvi_out(xxx4);
441     dvi_four(cur_length); 
442   } 
443
444   for (k = str_start[str_ptr]; k <= pool_ptr - 1; k++)
445     dvi_out(str_pool[k]);
446 */
447   pool_ptr = str_start[str_ptr];
448 }
449 /* sec 1370 */
450 void write_out (pointer p)
451 {
452   char old_setting;
453   /* integer old_mode; */
454   int old_mode;
455   /* small_number j; */
456   int j;
457   pointer q, r;
458
459   q = get_avail();
460   info(q) = right_brace_token + '}';
461   r = get_avail();
462   link(q) = r;
463   info(r) = end_write_token;
464   ins_list(q);
465   begin_token_list(write_tokens(p), write_text);
466   q = get_avail();
467   info(q) = left_brace_token + '{';
468   ins_list(q);
469   old_mode = mode;
470   mode = 0;
471   cur_cs = write_loc;
472   q = scan_toks(false, true);
473   get_token();
474
475   if (cur_tok != end_write_token)
476   {
477     print_err("Unbalanced write command");
478     help2("On this page there's a \\write with fewer real {'s than }'s.",
479         "I can't handle that very well; good luck.");
480     error();
481
482     do
483       {
484         get_token();
485       }
486     while (!(cur_tok == end_write_token));
487   }
488
489   mode = old_mode;
490   end_token_list();
491   old_setting = selector;
492   j = write_stream(p);
493
494   if (write_open[j])
495     selector = j;
496   else
497   {
498     if ((j == 17) && (selector == term_and_log))
499       selector = log_only;
500
501     print_nl("");
502   }
503
504   token_show(def_ref);
505   print_ln();
506   flush_list(def_ref);
507   selector = old_setting;
508 }
509 /* sec 1373 */
510 void out_what (pointer p)
511 {
512   /* small_number j; */
513   int j;
514
515   switch (subtype(p))
516   {
517     case open_node:
518     case write_node:
519     case close_node:
520       if (!doing_leaders)
521       {
522         j = write_stream(p);
523
524         if (subtype(p) == write_node)
525           write_out(p);
526         else
527         {
528           if (write_open[j])
529             a_close(write_file[j]); 
530
531           if (subtype(p) == close_node)
532             write_open[j]= false;
533           else if (j < 16)
534           {
535             cur_name = open_name(p);
536             cur_area = open_area(p);
537             cur_ext = open_ext(p); 
538
539             if (cur_ext == 335) /* "" */
540               cur_ext = 785;    /* ".tex" */
541
542             pack_file_name(cur_name, cur_area, cur_ext);
543
544             while (!a_open_out(write_file[j]))
545               prompt_file_name("output file name", ".tex");
546
547             write_open[j] = true;
548           }
549         }
550       }
551       break;
552
553     case special_node:
554       special_out(p); 
555       break;
556
557     case language_node:
558       do_nothing();
559       break;
560
561     default:
562       {
563         confusion("ext4");
564         return;
565       }
566       break;
567   }
568 }
569 /* sec 0619 */
570 void hlist_out (void)
571 {
572   scaled base_line;
573   scaled left_edge;
574   scaled save_h, save_v;
575   pointer this_box;
576   /* glue_ord g_order; */
577   int g_order;
578   /* char g_sign; */
579   int g_sign;
580   pointer p;
581   integer save_loc;
582   pointer leader_box;
583   scaled leader_wd;
584   scaled lx;
585   boolean outer_doing_leaders;
586   scaled edge;
587   real glue_temp;
588   real cur_glue;
589   scaled cur_g;
590
591   cur_g = 0;
592   cur_glue = 0.0;
593   this_box = temp_ptr;
594   g_order = glue_order(this_box);
595   g_sign = glue_sign(this_box);
596   p = list_ptr(this_box);
597   incr(cur_s);
598
599   if (cur_s > 0)
600     dvi_out(push);
601
602   if (cur_s > max_push)
603     max_push = cur_s;
604
605   save_loc = dvi_offset + dvi_ptr;
606   base_line = cur_v;
607   left_edge = cur_h;
608
609   while (p != 0)
610 reswitch:
611     if (is_char_node(p))
612     {
613       synch_h();
614       synch_v();
615
616       do
617         {
618           f = font(p);
619           c = character(p);
620
621           if (f != dvi_f)
622           {
623             if (!font_used[f])
624             {
625               dvi_font_def(f);
626               font_used[f] = true;
627             }
628
629             if (f <= 64 + font_base)
630               dvi_out(f - font_base - 1 + fnt_num_0);
631 #ifdef INCREASEFONTS
632             else if (f <= 256)
633             {
634               dvi_out(fnt1);
635               dvi_out(f - 1);
636             }
637             else
638             {
639               dvi_out(fnt2);
640               dvi_out(((f - 1) >> 8));
641               dvi_out(((f - 1) & 255));
642             }
643 #else
644             else
645             {
646               dvi_out(fnt1);
647               dvi_out(f - 1);
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_(pointer 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   //printf("init pdf devices.");
1253   //dvi_ship_out_(p);
1254   //printf("DPX test");
1255   pdf_ship_out(p);
1256   /*
1257   switch (shipout_flag)
1258   {
1259     case out_dvi_flag:
1260     case out_xdv_flag:
1261       dvi_ship_out_(p);
1262       break;
1263     case out_pdf_flag:
1264       //pdf_ship_out(p);
1265       break;
1266   }*/
1267 }
1268 /* sec 0645 */
1269 void scan_spec (group_code c, boolean three_codes)
1270 {
1271   integer s;
1272   char spec_code;
1273
1274   if (three_codes)
1275     s = saved(0);
1276
1277   if (scan_keyword("to"))
1278     spec_code = exactly;
1279   else if (scan_keyword("spread"))
1280     spec_code = additional;
1281   else
1282   {
1283     spec_code = additional;
1284     cur_val = 0;
1285     goto found;
1286   }
1287
1288   scan_dimen(false, false, false);
1289
1290 found:
1291   if (three_codes)
1292   {
1293     saved(0) = s;
1294     incr(save_ptr);
1295   }
1296
1297   saved(0) = spec_code;
1298   saved(1) = cur_val;
1299   save_ptr = save_ptr + 2;
1300   new_save_level(c);
1301   scan_left_brace();
1302 }
1303 /* sec 0649 */
1304 pointer hpack_(pointer p, scaled w, small_number m)
1305 {
1306   pointer r;
1307   pointer q;
1308   scaled h, d, x;
1309   scaled s;
1310   pointer g;
1311   /* glue_ord o; */
1312   int o;
1313   internal_font_number f;
1314   four_quarters i;
1315   eight_bits hd;
1316
1317   last_badness = 0;
1318   r = get_node(box_node_size);
1319   type(r) = hlist_node;
1320   subtype(r) = 0;
1321   shift_amount(r) = 0;
1322   q = r + list_offset;
1323   link(q) = p;
1324   h = 0;
1325   d = 0;
1326   x = 0;
1327   total_stretch[normal] = 0;
1328   total_shrink[normal] = 0;
1329   total_stretch[fil] = 0;
1330   total_shrink[fil] = 0;
1331   total_stretch[fill] = 0;
1332   total_shrink[fill] = 0;
1333   total_stretch[filll] = 0;
1334   total_shrink[filll] = 0;
1335
1336   while (p != 0)
1337   {
1338 reswitch:
1339
1340     while (is_char_node(p))
1341     {
1342       f = font(p);
1343       i = char_info(f, character(p));
1344       hd = height_depth(i);
1345       x = x + char_width(f, i);
1346       s = char_height(f, hd);
1347
1348       if (s > h)
1349         h = s;
1350
1351       s = char_depth(f, hd);
1352
1353       if (s > d)
1354         d = s;
1355
1356       p = link(p);
1357     }
1358
1359     if (p != 0)
1360     {
1361       switch (type(p))
1362       {
1363         case hlist_node:
1364         case vlist_node:
1365         case rule_node:
1366         case unset_node:
1367           {
1368             x = x + width(p);
1369
1370             if (type(p) >= rule_node)
1371               s = 0;
1372             else
1373               s = shift_amount(p);
1374
1375             if (height(p) - s > h)
1376               h = height(p) - s;
1377
1378             if (depth(p) + s > d)
1379               d = depth(p) + s;
1380           }
1381           break;
1382
1383         case ins_node:
1384         case mark_node:
1385         case adjust_node:
1386           if (adjust_tail != 0)
1387           {
1388             while (link(q) != p)
1389               q = link(q);
1390
1391             if (type(p) == adjust_node)
1392             {
1393               link(adjust_tail) = adjust_ptr(p);
1394
1395               while (link(adjust_tail) != 0)
1396                 adjust_tail = link(adjust_tail);
1397
1398               p = link(p);
1399               free_node(link(q), small_node_size);
1400             }
1401             else
1402             {
1403               link(adjust_tail) = p;
1404               adjust_tail = p;
1405               p = link(p);
1406             }
1407
1408             link(q) = p;
1409             p = q;
1410           }
1411           break;
1412
1413         case whatsit_node:
1414           break;
1415
1416         case glue_node:
1417           {
1418             g = glue_ptr(p);
1419             x = x + width(g);
1420             o = stretch_order(g);
1421             total_stretch[o] = total_stretch[o] + stretch(g);
1422             o = shrink_order(g);
1423             total_shrink[o] = total_shrink[o] + shrink(g);
1424
1425             if (subtype(p) >= a_leaders)
1426             {
1427               g = leader_ptr(p);
1428
1429               if (height(g) > h)
1430                 h = height(g);
1431
1432               if (depth(g) > d)
1433                 d = depth(g);
1434             }
1435           }
1436           break;
1437
1438         case kern_node:
1439         case math_node:
1440           x = x + width(p);
1441           break;
1442
1443         case ligature_node:
1444           {
1445             mem[lig_trick] = mem[lig_char(p)];
1446             link(lig_trick) = link(p);
1447             p = lig_trick;
1448             goto reswitch;
1449           }
1450           break;
1451
1452         default:
1453           break;
1454       }
1455       p = link(p);
1456     }
1457   }
1458
1459   if (adjust_tail != 0)
1460     link(adjust_tail) = 0;
1461
1462   height(r) = h;
1463   depth(r) = d;
1464
1465   if (m == additional)
1466     w = x + w;
1467
1468   width(r) = w;
1469   x = w - x;
1470
1471   if (x == 0)
1472   {
1473     glue_sign(r) = normal;
1474     glue_order(r) = normal;
1475     glue_set(r) = 0.0;
1476     goto exit;
1477   }
1478   else if (x > 0)
1479   {
1480     if (total_stretch[filll] != 0)
1481       o = filll;
1482     else if (total_stretch[fill] != 0)
1483       o = fill;
1484     else if (total_stretch[fil] != 0)
1485       o = fil;
1486     else
1487       o = normal;
1488
1489     glue_order(r) = o;
1490     glue_sign(r) = stretching;
1491
1492     if (total_stretch[o] != 0)
1493       glue_set(r) = x / ((double) total_stretch[o]);
1494     else
1495     {
1496       glue_sign(r) = normal;
1497       glue_set(r) = 0.0;
1498     }
1499
1500     if (o == normal)
1501       if (list_ptr(r) != 0)
1502       {
1503         last_badness = badness(x, total_stretch[normal]);
1504
1505         if (last_badness > hbadness)
1506         {
1507           print_ln();
1508
1509           if (last_badness > 100)
1510             print_nl("Underfull");
1511           else
1512             print_nl("Loose");
1513
1514           prints(" \\hbox (badness ");
1515           print_int(last_badness);
1516
1517           if (last_badness > 100)
1518             underfull_hbox++;
1519
1520           goto common_ending;
1521         }
1522       }
1523
1524     goto exit;
1525   }
1526   else
1527   {
1528     if (total_shrink[filll] != 0)
1529       o = filll;
1530     else if (total_shrink[fill] != 0)
1531       o = fill;
1532     else if (total_shrink[fil] != 0)
1533       o = fil;
1534     else
1535       o = normal;
1536
1537     glue_order(r) = o;
1538     glue_sign(r) = shrinking;
1539
1540     if (total_shrink[o] != 0)
1541       glue_set(r) = ((- (integer) x) / ((double) total_shrink[o]));
1542     else
1543     {
1544       glue_sign(r) = normal;
1545       glue_set(r) = 0.0;
1546     }
1547
1548     if ((total_shrink[o] < - (integer) x) && (o == 0) && (list_ptr(r) != 0))
1549     {
1550       last_badness = 1000000L;
1551       glue_set(r) = 1.0;
1552
1553       if ((- (integer) x - total_shrink[normal] > hfuzz) || (hbadness < 100))
1554       {
1555         if ((overfull_rule > 0) && (- (integer) x - total_shrink[0] > hfuzz))
1556         {
1557           while (link(q) != 0)
1558             q = link(q);
1559           
1560           link(q) = new_rule();
1561           width(link(q)) = overfull_rule;
1562         }
1563         
1564         print_ln();
1565         print_nl("Overfull \\hbox (");
1566         print_scaled(- (integer) x - total_shrink[normal]);
1567         prints("pt too wide");
1568         
1569         overfull_hbox++;
1570         goto common_ending;
1571       }
1572     }
1573     else if (o == normal)
1574       if (list_ptr(r) != 0)
1575       {
1576         last_badness = badness(- (integer) x, total_shrink[normal]);
1577
1578         if (last_badness > hbadness)
1579         {
1580           print_ln();
1581           print_nl("Tight \\hbox (badness ");
1582           print_int(last_badness);
1583           goto common_ending;
1584         }
1585       }
1586
1587     goto exit;
1588   }
1589
1590 common_ending:
1591
1592   if (output_active)
1593     prints(") has occurred while \\output is active");
1594   else
1595   {
1596     if (pack_begin_line != 0)
1597     {
1598       if (pack_begin_line > 0)
1599         prints(") in paragraph at lines ");
1600       else
1601         prints(") in alignment at lines ");
1602
1603       print_int(abs(pack_begin_line));
1604       prints("--");
1605     }
1606     else
1607       prints(") detected at line ");
1608
1609     print_int(line);
1610   }
1611
1612   print_ln();
1613   font_in_short_display = null_font;
1614   short_display(list_ptr(r));
1615   print_ln();
1616   begin_diagnostic();
1617   show_box(r);
1618   end_diagnostic(true);
1619
1620 exit:
1621   return r;
1622 }
1623 /* sec 0668 */
1624 pointer vpackage_(pointer p, scaled h, small_number m, scaled l)
1625 {
1626   pointer r;
1627   scaled w, d, x;
1628   scaled s;
1629   pointer g;
1630   /* glue_ord o; */
1631   int o;
1632
1633   last_badness = 0;
1634   r = get_node(box_node_size);
1635   type(r) = vlist_node;
1636   subtype(r) = min_quarterword;
1637   shift_amount(r) = 0;
1638   list_ptr(r) = p;
1639   w = 0;
1640   d = 0;
1641   x = 0;
1642   total_stretch[normal] = 0;
1643   total_shrink[normal] = 0;
1644   total_stretch[fil] = 0;
1645   total_shrink[fil] = 0;
1646   total_stretch[fill] = 0;
1647   total_shrink[fill] = 0;
1648   total_stretch[filll] = 0;
1649   total_shrink[filll] = 0;
1650
1651   while (p != 0)
1652   {
1653     if (is_char_node(p))
1654     {
1655       confusion("vpack");
1656       return 0;
1657     }
1658     else switch (type(p))
1659     {
1660       case hlist_node:
1661       case vlist_node:
1662       case rule_node:
1663       case unset_node:
1664         {
1665           x = x + d + height(p);
1666           d = depth(p);
1667
1668           if (type(p) >= rule_node)
1669             s = 0;
1670           else
1671             s = shift_amount(p);
1672
1673           if (width(p) + s > w)
1674             w = width(p) + s;
1675         }
1676         break;
1677
1678       case whatsit_node:
1679         break;
1680
1681       case glue_node:
1682         {
1683           x = x + d;
1684           d = 0;
1685           g = glue_ptr(p);
1686           x = x + width(g);
1687           o = stretch_order(g);
1688           total_stretch[o] = total_stretch[o] + stretch(g);
1689           o = shrink_order(g);
1690           total_shrink[o] = total_shrink[o] + shrink(g);
1691
1692           if (subtype(p) >= a_leaders)
1693           {
1694             g = leader_ptr(p);
1695
1696             if (width(g) > w)
1697               w = width(g);
1698           }
1699         }
1700         break;
1701
1702       case kern_node:
1703         {
1704           x = x + d + width(p);
1705           d = 0;
1706         }
1707         break;
1708
1709       default:
1710         break;
1711     }
1712
1713     p = link(p);
1714   }
1715
1716   width(r) = w;
1717
1718   if (d > l)
1719   {
1720     x = x + d - l;
1721     depth(r) = l;
1722   }
1723   else
1724     depth(r) = d;
1725
1726   if (m == additional)
1727     h = x + h;
1728
1729   height(r) = h;
1730   x = h - x;
1731
1732   if (x == 0)
1733   {
1734     glue_sign(r) = normal;
1735     glue_order(r) = normal;
1736     glue_set(r) = 0.0;
1737     goto exit;
1738   }
1739   else if (x > 0)
1740   {
1741     if (total_stretch[filll] != 0)
1742       o = filll;
1743     else if (total_stretch[fill] != 0)
1744       o = fill;
1745     else if (total_stretch[fil] != 0)
1746       o = fil;
1747     else
1748       o = normal;
1749
1750     glue_order(r) = o;
1751     glue_sign(r) = stretching;
1752
1753     if (total_stretch[o] != 0)
1754       glue_set(r) = x / ((double) total_stretch[o]);
1755     else
1756     {
1757       glue_sign(r) = normal;
1758       glue_set(r) = 0.0;
1759     }
1760
1761     if (o == normal)
1762       if (list_ptr(r) != 0)
1763       {
1764         last_badness = badness(x, total_stretch[normal]);
1765
1766         if (last_badness > vbadness)
1767         {
1768           print_ln();
1769
1770           if (last_badness > 100)
1771             print_nl("Underfull");
1772           else
1773             print_nl("Loose");
1774
1775           prints(" \\vbox (badness ");
1776           print_int(last_badness);
1777
1778           if (last_badness > 100)
1779             underfull_vbox++;
1780
1781           goto common_ending;
1782         }
1783       }
1784
1785     goto exit;
1786   }
1787   else
1788   {
1789     if (total_shrink[filll] != 0)
1790       o = filll;
1791     else if (total_shrink[fill] != 0)
1792       o = fill;
1793     else if (total_shrink[fil] != 0)
1794       o = fil;
1795     else
1796       o = normal;
1797
1798     glue_order(r) = o;
1799     glue_sign(r) = shrinking;
1800
1801     if (total_shrink[o] != 0)
1802       glue_set(r) = (- (integer) x) / ((double) total_shrink[o]);
1803     else
1804     {
1805       glue_sign(r) = normal;
1806       glue_set(r) = 0.0;
1807     }
1808
1809     if ((total_shrink[o] < - (integer) x) && (o == 0) && (list_ptr(r) != 0))
1810     {
1811       last_badness = 1000000L;
1812       glue_set(r) = 1.0;
1813
1814       if ((- (integer) x - total_shrink[0] > vfuzz) || (vbadness < 100))
1815       {
1816         print_ln();
1817         print_nl("Overfull \\vbox (");
1818         print_scaled(- (integer) x - total_shrink[0]);
1819         prints("pt too high");
1820
1821         overfull_vbox++;
1822
1823         goto common_ending;
1824       }
1825     }
1826     else if (o == 0)
1827       if (list_ptr(r) != 0)
1828       {
1829         last_badness = badness(- (integer) x, total_shrink[normal]);
1830         if (last_badness > vbadness)
1831         {
1832           print_ln();
1833           print_nl("Tight \\vbox (badness ");
1834           print_int(last_badness);
1835           goto common_ending;
1836         }
1837       }
1838
1839     goto exit;
1840   }
1841
1842 common_ending:
1843
1844   if (output_active)
1845     prints(") has occurred while \\output is active");
1846   else
1847   {
1848     if (pack_begin_line != 0)
1849     {
1850       prints(") in alignment at lines ");
1851       print_int(abs(pack_begin_line));
1852       prints("--");
1853     }
1854     else
1855       prints(") detected at line ");
1856
1857     print_int(line);
1858     print_ln();
1859   }
1860
1861   begin_diagnostic();
1862   show_box(r);
1863   end_diagnostic(true);
1864
1865 exit:
1866   return r;
1867 }
1868 /* sec 0679 */
1869 void append_to_vlist (pointer b)
1870 {
1871   scaled d;
1872   pointer p;
1873
1874   if (prev_depth > ignore_depth)
1875   {
1876     d = width(baseline_skip) - prev_depth - height(b);
1877
1878     if (d < line_skip_limit)
1879       p = new_param_glue(line_skip_code);
1880     else
1881     {
1882       p = new_skip_param(baseline_skip_code);
1883       width(temp_ptr) = d;
1884     }
1885
1886     link(tail) = p;
1887     tail = p;
1888   }
1889
1890   link(tail) = b;
1891   tail = b;
1892   prev_depth = depth(b);
1893 }
1894 /* sec 0686 */
1895 pointer new_noad (void)
1896 {
1897   pointer p;
1898
1899   p = get_node(noad_size);
1900   type(p) = ord_noad;
1901   subtype(p) = normal;
1902   mem[nucleus(p)].hh = empty_field;
1903   mem[subscr(p)].hh = empty_field;
1904   mem[supscr(p)].hh = empty_field;
1905
1906   return p;
1907 }
1908 /* sec 0688 */
1909 pointer new_style (small_number s)
1910 {
1911   pointer p;
1912
1913   p = get_node(style_node_size);
1914   type(p) = style_node;
1915   subtype(p) = s;
1916   width(p) = 0;
1917   depth(p) = 0;
1918
1919   return p;
1920 }
1921 /* sec 0689 */
1922 pointer new_choice (void)
1923 {
1924   pointer p;
1925
1926   p = get_node(style_node_size);
1927   type(p) = choice_node;
1928   subtype(p) = 0;
1929   display_mlist(p) = 0;
1930   text_mlist(p) = 0;
1931   script_mlist(p) = 0;
1932   script_script_mlist(p) = 0;
1933
1934   return p;
1935 }
1936 /* sec 0693 */
1937 void show_info (void)
1938 {
1939   show_node_list(info(temp_ptr));
1940 }
1941 /* sec 0704 */
1942 pointer fraction_rule (scaled t)
1943 {
1944   pointer p;
1945
1946   p = new_rule();
1947   height(p) = t;
1948   depth(p) = 0;
1949
1950   return p;
1951 }
1952 /* sec 0705 */
1953 pointer overbar (pointer b, scaled k, scaled t)
1954 {
1955   pointer p, q;
1956
1957   p = new_kern(k);
1958   link(p) = b;
1959   q = fraction_rule(t);
1960   link(q) = p;
1961   p = new_kern(t);
1962   link(p) = q;
1963
1964   return vpackage(p, 0, 1, max_dimen);
1965 }
1966 /* sec 0709 */
1967 pointer char_box (internal_font_number f, quarterword c)
1968 {
1969   four_quarters q;
1970   eight_bits hd;
1971   pointer b, p;
1972
1973   q = char_info(f, c);
1974   hd = height_depth(q);
1975   b = new_null_box();
1976   width(b) = char_width(f, q) + char_italic(f, q);
1977   height(b) = char_height(f, hd);
1978   depth(b) = char_depth(f, hd);
1979   p = get_avail();
1980   character(p) = c;
1981   font(p) = f;
1982   list_ptr(b) = p;
1983
1984   return b;
1985 }
1986 /* sec 0711 */
1987 void stack_into_box (pointer b, internal_font_number f, quarterword c)
1988 {
1989   pointer p;
1990
1991   p = char_box(f, c);
1992   link(p) = list_ptr(b);
1993   list_ptr(b) = p;
1994   height(b) = height(p);
1995 }
1996 /* sec 0712 */
1997 scaled height_plus_depth (internal_font_number f, quarterword c)
1998 {
1999   four_quarters q;
2000   eight_bits hd;
2001
2002   q = char_info(f, c);
2003   hd = height_depth(q);
2004
2005   return char_height(f, hd) + char_depth(f, hd);
2006 }
2007 /* sec 0706 */
2008 pointer var_delimiter (pointer d, small_number s, scaled v)
2009 {
2010   pointer b;
2011   internal_font_number f, g;
2012   quarterword c, x, y;
2013   integer m, n;
2014   scaled u;
2015   scaled w;
2016   four_quarters q;
2017   four_quarters r;
2018   eight_bits hd;
2019   /* small_number z; */
2020   int z;
2021   boolean large_attempt;
2022
2023   f = null_font;
2024   w = 0;
2025   large_attempt = false;
2026   z = small_fam(d);
2027   x = small_char(d);
2028
2029   while (true)
2030   {
2031     if ((z != 0) || (x != 0))
2032     {
2033       z = z + s + 16;
2034
2035       do
2036         {
2037           z = z - 16;
2038           g = fam_fnt(z);
2039
2040           if (g != null_font)
2041           {
2042             y = x;
2043
2044             if ((y >= font_bc[g]) && (y <= font_ec[g]))
2045             {
2046 continu:
2047               q = char_info(g, y);
2048               
2049               if (char_exists(q))
2050               {
2051                 if (char_tag(q) == ext_tag)
2052                 {
2053                   f = g;
2054                   c = y;
2055                   goto found;
2056                 }
2057
2058                 hd = height_depth(q);
2059                 u = char_height(g, hd) + char_depth(g, hd);
2060
2061                 if (u > w)
2062                 {
2063                   f = g;
2064                   c = y;
2065                   w = u;
2066
2067                   if (u >= v)
2068                     goto found;
2069                 }
2070
2071                 if (char_tag(q) == list_tag)
2072                 {
2073                   y = rem_byte(q);
2074                   goto continu;
2075                 }
2076               }
2077             }
2078           }
2079         }
2080       while (!(z < 16));
2081     }
2082
2083     if (large_attempt)
2084       goto found;
2085
2086     large_attempt = true;
2087     z = large_fam(d);
2088     x = large_char(d);
2089   }
2090
2091 found:
2092   if (f != null_font)
2093     if (char_tag(q) == ext_tag)
2094     {
2095       b = new_null_box();
2096       type(b) = vlist_node;
2097       r = font_info[exten_base[f] + rem_byte(q)].qqqq;
2098       c = ext_rep(r);
2099       u = height_plus_depth(f, c);
2100       w = 0;
2101       q = char_info(f, c);
2102       width(b) = char_width(f, q) + char_italic(f, q);
2103       c = ext_bot(r);
2104
2105       if (c != min_quarterword)
2106         w = w + height_plus_depth(f, c);
2107
2108       c = ext_mid(r);
2109
2110       if (c != min_quarterword)
2111         w = w + height_plus_depth(f, c);
2112
2113       c = ext_top(r);
2114
2115       if (c != min_quarterword)
2116         w = w + height_plus_depth(f, c);
2117
2118       n = 0;
2119
2120       if (u > 0)
2121         while (w < v)
2122         {
2123           w = w + u;
2124           incr(n);
2125
2126           if (ext_mid(r) != min_quarterword)
2127             w = w + u;
2128         }
2129
2130       c = ext_bot(r);
2131
2132       if (c != min_quarterword)
2133         stack_into_box(b, f, c);
2134
2135       c = ext_rep(r);
2136
2137       for (m = 1; m <= n; m++)
2138         stack_into_box(b, f, c);
2139
2140       c = ext_mid(r);
2141
2142       if (c != min_quarterword)
2143       {
2144         stack_into_box(b, f, c);
2145         c = ext_rep(r);
2146
2147         for (m = 1; m <= n; m++)
2148           stack_into_box(b, f, c);
2149       }
2150
2151       c = ext_top(r);
2152
2153       if (c != 0)
2154         stack_into_box(b, f, c);
2155       
2156       depth(b) = w - height(b);
2157     }
2158     else
2159       b = char_box(f, c);
2160   else
2161   {
2162     b = new_null_box();
2163     width(b) = null_delimiter_space;
2164   }
2165
2166   shift_amount(b) = half(height(b) - depth(b)) - axis_height(s);
2167
2168   return b;
2169 }