2 /* Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
3 Written by James Clark (jjc@jclark.uucp)
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 1, or (at your option) any later
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 along
18 with groff; see the file LICENSE. If not, write to the Free Software
19 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
24 class script_box
: public pointer_box
{
29 script_box(box
*, box
*, box
*);
31 int compute_metrics(int);
39 /* The idea is that the script should attach to the rightmost box
40 of a list. For example, given `2x sup 3', the superscript should
41 attach to `x' rather than `2x'. */
43 box
*make_script_box(box
*nuc
, box
*sub
, box
*sup
)
45 list_box
*b
= nuc
->to_list_box();
47 b
->list
.p
[b
->list
.len
-1] = make_script_box(b
->list
.p
[b
->list
.len
- 1],
53 return new script_box(nuc
, sub
, sup
);
56 script_box::script_box(box
*pp
, box
*qq
, box
*rr
)
57 : pointer_box(pp
), sub(qq
), sup(rr
)
61 script_box::~script_box()
67 int script_box::left_is_italic()
69 return p
->left_is_italic();
72 int script_box::compute_metrics(int style
)
74 int res
= p
->compute_metrics(style
);
75 p
->compute_subscript_kern();
76 printf(".nr " SIZE_FORMAT
" \\n[.s]\n", uid
);
77 if (!(style
<= SCRIPT_STYLE
&& one_size_reduction_flag
))
79 printf(".nr " SMALL_SIZE_FORMAT
" \\n[.s]\n", uid
);
81 sub
->compute_metrics(cramped_style(script_style(style
)));
83 sup
->compute_metrics(script_style(style
));
86 printf(".nr " SUP_RAISE_FORMAT
" 0\n", uid
);
87 printf(".nr " SUB_LOWER_FORMAT
" 0\n", uid
);
90 printf(".nr " SUP_RAISE_FORMAT
" \\n[" HEIGHT_FORMAT
"]-%dM>?0\n",
91 uid
, p
->uid
, sup_drop
);
92 printf(".nr " SUB_LOWER_FORMAT
" \\n[" DEPTH_FORMAT
"]+%dM\n",
93 uid
, p
->uid
, sub_drop
);
95 printf(".ps \\n[" SIZE_FORMAT
"]\n", uid
);
99 printf(".nr " SUB_LOWER_FORMAT
" \\n[" SUB_LOWER_FORMAT
"]>?%dM>?(\\n["
100 HEIGHT_FORMAT
"]-(%dM*4/5))\n",
101 uid
, uid
, sub1
, sub
->uid
, x_height
);
107 if (style
== DISPLAY_STYLE
)
109 else if (style
& 1) // not cramped
113 printf(".nr " SUP_RAISE_FORMAT
" \\n[" SUP_RAISE_FORMAT
114 "]>?%dM>?(\\n[" DEPTH_FORMAT
"]+(%dM/4))\n",
115 uid
, uid
, p
, sup
->uid
, x_height
);
118 printf(".nr " SUB_LOWER_FORMAT
" \\n[" SUB_LOWER_FORMAT
"]>?%dM\n",
121 printf(".nr " TEMP_REG
" \\n[" DEPTH_FORMAT
"]-\\n["
122 SUP_RAISE_FORMAT
"]+\\n[" HEIGHT_FORMAT
"]-\\n["
123 SUB_LOWER_FORMAT
"]+(4*%dM)\n",
124 sup
->uid
, uid
, sub
->uid
, uid
, default_rule_thickness
);
125 printf(".if \\n[" TEMP_REG
"] \\{");
126 printf(".nr " SUB_LOWER_FORMAT
" +\\n[" TEMP_REG
"]\n", uid
);
127 printf(".nr " TEMP_REG
" (%dM*4/5)-\\n[" SUP_RAISE_FORMAT
128 "]+\\n[" DEPTH_FORMAT
"]>?0\n",
129 x_height
, uid
, sup
->uid
);
130 printf(".nr " SUP_RAISE_FORMAT
" +\\n[" TEMP_REG
"]\n", uid
);
131 printf(".nr " SUB_LOWER_FORMAT
" -\\n[" TEMP_REG
"]\n", uid
);
135 printf(".nr " WIDTH_FORMAT
" 0\\n[" WIDTH_FORMAT
"]", uid
, p
->uid
);
136 if (sub
!= 0 && sup
!= 0)
137 printf("+((\\n[" WIDTH_FORMAT
"]-\\n[" SUB_KERN_FORMAT
"]>?\\n["
138 WIDTH_FORMAT
"])+%dM)>?0\n",
139 sub
->uid
, p
->uid
, sup
->uid
, script_space
);
141 printf("+(\\n[" WIDTH_FORMAT
"]-\\n[" SUB_KERN_FORMAT
"]+%dM)>?0\n",
142 sub
->uid
, p
->uid
, script_space
);
144 printf("+(\\n[" WIDTH_FORMAT
"]+%dM)>?0\n", sup
->uid
, script_space
);
147 printf(".nr " HEIGHT_FORMAT
" \\n[" HEIGHT_FORMAT
"]",
150 printf(">?(\\n[" SUP_RAISE_FORMAT
"]+\\n[" HEIGHT_FORMAT
"])",
153 printf(">?(-\\n[" SUB_LOWER_FORMAT
"]+\\n[" HEIGHT_FORMAT
"])",
156 printf(".nr " DEPTH_FORMAT
" \\n[" DEPTH_FORMAT
"]",
159 printf(">?(\\n[" SUB_LOWER_FORMAT
"]+\\n[" DEPTH_FORMAT
"])",
162 printf(">?(-\\n[" SUP_RAISE_FORMAT
"]+\\n[" DEPTH_FORMAT
"])",
168 void script_box::output()
172 printf("\\Z" DELIMITER_CHAR
);
173 printf("\\v'-\\n[" SUP_RAISE_FORMAT
"]u'", uid
);
174 printf("\\s[\\n[" SMALL_SIZE_FORMAT
"]]", uid
);
176 printf("\\s[\\n[" SIZE_FORMAT
"]]", 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
"]]", uid
);
183 printf("\\h'-\\n[" SUB_KERN_FORMAT
"]u'", p
->uid
);
185 printf("\\s[\\n[" SIZE_FORMAT
"]]", uid
);
186 printf(DELIMITER_CHAR
);
188 printf("\\h'\\n[" WIDTH_FORMAT
"]u-\\n[" WIDTH_FORMAT
"]u'",
192 void script_box::hint(unsigned flags
)
194 p
->hint(flags
& ~HINT_NEXT_IS_ITALIC
);
197 void script_box::debug_print()
199 fprintf(stderr
, "{ ");
201 fprintf(stderr
, " }");
203 fprintf(stderr
, " sub { ");
205 fprintf(stderr
, " }");
208 fprintf(stderr
, " sup { ");
210 fprintf(stderr
, " }");
214 void script_box::check_tabs(int level
)
217 sup
->check_tabs(level
+ 1);
219 sub
->check_tabs(level
+ 1);
220 p
->check_tabs(level
);