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
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
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. */
27 class script_box
: public pointer_box
{
32 script_box(box
*, box
*, box
*);
34 int compute_metrics(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();
50 b
->list
.p
[b
->list
.len
-1] = make_script_box(b
->list
.p
[b
->list
.len
- 1],
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()
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
))
82 printf(".nr " SMALL_SIZE_FORMAT
" \\n[.ps]\n", uid
);
84 sub
->compute_metrics(cramped_style(script_style(style
)));
86 sup
->compute_metrics(script_style(style
));
89 printf(".nr " SUP_RAISE_FORMAT
" 0\n", uid
);
90 printf(".nr " SUB_LOWER_FORMAT
" 0\n", uid
);
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
);
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
);
110 if (style
== DISPLAY_STYLE
)
112 else if (style
& 1) // not cramped
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
);
121 printf(".nr " SUB_LOWER_FORMAT
" \\n[" SUB_LOWER_FORMAT
"]>?%dM\n",
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
);
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
);
144 printf("+(\\n[" WIDTH_FORMAT
"]-\\n[" SUB_KERN_FORMAT
"]+%dM)>?0\n",
145 sub
->uid
, p
->uid
, script_space
);
147 printf("+(\\n[" WIDTH_FORMAT
"]+%dM)>?0\n", sup
->uid
, script_space
);
150 printf(".nr " HEIGHT_FORMAT
" \\n[" HEIGHT_FORMAT
"]",
153 printf(">?(\\n[" SUP_RAISE_FORMAT
"]+\\n[" HEIGHT_FORMAT
"])",
156 printf(">?(-\\n[" SUB_LOWER_FORMAT
"]+\\n[" HEIGHT_FORMAT
"])",
159 printf(".nr " DEPTH_FORMAT
" \\n[" DEPTH_FORMAT
"]",
162 printf(">?(\\n[" SUB_LOWER_FORMAT
"]+\\n[" DEPTH_FORMAT
"])",
165 printf(">?(-\\n[" SUP_RAISE_FORMAT
"]+\\n[" DEPTH_FORMAT
"])",
171 void script_box::output()
175 printf("\\Z" DELIMITER_CHAR
);
176 printf("\\v'-\\n[" SUP_RAISE_FORMAT
"]u'", uid
);
177 printf("\\s[\\n[" SMALL_SIZE_FORMAT
"]u]", uid
);
179 printf("\\s[\\n[" SIZE_FORMAT
"]u]", uid
);
180 printf(DELIMITER_CHAR
);
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
);
188 printf("\\s[\\n[" SIZE_FORMAT
"]u]", uid
);
189 printf(DELIMITER_CHAR
);
191 printf("\\h'\\n[" WIDTH_FORMAT
"]u-\\n[" WIDTH_FORMAT
"]u'",
195 void script_box::hint(unsigned flags
)
197 p
->hint(flags
& ~HINT_NEXT_IS_ITALIC
);
200 void script_box::debug_print()
202 fprintf(stderr
, "{ ");
204 fprintf(stderr
, " }");
206 fprintf(stderr
, " sub { ");
208 fprintf(stderr
, " }");
211 fprintf(stderr
, " sup { ");
213 fprintf(stderr
, " }");
217 void script_box::check_tabs(int level
)
220 sup
->check_tabs(level
+ 1);
222 sub
->check_tabs(level
+ 1);
223 p
->check_tabs(level
);