1 
2 /* grGlyphs.c -
3  *
4  *	Handle glyphs -- reading and display.
5  *
6  *     *********************************************************************
7  *     * Copyright (C) 1985, 1990 Regents of the University of California. *
8  *     * Permission to use, copy, modify, and distribute this              *
9  *     * software and its documentation for any purpose and without        *
10  *     * fee is hereby granted, provided that the above copyright          *
11  *     * notice appear in all copies.  The University of California        *
12  *     * makes no representations about the suitability of this            *
13  *     * software for any purpose.  It is provided "as is" without         *
14  *     * express or implied warranty.  Export of this software outside     *
15  *     * of the United States of America may require an export license.    *
16  *     *********************************************************************
17  */
18 
19 #ifndef lint
20 static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/graphics/grGlyphs.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
21 #endif  /* not lint */
22 
23 #include <stdio.h>
24 #include <ctype.h>
25 #include <string.h>
26 
27 #include "utils/magic.h"
28 #include "utils/geometry.h"
29 #include "utils/utils.h"
30 #include "windows/windows.h"
31 #include "graphics/graphics.h"
32 #include "graphics/graphicsInt.h"
33 #include "graphics/glyphs.h"
34 #include "textio/textio.h"
35 #include "utils/malloc.h"
36 
37 #define STRLEN	500
38 
39 extern void (*grFreeCursorPtr)();
40 
41 
42 /*
43  * ----------------------------------------------------------------------------
44  * GrFreeGlyphs --
45  *
46  *	Free a malloc'ed glyph structure.
47  *
48  * Results:
49  *	None.
50  *
51  * Side effects:
52  *	None.
53  * ----------------------------------------------------------------------------
54  */
55 
56 void
GrFreeGlyphs(g)57 GrFreeGlyphs(g)
58     GrGlyphs *g;
59 {
60     int i;
61     ASSERT(g != NULL, "GrFreeGlyphs");
62 
63     if (grFreeCursorPtr != NULL)
64 	(*grFreeCursorPtr)(g);
65 
66 
67     for (i = 0; i < g->gr_num; i++)
68     {
69 	if ((g->gr_glyph[i]->gr_cache != (ClientData) NULL) &&
70 	    (g->gr_glyph[i]->gr_free != NULL))
71 	{
72 	    (*(g->gr_glyph[i]->gr_free))(g->gr_glyph[i]->gr_cache);
73 	}
74 	freeMagic( (char *) g->gr_glyph[i]);
75     }
76     freeMagic( (char *) g);
77 }
78 
79 
80 /*
81  * ----------------------------------------------------------------------------
82  * GrReadGlyphs --
83  *
84  *	Read a set of glyphs from the specified file.
85  *
86  * Results:
87  *	TRUE if it worked.
88  *
89  * Side effects:
90  *	A structure is malloc'ed and the last argument pointed to it.
91  *	Error messages are printed if there is any problem reading
92  *	the glyphs file.
93  * ----------------------------------------------------------------------------
94  */
95 
96 bool
GrReadGlyphs(filename,path,libPath,gl)97 GrReadGlyphs(filename, path, libPath, gl)
98     char *filename;
99     char *path, *libPath;	/* paths to search in for the file */
100     GrGlyphs **gl;		/* To be filled in with a malloc'ed structure
101 				 * This structure must be freed by the caller
102 				 * if it is not to live forever.
103 				 */
104 {
105     FILE *file;
106     bool result = TRUE;
107     GrGlyphs *ourgl = NULL;
108     int x, y, glyphnum;
109     int xmax, ymax, glyphnummax;
110     char line[STRLEN], *fullname;
111     bool sizeline = FALSE;
112 
113     file = PaOpen(filename, "r", ".glyphs", path, libPath, &fullname);
114     if (file == NULL)
115     {
116 	TxError("Couldn't read glyphs file \"%s.glyphs\"\n", filename);
117 	result = FALSE;
118 	goto endit;
119     }
120     y = glyphnum = glyphnummax = xmax = ymax = -1;
121 
122     while (TRUE)
123     {
124 	char *sres;
125 	sres = fgets(line, STRLEN, file);
126 	if (sres == NULL)  /* end of file */
127 	{
128 	    if ((y == 0) && (glyphnum == glyphnummax))
129 		result = TRUE;
130 	    else
131 	    {
132 		TxError("Unexpected end of file in file '%s'\n", fullname);
133 		result = FALSE;
134 	    }
135 	    goto endit;
136 	}
137 	else if (!StrIsWhite(line, TRUE))
138 	{
139 	    char *cp;
140 	    /* an interesting line */
141 	    if (sizeline)
142 	    {
143 		if (y > 0)
144 		    y--; 	/* scan from top down */
145 		else
146 		{
147 		    y = ymax;
148 		    glyphnum++;
149 		    if (glyphnum > glyphnummax)
150 		    {
151 			TxError("Extra lines at end of glyph file '%s'\n",
152 			    fullname);
153 			result = TRUE;
154 			goto endit;
155 		    }
156 		}
157 		cp = line;
158 
159 		for (x = 0; x <= xmax; x++)
160 		{
161 		    char trailingChar;
162 
163 		    if (isspace(*cp))
164 		    {
165 			TxError("Error in glyph file '%s', %s\n ", fullname,
166 			    "white space is not a valid glyph character");
167 			TxError("Line in error is '%s'\n", line);
168 			result = FALSE;
169 			goto endit;
170 		    }
171 		    ourgl->gr_glyph[glyphnum]->gr_pixels[x + (xmax+1) * y] =
172 			    GrStyleNames[ (*cp) & 127 ];
173 
174 		    cp++;
175 		    trailingChar = *cp;
176 		    if (trailingChar == '*')
177 		    {
178 			ourgl->gr_glyph[glyphnum]->gr_origin.p_x = x;
179 			ourgl->gr_glyph[glyphnum]->gr_origin.p_y = y;
180 		    }
181 
182 		    if (x != xmax)
183 		    {
184 			cp++;
185 			if ((trailingChar == '\0') || (*cp == '\0'))
186 			{
187 			    TxError("Error in glyph file '%s', %s\n ",
188 				fullname, "line is too short.");
189 			    TxError("Line in error is '%s'\n", line);
190 			    result = FALSE;
191 			    goto endit;
192 			}
193 		    }
194 		}
195 	    }
196 	    else
197 	    {
198 		int i;
199 		if (sscanf(line, "size %d %d %d\n",
200 			&glyphnummax, &xmax, &ymax) != 3)
201 		{
202 		    TxError("Format error in  file '%s'\n", fullname);
203 		    result = FALSE;
204 		    goto endit;
205 		}
206 		sizeline = TRUE;
207 		glyphnummax--;
208 		xmax--;
209 		ymax--;
210 		glyphnum = 0;
211 		x = 0;
212 		y = ymax + 1;
213 		ourgl = (GrGlyphs *) mallocMagic((unsigned) (sizeof(GrGlyphs) +
214 			((glyphnummax + 1) * sizeof(GrGlyph *))) );
215 		ourgl->gr_num = glyphnummax + 1;
216 		for (i = 0; i <= glyphnummax; i++)
217 		{
218 		    size_t size = sizeof(GrGlyph) + sizeof(int) * (xmax + 1)
219 				* (ymax + 1);
220 		    ourgl->gr_glyph[i] = (GrGlyph *) mallocMagic(size);
221 
222 		    /* Null all the fields initially. */
223 		    memset(ourgl->gr_glyph[i], 0, size);
224 
225 		    ourgl->gr_glyph[i]->gr_origin.p_x = 0;
226 		    ourgl->gr_glyph[i]->gr_origin.p_y = 0;
227 		    ourgl->gr_glyph[i]->gr_xsize = xmax + 1;
228 		    ourgl->gr_glyph[i]->gr_ysize = ymax + 1;
229 		}
230 	    }
231 	}
232     }
233 
234 endit:
235     if (file != NULL)
236 	(void) fclose(file);
237     if (result)
238 	*gl = ourgl;
239     else if (ourgl != NULL)
240 	GrFreeGlyphs(ourgl);
241     return result;
242 }
243