Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

646 lines
15 KiB

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