home *** CD-ROM | disk | FTP | other *** search
/ Mega Top 1 / os2_top1.zip / os2_top1 / APPS / TEKST / CMTEX330 / SOURCE / PACK.C < prev    next >
C/C++ Source or Header  |  1992-02-19  |  8KB  |  447 lines

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