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

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