|
|
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.