Merge branch 'topic/sync-to-go-2'
[s-roff.git] / src / pre-eqn / sqrt.cpp
blobfa283954a3ec5c65288d6fa181917403fb5fe46d
1 /*@
2 * Copyright (c) 2014 - 2017 Steffen (Daode) Nurpmeso <steffen@sdaoden.eu>.
4 * Copyright (C) 1989 - 1992, 2002, 2003, 2007, 2008
5 * Free Software Foundation, Inc.
6 * Written by James Clark (jjc@jclark.com)
8 * This 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
11 * version.
13 * This 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
16 * for more details.
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.
23 #include "config.h"
24 #include "eqn-config.h"
26 #include "eqn.h"
27 #include "pbox.h"
29 #define SQRT_CHAR "\\[sqrt]"
30 #define RADICAL_EXTENSION_CHAR "\\[sqrtex]"
32 #define SQRT_CHAIN "\\[sqrt\\\\n[" INDEX_REG "]]"
33 #define BAR_CHAIN "\\[sqrtex\\\\n[" INDEX_REG "]]"
35 class sqrt_box
36 : public pointer_box
38 public:
39 sqrt_box(box *);
40 int compute_metrics(int style);
41 void output();
42 void debug_print();
43 void check_tabs(int);
46 box *make_sqrt_box(box *pp)
48 return new sqrt_box(pp);
51 sqrt_box::sqrt_box(box *pp) : pointer_box(pp)
55 int sqrt_box::compute_metrics(int style)
57 // 11
58 int r = p->compute_metrics(cramped_style(style));
59 printf(".nr " TEMP_REG " \\n[" HEIGHT_FORMAT "]+\\n[" DEPTH_FORMAT
60 "]+%dM+(%dM/4)\n",
61 p->uid, p->uid, default_rule_thickness,
62 (style > SCRIPT_STYLE ? x_height : default_rule_thickness));
63 printf(".nr " SIZE_FORMAT " \\n[.ps]\n", uid);
64 printf(".ds " SQRT_STRING_FORMAT " " SQRT_CHAR "\n", uid);
65 printf(".ds " BAR_STRING " " RADICAL_EXTENSION_CHAR "\n");
66 printf(".nr " SQRT_WIDTH_FORMAT
67 " 0\\w" DELIMITER_CHAR SQRT_CHAR DELIMITER_CHAR "\n",
68 uid);
69 printf(".if \\n[rst]-\\n[rsb]-%dM<\\n[" TEMP_REG "] \\{",
70 default_rule_thickness);
72 printf(".nr " INDEX_REG " 0\n"
73 ".de " TEMP_MACRO "\n"
74 ".ie c" SQRT_CHAIN " \\{"
75 ".ds " SQRT_STRING_FORMAT " " SQRT_CHAIN "\n"
76 ".ie c" BAR_CHAIN " .ds " BAR_STRING " " BAR_CHAIN "\n"
77 ".el .ds " BAR_STRING " " RADICAL_EXTENSION_CHAR "\n"
78 ".nr " SQRT_WIDTH_FORMAT
79 " 0\\w" DELIMITER_CHAR SQRT_CHAIN DELIMITER_CHAR "\n"
80 ".if \\\\n[rst]-\\\\n[rsb]-%dM<\\n[" TEMP_REG "] \\{"
81 ".nr " INDEX_REG " +1\n"
82 "." TEMP_MACRO "\n"
83 ".\\}\\}\n"
84 ".el .nr " INDEX_REG " 0-1\n"
85 "..\n"
86 "." TEMP_MACRO "\n",
87 uid, uid, default_rule_thickness);
89 printf(".if \\n[" INDEX_REG "]<0 \\{");
91 // Determine the maximum point size
92 printf(".ps 1000\n");
93 printf(".nr " MAX_SIZE_REG " \\n[.ps]\n");
94 printf(".ps \\n[" SIZE_FORMAT "]u\n", uid);
95 // We define a macro that will increase the current point size
96 // until we get a radical sign that's tall enough or we reach
97 // the maximum point size.
98 printf(".de " TEMP_MACRO "\n"
99 ".nr " SQRT_WIDTH_FORMAT
100 " 0\\w" DELIMITER_CHAR "\\*[" SQRT_STRING_FORMAT "]" DELIMITER_CHAR "\n"
101 ".if \\\\n[rst]"
102 "&(\\\\n[rst]-\\\\n[rsb]-%dM<\\n[" TEMP_REG "])"
103 "&(\\\\n[.ps]<\\n[" MAX_SIZE_REG "]) \\{"
104 ".ps +1\n"
105 "." TEMP_MACRO "\n"
106 ".\\}\n"
107 "..\n"
108 "." TEMP_MACRO "\n",
109 uid, uid, default_rule_thickness);
111 printf(".\\}\\}\n");
113 printf(".nr " SMALL_SIZE_FORMAT " \\n[.ps]\n", uid);
114 // set TEMP_REG to the amount by which the radical sign is too big
115 printf(".nr " TEMP_REG " \\n[rst]-\\n[rsb]-%dM-\\n[" TEMP_REG "]\n",
116 default_rule_thickness);
117 // If TEMP_REG is negative, the bottom of the radical sign should
118 // be -TEMP_REG above the bottom of p. If it's positive, the bottom
119 // of the radical sign should be TEMP_REG/2 below the bottom of p.
120 // This calculates the amount by which the baseline of the radical
121 // should be raised.
122 printf(".nr " SUP_RAISE_FORMAT " (-\\n[" TEMP_REG "]>?(-\\n[" TEMP_REG "]/2))"
123 "-\\n[rsb]-\\n[" DEPTH_FORMAT "]\n", uid, p->uid);
124 printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]"
125 ">?(\\n[" SUP_RAISE_FORMAT "]+\\n[rst])\n",
126 uid, p->uid, uid);
127 printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]"
128 ">?(-\\n[" SUP_RAISE_FORMAT "]-\\n[rsb])\n",
129 uid, p->uid, uid);
130 // Do this last, so we don't lose height and depth information on
131 // the radical sign.
132 // Remember that the width of the bar might be greater than the width of p.
134 printf(".nr " TEMP_REG " "
135 "\\n[" WIDTH_FORMAT "]"
136 ">?\\w" DELIMITER_CHAR "\\*[" BAR_STRING "]" DELIMITER_CHAR "\n",
137 p->uid);
138 printf(".as " SQRT_STRING_FORMAT " "
139 "\\l'\\n[" TEMP_REG "]u\\&\\*[" BAR_STRING "]'\n",
140 uid);
141 printf(".nr " WIDTH_FORMAT " \\n[" TEMP_REG "]"
142 "+\\n[" SQRT_WIDTH_FORMAT "]\n",
143 uid, uid);
145 if (r)
146 printf(".nr " MARK_REG " +\\n[" SQRT_WIDTH_FORMAT "]\n", uid);
147 // the top of the bar might be higher than the top of the radical sign
148 printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]"
149 ">?(\\n[" SUP_RAISE_FORMAT "]+\\n[rst])\n",
150 uid, p->uid, uid);
151 // put a bit of extra space above the bar
152 printf(".nr " HEIGHT_FORMAT " +%dM\n", uid, default_rule_thickness);
153 printf(".ps \\n[" SIZE_FORMAT "]u\n", uid);
154 return r;
157 void sqrt_box::output()
159 if (output_format == troff) {
160 printf("\\Z" DELIMITER_CHAR);
161 printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
162 printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
163 printf("\\*[" SQRT_STRING_FORMAT "]", uid);
164 printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
165 printf(DELIMITER_CHAR);
167 printf("\\Z" DELIMITER_CHAR);
168 printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u"
169 "+\\n[" SQRT_WIDTH_FORMAT "]u/2u'",
170 uid, p->uid, uid);
171 p->output();
172 printf(DELIMITER_CHAR);
174 printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
176 else if (output_format == mathml) {
177 printf("<msqrt>");
178 p->output();
179 printf("</msqrt>");
183 void sqrt_box::debug_print()
185 fprintf(stderr, "sqrt { ");
186 p->debug_print();
187 fprintf(stderr, " }");
190 void sqrt_box::check_tabs(int level)
192 p->check_tabs(level + 1);
195 // s-it2-mode