2 /* Copyright (C) 1989, 1990, 1991, 1992, 2002, 2003, 2007, 2008
3 Free Software Foundation, Inc.
4 Written by James Clark (jjc@jclark.com)
6 This file is part of groff.
8 groff is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 groff is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License along
19 with groff; see the file COPYING. If not, write to the Free Software
20 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
26 class sqrt_box
: public pointer_box
{
29 int compute_metrics(int style
);
35 box
*make_sqrt_box(box
*pp
)
37 return new sqrt_box(pp
);
40 sqrt_box::sqrt_box(box
*pp
) : pointer_box(pp
)
44 #define SQRT_CHAR "\\[sqrt]"
45 #define RADICAL_EXTENSION_CHAR "\\[sqrtex]"
47 #define SQRT_CHAIN "\\[sqrt\\\\n[" INDEX_REG "]]"
48 #define BAR_CHAIN "\\[sqrtex\\\\n[" INDEX_REG "]]"
50 int sqrt_box::compute_metrics(int style
)
53 int r
= p
->compute_metrics(cramped_style(style
));
54 printf(".nr " TEMP_REG
" \\n[" HEIGHT_FORMAT
"]+\\n[" DEPTH_FORMAT
56 p
->uid
, p
->uid
, default_rule_thickness
,
57 (style
> SCRIPT_STYLE
? x_height
: default_rule_thickness
));
58 printf(".nr " SIZE_FORMAT
" \\n[.ps]\n", uid
);
59 printf(".ds " SQRT_STRING_FORMAT
" " SQRT_CHAR
"\n", uid
);
60 printf(".ds " BAR_STRING
" " RADICAL_EXTENSION_CHAR
"\n");
61 printf(".nr " SQRT_WIDTH_FORMAT
62 " 0\\w" DELIMITER_CHAR SQRT_CHAR DELIMITER_CHAR
"\n",
64 printf(".if \\n[rst]-\\n[rsb]-%dM<\\n[" TEMP_REG
"] \\{",
65 default_rule_thickness
);
67 printf(".nr " INDEX_REG
" 0\n"
68 ".de " TEMP_MACRO
"\n"
69 ".ie c" SQRT_CHAIN
" \\{"
70 ".ds " SQRT_STRING_FORMAT
" " SQRT_CHAIN
"\n"
71 ".ie c" BAR_CHAIN
" .ds " BAR_STRING
" " BAR_CHAIN
"\n"
72 ".el .ds " BAR_STRING
" " RADICAL_EXTENSION_CHAR
"\n"
73 ".nr " SQRT_WIDTH_FORMAT
74 " 0\\w" DELIMITER_CHAR SQRT_CHAIN DELIMITER_CHAR
"\n"
75 ".if \\\\n[rst]-\\\\n[rsb]-%dM<\\n[" TEMP_REG
"] \\{"
76 ".nr " INDEX_REG
" +1\n"
79 ".el .nr " INDEX_REG
" 0-1\n"
82 uid
, uid
, default_rule_thickness
);
84 printf(".if \\n[" INDEX_REG
"]<0 \\{");
86 // Determine the maximum point size
88 printf(".nr " MAX_SIZE_REG
" \\n[.ps]\n");
89 printf(".ps \\n[" SIZE_FORMAT
"]u\n", uid
);
90 // We define a macro that will increase the current point size
91 // until we get a radical sign that's tall enough or we reach
92 // the maximum point size.
93 printf(".de " TEMP_MACRO
"\n"
94 ".nr " SQRT_WIDTH_FORMAT
95 " 0\\w" DELIMITER_CHAR
"\\*[" SQRT_STRING_FORMAT
"]" DELIMITER_CHAR
"\n"
97 "&(\\\\n[rst]-\\\\n[rsb]-%dM<\\n[" TEMP_REG
"])"
98 "&(\\\\n[.ps]<\\n[" MAX_SIZE_REG
"]) \\{"
104 uid
, uid
, default_rule_thickness
);
108 printf(".nr " SMALL_SIZE_FORMAT
" \\n[.ps]\n", uid
);
109 // set TEMP_REG to the amount by which the radical sign is too big
110 printf(".nr " TEMP_REG
" \\n[rst]-\\n[rsb]-%dM-\\n[" TEMP_REG
"]\n",
111 default_rule_thickness
);
112 // If TEMP_REG is negative, the bottom of the radical sign should
113 // be -TEMP_REG above the bottom of p. If it's positive, the bottom
114 // of the radical sign should be TEMP_REG/2 below the bottom of p.
115 // This calculates the amount by which the baseline of the radical
117 printf(".nr " SUP_RAISE_FORMAT
" (-\\n[" TEMP_REG
"]>?(-\\n[" TEMP_REG
"]/2))"
118 "-\\n[rsb]-\\n[" DEPTH_FORMAT
"]\n", uid
, p
->uid
);
119 printf(".nr " HEIGHT_FORMAT
" \\n[" HEIGHT_FORMAT
"]"
120 ">?(\\n[" SUP_RAISE_FORMAT
"]+\\n[rst])\n",
122 printf(".nr " DEPTH_FORMAT
" \\n[" DEPTH_FORMAT
"]"
123 ">?(-\\n[" SUP_RAISE_FORMAT
"]-\\n[rsb])\n",
125 // Do this last, so we don't lose height and depth information on
127 // Remember that the width of the bar might be greater than the width of p.
129 printf(".nr " TEMP_REG
" "
130 "\\n[" WIDTH_FORMAT
"]"
131 ">?\\w" DELIMITER_CHAR
"\\*[" BAR_STRING
"]" DELIMITER_CHAR
"\n",
133 printf(".as " SQRT_STRING_FORMAT
" "
134 "\\l'\\n[" TEMP_REG
"]u\\&\\*[" BAR_STRING
"]'\n",
136 printf(".nr " WIDTH_FORMAT
" \\n[" TEMP_REG
"]"
137 "+\\n[" SQRT_WIDTH_FORMAT
"]\n",
141 printf(".nr " MARK_REG
" +\\n[" SQRT_WIDTH_FORMAT
"]\n", uid
);
142 // the top of the bar might be higher than the top of the radical sign
143 printf(".nr " HEIGHT_FORMAT
" \\n[" HEIGHT_FORMAT
"]"
144 ">?(\\n[" SUP_RAISE_FORMAT
"]+\\n[rst])\n",
146 // put a bit of extra space above the bar
147 printf(".nr " HEIGHT_FORMAT
" +%dM\n", uid
, default_rule_thickness
);
148 printf(".ps \\n[" SIZE_FORMAT
"]u\n", uid
);
152 void sqrt_box::output()
154 if (output_format
== troff
) {
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'",
167 printf(DELIMITER_CHAR
);
169 printf("\\h'\\n[" WIDTH_FORMAT
"]u'", uid
);
171 else if (output_format
== mathml
) {
178 void sqrt_box::debug_print()
180 fprintf(stderr
, "sqrt { ");
182 fprintf(stderr
, " }");
185 void sqrt_box::check_tabs(int level
)
187 p
->check_tabs(level
+ 1);