1 /**
2 *
3 * $Id: gra2ps.c,v 1.16 2009/04/03 14:07:43 isizaka Exp isizaka $
4 *
5 * This is free software; you can redistribute it and/or modify it.
6 *
7 * Original author: Satoshi ISHIZAKA
8 * isizaka@msa.biglobe.ne.jp
9 **/
10
11 /**
12 *
13 * $Log: gra2ps.c,v $
14 * Revision 1.16 2009/04/03 14:07:43 isizaka
15 * add viewc
16 *
17 * Revision 1.15 2003/08/15 12:04:26 isizaka
18 * 2.03.17
19 *
20 * Revision 1.13 2000/10/17 14:43:28 isizaka
21 * add '-r', '-p', '-l' option
22 *
23 * Revision 1.12 2000/10/16 13:41:03 isizaka
24 * bug fix about undefined current point.
25 *
26 * Revision 1.11 1999/10/15 15:31:11 isizaka
27 * Encoding is changed to ISOLatin1.
28 *
29 * Revision 1.10 1999/08/26 14:30:39 isizaka
30 * charwidth is changed
31 *
32 *
33 * Revision 1.6 1999/04/15 12:16:39 isizaka
34 * 99/04/15
35 *
36 * Revision 1.5 1999/04/11 06:10:15 isizaka
37 * *** empty log message ***
38 *
39 * Revision 1.4 1999/03/22 05:33:59 isizaka
40 * check time stamp for 'Ngraph.ini'
41 *
42 * Revision 1.3 1999/03/21 16:11:11 isizaka
43 * hyphen for Windows and X11
44 *
45 * Revision 1.2 1999/03/18 11:31:50 isizaka
46 * add 'setcp' flag to avoid "nocurrentpoint" error.
47 *
48 * Revision 1.1 1999/03/17 13:36:29 isizaka
49 * Initial revision
50 *
51 *
52 **/
53
54 #include <sys/stat.h>
55 #include <stdio.h>
56 #include <stdlib.h>
57 #include <time.h>
58 #include <ctype.h>
59 #include <limits.h>
60 #include <math.h>
61 #include <string.h>
62 #include <stdarg.h>
63 #include <errno.h>
64 #ifdef WINDOWS
65 #include <io.h>
66 #include <dir.h>
67 #else
68 #include <unistd.h>
69 #endif
70
71 #define MPI 3.1415926535897932385
72
73 #define GRAF "%Ngraph GRAF"
74 #ifndef LIBDIR
75 #define LIBDIR "/usr/local/lib/Ngraph"
76 #endif
77 #define CONF "gra2ps.ini"
78 #define GRA2CONF "[gra2ps]"
79 #define DIRSEP '/'
80 #define CONFSEP "/"
81 #define NSTRLEN 256
82 #define LINETOLIMIT 500
83 #define VERSION "2.03.20"
84
85 #define TRUE 1
86 #define FALSE 0
87
88 enum {A3=0,A4,B4,A5,B5,LETTER,LEGAL};
89 enum {NORMAL=0,BOLD,ITALIC,BOLDITALIC};
90
91 struct fontmap;
92 struct fontmap {
93 char *fontalias;
94 char *fontname;
95 int type;
96 int used;
97 struct fontmap *next;
98 } *fmap=NULL;
99
100 char *outfilename;
101 FILE *outfp;
102 char *libdir,*homedir;
103 char *includefile=NULL;
104 int include=FALSE;
105 int epsf=FALSE;
106 int color=FALSE;
107 int landscape=FALSE;
108 int paper=A4;
109 int rotate=FALSE;
110 int bottom=29700;
111 int sjis=FALSE;
112 int font_slant=12;
113
printfstderr(char * fmt,...)114 int printfstderr(char *fmt,...)
115 {
116 int len;
117 va_list ap;
118
119 va_start(ap,fmt);
120 len=vfprintf(stderr,fmt,ap);
121 va_end(ap);
122 return len;
123 }
124
niskanji(unsigned int code)125 int niskanji(unsigned int code)
126 {
127 if (((0x81<=code) && (code<=0x9f))
128 || ((0xe0<=code) && (code<=0xff))) return TRUE;
129 return FALSE;
130 }
131
njms2jis(unsigned int code)132 unsigned int njms2jis(unsigned int code)
133 {
134 unsigned char dh,dl;
135
136 dh=code >> 8;
137 dl=code & 0xff;
138 if (dh<=0x9f) dh-=0x70;
139 else dh-=0xb0;
140 dh=dh<<1;
141 if (dl>=0x9f) dl-=0x7e;
142 else {
143 dh--;
144 if (dl>=0x80) dl-=0x20;
145 else dl-=0x1f;
146 }
147 return ((unsigned int)(dh << 8))+dl;
148 }
149
nstrnew(void)150 char *nstrnew(void)
151 {
152 char *po;
153
154 po=malloc(NSTRLEN);
155 po[0]='\0';
156 return po;
157 }
158
nstrccat(char * po,char ch)159 char *nstrccat(char *po,char ch)
160 {
161 size_t len,num;
162
163 if (po==NULL) return NULL;
164 len=strlen(po);
165 num=len/NSTRLEN;
166 if (len%NSTRLEN==NSTRLEN-1) po=realloc(po,NSTRLEN*(num+2));
167 po[len]=ch;
168 po[len+1]='\0';
169 return po;
170 }
171
fgetline(FILE * fp,char ** buf)172 int fgetline(FILE *fp,char **buf)
173 {
174 char *s;
175 int ch;
176
177 *buf=NULL;
178 ch=fgetc(fp);
179 if (ch==EOF) return 1;
180 s=nstrnew();
181 while (TRUE) {
182 if ((ch=='\0') || (ch=='\n') || (ch==EOF)) {
183 *buf=s;
184 return 0;
185 }
186 if (ch!='\r') s=nstrccat(s,ch);
187 ch=fgetc(fp);
188 }
189 }
190
openconfig(char * section)191 FILE *openconfig(char *section)
192 {
193 char *s,*buf,*homeconf,*libconf;
194 FILE *fp;
195 struct stat homestat,libstat;
196
197 homeconf=(char *)malloc(strlen(homedir)+strlen(CONFSEP)+strlen(CONF)+1);
198 strcpy(homeconf,homedir);
199 if ((strlen(homedir)>0) && (homeconf[strlen(homedir)-1]=='/'))
200 homeconf[strlen(homedir)-1]='\0';
201 strcat(homeconf,CONFSEP);
202 strcat(homeconf,CONF);
203 libconf=(char *)malloc(strlen(libdir)+strlen(CONFSEP)+strlen(CONF)+1);
204 strcpy(libconf,libdir);
205 if ((strlen(libdir)>0) && (libconf[strlen(libdir)-1]=='/'))
206 libconf[strlen(libdir)-1]='\0';
207 strcat(libconf,CONFSEP);
208 strcat(libconf,CONF);
209 if (access(homeconf,04)==0) {
210 if (stat(homeconf,&homestat)!=0) {
211 free(homeconf);
212 homeconf=NULL;
213 }
214 } else {
215 free(homeconf);
216 homeconf=NULL;
217 }
218 if (access(libconf,04)==0) {
219 if (stat(libconf,&libstat)!=0) {
220 free(libconf);
221 libconf=NULL;
222 }
223 } else {
224 free(libconf);
225 libconf=NULL;
226 }
227 if (homeconf!=NULL) {
228 if (libconf==NULL) s=homeconf;
229 else if (homestat.st_mtime>=libstat.st_mtime) {
230 s=homeconf;
231 free(libconf);
232 } else {
233 s=libconf;
234 free(homeconf);
235 }
236 } else if (libconf!=NULL) s=libconf;
237 else return NULL;
238 if ((fp=fopen(s,"rt"))==NULL) return NULL;
239 free(s);
240 while (fgetline(fp,&buf)==0) {
241 if (strcmp(buf,section)==0) {
242 free(buf);
243 return fp;
244 }
245 free(buf);
246 }
247 fclose(fp);
248 return NULL;
249 }
250
getitok(char ** s,int * len,char * ifs)251 char *getitok(char **s,int *len,char *ifs)
252 {
253 char *po,*spo;
254 int i;
255
256 if (*s==NULL) return NULL;
257 po=*s;
258 for (i=0;(po[i]!='\0') && (strchr(ifs,po[i])!=NULL);i++);
259 if (po[i]=='\0') {
260 *len=0;
261 return NULL;
262 }
263 spo=po+i;
264 for (;(po[i]!='\0') && (strchr(ifs,po[i])==NULL);i++);
265 *s+=i;
266 *len=*s-spo;
267 return spo;
268 }
269
getitok2(char ** s,int * len,char * ifs)270 char *getitok2(char **s,int *len,char *ifs)
271 {
272 char *po,*s2;
273
274 if ((s2=getitok(s,len,ifs))==NULL) return NULL;
275 po=malloc(*len+1);
276 strncpy(po,s2,*len);
277 po[*len]='\0';
278 return po;
279 }
280
getconfig(FILE * fp,char ** val)281 char *getconfig(FILE *fp,char **val)
282 {
283 char *s,*tok,*buf;
284 int len;
285
286 while (TRUE) {
287 if (fgetline(fp,&buf)!=0) return NULL;
288 else {
289 if (buf[0]=='[') {
290 free(buf);
291 return NULL;
292 } else {
293 s=buf;
294 if ((tok=getitok2(&s,&len," \t=,"))!=NULL) {
295 for (;(s[0]!='\0') && (strchr(" \t=,",s[0])!=NULL);s++);
296 *val=malloc(strlen(s)+1);
297 strcpy(*val,s);
298 free(buf);
299 return tok;
300 }
301 free(buf);
302 free(tok);
303 }
304 }
305 }
306 }
307
closeconfig(FILE * fp)308 void closeconfig(FILE *fp)
309 {
310 fclose(fp);
311 }
312
getintpar(char * s,int num,int cpar[])313 int getintpar(char *s,int num,int cpar[])
314 {
315 int i,pos1,pos2;
316 char s2[256];
317 char *endptr;
318
319 pos1=0;
320 for (i=0;i<num;i++) {
321 while ((s[pos1]!='\0') && (strchr(" \t,",s[pos1])!=NULL)) pos1++;
322 if (s[pos1]=='\0') return FALSE;
323 pos2=0;
324 while ((s[pos1]!='\0') && (strchr(" \t,",s[pos1])==NULL)) {
325 s2[pos2]=s[pos1];
326 pos2++;
327 pos1++;
328 }
329 s2[pos2]='\0';
330 cpar[i]=strtol(s2,&endptr,10);
331 if (endptr[0]!='\0') return FALSE;
332 }
333 return TRUE;
334 }
335
GRAinput(char * s,void (* draw)(char code,int * cpar,char * cstr))336 int GRAinput(char *s,void (*draw)(char code,int *cpar,char *cstr))
337 {
338 int pos,i;
339 int num;
340 char code;
341 int *cpar;
342 char *cstr;
343
344 code='\0';
345 cpar=NULL;
346 cstr=NULL;
347 for (i=0;s[i]!='\0';i++)
348 if (strchr("\n\r",s[i])!=NULL) {
349 s[i]='\0';
350 break;
351 }
352 pos=0;
353 while ((s[pos]==' ') || (s[pos]=='\t')) pos++;
354 if (s[pos]=='\0') return TRUE;
355 if (strchr("IE%VAGOMNLTCBPRDFHSK",s[pos])==NULL) return FALSE;
356 code=s[pos];
357 if (strchr("%FSK",code)==NULL) {
358 if (!getintpar(s+pos+1,1,&num)) return FALSE;
359 num++;
360 cpar=malloc(sizeof(int)*num);
361 if (!getintpar(s+pos+1,num,cpar)) goto errexit;
362 } else {
363 cpar=malloc(sizeof(int));
364 cpar[0]=-1;
365 cstr=malloc(strlen(s)-pos);
366 strcpy(cstr,s+pos+1);
367 }
368 draw(code,cpar,cstr);
369 free(cpar);
370 free(cstr);
371 return TRUE;
372
373 errexit:
374 free(cpar);
375 free(cstr);
376 return FALSE;
377 }
378
putstdout(char * s)379 void putstdout(char *s)
380 {
381 fputs(s,outfp);
382 fputs("\n",outfp);
383 }
384
printfstdout(char * fmt,...)385 void printfstdout(char *fmt,...)
386 {
387 va_list ap;
388
389 va_start(ap,fmt);
390 vfprintf(outfp,fmt,ap);
391 va_end(ap);
392 }
393
394 char *fontalias=NULL;
395 double fontsize=2000;
396 int fonttype=NORMAL;
397 char textspace[256];
398 int loadfont=FALSE;
399 int setcp=FALSE;
400 int cpx=0;
401 int cpy=0;
402 int lineto=FALSE;
403 int linetonum=0;
404
405 int HelveticaSet[256]={
406 278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,
407 278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,
408 278,278,355,556,556,889,667,222,333,333,389,584,278,584,278,278,
409 556,556,556,556,556,556,556,556,556,556,278,278,584,584,584,556,
410 1015,667,667,722,722,667,611,778,722,278,500,667,556,833,722,778,
411 667,778,722,667,611,722,667,944,667,667,611,278,278,278,469,556,
412 222,556,556,500,556,556,278,556,556,222,222,500,222,833,556,556,
413 556,556,333,500,278,556,500,722,500,500,500,334,260,334,584,278,
414 278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,
415 278,333,333,333,333,333,333,333,333,278,333,333,278,333,333,333,
416 278,333,556,556,556,556,260,556,333,737,370,556,584,333,737,333,
417 400,584,333,333,333,556,537,278,333,333,365,556,834,834,834,611,
418 667,667,667,667,667,667,1000,722,667,667,667,667,278,278,278,278,
419 722,722,778,778,778,778,778,584,778,722,722,722,722,667,667,611,
420 556,556,556,556,556,556,889,500,556,556,556,556,278,278,278,278,
421 556,556,556,556,556,556,556,584,611,556,556,556,556,500,556,500};
422
423 int HelveticaBoldSet[256]={
424 278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,
425 278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,
426 278,333,474,556,556,889,722,278,333,333,389,584,278,584,278,278,
427 556,556,556,556,556,556,556,556,556,556,333,333,584,584,584,611,
428 975,722,722,722,722,667,611,778,722,278,556,722,611,833,722,778,
429 667,778,722,667,611,722,667,944,667,667,611,333,278,333,584,556,
430 278,556,611,556,611,556,333,611,611,278,278,556,278,889,611,611,
431 611,611,389,556,333,611,556,778,556,556,500,389,280,389,584,278,
432 278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,
433 278,333,333,333,333,333,333,333,333,278,333,333,278,333,333,333,
434 278,333,556,556,556,556,280,556,333,737,370,556,584,333,737,333,
435 400,584,333,333,333,611,556,278,333,333,365,556,834,834,834,611,
436 722,722,722,722,722,722,1000,722,667,667,667,667,278,278,278,278,
437 722,722,778,778,778,778,778,584,778,722,722,722,722,667,667,611,
438 556,556,556,556,556,556,889,556,556,556,556,556,278,278,278,278,
439 611,611,611,611,611,611,611,584,611,611,611,611,611,556,611,556};
440
441 int TimesRomanSet[256]={
442 250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
443 250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
444 250,333,408,500,500,833,778,333,333,333,500,564,250,564,250,278,
445 500,500,500,500,500,500,500,500,500,500,278,278,564,564,564,444,
446 921,722,667,667,722,611,556,722,722,333,389,722,611,889,722,722,
447 556,722,667,556,611,722,722,944,722,722,611,333,278,333,469,500,
448 333,444,500,444,500,444,333,500,500,278,278,500,278,778,500,500,
449 500,500,333,389,278,500,500,722,500,500,444,480,200,480,541,250,
450 250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
451 278,333,333,333,333,333,333,333,333,250,333,333,250,333,333,333,
452 250,333,500,500,500,500,200,500,333,760,276,500,564,333,760,333,
453 400,564,300,300,333,500,453,250,333,300,310,500,750,750,750,444,
454 722,722,722,722,722,722,889,667,611,611,611,611,333,333,333,333,
455 722,722,722,722,722,722,722,564,722,722,722,722,722,722,556,500,
456 444,444,444,444,444,444,667,444,444,444,444,444,278,278,278,278,
457 500,500,500,500,500,500,500,564,500,500,500,500,500,500,500,500};
458
459 int TimesBoldSet[256]={
460 250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
461 250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
462 250,333,555,500,500,1000,833,333,333,333,500,570,250,570,250,278,
463 500,500,500,500,500,500,500,500,500,500,333,333,570,570,570,500,
464 930,722,667,722,722,667,611,778,778,389,500,778,667,944,722,778,
465 611,778,722,556,667,722,722,1000,722,722,667,333,278,333,581,500,
466 333,500,556,444,556,444,333,500,556,278,333,556,278,833,556,500,
467 556,556,444,389,333,556,500,722,500,500,444,394,220,394,520,250,
468 250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
469 278,333,333,333,333,333,333,333,333,250,333,333,250,333,333,333,
470 250,333,500,500,500,500,220,500,333,747,300,500,570,333,747,333,
471 400,570,300,300,333,556,540,250,333,300,330,500,750,750,750,500,
472 722,722,722,722,722,722,1000,722,667,667,667,667,389,389,389,389,
473 722,722,778,778,778,778,778,570,778,722,722,722,722,722,611,556,
474 500,500,500,500,500,500,722,444,444,444,444,444,278,278,278,278,
475 500,556,500,500,500,500,500,570,500,556,556,556,556,500,556,500};
476
477 int TimesItalicSet[256]={
478 250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
479 250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
480 250,333,420,500,500,833,778,333,333,333,500,675,250,675,250,278,
481 500,500,500,500,500,500,500,500,500,500,333,333,675,675,675,500,
482 920,611,611,667,722,611,611,722,722,333,444,667,556,833,667,722,
483 611,722,611,500,556,722,611,833,611,556,556,389,278,389,422,500,
484 333,500,500,444,500,444,278,500,500,278,278,444,278,722,500,500,
485 500,500,389,389,278,500,444,667,444,444,389,400,275,400,541,250,
486 250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
487 278,333,333,333,333,333,333,333,333,250,333,333,250,333,333,333,
488 250,389,500,500,500,500,275,500,333,760,276,500,675,333,760,333,
489 400,675,300,300,333,500,523,250,333,300,310,500,750,750,750,500,
490 611,611,611,611,611,611,889,667,611,611,611,611,333,333,333,333,
491 722,667,722,722,722,722,722,675,722,722,722,722,722,556,611,500,
492 500,500,500,500,500,500,667,444,444,444,444,444,278,278,278,278,
493 500,500,500,500,500,500,500,675,500,500,500,500,500,444,500,444};
494
495 int TimesBoldItalicSet[256]={
496 250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
497 250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
498 250,389,555,500,500,833,778,333,333,333,500,570,250,606,250,278,
499 500,500,500,500,500,500,500,500,500,500,333,333,570,570,570,500,
500 832,667,667,667,722,667,667,722,778,389,500,667,611,889,722,722,
501 611,722,667,556,611,722,667,889,667,611,611,333,278,333,570,500,
502 333,500,500,444,500,444,333,500,556,278,278,500,278,778,556,500,
503 500,500,389,389,278,556,444,667,500,444,389,348,220,348,570,250,
504 250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
505 278,333,333,333,333,333,333,333,333,250,333,333,250,333,333,333,
506 250,389,500,500,500,500,220,500,333,747,266,500,606,333,747,333,
507 400,570,300,300,333,576,500,250,333,300,300,500,750,750,750,500,
508 667,667,667,667,667,667,944,667,667,667,667,667,389,389,389,389,
509 722,722,722,722,722,722,722,570,722,722,722,722,722,611,611,500,
510 500,500,500,500,500,500,722,444,444,444,444,444,278,278,278,278,
511 500,556,500,500,500,500,500,570,500,556,556,556,556,444,500,444};
512
513 int SymbolSet[256]={
514 250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
515 250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
516 250,333,713,500,549,833,778,439,333,333,500,549,250,549,250,278,
517 500,500,500,500,500,500,500,500,500,500,278,278,549,549,549,444,
518 549,722,667,722,612,611,763,603,722,333,631,722,686,889,722,722,
519 768,741,556,592,611,690,439,768,645,795,611,333,863,333,658,500,
520 500,631,549,549,494,439,521,411,603,329,603,549,549,576,521,549,
521 549,521,549,603,439,576,713,686,493,686,494,480,200,480,549,250,
522 250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
523 250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
524 250,620,247,549,167,713,500,753,753,753,753,1042,987,603,987,603,
525 400,549,411,549,549,713,494,460,549,549,549,549,1000,603,1000,658,
526 823,686,795,987,768,768,823,768,768,713,713,713,713,713,713,713,
527 768,713,790,790,890,823,549,250,713,603,603,1042,987,603,987,603,
528 494,329,790,790,786,713,384,384,384,384,384,384,494,494,494,494,
529 250,329,274,686,686,686,384,384,384,384,384,384,494,494,494,250};
530
531
charwidth(unsigned int ch,char * font,int size)532 int charwidth(unsigned int ch, char *font,int size)
533 {
534 if ((strcmp(font,"Times")==0) || (strcmp(font,"Tim")==0))
535 return (int )(25.4/72000.0*size*TimesRomanSet[ch]);
536 else if ((strcmp(font,"TimesBold")==0) || (strcmp(font,"TimB")==0))
537 return (int )(25.4/72000.0*size*TimesBoldSet[ch]);
538 else if ((strcmp(font,"TimesItalic")==0) || (strcmp(font,"TimI")==0))
539 return (int )(25.4/72000.0*size*TimesItalicSet[ch]);
540 else if ((strcmp(font,"TimesBoldItalic")==0) || (strcmp(font,"TimBI")==0))
541 return (int )(25.4/72000.0*size*TimesBoldItalicSet[ch]);
542 else if ((strcmp(font,"Helvetica")==0) || (strcmp(font,"Helv")==0)
543 || (strcmp(font,"HelveticaOblique")==0) || (strcmp(font,"HelvO")==0)
544 || (strcmp(font,"HelveticaItalic")==0) || (strcmp(font,"HelvI")==0))
545 return (int )(25.4/72000.0*size*HelveticaSet[ch]);
546 else if ((strcmp(font,"HelveticaBold")==0) || (strcmp(font,"HelvB")==0)
547 || (strcmp(font,"HelveticaBoldOblique")==0) || (strcmp(font,"HelvBO")==0)
548 || (strcmp(font,"HelveticaBoldItalic")==0) || (strcmp(font,"HelvBI")==0))
549 return (int )(25.4/72000.0*size*HelveticaBoldSet[ch]);
550 else if ((strcmp(font,"Symbol")==0) || (strcmp(font,"Sym")==0)
551 || (strcmp(font,"SymbolBold")==0) || (strcmp(font,"SymB")==0)
552 || (strcmp(font,"SymbolItalic")==0) || (strcmp(font,"SymI")==0)
553 || (strcmp(font,"SymbolBoldItalic")==0) || (strcmp(font,"SymBI")==0))
554 return (int )(25.4/72000.0*size*SymbolSet[ch]);
555 else if ((strcmp(font,"Gothic")==0) || (strcmp(font,"Goth")==0)
556 || (strcmp(font,"GothicBold")==0) || (strcmp(font,"GothB")==0)
557 || (strcmp(font,"GothicItalic")==0) || (strcmp(font,"GothI")==0)
558 || (strcmp(font,"GothicBoldItalic")==0) || (strcmp(font,"GothBI")==0)
559 || (strcmp(font,"Mincho")==0) || (strcmp(font,"Min")==0)
560 || (strcmp(font,"MinchoBold")==0) || (strcmp(font,"MinB")==0)
561 || (strcmp(font,"MinchoItalic")==0) || (strcmp(font,"MinI")==0)
562 || (strcmp(font,"MinchoBoldItalic")==0) || (strcmp(font,"MinBI")==0))
563 return (int )(25.4/72000.0*size*1000);
564 else return (int )(25.4/72000.0*size*600);
565 }
566
charheight(char * font,int size)567 int charheight(char *font,int size)
568 {
569 if ((strcmp(font,"Times")==0) || (strcmp(font,"Tim")==0))
570 return (int )(25.4/72000.0*size*662);
571 else if ((strcmp(font,"TimesBold")==0) || (strcmp(font,"TimB")==0))
572 return (int )(25.4/72000.0*size*676);
573 else if ((strcmp(font,"TimesItalic")==0) || (strcmp(font,"TimI")==0))
574 return (int )(25.4/72000.0*size*653);
575 else if ((strcmp(font,"TimesBoldItalic")==0) || (strcmp(font,"TimBI")==0))
576 return (int )(25.4/72000.0*size*669);
577 else if ((strcmp(font,"Helvetica")==0) || (strcmp(font,"Helv")==0)
578 || (strcmp(font,"HelveticaOblique")==0) || (strcmp(font,"HelvO")==0)
579 || (strcmp(font,"HelveticaItalic")==0) || (strcmp(font,"HelvI")==0))
580 return (int )(25.4/72000.0*size*718);
581 else if ((strcmp(font,"HelveticaBold")==0) || (strcmp(font,"HelvB")==0)
582 || (strcmp(font,"HelveticaBoldOblique")==0) || (strcmp(font,"HelvBO")==0)
583 || (strcmp(font,"HelveticaBoldItalic")==0) || (strcmp(font,"HelvBI")==0))
584 return (int )(25.4/72000.0*size*718);
585 else if ((strcmp(font,"Symbol")==0) || (strcmp(font,"Sym")==0)
586 || (strcmp(font,"SymbolBold")==0) || (strcmp(font,"SymB")==0)
587 || (strcmp(font,"SymbolItalic")==0) || (strcmp(font,"SymI")==0)
588 || (strcmp(font,"SymbolBoldItalic")==0) || (strcmp(font,"SymBI")==0))
589 return (int )(25.4/72000.0*size*673);
590 else if ((strcmp(font,"CourierBold")==0) || (strcmp(font,"CourB")==0)
591 || (strcmp(font,"CourierBoldOblique")==0) || (strcmp(font,"CourBO")==0)
592 || (strcmp(font,"CourierBoldItalic")==0) || (strcmp(font,"CourBI")==0))
593 return (int )(25.4/72000.0*size*562);
594 else if ((strcmp(font,"Gothic")==0) || (strcmp(font,"Goth")==0)
595 || (strcmp(font,"GothicBold")==0) || (strcmp(font,"GothB")==0)
596 || (strcmp(font,"GothicItalic")==0) || (strcmp(font,"GothI")==0)
597 || (strcmp(font,"GothicBoldItalic")==0) || (strcmp(font,"GothBI")==0))
598 return (int )(25.4/72000.0*size*791);
599 else if ((strcmp(font,"Mincho")==0) || (strcmp(font,"Min")==0)
600 || (strcmp(font,"MinchoBold")==0) || (strcmp(font,"MinB")==0)
601 || (strcmp(font,"MinchoItalic")==0) || (strcmp(font,"MinI")==0)
602 || (strcmp(font,"MinchoBoldItalic")==0) || (strcmp(font,"MinBI")==0))
603 return (int )(25.4/72000.0*size*807);
604 else return (int )(25.4/72000.0*size*562);
605 }
606
chardescent(char * font,int size)607 int chardescent(char *font,int size)
608 {
609 return (int )(25.4/72000.0*size*250);
610 }
611
612
613 char *bfontalias=NULL;
614 int bloadfont=FALSE;
615 int boffsetx=0;
616 int boffsety=0;
617 int bminx=INT_MAX;
618 int bminy=INT_MAX;
619 int bmaxx=INT_MIN;
620 int bmaxy=INT_MIN;
621 int bposx=0;
622 int bposy=0;
623 int bpt=0;
624 int bspc=0;
625 int bdir=0;
626 int blinew=0;
627 int bclip=TRUE;
628 int bclipsizex=21000;
629 int bclipsizey=29700;
630
setbbminmax(int x1,int y1,int x2,int y2,int lw)631 void setbbminmax(int x1,int y1,int x2,int y2,int lw)
632 {
633 int x,y;
634
635 if (x1>x2) {
636 x=x1; x1=x2; x2=x;
637 }
638 if (y1>y2) {
639 y=y1; y1=y2; y2=y;
640 }
641 if (lw) {
642 x1-=blinew;
643 y1-=blinew;
644 x2+=blinew;
645 y2+=blinew;
646 }
647 if (!bclip || !((x2<0) || (y2<0) || (x1>bclipsizex) || (y1>bclipsizey))) {
648 if (bclip) {
649 if (x1<0) x1=0;
650 if (y1<0) y1=0;
651 if (x2>bclipsizex) x2=bclipsizex;
652 if (y2>bclipsizey) y1=bclipsizey;
653 }
654 x1+=boffsetx;
655 x2+=boffsetx;
656 y1+=boffsety;
657 y2+=boffsety;
658 if (x1<bminx) bminx=x1;
659 if (y1<bminy) bminy=y1;
660 if (x2>bmaxx) bmaxx=x2;
661 if (y2>bmaxy) bmaxy=y2;
662 }
663 }
664
665
getboundingbox(char code,int * cpar,char * cstr)666 void getboundingbox(char code,int *cpar,char *cstr)
667 {
668 int i,lw;
669 double x,y,csin,ccos;
670 int w,h,d,x1,y1,x2,y2,x3,y3,x4,y4;
671 int c1,c2;
672 char ch;
673
674 switch (code) {
675 case 'X': case 'I': case 'E': case '%': case 'G':
676 break;
677 case 'V':
678 boffsetx=cpar[1];
679 boffsety=cpar[2];
680 bposx=0;
681 bposy=0;
682 if (cpar[5]==1) bclip=TRUE;
683 else bclip=FALSE;
684 bclipsizex=cpar[3]-cpar[1];
685 bclipsizey=cpar[4]-cpar[2];
686 break;
687 case 'A':
688 blinew=cpar[2]/2;
689 break;
690 case 'M':
691 bposx=cpar[1];
692 bposy=cpar[2];
693 break;
694 case 'N':
695 bposx+=cpar[1];
696 bposy+=cpar[2];
697 break;
698 case 'L':
699 setbbminmax(cpar[1],cpar[2],cpar[3],cpar[4],TRUE);
700 break;
701 case 'T':
702 setbbminmax(bposx,bposy,cpar[1],cpar[2],TRUE);
703 bposx=cpar[1];
704 bposy=cpar[2];
705 break;
706 case 'C':
707 if (cpar[7]==0) lw=TRUE;
708 else lw=FALSE;
709 if (cpar[7]==1) setbbminmax(cpar[1],cpar[2],cpar[1],cpar[2],lw);
710 setbbminmax(cpar[1]+(int )(cpar[3]*cos(MPI*cpar[5]/18000.0)),
711 cpar[2]-(int )(cpar[4]*sin(MPI*cpar[5]/18000.0)),
712 cpar[1]+(int )(cpar[3]*cos((MPI*cpar[5]+cpar[6])/18000.0)),
713 cpar[2]-(int )(cpar[4]*sin((MPI*cpar[5]+cpar[6])/18000.0)),lw);
714 cpar[6]+=cpar[5];
715 cpar[5]-=9000;
716 cpar[6]-=9000;
717 if ((cpar[5]<0) && (cpar[6]>0))
718 setbbminmax(cpar[1],cpar[2]-cpar[4],cpar[1],cpar[2]-cpar[4],lw);
719 cpar[5]-=9000;
720 cpar[6]-=9000;
721 if ((cpar[5]<0) && (cpar[6]>0))
722 setbbminmax(cpar[1]-cpar[3],cpar[2],cpar[1]-cpar[3],cpar[2],lw);
723 cpar[5]-=9000;
724 cpar[6]-=9000;
725 if ((cpar[5]<0) && (cpar[6]>0))
726 setbbminmax(cpar[1],cpar[2]+cpar[4],cpar[1],cpar[2]+cpar[4],lw);
727 cpar[5]-=9000;
728 cpar[6]-=9000;
729 if ((cpar[5]<0) && (cpar[6]>0))
730 setbbminmax(cpar[1]+cpar[3],cpar[2],cpar[1]+cpar[3],cpar[2],lw);
731 break;
732 case 'B':
733 if (cpar[5]==1) lw=FALSE;
734 else lw=TRUE;
735 setbbminmax(cpar[1],cpar[2],cpar[3],cpar[4],lw);
736 break;
737 case 'P':
738 setbbminmax(cpar[1],cpar[2],cpar[1],cpar[2],FALSE);
739 break;
740 case 'R':
741 for (i=0;i<(cpar[1]-1);i++)
742 setbbminmax(cpar[i*2+2],cpar[i*2+3],cpar[i*2+4],cpar[i*2+5],lw);
743 break;
744 case 'D':
745 if (cpar[2]==0) lw=TRUE;
746 else lw=FALSE;
747 for (i=0;i<(cpar[1]-1);i++)
748 setbbminmax(cpar[i*2+3],cpar[i*2+4],cpar[i*2+5],cpar[i*2+6],lw);
749 break;
750 case 'F':
751 free(bfontalias);
752 bfontalias=malloc(strlen(cstr)+1);
753 strcpy(bfontalias,cstr);
754 break;
755 case 'H':
756 bpt=cpar[1];
757 bspc=cpar[2];
758 bdir=cpar[3];
759 bloadfont=TRUE;
760 break;
761 case 'S':
762 if (!bloadfont) break;
763 csin=sin(MPI*bdir/18000.0);
764 ccos=cos(MPI*bdir/18000.0);
765 i=0;
766 while (i<strlen(cstr)) {
767 ch=0;
768 if (cstr[i]=='\\') {
769 if (cstr[i+1]=='x') {
770 if (tolower(cstr[i+2])>='a') c1=tolower(cstr[i+2])-'a'+10;
771 else c1=tolower(cstr[i+2])-'0';
772 if (tolower(cstr[i+3])>='a') c2=tolower(cstr[i+3])-'a'+10;
773 else c2=tolower(cstr[i+3])-'0';
774 ch=c1*16+c2;
775 i+=4;
776 } else if (cstr[i+1]=='\\') {
777 ch=cstr[i];
778 i+=2;
779 } else i++;
780 } else {
781 switch (cstr[i]) {
782 case '\\':
783 ch='\\';
784 break;
785 case ')':
786 ch=')';
787 break;
788 case '(':
789 ch='(';
790 break;
791 default:
792 if (cstr[i]&0x80) {
793 c1=((unsigned char)cstr[i])>>4;
794 c2=((unsigned char)cstr[i]) & 0xF;
795 ch=c1*16+c2;
796 } else ch=cstr[i];
797 break;
798 }
799 i++;
800 }
801 w=charwidth((unsigned char)ch,bfontalias,bpt);
802 h=charheight(bfontalias,bpt);
803 d=chardescent(bfontalias,bpt);
804 x=0;
805 y=d;
806 x1=(int )(bposx+(x*ccos+y*csin));
807 y1=(int )(bposy+(-x*csin+y*ccos));
808 x=0;
809 y=-h;
810 x2=(int )(bposx+(x*ccos+y*csin));
811 y2=(int )(bposy+(-x*csin+y*ccos));
812 x=w;
813 y=d;
814 x3=(int )(bposx+(x*ccos+y*csin));
815 y3=(int )(bposy+(-x*csin+y*ccos));
816 x=w;
817 y=-h;
818 x4=(int )(bposx+(int )(x*ccos+y*csin));
819 y4=(int )(bposy+(int )(-x*csin+y*ccos));
820 setbbminmax(x1,y1,x4,y4,FALSE);
821 setbbminmax(x2,y2,x3,y3,FALSE);
822 bposx+=(int )((w+bspc*25.4/72)*ccos);
823 bposy-=(int )((w+bspc*25.4/72)*csin);
824 }
825 break;
826 case 'K':
827 if (!bloadfont) break;
828 csin=sin(MPI*bdir/18000.0);
829 ccos=cos(MPI*bdir/18000.0);
830 i=0;
831 while (i<strlen(cstr)) {
832 if (niskanji((unsigned char)cstr[i]) && (cstr[i+1]!='\0')) {
833 w=charwidth(cstr[i],bfontalias,bpt);
834 h=charheight(bfontalias,bpt);
835 d=chardescent(bfontalias,bpt);
836 x=0;
837 y=d;
838 x1=(int )(bposx+(x*ccos+y*csin));
839 y1=(int )(bposy+(-x*csin+y*ccos));
840 x=0;
841 y=-h;
842 x2=(int )(bposx+(x*ccos+y*csin));
843 y2=(int )(bposy+(-x*csin+y*ccos));
844 x=w;
845 y=d;
846 x3=(int )(bposx+(x*ccos+y*csin));
847 y3=(int )(bposy+(-x*csin+y*ccos));
848 x=w;
849 y=-h;
850 x4=(int )(bposx+(int )(x*ccos+y*csin));
851 y4=(int )(bposy+(int )(-x*csin+y*ccos));
852 setbbminmax(x1,y1,x4,y4,FALSE);
853 setbbminmax(x2,y2,x3,y3,FALSE);
854 bposx+=(int )((w+bspc*25.4/72)*ccos);
855 bposy-=(int )((w+bspc*25.4/72)*csin);
856 i+=2;
857 } else i++;
858 }
859 break;
860 }
861 }
862
draw(char code,int * cpar,char * cstr)863 void draw(char code,int *cpar,char *cstr)
864 {
865 time_t t;
866 struct tm *ltime;
867 char *buf,*fontname;
868 FILE *fp;
869 int i,a;
870 struct fontmap *fcur;
871 unsigned int jis,R,G,B;
872 int c1,c2,sx,sy;
873 double d,ftan;
874
875 if (lineto) {
876 if (code!='T') {
877 putstdout("st");
878 setcp=FALSE;
879 lineto=FALSE;
880 linetonum=0;
881 } else if (linetonum>LINETOLIMIT) {
882 putstdout("st");
883 printfstdout("%d %d mto\n",cpx,cpy);
884 lineto=FALSE;
885 linetonum=1;
886 }
887 }
888 switch (code) {
889 case 'X':
890 printfstdout("%s",cstr);
891 break;
892 case 'I':
893 printfstderr("Include (%s)\n",includefile);
894 if ((fp=fopen(includefile,"rt"))==NULL) {
895 printfstderr("Error: no include file %s\n",includefile);
896 exit(1);
897 }
898 while (fgetline(fp,&buf)!=1) {
899 if (strcmp(buf,"%%Creator:")==0) {
900 printfstdout("%s GRA2PS %s\n",buf,VERSION);
901 } else if (strcmp(buf,"%%CreationDate:")==0) {
902 t=time(NULL);
903 ltime=localtime(&t);
904 printfstdout("%s %d-%d-%d %d:%d\n",buf,
905 ltime->tm_mon+1,ltime->tm_mday,1900+ltime->tm_year,
906 ltime->tm_hour,ltime->tm_min);
907 } else if (strcmp(buf,"%%Pages:")==0) {
908 printfstdout("%s %d\n",buf,1);
909 } else if (strcmp(buf,"%%BoundingBox:")==0) {
910 if (epsf) {
911 if (bminx>bmaxx) {
912 bminx=0;
913 bmaxx=0;
914 }
915 if (bminy>bmaxy) {
916 bminy=bottom;
917 bmaxy=bottom;
918 }
919 sx=(bmaxx-bminx)/100;
920 sy=(bmaxy-bminy)/100;
921 bminx-=sx;
922 bminy-=sy;
923 bmaxx+=sx;
924 bmaxy+=sy;
925 if (rotate)
926 printfstdout("%s %d %d %d %d\n",buf,
927 (int )(bminy/2540.0*72),
928 (int )(bminx/2540.0*72),
929 (int )(bmaxy/2540.0*72),
930 (int )(bmaxx/2540.0*72));
931 else
932 printfstdout("%s %d %d %d %d\n",buf,
933 (int )(bminx/2540.0*72),
934 (int )((bottom-bmaxy)/2540.0*72),
935 (int )(bmaxx/2540.0*72),
936 (int )((bottom-bminy)/2540.0*72));
937 } else {
938 if (rotate)
939 printfstdout("%s %d %d %d %d\n",buf,
940 (int )(0),
941 (int )(0),
942 (int )(cpar[4]/2540.0*72),
943 (int )(cpar[3]/2540.0*72));
944 else
945 printfstdout("%s %d %d %d %d\n",buf,
946 (int )(0),
947 (int )((bottom-cpar[4])/2540.0*72),
948 (int )(cpar[3]/2540.0*72),
949 (int )(bottom/2540.0*72));
950 }
951 } else if ((strcmp(buf,"%%EndComments")==0) && (epsf)) {
952 putstdout(buf);
953 } else {
954 putstdout(buf);
955 }
956 free(buf);
957 }
958 fclose(fp);
959 putstdout("%%Page: Figure 1");
960 putstdout("%%BeginPageSetup");
961 if (rotate) printfstdout("/ANGLE %d def\n",-90);
962 else printfstdout("/ANGLE %d def\n",0);
963 printfstdout("/bottom %d def\n",-bottom);
964 putstdout("NgraphDict begin");
965 putstdout("PageSave");
966 putstdout("BeginPage");
967 putstdout("%%EndPageSetup");
968 include=TRUE;
969 break;
970 case 'E':
971 putstdout("EndPage");
972 putstdout("PageRestore");
973 putstdout("showpage");
974 putstdout("end");
975 putstdout("%%Trailer");
976 putstdout("%%DocumentNeededResources: ");
977 fcur=fmap;
978 while (fcur!=NULL) {
979 if (fcur->used)
980 printfstdout("%% font %s\n",fcur->fontname);
981 fcur=fcur->next;
982 }
983 putstdout("%%EOF");
984 break;
985 case '%':
986 if (include) printfstdout("%c%s\n",'%',cstr);
987 printfstderr("%c%s\n",'%',cstr);
988 break;
989 case 'V':
990 if (color)
991 printfstdout("%d %d %d %d %d viewc\n",
992 cpar[1],cpar[2],cpar[3]-cpar[1],cpar[4]-cpar[2],cpar[5]);
993 else
994 printfstdout("%d %d %d %d %d view\n",
995 cpar[1],cpar[2],cpar[3]-cpar[1],cpar[4]-cpar[2],cpar[5]);
996 break;
997 case 'A':
998 if (cpar[1]==0) printfstdout("[] 0 ");
999 else {
1000 printfstdout("[");
1001 for (i=0;i<cpar[1];i++) printfstdout("%d ",cpar[i+6]);
1002 printfstdout("] 0 ");
1003 }
1004 printfstdout("%d %d %d %g lsty\n",cpar[2],cpar[3],cpar[4],cpar[5]/100.0);
1005 break;
1006 case 'G':
1007 R=cpar[1];
1008 G=cpar[2];
1009 B=cpar[3];
1010 if (color)
1011 printfstdout(
1012 "%d 255 div %d 255 div %d 255 div setrgbcolor\n",R,G,B);
1013 else {
1014 d=0.3*R+0.59*G+0.11*B;
1015 a=(int )d;
1016 if (d-a>=0.5) a++;
1017 printfstdout("%d 255 div setgray\n",a);
1018 }
1019 break;
1020 case 'M':
1021 printfstdout("%d %d mto\n",cpar[1],cpar[2]);
1022 cpx=cpar[1];
1023 cpy=cpar[2];
1024 setcp=TRUE;
1025 break;
1026 case 'N':
1027 printfstdout("%d %d rmto\n",cpar[1],cpar[2]);
1028 cpx+=cpar[1];
1029 cpy+=cpar[2];
1030 setcp=TRUE;
1031 break;
1032 case 'L':
1033 printfstdout("%d %d %d %d l\n",cpar[1],cpar[2],cpar[3],cpar[4]);
1034 setcp=FALSE;
1035 break;
1036 case 'T':
1037 if (!setcp) printfstdout("%d %d mto\n",cpx,cpy);
1038 printfstdout("%d %d lto\n",cpar[1],cpar[2]);
1039 cpx=cpar[1];
1040 cpy=cpar[2];
1041 lineto=TRUE;
1042 linetonum++;
1043 setcp=TRUE;
1044 break;
1045 case 'C':
1046 if (cpar[7]==0)
1047 printfstdout("%d %d %d %d %d %d e\n",
1048 -cpar[5]-cpar[6],-cpar[5],cpar[3],cpar[4],cpar[1],cpar[2]);
1049 else if (cpar[7]==1)
1050 printfstdout("%d %d %d %d %d %d fe\n",
1051 -cpar[5]-cpar[6],-cpar[5],cpar[3],cpar[4],cpar[1],cpar[2]);
1052 else
1053 printfstdout("%d %d %d %d %d %d ae\n",
1054 -cpar[5]-cpar[6],-cpar[5],cpar[3],cpar[4],cpar[1],cpar[2]);
1055 setcp=FALSE;
1056 break;
1057 case 'B':
1058 if (cpar[5]==0)
1059 printfstdout("%d %d %d %d rec\n",
1060 cpar[3]-cpar[1],cpar[4]-cpar[2],cpar[1],cpar[2]);
1061 else
1062 printfstdout("%d %d %d %d bar\n",
1063 cpar[3]-cpar[1],cpar[4]-cpar[2],cpar[1],cpar[2]);
1064 setcp=FALSE;
1065 break;
1066 case 'P':
1067 printfstdout("%d %d pix\n",cpar[1],cpar[2]);
1068 break;
1069 case 'R':
1070 for (i=0;i<cpar[1];i++)
1071 printfstdout("%d %d ",cpar[i*2+2],cpar[i*2+3]);
1072 printfstdout("%d ",cpar[1]);
1073 putstdout("rpo");
1074 setcp=FALSE;
1075 break;
1076 case 'D':
1077 for (i=0;i<cpar[1];i++)
1078 printfstdout("%d %d ",cpar[i*2+3],cpar[i*2+4]);
1079 printfstdout("%d ",cpar[1]);
1080 if (cpar[2]==0) putstdout("dpo");
1081 else if (cpar[2]==1) putstdout("epo");
1082 else putstdout("fpo");
1083 setcp=FALSE;
1084 break;
1085 case 'F':
1086 free(fontalias);
1087 fontalias=malloc(strlen(cstr)+1);
1088 strcpy(fontalias,cstr);
1089 break;
1090 case 'H':
1091 fontname=NULL;
1092 if (fontalias==NULL) {
1093 loadfont=FALSE;
1094 break;
1095 }
1096 fcur=fmap;
1097 while (fcur!=NULL) {
1098 if (strcmp(fontalias,fcur->fontalias)==0) {
1099 fontname=fcur->fontname;
1100 fonttype=fcur->type;
1101 if (!(fcur->used))
1102 printfstdout("%%IncludeResource: font %s\n",fcur->fontname);
1103 fcur->used=TRUE;
1104 break;
1105 }
1106 fcur=fcur->next;
1107 }
1108 if (fontname==NULL) {
1109 loadfont=FALSE;
1110 break;
1111 }
1112 fontsize=cpar[1]/72.0*25.4;
1113 sprintf(textspace,"%g %g",cpar[2]*cos(MPI*cpar[3]/18000.0)*25.4/72,
1114 -cpar[2]*sin(MPI*cpar[3]/18000.0)*25.4/72);
1115 if ((fonttype==ITALIC) || (fonttype==BOLDITALIC)) {
1116 ftan=tan(font_slant*MPI/180.0);
1117 printfstdout("[%g %g %g %g 0 0] ",
1118 cpar[1]*cos(MPI*cpar[3]/18000.0)*25.4/72,
1119 -cpar[1]*sin(MPI*cpar[3]/18000.0)*25.4/72,
1120 -cpar[1]*(sin(MPI*cpar[3]/18000.0)
1121 -ftan*cos(MPI*cpar[3]/18000.0))*25.4/72,
1122 -cpar[1]*(cos(MPI*cpar[3]/18000.0)
1123 +ftan*sin(MPI*cpar[3]/18000.0))*25.4/72);
1124 } else {
1125 printfstdout("[%g %g %g %g 0 0] ",
1126 cpar[1]*cos(MPI*cpar[3]/18000.0)*25.4/72,
1127 -cpar[1]*sin(MPI*cpar[3]/18000.0)*25.4/72,
1128 -cpar[1]*sin(MPI*cpar[3]/18000.0)*25.4/72,
1129 -cpar[1]*cos(MPI*cpar[3]/18000.0)*25.4/72);
1130 }
1131 printfstdout("%s F\n",fontname);
1132 loadfont=TRUE;
1133 break;
1134 case 'S':
1135 if (!loadfont) break;
1136 if ((fonttype==BOLD) || (fonttype==BOLDITALIC)) {
1137 printfstdout("/BOLDS %g def\n",fontsize*0.018);
1138 }
1139 printfstdout("%s (",textspace);
1140 i=0;
1141 while (i<strlen(cstr)) {
1142 if (cstr[i]=='\\') {
1143 if (cstr[i+1]=='x') {
1144 if (tolower(cstr[i+2])>='a') c1=tolower(cstr[i+2])-'a'+10;
1145 else c1=tolower(cstr[i+2])-'0';
1146 if (tolower(cstr[i+3])>='a') c2=tolower(cstr[i+3])-'a'+10;
1147 else c2=tolower(cstr[i+3])-'0';
1148 printfstdout("\\%c%c%c",c1/4+'0',(c1%4)*2+c2/8+'0',c2%8+'0');
1149 i+=4;
1150 } else if (cstr[i+1]=='\\') {
1151 printfstdout("\\\\");
1152 i+=2;
1153 } else i++;
1154 } else {
1155 switch (cstr[i]) {
1156 case '\\':
1157 printfstdout("\\\\");
1158 break;
1159 case ')':
1160 printfstdout("\\)");
1161 break;
1162 case '(':
1163 printfstdout("\\(");
1164 break;
1165 default:
1166 if (cstr[i]&0x80) {
1167 c1=((unsigned char)cstr[i])>>4;
1168 c2=((unsigned char)cstr[i]) & 0xF;
1169 printfstdout("\\%c%c%c",c1/4+'0',(c1%4)*2+c2/8+'0',c2%8+'0');
1170 } else printfstdout("%c",cstr[i]);
1171 break;
1172 }
1173 i++;
1174 }
1175 }
1176 if ((fonttype==BOLD) || (fonttype==BOLDITALIC)) {
1177 printfstdout(") ashowB\n");
1178 } else {
1179 printfstdout(") ashow\n");
1180 }
1181 break;
1182 case 'K':
1183 if (!loadfont) break;
1184 if ((fonttype==BOLD) || (fonttype==BOLDITALIC)) {
1185 printfstdout("/BOLDS %g def\n",fontsize*0.018);
1186 }
1187 printfstdout("%s <",textspace);
1188 i=0;
1189 while (i<strlen(cstr)) {
1190 if (niskanji((unsigned char)cstr[i]) && (cstr[i+1]!='\0')) {
1191 if (!sjis)
1192 jis=njms2jis(((unsigned char)cstr[i] << 8)+(unsigned char)cstr[i+1]);
1193 else
1194 jis=((unsigned char)cstr[i] << 8)+(unsigned char)cstr[i+1];
1195 printfstdout(" %2hx%2hx",jis>>8,jis &0xff);
1196 i+=2;
1197 } else i++;
1198 }
1199 if ((fonttype==BOLD) || (fonttype==BOLDITALIC)) {
1200 printfstdout("> ashowB\n");
1201 } else {
1202 printfstdout("> ashow\n");
1203 }
1204 break;
1205 }
1206 }
1207
loadconfig(void)1208 void loadconfig(void)
1209 {
1210 FILE *fp;
1211 char *tok,*str,*s2;
1212 char *f1,*f2,*f3;
1213 struct fontmap *fcur,*fnew;
1214 int val;
1215 char *endptr;
1216 int len;
1217
1218 if ((fp=openconfig(GRA2CONF))==NULL) {
1219 printfstderr("Error: configuration file (%s) is not found.\n",CONF);
1220 exit(1);
1221 }
1222 fcur=NULL;
1223 while ((tok=getconfig(fp,&str))!=NULL) {
1224 s2=str;
1225 if (strcmp(tok,"font_map")==0) {
1226 f1=getitok2(&s2,&len," \t,");
1227 f2=getitok2(&s2,&len," \t,");
1228 f3=getitok2(&s2,&len," \t,");
1229 if ((f1!=NULL) && (f2!=NULL) && (f3!=NULL)) {
1230 fnew=malloc(sizeof(struct fontmap));
1231 if (fcur==NULL) fmap=fnew;
1232 else fcur->next=fnew;
1233 fcur=fnew;
1234 fcur->next=NULL;
1235 fcur->fontalias=f1;
1236 if (strcmp(f2,"bold")==0) fcur->type=BOLD;
1237 else if (strcmp(f2,"italic")==0) fcur->type=ITALIC;
1238 else if (strcmp(f2,"bold_italic")==0) fcur->type=BOLDITALIC;
1239 else fcur->type=NORMAL;
1240 fcur->fontname=f3;
1241 fcur->used=FALSE;
1242 free(f2);
1243 } else {
1244 free(f1);
1245 free(f2);
1246 free(f3);
1247 }
1248 } else if (strcmp(tok,"include")==0) {
1249 includefile=getitok2(&s2,&len,"");
1250 } else if (strcmp(tok,"color")==0) {
1251 f1=getitok2(&s2,&len," \t,");
1252 val=strtol(f1,&endptr,10);
1253 if (endptr[0]=='\0') {
1254 if (val==0) color=FALSE;
1255 else color=TRUE;
1256 }
1257 free(f1);
1258 } else if (strcmp(tok,"sjis")==0) {
1259 f1=getitok2(&s2,&len," \t,");
1260 val=strtol(f1,&endptr,10);
1261 if (endptr[0]=='\0') {
1262 if (val==0) sjis=FALSE;
1263 else sjis=TRUE;
1264 }
1265 free(f1);
1266 }
1267 free(tok);
1268 free(str);
1269 }
1270 closeconfig(fp);
1271 }
1272
main(int argc,char ** argv)1273 int main(int argc,char **argv)
1274 {
1275 int i;
1276 char *filename;
1277 FILE *fp;
1278 char *buf;
1279 char *lib,*home;
1280 char *tmpname;
1281 int ch;
1282 char *endptr;
1283 int a;
1284
1285 printfstderr("Ngraph - PostScript(R) Printer Driver version: "VERSION"\n");
1286
1287 #ifndef WINDOWS
1288 if ((lib=getenv("NGRAPHLIB"))!=NULL) {
1289 if ((libdir=(char *)malloc(strlen(lib)+1))==NULL) exit(1);
1290 strcpy(libdir,lib);
1291 } else {
1292 if ((libdir=(char *)malloc(strlen(LIBDIR)+1))==NULL) exit(1);
1293 strcpy(libdir,LIBDIR);
1294 }
1295 if ((home=getenv("NGRAPHHOME"))!=NULL) {
1296 if ((homedir=(char *)malloc(strlen(home)+1))==NULL) exit(1);
1297 strcpy(homedir,home);
1298 } else if ((home=getenv("HOME"))!=NULL) {
1299 if ((homedir=(char *)malloc(strlen(home)+1))==NULL) exit(1);
1300 strcpy(homedir,home);
1301 } else if ((home=getenv("Home"))!=NULL) {
1302 if ((homedir=(char *)malloc(strlen(home)+1))==NULL) exit(1);
1303 strcpy(homedir,home);
1304 } else {
1305 if ((homedir=(char *)malloc(strlen(libdir)+1))==NULL) exit(1);
1306 strcpy(homedir,libdir);
1307 }
1308 #else
1309 if ((lib=getenv("NGRAPHLIB"))!=NULL) {
1310 if ((libdir=(char *)malloc(strlen(lib)+1))==NULL) exit(1);
1311 strcpy(libdir,lib);
1312 } else {
1313 for (i=strlen(argv[0]);(argv[0][i]!='\\') && (i>0);i--);
1314 if ((libdir=(char *)malloc(i+1))==NULL) exit(1);
1315 strncpy(libdir,argv[0],i);
1316 libdir[i]='\0';
1317 }
1318 if ((home=getenv("NGRAPHHOME"))!=NULL) {
1319 if ((homedir=(char *)malloc(strlen(home)+1))==NULL) exit(1);
1320 strcpy(homedir,home);
1321 } else if ((home=getenv("HOME"))!=NULL) {
1322 if ((homedir=(char *)malloc(strlen(home)+1))==NULL) exit(1);
1323 strcpy(homedir,home);
1324 } else {
1325 if ((homedir=(char *)malloc(strlen(libdir)+1))==NULL) exit(1);
1326 strcpy(homedir,libdir);
1327 }
1328 #endif
1329 includefile=malloc(strlen(libdir)+11);
1330 strcpy(includefile,libdir);
1331 strcat(includefile,"/Ngraph.ps");
1332
1333 loadconfig();
1334
1335 outfilename=NULL;
1336 for (i=1;(i<argc) && (argv[i][0]=='-') && (argv[i][1]!='\0');i++) {
1337 switch (argv[i][1]) {
1338 case 'o':
1339 if (((i+1)<argc) && (argv[i+1][0]!='-')) {
1340 outfilename=argv[i+1];
1341 i++;
1342 }
1343 break;
1344 case 'i':
1345 if (((i+1)<argc) && (argv[i+1][0]!='-')) {
1346 free(includefile);
1347 if ((includefile=malloc(strlen(argv[i+1])+1))!=NULL)
1348 strcpy(includefile,argv[i+1]);
1349 i++;
1350 }
1351 break;
1352 case 'c':
1353 color=TRUE;
1354 break;
1355 case 'e':
1356 epsf=TRUE;
1357 break;
1358 case 'p':
1359 if (((i+1)<argc) && (argv[i+1][0]!='-')) {
1360 if ((strcmp(argv[i+1],"A3")==0) || (strcmp(argv[i+1],"a3")==0))
1361 paper=A3;
1362 else if ((strcmp(argv[i+1],"A4")==0) || (strcmp(argv[i+1],"a4")==0))
1363 paper=A4;
1364 else if ((strcmp(argv[i+1],"B4")==0) || (strcmp(argv[i+1],"b4")==0))
1365 paper=B4;
1366 else if ((strcmp(argv[i+1],"A5")==0) || (strcmp(argv[i+1],"a5")==0))
1367 paper=A5;
1368 else if ((strcmp(argv[i+1],"B5")==0) || (strcmp(argv[i+1],"b5")==0))
1369 paper=B5;
1370 else if ((strcmp(argv[i+1],"LETTER")==0)
1371 || (strcmp(argv[i+1],"letter")==0))
1372 paper=LETTER;
1373 else if ((strcmp(argv[i+1],"LEGAL")==0)
1374 || (strcmp(argv[i+1],"legal")==0))
1375 paper=LEGAL;
1376 i++;
1377 }
1378 break;
1379 case 'l':
1380 landscape=TRUE;
1381 break;
1382 case 'r':
1383 rotate=TRUE;
1384 break;
1385 case 's':
1386 if ((i+1)<argc) {
1387 a=strtol(argv[i+1],&endptr,10);
1388 if ((endptr[0]=='\0') && (0<=a) && (a<=60)) font_slant=a;
1389 i++;
1390 }
1391 break;
1392 default:
1393 printfstderr("unknown option `%s'.\n",argv[i]);
1394 free(includefile);
1395 free(libdir);
1396 free(homedir);
1397 exit(1);
1398 }
1399 }
1400
1401 if (i>=argc) {
1402 printfstderr("Usage: gra2ps [options] grafile\n");
1403 printfstderr("Options:\n");
1404 printfstderr(" -o file : output file\n");
1405 printfstderr(" -i file : include file\n");
1406 printfstderr(" -c : color output\n");
1407 printfstderr(" -e : EPSF output\n");
1408 printfstderr(" -p a3|a4|b4|a5|b5|letter|legal : paper\n");
1409 printfstderr(" -l : landscape\n");
1410 printfstderr(" -r : rotate by 90 degree\n");
1411 printfstderr(" -s theta : slant angle (degree)\n");
1412 free(includefile);
1413 free(libdir);
1414 free(homedir);
1415 exit(1);
1416 }
1417
1418 if (!rotate) {
1419 switch (paper) {
1420 case A3:
1421 if (landscape) bottom=29700;
1422 else bottom=42000;
1423 break;
1424 case A4:
1425 if (landscape) bottom=21000;
1426 else bottom=29700;
1427 break;
1428 case B4:
1429 if (landscape) bottom=25700;
1430 else bottom=36400;
1431 break;
1432 case B5:
1433 if (landscape) bottom=18200;
1434 else bottom=25700;
1435 break;
1436 case LETTER:
1437 if (landscape) bottom=21590;
1438 else bottom=27940;
1439 break;
1440 case LEGAL:
1441 if (landscape) bottom=21590;
1442 else bottom=35560;
1443 break;
1444 }
1445 } else bottom=0;
1446
1447 if (outfilename!=NULL) {
1448 if ((outfp=fopen(outfilename,"wt"))==NULL) {
1449 fprintf(stderr,"error: file open `%s'.\n",outfilename);
1450 free(includefile);
1451 free(libdir);
1452 free(homedir);
1453 exit(1);
1454 }
1455 } else outfp=stdout;
1456
1457 filename=argv[i];
1458 tmpname=NULL;
1459 if (epsf && (filename[0]=='-') && (filename[1]=='\0')) {
1460 if ((tmpname=tempnam(NULL,"GR2PS"))==NULL) exit(1);
1461 if ((fp=fopen(tmpname,"wt"))==NULL) exit(1);
1462 while ((ch=fgetc(stdin))!=EOF) fputc(ch,fp);
1463 fclose(fp);
1464 filename=tmpname;
1465 }
1466 if (epsf) {
1467 if ((fp=fopen(filename,"rt"))==NULL) {
1468 printfstderr("error: file not found `%s'.\n",filename);
1469 goto errexit;
1470 }
1471 if (fgetline(fp,&buf)==1) {
1472 printfstderr("error: illegal GRA format.\n");
1473 goto errexit;
1474 }
1475 if (strcmp(buf,GRAF)!=0) {
1476 printfstderr("error: illegal GRA format.\n");
1477 goto errexit;
1478 }
1479 free(buf);
1480 while (fgetline(fp,&buf)!=1) {
1481 if (!GRAinput(buf,getboundingbox)) {
1482 printfstderr("error: illegal GRA format.\n");
1483 goto errexit;
1484 }
1485 free(buf);
1486 }
1487 fclose(fp);
1488 }
1489 if ((filename[0]=='-') && (filename[1]=='\0')) fp=stdin;
1490 else {
1491 if ((fp=fopen(filename,"rt"))==NULL) {
1492 printfstderr("error: file not found `%s'.\n",filename);
1493 goto errexit;
1494 }
1495 }
1496 if (fgetline(fp,&buf)==1) {
1497 printfstderr("error: illegal GRA format.\n");
1498 goto errexit;
1499 }
1500 if (strcmp(buf,GRAF)!=0) {
1501 printfstderr("error: illegal GRA format.\n");
1502 goto errexit;
1503 }
1504 free(buf);
1505 while (fgetline(fp,&buf)!=1) {
1506 if (!GRAinput(buf,draw)) {
1507 printfstderr("error: illegal GRA format.\n");
1508 goto errexit;
1509 }
1510 free(buf);
1511 }
1512 fclose(outfp);
1513 fclose(fp);
1514 if (tmpname!=NULL) {
1515 unlink(tmpname);
1516 free(tmpname);
1517 }
1518 free(includefile);
1519 free(libdir);
1520 free(homedir);
1521 return 0;
1522 errexit:
1523 if (tmpname!=NULL) {
1524 unlink(tmpname);
1525 free(tmpname);
1526 }
1527 free(includefile);
1528 free(libdir);
1529 free(homedir);
1530 return 1;
1531 }
1532