Line data Source code
1 : /* Copyright 1989-2024 Free Software Foundation, Inc.
2 : Written by James Clark (jjc@jclark.com)
3 :
4 : This file is part of groff, the GNU roff typesetting system.
5 :
6 : groff is free software; you can redistribute it and/or modify it under
7 : the terms of the GNU General Public License as published by the Free
8 : Software Foundation, either version 3 of the License, or
9 : (at your option) any later version.
10 :
11 : groff is distributed in the hope that it will be useful, but WITHOUT ANY
12 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 :
19 : #ifdef HAVE_CONFIG_H
20 : #include <config.h>
21 : #endif
22 :
23 : #include <stdlib.h> // free()
24 : #include <stdio.h> // fprintf(), printf()
25 :
26 : #include "eqn.h"
27 : #include "pbox.h"
28 :
29 : class accent_box : public pointer_box {
30 : private:
31 : box *ab;
32 : public:
33 : accent_box(box *, box *);
34 : ~accent_box();
35 : int compute_metrics(int);
36 : void output();
37 : void debug_print();
38 : void diagnose_tab_stop_usage(int);
39 : };
40 :
41 0 : box *make_accent_box(box *p, box *q)
42 : {
43 0 : return new accent_box(p, q);
44 : }
45 :
46 2 : accent_box::accent_box(box *pp, box *qq) : pointer_box(pp), ab(qq)
47 : {
48 2 : }
49 :
50 4 : accent_box::~accent_box()
51 : {
52 2 : delete ab;
53 4 : }
54 :
55 : #if 0
56 : int accent_box::compute_metrics(int style)
57 : {
58 : int r = p->compute_metrics(style);
59 : p->compute_skew();
60 : ab->compute_metrics(style);
61 : printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid);
62 : printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
63 : printf(".nr " SUP_RAISE_FORMAT " \\n[" HEIGHT_FORMAT "]-%dM>?0\n",
64 : uid, p->uid, get_param("x_height"));
65 : printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]+\\n["
66 : SUP_RAISE_FORMAT "]\n",
67 : uid, ab->uid, uid);
68 : return r;
69 : }
70 :
71 : void accent_box::output()
72 : {
73 : if (output_format == troff) {
74 : printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u+\\n["
75 : SKEW_FORMAT "]u'",
76 : p->uid, ab->uid, p->uid);
77 : printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
78 : ab->output();
79 : printf("\\h'-\\n[" WIDTH_FORMAT "]u'", ab->uid);
80 : printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
81 : printf("\\h'-(\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u+\\n["
82 : SKEW_FORMAT "]u)'",
83 : p->uid, ab->uid, p->uid);
84 : p->output();
85 : }
86 : else if (output_format == mathml) {
87 : printf("<mover accent='true'>");
88 : p->output();
89 : ab->output();
90 : printf("</mover>")
91 : }
92 : }
93 : #endif
94 :
95 : /* This version copes with the possibility of an accent's being wider
96 : than its accentee. LEFT_WIDTH_FORMAT gives the distance from the
97 : left edge of the resulting box to the middle of the accentee's box.*/
98 :
99 2 : int accent_box::compute_metrics(int style)
100 : {
101 2 : int r = p->compute_metrics(style);
102 2 : p->compute_skew();
103 2 : ab->compute_metrics(style);
104 2 : printf(".nr " LEFT_WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]/2"
105 : ">?(\\n[" WIDTH_FORMAT "]/2-\\n[" SKEW_FORMAT "])\n",
106 2 : uid, p->uid, ab->uid, p->uid);
107 2 : printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]/2"
108 : ">?(\\n[" WIDTH_FORMAT "]/2+\\n[" SKEW_FORMAT "])"
109 : "+\\n[" LEFT_WIDTH_FORMAT "]\n",
110 2 : uid, p->uid, ab->uid, p->uid, uid);
111 2 : printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
112 2 : printf(".nr " SUP_RAISE_FORMAT " \\n[" HEIGHT_FORMAT "]-%dM>?0\n",
113 2 : uid, p->uid, get_param("x_height"));
114 2 : printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]+\\n["
115 : SUP_RAISE_FORMAT "]\n",
116 2 : uid, ab->uid, uid);
117 2 : if (r)
118 0 : printf(".nr " MARK_REG " +\\n[" LEFT_WIDTH_FORMAT "]"
119 : "-(\\n[" WIDTH_FORMAT "]/2)'\n",
120 0 : uid, p->uid);
121 2 : return r;
122 : }
123 :
124 2 : void accent_box::output()
125 : {
126 2 : if (output_format == troff) {
127 2 : printf("\\Z" DELIMITER_CHAR);
128 2 : printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u+\\n[" SKEW_FORMAT "]u"
129 : "-(\\n[" WIDTH_FORMAT "]u/2u)'",
130 2 : uid, p->uid, ab->uid);
131 2 : printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
132 2 : ab->output();
133 2 : printf(DELIMITER_CHAR);
134 2 : printf("\\Z" DELIMITER_CHAR);
135 2 : printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u-(\\n[" WIDTH_FORMAT "]u/2u)'",
136 2 : uid, p->uid);
137 2 : p->output();
138 2 : printf(DELIMITER_CHAR);
139 2 : printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
140 : }
141 0 : else if (output_format == mathml) {
142 0 : printf("<mover accent='true'>");
143 0 : p->output();
144 0 : ab->output();
145 0 : printf("</mover>");
146 : }
147 2 : }
148 :
149 2 : void accent_box::diagnose_tab_stop_usage(int level)
150 : {
151 2 : ab->diagnose_tab_stop_usage(level + 1);
152 2 : p->diagnose_tab_stop_usage(level + 1);
153 2 : }
154 :
155 0 : void accent_box::debug_print()
156 : {
157 0 : fprintf(stderr, "{ ");
158 0 : p->debug_print();
159 0 : fprintf(stderr, " } accent { ");
160 0 : ab->debug_print();
161 0 : fprintf(stderr, " }");
162 0 : }
163 :
164 : class overline_char_box : public simple_box {
165 : public:
166 : overline_char_box();
167 : void output();
168 : void debug_print();
169 : };
170 :
171 2 : overline_char_box::overline_char_box()
172 : {
173 2 : }
174 :
175 4 : void overline_char_box::output()
176 : {
177 4 : if (output_format == troff) {
178 4 : printf("\\v'-%dM/2u-%dM'", 7 * get_param("default_rule_thickness"),
179 : get_param("x_height"));
180 4 : printf((draw_flag ? "\\D'l%dM 0'" : "\\l'%dM\\&\\(ru'"),
181 : get_param("accent_width"));
182 4 : printf("\\v'%dM/2u+%dM'", 7 * get_param("default_rule_thickness"),
183 : get_param("x_height"));
184 : }
185 0 : else if (output_format == mathml)
186 0 : printf("<mo>¯</mo>");
187 4 : }
188 :
189 0 : void overline_char_box::debug_print()
190 : {
191 0 : fprintf(stderr, "<overline char>");
192 0 : }
193 :
194 : class overline_box : public pointer_box {
195 : public:
196 : overline_box(box *);
197 : int compute_metrics(int);
198 : void output();
199 : void debug_print();
200 : };
201 :
202 2 : box *make_overline_box(box *p)
203 : {
204 2 : if (p->is_char())
205 2 : return new accent_box(p, new overline_char_box);
206 : else
207 0 : return new overline_box(p);
208 : }
209 :
210 0 : overline_box::overline_box(box *pp) : pointer_box(pp)
211 : {
212 0 : }
213 :
214 0 : int overline_box::compute_metrics(int style)
215 : {
216 0 : int r = p->compute_metrics(cramped_style(style));
217 : // 9
218 0 : printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]+%dM\n",
219 0 : uid, p->uid, get_param("default_rule_thickness") * 5);
220 0 : printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid);
221 0 : printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
222 0 : return r;
223 : }
224 :
225 0 : void overline_box::output()
226 : {
227 0 : if (output_format == troff) {
228 : // 9
229 0 : printf("\\Z" DELIMITER_CHAR);
230 0 : printf("\\v'-\\n[" HEIGHT_FORMAT "]u-(%dM/2u)'",
231 0 : p->uid, 7 * get_param("default_rule_thickness"));
232 0 : if (draw_flag)
233 0 : printf("\\D'l\\n[" WIDTH_FORMAT "]u 0'", p->uid);
234 : else
235 0 : printf("\\l'\\n[" WIDTH_FORMAT "]u\\&\\(ru'", p->uid);
236 0 : printf(DELIMITER_CHAR);
237 0 : p->output();
238 : }
239 0 : else if (output_format == mathml) {
240 0 : printf("<mover accent='false'>");
241 0 : p->output();
242 0 : printf("<mo>¯</mo></mover>");
243 : }
244 0 : }
245 :
246 0 : void overline_box::debug_print()
247 : {
248 0 : fprintf(stderr, "{ ");
249 0 : p->debug_print();
250 0 : fprintf(stderr, " } bar");
251 0 : }
252 :
253 : class uaccent_box : public pointer_box {
254 : box *ab;
255 : public:
256 : uaccent_box(box *, box *);
257 : ~uaccent_box();
258 : int compute_metrics(int);
259 : void output();
260 : void compute_subscript_kern();
261 : void diagnose_tab_stop_usage(int);
262 : void debug_print();
263 : };
264 :
265 0 : box *make_uaccent_box(box *p, box *q)
266 : {
267 0 : return new uaccent_box(p, q);
268 : }
269 :
270 0 : uaccent_box::uaccent_box(box *pp, box *qq)
271 0 : : pointer_box(pp), ab(qq)
272 : {
273 0 : }
274 :
275 0 : uaccent_box::~uaccent_box()
276 : {
277 0 : delete ab;
278 0 : }
279 :
280 0 : int uaccent_box::compute_metrics(int style)
281 : {
282 0 : int r = p->compute_metrics(style);
283 0 : ab->compute_metrics(style);
284 0 : printf(".nr " LEFT_WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]/2"
285 : ">?(\\n[" WIDTH_FORMAT "]/2)\n",
286 0 : uid, p->uid, ab->uid);
287 0 : printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]/2"
288 : ">?(\\n[" WIDTH_FORMAT "]/2)"
289 : "+\\n[" LEFT_WIDTH_FORMAT "]\n",
290 0 : uid, p->uid, ab->uid, uid);
291 0 : printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid);
292 0 : printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]"
293 : "+\\n[" DEPTH_FORMAT "]\n",
294 0 : uid, p->uid, ab->uid);
295 0 : if (r)
296 0 : printf(".nr " MARK_REG " +\\n[" LEFT_WIDTH_FORMAT "]"
297 : "-(\\n[" WIDTH_FORMAT "]/2)'\n",
298 0 : uid, p->uid);
299 0 : return r;
300 : }
301 :
302 0 : void uaccent_box::output()
303 : {
304 0 : if (output_format == troff) {
305 0 : printf("\\Z" DELIMITER_CHAR);
306 0 : printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u-(\\n[" WIDTH_FORMAT "]u/2u)'",
307 0 : uid, ab->uid);
308 0 : printf("\\v'\\n[" DEPTH_FORMAT "]u'", p->uid);
309 0 : ab->output();
310 0 : printf(DELIMITER_CHAR);
311 0 : printf("\\Z" DELIMITER_CHAR);
312 0 : printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u-(\\n[" WIDTH_FORMAT "]u/2u)'",
313 0 : uid, p->uid);
314 0 : p->output();
315 0 : printf(DELIMITER_CHAR);
316 0 : printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
317 : }
318 0 : else if (output_format == mathml) {
319 0 : printf("<munder accent='true'>");
320 0 : p->output();
321 0 : ab->output();
322 0 : printf("</munder>");
323 : }
324 0 : }
325 :
326 0 : void uaccent_box::diagnose_tab_stop_usage(int level)
327 : {
328 0 : ab->diagnose_tab_stop_usage(level + 1);
329 0 : p->diagnose_tab_stop_usage(level + 1);
330 0 : }
331 :
332 0 : void uaccent_box::compute_subscript_kern()
333 : {
334 0 : box::compute_subscript_kern(); // want 0 subscript kern
335 0 : }
336 :
337 0 : void uaccent_box::debug_print()
338 : {
339 0 : fprintf(stderr, "{ ");
340 0 : p->debug_print();
341 0 : fprintf(stderr, " } uaccent { ");
342 0 : ab->debug_print();
343 0 : fprintf(stderr, " }");
344 0 : }
345 :
346 : class underline_char_box : public simple_box {
347 : public:
348 : underline_char_box();
349 : void output();
350 : void debug_print();
351 : };
352 :
353 0 : underline_char_box::underline_char_box()
354 : {
355 0 : }
356 :
357 0 : void underline_char_box::output()
358 : {
359 0 : if (output_format == troff) {
360 0 : printf("\\v'%dM/2u'", 7 * get_param("default_rule_thickness"));
361 0 : printf((draw_flag ? "\\D'l%dM 0'" : "\\l'%dM\\&\\(ru'"),
362 : get_param("accent_width"));
363 0 : printf("\\v'-%dM/2u'", 7 * get_param("default_rule_thickness"));
364 : }
365 0 : else if (output_format == mathml)
366 0 : printf("<mo>_</mo>");
367 0 : }
368 :
369 0 : void underline_char_box::debug_print()
370 : {
371 0 : fprintf(stderr, "<underline char>");
372 0 : }
373 :
374 :
375 : class underline_box : public pointer_box {
376 : public:
377 : underline_box(box *);
378 : int compute_metrics(int);
379 : void output();
380 : void compute_subscript_kern();
381 : void debug_print();
382 : };
383 :
384 0 : box *make_underline_box(box *p)
385 : {
386 0 : if (p->is_char())
387 0 : return new uaccent_box(p, new underline_char_box);
388 : else
389 0 : return new underline_box(p);
390 : }
391 :
392 0 : underline_box::underline_box(box *pp) : pointer_box(pp)
393 : {
394 0 : }
395 :
396 0 : int underline_box::compute_metrics(int style)
397 : {
398 0 : int r = p->compute_metrics(style);
399 : // 10
400 0 : printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]+%dM\n",
401 0 : uid, p->uid, get_param("default_rule_thickness") * 5);
402 0 : printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid);
403 0 : printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid);
404 0 : return r;
405 : }
406 :
407 0 : void underline_box::output()
408 : {
409 0 : if (output_format == troff) {
410 : // 10
411 0 : printf("\\Z" DELIMITER_CHAR);
412 0 : printf("\\v'\\n[" DEPTH_FORMAT "]u+(%dM/2u)'",
413 0 : p->uid, 7 * get_param("default_rule_thickness"));
414 0 : if (draw_flag)
415 0 : printf("\\D'l\\n[" WIDTH_FORMAT "]u 0'", p->uid);
416 : else
417 0 : printf("\\l'\\n[" WIDTH_FORMAT "]u\\&\\(ru'", p->uid);
418 0 : printf(DELIMITER_CHAR);
419 0 : p->output();
420 : }
421 0 : else if (output_format == mathml) {
422 0 : printf("<munder accent='true'>");
423 0 : p->output();
424 0 : printf("<mo>¯</mo></munder>");
425 : }
426 0 : }
427 :
428 : // we want an underline box to have 0 subscript kern
429 :
430 0 : void underline_box::compute_subscript_kern()
431 : {
432 0 : box::compute_subscript_kern();
433 0 : }
434 :
435 0 : void underline_box::debug_print()
436 : {
437 0 : fprintf(stderr, "{ ");
438 0 : p->debug_print();
439 0 : fprintf(stderr, " } under");
440 0 : }
441 :
442 122 : size_box::size_box(char *s, box *pp) : pointer_box(pp), size(s)
443 : {
444 122 : }
445 :
446 122 : int size_box::compute_metrics(int style)
447 : {
448 122 : printf(".nr " SIZE_FORMAT " \\n[.ps]\n", uid);
449 122 : printf(".ps %s\n", size);
450 122 : printf(".nr " SMALL_SIZE_FORMAT " \\n[.ps]\n", uid);
451 122 : int r = p->compute_metrics(style);
452 122 : printf(".ps \\n[" SIZE_FORMAT "]u\n", uid);
453 122 : printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid);
454 122 : printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid);
455 122 : printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
456 122 : return r;
457 : }
458 :
459 122 : void size_box::output()
460 : {
461 122 : if (output_format == troff) {
462 122 : printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
463 122 : p->output();
464 122 : printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
465 : }
466 0 : else if (output_format == mathml) {
467 0 : printf("<mstyle mathsize='%s'>", size);
468 0 : p->output();
469 0 : printf("</mstyle>");
470 : }
471 122 : }
472 :
473 244 : size_box::~size_box()
474 : {
475 122 : free(size);
476 244 : }
477 :
478 0 : void size_box::debug_print()
479 : {
480 0 : fprintf(stderr, "size %s { ", size);
481 0 : p->debug_print();
482 0 : fprintf(stderr, " }");
483 0 : }
484 :
485 :
486 25 : font_box::font_box(char *s, box *pp) : pointer_box(pp), f(s)
487 : {
488 25 : }
489 :
490 50 : font_box::~font_box()
491 : {
492 25 : free(f);
493 50 : }
494 :
495 25 : int font_box::compute_metrics(int style)
496 : {
497 25 : const char *old_roman_font = current_roman_font;
498 25 : current_roman_font = f;
499 25 : printf(".nr " FONT_FORMAT " \\n[.f]\n", uid);
500 25 : printf(".ft %s\n", f);
501 25 : int r = p->compute_metrics(style);
502 25 : current_roman_font = old_roman_font;
503 25 : printf(".ft \\n[" FONT_FORMAT "]\n", uid);
504 25 : printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid);
505 25 : printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid);
506 25 : printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
507 25 : return r;
508 : }
509 :
510 25 : void font_box::output()
511 : {
512 25 : if (output_format == troff) {
513 25 : printf("\\f[%s]", f);
514 25 : const char *old_roman_font = current_roman_font;
515 25 : current_roman_font = f;
516 25 : p->output();
517 25 : current_roman_font = old_roman_font;
518 25 : printf("\\f[\\n[" FONT_FORMAT "]]", uid);
519 : }
520 0 : else if (output_format == mathml) {
521 0 : const char *mlfont = f;
522 : // bold and italic are already in MathML; translate eqn roman here
523 0 : switch (f[0]) {
524 0 : case 'I':
525 : case 'i':
526 0 : mlfont = "italic";
527 0 : break;
528 0 : case 'B':
529 : case 'b':
530 0 : mlfont = "bold";
531 0 : break;
532 0 : case 'R':
533 : case 'r':
534 : default:
535 0 : mlfont = "normal";
536 0 : break;
537 : }
538 0 : printf("<mstyle mathvariant='%s'>", mlfont);
539 0 : p->output();
540 0 : printf("</mstyle>");
541 : }
542 25 : }
543 :
544 0 : void font_box::debug_print()
545 : {
546 0 : fprintf(stderr, "font %s { ", f);
547 0 : p->debug_print();
548 0 : fprintf(stderr, " }");
549 0 : }
550 :
551 0 : fat_box::fat_box(box *pp) : pointer_box(pp)
552 : {
553 0 : }
554 :
555 0 : int fat_box::compute_metrics(int style)
556 : {
557 0 : int r = p->compute_metrics(style);
558 0 : printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]+%dM\n",
559 0 : uid, p->uid, get_param("fat_offset"));
560 0 : printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid);
561 0 : printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
562 0 : return r;
563 : }
564 :
565 0 : void fat_box::output()
566 : {
567 0 : if (output_format == troff) {
568 0 : p->output();
569 0 : printf("\\h'-\\n[" WIDTH_FORMAT "]u'", p->uid);
570 0 : printf("\\h'%dM'", get_param("fat_offset"));
571 0 : p->output();
572 : }
573 0 : else if (output_format == mathml) {
574 0 : printf("<mstyle mathvariant='double-struck'>");
575 0 : p->output();
576 0 : printf("</mstyle>");
577 : }
578 0 : }
579 :
580 :
581 0 : void fat_box::debug_print()
582 : {
583 0 : fprintf(stderr, "fat { ");
584 0 : p->debug_print();
585 0 : fprintf(stderr, " }");
586 0 : }
587 :
588 :
589 0 : vmotion_box::vmotion_box(int i, box *pp) : pointer_box(pp), n(i)
590 : {
591 0 : }
592 :
593 0 : int vmotion_box::compute_metrics(int style)
594 : {
595 0 : int r = p->compute_metrics(style);
596 0 : printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid);
597 0 : if (n > 0) {
598 0 : printf(".nr " HEIGHT_FORMAT " %dM+\\n[" HEIGHT_FORMAT "]\n",
599 0 : uid, n, p->uid);
600 0 : printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
601 : }
602 : else {
603 0 : printf(".nr " DEPTH_FORMAT " %dM+\\n[" DEPTH_FORMAT "]>?0\n",
604 0 : uid, -n, p->uid);
605 0 : printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n",
606 0 : uid, p->uid);
607 : }
608 0 : return r;
609 : }
610 :
611 0 : void vmotion_box::output()
612 : {
613 0 : if (output_format == troff) {
614 0 : printf("\\v'%dM'", -n);
615 0 : p->output();
616 0 : printf("\\v'%dM'", n);
617 : }
618 0 : else if (output_format == mathml) {
619 0 : printf("<merror>eqn vertical motion cannot be expressed "
620 : "in MathML</merror>");
621 0 : p->output();
622 : }
623 0 : }
624 :
625 0 : void vmotion_box::debug_print()
626 : {
627 0 : if (n >= 0)
628 0 : fprintf(stderr, "up %d { ", n);
629 : else
630 0 : fprintf(stderr, "down %d { ", -n);
631 0 : p->debug_print();
632 0 : fprintf(stderr, " }");
633 0 : }
634 :
635 0 : hmotion_box::hmotion_box(int i, box *pp) : pointer_box(pp), n(i)
636 : {
637 0 : }
638 :
639 0 : int hmotion_box::compute_metrics(int style)
640 : {
641 0 : int r = p->compute_metrics(style);
642 0 : printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]+%dM\n",
643 0 : uid, p->uid, n);
644 0 : printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid);
645 0 : printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
646 0 : if (r)
647 0 : printf(".nr " MARK_REG " +%dM\n", n);
648 0 : return r;
649 : }
650 :
651 0 : void hmotion_box::output()
652 : {
653 0 : if (output_format == troff) {
654 0 : printf("\\h'%dM'", n);
655 0 : p->output();
656 : }
657 0 : else if (output_format == mathml) {
658 0 : printf("<merror>eqn horizontal motion cannot be expressed "
659 : "in MathML</merror>");
660 0 : p->output();
661 : }
662 0 : }
663 :
664 0 : void hmotion_box::debug_print()
665 : {
666 0 : if (n >= 0)
667 0 : fprintf(stderr, "fwd %d { ", n);
668 : else
669 0 : fprintf(stderr, "back %d { ", -n);
670 0 : p->debug_print();
671 0 : fprintf(stderr, " }");
672 0 : }
673 :
674 16 : vcenter_box::vcenter_box(box *pp) : pointer_box(pp)
675 : {
676 16 : }
677 :
678 16 : int vcenter_box::compute_metrics(int style)
679 : {
680 16 : int r = p->compute_metrics(style);
681 16 : printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid);
682 16 : printf(".nr " SUP_RAISE_FORMAT " \\n[" DEPTH_FORMAT "]-\\n["
683 : HEIGHT_FORMAT "]/2+%dM\n",
684 16 : uid, p->uid, p->uid, get_param("axis_height"));
685 16 : printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]+\\n["
686 16 : SUP_RAISE_FORMAT "]>?0\n", uid, p->uid, uid);
687 16 : printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]-\\n["
688 16 : SUP_RAISE_FORMAT "]>?0\n", uid, p->uid, uid);
689 :
690 16 : return r;
691 : }
692 :
693 16 : void vcenter_box::output()
694 : {
695 16 : if (output_format == troff)
696 16 : printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
697 16 : p->output();
698 16 : if (output_format == troff)
699 16 : printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
700 16 : }
701 :
702 0 : void vcenter_box::debug_print()
703 : {
704 0 : fprintf(stderr, "vcenter { ");
705 0 : p->debug_print();
706 0 : fprintf(stderr, " }");
707 0 : }
708 :
709 : // Local Variables:
710 : // fill-column: 72
711 : // mode: C++
712 : // End:
713 : // vim: set cindent noexpandtab shiftwidth=2 textwidth=72:
|