PageRenderTime 68ms CodeModel.GetById 14ms app.highlight 51ms RepoModel.GetById 1ms app.codeStats 0ms

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

https://bitbucket.org/freebsd/freebsd-head/
C++ | 293 lines | 249 code | 20 blank | 24 comment | 35 complexity | dc8ad411300a1ab51ee1d3129bf2e096 MD5 | raw file
  1// -*- C++ -*-
  2/* Copyright (C) 1989, 1990, 1991, 1992, 2004 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// piles and matrices
 21
 22#include "eqn.h"
 23#include "pbox.h"
 24
 25// SUP_RAISE_FORMAT gives the first baseline
 26// BASELINE_SEP_FORMAT gives the separation between baselines
 27
 28int pile_box::compute_metrics(int style)
 29{
 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");
 44
 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;
 55}
 56
 57void pile_box::output()
 58{
 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);
 75    }
 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);
 91    }
 92    if (i != col.len - 1)
 93      printf("\\v'\\n[" BASELINE_SEP_FORMAT "]u'", uid);
 94  }
 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);
 98}
 99
100pile_box::pile_box(box *pp) : col(pp)
101{
102}
103
104void pile_box::check_tabs(int level)
105{
106  col.list_check_tabs(level);
107}
108
109void pile_box::debug_print()
110{
111  col.debug_print("pile");
112}
113
114int matrix_box::compute_metrics(int style)
115{
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;
126  }
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");
132  }
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;
162}
163
164void matrix_box::output()
165{
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);
184      }
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);
200      }
201      if (j != p[i]->len - 1)
202	printf("\\v'\\n[" BASELINE_SEP_FORMAT "]u'", uid);
203    }
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);
209  }
210  printf("\\h'%dM'", matrix_side_sep);
211}
212
213matrix_box::matrix_box(column *pp)
214{
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;
221}
222
223matrix_box::~matrix_box()
224{
225  for (int i = 0; i < len; i++)
226    delete p[i];
227  a_delete p;
228}
229
230void matrix_box::append(column *pp)
231{
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;
238  }
239  p[len++] = pp;
240}
241
242void matrix_box::check_tabs(int level)
243{
244  for (int i = 0; i < len; i++)
245    p[i]->list_check_tabs(level);
246}
247
248void matrix_box::debug_print()
249{
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");
255  }
256  fprintf(stderr, " }");
257}
258
259column::column(box *pp) : box_list(pp), align(CENTER_ALIGN), space(0)
260{
261}
262
263void column::set_alignment(alignment a)
264{
265  align = a;
266}
267
268void column::set_space(int n)
269{
270  space = n;
271}
272
273void column::debug_print(const char *s)
274{
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);
288  }
289  fprintf(stderr, "%c%s %d { ", c, s, space);
290  list_debug_print(" above ");
291  fprintf(stderr, " }");
292}
293