No empty .Rs/.Re
[netbsd-mini2440.git] / gnu / dist / groff / src / preproc / eqn / script.cpp
blob9d1a44473afa4c428fc240cfe0b98362ca9cc14d
1 /* $NetBSD$ */
3 // -*- C++ -*-
4 /* Copyright (C) 1989, 1990, 1991, 1992, 2002, 2004
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"
27 class script_box : public pointer_box {
28 private:
29 box *sub;
30 box *sup;
31 public:
32 script_box(box *, box *, box *);
33 ~script_box();
34 int compute_metrics(int);
35 void output();
36 void debug_print();
37 int left_is_italic();
38 void hint(unsigned);
39 void check_tabs(int);
42 /* The idea is that the script should attach to the rightmost box
43 of a list. For example, given `2x sup 3', the superscript should
44 attach to `x' rather than `2x'. */
46 box *make_script_box(box *nuc, box *sub, box *sup)
48 list_box *b = nuc->to_list_box();
49 if (b != 0) {
50 b->list.p[b->list.len-1] = make_script_box(b->list.p[b->list.len - 1],
51 sub,
52 sup);
53 return b;
55 else
56 return new script_box(nuc, sub, sup);
59 script_box::script_box(box *pp, box *qq, box *rr)
60 : pointer_box(pp), sub(qq), sup(rr)
64 script_box::~script_box()
66 delete sub;
67 delete sup;
70 int script_box::left_is_italic()
72 return p->left_is_italic();
75 int script_box::compute_metrics(int style)
77 int res = p->compute_metrics(style);
78 p->compute_subscript_kern();
79 printf(".nr " SIZE_FORMAT " \\n[.ps]\n", uid);
80 if (!(style <= SCRIPT_STYLE && one_size_reduction_flag))
81 set_script_size();
82 printf(".nr " SMALL_SIZE_FORMAT " \\n[.ps]\n", uid);
83 if (sub != 0)
84 sub->compute_metrics(cramped_style(script_style(style)));
85 if (sup != 0)
86 sup->compute_metrics(script_style(style));
87 // 18a
88 if (p->is_char()) {
89 printf(".nr " SUP_RAISE_FORMAT " 0\n", uid);
90 printf(".nr " SUB_LOWER_FORMAT " 0\n", uid);
92 else {
93 printf(".nr " SUP_RAISE_FORMAT " \\n[" HEIGHT_FORMAT "]-%dM>?0\n",
94 uid, p->uid, sup_drop);
95 printf(".nr " SUB_LOWER_FORMAT " \\n[" DEPTH_FORMAT "]+%dM\n",
96 uid, p->uid, sub_drop);
98 printf(".ps \\n[" SIZE_FORMAT "]u\n", uid);
99 if (sup == 0) {
100 assert(sub != 0);
101 // 18b
102 printf(".nr " SUB_LOWER_FORMAT " \\n[" SUB_LOWER_FORMAT "]>?%dM>?(\\n["
103 HEIGHT_FORMAT "]-(%dM*4/5))\n",
104 uid, uid, sub1, sub->uid, x_height);
106 else {
107 // sup != 0
108 // 18c
109 int pos;
110 if (style == DISPLAY_STYLE)
111 pos = sup1;
112 else if (style & 1) // not cramped
113 pos = sup2;
114 else
115 pos = sup3;
116 printf(".nr " SUP_RAISE_FORMAT " \\n[" SUP_RAISE_FORMAT
117 "]>?%dM>?(\\n[" DEPTH_FORMAT "]+(%dM/4))\n",
118 uid, uid, pos, sup->uid, x_height);
119 // 18d
120 if (sub != 0) {
121 printf(".nr " SUB_LOWER_FORMAT " \\n[" SUB_LOWER_FORMAT "]>?%dM\n",
122 uid, uid, sub2);
123 // 18e
124 printf(".nr " TEMP_REG " \\n[" DEPTH_FORMAT "]-\\n["
125 SUP_RAISE_FORMAT "]+\\n[" HEIGHT_FORMAT "]-\\n["
126 SUB_LOWER_FORMAT "]+(4*%dM)\n",
127 sup->uid, uid, sub->uid, uid, default_rule_thickness);
128 printf(".if \\n[" TEMP_REG "] \\{");
129 printf(".nr " SUB_LOWER_FORMAT " +\\n[" TEMP_REG "]\n", uid);
130 printf(".nr " TEMP_REG " (%dM*4/5)-\\n[" SUP_RAISE_FORMAT
131 "]+\\n[" DEPTH_FORMAT "]>?0\n",
132 x_height, uid, sup->uid);
133 printf(".nr " SUP_RAISE_FORMAT " +\\n[" TEMP_REG "]\n", uid);
134 printf(".nr " SUB_LOWER_FORMAT " -\\n[" TEMP_REG "]\n", uid);
135 printf(".\\}\n");
138 printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]", uid, p->uid);
139 if (sub != 0 && sup != 0)
140 printf("+((\\n[" WIDTH_FORMAT "]-\\n[" SUB_KERN_FORMAT "]>?\\n["
141 WIDTH_FORMAT "])+%dM)>?0\n",
142 sub->uid, p->uid, sup->uid, script_space);
143 else if (sub != 0)
144 printf("+(\\n[" WIDTH_FORMAT "]-\\n[" SUB_KERN_FORMAT "]+%dM)>?0\n",
145 sub->uid, p->uid, script_space);
146 else if (sup != 0)
147 printf("+(\\n[" WIDTH_FORMAT "]+%dM)>?0\n", sup->uid, script_space);
148 else
149 printf("\n");
150 printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]",
151 uid, p->uid);
152 if (sup != 0)
153 printf(">?(\\n[" SUP_RAISE_FORMAT "]+\\n[" HEIGHT_FORMAT "])",
154 uid, sup->uid);
155 if (sub != 0)
156 printf(">?(-\\n[" SUB_LOWER_FORMAT "]+\\n[" HEIGHT_FORMAT "])",
157 uid, sub->uid);
158 printf("\n");
159 printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]",
160 uid, p->uid);
161 if (sub != 0)
162 printf(">?(\\n[" SUB_LOWER_FORMAT "]+\\n[" DEPTH_FORMAT "])",
163 uid, sub->uid);
164 if (sup != 0)
165 printf(">?(-\\n[" SUP_RAISE_FORMAT "]+\\n[" DEPTH_FORMAT "])",
166 uid, sup->uid);
167 printf("\n");
168 return res;
171 void script_box::output()
173 p->output();
174 if (sup != 0) {
175 printf("\\Z" DELIMITER_CHAR);
176 printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
177 printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
178 sup->output();
179 printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
180 printf(DELIMITER_CHAR);
182 if (sub != 0) {
183 printf("\\Z" DELIMITER_CHAR);
184 printf("\\v'\\n[" SUB_LOWER_FORMAT "]u'", uid);
185 printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
186 printf("\\h'-\\n[" SUB_KERN_FORMAT "]u'", p->uid);
187 sub->output();
188 printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
189 printf(DELIMITER_CHAR);
191 printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u'",
192 uid, p->uid);
195 void script_box::hint(unsigned flags)
197 p->hint(flags & ~HINT_NEXT_IS_ITALIC);
200 void script_box::debug_print()
202 fprintf(stderr, "{ ");
203 p->debug_print();
204 fprintf(stderr, " }");
205 if (sub) {
206 fprintf(stderr, " sub { ");
207 sub->debug_print();
208 fprintf(stderr, " }");
210 if (sup) {
211 fprintf(stderr, " sup { ");
212 sup->debug_print();
213 fprintf(stderr, " }");
217 void script_box::check_tabs(int level)
219 if (sup)
220 sup->check_tabs(level + 1);
221 if (sub)
222 sub->check_tabs(level + 1);
223 p->check_tabs(level);