Sync-to-go: update copyright for 2015
[s-roff.git] / src / pre-eqn / over.cpp
blob518de73d571f73f3beb2088c83cbfc49bdb39adf
1 /*@
2 * Copyright (c) 2014 - 2015 Steffen (Daode) Nurpmeso <sdaoden@users.sf.net>.
4 * Copyright (C) 1989 - 1992, 2001, 2002, 2007
5 * Free Software Foundation, Inc.
6 * Written by James Clark (jjc@jclark.com)
8 * This is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2, or (at your option) any later
11 * version.
13 * This is distributed in the hope that it will be useful, but WITHOUT ANY
14 * WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with groff; see the file COPYING. If not, write to the Free Software
20 * Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA.
23 #include "config.h"
24 #include "eqn-config.h"
26 #include "eqn.h"
27 #include "pbox.h"
29 class over_box
30 : public box
32 int reduce_size;
33 box *num;
34 box *den;
36 public:
37 over_box(int small, box *, box *);
38 ~over_box();
39 void debug_print();
40 int compute_metrics(int);
41 void output();
42 void check_tabs(int);
45 box *make_over_box(box *pp, box *qq)
47 return new over_box(0, pp, qq);
50 box *make_small_over_box(box *pp, box *qq)
52 return new over_box(1, pp, qq);
55 over_box::over_box(int is_small, box *pp, box *qq)
56 : reduce_size(is_small), num(pp), den(qq)
58 spacing_type = INNER_TYPE;
61 over_box::~over_box()
63 delete num;
64 delete den;
67 int over_box::compute_metrics(int style)
69 if (reduce_size) {
70 style = script_style(style);
71 printf(".nr " SIZE_FORMAT " \\n[.ps]\n", uid);
72 set_script_size();
73 printf(".nr " SMALL_SIZE_FORMAT " \\n[.ps]\n", uid);
75 int mark_uid = 0;
76 int res = num->compute_metrics(style);
77 if (res)
78 mark_uid = num->uid;
79 int r = den->compute_metrics(cramped_style(style));
80 if (r && res)
81 error("multiple marks and lineups");
82 else {
83 mark_uid = den->uid;
84 res = r;
86 if (reduce_size)
87 printf(".ps \\n[" SIZE_FORMAT "]u\n", uid);
88 printf(".nr " WIDTH_FORMAT " (\\n[" WIDTH_FORMAT "]>?\\n[" WIDTH_FORMAT "]",
89 uid, num->uid, den->uid);
90 // allow for \(ru being wider than both the numerator and denominator
91 if (!draw_flag)
92 fputs(">?\\w" DELIMITER_CHAR "\\(ru" DELIMITER_CHAR, stdout);
93 printf(")+%dM\n", null_delimiter_space*2 + over_hang*2);
94 // 15b
95 printf(".nr " SUP_RAISE_FORMAT " %dM\n",
96 uid, (reduce_size ? num2 : num1));
97 printf(".nr " SUB_LOWER_FORMAT " %dM\n",
98 uid, (reduce_size ? denom2 : denom1));
100 // 15d
101 printf(".nr " SUP_RAISE_FORMAT " +(\\n[" DEPTH_FORMAT
102 "]-\\n[" SUP_RAISE_FORMAT "]+%dM+(%dM/2)+%dM)>?0\n",
103 uid, num->uid, uid, axis_height, default_rule_thickness,
104 default_rule_thickness*(reduce_size ? 1 : 3));
105 printf(".nr " SUB_LOWER_FORMAT " +(\\n[" HEIGHT_FORMAT
106 "]-\\n[" SUB_LOWER_FORMAT "]-%dM+(%dM/2)+%dM)>?0\n",
107 uid, den->uid, uid, axis_height, default_rule_thickness,
108 default_rule_thickness*(reduce_size ? 1 : 3));
111 printf(".nr " HEIGHT_FORMAT " \\n[" SUP_RAISE_FORMAT "]+\\n["
112 HEIGHT_FORMAT "]\n",
113 uid, uid, num->uid);
114 printf(".nr " DEPTH_FORMAT " \\n[" SUB_LOWER_FORMAT "]+\\n["
115 DEPTH_FORMAT "]\n",
116 uid, uid, den->uid);
117 if (res)
118 printf(".nr " MARK_REG " +(\\n[" WIDTH_FORMAT "]-\\n["
119 WIDTH_FORMAT "]/2)\n", uid, mark_uid);
120 return res;
123 #define USE_Z
125 void over_box::output()
127 if (output_format == troff) {
128 if (reduce_size)
129 printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
130 #ifdef USE_Z
131 printf("\\Z" DELIMITER_CHAR);
132 #endif
133 // move up to the numerator baseline
134 printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
135 // move across so that it's centered
136 printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
137 uid, num->uid);
139 // print the numerator
140 num->output();
142 #ifdef USE_Z
143 printf(DELIMITER_CHAR);
144 #else
145 // back again
146 printf("\\h'-\\n[" WIDTH_FORMAT "]u'", num->uid);
147 printf("\\h'-(\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u)'",
148 uid, num->uid);
149 // down again
150 printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
151 #endif
152 #ifdef USE_Z
153 printf("\\Z" DELIMITER_CHAR);
154 #endif
155 // move down to the denominator baseline
156 printf("\\v'\\n[" SUB_LOWER_FORMAT "]u'", uid);
158 // move across so that it's centered
159 printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
160 uid, den->uid);
162 // print the the denominator
163 den->output();
165 #ifdef USE_Z
166 printf(DELIMITER_CHAR);
167 #else
168 // back again
169 printf("\\h'-\\n[" WIDTH_FORMAT "]u'", den->uid);
170 printf("\\h'-(\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u)'",
171 uid, den->uid);
172 // up again
173 printf("\\v'-\\n[" SUB_LOWER_FORMAT "]u'", uid);
174 #endif
175 if (reduce_size)
176 printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
177 // draw the line
178 printf("\\h'%dM'", null_delimiter_space);
179 printf("\\v'-%dM'", axis_height);
180 fputs(draw_flag ? "\\D'l" : "\\l'", stdout);
181 printf("\\n[" WIDTH_FORMAT "]u-%dM",
182 uid, 2*null_delimiter_space);
183 fputs(draw_flag ? " 0'" : "\\&\\(ru'", stdout);
184 printf("\\v'%dM'", axis_height);
185 printf("\\h'%dM'", null_delimiter_space);
187 else if (output_format == mathml) {
188 // FIXME: passing a displaystyle attribute doesn't validate.
189 printf("<mfrac>");
190 num->output();
191 den->output();
192 printf("</mfrac>");
196 void over_box::debug_print()
198 fprintf(stderr, "{ ");
199 num->debug_print();
200 if (reduce_size)
201 fprintf(stderr, " } smallover { ");
202 else
203 fprintf(stderr, " } over { ");
204 den->debug_print();
205 fprintf(stderr, " }");
208 void over_box::check_tabs(int level)
210 num->check_tabs(level + 1);
211 den->check_tabs(level + 1);
214 // s-it2-mode