2 /* $XConsortium: to_wfont.y /main/9 1996/06/11 07:38:48 kaleb $ */
3 /* $XFree86: xc/fonts/PEX/to_wfont.y,v 3.6.2.1 1998/12/22 11:23:04 hohndel Exp $ */
5 /*****************************************************************
7 Copyright (c) 1989,1990, 1991 X Consortium
9 Permission is hereby granted, free of charge, to any person obtaining a copy
10 of this software and associated documentation files (the "Software"), to deal
11 in the Software without restriction, including without limitation the rights
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom the Software is
14 furnished to do so, subject to the following conditions:
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 Except as contained in this notice, the name of the X Consortium shall not be
27 used in advertising or otherwise to promote the sale, use or other dealings
28 in this Software without prior written authorization from the X Consortium.
30 Copyright (c) 1989,1990, 1991 by Sun Microsystems, Inc.
34 Permission to use, copy, modify, and distribute this software and its
35 documentation for any purpose and without fee is hereby granted,
36 provided that the above copyright notice appear in all copies and that
37 both that copyright notice and this permission notice appear in
38 supporting documentation, and that the names of Sun Microsystems,
39 and the X Consortium, not be used in advertising or publicity
40 pertaining to distribution of the software without specific, written
43 SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
44 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
45 SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
46 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
47 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
48 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
51 ******************************************************************/
54 #define YYMAXDEPTH 10000
63 #define L_SET SEEK_SET
68 float std_left, /* NCGA standard left spacing */
69 std_wide, /* character width */
70 std_rght; /* Right spacing */
75 Dispatch *Table; /* dispatch table */
76 Standard *sp_table; /* NCGA font spacings */
77 Path *strokes; /* strokes of each character */
78 Property *property; /* property list */
81 int path, point, props;
84 Path_subpath *current_path;
86 Font_header head; /* font header */
87 int tableindex; /* which character */
88 int yyerrno; /* error number */
94 void init_properties(int);
95 void check_num_props(void);
96 void add_property(char *, char *);
97 void check_num_ch(void);
98 void wf_header(char *, float, float);
99 void glyph_header(int, float, float, int);
100 void std_space(float, float, float);
101 void init_path(int, int);
102 void add_point(float, float);
105 void check_nstroke(void);
106 void check_npts(void);
111 int nil; /* void is reserved */
120 %token <ival> INTEGER
126 %token <nil> FONTNAME
127 %token <nil> PROPERTIES
137 %token <nil> VERTICES
141 %type <cval> fontname
142 %type <dval> top bottom center right
143 %type <ival> nstroke nvertice n_pts index num_ch
144 %type <ival> closeflag
146 %type <dval> sp_left wide sp_right
150 font : fontheader num_ch fontprops fontbody spacing { fini(); }|
151 fontheader fontbody { fini(); };
153 fontheader : fontname top bottom
154 { wf_header($1, $2, $3); };
156 fontname : FONTNAME STRING
159 top : TOP REAL { $$ = $2;};
161 bottom : BOTTOM REAL { $$ = $2;};
163 num_ch: NUM_CH INTEGER { set_num_ch($2);};
165 fontprops : /* empty */ | properties;
167 properties : PROPERTIES INTEGER { init_properties ($2); } property_list
168 { check_num_props (); }
170 property_list : /* empty */ | single_property property_list
172 single_property : STRING STRING { add_property($1, $2); };
174 fontbody : /* empty */
177 glyph : glyph_header strokes
178 { check_nstroke(); };
180 glyph_header : index { tableindex = $1; } sym_headinfo;
182 sym_headinfo : nstroke center right nvertice
183 { glyph_header($1, $2, $3, $4); };
185 index : INDEX INTEGER { check_num_ch(); $$ = $2; };
187 nstroke : STROKE INTEGER { $$ = $2; expect.path = $2; };
189 nvertice: {$$ = 0;} | VERTICES INTEGER { $$ = $2; } ;
191 center : CENTER REAL{ $$ = $2; };
193 right : RIGHT REAL{ $$ = $2; };
195 strokes : /* empty */ | path strokes;
197 path : closeflag n_pts { init_path($1, $2); } points
200 points : /* empty */ | coord points;
202 closeflag : CLOSE { $$ = $1 == CLOSE; } | OPEN { $$ = $1 == CLOSE; } ;
204 n_pts : INTEGER { $$ = $1; };
206 coord : REAL REAL { add_point($1, $2); };
208 spacing : /* empty */
211 item : counter {tableindex = $1;} sp_left wide sp_right
212 { std_space($3, $4, $5); };
214 counter : BEARING INTEGER {$$ = $2;};
216 sp_left: L_SPACE REAL {$$ = $2;};
218 wide : WIDTH REAL {$$ = $2;};
220 sp_right: R_SPACE REAL {$$ = $2;};
224 #define BYE(err) yyerrno = (err), yyerror(NULL)
226 #define ERR_BASE 1000
227 #define OPEN_ERROR 1001
228 #define WRITE_ERROR 1002
229 #define WRONG_NAME 1003
230 #define NO_MEMORY 1004
231 #define EXCEED_PATH 1005
232 #define EXCEED_POINT 1006
233 #define PATH_MISMATCH 1007
234 #define POINT_MISMATCH 1008
235 #define PROP_MISMATCH 1009
236 #define EXCEED_PROPS 1010
242 int main(int argc, char **argv)
244 /* Usage : genstroke [-o outfile] [infile] */
252 while (--argc > 0 && *++argv != NULL)
263 (void) strcpy(fname, *argv);
266 default: /* ignore other options */
274 /* standard input redirection */
275 fd = open(*argv, O_RDONLY);
278 if (close(fileno(stdin)) < 0)
295 /* set number of characters */
296 void set_num_ch(int num_ch)
299 head.num_ch = num_ch;
302 Table = (Dispatch *) malloc(num_ch * sizeof(Dispatch));
303 sp_table = (Standard *) malloc(num_ch * sizeof(Standard));
304 strokes = (Path *) malloc(num_ch * sizeof(Path));
307 for (tableindex = 0; tableindex < num_ch; tableindex++)
309 Table[tableindex].center = 0.0;
310 Table[tableindex].right = 0.0;
311 Table[tableindex].offset = 0;
313 sp_table[tableindex].std_left = 0.0;
314 sp_table[tableindex].std_wide = 0.0;
315 sp_table[tableindex].std_rght = 0.0;
317 strokes[tableindex].n_subpaths = 0;
318 strokes[tableindex].n_vertices = 0;
319 strokes[tableindex].subpaths = NULL;
323 /* initialize the property info in the header */
324 void init_properties(int num_props)
328 head.properties = malloc(num_props * sizeof(Property));
329 head.num_props = expect.props = num_props;
333 head.properties = NULL;
334 head.num_props = expect.props = 0;
337 property = head.properties; /* initialize the list pointer */
340 void check_num_props(void)
343 if (count.props != expect.props)
347 /* add individual property info into the buffer */
348 void add_property(char *name, char *value)
350 /* check if the property exceeds allocated space */
352 if (++count.props >= head.num_props)
355 /* copy the strings into the buffer */
357 (void) strcpy(property->propname, name);
358 (void) strcpy(property->propvalue, value);
360 /* increment the property pointer */
365 void check_num_ch(void)
367 if (head.num_ch == -1)
371 void yyerror(char *str)
373 # define ERR_SIZE (sizeof(err_string) / sizeof(char *))
374 static char *err_string[] = {
378 "Memory allocation failure",
379 "Specified number of strokes exceeded",
380 "Specified number of points exceeded",
381 "Number of strokes do not match",
382 "Number of points do not match",
383 "Number of properties do not match",
384 "Specified number of properties exceeded",
390 if (yyerrno > 0 && yyerrno < ERR_SIZE)
391 str = err_string[yyerrno-1];
393 str = "Syntax error";
395 fprintf(stderr, "%s.\n", str);
397 (void) unlink(fname);
401 /* create wfont header */
402 void wf_header(char *name, float top, float bottom)
407 head.bottom = bottom;
408 head.magic = WFONT_MAGIC_PEX;
409 (void) strcpy(head.name, name);
413 /* create header for each glyph */
414 void glyph_header(int npath, float center, float right, int npts)
417 register Path *strk = strokes + tableindex;
419 if (npath > 0) /* Don't allocate space unless the character
420 has strokes associated with it. */
422 strk->subpaths = malloc(npath * sizeof(Path_subpath));
424 if (strk->subpaths == NULL)
427 strk->type = PATH_2DF;
428 strk->n_subpaths = npath;
429 strk->n_vertices = npts;
431 else /* Just initialize the entry */
433 strk->subpaths = NULL;
434 strk->type = PATH_2DF;
435 strk->n_subpaths = 0;
436 strk->n_vertices = 0;
440 register Dispatch *tbl = Table + tableindex;
443 tbl->center = center;
446 count.path = -1; /* initialize path counter, not to
447 * exceed n_subpath */
450 /* create standard spacing info for each glyph */
451 void std_space(float l_bear, float wide, float r_bear)
453 register Standard *tbl = sp_table + tableindex;
454 tbl->std_left = l_bear;
455 tbl->std_wide = wide;
456 tbl->std_rght = r_bear;
459 /* initialize each sub_path */
460 void init_path(int close, int n)
462 register Path_subpath *path;
464 if (++count.path >= strokes[tableindex].n_subpaths)
466 path = current_path = strokes[tableindex].subpaths + count.path;
468 path->closed = close;
470 path->pts.pt2df = malloc(n * sizeof(Path_point2df));
471 if (path->pts.pt2df == NULL)
473 expect.point = path->n_pts;
474 count.point = -1; /* initialize point counter, not to
478 /* accumulating points for each sub_path */
479 void add_point(float x, float y)
481 register Path_subpath *path;
482 register Path_point2df *pt_ptr;
485 if (++count.point >= path->n_pts)
487 pt_ptr = path->pts.pt2df + count.point;
492 /* Path_type + n_subpaths + n_vertices */
493 #define STROKE_HEAD (sizeof(Path_type) + sizeof(int) + sizeof(int))
495 /* write out file, close everything, free everything */
498 /* pointers used to walk the arrays */
499 register Path_subpath *spath;
500 register Dispatch *tbl_ptr;
501 register Path *strptr;
505 register int i, j, k;
509 if (fname[0] == 0) /* default output file name */
511 (void) strcpy(fname, head.name);
512 (void) strcat(fname, ".c");
515 if ((fp = fopen(fname, "w")) == NULL)
518 fprintf(fp, "\n/* This file has been automatically generated by the genstroke utility. */\n");
519 fprintf(fp, "\n#include \"../include/GL/freeglut_internal.h\"\n");
521 # define BY_BYE(err) fclose(fp), BYE(err)
523 /* adjust the characters for spacing, note max char width */
524 head.max_width = 0.0;
525 for (i = 0, tbl_ptr = Table, strptr = strokes, sp_ptr = sp_table;
526 i < head.num_ch; i++, tbl_ptr++, strptr++, sp_ptr++)
528 tbl_ptr->center += sp_ptr->std_left;
529 tbl_ptr->right += sp_ptr->std_left + sp_ptr->std_rght;
530 if (tbl_ptr->right > head.max_width)
531 head.max_width = tbl_ptr->right;
532 npath = strptr->n_subpaths;
533 if (npath > 0 || tbl_ptr->center != 0.0 ||
534 tbl_ptr->right != 0.0)
536 for (j = 0, spath = strptr->subpaths;
537 j < npath; j++, spath++)
539 for(k=0, pt = spath->pts.pt2df;
540 k<spath->n_pts; k++, pt++)
542 pt->x += sp_ptr->std_left;
548 /* write the stroke table */
549 for (i = 0, tbl_ptr = Table, strptr = strokes;
550 i < head.num_ch; i++, tbl_ptr++, strptr++)
552 npath = strptr->n_subpaths;
554 if (npath > 0 || tbl_ptr->center != 0.0 ||
555 tbl_ptr->right != 0.0)
557 fprintf(fp, "\n/* char: 0x%x */\n", i);
559 for (j = 0, spath = strptr->subpaths;
560 j < npath; j++, spath++)
562 fprintf(fp, "\nstatic const SFG_StrokeVertex ch%ust%u[] =\n{\n", i, j);
563 for(k = 0; k < spath->n_pts; k++)
565 fprintf(fp, " {%g,%g}%s\n",
566 spath->pts.pt2df[k].x,
567 spath->pts.pt2df[k].y,
568 k+1 < spath->n_pts ? "," : "");
573 fprintf(fp, "\nstatic const SFG_StrokeStrip ch%ust[] =\n{\n", i);
574 for (j = 0, spath = strptr->subpaths;
575 j < npath; j++, spath++)
577 fprintf(fp, " {%u,ch%ust%u}%s\n",
579 j+1 < npath ? "," : "");
583 fprintf(fp, "\nstatic const SFG_StrokeChar ch%u = {%g,%u,ch%ust};\n",
584 i, tbl_ptr->right, npath, i);
588 fprintf(fp, "\nstatic const SFG_StrokeChar *chars[] =\n{\n");
590 for (i = 0, tbl_ptr = Table, strptr = strokes;
593 for (j = 0; j < 8 && i < head.num_ch;
594 j++, i++, tbl_ptr++, strptr++)
597 npath = strptr->n_subpaths;
598 if (npath > 0 || tbl_ptr->center != 0.0 ||
599 tbl_ptr->right != 0.0)
600 fprintf(fp, "&ch%u", i);
603 if (i+1 < head.num_ch)
610 fprintf(fp, "\nconst SFG_StrokeFont fgStroke%s = {\"%s\",%d,%g,chars};\n",
611 head.name, head.name, head.num_ch, head.top - head.bottom);
621 register Path_subpath *spath;
622 register int i, j, n;
625 for (i = 0; i < head.num_ch; i++, path++)
627 n = path->n_subpaths;
630 spath = path->subpaths;
631 for (j = 0; j < n; j++, spath++)
632 if (spath->pts.pt2df != NULL)
633 free((char *) spath->pts.pt2df);
634 if (path->subpaths != NULL)
635 free((char *) path->subpaths);
643 if (head.properties != NULL)
644 free((char *) head.properties);
647 void check_nstroke(void)
650 if (expect.path != count.path)
654 void check_npts(void)
657 if (expect.point != count.point)