No empty .Rs/.Re
[netbsd-mini2440.git] / gnu / dist / groff / src / preproc / eqn / sqrt.cpp
blob6f8a74aedb52168a661a8a2c4ac337db049913e9
1 /* $NetBSD$ */
3 // -*- C++ -*-
4 /* Copyright (C) 1989, 1990, 1991, 1992, 2002, 2003
5 Free Software Foundation, Inc.
6 Written by James Clark (jjc@jclark.com)
8 This file is part of groff.
10 groff is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 2, or (at your option) any later
13 version.
15 groff is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 for more details.
20 You should have received a copy of the GNU General Public License along
21 with groff; see the file COPYING. If not, write to the Free Software
22 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
24 #include "eqn.h"
25 #include "pbox.h"
28 class sqrt_box : public pointer_box {
29 public:
30 sqrt_box(box *);
31 int compute_metrics(int style);
32 void output();
33 void debug_print();
34 void check_tabs(int);
37 box *make_sqrt_box(box *pp)
39 return new sqrt_box(pp);
42 sqrt_box::sqrt_box(box *pp) : pointer_box(pp)
46 #define SQRT_CHAR "\\[sqrt]"
47 #define RADICAL_EXTENSION_CHAR "\\[sqrtex]"
49 #define SQRT_CHAIN "\\[sqrt\\\\n[" INDEX_REG "]]"
50 #define BAR_CHAIN "\\[sqrtex\\\\n[" INDEX_REG "]]"
52 int sqrt_box::compute_metrics(int style)
54 // 11
55 int r = p->compute_metrics(cramped_style(style));
56 printf(".nr " TEMP_REG " \\n[" HEIGHT_FORMAT "]+\\n[" DEPTH_FORMAT
57 "]+%dM+(%dM/4)\n",
58 p->uid, p->uid, default_rule_thickness,
59 (style > SCRIPT_STYLE ? x_height : default_rule_thickness));
60 printf(".nr " SIZE_FORMAT " \\n[.ps]\n", uid);
61 printf(".ds " SQRT_STRING_FORMAT " " SQRT_CHAR "\n", uid);
62 printf(".ds " BAR_STRING " " RADICAL_EXTENSION_CHAR "\n");
63 printf(".nr " SQRT_WIDTH_FORMAT
64 " 0\\w" DELIMITER_CHAR SQRT_CHAR DELIMITER_CHAR "\n",
65 uid);
66 printf(".if \\n[rst]-\\n[rsb]-%dM<\\n[" TEMP_REG "] \\{",
67 default_rule_thickness);
69 printf(".nr " INDEX_REG " 0\n"
70 ".de " TEMP_MACRO "\n"
71 ".ie c" SQRT_CHAIN " \\{"
72 ".ds " SQRT_STRING_FORMAT " " SQRT_CHAIN "\n"
73 ".ie c" BAR_CHAIN " .ds " BAR_STRING " " BAR_CHAIN "\n"
74 ".el .ds " BAR_STRING " " RADICAL_EXTENSION_CHAR "\n"
75 ".nr " SQRT_WIDTH_FORMAT
76 " 0\\w" DELIMITER_CHAR SQRT_CHAIN DELIMITER_CHAR "\n"
77 ".if \\\\n[rst]-\\\\n[rsb]-%dM<\\n[" TEMP_REG "] \\{"
78 ".nr " INDEX_REG " +1\n"
79 "." TEMP_MACRO "\n"
80 ".\\}\\}\n"
81 ".el .nr " INDEX_REG " 0-1\n"
82 "..\n"
83 "." TEMP_MACRO "\n",
84 uid, uid, default_rule_thickness);
86 printf(".if \\n[" INDEX_REG "]<0 \\{");
88 // Determine the maximum point size
89 printf(".ps 1000\n");
90 printf(".nr " MAX_SIZE_REG " \\n[.ps]\n");
91 printf(".ps \\n[" SIZE_FORMAT "]u\n", uid);
92 // We define a macro that will increase the current point size
93 // until we get a radical sign that's tall enough or we reach
94 // the maximum point size.
95 printf(".de " TEMP_MACRO "\n"
96 ".nr " SQRT_WIDTH_FORMAT
97 " 0\\w" DELIMITER_CHAR "\\*[" SQRT_STRING_FORMAT "]" DELIMITER_CHAR "\n"
98 ".if \\\\n[rst]-\\\\n[rsb]-%dM<\\n[" TEMP_REG "]"
99 "&(\\\\n[.ps]<\\n[" MAX_SIZE_REG "]) \\{"
100 ".ps +1\n"
101 "." TEMP_MACRO "\n"
102 ".\\}\n"
103 "..\n"
104 "." TEMP_MACRO "\n",
105 uid, uid, default_rule_thickness);
107 printf(".\\}\\}\n");
109 printf(".nr " SMALL_SIZE_FORMAT " \\n[.ps]\n", uid);
110 // set TEMP_REG to the amount by which the radical sign is too big
111 printf(".nr " TEMP_REG " \\n[rst]-\\n[rsb]-%dM-\\n[" TEMP_REG "]\n",
112 default_rule_thickness);
113 // If TEMP_REG is negative, the bottom of the radical sign should
114 // be -TEMP_REG above the bottom of p. If it's positive, the bottom
115 // of the radical sign should be TEMP_REG/2 below the bottom of p.
116 // This calculates the amount by which the baseline of the radical
117 // should be raised.
118 printf(".nr " SUP_RAISE_FORMAT " (-\\n[" TEMP_REG "]>?(-\\n[" TEMP_REG "]/2))"
119 "-\\n[rsb]-\\n[" DEPTH_FORMAT "]\n", uid, p->uid);
120 printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]"
121 ">?(\\n[" SUP_RAISE_FORMAT "]+\\n[rst])\n",
122 uid, p->uid, uid);
123 printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]"
124 ">?(-\\n[" SUP_RAISE_FORMAT "]-\\n[rsb])\n",
125 uid, p->uid, uid);
126 // Do this last, so we don't lose height and depth information on
127 // the radical sign.
128 // Remember that the width of the bar might be greater than the width of p.
130 printf(".nr " TEMP_REG " "
131 "\\n[" WIDTH_FORMAT "]"
132 ">?\\w" DELIMITER_CHAR "\\*[" BAR_STRING "]" DELIMITER_CHAR "\n",
133 p->uid);
134 printf(".as " SQRT_STRING_FORMAT " "
135 "\\l'\\n[" TEMP_REG "]u\\&\\*[" BAR_STRING "]'\n",
136 uid);
137 printf(".nr " WIDTH_FORMAT " \\n[" TEMP_REG "]"
138 "+\\n[" SQRT_WIDTH_FORMAT "]\n",
139 uid, uid);
141 if (r)
142 printf(".nr " MARK_REG " +\\n[" SQRT_WIDTH_FORMAT "]\n", uid);
143 // the top of the bar might be higher than the top of the radical sign
144 printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]"
145 ">?(\\n[" SUP_RAISE_FORMAT "]+\\n[rst])\n",
146 uid, p->uid, uid);
147 // put a bit of extra space above the bar
148 printf(".nr " HEIGHT_FORMAT " +%dM\n", uid, default_rule_thickness);
149 printf(".ps \\n[" SIZE_FORMAT "]u\n", uid);
150 return r;
153 void sqrt_box::output()
155 printf("\\Z" DELIMITER_CHAR);
156 printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
157 printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
158 printf("\\*[" SQRT_STRING_FORMAT "]", uid);
159 printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
160 printf(DELIMITER_CHAR);
162 printf("\\Z" DELIMITER_CHAR);
163 printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u"
164 "+\\n[" SQRT_WIDTH_FORMAT "]u/2u'",
165 uid, p->uid, uid);
166 p->output();
167 printf(DELIMITER_CHAR);
169 printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
172 void sqrt_box::debug_print()
174 fprintf(stderr, "sqrt { ");
175 p->debug_print();
176 fprintf(stderr, " }");
179 void sqrt_box::check_tabs(int level)
181 p->check_tabs(level + 1);