/* pbmtopk, adapted from "pxtopk.c by tomas rokicki" by AJCD 1/8/90 compile with: cc -o pbmtopk pbmtopk.c -lm -lpbm */ #define _BSD_SOURCE 1 /* Make sure strdup() is in string.h */ #define _XOPEN_SOURCE 500 /* Make sure strdup() is in string.h */ #include #include #include #include #include "pm_c_util.h" #include "pbm.h" #include "nstring.h" #include "mallocvar.h" #define MAXPKCHAR 256 #define MAXOPTLINE 200 #define MAXWIDTHTAB 256 #define MAXHEIGHTTAB 16 #define MAXDEPTHTAB 16 #define MAXITALICTAB 64 #define MAXPARAMS 30 #define NAMELENGTH 80 #define fixword(d) ((int)((double)(d)*1048576)) #define unfixword(f) ((double)(f) / 1048576) #define fixrange(f) ((f) < 16777216 && (f) > -16777216) #define designunits(p) ((p)*72.27/(double)resolution/unfixword(designsize)) /* character flags: in order of appearance in option files. */ #define XOFFSET 1 #define YOFFSET 2 #define HORZESC 4 #define VERTESC 8 #define TFMWIDTH 16 #define TFMHEIGHT 32 #define TFMDEPTH 64 #define TFMITALIC 128 typedef int integer ; typedef char quarterword ; typedef char boolean ; typedef quarterword ASCIIcode ; typedef quarterword eightbits ; typedef unsigned char byte ; static integer resolution, designsize ; static char *filename[MAXPKCHAR] ; static integer xoffset[MAXPKCHAR] ; static integer yoffset[MAXPKCHAR] ; static integer horzesc[MAXPKCHAR] ; static integer vertesc[MAXPKCHAR] ; static byte tfmindex[MAXPKCHAR] ; static byte hgtindex[MAXPKCHAR] ; static byte depindex[MAXPKCHAR] ; static byte italindex[MAXPKCHAR] ; static byte charflags[MAXPKCHAR] ; static bit **bitmap ; static integer smallestch = MAXPKCHAR ; static integer largestch = -1; static integer emwidth = 0; static integer checksum ; static const char *codingscheme = "GRAPHIC" ; static const char *familyname = "PBM" ; static integer widthtab[MAXWIDTHTAB] = {0}; /* TFM widths */ static integer numwidth = 1; /* number of entries in width table */ static integer heighttab[MAXHEIGHTTAB] = {0}; static integer numheight = 1; static integer depthtab[MAXDEPTHTAB] = {0}; static integer numdepth = 1; static integer italictab[MAXITALICTAB] = {0}; static integer numitalic = 1; static integer parameters[MAXPARAMS] = {0}; static integer numparam = 0; static ASCIIcode xord[128] ; static char xchr[256] = { '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '?' }; static FILE *tfmfile, *pkfile ; static char tfmname[NAMELENGTH+1], pkname[NAMELENGTH+1] ; static integer pbmtopk_pkloc = 0 ; static integer bitweight ; static integer outputbyte ; static integer car ; static integer hppp ; static integer width ; static integer height ; /* check sum algorithm (in Pascal): compute_checksum() begin c0:=bc; c1:=ec; c2:=bc; c3:=ec; for c:=bc to ec do if char_wd[c]>0 then begin temp_width:=memory[char_wd[c]]; if design_units<>unity then temp_width:=round((temp_width/design_units)*1048576.0); temp_width:=temp_width + (c+4)*@'20000000; {this should be positive} c0:=(c0+c0+temp_width) mod 255; c1:=(c1+c1+temp_width) mod 253; c2:=(c2+c2+temp_width) mod 251; c3:=(c3+c3+temp_width) mod 247; end; header_bytes[check_sum_loc]:=c0; header_bytes[check_sum_loc+1]:=c1; header_bytes[check_sum_loc+2]:=c2; header_bytes[check_sum_loc+3]:=c3; end */ #define add_tfmwidth(v) (add_tfmtable(widthtab, &numwidth, v, MAXWIDTHTAB,\ "TFM width")) #define add_tfmheight(v) (add_tfmtable(heighttab, &numheight, v, MAXHEIGHTTAB,\ "TFM height")) #define add_tfmdepth(v) (add_tfmtable(depthtab, &numdepth, v, MAXDEPTHTAB,\ "TFM depth")) #define add_tfmitalic(v) (add_tfmtable(italictab, &numitalic, v, MAXITALICTAB,\ "Italic correction")) static byte add_tfmtable(int * const table, int * const count, int const value, int const max_count, const char * const name) { integer i; for (i = 0; i < *count; i++) /* search for value in tfm table */ if (table[i] == value) return (byte)i; if (*count >= max_count) pm_error("too many values in %s table", name) ; if (!fixrange(value)) pm_error("%s %f for char %d out of range", name, unfixword(value), car); table[*count] = value ; return (*count)++ ; } /* add a suffix to a filename in an allocated space */ static void pbmtopk_add_suffix(char * const name, const char * const suffix) { char *slash = strrchr(name, '/'); char *dot = strrchr(name, '.'); if ((dot && slash ? dot < slash : !dot) && !STREQ(name, "-")) strcat(name, suffix); } /* initialize the PK parameters */ static void initialize_pk(void) { integer i ; pm_message("This is PBMtoPK, version 2.4") ; for (i = 127 ; i <= 255 ; i ++) xchr[i] = '?' ; for (i = 0 ; i <= 127 ; i ++) xord[i] = 32 ; for (i = 32 ; i < 127 ; i ++) xord[(int)xchr[i]] = i ; for (i = 0; i < MAXPKCHAR; i++) { filename[i] = NULL; charflags[i] = 0; } designsize = fixword(1.0) ; } /* write a single byte to the PK file */ static void pbmtopk_pkbyte(integer const b_in) { integer b; b = b_in; /* initial value */ if (b < 0) b += 256 ; putc(b, pkfile) ; pbmtopk_pkloc++ ; } /* write two bytes to the PK file */ static void pkhalfword(integer const a_in) { integer a; a = a_in; if (a < 0) a += 65536 ; pbmtopk_pkbyte(a >> 8) ; pbmtopk_pkbyte(a & 255) ; } /* write three bytes to the PK file */ static void pkthreebytes(integer const a) { pbmtopk_pkbyte((a>>16) & 255) ; pbmtopk_pkbyte((a>>8) & 255) ; pbmtopk_pkbyte(a & 255) ; } /* write four bytes to the PK file */ static void pkword(integer const a) { pbmtopk_pkbyte((a>>24) & 255) ; pbmtopk_pkbyte((a>>16) & 255) ; pbmtopk_pkbyte((a>>8) & 255) ; pbmtopk_pkbyte(a & 255) ; } /* write a nibble to the PK file */ static void pknyb(integer const a) { if (bitweight == 16) { outputbyte = (a<<4) ; bitweight = 1 ; } else { pbmtopk_pkbyte(outputbyte + a) ; bitweight = 16 ; } } /* write preamble to PK file */ static void writepreamble(void) { integer i ; const char * const comment = "PBMtoPK 2.4 output" ; pbmtopk_pkbyte(247) ; /* PRE command */ pbmtopk_pkbyte(89) ; /* PK file type */ pbmtopk_pkbyte(strlen(comment)) ; /* output comment */ for (i = 0 ; i < strlen(comment); i++) pbmtopk_pkbyte(xord[(int)comment[i]]) ; pkword(designsize) ; /* write designsize */ pkword(checksum) ; /* write checksum; calculate if possible */ pkword(hppp) ; /* write H pixels per point */ pkword(hppp) ; /* write V pixels per point */ } /* write postamble to PK file, padded to word length */ static void writepostamble(void) { pbmtopk_pkbyte(245) ; /* POST command */ while (pbmtopk_pkloc % 4) pbmtopk_pkbyte(246) ; /* pad with no-ops */ pm_message("%d bytes written to packed file.", pbmtopk_pkloc) ; } /* write a byte to the TFM file */ static void tfmbyte(integer const b_in) { integer b; b = b_in; if (b < 0) b += 256 ; putc(b, tfmfile) ; } /* write a half word to the TFM file */ static void tfmhalfword(integer const a_in) { integer a; a = a_in; if (a < 0) a += 65536 ; tfmbyte(a >> 8) ; tfmbyte(a & 255) ; } /* write a word to the TFM file */ static void tfmword(integer const a) { tfmbyte((a>>24) & 255) ; tfmbyte((a>>16) & 255) ; tfmbyte((a>>8) & 255) ; tfmbyte(a & 255) ; } /* write the whole TFM file for the font */ static void writetfmfile(void) { integer totallength ; integer headersize = 17; integer i ; if (largestch - smallestch < 0) { largestch = 0; smallestch = 1; } if (numparam < 7) /* set default parameters */ switch (numparam) { case 0: /* slant */ parameters[numparam++] = 0 ; case 1: /* space */ parameters[numparam++] = fixword(designunits(emwidth/3.0)); case 2: /* space_stretch */ parameters[numparam++] = fixword(unfixword(parameters[1])/2.0) ; case 3: /* space_shrink */ parameters[numparam++] = fixword(unfixword(parameters[1])/3.0) ; case 4: /* x_height */ parameters[numparam++] = fixword(0.45); case 5: /* quad */ parameters[numparam++] = fixword(designunits(emwidth)) ; case 6: /* extra_space */ parameters[numparam++] = fixword(unfixword(parameters[1])/3.0) ; } totallength = 6 + headersize + (largestch+1-smallestch) + numwidth + numheight + numdepth + numitalic + numparam ; /* lengths */ tfmhalfword(totallength) ; /* write file TFM length */ tfmhalfword(headersize) ; /* write TFM header length */ tfmhalfword(smallestch) ; /* write lowest char index */ tfmhalfword(largestch) ; /* write highest char index */ tfmhalfword(numwidth) ; /* write number of widths */ tfmhalfword(numheight) ; /* write number of heights */ tfmhalfword(numdepth) ; /* write number of depths */ tfmhalfword(numitalic) ; /* write number of italcorrs */ tfmhalfword(0) ; /* lig/kern table */ tfmhalfword(0) ; /* kern table */ tfmhalfword(0) ; /* extensible char table */ tfmhalfword(numparam) ; /* number of fontdimens */ /* header */ tfmword(checksum) ; /* write checksum */ tfmword(designsize) ; /* write designsize */ if (strlen(codingscheme) > 39) tfmbyte(39) ; /* write coding scheme len */ else tfmbyte(strlen(codingscheme)) ; for (i = 0; i < 39; i++) /* write coding scheme */ if (*codingscheme) tfmbyte(xord[(int)(*codingscheme++)]) ; else tfmbyte(0) ; if (strlen(familyname) > 19) tfmbyte(19) ; /* write family length */ else tfmbyte(strlen(familyname)) ; for (i = 0; i < 19; i++) /* write family */ if (*familyname) tfmbyte(xord[(int)(*familyname++)]) ; else tfmbyte(0) ; /* char_info */ for (car = smallestch; car <= largestch; car++) if (filename[car]) { /* write character info */ tfmbyte(tfmindex[car]) ; tfmbyte((hgtindex[car]<<4) + depindex[car]) ; tfmbyte(italindex[car]<<2) ; tfmbyte(0) ; } else tfmword(0) ; /* width table */ for (i = 0; i < numwidth; i++) tfmword(widthtab[i]) ; /* height table */ for (i = 0; i < numheight; i++) tfmword(heighttab[i]) ; /* depth table */ for (i = 0; i < numdepth; i++) tfmword(depthtab[i]) ; /* italic correction table */ for (i = 0; i < numitalic; i++) tfmword(italictab[i]) ; /* no lig_kern, kern, or exten tables */ /* fontdimen table */ for (i = 0; i < numparam; i++) if (i && !fixrange(parameters[i])) pm_error("parameter %d out of range (-p)", i); else tfmword(parameters[i]) ; pm_message("%d bytes written to tfm file.", totallength*4) ; } /* read a character from a PBM file */ static void readcharacter(void) { FILE *fp; fp = pm_openr(filename[car]); bitmap = pbm_readpbm(fp, &width, &height) ; pm_close(fp) ; if ((charflags[car] & HORZESC) == 0) horzesc[car] = width ; if ((charflags[car] & VERTESC) == 0) vertesc[car] = 0; if ((charflags[car] & XOFFSET) == 0) xoffset[car] = 0; if ((charflags[car] & YOFFSET) == 0) yoffset[car] = height-1; if ((charflags[car] & TFMWIDTH) == 0) tfmindex[car] = add_tfmwidth(fixword(designunits(width))); if ((charflags[car] & TFMHEIGHT) == 0) hgtindex[car] = add_tfmheight(fixword(designunits(yoffset[car]+1))); if ((charflags[car] & TFMDEPTH) == 0) depindex[car] = add_tfmdepth(fixword(designunits(height-1-yoffset[car]))); if ((charflags[car] & TFMITALIC) == 0) italindex[car] = 0; if (car < smallestch) smallestch = car; if (car > largestch) largestch = car; if (width > emwidth) emwidth = width ; } /* test if two rows of the PBM are the same */ static int equal(const bit * const row1, const bit * const row2) { integer i ; for (i = 0; i < width; i++) if (row1[i] != row2[i]) return (0) ; return(1) ; } static void shipcharacter(void) { integer compsize ; integer i, j, k ; bit *zerorow, *onesrow ; integer *repeatptr, *bitcounts ; integer count ; integer test ; integer curptr, rowptr ; integer bitval ; integer repeatflag ; integer colptr ; integer currepeat ; integer dynf ; integer deriv[14] ; integer bcompsize ; boolean firston ; integer flagbyte ; boolean state ; boolean on ; integer hbit ; integer pbit ; boolean ron, son ; integer rcount, scount ; integer ri, si ; integer max2 ; integer predpkloc ; integer buff ; integer tfwid = widthtab[tfmindex[car]] ; integer hesc = horzesc[car] ; integer vesc = vertesc[car] ; integer xoff = xoffset[car] ; integer yoff = yoffset[car] ; MALLOCARRAY(repeatptr, height + 1); MALLOCARRAY(bitcounts, height * width); if (repeatptr == NULL || bitcounts == NULL) pm_error("out of memory while allocating bit counts"); zerorow = pbm_allocrow(width) ; /* initialize plain rows */ onesrow = pbm_allocrow(width) ; for (i = 0 ; i < width ; i++) { zerorow[i] = PBM_WHITE ; onesrow[i] = PBM_BLACK ; } for (i=0; i < height; i = k) { /* set repeat pointers */ k = i + 1; if (!equal(bitmap[i], zerorow) && !equal(bitmap[i], onesrow)) { while (k < height && equal(bitmap[i], bitmap[k])) k++; repeatptr[i] = k - i - 1; } else { repeatptr[i] = 0; } } repeatptr[height] = 0 ; colptr = width - 1 ; repeatflag = currepeat = curptr = count = rowptr = 0 ; test = PBM_WHITE ; do { colptr++ ; if (colptr == width) { /* end of row, get next row */ colptr = 0 ; rowptr = currepeat ; if (repeatptr[currepeat] > 0) { repeatflag = repeatptr[currepeat] ; currepeat += repeatflag ; rowptr += repeatflag ; } currepeat++ ; } if (rowptr >= height) bitval = -1 ; else bitval = bitmap[rowptr][colptr] ; if (bitval == test) count++ ; /* count repeated pixels */ else { /* end of pixel run */ bitcounts[curptr++] = count ; if (curptr+3 >= height*width) pm_error("out of memory while saving character counts"); count = 1 ; test = bitval ; if (repeatflag > 0) { bitcounts[curptr++] = -repeatflag ; repeatflag = 0 ; } } } while (test != -1) ; bitcounts[curptr] = 0 ; bitcounts[curptr + 1] = 0 ; for (i = 1 ; i <= 13 ; i ++) deriv[i] = 0 ; i = firston = (bitcounts[0] == 0) ; compsize = 0 ; while (bitcounts[i] != 0) { /* calculate dyn_f */ j = bitcounts[i] ; if (j == -1) compsize++ ; else { if (j < 0) { compsize++ ; j = -j ; } if (j < 209) compsize += 2 ; else { k = j - 193 ; while (k >= 16) { k >>= 4 ; compsize += 2 ; } compsize++ ; } if (j < 14) (deriv[j])-- ; else if (j < 209) (deriv[(223 - j) / 15])++ ; else { k = 16 ; while (((k<<4) < j + 3)) k <<= 4 ; if (j - k <= 192) deriv[(207 - j + k) / 15] += 2 ; } } i++ ; } bcompsize = compsize ; dynf = 0 ; for (i = 1 ; i <= 13 ; i ++) { compsize += deriv[i] ; if (compsize <= bcompsize) { bcompsize = compsize ; dynf = i ; } } compsize = ((bcompsize + 1)>>1) ; if ((compsize > ((height*width+7)>>3)) || (height*width == 0)) { compsize = ((height*width+7)>>3) ; dynf = 14 ; } flagbyte = (dynf<<4) ; if (firston) flagbyte |= 8 ; if (tfwid > 16777215 || tfwid < 0 || hesc < 0 || vesc != 0 || compsize > 196579 || width > 65535 || height > 65535 || xoff > 32767 || yoff > 32767 || xoff < -32768 || yoff < -32768) { flagbyte |= 7 ; /* long form preamble */ pbmtopk_pkbyte(flagbyte) ; compsize += 28 ; pkword(compsize) ; /* char packet size */ pkword(car) ; /* character number */ predpkloc = pbmtopk_pkloc + compsize ; pkword(tfwid) ; /* TFM width */ pkword(hesc<<16) ; /* horiz escapement */ pkword(vesc<<16) ; /* vert escapement */ pkword(width) ; /* bounding box width */ pkword(height) ; /* bounding box height */ pkword(xoff) ; /* horiz offset */ pkword(yoff) ; /* vert offset */ } else if (hesc > 255 || width > 255 || height > 255 || xoff > 127 || yoff > 127 || xoff < -128 || yoff < -128 || compsize > 1016) { compsize += 13 ; /* extended short preamble */ flagbyte += (compsize>>16) + 4 ; pbmtopk_pkbyte(flagbyte) ; pkhalfword(compsize & 65535) ; /* char packet size */ pbmtopk_pkbyte(car) ; /* character number */ predpkloc = pbmtopk_pkloc + compsize ; pkthreebytes(tfwid) ; /* TFM width */ pkhalfword(hesc) ; /* horiz escapement */ pkhalfword(width) ; /* bounding box width */ pkhalfword(height) ; /* bounding box height */ pkhalfword(xoff) ; /* horiz offset */ pkhalfword(yoff) ; /* vert offset */ } else { compsize += 8 ; /* short form preamble */ flagbyte = flagbyte + (compsize>>8) ; pbmtopk_pkbyte(flagbyte) ; pbmtopk_pkbyte(compsize & 255) ; /* char packet size */ pbmtopk_pkbyte(car) ; /* character number */ predpkloc = pbmtopk_pkloc + compsize ; pkthreebytes(tfwid) ; /* TFM width */ pbmtopk_pkbyte(hesc) ; /* horiz escapement */ pbmtopk_pkbyte(width) ; /* bounding box width */ pbmtopk_pkbyte(height) ; /* bounding box height */ pbmtopk_pkbyte(xoff) ; /* horiz offset */ pbmtopk_pkbyte(yoff) ; /* vert offset */ } if (dynf != 14) { /* write packed character */ bitweight = 16 ; max2 = 208 - 15 * dynf ; i = firston ; while (bitcounts[i] != 0) { j = bitcounts[i] ; if (j == - 1) pknyb(15) ; else { if (j < 0) { pknyb(14) ; j = -j ; } if (j <= dynf) pknyb(j) ; else if (j <= max2) { j -= dynf + 1 ; pknyb((j >> 4) + dynf + 1) ; pknyb((j & 15)) ; } else { j -= max2 - 15 ; k = 16 ; while (k <= j) { k <<= 4 ; pknyb(0) ; } while (k > 1) { k >>= 4 ; pknyb(j / k) ; j = j % k ; } } } i++ ; } if (bitweight != 16) pbmtopk_pkbyte(outputbyte) ; } else { /* write bitmap character */ buff = 0 ; pbit = 8 ; i = firston ; hbit = width ; on = ! firston ; state = 0 ; count = repeatflag = 0 ; while ((bitcounts[i] != 0) || state || (count > 0)) { if (state) { count = rcount ; i = ri ; on = ron ; repeatflag-- ; } else { rcount = count ; ri = i ; ron = on ; } do { if (count == 0) { if (bitcounts[i] < 0) { if (! state) repeatflag = -bitcounts[i] ; i++ ; } count = bitcounts[i] ; i++ ; on = !on ; } if ((count >= pbit) && (pbit < hbit)) { if (on) buff += (1 << pbit) - 1 ; pbmtopk_pkbyte(buff) ; buff = 0 ; hbit -= pbit ; count -= pbit ; pbit = 8 ; } else if ((count < pbit) && (count < hbit)) { if (on) buff += (1 << pbit) - (1 << (pbit - count)) ; pbit -= count ; hbit -= count ; count = 0 ; } else { if (on) buff += (1 << pbit) - (1 << (pbit - hbit)) ; count -= hbit ; pbit -= hbit ; hbit = width ; if (pbit == 0) { pbmtopk_pkbyte(buff) ; buff = 0 ; pbit = 8 ; } } } while (hbit != width) ; if (state && (repeatflag == 0)) { count = scount ; i = si ; on = son ; state = 0 ; } else if (! state && (repeatflag > 0)) { scount = count ; si = i ; son = on ; state = 1 ; } } if (pbit != 8) pbmtopk_pkbyte(buff) ; } if (predpkloc != pbmtopk_pkloc) pm_error("bad predicted character length: character %d", car); pbm_freerow(zerorow); pbm_freerow(onesrow); free((char *)repeatptr); free((char *)bitcounts); } /* check that character is in valid range */ static void checkchar(void) { if (car < 0 || car >= MAXPKCHAR) pm_error("character must be in range 0 to %d", MAXPKCHAR-1) ; } /* read character information from an option file */ static void optionfile(const char * const name) { FILE *fp ; char buffer[MAXOPTLINE] ; fp = pm_openr(name); while (!feof(fp)) { char *here = buffer; if (fgets(buffer, MAXOPTLINE, fp) == NULL) break ; while (ISSPACE(*here)) here++ ; if (*here && *here == '=') { if (sscanf(here+1, "%d", &car) != 1) pm_error("bad option file line %s", buffer) ; } else if (*here && *here != '%' && *here != '#') { char str[NAMELENGTH] ; integer i, n; checkchar() ; if (sscanf(here, "%s%n", str, &n) != 1) pm_error("bad option file line %s", buffer) ; filename[car] = strdup(str); if (filename[car] == NULL) pm_error("out of memory allocating filename %s", str); for (i = 1; i < 256; i<<=1) { here += n; if (sscanf(here, "%s%n", str, &n) != 1) break ; if (strcmp(str, "*")) { charflags[car] |= i ; switch (i) { case XOFFSET: xoffset[car] = atoi(str) ; break ; case YOFFSET: yoffset[car] = atoi(str) ; break ; case HORZESC: horzesc[car] = atoi(str) ; break ; case VERTESC: vertesc[car] = atoi(str) ; break ; case TFMWIDTH: tfmindex[car] = add_tfmwidth(fixword(atof(str))) ; break ; case TFMHEIGHT: hgtindex[car] = add_tfmheight(fixword(atof(str))) ; break ; case TFMDEPTH: depindex[car] = add_tfmdepth(fixword(atof(str))) ; break ; case TFMITALIC: italindex[car] = add_tfmitalic(fixword(atof(str))) ; break ; } } } car++ ; } } pm_close(fp) ; } int main(int argc, char *argv[]) { integer i, hesc, vesc, xoff, yoff, tfwid, tfdep, tfhgt, tfital ; byte flags ; const char * const usage = "pkfile[.pk] tfmfile[.tfm] dpi " "[-s designsize] [-p num param...]\n" "[-C codingscheme ] [-F family] [-c num | ]...\n" " is:\n" "[-W tfmwidth] [-H tfmheight] [-D tfmdepth] [-I ital_corr] " "[-h horiz]\n" "[-v vert] [-x xoffset] [-y yoffset] file\n" "or:\n" "-f optfile\n" ; pbm_init(&argc, argv); initialize_pk() ; if (--argc < 1) pm_usage(usage) ; strcpy(pkname, *++argv) ; pbmtopk_add_suffix(pkname, ".pk") ; if (--argc < 1) pm_usage(usage) ; strcpy(tfmname, *++argv) ; pbmtopk_add_suffix(tfmname, ".tfm") ; if (--argc < 1) pm_usage(usage) ; resolution = atoi(*++argv) ; if (resolution < 1 || resolution > 32767) pm_error("unlikely resolution %d dpi", resolution); car = flags = hesc = vesc = xoff = yoff = tfwid = 0; while (++argv, --argc) { if (argv[0][0] == '-' && argv[0][1]) { char c, *p; c = argv[0][1] ; if (argv[0][2]) p = *argv + 2 ; /* set argument pointer */ else if (++argv, --argc) p = *argv ; else pm_usage(usage) ; switch (c) { case 'C': codingscheme = p; break ; case 'F': familyname = p; break ; case 'c': car = atoi(p) ; break ; case 's': designsize = fixword(atof(p)); if (designsize < 1048576) pm_error("design size %f out of range", unfixword(designsize)); case 'h': hesc = atoi(p) ; flags |= HORZESC ; break ; case 'v': vesc = atoi(p) ; flags |= VERTESC ; break ; case 'x': xoff = atoi(p) ; flags |= XOFFSET ; break ; case 'y': yoff = atoi(p) ; flags |= YOFFSET ; break ; case 'W': tfwid = fixword(atof(p)) ; flags |= TFMWIDTH ; break ; case 'H': tfhgt = fixword(atof(p)) ; flags |= TFMHEIGHT ; break ; case 'D': tfdep = fixword(atof(p)) ; flags |= TFMDEPTH ; break ; case 'I': tfital = fixword(atof(p)) ; flags |= TFMITALIC ; break ; case 'f': optionfile(p) ; break ; case 'p': numparam = atoi(p); if (numparam < 1 || numparam > MAXPARAMS) pm_error("parameter count %d out of range", numparam); for (i=0; i