4 /* Copyright (C) 1989, 1990, 1991, 1992, 2002 Free Software Foundation, Inc.
5 Written by James Clark (jjc@jclark.com)
7 This file is part of groff.
9 groff is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
14 groff is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License along
20 with groff; see the file COPYING. If not, write to the Free Software
21 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
26 class accent_box
: public pointer_box
{
30 accent_box(box
*, box
*);
32 int compute_metrics(int);
38 box
*make_accent_box(box
*p
, box
*q
)
40 return new accent_box(p
, q
);
43 accent_box::accent_box(box
*pp
, box
*qq
) : pointer_box(pp
), ab(qq
)
47 accent_box::~accent_box()
53 int accent_box::compute_metrics(int style
)
55 int r
= p
->compute_metrics(style
);
57 ab
->compute_metrics(style
);
58 printf(".nr " WIDTH_FORMAT
" 0\\n[" WIDTH_FORMAT
"]\n", uid
, p
->uid
);
59 printf(".nr " DEPTH_FORMAT
" \\n[" DEPTH_FORMAT
"]\n", uid
, p
->uid
);
60 printf(".nr " SUP_RAISE_FORMAT
" \\n[" HEIGHT_FORMAT
"]-%dM>?0\n",
61 uid
, p
->uid
, x_height
);
62 printf(".nr " HEIGHT_FORMAT
" \\n[" HEIGHT_FORMAT
"]+\\n["
63 SUP_RAISE_FORMAT
"]\n",
68 void accent_box::output()
70 printf("\\h'\\n[" WIDTH_FORMAT
"]u-\\n[" WIDTH_FORMAT
"]u/2u+\\n["
72 p
->uid
, ab
->uid
, p
->uid
);
73 printf("\\v'-\\n[" SUP_RAISE_FORMAT
"]u'", uid
);
75 printf("\\h'-\\n[" WIDTH_FORMAT
"]u'", ab
->uid
);
76 printf("\\v'\\n[" SUP_RAISE_FORMAT
"]u'", uid
);
77 printf("\\h'-(\\n[" WIDTH_FORMAT
"]u-\\n[" WIDTH_FORMAT
"]u/2u+\\n["
79 p
->uid
, ab
->uid
, p
->uid
);
84 /* This version copes with the possibility of an accent's being wider
85 than its accentee. LEFT_WIDTH_FORMAT gives the distance from the
86 left edge of the resulting box to the middle of the accentee's box.*/
88 int accent_box::compute_metrics(int style
)
90 int r
= p
->compute_metrics(style
);
92 ab
->compute_metrics(style
);
93 printf(".nr " LEFT_WIDTH_FORMAT
" 0\\n[" WIDTH_FORMAT
"]/2"
94 ">?(\\n[" WIDTH_FORMAT
"]/2-\\n[" SKEW_FORMAT
"])\n",
95 uid
, p
->uid
, ab
->uid
, p
->uid
);
96 printf(".nr " WIDTH_FORMAT
" 0\\n[" WIDTH_FORMAT
"]/2"
97 ">?(\\n[" WIDTH_FORMAT
"]/2+\\n[" SKEW_FORMAT
"])"
98 "+\\n[" LEFT_WIDTH_FORMAT
"]\n",
99 uid
, p
->uid
, ab
->uid
, p
->uid
, uid
);
100 printf(".nr " DEPTH_FORMAT
" \\n[" DEPTH_FORMAT
"]\n", uid
, p
->uid
);
101 printf(".nr " SUP_RAISE_FORMAT
" \\n[" HEIGHT_FORMAT
"]-%dM>?0\n",
102 uid
, p
->uid
, x_height
);
103 printf(".nr " HEIGHT_FORMAT
" \\n[" HEIGHT_FORMAT
"]+\\n["
104 SUP_RAISE_FORMAT
"]\n",
107 printf(".nr " MARK_REG
" +\\n[" LEFT_WIDTH_FORMAT
"]"
108 "-(\\n[" WIDTH_FORMAT
"]/2)'\n",
113 void accent_box::output()
115 printf("\\Z" DELIMITER_CHAR
);
116 printf("\\h'\\n[" LEFT_WIDTH_FORMAT
"]u+\\n[" SKEW_FORMAT
"]u"
117 "-(\\n[" WIDTH_FORMAT
"]u/2u)'",
118 uid
, p
->uid
, ab
->uid
);
119 printf("\\v'-\\n[" SUP_RAISE_FORMAT
"]u'", uid
);
121 printf(DELIMITER_CHAR
);
122 printf("\\Z" DELIMITER_CHAR
);
123 printf("\\h'\\n[" LEFT_WIDTH_FORMAT
"]u-(\\n[" WIDTH_FORMAT
"]u/2u)'",
126 printf(DELIMITER_CHAR
);
127 printf("\\h'\\n[" WIDTH_FORMAT
"]u'", uid
);
130 void accent_box::check_tabs(int level
)
132 ab
->check_tabs(level
+ 1);
133 p
->check_tabs(level
+ 1);
136 void accent_box::debug_print()
138 fprintf(stderr
, "{ ");
140 fprintf(stderr
, " } accent { ");
142 fprintf(stderr
, " }");
145 class overline_char_box
: public simple_box
{
152 overline_char_box::overline_char_box()
156 void overline_char_box::output()
158 printf("\\v'-%dM/2u-%dM'", 7*default_rule_thickness
, x_height
);
159 printf((draw_flag
? "\\D'l%dM 0'" : "\\l'%dM\\&\\(ru'"),
161 printf("\\v'%dM/2u+%dM'", 7*default_rule_thickness
, x_height
);
164 void overline_char_box::debug_print()
166 fprintf(stderr
, "<overline char>");
169 class overline_box
: public pointer_box
{
172 int compute_metrics(int);
177 box
*make_overline_box(box
*p
)
180 return new accent_box(p
, new overline_char_box
);
182 return new overline_box(p
);
185 overline_box::overline_box(box
*pp
) : pointer_box(pp
)
189 int overline_box::compute_metrics(int style
)
191 int r
= p
->compute_metrics(cramped_style(style
));
193 printf(".nr " HEIGHT_FORMAT
" \\n[" HEIGHT_FORMAT
"]+%dM\n",
194 uid
, p
->uid
, default_rule_thickness
*5);
195 printf(".nr " WIDTH_FORMAT
" 0\\n[" WIDTH_FORMAT
"]\n", uid
, p
->uid
);
196 printf(".nr " DEPTH_FORMAT
" \\n[" DEPTH_FORMAT
"]\n", uid
, p
->uid
);
200 void overline_box::output()
203 printf("\\Z" DELIMITER_CHAR
);
204 printf("\\v'-\\n[" HEIGHT_FORMAT
"]u-(%dM/2u)'",
205 p
->uid
, 7*default_rule_thickness
);
207 printf("\\D'l\\n[" WIDTH_FORMAT
"]u 0'", p
->uid
);
209 printf("\\l'\\n[" WIDTH_FORMAT
"]u\\&\\(ru'", p
->uid
);
210 printf(DELIMITER_CHAR
);
214 void overline_box::debug_print()
216 fprintf(stderr
, "{ ");
218 fprintf(stderr
, " } bar");
221 class uaccent_box
: public pointer_box
{
224 uaccent_box(box
*, box
*);
226 int compute_metrics(int);
228 void compute_subscript_kern();
229 void check_tabs(int);
233 box
*make_uaccent_box(box
*p
, box
*q
)
235 return new uaccent_box(p
, q
);
238 uaccent_box::uaccent_box(box
*pp
, box
*qq
)
239 : pointer_box(pp
), ab(qq
)
243 uaccent_box::~uaccent_box()
248 int uaccent_box::compute_metrics(int style
)
250 int r
= p
->compute_metrics(style
);
251 ab
->compute_metrics(style
);
252 printf(".nr " LEFT_WIDTH_FORMAT
" 0\\n[" WIDTH_FORMAT
"]/2"
253 ">?(\\n[" WIDTH_FORMAT
"]/2)\n",
254 uid
, p
->uid
, ab
->uid
);
255 printf(".nr " WIDTH_FORMAT
" 0\\n[" WIDTH_FORMAT
"]/2"
256 ">?(\\n[" WIDTH_FORMAT
"]/2)"
257 "+\\n[" LEFT_WIDTH_FORMAT
"]\n",
258 uid
, p
->uid
, ab
->uid
, uid
);
259 printf(".nr " HEIGHT_FORMAT
" \\n[" HEIGHT_FORMAT
"]\n", uid
, p
->uid
);
260 printf(".nr " DEPTH_FORMAT
" \\n[" DEPTH_FORMAT
"]"
261 "+\\n[" DEPTH_FORMAT
"]\n",
262 uid
, p
->uid
, ab
->uid
);
264 printf(".nr " MARK_REG
" +\\n[" LEFT_WIDTH_FORMAT
"]"
265 "-(\\n[" WIDTH_FORMAT
"]/2)'\n",
270 void uaccent_box::output()
272 printf("\\Z" DELIMITER_CHAR
);
273 printf("\\h'\\n[" LEFT_WIDTH_FORMAT
"]u-(\\n[" WIDTH_FORMAT
"]u/2u)'",
275 printf("\\v'\\n[" DEPTH_FORMAT
"]u'", p
->uid
);
277 printf(DELIMITER_CHAR
);
278 printf("\\Z" DELIMITER_CHAR
);
279 printf("\\h'\\n[" LEFT_WIDTH_FORMAT
"]u-(\\n[" WIDTH_FORMAT
"]u/2u)'",
282 printf(DELIMITER_CHAR
);
283 printf("\\h'\\n[" WIDTH_FORMAT
"]u'", uid
);
286 void uaccent_box::check_tabs(int level
)
288 ab
->check_tabs(level
+ 1);
289 p
->check_tabs(level
+ 1);
292 void uaccent_box::compute_subscript_kern()
294 box::compute_subscript_kern(); // want 0 subscript kern
297 void uaccent_box::debug_print()
299 fprintf(stderr
, "{ ");
301 fprintf(stderr
, " } uaccent { ");
303 fprintf(stderr
, " }");
306 class underline_char_box
: public simple_box
{
308 underline_char_box();
313 underline_char_box::underline_char_box()
317 void underline_char_box::output()
319 printf("\\v'%dM/2u'", 7*default_rule_thickness
);
320 printf((draw_flag
? "\\D'l%dM 0'" : "\\l'%dM\\&\\(ru'"),
322 printf("\\v'-%dM/2u'", 7*default_rule_thickness
);
325 void underline_char_box::debug_print()
327 fprintf(stderr
, "<underline char>");
331 class underline_box
: public pointer_box
{
333 underline_box(box
*);
334 int compute_metrics(int);
336 void compute_subscript_kern();
340 box
*make_underline_box(box
*p
)
343 return new uaccent_box(p
, new underline_char_box
);
345 return new underline_box(p
);
348 underline_box::underline_box(box
*pp
) : pointer_box(pp
)
352 int underline_box::compute_metrics(int style
)
354 int r
= p
->compute_metrics(style
);
356 printf(".nr " DEPTH_FORMAT
" \\n[" DEPTH_FORMAT
"]+%dM\n",
357 uid
, p
->uid
, default_rule_thickness
*5);
358 printf(".nr " WIDTH_FORMAT
" 0\\n[" WIDTH_FORMAT
"]\n", uid
, p
->uid
);
359 printf(".nr " HEIGHT_FORMAT
" \\n[" HEIGHT_FORMAT
"]\n", uid
, p
->uid
);
363 void underline_box::output()
366 printf("\\Z" DELIMITER_CHAR
);
367 printf("\\v'\\n[" DEPTH_FORMAT
"]u+(%dM/2u)'",
368 p
->uid
, 7*default_rule_thickness
);
370 printf("\\D'l\\n[" WIDTH_FORMAT
"]u 0'", p
->uid
);
372 printf("\\l'\\n[" WIDTH_FORMAT
"]u\\&\\(ru'", p
->uid
);
373 printf(DELIMITER_CHAR
);
377 // we want an underline box to have 0 subscript kern
379 void underline_box::compute_subscript_kern()
381 box::compute_subscript_kern();
384 void underline_box::debug_print()
386 fprintf(stderr
, "{ ");
388 fprintf(stderr
, " } under");
391 size_box::size_box(char *s
, box
*pp
) : pointer_box(pp
), size(s
)
395 int size_box::compute_metrics(int style
)
397 printf(".nr " SIZE_FORMAT
" \\n[.ps]\n", uid
);
398 printf(".ps %s\n", size
);
399 printf(".nr " SMALL_SIZE_FORMAT
" \\n[.ps]\n", uid
);
400 int r
= p
->compute_metrics(style
);
401 printf(".ps \\n[" SIZE_FORMAT
"]u\n", uid
);
402 printf(".nr " WIDTH_FORMAT
" 0\\n[" WIDTH_FORMAT
"]\n", uid
, p
->uid
);
403 printf(".nr " HEIGHT_FORMAT
" \\n[" HEIGHT_FORMAT
"]\n", uid
, p
->uid
);
404 printf(".nr " DEPTH_FORMAT
" \\n[" DEPTH_FORMAT
"]\n", uid
, p
->uid
);
408 void size_box::output()
410 printf("\\s[\\n[" SMALL_SIZE_FORMAT
"]u]", uid
);
412 printf("\\s[\\n[" SIZE_FORMAT
"]u]", uid
);
415 size_box::~size_box()
420 void size_box::debug_print()
422 fprintf(stderr
, "size %s { ", size
);
424 fprintf(stderr
, " }");
428 font_box::font_box(char *s
, box
*pp
) : pointer_box(pp
), f(s
)
432 font_box::~font_box()
437 int font_box::compute_metrics(int style
)
439 const char *old_roman_font
= current_roman_font
;
440 current_roman_font
= f
;
441 printf(".nr " FONT_FORMAT
" \\n[.f]\n", uid
);
442 printf(".ft %s\n", f
);
443 int r
= p
->compute_metrics(style
);
444 current_roman_font
= old_roman_font
;
445 printf(".ft \\n[" FONT_FORMAT
"]\n", uid
);
446 printf(".nr " WIDTH_FORMAT
" 0\\n[" WIDTH_FORMAT
"]\n", uid
, p
->uid
);
447 printf(".nr " HEIGHT_FORMAT
" \\n[" HEIGHT_FORMAT
"]\n", uid
, p
->uid
);
448 printf(".nr " DEPTH_FORMAT
" \\n[" DEPTH_FORMAT
"]\n", uid
, p
->uid
);
452 void font_box::output()
454 printf("\\f[%s]", f
);
455 const char *old_roman_font
= current_roman_font
;
456 current_roman_font
= f
;
458 current_roman_font
= old_roman_font
;
459 printf("\\f[\\n[" FONT_FORMAT
"]]", uid
);
462 void font_box::debug_print()
464 fprintf(stderr
, "font %s { ", f
);
466 fprintf(stderr
, " }");
469 fat_box::fat_box(box
*pp
) : pointer_box(pp
)
473 int fat_box::compute_metrics(int style
)
475 int r
= p
->compute_metrics(style
);
476 printf(".nr " WIDTH_FORMAT
" 0\\n[" WIDTH_FORMAT
"]+%dM\n",
477 uid
, p
->uid
, fat_offset
);
478 printf(".nr " HEIGHT_FORMAT
" \\n[" HEIGHT_FORMAT
"]\n", uid
, p
->uid
);
479 printf(".nr " DEPTH_FORMAT
" \\n[" DEPTH_FORMAT
"]\n", uid
, p
->uid
);
483 void fat_box::output()
486 printf("\\h'-\\n[" WIDTH_FORMAT
"]u'", p
->uid
);
487 printf("\\h'%dM'", fat_offset
);
492 void fat_box::debug_print()
494 fprintf(stderr
, "fat { ");
496 fprintf(stderr
, " }");
500 vmotion_box::vmotion_box(int i
, box
*pp
) : pointer_box(pp
), n(i
)
504 int vmotion_box::compute_metrics(int style
)
506 int r
= p
->compute_metrics(style
);
507 printf(".nr " WIDTH_FORMAT
" 0\\n[" WIDTH_FORMAT
"]\n", uid
, p
->uid
);
509 printf(".nr " HEIGHT_FORMAT
" %dM+\\n[" HEIGHT_FORMAT
"]\n",
511 printf(".nr " DEPTH_FORMAT
" \\n[" DEPTH_FORMAT
"]\n", uid
, p
->uid
);
514 printf(".nr " DEPTH_FORMAT
" %dM+\\n[" DEPTH_FORMAT
"]>?0\n",
516 printf(".nr " HEIGHT_FORMAT
" \\n[" HEIGHT_FORMAT
"]\n",
522 void vmotion_box::output()
524 printf("\\v'%dM'", -n
);
526 printf("\\v'%dM'", n
);
529 void vmotion_box::debug_print()
532 fprintf(stderr
, "up %d { ", n
);
534 fprintf(stderr
, "down %d { ", -n
);
536 fprintf(stderr
, " }");
539 hmotion_box::hmotion_box(int i
, box
*pp
) : pointer_box(pp
), n(i
)
543 int hmotion_box::compute_metrics(int style
)
545 int r
= p
->compute_metrics(style
);
546 printf(".nr " WIDTH_FORMAT
" 0\\n[" WIDTH_FORMAT
"]+%dM\n",
548 printf(".nr " HEIGHT_FORMAT
" \\n[" HEIGHT_FORMAT
"]\n", uid
, p
->uid
);
549 printf(".nr " DEPTH_FORMAT
" \\n[" DEPTH_FORMAT
"]\n", uid
, p
->uid
);
551 printf(".nr " MARK_REG
" +%dM\n", n
);
555 void hmotion_box::output()
557 printf("\\h'%dM'", n
);
561 void hmotion_box::debug_print()
564 fprintf(stderr
, "fwd %d { ", n
);
566 fprintf(stderr
, "back %d { ", -n
);
568 fprintf(stderr
, " }");
571 vcenter_box::vcenter_box(box
*pp
) : pointer_box(pp
)
575 int vcenter_box::compute_metrics(int style
)
577 int r
= p
->compute_metrics(style
);
578 printf(".nr " WIDTH_FORMAT
" 0\\n[" WIDTH_FORMAT
"]\n", uid
, p
->uid
);
579 printf(".nr " SUP_RAISE_FORMAT
" \\n[" DEPTH_FORMAT
"]-\\n["
580 HEIGHT_FORMAT
"]/2+%dM\n",
581 uid
, p
->uid
, p
->uid
, axis_height
);
582 printf(".nr " HEIGHT_FORMAT
" \\n[" HEIGHT_FORMAT
"]+\\n["
583 SUP_RAISE_FORMAT
"]>?0\n", uid
, p
->uid
, uid
);
584 printf(".nr " DEPTH_FORMAT
" \\n[" DEPTH_FORMAT
"]-\\n["
585 SUP_RAISE_FORMAT
"]>?0\n", uid
, p
->uid
, uid
);
590 void vcenter_box::output()
592 printf("\\v'-\\n[" SUP_RAISE_FORMAT
"]u'", uid
);
594 printf("\\v'\\n[" SUP_RAISE_FORMAT
"]u'", uid
);
597 void vcenter_box::debug_print()
599 fprintf(stderr
, "vcenter { ");
601 fprintf(stderr
, " }");