xref: /netbsd-src/external/gpl2/groff/dist/src/preproc/eqn/other.cpp (revision 89a07cf815a29524268025a1139fac4c5190f765)
1 /*	$NetBSD: other.cpp,v 1.1.1.1 2016/01/13 18:41:49 christos Exp $	*/
2 
3 // -*- C++ -*-
4 /* Copyright (C) 1989, 1990, 1991, 1992, 2002 Free Software Foundation, Inc.
5      Written by James Clark (jjc@jclark.com)
6 
7 This file is part of groff.
8 
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
12 version.
13 
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
17 for more details.
18 
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. */
22 
23 #include "eqn.h"
24 #include "pbox.h"
25 
26 class accent_box : public pointer_box {
27 private:
28   box *ab;
29 public:
30   accent_box(box *, box *);
31   ~accent_box();
32   int compute_metrics(int);
33   void output();
34   void debug_print();
35   void check_tabs(int);
36 };
37 
make_accent_box(box * p,box * q)38 box *make_accent_box(box *p, box *q)
39 {
40   return new accent_box(p, q);
41 }
42 
accent_box(box * pp,box * qq)43 accent_box::accent_box(box *pp, box *qq) : pointer_box(pp), ab(qq)
44 {
45 }
46 
~accent_box()47 accent_box::~accent_box()
48 {
49   delete ab;
50 }
51 
52 #if 0
53 int accent_box::compute_metrics(int style)
54 {
55   int r = p->compute_metrics(style);
56   p->compute_skew();
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",
64 	 uid, ab->uid, uid);
65   return r;
66 }
67 
68 void accent_box::output()
69 {
70   printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u+\\n["
71 	 SKEW_FORMAT "]u'",
72 	 p->uid, ab->uid, p->uid);
73   printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
74   ab->output();
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["
78 	 SKEW_FORMAT "]u)'",
79 	 p->uid, ab->uid, p->uid);
80   p->output();
81 }
82 #endif
83 
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.*/
87 
compute_metrics(int style)88 int accent_box::compute_metrics(int style)
89 {
90   int r = p->compute_metrics(style);
91   p->compute_skew();
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",
105 	 uid, ab->uid, uid);
106   if (r)
107     printf(".nr " MARK_REG " +\\n[" LEFT_WIDTH_FORMAT "]"
108 	   "-(\\n[" WIDTH_FORMAT "]/2)'\n",
109 	   uid, p->uid);
110   return r;
111 }
112 
output()113 void accent_box::output()
114 {
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);
120   ab->output();
121   printf(DELIMITER_CHAR);
122   printf("\\Z" DELIMITER_CHAR);
123   printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u-(\\n[" WIDTH_FORMAT "]u/2u)'",
124 	 uid, p->uid);
125   p->output();
126   printf(DELIMITER_CHAR);
127   printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
128 }
129 
check_tabs(int level)130 void accent_box::check_tabs(int level)
131 {
132   ab->check_tabs(level + 1);
133   p->check_tabs(level + 1);
134 }
135 
debug_print()136 void accent_box::debug_print()
137 {
138   fprintf(stderr, "{ ");
139   p->debug_print();
140   fprintf(stderr, " } accent { ");
141   ab->debug_print();
142   fprintf(stderr, " }");
143 }
144 
145 class overline_char_box : public simple_box {
146 public:
147   overline_char_box();
148   void output();
149   void debug_print();
150 };
151 
overline_char_box()152 overline_char_box::overline_char_box()
153 {
154 }
155 
output()156 void overline_char_box::output()
157 {
158   printf("\\v'-%dM/2u-%dM'", 7*default_rule_thickness, x_height);
159   printf((draw_flag ? "\\D'l%dM 0'" : "\\l'%dM\\&\\(ru'"),
160 	 accent_width);
161   printf("\\v'%dM/2u+%dM'", 7*default_rule_thickness, x_height);
162 }
163 
debug_print()164 void overline_char_box::debug_print()
165 {
166   fprintf(stderr, "<overline char>");
167 }
168 
169 class overline_box : public pointer_box {
170 public:
171   overline_box(box *);
172   int compute_metrics(int);
173   void output();
174   void debug_print();
175 };
176 
make_overline_box(box * p)177 box *make_overline_box(box *p)
178 {
179   if (p->is_char())
180     return new accent_box(p, new overline_char_box);
181   else
182     return new overline_box(p);
183 }
184 
overline_box(box * pp)185 overline_box::overline_box(box *pp) : pointer_box(pp)
186 {
187 }
188 
compute_metrics(int style)189 int overline_box::compute_metrics(int style)
190 {
191   int r = p->compute_metrics(cramped_style(style));
192   // 9
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);
197   return r;
198 }
199 
output()200 void overline_box::output()
201 {
202   // 9
203   printf("\\Z" DELIMITER_CHAR);
204   printf("\\v'-\\n[" HEIGHT_FORMAT "]u-(%dM/2u)'",
205 	 p->uid, 7*default_rule_thickness);
206   if (draw_flag)
207     printf("\\D'l\\n[" WIDTH_FORMAT "]u 0'", p->uid);
208   else
209     printf("\\l'\\n[" WIDTH_FORMAT "]u\\&\\(ru'", p->uid);
210   printf(DELIMITER_CHAR);
211   p->output();
212 }
213 
debug_print()214 void overline_box::debug_print()
215 {
216   fprintf(stderr, "{ ");
217   p->debug_print();
218   fprintf(stderr, " } bar");
219 }
220 
221 class uaccent_box : public pointer_box {
222   box *ab;
223 public:
224   uaccent_box(box *, box *);
225   ~uaccent_box();
226   int compute_metrics(int);
227   void output();
228   void compute_subscript_kern();
229   void check_tabs(int);
230   void debug_print();
231 };
232 
make_uaccent_box(box * p,box * q)233 box *make_uaccent_box(box *p, box *q)
234 {
235   return new uaccent_box(p, q);
236 }
237 
uaccent_box(box * pp,box * qq)238 uaccent_box::uaccent_box(box *pp, box *qq)
239 : pointer_box(pp), ab(qq)
240 {
241 }
242 
~uaccent_box()243 uaccent_box::~uaccent_box()
244 {
245   delete ab;
246 }
247 
compute_metrics(int style)248 int uaccent_box::compute_metrics(int style)
249 {
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);
263   if (r)
264     printf(".nr " MARK_REG " +\\n[" LEFT_WIDTH_FORMAT "]"
265 	   "-(\\n[" WIDTH_FORMAT "]/2)'\n",
266 	   uid, p->uid);
267   return r;
268 }
269 
output()270 void uaccent_box::output()
271 {
272   printf("\\Z" DELIMITER_CHAR);
273   printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u-(\\n[" WIDTH_FORMAT "]u/2u)'",
274 	 uid, ab->uid);
275   printf("\\v'\\n[" DEPTH_FORMAT "]u'", p->uid);
276   ab->output();
277   printf(DELIMITER_CHAR);
278   printf("\\Z" DELIMITER_CHAR);
279   printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u-(\\n[" WIDTH_FORMAT "]u/2u)'",
280 	 uid, p->uid);
281   p->output();
282   printf(DELIMITER_CHAR);
283   printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
284 }
285 
check_tabs(int level)286 void uaccent_box::check_tabs(int level)
287 {
288   ab->check_tabs(level + 1);
289   p->check_tabs(level + 1);
290 }
291 
compute_subscript_kern()292 void uaccent_box::compute_subscript_kern()
293 {
294   box::compute_subscript_kern(); // want 0 subscript kern
295 }
296 
debug_print()297 void uaccent_box::debug_print()
298 {
299   fprintf(stderr, "{ ");
300   p->debug_print();
301   fprintf(stderr, " } uaccent { ");
302   ab->debug_print();
303   fprintf(stderr, " }");
304 }
305 
306 class underline_char_box : public simple_box {
307 public:
308   underline_char_box();
309   void output();
310   void debug_print();
311 };
312 
underline_char_box()313 underline_char_box::underline_char_box()
314 {
315 }
316 
output()317 void underline_char_box::output()
318 {
319   printf("\\v'%dM/2u'", 7*default_rule_thickness);
320   printf((draw_flag ? "\\D'l%dM 0'" : "\\l'%dM\\&\\(ru'"),
321 	 accent_width);
322   printf("\\v'-%dM/2u'", 7*default_rule_thickness);
323 }
324 
debug_print()325 void underline_char_box::debug_print()
326 {
327   fprintf(stderr, "<underline char>");
328 }
329 
330 
331 class underline_box : public pointer_box {
332 public:
333   underline_box(box *);
334   int compute_metrics(int);
335   void output();
336   void compute_subscript_kern();
337   void debug_print();
338 };
339 
make_underline_box(box * p)340 box *make_underline_box(box *p)
341 {
342   if (p->is_char())
343     return new uaccent_box(p, new underline_char_box);
344   else
345     return new underline_box(p);
346 }
347 
underline_box(box * pp)348 underline_box::underline_box(box *pp) : pointer_box(pp)
349 {
350 }
351 
compute_metrics(int style)352 int underline_box::compute_metrics(int style)
353 {
354   int r = p->compute_metrics(style);
355   // 10
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);
360   return r;
361 }
362 
output()363 void underline_box::output()
364 {
365   // 10
366   printf("\\Z" DELIMITER_CHAR);
367   printf("\\v'\\n[" DEPTH_FORMAT "]u+(%dM/2u)'",
368 	 p->uid, 7*default_rule_thickness);
369   if (draw_flag)
370     printf("\\D'l\\n[" WIDTH_FORMAT "]u 0'", p->uid);
371   else
372     printf("\\l'\\n[" WIDTH_FORMAT "]u\\&\\(ru'", p->uid);
373   printf(DELIMITER_CHAR);
374   p->output();
375 }
376 
377 // we want an underline box to have 0 subscript kern
378 
compute_subscript_kern()379 void underline_box::compute_subscript_kern()
380 {
381   box::compute_subscript_kern();
382 }
383 
debug_print()384 void underline_box::debug_print()
385 {
386   fprintf(stderr, "{ ");
387   p->debug_print();
388   fprintf(stderr, " } under");
389 }
390 
size_box(char * s,box * pp)391 size_box::size_box(char *s, box *pp) : pointer_box(pp), size(s)
392 {
393 }
394 
compute_metrics(int style)395 int size_box::compute_metrics(int style)
396 {
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);
405   return r;
406 }
407 
output()408 void size_box::output()
409 {
410   printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
411   p->output();
412   printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
413 }
414 
~size_box()415 size_box::~size_box()
416 {
417   a_delete size;
418 }
419 
debug_print()420 void size_box::debug_print()
421 {
422   fprintf(stderr, "size %s { ", size);
423   p->debug_print();
424   fprintf(stderr, " }");
425 }
426 
427 
font_box(char * s,box * pp)428 font_box::font_box(char *s, box *pp) : pointer_box(pp), f(s)
429 {
430 }
431 
~font_box()432 font_box::~font_box()
433 {
434   a_delete f;
435 }
436 
compute_metrics(int style)437 int font_box::compute_metrics(int style)
438 {
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);
449   return r;
450 }
451 
output()452 void font_box::output()
453 {
454   printf("\\f[%s]", f);
455   const char *old_roman_font = current_roman_font;
456   current_roman_font = f;
457   p->output();
458   current_roman_font = old_roman_font;
459   printf("\\f[\\n[" FONT_FORMAT "]]", uid);
460 }
461 
debug_print()462 void font_box::debug_print()
463 {
464   fprintf(stderr, "font %s { ", f);
465   p->debug_print();
466   fprintf(stderr, " }");
467 }
468 
fat_box(box * pp)469 fat_box::fat_box(box *pp) : pointer_box(pp)
470 {
471 }
472 
compute_metrics(int style)473 int fat_box::compute_metrics(int style)
474 {
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);
480   return r;
481 }
482 
output()483 void fat_box::output()
484 {
485   p->output();
486   printf("\\h'-\\n[" WIDTH_FORMAT "]u'", p->uid);
487   printf("\\h'%dM'", fat_offset);
488   p->output();
489 }
490 
491 
debug_print()492 void fat_box::debug_print()
493 {
494   fprintf(stderr, "fat { ");
495   p->debug_print();
496   fprintf(stderr, " }");
497 }
498 
499 
vmotion_box(int i,box * pp)500 vmotion_box::vmotion_box(int i, box *pp) : pointer_box(pp), n(i)
501 {
502 }
503 
compute_metrics(int style)504 int vmotion_box::compute_metrics(int style)
505 {
506   int r = p->compute_metrics(style);
507   printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid);
508   if (n > 0) {
509     printf(".nr " HEIGHT_FORMAT " %dM+\\n[" HEIGHT_FORMAT "]\n",
510 	   uid, n, p->uid);
511     printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
512   }
513   else {
514     printf(".nr " DEPTH_FORMAT " %dM+\\n[" DEPTH_FORMAT "]>?0\n",
515 	   uid, -n, p->uid);
516     printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n",
517 	   uid, p->uid);
518   }
519   return r;
520 }
521 
output()522 void vmotion_box::output()
523 {
524   printf("\\v'%dM'", -n);
525   p->output();
526   printf("\\v'%dM'", n);
527 }
528 
debug_print()529 void vmotion_box::debug_print()
530 {
531   if (n >= 0)
532     fprintf(stderr, "up %d { ", n);
533   else
534     fprintf(stderr, "down %d { ", -n);
535   p->debug_print();
536   fprintf(stderr, " }");
537 }
538 
hmotion_box(int i,box * pp)539 hmotion_box::hmotion_box(int i, box *pp) : pointer_box(pp), n(i)
540 {
541 }
542 
compute_metrics(int style)543 int hmotion_box::compute_metrics(int style)
544 {
545   int r = p->compute_metrics(style);
546   printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]+%dM\n",
547 	 uid, p->uid, 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);
550   if (r)
551     printf(".nr " MARK_REG " +%dM\n", n);
552   return r;
553 }
554 
output()555 void hmotion_box::output()
556 {
557   printf("\\h'%dM'", n);
558   p->output();
559 }
560 
debug_print()561 void hmotion_box::debug_print()
562 {
563   if (n >= 0)
564     fprintf(stderr, "fwd %d { ", n);
565   else
566     fprintf(stderr, "back %d { ", -n);
567   p->debug_print();
568   fprintf(stderr, " }");
569 }
570 
vcenter_box(box * pp)571 vcenter_box::vcenter_box(box *pp) : pointer_box(pp)
572 {
573 }
574 
compute_metrics(int style)575 int vcenter_box::compute_metrics(int style)
576 {
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);
586 
587   return r;
588 }
589 
output()590 void vcenter_box::output()
591 {
592   printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
593   p->output();
594   printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
595 }
596 
debug_print()597 void vcenter_box::debug_print()
598 {
599   fprintf(stderr, "vcenter { ");
600   p->debug_print();
601   fprintf(stderr, " }");
602 }
603 
604