2 /* Copyright (C) 1989-2014 Free Software Foundation, Inc.
3 Written by James Clark (jjc@jclark.com)
5 This file is part of groff.
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 3 of the License, or
10 (at your option) any later version.
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
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24 class sqrt_box : public pointer_box {
27 int compute_metrics(int style);
33 box *make_sqrt_box(box *pp)
35 return new sqrt_box(pp);
38 sqrt_box::sqrt_box(box *pp) : pointer_box(pp)
42 #define SQRT_CHAR "\\[sqrt]"
43 #define RADICAL_EXTENSION_CHAR "\\[sqrtex]"
45 #define SQRT_CHAIN "\\[sqrt\\\\n[" INDEX_REG "]]"
46 #define BAR_CHAIN "\\[sqrtex\\\\n[" INDEX_REG "]]"
48 int sqrt_box::compute_metrics(int style)
51 int r = p->compute_metrics(cramped_style(style));
52 printf(".nr " TEMP_REG " \\n[" HEIGHT_FORMAT "]+\\n[" DEPTH_FORMAT
54 p->uid, p->uid, default_rule_thickness,
55 (style > SCRIPT_STYLE ? x_height : default_rule_thickness));
56 printf(".nr " SIZE_FORMAT " \\n[.ps]\n", uid);
57 printf(".ds " SQRT_STRING_FORMAT " " SQRT_CHAR "\n", uid);
58 printf(".ds " BAR_STRING " " RADICAL_EXTENSION_CHAR "\n");
59 printf(".nr " SQRT_WIDTH_FORMAT
60 " 0\\w" DELIMITER_CHAR SQRT_CHAR DELIMITER_CHAR "\n",
62 printf(".if \\n[rst]-\\n[rsb]-%dM<\\n[" TEMP_REG "] \\{",
63 default_rule_thickness);
65 printf(".nr " INDEX_REG " 0\n"
66 ".de " TEMP_MACRO "\n"
67 ".ie c" SQRT_CHAIN " \\{"
68 ".ds " SQRT_STRING_FORMAT " " SQRT_CHAIN "\n"
69 ".ie c" BAR_CHAIN " .ds " BAR_STRING " " BAR_CHAIN "\n"
70 ".el .ds " BAR_STRING " " RADICAL_EXTENSION_CHAR "\n"
71 ".nr " SQRT_WIDTH_FORMAT
72 " 0\\w" DELIMITER_CHAR SQRT_CHAIN DELIMITER_CHAR "\n"
73 ".if \\\\n[rst]-\\\\n[rsb]-%dM<\\n[" TEMP_REG "] \\{"
74 ".nr " INDEX_REG " +1\n"
77 ".el .nr " INDEX_REG " 0-1\n"
80 uid, uid, default_rule_thickness);
82 printf(".if \\n[" INDEX_REG "]<0 \\{");
84 // Determine the maximum point size
86 printf(".nr " MAX_SIZE_REG " \\n[.ps]\n");
87 printf(".ps \\n[" SIZE_FORMAT "]u\n", uid);
88 // We define a macro that will increase the current point size
89 // until we get a radical sign that's tall enough or we reach
90 // the maximum point size.
91 printf(".de " TEMP_MACRO "\n"
92 ".nr " SQRT_WIDTH_FORMAT
93 " 0\\w" DELIMITER_CHAR "\\*[" SQRT_STRING_FORMAT "]" DELIMITER_CHAR "\n"
95 "&(\\\\n[rst]-\\\\n[rsb]-%dM<\\n[" TEMP_REG "])"
96 "&(\\\\n[.ps]<\\n[" MAX_SIZE_REG "]) \\{"
102 uid, uid, default_rule_thickness);
106 printf(".nr " SMALL_SIZE_FORMAT " \\n[.ps]\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
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",
120 printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]"
121 ">?(-\\n[" SUP_RAISE_FORMAT "]-\\n[rsb])\n",
123 // Do this last, so we don't lose height and depth information on
125 // Remember that the width of the bar might be greater than the width of p.
127 printf(".nr " TEMP_REG " "
128 "\\n[" WIDTH_FORMAT "]"
129 ">?\\w" DELIMITER_CHAR "\\*[" BAR_STRING "]" DELIMITER_CHAR "\n",
131 printf(".as " SQRT_STRING_FORMAT " "
132 "\\l'\\n[" TEMP_REG "]u\\&\\*[" BAR_STRING "]'\n",
134 printf(".nr " WIDTH_FORMAT " \\n[" TEMP_REG "]"
135 "+\\n[" SQRT_WIDTH_FORMAT "]\n",
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",
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 "]u\n", uid);
150 void sqrt_box::output()
152 if (output_format == troff) {
153 printf("\\Z" DELIMITER_CHAR);
154 printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
155 printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
156 printf("\\*[" SQRT_STRING_FORMAT "]", uid);
157 printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
158 printf(DELIMITER_CHAR);
160 printf("\\Z" DELIMITER_CHAR);
161 printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u"
162 "+\\n[" SQRT_WIDTH_FORMAT "]u/2u'",
165 printf(DELIMITER_CHAR);
167 printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
169 else if (output_format == mathml) {
176 void sqrt_box::debug_print()
178 fprintf(stderr, "sqrt { ");
180 fprintf(stderr, " }");
183 void sqrt_box::check_tabs(int level)
185 p->check_tabs(level + 1);