1 /* frac.c: layout/dimentioning and drawing routines for fractions. */
2 
3 /*  This file is part of asciiTeX.
4 
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License
15     along with this program; see the file COPYING.  If not, write to
16       The Free Software Foundation, Inc.
17       59 Temple Place, Suite 330
18       Boston, MA 02111 USA
19 
20 
21     Authors:
22     Original program (eqascii): Przemek Borys
23     Fork by: Bart Pieters
24 
25 *************************************************************************/
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include "parsedef.h"
31 #include "asciiTeX_struct.h"
32 #include "utils.h"
33 #include "frac.h"
34 #include "dim.h"
35 #include "draw.h"
36 
37 int
dimFrac(char * found,char ** Gpos,Tdim * Our,struct Tgraph * graph)38 dimFrac(char *found, char **Gpos, Tdim * Our, struct Tgraph *graph)
39 /*
40 The dimXxx routines all have the forllowing arguments:
41 found		--	Pointer to a sting containing the remaining part of the equation
42 Gpos		--	Pointer to a string which will contain the part of the equation
43 			relevant to the current parent with flags to indicate which drawing
44 			routines to use.
45 Our		--	dimention of the parent
46 graph		--	The parent
47 The routines returns the number of characters it used of the found vector.
48 */
49 {
50 	Tdim            out;
51 	char           *start,
52 	               *end,
53 	               *tmp;
54 #define our (*Our)
55 #define gpos (*Gpos)
56 	int             height = 0,
57 	    width = 0;
58 
59 	*gpos = 1;		/* See parsedef.h for the keyword
60 				 * definitions */
61 	gpos++;
62 	*gpos = (char) FRAC;
63 	gpos++;
64 	*gpos = 0;
65 
66 	start = strchr(found, '{');
67 	if (start)
68 		end = findClosingBrace(start + 1);
69 	if (!start || !end || (end - start < 2))
70 	{
71 		SyntaxError("Usage: \\frac{num}{den}\n\tProduces the fraction num divided by den.\n");
72 		return 0;
73 	}
74 	if (start - found - 5 > 0)
75 		fprintf(stderr,
76 			"Warning spurious characters ignores in \\frac\n");
77 
78 	*end = 0;
79 	tmp = strdup(start + 1);
80 	*end = '}';
81 
82 	out = dim(tmp, newChild(graph));
83 	free(tmp);
84 	height += out.y;
85 	width = out.x;
86 
87 	start = strchr(end, '{');
88 	if (start - end - 1 > 0)
89 		SyntaxWarning("Warning spurious characters ignored in \\frac\n");
90 	if (start)
91 		end = findClosingBrace(start + 1);
92 
93 	if (!start || !end || (end - start < 2))
94 	{
95 		SyntaxError("Usage: \\frac{num}{den}\n\tProduces the fraction num divided by den.\n");
96 		return 0;
97 	}
98 
99 	*end = 0;
100 	tmp = strdup(start + 1);
101 	*end = '}';
102 	out = dim(tmp, newChild(graph));
103 	free(tmp);
104 
105 	if (out.y > our.baseline)
106 	{
107 		our.y += out.y - our.baseline;
108 		our.baseline = out.y;	/* baseline+(out.y-baseline) */
109 	}
110 	if (height > our.y - our.baseline - 1)
111 	{
112 		our.y += height - (our.y - our.baseline - 1);
113 	}
114 	if (out.x > width)
115 		our.x += out.x;
116 	else
117 		our.x += width;
118 
119 	if (our.baseline < out.y)
120 		our.baseline = out.y;
121 	return end - (found);	/* skip parsed text */
122 #undef our
123 #undef gpos
124 }
125 
126 void
drawFrac(int * Kid,int * Curx,int * Cury,char *** screen,struct Tgraph * graph)127 drawFrac(int *Kid, int *Curx, int *Cury, char ***screen,
128 	 struct Tgraph *graph)
129 /*
130 The drawXxx routines all have the forllowing arguments:
131 Kid		--	Ineger index of the current child
132 Curx		--	Current x position in the 2D character field
133 Cury		--	Current y position in the 2D character field
134 screen		--	pointer to the 2D character field
135 graph		--	The parent
136 */
137 {
138 #define kid (*Kid)
139 #define curx (*Curx)
140 #define cury (*Cury)
141 	int             width = graph->down[kid]->dim.x;
142 	int             i;
143 	if (width < graph->down[kid + 1]->dim.x)
144 		width = graph->down[kid + 1]->dim.x;
145 	drawInternal(screen, graph->down[kid],
146 		     curx + width / 2 - (graph->down[kid]->dim.x) / 2,
147 		     cury - (graph->down[kid]->dim.y));
148 	drawInternal(screen, graph->down[kid + 1],
149 		     curx + width / 2 - (graph->down[kid + 1]->dim.x) / 2,
150 		     cury + 1);
151 	for (i = 0; i < width; i++)
152 		(*screen)[cury][curx++] = '-';
153 	kid += 2;
154 
155 }
156