OSDN Git Service

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