home *** CD-ROM | disk | FTP | other *** search
/ Aminet 10 / aminetcdnumber101996.iso / Aminet / util / gnu / groff_src.lha / groff-1.10src / eqn / over.cc < prev    next >
C/C++ Source or Header  |  1995-06-22  |  5KB  |  197 lines

  1. // -*- C++ -*-
  2. /* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
  3.      Written by James Clark (jjc@jclark.com)
  4.  
  5. This file is part of groff.
  6.  
  7. groff is free software; you can redistribute it and/or modify it under
  8. the terms of the GNU General Public License as published by the Free
  9. Software Foundation; either version 2, or (at your option) any later
  10. version.
  11.  
  12. groff is distributed in the hope that it will be useful, but WITHOUT ANY
  13. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15. for more details.
  16.  
  17. You should have received a copy of the GNU General Public License along
  18. with groff; see the file COPYING.  If not, write to the Free Software
  19. Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  20.  
  21. #include "eqn.h"
  22. #include "pbox.h"
  23.  
  24. class over_box : public box {
  25. private:
  26.   int reduce_size;
  27.   box *num;
  28.   box *den;
  29. public:
  30.   over_box(int small, box *, box *);
  31.   ~over_box();
  32.   void debug_print();
  33.   int compute_metrics(int);
  34.   void output();
  35.   void check_tabs(int);
  36. };
  37.  
  38. box *make_over_box(box *pp, box *qq)
  39. {
  40.   return new over_box(0, pp, qq);
  41. }
  42.  
  43. box *make_small_over_box(box *pp, box *qq)
  44. {
  45.   return new over_box(1, pp, qq);
  46. }
  47.  
  48. over_box::over_box(int is_small, box *pp, box *qq)
  49. : num(pp), den(qq), reduce_size(is_small)
  50. {
  51.   spacing_type = INNER_TYPE;
  52. }
  53.  
  54. over_box::~over_box()
  55. {
  56.   delete num;
  57.   delete den;
  58. }
  59.  
  60. int over_box::compute_metrics(int style)
  61. {
  62.   if (reduce_size) {
  63.     style = script_style(style);
  64.     printf(".nr " SIZE_FORMAT " \\n[.s]\n", uid);
  65.     set_script_size();
  66.     printf(".nr " SMALL_SIZE_FORMAT " \\n[.s]\n", uid);
  67.   }
  68.   int mark_uid;
  69.   int res = num->compute_metrics(style);
  70.   if (res)
  71.     mark_uid = num->uid;
  72.   int r = den->compute_metrics(cramped_style(style));
  73.   if (r && res)
  74.     error("multiple marks and lineups");
  75.   else {
  76.     mark_uid = den->uid;
  77.     res = r;
  78.   }
  79.   if (reduce_size)
  80.     printf(".ps \\n[" SIZE_FORMAT "]\n", uid);
  81.   printf(".nr " WIDTH_FORMAT " (\\n[" WIDTH_FORMAT "]>?\\n[" WIDTH_FORMAT "]", 
  82.      uid, num->uid, den->uid);
  83.   // allow for \(ru being wider than both the numerator and denominator
  84.   if (!draw_flag)
  85.     fputs(">?\\w" DELIMITER_CHAR "\\(ru" DELIMITER_CHAR, stdout);
  86.   printf(")+%dM\n", null_delimiter_space*2 + over_hang*2);
  87.   // 15b
  88.   printf(".nr " SUP_RAISE_FORMAT " %dM\n",
  89.      uid, (reduce_size ? num2 : num1));
  90.   printf(".nr " SUB_LOWER_FORMAT " %dM\n",
  91.      uid, (reduce_size ? denom2 : denom1));
  92.  
  93.   // 15d
  94.   printf(".nr " SUP_RAISE_FORMAT " +(\\n[" DEPTH_FORMAT
  95.      "]-\\n[" SUP_RAISE_FORMAT "]+%dM+(%dM/2)+%dM)>?0\n",
  96.      uid, num->uid, uid, axis_height, default_rule_thickness,
  97.      default_rule_thickness*(reduce_size ? 1 : 3));
  98.   printf(".nr " SUB_LOWER_FORMAT " +(\\n[" HEIGHT_FORMAT
  99.      "]-\\n[" SUB_LOWER_FORMAT "]-%dM+(%dM/2)+%dM)>?0\n",
  100.      uid, den->uid, uid, axis_height, default_rule_thickness,
  101.      default_rule_thickness*(reduce_size ? 1 : 3));
  102.  
  103.  
  104.   printf(".nr " HEIGHT_FORMAT " \\n[" SUP_RAISE_FORMAT "]+\\n["
  105.      HEIGHT_FORMAT "]\n",
  106.      uid, uid, num->uid);
  107.   printf(".nr " DEPTH_FORMAT " \\n[" SUB_LOWER_FORMAT "]+\\n["
  108.      DEPTH_FORMAT "]\n",
  109.      uid, uid, den->uid);
  110.   if (res)
  111.     printf(".nr " MARK_REG " +(\\n[" WIDTH_FORMAT "]-\\n["
  112.        WIDTH_FORMAT "]/2)\n", uid, mark_uid);
  113.   return res;
  114. }
  115.  
  116. #define USE_Z
  117.  
  118. void over_box::output()
  119. {
  120.   if (reduce_size)
  121.     printf("\\s[\\n[" SMALL_SIZE_FORMAT "]]", uid);
  122. #ifdef USE_Z
  123.   printf("\\Z" DELIMITER_CHAR);
  124. #endif
  125.   // move up to the numerator baseline
  126.   printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
  127.   // move across so that it's centered
  128.   printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
  129.      uid, num->uid);
  130.  
  131.   // print the numerator
  132.   num->output();
  133.  
  134. #ifdef USE_Z
  135.   printf(DELIMITER_CHAR);
  136. #else
  137.   // back again
  138.   printf("\\h'-\\n[" WIDTH_FORMAT "]u'", num->uid);
  139.   printf("\\h'-(\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u)'",
  140.      uid, num->uid);
  141.   // down again
  142.   printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
  143. #endif
  144. #ifdef USE_Z
  145.   printf("\\Z" DELIMITER_CHAR);
  146. #endif
  147.   // move down to the denominator baseline
  148.   printf("\\v'\\n[" SUB_LOWER_FORMAT "]u'", uid);
  149.  
  150.   // move across so that it's centered
  151.   printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
  152.      uid, den->uid);
  153.  
  154.   // print the the denominator
  155.   den->output();
  156.  
  157. #ifdef USE_Z
  158.   printf(DELIMITER_CHAR);
  159. #else
  160.   // back again
  161.   printf("\\h'-\\n[" WIDTH_FORMAT "]u'", den->uid);
  162.   printf("\\h'-(\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u)'",
  163.      uid, den->uid);
  164.   // up again
  165.   printf("\\v'-\\n[" SUB_LOWER_FORMAT "]u'", uid);
  166. #endif
  167.   if (reduce_size)
  168.     printf("\\s[\\n[" SIZE_FORMAT "]]", uid);
  169.   // draw the line
  170.   printf("\\h'%dM'", null_delimiter_space);
  171.   printf("\\v'-%dM'", axis_height);
  172.   fputs(draw_flag ? "\\D'l" : "\\l'", stdout);
  173.   printf("\\n[" WIDTH_FORMAT "]u-%dM",
  174.      uid, 2*null_delimiter_space);
  175.   fputs(draw_flag ? " 0'" : "\\&\\(ru'", stdout);
  176.   printf("\\v'%dM'", axis_height);
  177.   printf("\\h'%dM'", null_delimiter_space);
  178. }
  179.  
  180. void over_box::debug_print()
  181. {
  182.   fprintf(stderr, "{ ");
  183.   num->debug_print();
  184.   if (reduce_size)
  185.     fprintf(stderr, " } smallover { ");
  186.   else
  187.     fprintf(stderr, " } over { ");
  188.   den->debug_print();
  189.   fprintf(stderr, " }");
  190. }
  191.  
  192. void over_box::check_tabs(int level)
  193. {
  194.   num->check_tabs(level + 1);
  195.   den->check_tabs(level + 1);
  196. }
  197.