home *** CD-ROM | disk | FTP | other *** search
/ Aminet 10 / aminetcdnumber101996.iso / Aminet / util / gnu / groff_src.lha / groff-1.10src / eqn / pile.cc < prev    next >
C/C++ Source or Header  |  1995-06-22  |  8KB  |  294 lines

  1. // -*- C++ -*-
  2. /* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
  3.      Written by James Clark (jjc@jclark.com)
  4.  
  5. This file is part of groff.
  6.  
  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.
  11.  
  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.
  16.  
  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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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.  
  28. int 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.  
  57. void 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.  
  100. pile_box::pile_box(box *pp) : col(pp)
  101. {
  102. }
  103.  
  104. void pile_box::check_tabs(int level)
  105. {
  106.   col.list_check_tabs(level);
  107. }
  108.  
  109. void pile_box::debug_print()
  110. {
  111.   col.debug_print("pile");
  112. }
  113.  
  114. int matrix_box::compute_metrics(int style)
  115. {
  116.   int i, j;
  117.   int maxlen = 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 > maxlen)
  123.       maxlen = 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, maxlen-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, maxlen-1, uid);
  157.   for (i = 0; i < len; i++)
  158.     if (p[i]->len == maxlen)
  159.       printf(">?\\n[" DEPTH_FORMAT "]", p[i]->p[maxlen-1]->uid);
  160.   printf(")>?0\n");
  161.   return FOUND_NOTHING;
  162. }
  163.  
  164. void 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.  
  213. matrix_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.  
  223. matrix_box::~matrix_box()
  224. {
  225.   for (int i = 0; i < len; i++)
  226.     delete p[i];
  227.   a_delete p;
  228. }
  229.  
  230. void 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.  
  242. void matrix_box::check_tabs(int level)
  243. {
  244.   for (int i = 0; i < len; i++)
  245.     p[i]->list_check_tabs(level);
  246. }
  247.  
  248. void 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.  
  259. column::column(box *pp) : box_list(pp), align(CENTER_ALIGN), space(0)
  260. {
  261. }
  262.  
  263. void column::set_alignment(alignment a)
  264. {
  265.   align = a;
  266. }
  267.  
  268. void column::set_space(int n)
  269. {
  270.   space = n;
  271. }
  272.  
  273. void 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.  
  294.