home *** CD-ROM | disk | FTP | other *** search
/ Aminet 10 / aminetcdnumber101996.iso / Aminet / util / gnu / groff_src.lha / groff-1.10src / eqn / sqrt.cc < prev    next >
C/C++ Source or Header  |  1995-06-22  |  6KB  |  180 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.  
  25. class sqrt_box : public pointer_box {
  26. public:
  27.   sqrt_box(box *);
  28.   int compute_metrics(int style);
  29.   void output();
  30.   void debug_print();
  31.   void check_tabs(int);
  32. };
  33.  
  34. box *make_sqrt_box(box *pp)
  35. {
  36.   return new sqrt_box(pp);
  37. }
  38.  
  39. sqrt_box::sqrt_box(box *pp) : pointer_box(pp)
  40. {
  41. }
  42.  
  43. #define SQRT_CHAR "\\(sr"
  44. #define RADICAL_EXTENSION_CHAR "\\[radicalex]"
  45.  
  46. #define SQRT_CHAIN "\\[sr\\\\n[" INDEX_REG "]]"
  47. #define BAR_CHAIN "\\[radicalex\\\\n[" INDEX_REG "]]"
  48.  
  49. int sqrt_box::compute_metrics(int style)
  50. {
  51.   // 11
  52.   int r = p->compute_metrics(cramped_style(style));
  53.   printf(".nr " TEMP_REG " \\n[" HEIGHT_FORMAT "]+\\n[" DEPTH_FORMAT
  54.      "]+%dM+(%dM/4)\n",
  55.      p->uid, p->uid, default_rule_thickness,
  56.      (style > SCRIPT_STYLE ? x_height : default_rule_thickness));
  57.   printf(".nr " SIZE_FORMAT " \\n[.s]\n", uid);
  58.   printf(".ds " SQRT_STRING_FORMAT " " SQRT_CHAR "\n", uid);
  59.   printf(".ds " BAR_STRING " " RADICAL_EXTENSION_CHAR "\n");
  60.   printf(".nr " SQRT_WIDTH_FORMAT
  61.      " 0\\w" DELIMITER_CHAR SQRT_CHAR DELIMITER_CHAR "\n",
  62.      uid);
  63.   printf(".if \\n[rst]-\\n[rsb]-%dM<\\n[" TEMP_REG "] \\{",
  64.      default_rule_thickness);
  65.  
  66.   printf(".nr " INDEX_REG " 0\n"
  67.      ".de " TEMP_MACRO "\n"
  68.      ".ie c" SQRT_CHAIN " \\{"
  69.      ".ds " SQRT_STRING_FORMAT " " SQRT_CHAIN "\n"
  70.      ".ie c" BAR_CHAIN " .ds " BAR_STRING " " BAR_CHAIN "\n"
  71.      ".el .ds " BAR_STRING " " RADICAL_EXTENSION_CHAR "\n"
  72.      ".nr " SQRT_WIDTH_FORMAT
  73.      " 0\\w" DELIMITER_CHAR SQRT_CHAIN DELIMITER_CHAR "\n"
  74.      ".if \\\\n[rst]-\\\\n[rsb]-%dM<\\n[" TEMP_REG "] \\{"
  75.      ".nr " INDEX_REG " +1\n"
  76.      "." TEMP_MACRO "\n"
  77.      ".\\}\\}\n"
  78.      ".el .nr " INDEX_REG " 0-1\n"
  79.      "..\n"
  80.      "." TEMP_MACRO "\n",
  81.      uid, uid, default_rule_thickness);
  82.  
  83.   printf(".if \\n[" INDEX_REG "]<0 \\{");
  84.  
  85.   // Determine the maximum point size
  86.   printf(".ps 1000\n");
  87.   printf(".nr " MAX_SIZE_REG " \\n[.s]\n");
  88.   printf(".ps \\n[" SIZE_FORMAT "]\n", uid);
  89.   // We define a macro that will increase the current point size
  90.   // until we get a radical sign that's tall enough or we reach
  91.   // the maximum point size.
  92.   printf(".de " TEMP_MACRO "\n"
  93.      ".nr " SQRT_WIDTH_FORMAT
  94.      " 0\\w" DELIMITER_CHAR "\\*[" SQRT_STRING_FORMAT "]" DELIMITER_CHAR "\n"
  95.      ".if \\\\n[rst]-\\\\n[rsb]-%dM<\\n[" TEMP_REG "]"
  96.      "&(\\\\n[.s]<\\n[" MAX_SIZE_REG "]) \\{"
  97.      ".ps +1\n"
  98.      "." TEMP_MACRO "\n"
  99.      ".\\}\n"
  100.      "..\n"
  101.      "." TEMP_MACRO "\n",
  102.      uid, uid, default_rule_thickness);
  103.   
  104.   printf(".\\}\\}\n");
  105.  
  106.   printf(".nr " SMALL_SIZE_FORMAT " \\n[.s]\n", uid);
  107.   // set TEMP_REG to the amount by which the radical sign is too big
  108.   printf(".nr " TEMP_REG " \\n[rst]-\\n[rsb]-%dM-\\n[" TEMP_REG "]\n",
  109.      default_rule_thickness);
  110.   // If TEMP_REG is negative, the bottom of the radical sign should
  111.   // be -TEMP_REG above the bottom of p. If it's positive, the bottom
  112.   // of the radical sign should be TEMP_REG/2 below the bottom of p.
  113.   // This calculates the amount by which the baseline of the radical
  114.   // should be raised.
  115.   printf(".nr " SUP_RAISE_FORMAT " (-\\n[" TEMP_REG "]>?(-\\n[" TEMP_REG "]/2))"
  116.      "-\\n[rsb]-\\n[" DEPTH_FORMAT "]\n", uid, p->uid);
  117.   printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]"
  118.      ">?(\\n[" SUP_RAISE_FORMAT "]+\\n[rst])\n",
  119.      uid, p->uid, uid);
  120.   printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]"
  121.      ">?(-\\n[" SUP_RAISE_FORMAT "]-\\n[rsb])\n",
  122.      uid, p->uid, uid);
  123.   // Do this last, so we don't lose height and depth information on
  124.   // the radical sign.
  125.   // Remember that the width of the bar might be greater than the width of p.
  126.  
  127.   printf(".nr " TEMP_REG " "
  128.      "\\n[" WIDTH_FORMAT "]"
  129.      ">?\\w" DELIMITER_CHAR "\\*[" BAR_STRING "]" DELIMITER_CHAR "\n",
  130.      p->uid);
  131.   printf(".as " SQRT_STRING_FORMAT " "
  132.      "\\l'\\n[" TEMP_REG "]u\\&\\*[" BAR_STRING "]'\n",
  133.      uid);
  134.   printf(".nr " WIDTH_FORMAT " \\n[" TEMP_REG "]"
  135.      "+\\n[" SQRT_WIDTH_FORMAT "]\n",
  136.      uid, uid);
  137.  
  138.   if (r)
  139.     printf(".nr " MARK_REG " +\\n[" SQRT_WIDTH_FORMAT "]\n", uid);
  140.   // the top of the bar might be higher than the top of the radical sign
  141.   printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]"
  142.      ">?(\\n[" SUP_RAISE_FORMAT "]+\\n[rst])\n",
  143.      uid, p->uid, uid);
  144.   // put a bit of extra space above the bar
  145.   printf(".nr " HEIGHT_FORMAT " +%dM\n", uid, default_rule_thickness);
  146.   printf(".ps \\n[" SIZE_FORMAT "]\n", uid);
  147.   return r;
  148. }
  149.  
  150. void sqrt_box::output()
  151. {
  152.   printf("\\Z" DELIMITER_CHAR);
  153.   printf("\\s[\\n[" SMALL_SIZE_FORMAT "]]", uid);
  154.   printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
  155.   printf("\\*[" SQRT_STRING_FORMAT "]", uid);
  156.   printf("\\s[\\n[" SIZE_FORMAT "]]", uid);
  157.   printf(DELIMITER_CHAR);
  158.  
  159.   printf("\\Z" DELIMITER_CHAR);
  160.   printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u"
  161.      "+\\n[" SQRT_WIDTH_FORMAT "]u/2u'",
  162.      uid, p->uid, uid);
  163.   p->output();
  164.   printf(DELIMITER_CHAR);
  165.  
  166.   printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
  167. }
  168.  
  169. void sqrt_box::debug_print()
  170. {
  171.   fprintf(stderr, "sqrt { ");
  172.   p->debug_print();
  173.   fprintf(stderr, " }");
  174. }
  175.  
  176. void sqrt_box::check_tabs(int level)
  177. {
  178.   p->check_tabs(level + 1);
  179. }
  180.