1 /***************************************************************************
2  * Copyright (C) 1991,1992 by Wei Sun (william@cs.anu.edu.au)
3  * All Rights Reserved
4  * Version 2.02
5  *
6  * File:gbchar.c
7  *
8  * DISTRIBUTION:
9  *      This program is NOT in public domain.
10  *      It can be freely distributed for non-commercial purposes only,
11  *      and THERE IS NO WARRANTY FOR THIS PROGRAM.
12  **************************************************************************/
13 #include "gb2ps.h"
14 
15 int  	CHcode[8836][6];
16 int	ascflag=FALSE;
17 int	CH_mode=FALSE;
18 int	paraflag=TRUE;
19 int	newpage_flag=TRUE;
20 int	file_pointer_flag;
21 struct	Page 	page[400];
22 int	linecounter=0;
23 float	line_h[26400];
24 int	maxFont_height=0; /* will be set when read commands*/
25 int	commandcounter=0;
26 int	rotate_flag=FALSE;
27 int	setgray=0;
28 
29 void
ASCshow()30 ASCshow() {
31 	if (ascflag) {
32 		if (!Analyse_flag) fprintf(out,") S\n");
33 		ascflag=FALSE;
34 	}
35 }
36 
37 void
newline()38 newline ()
39 {
40 	charcount=0;  H=_LM;
41 	ASCshow();
42 
43 	if (maxFont_height<font_height)
44 			maxFont_height=font_height;
45 
46 	if (Analyse_flag) {
47 		if (newpage_flag) {
48 			newpage_flag=FALSE;
49 			V =_TM-_CLP;
50 		}
51 		V -= _CLP;
52 		line_h[linecounter]=_CLP;
53 		linecounter++;
54 		maxFont_height=0;
55 	}
56 	else {
57 		V -= line_h[linecounter];
58 		linecounter++;
59 	}
60 	if (V<_BM) {
61 		if (endpage_flag) {
62 			end_page();
63 			begin_page();
64 			newpage_flag=TRUE;
65 			endpage_flag=FALSE;
66 		}
67 		else {
68 			endpage_flag=TRUE;
69 /*			printf("==Page %d lines:%d  offset:%d V=%f\n", pagecounter,linecounter,ftell(in)-file_pointer_flag,V);*/
70 			if (Analyse_flag) {
71 				page[pagecounter+1].offset=ftell(in)
72 							-file_pointer_flag;
73 				page[pagecounter+1].chfont=CFP;
74 				page[pagecounter+1].font_height=font_height;
75 				page[pagecounter+1].font_width=font_width;
76 				page[pagecounter+1]._LM=_LM;
77 				page[pagecounter+1]._RM=_RM;
78 				page[pagecounter+1]._TM=_TM;
79 				page[pagecounter+1]._BM=_BM;
80 				page[pagecounter+1]._FI=_FI;
81 				page[pagecounter+1].lineNo=linecounter-1;
82 			}
83 		}
84 	}
85 }
86 
87 void
put_ASC(c)88 put_ASC(c)
89 int c;
90 {
91 	if(c==26||c==EOF||c==0) return;
92 
93 	charcount++;
94 	if (maxFont_height<font_height)
95 			maxFont_height=font_height;
96 
97 	if (paraflag) {
98 		H=_LM;
99 		H+=_FI; paraflag=FALSE;
100 	}
101 
102 	if (endpage_flag) {
103 		end_page();
104 		begin_page();
105 		newpage_flag=TRUE;
106 		endpage_flag=FALSE;
107 	}
108 
109 
110 	if (Analyse_flag) {
111 	  if ((c>=' ') && (!ascflag)) ascflag=TRUE;
112 	}
113 	else {
114 	  if(c>=' ') {
115 		if (!ascflag) {
116 			ascflag=TRUE;
117 			  fprintf(out,"%.0f %.0f M (",H+0.5, V+0.5);
118 		}
119 		if ((c<=0x7f)&&(c>=0x20)&&(c!='(')&&(c!=')'))
120 			fprintf(out,"%c",c);
121 		else
122 			fprintf(out,"\\%03o",c);
123 	  }
124 	  else fprintf(out," ");
125 	}
126 
127 	H+=_ASP;
128 	if (H>_RM)
129 		newline ();
130 }
131 
132 void
put_CH(ch1,ch2)133 put_CH(ch1,ch2)
134 int ch1,ch2;
135 {
136 	long addr;
137 	char st1[10];
138 	char st2[200];
139 	charcount+=2;
140 	ASCshow();
141 
142 	if (maxFont_height<font_height)
143 			maxFont_height=font_height;
144 
145 	if (paraflag) {
146 		H=_LM;
147 		H+=_FI; paraflag=FALSE;
148 	}
149 
150 	if (endpage_flag) {
151 		end_page();
152 		begin_page();
153 		newpage_flag=TRUE;
154 		endpage_flag=FALSE;
155 	}
156 
157 	if (Analyse_flag) {
158 		if ((pagecounter>=page_begin_print) &&
159 		    (pagecounter!=page_end_print))
160 			CHcode[(ch1-0xA1)*94+ch2-0xA1][CFP]+=1;
161 	}
162 	else
163 	  if (ch1!=0xa1||ch2!=0xa1) {
164 		addr=(ch1-0xA1)*94+ch2-0xA1;
165 		fprintf(out,"%.0f %.0f ",H+0.5, V+0.5);
166 		if (CHcode[addr][CFP]>=CHAR_LIMIT)
167 			/*QuWei code start from 1*/
168 			fprintf(out,"C%1d%02d%02d\n",CFP,ch1-0xa0,ch2-0xa0);
169 		else {
170 			fseek(cfont,offset_CH+addr*size_of_CH,0);
171 			fgets(line,size_of_CH,cfont);
172 			sscanf(line,"%s %s",st1,st2);
173 			fprintf(out,"H {<%s>} I G\n",st2);
174 		}
175 	  }
176   	H+=_CSP;
177 	if (H>_RM)
178 		newline ();
179 }
180 
putChar(ch1,ch2)181 int putChar(ch1,ch2)
182 int ch1,ch2;
183 {
184       int k,k1;
185 	file_pointer_flag=1;
186 
187       switch (ch1) {
188       	case 13: case 26: break; /* for PC format file*/
189       	case '\n': paraflag=TRUE; newline(); break;
190       	case '\t': k1=8-charcount%8;
191 		  for (k=0;k<=k1;k++)
192 			put_ASC(' ');
193 		  break;
194         case 12: end_page(); break;
195         case EOF: return EOF;
196         default:
197       		if (ch1>=0xA1) {
198       			switch (ch2){
199       			  case 13:case 26:  /* for PC format file*/
200       			  case EOF:
201 				put_ASC(ch1); return EOF;
202 			  case '\n':case 0:
203       			  	put_ASC(ch1); paraflag=TRUE; newline(); break;
204 			  case 12:
205       			  	put_ASC(ch1); end_page(); break;
206       			  default:
207 	  			if (ch2<0xA1) {
208 			  		put_ASC(ch1);
209 					file_pointer_flag=0;
210 		  			put_ASC(ch2);
211 				}
212 	  			else {
213 					file_pointer_flag=0;
214 					put_CH(ch1,ch2);
215 				}
216 			}
217 			return 0;
218       		}
219 		else put_ASC(ch1);
220       }
221       return ch2;
222 }
223 
224 void
putString(st)225 putString(st)
226 char* st;
227 {
228 	int i,ch,ch1,ch2,len;
229 	i=0;
230 	ch=0;
231 	len=strlen(st);
232 	while (i<=len) {
233 		ch1=st[i++];
234 		if (!ch)
235 			ch2=st[i++];
236 		else {
237 	  		ch2=ch1;
238 			ch1=ch;
239 		}
240 		ch=putChar(ch1,ch2);
241 	}
242 }
243 
244 /*===========================================================================*/
245 
246 void
DefCHdict()247 DefCHdict() {
248 	long i,j,k=0;
249 	char st1[10];
250 	char st2[200];
251 
252 
253 	for (i=0;i<94*94;i++)
254 	   for (j=0;j<6;j++) {
255 		if (CHcode[i][j]>=CHAR_LIMIT) k++;
256 	   }
257 
258 	fprintf(out,"/CHdict %ld dict def\nCHdict begin\n",k+400);
259 
260 	for (i=0;i<94*94;i++)
261 	   for (j=0;j<6;j++) {
262 		if (CHcode[i][j]>=CHAR_LIMIT) {
263 			fseek(CHFONT[j].fp,offset_CH+i*size_of_CH,0);
264 			fgets(line,size_of_CH,CHFONT[j].fp);
265 			sscanf(line,"%s %s",st1,st2);
266 			fprintf(out,"/C%1ld%s {H {<%s>} I G} def \n",j,st1,st2);
267 		}
268 	   }
269 }
270 
271 
272 /*AnalyseDoc: analyse the input document.*/
273 
274 void
AnalyseDoc()275 AnalyseDoc() {
276   int	ch=0,ch1,ch2,i,j;
277 
278   for (i=0;i<94*94;i++)
279     for (j=0;j<6;j++)
280 	CHcode[i][j]=0;;
281 
282   begin_page();
283   while ((ch1=readchar())!=EOF) {
284 	if (!ch)
285 		ch2=readchar();
286 	else {
287 		ch2=ch1;
288 		ch1=ch;
289 	}
290 	ch=putChar(ch1,ch2);
291   }
292   newline();
293 
294   if (pagecounter>=page_begin_print) {
295 	CFP=page[page_begin_print].chfont;
296 	cfont=CHFONT[CFP].fp;
297 	_LM=page[page_begin_print]._LM;
298 	_RM=page[page_begin_print]._RM;
299 	_TM=page[page_begin_print]._TM;
300 	_BM=page[page_begin_print]._BM;
301 	_FI=page[page_begin_print]._FI;
302 	linecounter=page[page_begin_print].lineNo;
303 	font_height=page[page_begin_print].font_height;
304 	font_width=page[page_begin_print].font_width;
305 	fseek(in,page[page_begin_print].offset,0);
306 	pagecounter=page_begin_print;
307  }
308   else  {
309 	printf("The file %s only has %d Page(s).\n",filename,pagecounter);
310 	exit(1);
311   }
312   Analyse_flag=FALSE; H=_LM; paraflag=TRUE;ascflag=FALSE; CH_mode=FALSE;
313 }
314 
readchar()315 int readchar() {
316 	int	c;
317 	int	tmp;
318 	float	tmp1=0.0;
319 
320 	c=fgetc(in);
321 	while (c=='~') {
322 		tmp=fgetc(in);
323 		switch (tmp) {
324 		  case '{':	CH_mode=TRUE;  break;
325 		  case '}':	CH_mode=FALSE; break;
326 		  case '~':	break;
327 		  case '\n':	break;
328 		  default:	ungetc(tmp,in);
329 		}
330 		if (tmp=='~')
331 			break;
332 		else
333 			c=fgetc(in);
334 	}
335 
336 	if (CH_mode) {
337 		if (((c&0x7f)>=0x21)&&((c&0x7f)<=0x7e)) {
338 			return c|0x80;
339         } else {
340 			CH_mode=FALSE;
341 			return c;
342 		}
343     }
344 
345 	if (!format_flag) return c;
346 
347 	if (c=='<') {
348 	    ASCshow();
349 	    commandcounter=ftell(in);
350 	    while ((c!='>') && (c!=EOF)){
351 		c=fgetc(in);
352 		if (c=='<') break;
353 		switch (c) {
354 		  case '<':case EOF: break;
355 		  case 'L':
356 			fscanf(in,"%d",&tmp);
357 			if (tmp>0) linespace=tmp;
358 			break;
359 		  case 'C':
360 			fscanf(in,"%f",&tmp1);
361 			if (tmp1>0) charspace=tmp1;
362 			break;
363 		  case 'B':
364 			fscanf(in,"%f",&tmp1);
365 			V=-tmp1;
366 			break;
367 		  case 'm':
368 			fscanf(in,"%f",&tmp1);
369 			if (tmp1>0) H=tmp1;
370 			fscanf(in,"%f",&tmp1);
371 			if (tmp1>0) V=tmp1;
372 			break;
373 		  case 'M':
374 			switch (c=fgetc(in)) {
375 		  	  case 'L':
376 				fscanf(in,"%d",&tmp);
377 				if (tmp>0) _LM=tmp;
378 				if (H<tmp) H=(float)tmp;
379 				break;
380 		  	  case 'R':
381 				fscanf(in,"%d",&tmp);
382 				if (tmp>0) _RM=572-tmp;
383 				break;
384 		  	  case 'T':
385 				fscanf(in,"%d",&tmp);
386 				if (tmp>0) _TM=832-tmp;
387 				break;
388 		  	  case 'B':
389 				fscanf(in,"%d",&tmp);
390 				if (tmp>0) _BM=tmp;
391 				break;
392 		  	  case 'I':
393 				fscanf(in,"%d",&tmp);
394 				_FI=tmp;
395 				break;
396 			}
397 			break;
398 
399 		  case 'F':
400 			switch (c=fgetc(in)) {
401 			  case 'S':case 's':
402 				CFP=0; cfont=CHFONT[CFP].fp; break;
403 			  case 'K':case 'k':
404 				CFP=1; cfont=CHFONT[CFP].fp; break;
405 			  case 'F':case 'f':
406 				CFP=2; cfont=CHFONT[CFP].fp; break;
407 			  case 'H':case 'h':
408 				CFP=3; cfont=CHFONT[CFP].fp; break;
409 			  case 'G':case 'g':
410 				CFP=4; cfont=CHFONT[CFP].fp; break;
411 			  case 'U':case 'u':
412 				CFP=5; cfont=CHFONT[CFP].fp; break;
413 		  	  case 'Z':case 'z':
414 				fscanf(in,"%d",&tmp);
415 				if (tmp>0) font_width=tmp;
416 				fscanf(in,"%d",&tmp);
417 				if (tmp>0) font_height=tmp;
418 				if (!Analyse_flag) {
419 					fprintf(out,"/Courier findfont [%.2f 0 0 %.2f 0 0] makefont setfont\n",0.837*font_width,1.5*font_height);
420   					fprintf(out,"/H {moveto gsave currentpoint translate %d %d scale 24 24 true [24 0 0 -24 0 24]}def\n",font_width,font_height);
421 				}
422 				break;
423 		  	  case 'R':case'r':
424 				fscanf(in,"%d",&tmp);
425 				if (!Analyse_flag) {
426 				  if (tmp==0) {
427 					fprintf(out,"/Courier findfont [%.2f 0 0 %.2f 0 0] makefont setfont\n",0.837*font_width,1.5*font_height);
428 
429   					fprintf(out,"/H {moveto gsave currentpoint translate %d %d scale 24 24 true [24 0 0 -24 0 24]}def\n",font_width,font_height);
430 				  }
431 				  else {
432   					fprintf(out,"/H {moveto gsave currentpoint translate %d %d scale 24 24 true [24 0 0 -24 0 24] %d rotate}def\n",font_width,font_height,tmp);
433 				  }
434 				}
435 				break;
436 		  	  case 'O':case 'o':
437 				tmp=font_width;
438 				font_width=font_height;
439 				font_height=tmp;
440 				rotate_flag=(!rotate_flag);
441 				if (rotate_flag==FALSE) {
442 					H-=font_height;
443   					if (!Analyse_flag)
444 						fprintf(out,"/H {moveto gsave currentpoint translate %d %d scale 24 24 true [24 0 0 -24 0 24]}def\n",font_width,font_height);
445 				}
446 				else  {
447 					H+=font_width;
448   					if (!Analyse_flag)
449 						fprintf(out,"/H {moveto gsave currentpoint translate %d %d scale 24 24 true [24 0 0 -24 0 24] 90 rotate}def\n",font_width,font_height);
450 				}
451 				break;
452 			}
453 			break;
454 
455 		  case 'G':
456 			fscanf(in,"%d",&tmp);
457 			if ((tmp>=0)&&(!Analyse_flag)) {
458 				setgray=tmp;
459 				fprintf(out,"%.2f setgray\n",(float)tmp/100.0);
460 			}
461 			break;
462 		}
463 	    }
464 	}
465 	if (c=='>') c=fgetc(in);
466 	return c;
467 }
468