xref: /netbsd-src/external/gpl2/groff/dist/src/preproc/eqn/pile.cpp (revision 89a07cf815a29524268025a1139fac4c5190f765)
1 /*	$NetBSD: pile.cpp,v 1.1.1.1 2016/01/13 18:41:49 christos Exp $	*/
2 
3 // -*- C++ -*-
4 /* Copyright (C) 1989, 1990, 1991, 1992, 2004 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 // piles and matrices
23 
24 #include "eqn.h"
25 #include "pbox.h"
26 
27 // SUP_RAISE_FORMAT gives the first baseline
28 // BASELINE_SEP_FORMAT gives the separation between baselines
29 
compute_metrics(int style)30 int pile_box::compute_metrics(int style)
31 {
32   int i;
33   for (i = 0; i < col.len; i++)
34     col.p[i]->compute_metrics(style);
35   printf(".nr " WIDTH_FORMAT " 0", uid);
36   for (i = 0; i < col.len; i++)
37     printf(">?\\n[" WIDTH_FORMAT "]", col.p[i]->uid);
38   printf("\n");
39   printf(".nr " BASELINE_SEP_FORMAT " %dM",
40 	 uid, baseline_sep+col.space);
41   for (i = 1; i < col.len; i++)
42     printf(">?(\\n[" DEPTH_FORMAT "]+\\n[" HEIGHT_FORMAT "]+%dM)",
43 	   col.p[i-1]->uid, col.p[i]->uid, default_rule_thickness*5);
44   // round it so that it's a multiple of the vertical resolution
45   printf("/\\n(.V+(\\n(.V/2)*\\n(.V\n");
46 
47   printf(".nr " SUP_RAISE_FORMAT " \\n[" BASELINE_SEP_FORMAT "]*%d/2"
48 	 "+%dM\n",
49 	 uid, uid, col.len-1, axis_height - shift_down);
50   printf(".nr " HEIGHT_FORMAT " \\n[" SUP_RAISE_FORMAT "]+\\n["
51 	 HEIGHT_FORMAT "]\n",
52 	 uid, uid, col.p[0]->uid);
53   printf(".nr " DEPTH_FORMAT " \\n[" BASELINE_SEP_FORMAT "]*%d+\\n["
54 	 DEPTH_FORMAT "]-\\n[" SUP_RAISE_FORMAT "]\n",
55 	 uid, uid, col.len-1, col.p[col.len-1]->uid, uid);
56   return FOUND_NOTHING;
57 }
58 
output()59 void pile_box::output()
60 {
61   int i;
62   printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
63   for (i = 0; i < col.len; i++) {
64     switch (col.align) {
65     case LEFT_ALIGN:
66       break;
67     case CENTER_ALIGN:
68       printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
69 	     uid, col.p[i]->uid);
70       break;
71     case RIGHT_ALIGN:
72       printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u'",
73 	     uid, col.p[i]->uid);
74       break;
75     default:
76       assert(0);
77     }
78     col.p[i]->output();
79     printf("\\h'-\\n[" WIDTH_FORMAT "]u'", col.p[i]->uid);
80     switch (col.align) {
81     case LEFT_ALIGN:
82       break;
83     case CENTER_ALIGN:
84       printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
85 	     col.p[i]->uid, uid);
86       break;
87     case RIGHT_ALIGN:
88       printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u'",
89 	     col.p[i]->uid, uid);
90       break;
91     default:
92       assert(0);
93     }
94     if (i != col.len - 1)
95       printf("\\v'\\n[" BASELINE_SEP_FORMAT "]u'", uid);
96   }
97   printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
98   printf("\\v'-(%du*\\n[" BASELINE_SEP_FORMAT "]u)'", col.len - 1, uid);
99   printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
100 }
101 
pile_box(box * pp)102 pile_box::pile_box(box *pp) : col(pp)
103 {
104 }
105 
check_tabs(int level)106 void pile_box::check_tabs(int level)
107 {
108   col.list_check_tabs(level);
109 }
110 
debug_print()111 void pile_box::debug_print()
112 {
113   col.debug_print("pile");
114 }
115 
compute_metrics(int style)116 int matrix_box::compute_metrics(int style)
117 {
118   int i, j;
119   int max_len = 0;
120   int space = 0;
121   for (i = 0; i < len; i++) {
122     for (j = 0; j < p[i]->len; j++)
123       p[i]->p[j]->compute_metrics(style);
124     if (p[i]->len > max_len)
125       max_len = p[i]->len;
126     if (p[i]->space > space)
127       space = p[i]->space;
128   }
129   for (i = 0; i < len; i++) {
130     printf(".nr " COLUMN_WIDTH_FORMAT " 0", uid, i);
131     for (j = 0; j < p[i]->len; j++)
132       printf(">?\\n[" WIDTH_FORMAT "]", p[i]->p[j]->uid);
133     printf("\n");
134   }
135   printf(".nr " WIDTH_FORMAT " %dM",
136 	 uid, column_sep*(len-1)+2*matrix_side_sep);
137   for (i = 0; i < len; i++)
138     printf("+\\n[" COLUMN_WIDTH_FORMAT "]", uid, i);
139   printf("\n");
140   printf(".nr " BASELINE_SEP_FORMAT " %dM",
141 	 uid, baseline_sep+space);
142   for (i = 0; i < len; i++)
143     for (j = 1; j < p[i]->len; j++)
144       printf(">?(\\n[" DEPTH_FORMAT "]+\\n[" HEIGHT_FORMAT "]+%dM)",
145 	   p[i]->p[j-1]->uid, p[i]->p[j]->uid, default_rule_thickness*5);
146   // round it so that it's a multiple of the vertical resolution
147   printf("/\\n(.V+(\\n(.V/2)*\\n(.V\n");
148   printf(".nr " SUP_RAISE_FORMAT " \\n[" BASELINE_SEP_FORMAT "]*%d/2"
149 	 "+%dM\n",
150 	 uid, uid, max_len-1, axis_height - shift_down);
151   printf(".nr " HEIGHT_FORMAT " 0\\n[" SUP_RAISE_FORMAT "]+(0",
152 	 uid, uid);
153   for (i = 0; i < len; i++)
154     printf(">?\\n[" HEIGHT_FORMAT "]", p[i]->p[0]->uid);
155   printf(")>?0\n");
156   printf(".nr " DEPTH_FORMAT " \\n[" BASELINE_SEP_FORMAT "]*%d-\\n["
157 	 SUP_RAISE_FORMAT "]+(0",
158 	 uid, uid, max_len-1, uid);
159   for (i = 0; i < len; i++)
160     if (p[i]->len == max_len)
161       printf(">?\\n[" DEPTH_FORMAT "]", p[i]->p[max_len-1]->uid);
162   printf(")>?0\n");
163   return FOUND_NOTHING;
164 }
165 
output()166 void matrix_box::output()
167 {
168   printf("\\h'%dM'", matrix_side_sep);
169   for (int i = 0; i < len; i++) {
170     int j;
171     printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
172     for (j = 0; j < p[i]->len; j++) {
173       switch (p[i]->align) {
174       case LEFT_ALIGN:
175 	break;
176       case CENTER_ALIGN:
177 	printf("\\h'\\n[" COLUMN_WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u'",
178 	       uid, i, p[i]->p[j]->uid);
179 	break;
180       case RIGHT_ALIGN:
181 	printf("\\h'\\n[" COLUMN_WIDTH_FORMAT "]u-\\n[" WIDTH_FORMAT "]u'",
182 	       uid, i, p[i]->p[j]->uid);
183 	break;
184       default:
185 	assert(0);
186       }
187       p[i]->p[j]->output();
188       printf("\\h'-\\n[" WIDTH_FORMAT "]u'", p[i]->p[j]->uid);
189       switch (p[i]->align) {
190       case LEFT_ALIGN:
191 	break;
192       case CENTER_ALIGN:
193 	printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" COLUMN_WIDTH_FORMAT "]u/2u'",
194 	       p[i]->p[j]->uid, uid, i);
195 	break;
196       case RIGHT_ALIGN:
197 	printf("\\h'\\n[" WIDTH_FORMAT "]u-\\n[" COLUMN_WIDTH_FORMAT "]u'",
198 	       p[i]->p[j]->uid, uid, i);
199 	break;
200       default:
201 	assert(0);
202       }
203       if (j != p[i]->len - 1)
204 	printf("\\v'\\n[" BASELINE_SEP_FORMAT "]u'", uid);
205     }
206     printf("\\v'\\n[" SUP_RAISE_FORMAT "]u'", uid);
207     printf("\\v'-(%du*\\n[" BASELINE_SEP_FORMAT "]u)'", p[i]->len - 1, uid);
208     printf("\\h'\\n[" COLUMN_WIDTH_FORMAT "]u'", uid, i);
209     if (i != len - 1)
210       printf("\\h'%dM'", column_sep);
211   }
212   printf("\\h'%dM'", matrix_side_sep);
213 }
214 
matrix_box(column * pp)215 matrix_box::matrix_box(column *pp)
216 {
217   p = new column*[10];
218   for (int i = 0; i < 10; i++)
219     p[i] = 0;
220   maxlen = 10;
221   len = 1;
222   p[0] = pp;
223 }
224 
~matrix_box()225 matrix_box::~matrix_box()
226 {
227   for (int i = 0; i < len; i++)
228     delete p[i];
229   a_delete p;
230 }
231 
append(column * pp)232 void matrix_box::append(column *pp)
233 {
234   if (len + 1 > maxlen) {
235     column **oldp = p;
236     maxlen *= 2;
237     p = new column*[maxlen];
238     memcpy(p, oldp, sizeof(column*)*len);
239     a_delete oldp;
240   }
241   p[len++] = pp;
242 }
243 
check_tabs(int level)244 void matrix_box::check_tabs(int level)
245 {
246   for (int i = 0; i < len; i++)
247     p[i]->list_check_tabs(level);
248 }
249 
debug_print()250 void matrix_box::debug_print()
251 {
252   fprintf(stderr, "matrix { ");
253   p[0]->debug_print("col");
254   for (int i = 1; i < len; i++) {
255     fprintf(stderr, " ");
256     p[i]->debug_print("col");
257   }
258   fprintf(stderr, " }");
259 }
260 
column(box * pp)261 column::column(box *pp) : box_list(pp), align(CENTER_ALIGN), space(0)
262 {
263 }
264 
set_alignment(alignment a)265 void column::set_alignment(alignment a)
266 {
267   align = a;
268 }
269 
set_space(int n)270 void column::set_space(int n)
271 {
272   space = n;
273 }
274 
debug_print(const char * s)275 void column::debug_print(const char *s)
276 {
277   char c = '\0';		// shut up -Wall
278   switch (align) {
279   case LEFT_ALIGN:
280     c = 'l';
281     break;
282   case RIGHT_ALIGN:
283     c = 'r';
284     break;
285   case CENTER_ALIGN:
286     c = 'c';
287     break;
288   default:
289     assert(0);
290   }
291   fprintf(stderr, "%c%s %d { ", c, s, space);
292   list_debug_print(" above ");
293   fprintf(stderr, " }");
294 }
295 
296