|
|
1.1 root 1:
2:
3: /*
4: *
5: * Reads the raster files listed as arguments and prints the glyphs, along
6: * with information about character widths and glyph numbers, on an Imagen
7: * printer. The output is written in Impress. If no glyphs are selected by
8: * using the -o option the entire file or files will be printed. An Impress
9: * document header is the first thing written to the output file provided
10: * want_header == TRUE. Use the -H option to force the header. The target
11: * printer is assumed to have a resolution of res dots per inch, which by
12: * default is set to RAST_RES (probably 300). If that's not the case use
13: * the -r option to select a new resolution. It's really only important
14: * in determining the pixel length of a page.
15: *
16: * Text in the printout is written using font *font in size list_size.
17: * By default it's resident font cour10. You can change the requested font
18: * and size using the -f and -s options respectively.
19: *
20: * All the raster files are assumed to be in directory *rastdir, which by
21: * default is set to ".". *rastdir can be changed by using the -R option.
22: * but in all cases the string "*rastdir/" is prepended to the raster file
23: * names to get the complete pathname.
24: *
25: * As an example the command line,
26: *
27: * printrast -R /usr/lib/raster/rasti300 -H -r 300 R.10 I.10 >xxx
28: *
29: * will write the Impress commands needed to print the glyphs in raster
30: * file /usr/lib/raster/rasti300/R.10 and /usr/lib/raster/rasti300/I.10 out
31: * to file xxx. The target printer is assumed to have a resolution of 300
32: * dots per inch. The output file xxx begins with a document header defining
33: * the language to be Impress and can therefore be set directly to an 8/300.
34: *
35: * A word of warning is in order here. Because I've written readrastfile()
36: * so it accepts two different raster file naming conventions there isn't
37: * a one to one mapping of file names to font name, size pairs. That means
38: * if you have two similiarly named raster files, differing only in the
39: * naming convention used, and you keep them in the same directory you'll
40: * always display glyphs from the preferred file no matter which file
41: * you list on the command line. I don't think it will cause any real
42: * problems so I'm not going to change any of this stuff.
43: *
44: */
45:
46:
47: #include <stdio.h>
48:
49: #include "gen.h" /* general purpose definitions */
50: #include "ext.h" /* external variable declarations */
51: #include "rast.h" /* raster file definitions */
52: #include "impcodes.h" /* Impress opcode definitions */
53:
54:
55: FILE *fp_out = stdout; /* output file - probably won't change */
56:
57: char *font = "cour"; /* use this font for printing text */
58: int list_size = 10; /* and this point size */
59:
60: float xoffset = .25; /* start this far from left edge */
61: float yoffset = .50; /* and this far down the page - inches */
62:
63: int p_xoffset; /* same as last two but in pixels */
64: int p_yoffset;
65:
66: float height = 10.50; /* height of the paper in inches */
67: float width = 8.75; /* same but for paper width */
68:
69: int p_height; /* paper dimensions in pixels */
70: int p_width;
71:
72: int res = RAST_RES; /* resolution of the target printer */
73:
74: int hpos; /* current horizontal position - pixels */
75: int vpos; /* same but for vertical position */
76:
77: int linesp; /* interline spacing */
78: int spacewid; /* interword spacing */
79:
80: int want_header = FALSE; /* write document header first */
81:
82:
83: /*****************************************************************************/
84:
85:
86: main(agc, agv)
87:
88:
89: int agc;
90: char *agv[];
91:
92:
93: {
94:
95:
96: /*
97: *
98: * Reads Imagen formatted raster files and writes the Impress commands
99: * needed to print the glyphs, along with width and index data, to fp_out.
100: * Text is written using resident the resident font whose name is built
101: * by concatenating *font and list_size. By default the font is cour10,
102: * but both font and list_size can be changed by options. Individual glyphs
103: * in the raster files can be selected, rather than the whole file, by
104: * using the -o option (although I haven't tested this yet).
105: *
106: */
107:
108:
109: argc = agc; /* other routines may want them */
110: argv = agv;
111:
112: prog_name = argv[0]; /* really just for error messages */
113: rastdir = "."; /* current directory by default */
114:
115: options(); /* first get command line options */
116: doc_header(); /* make sure this comes first */
117: initialize(); /* must be done after options */
118: arguments(); /* then process non-option arguments */
119:
120: exit(x_stat); /* everything probably went OK */
121:
122: } /* End of main */
123:
124:
125: /*****************************************************************************/
126:
127:
128: options()
129:
130:
131: {
132:
133:
134: int ch; /* return value from getopt() */
135: char *names = "DIFHR:o:x:y:r:h:w:s:";
136:
137: extern char *optarg; /* used by getopt() */
138: extern int optind;
139:
140: float atof();
141:
142:
143: /*
144: *
145: * Reads and processes the command line options. Right now the recognized
146: * options are,
147: *
148: */
149:
150:
151: while ( (ch = getopt(argc, argv, names)) != EOF ) {
152:
153: switch ( ch ) {
154:
155: case 'r': /* target printer resolution */
156: res = atoi(optarg);
157: break;
158:
159: case 'f': /* use this font (omit size) */
160: font = optarg;
161: break;
162:
163: case 's': /* use this point size */
164: list_size = atoi(optarg);
165: break;
166:
167: case 'h': /* set the paper height - inches */
168: height = atof(optarg);
169: break;
170:
171: case 'w': /* same but for the width */
172: width = atof(optarg);
173: break;
174:
175: case 'x': /* set the xoffset - inches */
176: xoffset = atof(optarg);
177: break;
178:
179: case 'y': /* same but for yoffset */
180: yoffset = atof(optarg);
181: break;
182:
183: case 'o': /* processing range list */
184: out_list(optarg);
185: break;
186:
187: case 'H': /* want the document header */
188: want_header = TRUE;
189: break;
190:
191: case 'F': /* new troff font directory */
192: fontdir = optarg;
193: break;
194:
195: case 'R': /* set raster table directory */
196: rastdir = optarg;
197: break;
198:
199: case 'D': /* debug flag */
200: debug = ON;
201: break;
202:
203: case 'I': /* ignore FATAL errors */
204: ignore = ON;
205: break;
206:
207: case '?': /* don't understand the option */
208: error(FATAL, "");
209: break;
210:
211: default: /* don't know what to do for ch */
212: error(FATAL, "missing case for option %c\n", ch);
213: break;
214:
215: } /* End switch */
216:
217: } /* End while */
218:
219: argc -= optind; /* get ready for non-option args */
220: argv += optind;
221:
222: } /* End of options */
223:
224:
225: /*****************************************************************************/
226:
227:
228: doc_header()
229:
230:
231: {
232:
233:
234: /*
235: *
236: * If want_header is TRUE we'll make sure a document header is the first
237: * thing written to the output file.
238: *
239: */
240:
241:
242: if ( want_header == TRUE )
243: fprintf(fp_out, "@document(language impress)");
244:
245: } /* End of doc_header */
246:
247:
248: /*****************************************************************************/
249:
250:
251: initialize()
252:
253:
254: {
255:
256:
257: /*
258: *
259: * Does the run time initialization of variables that depend on the target
260: * printer resolution. Also handles printer initialization of things like
261: * the space width and creating the listing font family table.
262: *
263: */
264:
265:
266: p_xoffset = xoffset * res;
267: p_yoffset = yoffset * res;
268:
269: p_height = height * res;
270: p_width = width * res;
271:
272: spacewid = 2.2 * list_size; /* a reasonable value for spaces */
273:
274: putc(ASETSP, fp_out);
275: putint(spacewid, fp_out);
276:
277: putc(ACFT, fp_out); /* use resident font */
278: putc(MAXFAMILY, fp_out);
279: putc(1, fp_out);
280: putc(0, fp_out);
281: fprintf(fp_out, "%s%d", font, list_size);
282: putc('\0', fp_out);
283:
284: } /* End of initialize */
285:
286:
287: /*****************************************************************************/
288:
289:
290: arguments()
291:
292:
293: {
294:
295:
296: char name[100]; /* make sure we can acces file */
297: char *font; /* name of the font we're dumping */
298: char *size; /* in this point size */
299:
300: char *strtok();
301:
302:
303: /*
304: *
305: * All the remaining arguments are the names of raster files in *rastdir
306: * that we want to display. Because two raster file naming conventions
307: * are used in rast.c we can't be absolutely sure we're really displaying
308: * the raster file that the user wanted. That's why the pathname is built
309: * up in name[] and access to the file is checked. That's probably good
310: * enough for our purposes, but it still doesn't guarantee you get what
311: * you asked for. It shouldn't cause any real problems as long as you
312: * don't try and keep raster files with the two different naming conventions
313: * in the same directory.
314: *
315: */
316:
317:
318: if ( argc < 1 )
319: error(FATAL, "can't read standard input");
320: else { /* have at least one argument */
321: while ( argc > 0 ) {
322: sprintf(name, "%s/%s", rastdir, *argv);
323: if ( access(name, 04) == -1 )
324: error(FATAL, "can't read file %s", name);
325:
326: if ( (font = strtok(*argv, ".")) == NULL )
327: error(FATAL, "bad raster file name %s", *argv);
328:
329: if ( *(size = font + strlen(font) + 1) == 'r' ) size++;
330:
331: printrast(font, atoi(size));
332: argc--;
333: argv++;
334: } /* End while */
335: } /* End else */
336:
337: } /* End of arguments */
338:
339:
340: /*****************************************************************************/
341:
342:
343: printrast(name, size)
344:
345:
346: char *name; /* name of the font */
347: int size; /* in this point size */
348:
349:
350: {
351:
352:
353: int start, stop; /* glyph number end points */
354: int i; /* loop index */
355: int cwid; /* character width */
356: int xref, yref; /* reference point for current glyph */
357: char buff[200]; /* text string buffer */
358:
359:
360: /*
361: *
362: * Prints glyphs from the raster file associated with font *name in point
363: * size 'size'. If no -o option was given all the glyphs will be printed.
364: * The listing for each new font begins on a new page.
365: *
366: */
367:
368:
369: getrastdata(name, size); /* read the font's raster file */
370:
371: start = getvalue(P_FIRSTGLY); /* first glyph number in the font */
372: stop = getvalue(P_LASTGLY); /* number of the last glyph */
373:
374: linesp = ((MAX(size, list_size) + .2 * MAX(size, list_size)) / 72.27) * RAST_RES + 1.0;
375:
376: newpage(); /* dump starts on a new page */
377:
378: sprintf(buff, "FONT DUMP FOR %s: SIZE %d\n\n\n", name, size);
379: printstring(buff);
380:
381: for ( i = start; i <= stop; i++ )
382: if ( in_olist(i) == ON ) {
383: printchar(i, name, size, -1, fp_out);
384: cwid = PIXEL_WIDTH(getvalue(G_CHWIDTH, i), rast_res);
385: xref = getvalue(G_XREF, i);
386: yref = getvalue(G_YREF, i);
387: hpos = 6 * spacewid + p_xoffset;
388: xymove();
389: sprintf(buff, "width = %d code = %d xref = %d yref = %d\n", cwid, i, xref, yref);
390: printstring(buff);
391: } /* End if */
392:
393: } /* End of printrast */
394:
395:
396: /*****************************************************************************/
397:
398:
399: printchar(c, font, size, advance, fp)
400:
401:
402: int c; /* print glyph for this character */
403: char *font; /* in this font */
404: int size; /* and this point size */
405: int advance; /* using this as the advance width */
406: FILE *fp; /* Impress commands go here */
407:
408:
409: {
410:
411:
412: /*
413: *
414: * Does everything needed to get character c printed using the raster file
415: * for *font in point size 'size' and using advance as the character advance.
416: *
417: */
418:
419:
420: if ( fam == NULL || fam->size != size || strcmp(font, fam->name) != 0 || fam->rst == NULL )
421: getrastdata(font, size);
422:
423: putc(download(c, advance, ROT_0, fp), fp);
424:
425: } /* End of printchar */
426:
427:
428: /*****************************************************************************/
429:
430:
431: newline()
432:
433:
434: {
435:
436:
437: /*
438: *
439: * Makes sure everything is properly set up to start a new line. If the
440: * vertical position on the page has gone past p_height (ie. the height
441: * of the paper in pixels) we'll start a new page.
442: *
443: */
444:
445:
446: hpos = p_xoffset; /* left margin */
447: if ( (vpos += linesp) >= p_height )
448: newpage();
449: else xymove();
450:
451: } /* End of newline */
452:
453:
454: /*****************************************************************************/
455:
456:
457: newpage()
458:
459:
460: {
461:
462:
463: /*
464: *
465: * Ends the previous page and makes sure we're positioned at the upper left
466: * corner of a new page. The way things are done results in a blank page at
467: * the beginning of every job - no big deal because the program isn't used
468: * much.
469: *
470: */
471:
472:
473: putc(AENDP, fp_out);
474:
475: hpos = p_xoffset;
476: vpos = p_yoffset;
477:
478: xymove();
479:
480: } /* End of newpage */
481:
482:
483: /*****************************************************************************/
484:
485:
486: xymove()
487:
488:
489: {
490:
491:
492: /*
493: *
494: * Makes sure the current position for Impress is set to (hpos, vpos).
495: *
496: */
497:
498:
499: putc(ASETAH, fp_out);
500: putint(hpos, fp_out);
501:
502: putc(ASETAV, fp_out);
503: putint(vpos, fp_out);
504:
505:
506: } /* End of xymove */
507:
508:
509: /*****************************************************************************/
510:
511:
512: printstring(str)
513:
514:
515: char *str; /* want to print this string */
516:
517:
518: {
519:
520:
521: /*
522: *
523: * Arranges to have string *str printed using the resident font that's been
524: * assigned the family number MAXFAMILY. Spaces and newlines are handled
525: * separately, although that probably isn't necessary for resident fonts.
526: *
527: * Some of the glyphs in the raster files we got from Imagen are bad. It
528: * didn't seem to matter much for version 1.9, but a glyph having 0 for its
529: * raster height hung version 2.0 and nothing was printed. Anyway I put a
530: * check in routine download() to make sure glyphs having no height weren't
531: * downloaded. At least that made sure the printer didn't crash. All we
532: * get for those glyphs is a harmless undefined glyph message and a
533: * special character got printed to mark where the problem occurred.
534: *
535: */
536:
537:
538: if ( last_fam != MAXFAMILY ) { /* using this family for listing */
539: putc(ASF, fp_out); /* need to tell printer about it */
540: putc(MAXFAMILY, fp_out);
541: last_fam = MAXFAMILY;
542: } /* End if */
543:
544: while ( *str != '\0' ) { /* print the whole string */
545: if ( *str == ' ' )
546: putc(ASP, fp_out);
547: else if ( *str == '\n' )
548: newline();
549: else putc(*str, fp_out);
550: str++;
551: } /* End while */
552:
553: } /* End of printstring */
554:
555:
556: /*****************************************************************************/
557:
558:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.