PageRenderTime 46ms CodeModel.GetById 2ms app.highlight 40ms RepoModel.GetById 1ms app.codeStats 0ms

/contrib/groff/src/preproc/eqn/other.cpp

https://bitbucket.org/freebsd/freebsd-head/
C++ | 601 lines | 499 code | 75 blank | 27 comment | 11 complexity | 106f6386de855514a8f2717353525ade MD5 | raw file
  1// -*- C++ -*-
  2/* Copyright (C) 1989, 1990, 1991, 1992, 2002 Free Software Foundation, Inc.
  3     Written by James Clark (jjc@jclark.com)
  4
  5This file is part of groff.
  6
  7groff is free software; you can redistribute it and/or modify it under
  8the terms of the GNU General Public License as published by the Free
  9Software Foundation; either version 2, or (at your option) any later
 10version.
 11
 12groff is distributed in the hope that it will be useful, but WITHOUT ANY
 13WARRANTY; without even the implied warranty of MERCHANTABILITY or
 14FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 15for more details.
 16
 17You should have received a copy of the GNU General Public License along
 18with groff; see the file COPYING.  If not, write to the Free Software
 19Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
 20
 21#include "eqn.h"
 22#include "pbox.h"
 23
 24class accent_box : public pointer_box {
 25private:
 26  box *ab;
 27public:
 28  accent_box(box *, box *);
 29  ~accent_box();
 30  int compute_metrics(int);
 31  void output();
 32  void debug_print();
 33  void check_tabs(int);
 34};
 35
 36box *make_accent_box(box *p, box *q)
 37{
 38  return new accent_box(p, q);
 39}
 40
 41accent_box::accent_box(box *pp, box *qq) : pointer_box(pp), ab(qq)
 42{
 43}
 44
 45accent_box::~accent_box()
 46{
 47  delete ab;
 48}
 49
 50#if 0
 51int accent_box::compute_metrics(int style)
 52{
 53  int r = p->compute_metrics(style);
 54  p->compute_skew();
 55  ab->compute_metrics(style);
 56  printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid);
 57  printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
 58  printf(".nr " SUP_RAISE_FORMAT " \\n[" HEIGHT_FORMAT "]-%dM>?0\n",
 59	 uid, p->uid, x_height);
 60  printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]+\\n["
 61	 SUP_RAISE_FORMAT "]\n",
 62	 uid, ab->uid, uid);
 63  return r;
 64}
 65
 66void accent_box::output()
 67{
 68  printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u+\\n["
 69	 SKEW_FORMAT "]u'",
 70	 p->uid, ab->uid, p->uid);
 71  printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid); 
 72  ab->output();
 73  printf("\\h'-\\n[" WIDTH_FORMAT "]u'", ab->uid);
 74  printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
 75  printf("\\h'-(\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u+\\n["
 76	 SKEW_FORMAT "]u)'",
 77	 p->uid, ab->uid, p->uid);
 78  p->output();
 79}
 80#endif
 81
 82/* This version copes with the possibility of an accent's being wider
 83than its accentee.  LEFT_WIDTH_FORMAT gives the distance from the
 84left edge of the resulting box to the middle of the accentee's box.*/
 85
 86int accent_box::compute_metrics(int style)
 87{
 88  int r = p->compute_metrics(style);
 89  p->compute_skew();
 90  ab->compute_metrics(style);
 91  printf(".nr " LEFT_WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]/2"
 92	 ">?(\\n[" WIDTH_FORMAT "]/2-\\n[" SKEW_FORMAT "])\n",
 93	 uid, p->uid, ab->uid, p->uid);
 94  printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]/2"
 95	 ">?(\\n[" WIDTH_FORMAT "]/2+\\n[" SKEW_FORMAT "])"
 96	 "+\\n[" LEFT_WIDTH_FORMAT "]\n",
 97	 uid, p->uid, ab->uid, p->uid, uid);
 98  printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
 99  printf(".nr " SUP_RAISE_FORMAT " \\n[" HEIGHT_FORMAT "]-%dM>?0\n",
100	 uid, p->uid, x_height);
101  printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]+\\n["
102	 SUP_RAISE_FORMAT "]\n",
103	 uid, ab->uid, uid);
104  if (r)
105    printf(".nr " MARK_REG " +\\n[" LEFT_WIDTH_FORMAT "]"
106	   "-(\\n[" WIDTH_FORMAT "]/2)'\n",
107	   uid, p->uid);
108  return r;
109}
110
111void accent_box::output()
112{
113  printf("\\Z" DELIMITER_CHAR);
114  printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u+\\n[" SKEW_FORMAT "]u"
115	 "-(\\n[" WIDTH_FORMAT "]u/2u)'",
116	 uid, p->uid, ab->uid);
117  printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid); 
118  ab->output();
119  printf(DELIMITER_CHAR);
120  printf("\\Z" DELIMITER_CHAR);
121  printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u-(\\n[" WIDTH_FORMAT "]u/2u)'",
122	 uid, p->uid);
123  p->output();
124  printf(DELIMITER_CHAR);
125  printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
126}
127
128void accent_box::check_tabs(int level)
129{
130  ab->check_tabs(level + 1);
131  p->check_tabs(level + 1);
132}
133
134void accent_box::debug_print()
135{
136  fprintf(stderr, "{ ");
137  p->debug_print();
138  fprintf(stderr, " } accent { ");
139  ab->debug_print();
140  fprintf(stderr, " }");
141}
142
143class overline_char_box : public simple_box {
144public:
145  overline_char_box();
146  void output();
147  void debug_print();
148};
149
150overline_char_box::overline_char_box()
151{
152}
153
154void overline_char_box::output()
155{
156  printf("\\v'-%dM/2u-%dM'", 7*default_rule_thickness, x_height);
157  printf((draw_flag ? "\\D'l%dM 0'" : "\\l'%dM\\&\\(ru'"),
158	 accent_width);
159  printf("\\v'%dM/2u+%dM'", 7*default_rule_thickness, x_height);
160}
161
162void overline_char_box::debug_print()
163{
164  fprintf(stderr, "<overline char>");
165}
166
167class overline_box : public pointer_box {
168public:
169  overline_box(box *);
170  int compute_metrics(int);
171  void output();
172  void debug_print();
173};
174
175box *make_overline_box(box *p)
176{
177  if (p->is_char())
178    return new accent_box(p, new overline_char_box);
179  else
180    return new overline_box(p);
181}
182
183overline_box::overline_box(box *pp) : pointer_box(pp)
184{
185}
186
187int overline_box::compute_metrics(int style)
188{
189  int r = p->compute_metrics(cramped_style(style));
190  // 9
191  printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]+%dM\n",
192	 uid, p->uid, default_rule_thickness*5);
193  printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid);
194  printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
195  return r;
196}
197
198void overline_box::output()
199{
200  // 9
201  printf("\\Z" DELIMITER_CHAR);
202  printf("\\v'-\\n[" HEIGHT_FORMAT "]u-(%dM/2u)'",
203	 p->uid, 7*default_rule_thickness);
204  if (draw_flag)
205    printf("\\D'l\\n[" WIDTH_FORMAT "]u 0'", p->uid);
206  else
207    printf("\\l'\\n[" WIDTH_FORMAT "]u\\&\\(ru'", p->uid);
208  printf(DELIMITER_CHAR);
209  p->output();
210}
211
212void overline_box::debug_print()
213{
214  fprintf(stderr, "{ ");
215  p->debug_print();
216  fprintf(stderr, " } bar");
217}
218
219class uaccent_box : public pointer_box {
220  box *ab;
221public:
222  uaccent_box(box *, box *);
223  ~uaccent_box();
224  int compute_metrics(int);
225  void output();
226  void compute_subscript_kern();
227  void check_tabs(int);
228  void debug_print();
229};
230
231box *make_uaccent_box(box *p, box *q)
232{
233  return new uaccent_box(p, q);
234}
235
236uaccent_box::uaccent_box(box *pp, box *qq)
237: pointer_box(pp), ab(qq)
238{
239}
240
241uaccent_box::~uaccent_box()
242{
243  delete ab;
244}
245
246int uaccent_box::compute_metrics(int style)
247{
248  int r = p->compute_metrics(style);
249  ab->compute_metrics(style);
250  printf(".nr " LEFT_WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]/2"
251	 ">?(\\n[" WIDTH_FORMAT "]/2)\n",
252	 uid, p->uid, ab->uid);
253  printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]/2"
254	 ">?(\\n[" WIDTH_FORMAT "]/2)"
255	 "+\\n[" LEFT_WIDTH_FORMAT "]\n",
256	 uid, p->uid, ab->uid, uid);
257  printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid);
258  printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]"
259	 "+\\n[" DEPTH_FORMAT "]\n",
260	 uid, p->uid, ab->uid);
261  if (r)
262    printf(".nr " MARK_REG " +\\n[" LEFT_WIDTH_FORMAT "]"
263	   "-(\\n[" WIDTH_FORMAT "]/2)'\n",
264	   uid, p->uid);
265  return r;
266}
267
268void uaccent_box::output()
269{
270  printf("\\Z" DELIMITER_CHAR);
271  printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u-(\\n[" WIDTH_FORMAT "]u/2u)'",
272	 uid, ab->uid);
273  printf("\\v'\\n[" DEPTH_FORMAT "]u'", p->uid); 
274  ab->output();
275  printf(DELIMITER_CHAR);
276  printf("\\Z" DELIMITER_CHAR);
277  printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u-(\\n[" WIDTH_FORMAT "]u/2u)'",
278	 uid, p->uid);
279  p->output();
280  printf(DELIMITER_CHAR);
281  printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
282}
283
284void uaccent_box::check_tabs(int level)
285{
286  ab->check_tabs(level + 1);
287  p->check_tabs(level + 1);
288}
289
290void uaccent_box::compute_subscript_kern()
291{
292  box::compute_subscript_kern(); // want 0 subscript kern
293}
294
295void uaccent_box::debug_print()
296{
297  fprintf(stderr, "{ ");
298  p->debug_print();
299  fprintf(stderr, " } uaccent { ");
300  ab->debug_print();
301  fprintf(stderr, " }");
302}
303
304class underline_char_box : public simple_box {
305public:
306  underline_char_box();
307  void output();
308  void debug_print();
309};
310
311underline_char_box::underline_char_box()
312{
313}
314
315void underline_char_box::output()
316{
317  printf("\\v'%dM/2u'", 7*default_rule_thickness);
318  printf((draw_flag ? "\\D'l%dM 0'" : "\\l'%dM\\&\\(ru'"),
319	 accent_width);
320  printf("\\v'-%dM/2u'", 7*default_rule_thickness);
321}
322
323void underline_char_box::debug_print()
324{
325  fprintf(stderr, "<underline char>");
326}
327
328
329class underline_box : public pointer_box {
330public:
331  underline_box(box *);
332  int compute_metrics(int);
333  void output();
334  void compute_subscript_kern();
335  void debug_print();
336};
337
338box *make_underline_box(box *p)
339{
340  if (p->is_char())
341    return new uaccent_box(p, new underline_char_box);
342  else
343    return new underline_box(p);
344}
345
346underline_box::underline_box(box *pp) : pointer_box(pp)
347{
348}
349
350int underline_box::compute_metrics(int style)
351{
352  int r = p->compute_metrics(style);
353  // 10
354  printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]+%dM\n",
355	 uid, p->uid, default_rule_thickness*5);
356  printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid);
357  printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid);
358  return r;
359}
360
361void underline_box::output()
362{
363  // 10
364  printf("\\Z" DELIMITER_CHAR);
365  printf("\\v'\\n[" DEPTH_FORMAT "]u+(%dM/2u)'",
366	 p->uid, 7*default_rule_thickness);
367  if (draw_flag)
368    printf("\\D'l\\n[" WIDTH_FORMAT "]u 0'", p->uid);
369  else
370    printf("\\l'\\n[" WIDTH_FORMAT "]u\\&\\(ru'", p->uid);
371  printf(DELIMITER_CHAR);
372  p->output();
373}
374
375// we want an underline box to have 0 subscript kern
376
377void underline_box::compute_subscript_kern()
378{
379  box::compute_subscript_kern();
380}
381
382void underline_box::debug_print()
383{
384  fprintf(stderr, "{ ");
385  p->debug_print();
386  fprintf(stderr, " } under");
387}
388
389size_box::size_box(char *s, box *pp) : pointer_box(pp), size(s)
390{
391}
392
393int size_box::compute_metrics(int style)
394{
395  printf(".nr " SIZE_FORMAT " \\n[.ps]\n", uid);
396  printf(".ps %s\n", size);
397  printf(".nr " SMALL_SIZE_FORMAT " \\n[.ps]\n", uid);
398  int r = p->compute_metrics(style);
399  printf(".ps \\n[" SIZE_FORMAT "]u\n", uid);
400  printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid);
401  printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid);
402  printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
403  return r;
404}
405
406void size_box::output()
407{
408  printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
409  p->output();
410  printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
411}
412
413size_box::~size_box()
414{
415  a_delete size;
416}
417
418void size_box::debug_print()
419{
420  fprintf(stderr, "size %s { ", size);
421  p->debug_print();
422  fprintf(stderr, " }");
423}
424
425
426font_box::font_box(char *s, box *pp) : pointer_box(pp), f(s)
427{
428}
429
430font_box::~font_box()
431{
432  a_delete f;
433}
434
435int font_box::compute_metrics(int style)
436{
437  const char *old_roman_font = current_roman_font;
438  current_roman_font = f;
439  printf(".nr " FONT_FORMAT " \\n[.f]\n", uid);
440  printf(".ft %s\n", f);
441  int r = p->compute_metrics(style);
442  current_roman_font = old_roman_font;
443  printf(".ft \\n[" FONT_FORMAT "]\n", uid);
444  printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid);
445  printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid);
446  printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
447  return r;
448}
449
450void font_box::output()
451{
452  printf("\\f[%s]", f);
453  const char *old_roman_font = current_roman_font;
454  current_roman_font = f;
455  p->output();
456  current_roman_font = old_roman_font;
457  printf("\\f[\\n[" FONT_FORMAT "]]", uid);
458}
459
460void font_box::debug_print()
461{
462  fprintf(stderr, "font %s { ", f);
463  p->debug_print();
464  fprintf(stderr, " }");
465}
466
467fat_box::fat_box(box *pp) : pointer_box(pp)
468{
469}
470
471int fat_box::compute_metrics(int style)
472{
473  int r = p->compute_metrics(style);
474  printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]+%dM\n",
475	 uid, p->uid, fat_offset);
476  printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid);
477  printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
478  return r;
479}
480
481void fat_box::output()
482{
483  p->output();
484  printf("\\h'-\\n[" WIDTH_FORMAT "]u'", p->uid);
485  printf("\\h'%dM'", fat_offset);
486  p->output();
487}
488
489
490void fat_box::debug_print()
491{
492  fprintf(stderr, "fat { ");
493  p->debug_print();
494  fprintf(stderr, " }");
495}
496
497
498vmotion_box::vmotion_box(int i, box *pp) : pointer_box(pp), n(i)
499{
500}
501
502int vmotion_box::compute_metrics(int style)
503{
504  int r = p->compute_metrics(style);
505  printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid);
506  if (n > 0) {
507    printf(".nr " HEIGHT_FORMAT " %dM+\\n[" HEIGHT_FORMAT "]\n",
508	   uid, n, p->uid);
509    printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
510  }
511  else {
512    printf(".nr " DEPTH_FORMAT " %dM+\\n[" DEPTH_FORMAT "]>?0\n",
513	   uid, -n, p->uid);
514    printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n",
515	   uid, p->uid);
516  }
517  return r;
518}
519
520void vmotion_box::output()
521{
522  printf("\\v'%dM'", -n);
523  p->output();
524  printf("\\v'%dM'", n);
525}
526
527void vmotion_box::debug_print()
528{
529  if (n >= 0)
530    fprintf(stderr, "up %d { ", n);
531  else
532    fprintf(stderr, "down %d { ", -n);
533  p->debug_print();
534  fprintf(stderr, " }");
535}
536
537hmotion_box::hmotion_box(int i, box *pp) : pointer_box(pp), n(i)
538{
539}
540
541int hmotion_box::compute_metrics(int style)
542{
543  int r = p->compute_metrics(style);
544  printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]+%dM\n",
545	 uid, p->uid, n);
546  printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid);
547  printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
548  if (r)
549    printf(".nr " MARK_REG " +%dM\n", n);
550  return r;
551}
552
553void hmotion_box::output()
554{
555  printf("\\h'%dM'", n);
556  p->output();
557}
558
559void hmotion_box::debug_print()
560{
561  if (n >= 0)
562    fprintf(stderr, "fwd %d { ", n);
563  else
564    fprintf(stderr, "back %d { ", -n);
565  p->debug_print();
566  fprintf(stderr, " }");
567}
568
569vcenter_box::vcenter_box(box *pp) : pointer_box(pp)
570{
571}
572
573int vcenter_box::compute_metrics(int style)
574{
575  int r = p->compute_metrics(style);
576  printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid);
577  printf(".nr " SUP_RAISE_FORMAT " \\n[" DEPTH_FORMAT "]-\\n["
578	 HEIGHT_FORMAT "]/2+%dM\n",
579	 uid, p->uid, p->uid, axis_height);
580  printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]+\\n["
581	 SUP_RAISE_FORMAT "]>?0\n", uid, p->uid, uid);
582  printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]-\\n["
583	 SUP_RAISE_FORMAT "]>?0\n", uid, p->uid, uid);
584
585  return r;
586}
587
588void vcenter_box::output()
589{
590  printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
591  p->output();
592  printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
593}
594
595void vcenter_box::debug_print()
596{
597  fprintf(stderr, "vcenter { ");
598  p->debug_print();
599  fprintf(stderr, " }");
600}
601