1/* $NetBSD$ */ 2 3// -*- C++ -*- 4/* Copyright (C) 1989, 1990, 1991, 1992, 2002 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 23#include "eqn.h" 24#include "pbox.h" 25 26class limit_box : public box { 27private: 28 box *p; 29 box *from; 30 box *to; 31public: 32 limit_box(box *, box *, box *); 33 ~limit_box(); 34 int compute_metrics(int); 35 void output(); 36 void debug_print(); 37 void check_tabs(int); 38}; 39 40box *make_limit_box(box *pp, box *qq, box *rr) 41{ 42 return new limit_box(pp, qq, rr); 43} 44 45limit_box::limit_box(box *pp, box *qq, box *rr) 46: p(pp), from(qq), to(rr) 47{ 48 spacing_type = p->spacing_type; 49} 50 51limit_box::~limit_box() 52{ 53 delete p; 54 delete from; 55 delete to; 56} 57 58int limit_box::compute_metrics(int style) 59{ 60 printf(".nr " SIZE_FORMAT " \\n[.ps]\n", uid); 61 if (!(style <= SCRIPT_STYLE && one_size_reduction_flag)) 62 set_script_size(); 63 printf(".nr " SMALL_SIZE_FORMAT " \\n[.ps]\n", uid); 64 int res = 0; 65 int mark_uid = -1; 66 if (from != 0) { 67 res = from->compute_metrics(cramped_style(script_style(style))); 68 if (res) 69 mark_uid = from->uid; 70 } 71 if (to != 0) { 72 int r = to->compute_metrics(script_style(style)); 73 if (res && r) 74 error("multiple marks and lineups"); 75 else { 76 mark_uid = to->uid; 77 res = r; 78 } 79 } 80 printf(".ps \\n[" SIZE_FORMAT "]u\n", uid); 81 int r = p->compute_metrics(style); 82 p->compute_subscript_kern(); 83 if (res && r) 84 error("multiple marks and lineups"); 85 else { 86 mark_uid = p->uid; 87 res = r; 88 } 89 printf(".nr " LEFT_WIDTH_FORMAT " " 90 "0\\n[" WIDTH_FORMAT "]", 91 uid, p->uid); 92 if (from != 0) 93 printf(">?(\\n[" SUB_KERN_FORMAT "]+\\n[" WIDTH_FORMAT "])", 94 p->uid, from->uid); 95 if (to != 0) 96 printf(">?(-\\n[" SUB_KERN_FORMAT "]+\\n[" WIDTH_FORMAT "])", 97 p->uid, to->uid); 98 printf("/2\n"); 99 printf(".nr " WIDTH_FORMAT " " 100 "0\\n[" WIDTH_FORMAT "]", 101 uid, p->uid); 102 if (from != 0) 103 printf(">?(-\\n[" SUB_KERN_FORMAT "]+\\n[" WIDTH_FORMAT "])", 104 p->uid, from->uid); 105 if (to != 0) 106 printf(">?(\\n[" SUB_KERN_FORMAT "]+\\n[" WIDTH_FORMAT "])", 107 p->uid, to->uid); 108 printf("/2+\\n[" LEFT_WIDTH_FORMAT "]\n", uid); 109 printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]", uid, p->uid); 110 if (to != 0) 111 printf(">?\\n[" WIDTH_FORMAT "]", to->uid); 112 if (from != 0) 113 printf(">?\\n[" WIDTH_FORMAT "]", from->uid); 114 printf("\n"); 115 if (res) 116 printf(".nr " MARK_REG " +(\\n[" LEFT_WIDTH_FORMAT "]" 117 "-(\\n[" WIDTH_FORMAT "]/2))\n", 118 uid, mark_uid); 119 if (to != 0) { 120 printf(".nr " SUP_RAISE_FORMAT " %dM+\\n[" DEPTH_FORMAT 121 "]>?%dM+\\n[" HEIGHT_FORMAT "]\n", 122 uid, big_op_spacing1, to->uid, big_op_spacing3, p->uid); 123 printf(".nr " HEIGHT_FORMAT " \\n[" SUP_RAISE_FORMAT "]+\\n[" 124 HEIGHT_FORMAT "]+%dM\n", 125 uid, uid, to->uid, big_op_spacing5); 126 } 127 else 128 printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid); 129 if (from != 0) { 130 printf(".nr " SUB_LOWER_FORMAT " %dM+\\n[" HEIGHT_FORMAT 131 "]>?%dM+\\n[" DEPTH_FORMAT "]\n", 132 uid, big_op_spacing2, from->uid, big_op_spacing4, p->uid); 133 printf(".nr " DEPTH_FORMAT " \\n[" SUB_LOWER_FORMAT "]+\\n[" 134 DEPTH_FORMAT "]+%dM\n", 135 uid, uid, from->uid, big_op_spacing5); 136 } 137 else 138 printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid); 139 return res; 140} 141 142void limit_box::output() 143{ 144 printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid); 145 if (to != 0) { 146 printf("\\Z" DELIMITER_CHAR); 147 printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid); 148 printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u" 149 "+(-\\n[" WIDTH_FORMAT "]u+\\n[" SUB_KERN_FORMAT "]u/2u)'", 150 uid, to->uid, p->uid); 151 to->output(); 152 printf(DELIMITER_CHAR); 153 } 154 if (from != 0) { 155 printf("\\Z" DELIMITER_CHAR); 156 printf("\\v'\\n[" SUB_LOWER_FORMAT "]u'", uid); 157 printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u" 158 "+(-\\n[" SUB_KERN_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u)'", 159 uid, p->uid, from->uid); 160 from->output(); 161 printf(DELIMITER_CHAR); 162 } 163 printf("\\s[\\n[" SIZE_FORMAT "]u]", uid); 164 printf("\\Z" DELIMITER_CHAR); 165 printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u" 166 "-(\\n[" WIDTH_FORMAT "]u/2u)'", 167 uid, p->uid); 168 p->output(); 169 printf(DELIMITER_CHAR); 170 printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid); 171} 172 173void limit_box::debug_print() 174{ 175 fprintf(stderr, "{ "); 176 p->debug_print(); 177 fprintf(stderr, " }"); 178 if (from) { 179 fprintf(stderr, " from { "); 180 from->debug_print(); 181 fprintf(stderr, " }"); 182 } 183 if (to) { 184 fprintf(stderr, " to { "); 185 to->debug_print(); 186 fprintf(stderr, " }"); 187 } 188} 189 190void limit_box::check_tabs(int level) 191{ 192 if (to) 193 to->check_tabs(level + 1); 194 if (from) 195 from->check_tabs(level + 1); 196 p->check_tabs(level + 1); 197} 198