xref: /netbsd-src/external/gpl2/groff/dist/src/preproc/eqn/limit.cpp (revision 89a07cf815a29524268025a1139fac4c5190f765)
1 /*	$NetBSD: limit.cpp,v 1.1.1.1 2016/01/13 18:41:49 christos Exp $	*/
2 
3 // -*- C++ -*-
4 /* Copyright (C) 1989, 1990, 1991, 1992, 2002 Free Software Foundation, Inc.
5      Written by James Clark (jjc@jclark.com)
6 
7 This file is part of groff.
8 
9 groff is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
12 version.
13 
14 groff is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18 
19 You should have received a copy of the GNU General Public License along
20 with groff; see the file COPYING.  If not, write to the Free Software
21 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
22 
23 #include "eqn.h"
24 #include "pbox.h"
25 
26 class limit_box : public box {
27 private:
28   box *p;
29   box *from;
30   box *to;
31 public:
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 
make_limit_box(box * pp,box * qq,box * rr)40 box *make_limit_box(box *pp, box *qq, box *rr)
41 {
42   return new limit_box(pp, qq, rr);
43 }
44 
limit_box(box * pp,box * qq,box * rr)45 limit_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 
~limit_box()51 limit_box::~limit_box()
52 {
53   delete p;
54   delete from;
55   delete to;
56 }
57 
compute_metrics(int style)58 int 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 
output()142 void 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 
debug_print()173 void 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 
check_tabs(int level)190 void 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