* All affected files: Update postal address of FSF.
[s-roff.git] / src / preproc / eqn / pile.cpp
blob10d1708809afa14e46400923f7f39134de205a25
1 // -*- C++ -*-
2 /* Copyright (C) 1989, 1990, 1991, 1992, 2004 Free Software Foundation, Inc.
3 Written by James Clark (jjc@jclark.com)
5 This file is part of groff.
7 groff is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 groff is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License along
18 with groff; see the file COPYING. If not, write to the Free Software
19 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
20 // piles and matrices
22 #include "eqn.h"
23 #include "pbox.h"
25 // SUP_RAISE_FORMAT gives the first baseline
26 // BASELINE_SEP_FORMAT gives the separation between baselines
28 int pile_box::compute_metrics(int style)
30 int i;
31 for (i = 0; i < col.len; i++)
32 col.p[i]->compute_metrics(style);
33 printf(".nr " WIDTH_FORMAT " 0", uid);
34 for (i = 0; i < col.len; i++)
35 printf(">?\\n[" WIDTH_FORMAT "]", col.p[i]->uid);
36 printf("\n");
37 printf(".nr " BASELINE_SEP_FORMAT " %dM",
38 uid, baseline_sep+col.space);
39 for (i = 1; i < col.len; i++)
40 printf(">?(\\n[" DEPTH_FORMAT "]+\\n[" HEIGHT_FORMAT "]+%dM)",
41 col.p[i-1]->uid, col.p[i]->uid, default_rule_thickness*5);
42 // round it so that it's a multiple of the vertical resolution
43 printf("/\\n(.V+(\\n(.V/2)*\\n(.V\n");
45 printf(".nr " SUP_RAISE_FORMAT " \\n[" BASELINE_SEP_FORMAT "]*%d/2"
46 "+%dM\n",
47 uid, uid, col.len-1, axis_height - shift_down);
48 printf(".nr " HEIGHT_FORMAT " \\n[" SUP_RAISE_FORMAT "]+\\n["
49 HEIGHT_FORMAT "]\n",
50 uid, uid, col.p[0]->uid);
51 printf(".nr " DEPTH_FORMAT " \\n[" BASELINE_SEP_FORMAT "]*%d+\\n["
52 DEPTH_FORMAT "]-\\n[" SUP_RAISE_FORMAT "]\n",
53 uid, uid, col.len-1, col.p[col.len-1]->uid, uid);
54 return FOUND_NOTHING;
57 void pile_box::output()
59 int i;
60 printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
61 for (i = 0; i < col.len; i++) {
62 switch (col.align) {
63 case LEFT_ALIGN:
64 break;
65 case CENTER_ALIGN:
66 printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
67 uid, col.p[i]->uid);
68 break;
69 case RIGHT_ALIGN:
70 printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u'",
71 uid, col.p[i]->uid);
72 break;
73 default:
74 assert(0);
76 col.p[i]->output();
77 printf("\\h'-\\n[" WIDTH_FORMAT "]u'", col.p[i]->uid);
78 switch (col.align) {
79 case LEFT_ALIGN:
80 break;
81 case CENTER_ALIGN:
82 printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
83 col.p[i]->uid, uid);
84 break;
85 case RIGHT_ALIGN:
86 printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u'",
87 col.p[i]->uid, uid);
88 break;
89 default:
90 assert(0);
92 if (i != col.len - 1)
93 printf("\\v'\\n[" BASELINE_SEP_FORMAT "]u'", uid);
95 printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
96 printf("\\v'-(%du*\\n[" BASELINE_SEP_FORMAT "]u)'", col.len - 1, uid);
97 printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
100 pile_box::pile_box(box *pp) : col(pp)
104 void pile_box::check_tabs(int level)
106 col.list_check_tabs(level);
109 void pile_box::debug_print()
111 col.debug_print("pile");
114 int matrix_box::compute_metrics(int style)
116 int i, j;
117 int max_len = 0;
118 int space = 0;
119 for (i = 0; i < len; i++) {
120 for (j = 0; j < p[i]->len; j++)
121 p[i]->p[j]->compute_metrics(style);
122 if (p[i]->len > max_len)
123 max_len = p[i]->len;
124 if (p[i]->space > space)
125 space = p[i]->space;
127 for (i = 0; i < len; i++) {
128 printf(".nr " COLUMN_WIDTH_FORMAT " 0", uid, i);
129 for (j = 0; j < p[i]->len; j++)
130 printf(">?\\n[" WIDTH_FORMAT "]", p[i]->p[j]->uid);
131 printf("\n");
133 printf(".nr " WIDTH_FORMAT " %dM",
134 uid, column_sep*(len-1)+2*matrix_side_sep);
135 for (i = 0; i < len; i++)
136 printf("+\\n[" COLUMN_WIDTH_FORMAT "]", uid, i);
137 printf("\n");
138 printf(".nr " BASELINE_SEP_FORMAT " %dM",
139 uid, baseline_sep+space);
140 for (i = 0; i < len; i++)
141 for (j = 1; j < p[i]->len; j++)
142 printf(">?(\\n[" DEPTH_FORMAT "]+\\n[" HEIGHT_FORMAT "]+%dM)",
143 p[i]->p[j-1]->uid, p[i]->p[j]->uid, default_rule_thickness*5);
144 // round it so that it's a multiple of the vertical resolution
145 printf("/\\n(.V+(\\n(.V/2)*\\n(.V\n");
146 printf(".nr " SUP_RAISE_FORMAT " \\n[" BASELINE_SEP_FORMAT "]*%d/2"
147 "+%dM\n",
148 uid, uid, max_len-1, axis_height - shift_down);
149 printf(".nr " HEIGHT_FORMAT " 0\\n[" SUP_RAISE_FORMAT "]+(0",
150 uid, uid);
151 for (i = 0; i < len; i++)
152 printf(">?\\n[" HEIGHT_FORMAT "]", p[i]->p[0]->uid);
153 printf(")>?0\n");
154 printf(".nr " DEPTH_FORMAT " \\n[" BASELINE_SEP_FORMAT "]*%d-\\n["
155 SUP_RAISE_FORMAT "]+(0",
156 uid, uid, max_len-1, uid);
157 for (i = 0; i < len; i++)
158 if (p[i]->len == max_len)
159 printf(">?\\n[" DEPTH_FORMAT "]", p[i]->p[max_len-1]->uid);
160 printf(")>?0\n");
161 return FOUND_NOTHING;
164 void matrix_box::output()
166 printf("\\h'%dM'", matrix_side_sep);
167 for (int i = 0; i < len; i++) {
168 int j;
169 printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
170 for (j = 0; j < p[i]->len; j++) {
171 switch (p[i]->align) {
172 case LEFT_ALIGN:
173 break;
174 case CENTER_ALIGN:
175 printf("\\h'\\n[" COLUMN_WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
176 uid, i, p[i]->p[j]->uid);
177 break;
178 case RIGHT_ALIGN:
179 printf("\\h'\\n[" COLUMN_WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u'",
180 uid, i, p[i]->p[j]->uid);
181 break;
182 default:
183 assert(0);
185 p[i]->p[j]->output();
186 printf("\\h'-\\n[" WIDTH_FORMAT "]u'", p[i]->p[j]->uid);
187 switch (p[i]->align) {
188 case LEFT_ALIGN:
189 break;
190 case CENTER_ALIGN:
191 printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" COLUMN_WIDTH_FORMAT "]u/2u'",
192 p[i]->p[j]->uid, uid, i);
193 break;
194 case RIGHT_ALIGN:
195 printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" COLUMN_WIDTH_FORMAT "]u'",
196 p[i]->p[j]->uid, uid, i);
197 break;
198 default:
199 assert(0);
201 if (j != p[i]->len - 1)
202 printf("\\v'\\n[" BASELINE_SEP_FORMAT "]u'", uid);
204 printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
205 printf("\\v'-(%du*\\n[" BASELINE_SEP_FORMAT "]u)'", p[i]->len - 1, uid);
206 printf("\\h'\\n[" COLUMN_WIDTH_FORMAT "]u'", uid, i);
207 if (i != len - 1)
208 printf("\\h'%dM'", column_sep);
210 printf("\\h'%dM'", matrix_side_sep);
213 matrix_box::matrix_box(column *pp)
215 p = new column*[10];
216 for (int i = 0; i < 10; i++)
217 p[i] = 0;
218 maxlen = 10;
219 len = 1;
220 p[0] = pp;
223 matrix_box::~matrix_box()
225 for (int i = 0; i < len; i++)
226 delete p[i];
227 a_delete p;
230 void matrix_box::append(column *pp)
232 if (len + 1 > maxlen) {
233 column **oldp = p;
234 maxlen *= 2;
235 p = new column*[maxlen];
236 memcpy(p, oldp, sizeof(column*)*len);
237 a_delete oldp;
239 p[len++] = pp;
242 void matrix_box::check_tabs(int level)
244 for (int i = 0; i < len; i++)
245 p[i]->list_check_tabs(level);
248 void matrix_box::debug_print()
250 fprintf(stderr, "matrix { ");
251 p[0]->debug_print("col");
252 for (int i = 1; i < len; i++) {
253 fprintf(stderr, " ");
254 p[i]->debug_print("col");
256 fprintf(stderr, " }");
259 column::column(box *pp) : box_list(pp), align(CENTER_ALIGN), space(0)
263 void column::set_alignment(alignment a)
265 align = a;
268 void column::set_space(int n)
270 space = n;
273 void column::debug_print(const char *s)
275 char c = '\0'; // shut up -Wall
276 switch (align) {
277 case LEFT_ALIGN:
278 c = 'l';
279 break;
280 case RIGHT_ALIGN:
281 c = 'r';
282 break;
283 case CENTER_ALIGN:
284 c = 'c';
285 break;
286 default:
287 assert(0);
289 fprintf(stderr, "%c%s %d { ", c, s, space);
290 list_debug_print(" above ");
291 fprintf(stderr, " }");