1 /* sscript.c: layout/dimentioning and drawing routines for super and sub
2    scripts. */
3 
4 /*  This file is part of asciiTeX.
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program; see the file COPYING.  If not, write to
17       The Free Software Foundation, Inc.
18       59 Temple Place, Suite 330
19       Boston, MA 02111 USA
20 
21 
22     Authors:
23     Original program (eqascii): Przemek Borys
24     Fork by: Bart Pieters
25 
26 *************************************************************************/
27 
28 #include <string.h>
29 #include <stdlib.h>
30 #include "parsedef.h"
31 #include "utils.h"
32 #include "asciiTeX_struct.h"
33 #include "dim.h"
34 #include "draw.h"
35 
36 int
dimSubscript(char * found,char ** Gpos,Tdim * Our,struct Tgraph * graph)37 dimSubscript(char *found, char **Gpos, Tdim * Our, struct Tgraph *graph)
38 /*
39 The dimXxx routines all have the forllowing arguments:
40 found		--	Pointer to a sting containing the remaining part of the equation
41 Gpos		--	Pointer to a string which will contain the part of the equation
42 			relevant to the current parent with flags to indicate which drawing
43 			routines to use.
44 Our		--	dimention of the parent
45 graph		--	The parent
46 The routines returns the number of characters it used of the found vector.
47 */
48 {
49 #define gpos (*Gpos)
50 #define our (*Our)
51 	char           *start = found + 1,
52 	    *end,
53 	    *tmp;
54 	Tdim            out;
55 
56 	*gpos = 1;
57 	gpos++;
58 	*gpos = (char) SUB;
59 	gpos++;
60 	*gpos = 0;
61 
62 	end = findClosingBrace(start + 1);
63 	*end = 0;
64 	tmp = strdup(start + 1);
65 	*end = '}';
66 	out = dim(tmp, newChild(graph));
67 	free(tmp);
68 	if (out.y > our.baseline)
69 	{
70 		our.baseline = out.y;
71 		our.y += out.y;
72 	}
73 	if (gpos - graph->txt >= 4)
74 	{			/* check if we had a superscript before */
75 		if ((*(gpos - 4) == 1) && (*(gpos - 3) == (char) SUPER))
76 		{		/* yep, we had it */
77 			int             width =
78 			    graph->down[graph->children - 2]->dim.x;
79 			if (width < out.x)
80 				our.x += out.x - width;
81 		} else
82 			our.x += out.x;
83 	} else
84 		our.x += out.x;
85 	return end - found;
86 #undef gpos
87 #undef our
88 }
89 
90 void
drawSubscript(int * Kid,int * Curx,int * Cury,char *** screen,struct Tgraph * graph,char * txt)91 drawSubscript(int *Kid, int *Curx, int *Cury, char ***screen,
92 	      struct Tgraph *graph, char *txt)
93 {
94 #define kid (*Kid)
95 #define curx (*Curx)
96 #define cury (*Cury)
97 	int             width = graph->down[kid]->dim.x;
98 	if (txt - 3 >= graph->txt)
99 	{
100 		if ((*(txt - 3) == 1) && (*(txt - 2) == (char) SUPER))
101 		{
102 			drawInternal(screen, graph->down[kid],
103 				     curx - (graph->down[kid - 1]->dim.x),
104 				     cury + 1);
105 			if (width > graph->down[kid - 1]->dim.y)
106 				curx +=
107 				    width - graph->down[kid - 1]->dim.y;
108 		} else
109 		{
110 			drawInternal(screen, graph->down[kid], curx,
111 				     cury + 1);
112 			curx += width;
113 		}
114 	} else
115 	{
116 		drawInternal(screen, graph->down[kid], curx, cury + 1);
117 		curx += width;
118 	}
119 	kid++;
120 
121 }
122 
123 int
dimSuperscript(char * found,char ** Gpos,Tdim * Our,struct Tgraph * graph)124 dimSuperscript(char *found, char **Gpos, Tdim * Our, struct Tgraph *graph)
125 /*
126 The dimXxx routines all have the forllowing arguments:
127 found		--	Pointer to a sting containing the remaining part of the equation
128 Gpos		--	Pointer to a string which will contain the part of the equation
129 			relevant to the current parent with flags to indicate which drawing
130 			routines to use.
131 Our		--	dimention of the parent
132 graph		--	The parent
133 The routines returns the number of characters it used of the found vector.
134 */
135 {
136 #define gpos (*Gpos)
137 #define our (*Our)
138 	char           *start = found + 1,
139 	    *end,
140 	    *tmp;
141 	Tdim            out;
142 
143 	*gpos = 1;		/* See parsedef.h for the keyword
144 				 * definitions */
145 	gpos++;
146 	*gpos = (char) SUPER;
147 	gpos++;
148 	*gpos = 0;
149 
150 	end = findClosingBrace(start + 1);
151 	*end = 0;
152 	tmp = strdup(start + 1);
153 	*end = '}';
154 	out = dim(tmp, newChild(graph));
155 	free(tmp);
156 	if (out.y + 1 > our.y - our.baseline)
157 		our.y = our.baseline + out.y + 1;
158 
159 	if (gpos - graph->txt >= 4)
160 	{			/* check if we had a subscript before */
161 		if ((*(gpos - 4) == 1) && (*(gpos - 3) == (char) SUB))
162 		{		/* yep, we had it--our superscript will
163 				 * start at the same pos as the subscript */
164 			int             width =
165 			    graph->down[graph->children - 2]->dim.x;
166 			if (width < out.x)
167 				our.x += out.x - width;
168 		} else
169 			our.x += out.x;
170 	} else
171 		our.x += out.x;
172 	return end - found;
173 }
174 
175 void
drawSuperscript(int * Kid,int * Curx,int * Cury,char *** screen,struct Tgraph * graph,char * txt)176 drawSuperscript(int *Kid, int *Curx, int *Cury, char ***screen,
177 		struct Tgraph *graph, char *txt)
178 /*
179 The drawXxx routines all have the forllowing arguments:
180 Kid		--	Ineger index of the current child
181 Curx		--	Current x position in the 2D character field
182 Cury		--	Current y position in the 2D character field
183 screen		--	pointer to the 2D character field
184 graph		--	The parent
185 */
186 {
187 #define kid (*Kid)
188 #define curx (*Curx)
189 #define cury (*Cury)
190 	int             width = graph->down[kid]->dim.x;
191 	if (txt - 3 >= graph->txt)
192 	{
193 		if ((*(txt - 3) == 1) && (*(txt - 2) == (char) SUB))
194 		{
195 			drawInternal(screen, graph->down[kid],
196 				     curx - (graph->down[kid - 1]->dim.x),
197 				     cury - (graph->down[kid]->dim.y));
198 			if (width > graph->down[kid - 1]->dim.x)
199 				curx +=
200 				    width - graph->down[kid - 1]->dim.x;
201 		} else
202 		{
203 			drawInternal(screen, graph->down[kid], curx,
204 				     cury - (graph->down[kid]->dim.y));
205 			curx += width;
206 		}
207 	} else
208 	{
209 		drawInternal(screen, graph->down[kid], curx,
210 			     cury - (graph->down[kid]->dim.y));
211 		curx += width;
212 	}
213 	kid++;
214 
215 }
216