home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Tex / Tex29 / StTeXsrc.zoo / src / pack.c < prev    next >
C/C++ Source or Header  |  1988-03-13  |  11KB  |  409 lines

  1.  
  2. /*
  3.  * @(#)pack.c 2.6 EPA
  4.  *
  5.  * Copyright 1987,1988 Pat J Monardo
  6.  *
  7.  * Redistribution of this file is permitted through
  8.  * the specifications in the file COPYING.
  9.  *
  10.  * 
  11.  */
  12.  
  13. #include "tex.h"
  14. #include "scan.h"
  15. #include "tokenstack.h"
  16. #include "eqstack.h"
  17. #include "evalstack.h"
  18. #include "box.h"
  19. #include "tfm.h"
  20. #include "dvi.h"
  21. #include "pack.h"
  22.  
  23. ptr     adjust_tail;
  24. val     pack_begin_line;
  25. scal    total_shrink[4];
  26. scal    total_stretch[4];
  27.  
  28. #define clr_dimens() \
  29.     {d = x = 0;  \
  30.     total_stretch[FILLL] = 0;\
  31.     total_stretch[FILL] = 0; \
  32.     total_stretch[FIL] = 0; \
  33.     total_stretch[NORMAL] =  0; \
  34.     total_shrink[FILLL] = 0; \
  35.     total_shrink[FILL] = 0; \
  36.     total_shrink[FIL] = 0; \
  37.     total_shrink[NORMAL] = 0;}
  38.  
  39. ptr
  40. hpack (p, w, m)
  41.     ptr     p;
  42.     scal    w;
  43.     int     m;
  44. {
  45.     int     b;
  46.     scal    d;
  47.     fnt     f;
  48.     ptr     g;
  49.     scal    h;
  50.     qqqq    i;
  51.     gord    o;
  52.     ptr     q;
  53.     ptr     r;
  54.     scal    s;
  55.     scal    x;
  56.     byte    hd;
  57.  
  58.     r = get_node(BOX_NODE_SIZE);
  59.     type(r) = HLIST_NODE;
  60.     subtype(r) = MIN_QUARTERWORD;
  61.     shift_amount(r) = 0;
  62.     q = r + LIST_OFFSET;
  63.     link(q) = p;
  64.     h = 0;
  65.     clr_dimens();
  66.  
  67.     while (p != NULL) {
  68. reswitch:
  69.         while (is_char_node(p)) {
  70.             f = font(p);
  71.             i = char_info(f, character(p));
  72.             hd = height_depth(i);
  73.             x += char_width(f, i);
  74.             s = char_height(f, hd);
  75.             if (s > h)
  76.                 h = s;
  77.             s = char_depth(f, hd);
  78.             if (s > d)
  79.                 d = s;
  80.             p = link(p);
  81.         }
  82.         if (p != NULL) {
  83.             switch (type(p))
  84.             {
  85.             case HLIST_NODE:
  86.             case VLIST_NODE:
  87.             case RULE_NODE:
  88.             case UNSET_NODE:
  89.                 x += width(p);
  90.                 if (type(p) >= RULE_NODE)
  91.                     s = 0;
  92.                 else s = shift_amount(p);
  93.                 if (height(p) - s > h)
  94.                     h = height(p) - s;
  95.                 if (depth(p) + s > d)
  96.                     d = depth(p) + s;
  97.                 break;
  98.  
  99.             case INS_NODE:
  100.             case MARK_NODE:
  101.             case ADJUST_NODE:
  102.                 if (adjust_tail != NULL) {
  103.                     while (link(q) != p)
  104.                         q = link(q);
  105.                     if (type(p) == ADJUST_NODE) {
  106.                         link(adjust_tail) = adjust_ptr(p);
  107.                         while (link(adjust_tail) != NULL)
  108.                             adjust_tail = link(adjust_tail);
  109.                         p = link(p);
  110.                         free_node(link(q), SMALL_NODE_SIZE);
  111.                     } else {
  112.                         link(adjust_tail) = p;
  113.                         adjust_tail = p;
  114.                         p = link(p);
  115.                     }
  116.                     link(q) = p;
  117.                     p = q;
  118.                 }
  119.                 break;
  120.  
  121.             case WHATSIT_NODE:
  122.                 break;
  123.             
  124.             case GLUE_NODE:
  125.                 g = glue_ptr(p);
  126.                 x += width(g);
  127.                 o = stretch_order(g);
  128.                 total_stretch[o] += stretch(g);
  129.                 o = shrink_order(g);
  130.                 total_shrink[o] += shrink(g);
  131.                 if (subtype(p) >= A_LEADERS) {
  132.                     g = leader_ptr(p);
  133.                     if (height(g) > h)
  134.                         h = height(g);
  135.                     if (depth(g) > d)
  136.                         d = depth(g);
  137.                 }
  138.                 break;
  139.             
  140.             case KERN_NODE:
  141.             case MATH_NODE:
  142.                 x += width(p);
  143.                 break;
  144.             
  145.             case LIGATURE_NODE:
  146.                 make_char_from_lig();
  147.                 goto reswitch;
  148.                 break;
  149.  
  150.             default:
  151.                 break;
  152.             }
  153.             p = link(p);
  154.         }
  155.     }
  156.     if (adjust_tail != NULL)
  157.         link(adjust_tail) = NULL;
  158.     height(r) = h;
  159.     depth(r) = d;
  160.     if (m == ADDITIONAL)
  161.         w += x;
  162.     width(r) = w;
  163.     x = w - x;
  164.     if (x == 0) {
  165.         glue_sign(r) = NORMAL;
  166.         glue_order(r) = NORMAL;
  167.         glue_set(r) = 0.0;
  168.         return r;
  169.     } else if (x > 0) {
  170.         get_stretch_order(); 
  171.         glue_order(r) = o;
  172.         glue_sign(r) = STRETCHING;
  173.         if (total_stretch[o] != 0) {
  174.             glue_set(r) = (float) x / total_stretch[o];
  175.         } else {
  176.             glue_sign(r) = NORMAL;
  177.             glue_set(r) = 0.0;
  178.         }
  179.         if (hbadness < INF_BAD && o == NORMAL && list_ptr(r) != NULL) {
  180.             b = badness(x, total_stretch[NORMAL]);
  181.             if (b > hbadness) {
  182.                 print_ln();
  183.                 if (b > 100)
  184.                     print_nl("Underfull");
  185.                 else print_nl("Loose");
  186.                 print(" \\hbox (badness ");
  187.                 print_int(b);
  188.                 goto common_end;
  189.             }
  190.         }
  191.         return r;
  192.     } else {
  193.         get_shrink_order();
  194.         glue_order(r) = o;
  195.         glue_sign(r) = SHRINKING;
  196.         if (total_shrink[o] != 0) {
  197.             glue_set(r) = (float) -x / total_shrink[o];
  198.         } else {
  199.             glue_sign(r) = NORMAL;
  200.             glue_set(r) = 0.0;
  201.         }
  202.         if (total_shrink[o] < -x && o == NORMAL && list_ptr(r) != NULL) {
  203.             glue_set(r) = 1.0;
  204.             if (-x - total_shrink[NORMAL] > hfuzz || hbadness < 100) {
  205.                 if (overfull_rule > 0 && -x - total_shrink[NORMAL] > hfuzz) {
  206.                     while (link(q) != NULL)
  207.                         q = link(q);
  208.                     link(q) = new_rule();
  209.                     width(link(q)) = overfull_rule;
  210.                 }
  211.                 print_ln();
  212.                 print_nl("Overfull \\hbox ("); 
  213.                 print_scaled(-x - total_shrink[NORMAL]);
  214.                 print("pt too wide");
  215.                 goto common_end;
  216.             }
  217.         } else if (hbadness < 100 && o == NORMAL && list_ptr(r) != NULL) {
  218.             b = badness(-x, total_shrink[NORMAL]);
  219.             if (b > hbadness) {
  220.                 print_ln();
  221.                 print_nl("Tight \\hbox (badness ");
  222.                 print_int(b);
  223.                 goto common_end;
  224.             }
  225.         }
  226.         return r;
  227.     }
  228.  
  229. common_end:
  230.     if (output_active) {
  231.         print(") has occurred while \\output is active");
  232.     } else {
  233.         if (pack_begin_line != 0) {
  234.             if (pack_begin_line > 0)
  235.                 print(") in paragraph at lines ");
  236.             else print(") in alignment at lines ");
  237.             print_val(abs(pack_begin_line));
  238.             print("--");
  239.         } else print(") detected at line ");
  240.         print_val(line);
  241.     }
  242.     print_ln();
  243.     font_in_short_display = null_font;
  244.     short_display(list_ptr(r));
  245.     print_ln();
  246.     begin_diagnostic();
  247.     show_box(r);
  248.     end_diagnostic(TRUE);
  249.     return r;
  250. }
  251.  
  252. ptr
  253. vpackage (p, h, m, l)
  254.     ptr     p;
  255.     scal    h;
  256.     int     m;
  257.     scal    l;
  258. {
  259.     int     b;
  260.     scal    d;
  261.     ptr     g;
  262.     gord    o;
  263.     ptr     r;
  264.     scal    s;
  265.     scal    w;
  266.     scal    x;
  267.  
  268.     r = get_node(BOX_NODE_SIZE);
  269.     type(r) = VLIST_NODE;
  270.     subtype(r) = MIN_QUARTERWORD;
  271.     shift_amount(r) = 0;
  272.     list_ptr(r) = p;
  273.     w = 0;
  274.     clr_dimens();
  275.     while (p != NULL) {
  276.         if (is_char_node(p))
  277.             confusion("vpack");
  278.         switch (type(p))
  279.         {
  280.         case HLIST_NODE:
  281.         case VLIST_NODE:
  282.         case RULE_NODE:
  283.         case UNSET_NODE:
  284.             x += d + height(p);
  285.             d = depth(p);
  286.             if (type(p) >= RULE_NODE)
  287.                 s = 0;
  288.             else s = shift_amount(p);
  289.             if (width(p) + s > w)
  290.                 w = width(p) + s;
  291.             break;
  292.         
  293.         case WHATSIT_NODE:
  294.             break;
  295.         
  296.         case GLUE_NODE:
  297.             x += d;
  298.             d = 0;
  299.             g = glue_ptr(p);
  300.             x += width(g);
  301.             o = stretch_order(g);
  302.             total_stretch[o] += stretch(g);
  303.             o = shrink_order(g);
  304.             total_shrink[o] += shrink(g);
  305.             if (subtype(p) >= A_LEADERS) {
  306.                 g = leader_ptr(p);
  307.                 if (width(g) > w)
  308.                     w = width(g);
  309.             }
  310.             break;
  311.         
  312.         case KERN_NODE:
  313.             x += d + width(p);
  314.             d = 0;
  315.             break;
  316.  
  317.         default:
  318.             break;
  319.         }
  320.         p = link(p);
  321.     }
  322.     width(r) = w;
  323.     if (d > l) {
  324.         x += d - l;
  325.         depth(r) = l;
  326.     } else {
  327.         depth(r) = d;
  328.     }
  329.     if (m == ADDITIONAL)
  330.         h += x;
  331.     height(r) = h;
  332.     x = h - x;
  333.     if (x == 0) {
  334.         glue_sign(r) = NORMAL;
  335.         glue_order(r) = NORMAL;
  336.         glue_set(r) = 0.0;
  337.         return r;
  338.     } else if (x > 0) {
  339.         get_stretch_order();
  340.         glue_order(r) = o;
  341.         glue_sign(r) = STRETCHING;
  342.         if (total_stretch[o] != 0) {
  343.             glue_set(r) = (float) x / total_stretch[o];
  344.         } else {
  345.             glue_sign(r) = NORMAL;
  346.             glue_set(r) = 0.0;
  347.         }
  348.         if (vbadness < INF_BAD && o == NORMAL && list_ptr(r) != NULL) {
  349.             b = badness(x, total_stretch[NORMAL]);
  350.             if (b > vbadness) {
  351.                 print_ln();
  352.                 if (b > 100)
  353.                     print_nl("Underfull");
  354.                 else print_nl("Loose");
  355.                 print(" \\vbox (badness ");
  356.                 print_int(b);
  357.                 goto common_end;
  358.             }
  359.         }
  360.         return r;
  361.     } else {
  362.         get_shrink_order();
  363.         glue_order(r) = o;
  364.         glue_sign(r) = SHRINKING;
  365.         if (total_shrink[o] != 0) {
  366.             glue_set(r) = (float) -x / total_shrink[o];
  367.         } else {
  368.             glue_sign(r) = NORMAL;
  369.             glue_set(r) = 0.0;
  370.         }
  371.         if (total_shrink[o] < -x && o == NORMAL && list_ptr(r) != NULL) {
  372.             glue_set(r) = 1.0;
  373.             if (-x - total_shrink[NORMAL] > vfuzz || vbadness < 100) {
  374.                 print_ln();
  375.                 print_nl("Overfull \\vbox (");
  376.                 print_scaled(-x - total_shrink[NORMAL]);
  377.                 print("pt too high");
  378.                 goto common_end;
  379.             }
  380.         } else if (vbadness < 100 && o == NORMAL && list_ptr(r) != NULL) {
  381.             b = badness(-x, total_shrink[NORMAL]);
  382.             if (b > vbadness) {
  383.                 print_ln();
  384.                 print_nl("Tight \\vbox (badness ");
  385.                 print_int(b);
  386.                 goto common_end;
  387.             }
  388.         }
  389.         return r;
  390.     }
  391.  
  392. common_end:
  393.     if (output_active) {
  394.         print(") has occurred while \\output is active");
  395.     } else {
  396.         if (pack_begin_line != 0) {
  397.             print(") in alignment at lines ");
  398.             print_val(abs(pack_begin_line));
  399.             print("--");
  400.         } else print(") detected at line ");
  401.         print_val(line);
  402.         print_ln();
  403.     }
  404.     begin_diagnostic();
  405.     show_box(r);
  406.     end_diagnostic(TRUE);
  407.     return r;
  408. }
  409.