home *** CD-ROM | disk | FTP | other *** search
/ Mega Top 1 / os2_top1.zip / os2_top1 / APPS / TEKST / CMTEX330 / SOURCE / MATH.C < prev    next >
C/C++ Source or Header  |  1992-02-19  |  10KB  |  601 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
  20. new_style (s)
  21.     int    s;
  22. {
  23.     ptr    p;
  24.  
  25.     p = new_node(STYLE_NODE_SIZE);
  26.     type(p) = STYLE_NODE;
  27.     subtype(p) = s;
  28.     display_mlist(p) = null;
  29.     text_mlist(p) = null;
  30.     script_mlist(p) = null;
  31.     script_script_mlist(p) = null;
  32.  
  33.     return p;
  34. }
  35.  
  36. ptr
  37. new_choice ()
  38. {
  39.     ptr    p;
  40.  
  41.     p = new_node(STYLE_NODE_SIZE);
  42.     type(p) = CHOICE_NODE;
  43.     subtype(p) = 0;
  44.     display_mlist(p) = null;
  45.     text_mlist(p) = null;
  46.     script_mlist(p) = null;
  47.     script_script_mlist(p) = null;
  48.  
  49.     return p;
  50. }
  51.  
  52. ptr
  53. new_noad ()
  54. {
  55.     ptr    p;
  56.  
  57.     p = new_node(NOAD_SIZE);
  58.     type(p) = ORD_NOAD;
  59.     subtype(p) = NORMAL;
  60.     mzero(nucleus(p));
  61.     mzero(subscr(p));
  62.     mzero(supscr(p));
  63.  
  64.     return p;
  65. }
  66.  
  67. void
  68. print_fam_and_char (p)
  69.     ptr     p;
  70. {
  71.     print_esc("fam");
  72.     print_int(fam(p));
  73.     print(" ");
  74.     print_ASCII(character(p));
  75. }
  76.  
  77. void
  78. print_delimiter (p)
  79.     ptr    p;
  80. {
  81.     int    a;
  82.  
  83.     a = small_fam(p) * 256 + small_char(p);
  84.     a = a * 0x1000 + large_fam(p) * 256 + large_char(p);
  85.     if (a < 0) {
  86.         print_int(a);
  87.     } else {
  88.         print_hex(a);
  89.     }
  90. }
  91.  
  92. void
  93. print_subsidiary_data (p, c)
  94.     ptr    p;
  95.     int    c;
  96. {
  97.     if (cur_length() >= depth_threshold) {
  98.         if (math_type(p) != EMPTY) {
  99.             print(" []");
  100.         }
  101.         return;
  102.     }
  103.     append_char(c);
  104.     switch (math_type(p))
  105.     {
  106.     case MATH_CHAR:
  107.         print_ln();
  108.         print_str();
  109.         print_fam_and_char(p);
  110.         break;
  111.     
  112.     case SUB_BOX:
  113.         show_node_list(math_link(p));
  114.         break;
  115.     
  116.     case SUB_MLIST:
  117.         if (math_link(p) == null) {
  118.             print_ln();
  119.             print_str();
  120.             print("{}");
  121.         } else {
  122.             show_node_list(math_link(p));
  123.         }
  124.         break;
  125.     }
  126.     flush_char();
  127. }
  128.  
  129. void
  130. print_style (c)
  131.     int    c;
  132. {
  133.     switch (c / 2) {
  134.     case 0: print_esc("displaystyle"); break;
  135.     case 1: print_esc("textstyle"); break;
  136.     case 2: print_esc("scriptstyle"); break;
  137.     case 3: print_esc("scriptscriptstyle"); break;
  138.     default: print("Unknown style!"); break;
  139.     }
  140. }
  141.  
  142. void
  143. print_size (s)
  144.     int    s;
  145. {
  146.     if (s == TEXT_SIZE) {
  147.         print_esc("textfont");
  148.     } else if (s == SCRIPT_SIZE) {
  149.         print_esc("scriptfont");
  150.     } else {
  151.         print_esc("scriptscriptfont");
  152.     }
  153. }
  154.  
  155. void
  156. show_normal_noad (p)
  157.     ptr    p;
  158. {
  159.     switch (type(p))
  160.     {
  161.     case ORD_NOAD:
  162.         print_esc("mathord");
  163.         break;
  164.  
  165.     case OP_NOAD:
  166.         print_esc("mathop");
  167.         break;
  168.  
  169.     case BIN_NOAD:
  170.         print_esc("mathbin");
  171.         break;
  172.  
  173.     case REL_NOAD:
  174.         print_esc("mathrel");
  175.         break;
  176.  
  177.     case OPEN_NOAD:
  178.         print_esc("mathopen");
  179.         break;
  180.  
  181.     case CLOSE_NOAD:    
  182.         print_esc("mathclose");
  183.         break;
  184.  
  185.     case PUNCT_NOAD:
  186.         print_esc("mathpunct");
  187.         break;
  188.  
  189.     case INNER_NOAD:
  190.         print_esc("mathinner");
  191.         break;
  192.  
  193.     case OVER_NOAD:
  194.         print_esc("overline");
  195.         break;
  196.  
  197.     case UNDER_NOAD:
  198.         print_esc("underline");
  199.         break;
  200.  
  201.     case VCENTER_NOAD:
  202.         print_esc("vcenter");
  203.         break;
  204.  
  205.     case RADICAL_NOAD:
  206.         print_esc("radical");
  207.         print_delimiter(left_delimiter(p));
  208.         break;
  209.  
  210.     case ACCENT_NOAD:
  211.         print_esc("accent");
  212.         print_fam_and_char(accent_chr(p));
  213.         break;
  214.  
  215.     case LEFT_NOAD:
  216.         print_esc("left");
  217.         print_delimiter(nucleus(p));
  218.         break;
  219.  
  220.     case RIGHT_NOAD:
  221.         print_esc("right");
  222.         print_delimiter(nucleus(p));
  223.         break;
  224.  
  225.     }
  226.     if (subtype(p) != NORMAL) {
  227.         if (subtype(p) == LIMITS) {
  228.             print_esc("limits");
  229.         } else {
  230.             print_esc("nolimits");
  231.         }
  232.     }
  233.     if (type(p) < LEFT_NOAD) {
  234.         print_subsidiary_data(nucleus(p), '.');
  235.     }
  236.     print_subsidiary_data(supscr(p), '^');
  237.     print_subsidiary_data(subscr(p), '_');
  238. }
  239.  
  240. void
  241. show_fraction_noad (p)
  242.     ptr    p;
  243. {
  244.     print_esc("fraction, thickness ");
  245.     if (thickness(p) == DEFAULT_CODE) {
  246.         print("= default");
  247.     } else {
  248.         print_scaled(thickness(p));
  249.     }
  250.     if (small_fam(left_delimiter(p)) != 0
  251.     || small_char(left_delimiter(p)) != MIN_QUARTERWORD
  252.     || large_fam(left_delimiter(p)) != 0
  253.     || large_char(left_delimiter(p)) != MIN_QUARTERWORD) {
  254.         print(", left-delimiter ");
  255.         print_delimiter(left_delimiter(p));
  256.     }
  257.     if (small_fam(right_delimiter(p)) != 0
  258.     || small_char(right_delimiter(p)) != MIN_QUARTERWORD
  259.     || large_fam(right_delimiter(p)) != 0
  260.     || large_char(right_delimiter(p)) != MIN_QUARTERWORD) {
  261.         print(", right-delimiter ");
  262.         print_delimiter(right_delimiter(p));
  263.     }
  264.     print_subsidiary_data(numerator(p), '\\');
  265.     print_subsidiary_data(denominator(p), '/');
  266. }
  267.  
  268. void
  269. show_choice_node (p)
  270.     ptr    p;
  271. {
  272.     print_esc("mathchoice");
  273.     append_char('D');
  274.     show_node_list(display_mlist(p));
  275.     flush_char();
  276.     append_char('T');
  277.     show_node_list(text_mlist(p));
  278.     flush_char();
  279.     append_char('S');
  280.     show_node_list(script_mlist(p));
  281.     flush_char();
  282.     append_char('s');
  283.     show_node_list(script_script_mlist(p));
  284.     flush_char();
  285. }
  286.  
  287. ptr
  288. fraction_rule (t)
  289.     scal    t;
  290. {
  291.     ptr    p;
  292.  
  293.     p = new_rule();
  294.     rule_height(p) = t;
  295.     rule_depth(p) = 0;
  296.  
  297.     return p;
  298. }
  299.  
  300. ptr
  301. overbar (b, k, t)
  302.     ptr    b;
  303.     scal    k;
  304.     scal    t;
  305. {
  306.     ptr    p;
  307.     ptr    q;
  308.  
  309.     p = new_kern(k);
  310.     link(p) = b;
  311.     q = fraction_rule(t);
  312.     link(q) = p;
  313.     p = new_kern(t);
  314.     link(p) = q;
  315.     return (vpack(p, NATURAL));
  316. }
  317.  
  318. #define check_variants()                        \
  319.     y = x;                                 \
  320.     if (y >= font_bc(g) && y <= font_ec(g)) {            \
  321. contin:        q = char_info(g, y);                     \
  322.         if (char_exists(q)) {                     \
  323.             if (char_tag(q) == EXT_TAG)  {             \
  324.                 f = g;                     \
  325.                 c = y;                     \
  326.                 goto found;                 \
  327.             }                        \
  328.             hd = height_depth(q);                \
  329.             u = char_height(g, hd) + char_depth(g, hd);    \
  330.             if (u > w) {                    \
  331.                 f = g;                    \
  332.                 c = y;                    \
  333.                 w = u;                    \
  334.                 if (u >= v)                \
  335.                     goto found;            \
  336.             }                        \
  337.             if (char_tag(q) == LIST_TAG) {            \
  338.                 y = rem_byte(q);            \
  339.                 goto contin;                \
  340.             }                        \
  341.         }                            \
  342.     }                                \
  343.  
  344.  
  345. ptr
  346. var_delimiter (d, s, v)
  347.     ptr    d;
  348.     int    s;
  349.     scal    v;
  350. {
  351.     ptr    b;
  352.     fnt    f, g;
  353.     int    m, n;
  354.     qcell    q, r;
  355.     scal    u, w;
  356.     int    c, x, y, z;
  357.     int    hd;
  358.     bool    large_attempt;
  359.  
  360.     f = null_font;
  361.     w = 0;
  362.     large_attempt = FALSE;
  363.     z = small_fam(d);
  364.     x = small_char(d);
  365.     loop {
  366.         if (z != 0 || x != 0) {
  367.             z += s + 16;
  368.             do {
  369.                 z -= 16;
  370.                 g = fam_fnt(z);
  371.                 if (g != null_font) {
  372.                     check_variants();
  373.                 }
  374.             } while (z >= 16);
  375.         }
  376.         if (large_attempt) {
  377.             goto found;
  378.         }
  379.         large_attempt = TRUE;
  380.         z = large_fam(d);
  381.         x = large_char(d);
  382.     }
  383.  
  384. found:
  385.     if (f != null_font) {
  386.         if (char_tag(q) == EXT_TAG) {
  387.             b = new_null_box();
  388.             type(b) = VLIST_NODE;
  389.             r = exten_base(f)[rem_byte(q)];
  390.             c = ext_rep(r);
  391.             u = height_plus_depth(f, c);
  392.             w = 0;
  393.             q = char_info(f, c);
  394.             box_width(b) = char_width(f, q) + char_italic(f, q);
  395.             c = ext_bot(r);
  396.             if (c != MIN_QUARTERWORD) {
  397.                 w += height_plus_depth(f, c);
  398.             }
  399.             c = ext_mid(r);
  400.             if (c != MIN_QUARTERWORD) {
  401.                 w += height_plus_depth(f, c);
  402.             }
  403.             c = ext_top(r);
  404.             if (c != MIN_QUARTERWORD) {
  405.                 w += height_plus_depth(f, c);
  406.             }
  407.             n = 0;
  408.             if (u > 0) {
  409.                 while (w < v) {
  410.                     w += u;
  411.                     incr(n);
  412.                     if (ext_mid(r) != MIN_QUARTERWORD) {
  413.                         w += u;
  414.                     }
  415.                 }
  416.             }
  417.             c = ext_bot(r);
  418.             if (c != MIN_QUARTERWORD) {
  419.                 stack_into_box(b, f, c);
  420.             }
  421.             c = ext_rep(r);
  422.             for (m = 1; m <= n; incr(m)) {
  423.                 stack_into_box(b, f, c);
  424.             }
  425.             c = ext_mid(r);
  426.             if (c != MIN_QUARTERWORD) {
  427.                 stack_into_box(b, f, c);
  428.                 c = ext_rep(r);
  429.                 for (m = 1; m <= n; incr(m)) {
  430.                     stack_into_box(b, f, c);
  431.                 }
  432.             }
  433.             c = ext_top(r);
  434.             if (c != MIN_QUARTERWORD) {
  435.                 stack_into_box(b, f, c);
  436.             }
  437.             box_depth(b) = w - box_height(b);
  438.         } else {
  439.             b = char_box(f, c);
  440.         }
  441.     } else {
  442.         b = new_null_box();
  443.         box_width(b) = null_delimiter_space;
  444.     }
  445.     shift_amount(b) = half(box_height(b) - box_depth(b)) - axis_height(s);
  446.     return b;
  447. }
  448.  
  449. ptr
  450. char_box (f, c)
  451.     fnt    f;
  452.     int    c;
  453. {
  454.     ptr    b;
  455.     ptr    p;
  456.     qcell    q;
  457.     int    hd;
  458.  
  459.     q = char_info(f, c);
  460.     hd = height_depth(q);
  461.     b = new_null_box();
  462.     box_width(b) = char_width(f, q) + char_italic(f, q);
  463.     box_height(b) = char_height(f, hd);
  464.     box_depth(b) = char_depth(f, hd);
  465.     p = new_avail();
  466.     character(p) = c;
  467.     font(p) = f;
  468.     list_ptr(b) = p;
  469.  
  470.     return b;
  471. }
  472.  
  473. void
  474. stack_into_box (b, f, c)
  475.     ptr    b;
  476.     fnt    f;
  477.     int    c;
  478. {
  479.     ptr    p;
  480.  
  481.     p = char_box(f, c);
  482.     link(p) = list_ptr(b);
  483.     list_ptr(b) = p;
  484.     box_height(b) = box_height(p);
  485. }
  486.  
  487. scal
  488. height_plus_depth (f, c)
  489.     fnt    f;
  490.     int    c;
  491. {
  492.     qcell    q;
  493.     int    hd;
  494.  
  495.     q = char_info(f, c);
  496.     hd = height_depth(q);
  497.     return (char_height(f, hd) + char_depth(f, hd));
  498. }
  499.  
  500. ptr
  501. rebox (b, w)
  502.     ptr    b;
  503.     scal    w;
  504. {
  505.     fnt    f;
  506.     ptr    p;
  507.     scal    v;
  508.  
  509.     if (box_width(b) != w && list_ptr(b) != null) {
  510.         if (type(b) == VLIST_NODE) {
  511.             b = hpack(b, NATURAL);
  512.         }
  513.         p = list_ptr(b);
  514.         if (is_char_node(p) && link(p) == null) {
  515.             f = font(p);
  516.             v = char_width(f, char_info(f, character(p)));
  517.             if (v != box_width(b)) {
  518.                 link(p) = new_kern(box_width(b) - v);
  519.             }
  520.         }
  521.         free_node(b, BOX_NODE_SIZE);
  522.         b = new_glue(ss_glue);
  523.         link(b) = p;
  524.         while (link(p) != null) {
  525.             p = link(p);
  526.         }
  527.         link(p) = new_glue(ss_glue);
  528.         return (hpack(b, w, EXACTLY));
  529.     } else {
  530.         box_width(b) = w;
  531.         return b;
  532.     }
  533. }
  534.  
  535. #define mu_mult(x) \
  536.     nx_plus_y(n, x, xn_over_d(x, f, 0200000))
  537.  
  538. ptr
  539. math_glue (g, m)
  540.     ptr    g;
  541.     scal    m;
  542. {
  543.     scal    f;
  544.     int    n;
  545.     ptr    p;
  546.  
  547.     n = x_over_n(m, 0200000);
  548.     f = remainder;
  549.     p = new_node(GLUE_SPEC_SIZE);
  550.     glue_width(p) = mu_mult(glue_width(g));
  551.     stretch_order(p) = stretch_order(g);
  552.     if (stretch_order(p) == NORMAL) {
  553.         stretch(p) = mu_mult(stretch(g));
  554.     } else {
  555.         stretch(p) = stretch(g);
  556.     }
  557.     shrink_order(p) = shrink_order(g);
  558.     if (shrink_order(p) == NORMAL) {
  559.         shrink(p) = mu_mult(shrink(g));
  560.     } else {
  561.         shrink(p) = shrink(g);
  562.     }
  563.     return p;
  564. }
  565.  
  566. void
  567. math_kern (p, m)
  568.     ptr    p;
  569.     scal    m;
  570. {
  571.     scal    f;
  572.     int    n;
  573.  
  574.     if (subtype(p) == MU_GLUE) {
  575.         n = x_over_n(m, 0200000);
  576.         f = remainder;
  577.         kern_width(p) = mu_mult(kern_width(p));
  578.         subtype(p) = NORMAL;
  579.     }
  580. }
  581.  
  582. void
  583. flush_math ()
  584. {
  585.     flush_node_list(link(head));
  586.     flush_node_list(incompleat_noad);
  587.     link(head) = null;
  588.     tail = head;
  589.     incompleat_noad = null;
  590. }
  591.  
  592. void
  593. _math_init ()
  594. {
  595. }
  596.  
  597. void
  598. _math_init_once ()
  599. {
  600. }
  601.