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 7This file is part of groff. 8 9groff is free software; you can redistribute it and/or modify it under 10the terms of the GNU General Public License as published by the Free 11Software Foundation; either version 2, or (at your option) any later 12version. 13 14groff is distributed in the hope that it will be useful, but WITHOUT ANY 15WARRANTY; without even the implied warranty of MERCHANTABILITY or 16FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17for more details. 18 19You should have received a copy of the GNU General Public License along 20with groff; see the file COPYING. If not, write to the Free Software 21Foundation, 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 30int 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 59void 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 102pile_box::pile_box(box *pp) : col(pp) 103{ 104} 105 106void pile_box::check_tabs(int level) 107{ 108 col.list_check_tabs(level); 109} 110 111void pile_box::debug_print() 112{ 113 col.debug_print("pile"); 114} 115 116int 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 166void 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 215matrix_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 225matrix_box::~matrix_box() 226{ 227 for (int i = 0; i < len; i++) 228 delete p[i]; 229 a_delete p; 230} 231 232void 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 244void matrix_box::check_tabs(int level) 245{ 246 for (int i = 0; i < len; i++) 247 p[i]->list_check_tabs(level); 248} 249 250void 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 261column::column(box *pp) : box_list(pp), align(CENTER_ALIGN), space(0) 262{ 263} 264 265void column::set_alignment(alignment a) 266{ 267 align = a; 268} 269 270void column::set_space(int n) 271{ 272 space = n; 273} 274 275void 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