strokegen.y
上传用户:xk288cn
上传日期:2007-05-28
资源大小:4876k
文件大小:17k
源码类别:

GIS编程

开发平台:

Visual C++

  1. %{
  2. /* $XConsortium: to_wfont.y,v 5.7 94/04/17 20:10:08 rws Exp $ */
  3. /*****************************************************************
  4. Copyright (c) 1989,1990, 1991  X Consortium
  5. Permission is hereby granted, free of charge, to any person obtaining a copy
  6. of this software and associated documentation files (the "Software"), to deal
  7. in the Software without restriction, including without limitation the rights
  8. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. copies of the Software, and to permit persons to whom the Software is
  10. furnished to do so, subject to the following conditions:
  11. The above copyright notice and this permission notice shall be included in
  12. all copies or substantial portions of the Software.
  13. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
  16. X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  17. AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  18. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  19. Except as contained in this notice, the name of the X Consortium shall not be
  20. used in advertising or otherwise to promote the sale, use or other dealings
  21. in this Software without prior written authorization from the X Consortium.
  22. Copyright (c) 1989,1990, 1991 by Sun Microsystems, Inc.
  23.                         All Rights Reserved
  24. Permission to use, copy, modify, and distribute this software and its 
  25. documentation for any purpose and without fee is hereby granted, 
  26. provided that the above copyright notice appear in all copies and that
  27. both that copyright notice and this permission notice appear in 
  28. supporting documentation, and that the names of Sun Microsystems,
  29. and the X Consortium, not be used in advertising or publicity 
  30. pertaining to distribution of the software without specific, written 
  31. prior permission.  
  32. SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 
  33. INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT 
  34. SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 
  35. DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  36. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  37. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  38. SOFTWARE.
  39. ******************************************************************/
  40. #define YYMAXDEPTH 10000
  41. #include <X11/Xos.h>
  42. #include <stdio.h>
  43. #include <ctype.h>
  44. #ifndef L_SET
  45. #define L_SET SEEK_SET
  46. #endif
  47. #include "stroke.h"
  48. #ifdef X_NOT_STDC_ENV
  49. FILE *fopen();
  50. #endif
  51. typedef struct {
  52.         float           std_left,      /* NCGA standard left spacing */
  53.                         std_wide,      /* character width            */  
  54.                         std_rght;      /* Right spacing              */  
  55. }               Standard;
  56. char            fname[80];
  57. char            symname[80] = "FONT";
  58. Dispatch        *Table;    /* dispatch table */
  59. Standard *sp_table; /* NCGA font spacings */
  60. Path            *strokes;  /* strokes of each character */
  61. Property        *property; /* property list */
  62. struct {
  63. int path, point, props;
  64. } count, expect;
  65. Path_subpath   *current_path;
  66. Font_header     head; /* font header */
  67. int             tableindex; /* which character */
  68. int             yyerrno; /* error number */
  69. %}
  70. %union {
  71. int nil; /* void is reserved */
  72. int ival;
  73. float dval;
  74. char *cval;
  75. }
  76. %start font
  77. %token <dval> REAL
  78. %token <ival> INTEGER
  79. %token <cval> STRING
  80. %token <nil> BOTTOM
  81. %token <nil> CENTER
  82. %token <nil> CLOSE
  83. %token <nil> FONTNAME
  84. %token <nil> PROPERTIES
  85. %token <nil> NUM_CH
  86. %token <nil> INDEX
  87. %token <nil> L_SPACE
  88. %token <nil> MAGIC
  89. %token <nil> OPEN
  90. %token <nil> RIGHT
  91. %token <nil> R_SPACE
  92. %token <nil> STROKE
  93. %token <nil> TOP
  94. %token <nil> VERTICES
  95. %token <nil> BEARING
  96. %token <nil> WIDTH
  97. %type <cval> fontname
  98. %type <ival> properties
  99. %type <dval> top bottom center right
  100. %type <ival> nstroke nvertice n_pts index num_ch
  101. %type <ival> closeflag
  102. %type <ival> counter
  103. %type <dval> sp_left wide sp_right
  104. %%
  105. font : fontheader num_ch fontprops fontbody spacing { fini(); }|
  106. fontheader fontbody  { fini(); };
  107. fontheader : fontname top bottom 
  108. { wf_header($1, $2, $3); };
  109. fontname : FONTNAME STRING
  110. { $$ = $2; };
  111. top : TOP REAL { $$ = $2;};
  112. bottom : BOTTOM REAL { $$ = $2;};
  113. num_ch: NUM_CH INTEGER { set_num_ch($2);};
  114. fontprops : /* empty */ | properties;
  115. properties : PROPERTIES INTEGER { init_properties ($2); } property_list
  116.         { check_num_props (); }
  117. property_list : /* empty */ | single_property property_list
  118. single_property : STRING STRING { add_property($1, $2); };
  119. fontbody :  /* empty */ 
  120. | glyph fontbody;
  121. glyph : glyph_header strokes
  122. { check_nstroke(); };
  123. glyph_header : index { tableindex = $1; } sym_headinfo;
  124. sym_headinfo :  nstroke center right nvertice
  125. { glyph_header($1, $2, $3, $4); };
  126. index : INDEX INTEGER { check_num_ch(); $$ = $2; };
  127. nstroke : STROKE INTEGER { $$ = $2; expect.path = $2; };
  128. nvertice: {$$ = 0;} | VERTICES INTEGER  { $$ = $2; }  ;
  129. center : CENTER REAL{ $$ = $2; };
  130. right : RIGHT REAL{ $$ = $2; };
  131. strokes : /* empty */ | path strokes;
  132. path : closeflag n_pts { init_path($1, $2); } points
  133. { check_npts(); }
  134. points :  /* empty */ | coord points;
  135. closeflag : CLOSE { $$ = $1 == CLOSE; } | OPEN { $$ = $1 == CLOSE; } ;
  136. n_pts : INTEGER { $$ = $1; };
  137. coord : REAL REAL { add_point($1, $2); };
  138. spacing :  /* empty */ 
  139. | item spacing;
  140. item : counter {tableindex = $1;} sp_left wide sp_right
  141. { std_space($3, $4, $5); };
  142. counter  : BEARING INTEGER {$$ = $2;};
  143. sp_left: L_SPACE REAL {$$ = $2;};
  144. wide :  WIDTH REAL {$$ = $2;};
  145. sp_right: R_SPACE REAL {$$ = $2;};
  146. %%
  147. #define BYE(err) yyerrno = (err), yyerror()
  148. #define ERR_BASE 1000
  149. #define OPEN_ERROR  1001
  150. #define WRITE_ERROR  1002
  151. #define WRONG_NAME  1003
  152. #define NO_MEMORY  1004
  153. #define EXCEED_PATH  1005
  154. #define EXCEED_POINT  1006
  155. #define PATH_MISMATCH 1007
  156. #define POINT_MISMATCH 1008
  157. #define PROP_MISMATCH   1009
  158. #define EXCEED_PROPS  1010
  159. char *prog;
  160. main(argc, argv)
  161. int             argc;
  162. char           *argv[];
  163. {
  164. /* Usage : to_wfont [-o outfile] [infile] */
  165. char           *s;
  166. fname[0] = 0;
  167. tableindex = 0;
  168. head.num_ch = -1;
  169. prog = *argv;
  170. while (--argc > 0 && *++argv != NULL) {
  171. s = *argv;
  172. if (*s++ == '-')
  173. switch (*s) {
  174. case 's':
  175. if (*++argv != NULL)
  176. {
  177. --argc;
  178. (void) strcpy(symname, *argv);
  179. }
  180. break;
  181. case 'o':
  182. if (*++argv != NULL)
  183. {
  184. --argc;
  185. (void) strcpy(fname, *argv);
  186. }
  187. break;
  188. default:      /* ignore other options */
  189. ;
  190. }
  191. else {
  192. FILE           *fp;
  193. /* standard input redirection */
  194. fp = fopen(*argv, "r");
  195. if (fp != NULL) {
  196. if (close(fileno(stdin)) < 0)
  197. {
  198. perror(prog);
  199. return;
  200. }
  201. if (dup(fileno(fp)) < 0)
  202. {
  203. perror(prog);
  204. return;
  205. }
  206. (void) fclose(fp);
  207. }
  208. }
  209. }
  210. return (yyparse());
  211. }
  212. /* set number of characters */
  213. set_num_ch(num_ch)
  214. int num_ch;
  215. {
  216. yyerrno = 0;
  217. head.num_ch = num_ch;
  218. if (num_ch > 0) {
  219.   Table    = (Dispatch *) malloc(num_ch * sizeof(Dispatch));
  220.   sp_table = (Standard *) malloc(num_ch * sizeof(Standard));
  221.   strokes  = (Path *)     malloc(num_ch * sizeof(Path));
  222. }
  223. for (tableindex = 0; tableindex < num_ch; tableindex++) {
  224. Table[tableindex].center = 0.0;
  225. Table[tableindex].right = 0.0;
  226. Table[tableindex].offset = 0;
  227. sp_table[tableindex].std_left = 0.0;
  228. sp_table[tableindex].std_wide = 0.0;
  229. sp_table[tableindex].std_rght = 0.0;
  230. strokes[tableindex].n_subpaths = 0;
  231. strokes[tableindex].n_vertices = 0;
  232. strokes[tableindex].subpaths = NULL;
  233. }
  234. }
  235. /* initialize the property info in the header */
  236. init_properties(num_props)
  237. int             num_props;
  238. {
  239. if (num_props > 0) {
  240.   head.properties = (Property *) 
  241.                       malloc (num_props * sizeof (Property));
  242.   head.num_props = expect.props = num_props;
  243. }
  244. else {
  245.   head.properties = NULL;
  246.   head.num_props = expect.props = 0;
  247. }
  248. count.props = -1;
  249. property = head.properties;  /* initialize the list pointer */
  250. }
  251. check_num_props()
  252. {
  253.         count.props++;
  254.         if (count.props != expect.props)
  255.   BYE (PROP_MISMATCH);
  256. }
  257. /* add individual property info into the buffer */
  258. add_property(name, value)
  259. char            *name,
  260. *value;
  261. {
  262.         /* check if the property exceeds allocated space */
  263.         if (++count.props >= head.num_props)
  264.      BYE(EXCEED_PROPS);
  265. /* copy the strings into the buffer */
  266. (void) strcpy (property->propname, name);
  267. (void) strcpy (property->propvalue, value);
  268. /* increment the property pointer */
  269. property++;
  270. }
  271. check_num_ch()
  272. {
  273.   if (head.num_ch == -1)
  274. set_num_ch(128);
  275. }
  276. yyerror()
  277. {
  278. #ifndef __bsdi__
  279. extern int      yylineno;
  280. #endif
  281. # define ERR_SIZE (sizeof(err_string) / sizeof(char *))
  282. static char    *err_string[] = {
  283. "Cannot open file",
  284. "Write fails",
  285. "Illegal font name",
  286. "Memory allocation failure",
  287. "Specified number of strokes exceeded",
  288. "Specified number of points exceeded",
  289. "Number of strokes do not match",
  290. "Number of points do not match",
  291. "Number of properties do not match",
  292. "Specified number of properties exceeded",
  293. 0};
  294. char           *str;
  295. yyerrno -= ERR_BASE;
  296. if (yyerrno > 0 && yyerrno < ERR_SIZE)
  297. str = err_string[yyerrno-1];
  298. else
  299. str = "Syntax error";
  300. #ifdef __bsdi__
  301. fprintf(stderr, "%s.n", str);
  302. #else
  303. fprintf(stderr, "line %d: %s.n", yylineno, str);
  304. #endif
  305. freeall();
  306. (void) unlink(fname);
  307. exit(1);
  308. }
  309. /* create wfont header */
  310. wf_header(name, top, bottom)
  311. char           *name;
  312. float           top,
  313.                 bottom;
  314. {
  315. if (name == NULL)
  316. BYE(WRONG_NAME);
  317. head.top = (float) top;
  318. head.bottom = (float) bottom;
  319. head.magic = WFONT_MAGIC_PEX;
  320. (void) strcpy(head.name, name);
  321. free(name);
  322. }
  323. /* create header for each glyph */
  324. glyph_header(npath, center, right, npts)
  325. int             npath,
  326.                 npts;
  327. float           center,
  328.                 right;
  329. {
  330.      {
  331. register Path  *strk = strokes + tableindex;
  332.         if (npath > 0)     /* Don't allocate space unless the character
  333.       has strokes associated with it. */
  334. {
  335. strk->subpaths = (Path_subpath *)
  336. malloc(npath * sizeof (Path_subpath));
  337. if (strk->subpaths == NULL)
  338. BYE(NO_MEMORY);
  339. strk->type = PATH_2DF;
  340. strk->n_subpaths = npath;
  341. strk->n_vertices = npts;
  342. }
  343. else {            /* Just initialize the entry */
  344.         strk->subpaths = NULL;
  345. strk->type = PATH_2DF;
  346. strk->n_subpaths = 0;
  347. strk->n_vertices = 0;
  348. }
  349.       }
  350.       {
  351. register Dispatch *tbl = Table + tableindex;
  352. tbl->offset = 0;
  353. tbl->center = center;
  354. tbl->right = right;
  355.       }
  356. count.path = -1;        /* initialize path counter, not to
  357.         * exceed n_subpath */
  358. }
  359. /* create standard spacing info for each glyph  */
  360. std_space(l_bear, wide, r_bear)
  361. float l_bear,
  362.       wide,
  363.       r_bear;
  364. {
  365. register Standard *tbl = sp_table +tableindex;
  366. tbl->std_left = l_bear;
  367. tbl->std_wide = wide;
  368. tbl->std_rght = r_bear;
  369. }
  370. /* initialize each sub_path */
  371. init_path(close, n)
  372. int             close,
  373.                 n;
  374. {
  375. register Path_subpath *path;
  376. if (++count.path >= strokes[tableindex].n_subpaths)
  377. BYE(EXCEED_PATH);
  378. path = current_path = strokes[tableindex].subpaths + count.path;
  379. path->n_pts = n;
  380. path->closed = close;
  381. if (n > 0) 
  382.   path->pts.pt2df = (Path_point2df *) 
  383.                      malloc(n * sizeof (Path_point2df));
  384. if (path->pts.pt2df == NULL)
  385. BYE(NO_MEMORY);
  386. expect.point = path->n_pts;
  387. count.point = -1;        /* initialize point counter, not to
  388.         * exceed n_pts */
  389. }
  390. /* accumulating points for each sub_path */
  391. add_point(x, y)
  392. float           x,
  393.                 y;
  394. {
  395. register Path_subpath   *path;
  396. register Path_point2df *pt_ptr;
  397. path = current_path;
  398. if (++count.point >= path->n_pts)
  399. BYE(EXCEED_POINT);
  400. pt_ptr = path->pts.pt2df + count.point;
  401. pt_ptr->x = x;
  402. pt_ptr->y = y;
  403. }
  404. /* Path_type + n_subpaths + n_vertices */
  405. #define STROKE_HEAD (sizeof (Path_type) + sizeof (int) + sizeof (int))
  406. /* write out file, close everything, free everything */
  407. fini()
  408. {
  409. static long     zero = 0;
  410. /* pointers used to walk the arrays */
  411. register Path_subpath *spath;
  412. register Dispatch *tbl_ptr;
  413. register Path  *strptr;
  414. register Property *prop_ptr;
  415. FILE           *fp;
  416. int             npath;
  417. register int    i,
  418.                 j,
  419. k;
  420. Standard *sp_ptr;
  421. Path_point2df *pt;
  422.         printf("n/* GENERATED FILE -- DO NOT MODIFY */nn");
  423.         printf("#include "glutstroke.h"nn");
  424. # define BY_BYE(err) fclose(fp), BYE(err)
  425. /* adjust the characters for spacing, note max char width */
  426. head.max_width = 0.0;
  427. for (i = 0, tbl_ptr = Table, strptr = strokes, sp_ptr = sp_table;
  428.              i < head.num_ch; i++, tbl_ptr++, strptr++, sp_ptr++) {
  429. tbl_ptr->center += sp_ptr->std_left;
  430. tbl_ptr->right += sp_ptr->std_left + sp_ptr->std_rght;
  431. if (tbl_ptr->right > head.max_width)
  432. head.max_width = tbl_ptr->right;
  433. npath = strptr->n_subpaths;
  434. if (npath > 0 || tbl_ptr->center != 0.0 ||
  435.                     tbl_ptr->right != 0.0) {
  436. for (j = 0, spath = strptr->subpaths;
  437.                              j < npath; j++, spath++) {
  438. for(k=0, pt = spath->pts.pt2df;
  439.      k<spath->n_pts; k++, pt++) {
  440. pt->x += sp_ptr->std_left;
  441. }
  442. }
  443. }
  444. }
  445. /* write the stroke table */
  446. for (i = 0, tbl_ptr = Table, strptr = strokes;
  447.      i < head.num_ch; i++, tbl_ptr++, strptr++) {
  448. if (strptr->n_subpaths > 0 &&
  449.     tbl_ptr->center != 0.0 &&
  450.     tbl_ptr->right != 0.0) {
  451. if(isprint(i)) {
  452. printf("/* char: %d '%c' */nn", i, i);
  453. } else {
  454. printf("/* char: %d */nn", i);
  455. }
  456. for (j = 0, spath = strptr->subpaths;
  457.      j < strptr->n_subpaths; j++, spath++) {
  458. int z;
  459. printf("static const CoordRec char%d_stroke%d[] = {n", i, j);
  460. for(z = 0; z < spath->n_pts; z++) {
  461. printf("    { %g, %g },n",
  462. spath->pts.pt2df[z].x, spath->pts.pt2df[z].y);
  463. }
  464. printf("};nn");
  465. }
  466. printf("static const StrokeRec char%d[] = {n", i);
  467.                         for (j = 0, spath = strptr->subpaths;
  468.                              j < strptr->n_subpaths; j++, spath++) {
  469. printf("   { %d, char%d_stroke%d },n",
  470. spath->n_pts, i, j);
  471. }
  472. printf("};nn");
  473. }
  474. }
  475. printf("static const StrokeCharRec chars[] = {n");
  476. for (i = 0, tbl_ptr = Table, strptr = strokes;
  477.      i < head.num_ch; i++, tbl_ptr++, strptr++) {
  478.     if (strptr->n_subpaths > 0 &&
  479. tbl_ptr->center != 0.0 &&
  480. tbl_ptr->right != 0.0) {
  481. printf("    { %d, char%d, %g, %g },n",
  482. strptr->n_subpaths, i, tbl_ptr->center, tbl_ptr->right);
  483.     } else {
  484. printf("    { 0, /* char%d */ 0, %g, %g },n",
  485. i, tbl_ptr->center, tbl_ptr->right);
  486.     }
  487. }
  488. printf("};nn");
  489. printf("StrokeFontRec %s = { "%s", %d, chars, %.6g, %.6g };nn",
  490. symname, head.name, head.num_ch,
  491. (double) head.top, (double) head.bottom);
  492. fflush(stdout);
  493. freeall();
  494. # undef BY_BYE
  495. }
  496. freeall()
  497. {
  498. register Path  *path;
  499. register Path_subpath *spath;
  500. register int    i,
  501.                 j,
  502.                 n;
  503. path = strokes;
  504. for (i = 0; i < head.num_ch; i++, path++) {
  505. n = path->n_subpaths;
  506. if (n <= 0)
  507. continue;
  508. spath = path->subpaths;
  509. for (j = 0; j < n; j++, spath++)
  510. if (spath->pts.pt2df != NULL)
  511. free((char *) spath->pts.pt2df);
  512. if (path->subpaths != NULL)
  513. free((char *) path->subpaths);
  514. }
  515. free(Table);
  516. free(sp_table);
  517. free(strokes);
  518. if (head.properties != NULL)
  519.   free((char *) head.properties);
  520. }
  521. check_nstroke()
  522. {
  523. count.path++;
  524. if (expect.path != count.path)
  525. BYE(PATH_MISMATCH);
  526. }
  527. check_npts()
  528. {
  529. count.point++;
  530. if (expect.point != count.point)
  531. BYE(POINT_MISMATCH);
  532. }