Annotation of researchv10no/cmd/dimpress/printrast.c, revision 1.1.1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.