xref: /netbsd-src/external/gpl2/groff/dist/src/preproc/eqn/over.cpp (revision 89a07cf815a29524268025a1139fac4c5190f765)
1 /*	$NetBSD: over.cpp,v 1.1.1.1 2016/01/13 18:41:49 christos Exp $	*/
2 
3 // -*- C++ -*-
4 /* Copyright (C) 1989, 1990, 1991, 1992, 2001, 2002
5    Free Software Foundation, Inc.
6      Written by James Clark (jjc@jclark.com)
7 
8 This file is part of groff.
9 
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
13 version.
14 
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
18 for more details.
19 
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. */
23 
24 #include "eqn.h"
25 #include "pbox.h"
26 
27 class over_box : public box {
28 private:
29   int reduce_size;
30   box *num;
31   box *den;
32 public:
33   over_box(int small, box *, box *);
34   ~over_box();
35   void debug_print();
36   int compute_metrics(int);
37   void output();
38   void check_tabs(int);
39 };
40 
make_over_box(box * pp,box * qq)41 box *make_over_box(box *pp, box *qq)
42 {
43   return new over_box(0, pp, qq);
44 }
45 
make_small_over_box(box * pp,box * qq)46 box *make_small_over_box(box *pp, box *qq)
47 {
48   return new over_box(1, pp, qq);
49 }
50 
over_box(int is_small,box * pp,box * qq)51 over_box::over_box(int is_small, box *pp, box *qq)
52 : reduce_size(is_small), num(pp), den(qq)
53 {
54   spacing_type = INNER_TYPE;
55 }
56 
~over_box()57 over_box::~over_box()
58 {
59   delete num;
60   delete den;
61 }
62 
compute_metrics(int style)63 int over_box::compute_metrics(int style)
64 {
65   if (reduce_size) {
66     style = script_style(style);
67     printf(".nr " SIZE_FORMAT " \\n[.ps]\n", uid);
68     set_script_size();
69     printf(".nr " SMALL_SIZE_FORMAT " \\n[.ps]\n", uid);
70   }
71   int mark_uid = 0;
72   int res = num->compute_metrics(style);
73   if (res)
74     mark_uid = num->uid;
75   int r = den->compute_metrics(cramped_style(style));
76   if (r && res)
77     error("multiple marks and lineups");
78   else {
79     mark_uid = den->uid;
80     res = r;
81   }
82   if (reduce_size)
83     printf(".ps \\n[" SIZE_FORMAT "]u\n", uid);
84   printf(".nr " WIDTH_FORMAT " (\\n[" WIDTH_FORMAT "]>?\\n[" WIDTH_FORMAT "]",
85 	 uid, num->uid, den->uid);
86   // allow for \(ru being wider than both the numerator and denominator
87   if (!draw_flag)
88     fputs(">?\\w" DELIMITER_CHAR "\\(ru" DELIMITER_CHAR, stdout);
89   printf(")+%dM\n", null_delimiter_space*2 + over_hang*2);
90   // 15b
91   printf(".nr " SUP_RAISE_FORMAT " %dM\n",
92 	 uid, (reduce_size ? num2 : num1));
93   printf(".nr " SUB_LOWER_FORMAT " %dM\n",
94 	 uid, (reduce_size ? denom2 : denom1));
95 
96   // 15d
97   printf(".nr " SUP_RAISE_FORMAT " +(\\n[" DEPTH_FORMAT
98 	 "]-\\n[" SUP_RAISE_FORMAT "]+%dM+(%dM/2)+%dM)>?0\n",
99 	 uid, num->uid, uid, axis_height, default_rule_thickness,
100 	 default_rule_thickness*(reduce_size ? 1 : 3));
101   printf(".nr " SUB_LOWER_FORMAT " +(\\n[" HEIGHT_FORMAT
102 	 "]-\\n[" SUB_LOWER_FORMAT "]-%dM+(%dM/2)+%dM)>?0\n",
103 	 uid, den->uid, uid, axis_height, default_rule_thickness,
104 	 default_rule_thickness*(reduce_size ? 1 : 3));
105 
106 
107   printf(".nr " HEIGHT_FORMAT " \\n[" SUP_RAISE_FORMAT "]+\\n["
108 	 HEIGHT_FORMAT "]\n",
109 	 uid, uid, num->uid);
110   printf(".nr " DEPTH_FORMAT " \\n[" SUB_LOWER_FORMAT "]+\\n["
111 	 DEPTH_FORMAT "]\n",
112 	 uid, uid, den->uid);
113   if (res)
114     printf(".nr " MARK_REG " +(\\n[" WIDTH_FORMAT "]-\\n["
115 	   WIDTH_FORMAT "]/2)\n", uid, mark_uid);
116   return res;
117 }
118 
119 #define USE_Z
120 
output()121 void over_box::output()
122 {
123   if (reduce_size)
124     printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
125 #ifdef USE_Z
126   printf("\\Z" DELIMITER_CHAR);
127 #endif
128   // move up to the numerator baseline
129   printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
130   // move across so that it's centered
131   printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
132 	 uid, num->uid);
133 
134   // print the numerator
135   num->output();
136 
137 #ifdef USE_Z
138   printf(DELIMITER_CHAR);
139 #else
140   // back again
141   printf("\\h'-\\n[" WIDTH_FORMAT "]u'", num->uid);
142   printf("\\h'-(\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u)'",
143 	 uid, num->uid);
144   // down again
145   printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
146 #endif
147 #ifdef USE_Z
148   printf("\\Z" DELIMITER_CHAR);
149 #endif
150   // move down to the denominator baseline
151   printf("\\v'\\n[" SUB_LOWER_FORMAT "]u'", uid);
152 
153   // move across so that it's centered
154   printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
155 	 uid, den->uid);
156 
157   // print the the denominator
158   den->output();
159 
160 #ifdef USE_Z
161   printf(DELIMITER_CHAR);
162 #else
163   // back again
164   printf("\\h'-\\n[" WIDTH_FORMAT "]u'", den->uid);
165   printf("\\h'-(\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u)'",
166 	 uid, den->uid);
167   // up again
168   printf("\\v'-\\n[" SUB_LOWER_FORMAT "]u'", uid);
169 #endif
170   if (reduce_size)
171     printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
172   // draw the line
173   printf("\\h'%dM'", null_delimiter_space);
174   printf("\\v'-%dM'", axis_height);
175   fputs(draw_flag ? "\\D'l" : "\\l'", stdout);
176   printf("\\n[" WIDTH_FORMAT "]u-%dM",
177 	 uid, 2*null_delimiter_space);
178   fputs(draw_flag ? " 0'" : "\\&\\(ru'", stdout);
179   printf("\\v'%dM'", axis_height);
180   printf("\\h'%dM'", null_delimiter_space);
181 }
182 
debug_print()183 void over_box::debug_print()
184 {
185   fprintf(stderr, "{ ");
186   num->debug_print();
187   if (reduce_size)
188     fprintf(stderr, " } smallover { ");
189   else
190     fprintf(stderr, " } over { ");
191   den->debug_print();
192   fprintf(stderr, " }");
193 }
194 
check_tabs(int level)195 void over_box::check_tabs(int level)
196 {
197   num->check_tabs(level + 1);
198   den->check_tabs(level + 1);
199 }
200