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/>. */
23 class script_box : public pointer_box {
28 script_box(box *, box *, box *);
30 int compute_metrics(int);
38 /* The idea is that the script should attach to the rightmost box
39 of a list. For example, given `2x sup 3', the superscript should
40 attach to `x' rather than `2x'. */
42 box *make_script_box(box *nuc, box *sub, box *sup)
44 list_box *b = nuc->to_list_box();
46 b->list.p[b->list.len-1] = make_script_box(b->list.p[b->list.len - 1],
52 return new script_box(nuc, sub, sup);
55 script_box::script_box(box *pp, box *qq, box *rr)
56 : pointer_box(pp), sub(qq), sup(rr)
60 script_box::~script_box()
66 int script_box::left_is_italic()
68 return p->left_is_italic();
71 int script_box::compute_metrics(int style)
73 int res = p->compute_metrics(style);
74 p->compute_subscript_kern();
75 printf(".nr " SIZE_FORMAT " \\n[.ps]\n", uid);
76 if (!(style <= SCRIPT_STYLE && one_size_reduction_flag))
78 printf(".nr " SMALL_SIZE_FORMAT " \\n[.ps]\n", uid);
80 sub->compute_metrics(cramped_style(script_style(style)));
82 sup->compute_metrics(script_style(style));
85 printf(".nr " SUP_RAISE_FORMAT " 0\n", uid);
86 printf(".nr " SUB_LOWER_FORMAT " 0\n", uid);
89 printf(".nr " SUP_RAISE_FORMAT " \\n[" HEIGHT_FORMAT "]-%dM>?0\n",
90 uid, p->uid, sup_drop);
91 printf(".nr " SUB_LOWER_FORMAT " \\n[" DEPTH_FORMAT "]+%dM\n",
92 uid, p->uid, sub_drop);
94 printf(".ps \\n[" SIZE_FORMAT "]u\n", uid);
98 printf(".nr " SUB_LOWER_FORMAT " \\n[" SUB_LOWER_FORMAT "]>?%dM>?(\\n["
99 HEIGHT_FORMAT "]-(%dM*4/5))\n",
100 uid, uid, sub1, sub->uid, x_height);
106 if (style == DISPLAY_STYLE)
108 else if (style & 1) // not cramped
112 printf(".nr " SUP_RAISE_FORMAT " \\n[" SUP_RAISE_FORMAT
113 "]>?%dM>?(\\n[" DEPTH_FORMAT "]+(%dM/4))\n",
114 uid, uid, pos, sup->uid, x_height);
117 printf(".nr " SUB_LOWER_FORMAT " \\n[" SUB_LOWER_FORMAT "]>?%dM\n",
120 printf(".nr " TEMP_REG " \\n[" DEPTH_FORMAT "]-\\n["
121 SUP_RAISE_FORMAT "]+\\n[" HEIGHT_FORMAT "]-\\n["
122 SUB_LOWER_FORMAT "]+(4*%dM)\n",
123 sup->uid, uid, sub->uid, uid, default_rule_thickness);
124 printf(".if \\n[" TEMP_REG "] \\{");
125 printf(".nr " SUB_LOWER_FORMAT " +\\n[" TEMP_REG "]\n", uid);
126 printf(".nr " TEMP_REG " (%dM*4/5)-\\n[" SUP_RAISE_FORMAT
127 "]+\\n[" DEPTH_FORMAT "]>?0\n",
128 x_height, uid, sup->uid);
129 printf(".nr " SUP_RAISE_FORMAT " +\\n[" TEMP_REG "]\n", uid);
130 printf(".nr " SUB_LOWER_FORMAT " -\\n[" TEMP_REG "]\n", uid);
134 printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]", uid, p->uid);
135 if (sub != 0 && sup != 0)
136 printf("+((\\n[" WIDTH_FORMAT "]-\\n[" SUB_KERN_FORMAT "]>?\\n["
137 WIDTH_FORMAT "])+%dM)>?0\n",
138 sub->uid, p->uid, sup->uid, script_space);
140 printf("+(\\n[" WIDTH_FORMAT "]-\\n[" SUB_KERN_FORMAT "]+%dM)>?0\n",
141 sub->uid, p->uid, script_space);
143 printf("+(\\n[" WIDTH_FORMAT "]+%dM)>?0\n", sup->uid, script_space);
146 printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]",
149 printf(">?(\\n[" SUP_RAISE_FORMAT "]+\\n[" HEIGHT_FORMAT "])",
152 printf(">?(-\\n[" SUB_LOWER_FORMAT "]+\\n[" HEIGHT_FORMAT "])",
155 printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]",
158 printf(">?(\\n[" SUB_LOWER_FORMAT "]+\\n[" DEPTH_FORMAT "])",
161 printf(">?(-\\n[" SUP_RAISE_FORMAT "]+\\n[" DEPTH_FORMAT "])",
167 void script_box::output()
169 if (output_format == troff) {
172 printf("\\Z" DELIMITER_CHAR);
173 printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
174 printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
176 printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
177 printf(DELIMITER_CHAR);
180 printf("\\Z" DELIMITER_CHAR);
181 printf("\\v'\\n[" SUB_LOWER_FORMAT "]u'", uid);
182 printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
183 printf("\\h'-\\n[" SUB_KERN_FORMAT "]u'", p->uid);
185 printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
186 printf(DELIMITER_CHAR);
188 printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u'",
191 else if (output_format == mathml) {
192 if (sup != 0 && sub != 0) {
197 printf("</msubsup>");
214 void script_box::hint(unsigned flags)
216 p->hint(flags & ~HINT_NEXT_IS_ITALIC);
219 void script_box::debug_print()
221 fprintf(stderr, "{ ");
223 fprintf(stderr, " }");
225 fprintf(stderr, " sub { ");
227 fprintf(stderr, " }");
230 fprintf(stderr, " sup { ");
232 fprintf(stderr, " }");
236 void script_box::check_tabs(int level)
239 sup->check_tabs(level + 1);
241 sub->check_tabs(level + 1);
242 p->check_tabs(level);