home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
netpbma.zip
/
pbm
/
pbmtopk.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-31
|
25KB
|
904 lines
/*
pbmtopk, adapted from "pxtopk.c by tomas rokicki" by AJCD 1/8/90
compile with: cc -o pbmtopk pbmtopk.c -lm -lpbm
*/
#include <stdio.h>
#include <math.h>
#include <ctype.h>
#include "pbm.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 round(a) ((int)(a+.5))
#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 ;
integer resolution, designsize ;
char *filename[MAXPKCHAR] ;
integer xoffset[MAXPKCHAR] ;
integer yoffset[MAXPKCHAR] ;
integer horzesc[MAXPKCHAR] ;
integer vertesc[MAXPKCHAR] ;
byte tfmindex[MAXPKCHAR] ;
byte hgtindex[MAXPKCHAR] ;
byte depindex[MAXPKCHAR] ;
byte italindex[MAXPKCHAR] ;
byte charflags[MAXPKCHAR] ;
bit **bitmap ;
integer smallestch = MAXPKCHAR ;
integer largestch = -1;
integer emwidth = 0;
integer checksum ;
char *codingscheme = "GRAPHIC" ;
char *familyname = "PBM" ;
integer widthtab[MAXWIDTHTAB] = {0}; /* TFM widths */
integer numwidth = 1; /* number of entries in width table */
integer heighttab[MAXHEIGHTTAB] = {0};
integer numheight = 1;
integer depthtab[MAXDEPTHTAB] = {0};
integer numdepth = 1;
integer italictab[MAXITALICTAB] = {0};
integer numitalic = 1;
integer parameters[MAXPARAMS] = {0};
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 ;
/* checksum not computed at the moment
static integer 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(table, count, value, max_count, name)
integer *table, *count, value, max_count;
char *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(name, suffix)
char *name, *suffix ;
{
char *slash = rindex(name, '/');
char *dot = rindex(name, '.');
if ((dot && slash ? dot < slash : !dot) && strcmp(name, "-"))
strcat(name, suffix);
}
/* initialize the PK parameters */
static void initialize_pk()
{
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(b)
integer b ;
{
if (b < 0) b += 256 ;
putc(b, pkfile) ;
pbmtopk_pkloc++ ;
}
/* write two bytes to the PK file */
static void pkhalfword(a)
integer a ;
{
if (a < 0) a += 65536 ;
pbmtopk_pkbyte(a >> 8) ;
pbmtopk_pkbyte(a & 255) ;
}
/* write three bytes to the PK file */
static void pkthreebytes(a)
integer 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(a)
integer 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(a)
integer a ;
{
if (bitweight == 16) {
outputbyte = (a<<4) ;
bitweight = 1 ;
} else {
pbmtopk_pkbyte(outputbyte + a) ;
bitweight = 16 ;
}
}
/* write preamble to PK file */
static void writepreamble()
{
integer i ;
char *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()
{
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(b)
integer b ;
{
if (b < 0) b += 256 ;
putc(b, tfmfile) ;
}
/* write a half word to the TFM file */
static void tfmhalfword(a)
integer a ;
{
if (a < 0) a += 65536 ;
tfmbyte(a >> 8) ;
tfmbyte(a & 255) ;
}
/* write a word to the TFM file */
static void tfmword(a)
integer 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()
{
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()
{
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(row1, row2)
bit *row1, *row2 ;
{
integer i ;
for (i = 0; i < width; i++)
if (row1[i] != row2[i]) return (0) ;
return(1) ;
}
static void shipcharacter()
{
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] ;
repeatptr =
(integer *)malloc((unsigned int)((height+1)*sizeof(integer))) ;
bitcounts =
(integer *)malloc((unsigned int)((height*width)*sizeof(integer))) ;
if (repeatptr == NULL || bitcounts == NULL)
pm_error("out of memory while allocating bit counts");
zerorow = pbm_allocrow(width) ; /* initialise 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()
{
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(name)
char *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] =
(char *)malloc((unsigned int)(sizeof(char)*(strlen(str)+1))) ;
if (filename[car] == NULL)
pm_error("out of memory allocating filename %s", str);
strcpy(filename[car], 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(argc, argv)
int argc ;
char *argv[] ;
{
integer i, hesc, vesc, xoff, yoff, tfwid, tfdep, tfhgt, tfital ;
byte flags ;
char *usage = "pkfile[.pk] tfmfile[.tfm] dpi [-s designsize] [-p num param...]\n\
[-C codingscheme ] [-F family] [-c num | <char>]...\n\
<char> 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<numparam; i++)
if (++argv,--argc)
parameters[i] = fixword(atof(*argv)) ;
else
pm_error("not enough parameters (-p)");
break ;
default:
pm_usage(usage) ;
}
} else {
checkchar() ;
if (flags & TFMWIDTH)
tfmindex[car] = add_tfmwidth(tfwid);
if (flags & TFMDEPTH)
depindex[car] = add_tfmdepth(tfdep);
if (flags & TFMHEIGHT)
hgtindex[car] = add_tfmheight(tfhgt);
if (flags & TFMITALIC)
italindex[car] = add_tfmitalic(tfital);
horzesc[car] = hesc ;
vertesc[car] = vesc ;
xoffset[car] = xoff ;
yoffset[car] = yoff ;
filename[car] = *argv ;
charflags[car] = flags ;
car++ ;
flags = 0;
}
}
hppp = round((resolution<<16) / 72.27) ;
pkfile = pm_openw(pkname);
tfmfile = pm_openw(tfmname);
writepreamble() ;
for (car = 0 ; car < MAXPKCHAR ; car++)
if (filename[car]) {
readcharacter() ;
shipcharacter() ;
}
writepostamble() ;
writetfmfile() ;
pm_close(pkfile) ;
pm_close(tfmfile) ;
exit(0);
}