1114402Sru// -*- C++ -*- 2114402Sru/* Copyright (C) 1989, 1990, 1991, 1992, 2002 Free Software Foundation, Inc. 3114402Sru Written by James Clark (jjc@jclark.com) 4114402Sru 5114402SruThis file is part of groff. 6114402Sru 7114402Srugroff is free software; you can redistribute it and/or modify it under 8114402Sruthe terms of the GNU General Public License as published by the Free 9114402SruSoftware Foundation; either version 2, or (at your option) any later 10114402Sruversion. 11114402Sru 12114402Srugroff is distributed in the hope that it will be useful, but WITHOUT ANY 13114402SruWARRANTY; without even the implied warranty of MERCHANTABILITY or 14114402SruFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15114402Srufor more details. 16114402Sru 17114402SruYou should have received a copy of the GNU General Public License along 18114402Sruwith groff; see the file COPYING. If not, write to the Free Software 19151497SruFoundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */ 20114402Sru 21114402Sru#include "eqn.h" 22114402Sru#include "pbox.h" 23114402Sru 24114402Sruclass limit_box : public box { 25114402Sruprivate: 26114402Sru box *p; 27114402Sru box *from; 28114402Sru box *to; 29114402Srupublic: 30114402Sru limit_box(box *, box *, box *); 31114402Sru ~limit_box(); 32114402Sru int compute_metrics(int); 33114402Sru void output(); 34114402Sru void debug_print(); 35114402Sru void check_tabs(int); 36114402Sru}; 37114402Sru 38114402Srubox *make_limit_box(box *pp, box *qq, box *rr) 39114402Sru{ 40114402Sru return new limit_box(pp, qq, rr); 41114402Sru} 42114402Sru 43114402Srulimit_box::limit_box(box *pp, box *qq, box *rr) 44114402Sru: p(pp), from(qq), to(rr) 45114402Sru{ 46114402Sru spacing_type = p->spacing_type; 47114402Sru} 48114402Sru 49114402Srulimit_box::~limit_box() 50114402Sru{ 51114402Sru delete p; 52114402Sru delete from; 53114402Sru delete to; 54114402Sru} 55114402Sru 56114402Sruint limit_box::compute_metrics(int style) 57114402Sru{ 58114402Sru printf(".nr " SIZE_FORMAT " \\n[.ps]\n", uid); 59114402Sru if (!(style <= SCRIPT_STYLE && one_size_reduction_flag)) 60114402Sru set_script_size(); 61114402Sru printf(".nr " SMALL_SIZE_FORMAT " \\n[.ps]\n", uid); 62114402Sru int res = 0; 63114402Sru int mark_uid = -1; 64114402Sru if (from != 0) { 65114402Sru res = from->compute_metrics(cramped_style(script_style(style))); 66114402Sru if (res) 67114402Sru mark_uid = from->uid; 68114402Sru } 69114402Sru if (to != 0) { 70114402Sru int r = to->compute_metrics(script_style(style)); 71114402Sru if (res && r) 72114402Sru error("multiple marks and lineups"); 73114402Sru else { 74114402Sru mark_uid = to->uid; 75114402Sru res = r; 76114402Sru } 77114402Sru } 78114402Sru printf(".ps \\n[" SIZE_FORMAT "]u\n", uid); 79114402Sru int r = p->compute_metrics(style); 80114402Sru p->compute_subscript_kern(); 81114402Sru if (res && r) 82114402Sru error("multiple marks and lineups"); 83114402Sru else { 84114402Sru mark_uid = p->uid; 85114402Sru res = r; 86114402Sru } 87114402Sru printf(".nr " LEFT_WIDTH_FORMAT " " 88114402Sru "0\\n[" WIDTH_FORMAT "]", 89114402Sru uid, p->uid); 90114402Sru if (from != 0) 91114402Sru printf(">?(\\n[" SUB_KERN_FORMAT "]+\\n[" WIDTH_FORMAT "])", 92114402Sru p->uid, from->uid); 93114402Sru if (to != 0) 94114402Sru printf(">?(-\\n[" SUB_KERN_FORMAT "]+\\n[" WIDTH_FORMAT "])", 95114402Sru p->uid, to->uid); 96114402Sru printf("/2\n"); 97114402Sru printf(".nr " WIDTH_FORMAT " " 98114402Sru "0\\n[" WIDTH_FORMAT "]", 99114402Sru uid, p->uid); 100114402Sru if (from != 0) 101114402Sru printf(">?(-\\n[" SUB_KERN_FORMAT "]+\\n[" WIDTH_FORMAT "])", 102114402Sru p->uid, from->uid); 103114402Sru if (to != 0) 104114402Sru printf(">?(\\n[" SUB_KERN_FORMAT "]+\\n[" WIDTH_FORMAT "])", 105114402Sru p->uid, to->uid); 106114402Sru printf("/2+\\n[" LEFT_WIDTH_FORMAT "]\n", uid); 107114402Sru printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]", uid, p->uid); 108114402Sru if (to != 0) 109114402Sru printf(">?\\n[" WIDTH_FORMAT "]", to->uid); 110114402Sru if (from != 0) 111114402Sru printf(">?\\n[" WIDTH_FORMAT "]", from->uid); 112114402Sru printf("\n"); 113114402Sru if (res) 114114402Sru printf(".nr " MARK_REG " +(\\n[" LEFT_WIDTH_FORMAT "]" 115114402Sru "-(\\n[" WIDTH_FORMAT "]/2))\n", 116114402Sru uid, mark_uid); 117114402Sru if (to != 0) { 118114402Sru printf(".nr " SUP_RAISE_FORMAT " %dM+\\n[" DEPTH_FORMAT 119114402Sru "]>?%dM+\\n[" HEIGHT_FORMAT "]\n", 120114402Sru uid, big_op_spacing1, to->uid, big_op_spacing3, p->uid); 121114402Sru printf(".nr " HEIGHT_FORMAT " \\n[" SUP_RAISE_FORMAT "]+\\n[" 122114402Sru HEIGHT_FORMAT "]+%dM\n", 123114402Sru uid, uid, to->uid, big_op_spacing5); 124114402Sru } 125114402Sru else 126114402Sru printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid); 127114402Sru if (from != 0) { 128114402Sru printf(".nr " SUB_LOWER_FORMAT " %dM+\\n[" HEIGHT_FORMAT 129114402Sru "]>?%dM+\\n[" DEPTH_FORMAT "]\n", 130114402Sru uid, big_op_spacing2, from->uid, big_op_spacing4, p->uid); 131114402Sru printf(".nr " DEPTH_FORMAT " \\n[" SUB_LOWER_FORMAT "]+\\n[" 132114402Sru DEPTH_FORMAT "]+%dM\n", 133114402Sru uid, uid, from->uid, big_op_spacing5); 134114402Sru } 135114402Sru else 136114402Sru printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid); 137114402Sru return res; 138114402Sru} 139114402Sru 140114402Sruvoid limit_box::output() 141114402Sru{ 142114402Sru printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid); 143114402Sru if (to != 0) { 144114402Sru printf("\\Z" DELIMITER_CHAR); 145114402Sru printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid); 146114402Sru printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u" 147114402Sru "+(-\\n[" WIDTH_FORMAT "]u+\\n[" SUB_KERN_FORMAT "]u/2u)'", 148114402Sru uid, to->uid, p->uid); 149114402Sru to->output(); 150114402Sru printf(DELIMITER_CHAR); 151114402Sru } 152114402Sru if (from != 0) { 153114402Sru printf("\\Z" DELIMITER_CHAR); 154114402Sru printf("\\v'\\n[" SUB_LOWER_FORMAT "]u'", uid); 155114402Sru printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u" 156114402Sru "+(-\\n[" SUB_KERN_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u)'", 157114402Sru uid, p->uid, from->uid); 158114402Sru from->output(); 159114402Sru printf(DELIMITER_CHAR); 160114402Sru } 161114402Sru printf("\\s[\\n[" SIZE_FORMAT "]u]", uid); 162114402Sru printf("\\Z" DELIMITER_CHAR); 163114402Sru printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u" 164114402Sru "-(\\n[" WIDTH_FORMAT "]u/2u)'", 165114402Sru uid, p->uid); 166114402Sru p->output(); 167114402Sru printf(DELIMITER_CHAR); 168114402Sru printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid); 169114402Sru} 170114402Sru 171114402Sruvoid limit_box::debug_print() 172114402Sru{ 173114402Sru fprintf(stderr, "{ "); 174114402Sru p->debug_print(); 175114402Sru fprintf(stderr, " }"); 176114402Sru if (from) { 177114402Sru fprintf(stderr, " from { "); 178114402Sru from->debug_print(); 179114402Sru fprintf(stderr, " }"); 180114402Sru } 181114402Sru if (to) { 182114402Sru fprintf(stderr, " to { "); 183114402Sru to->debug_print(); 184114402Sru fprintf(stderr, " }"); 185114402Sru } 186114402Sru} 187114402Sru 188114402Sruvoid limit_box::check_tabs(int level) 189114402Sru{ 190114402Sru if (to) 191114402Sru to->check_tabs(level + 1); 192114402Sru if (from) 193114402Sru from->check_tabs(level + 1); 194114402Sru p->check_tabs(level + 1); 195114402Sru} 196