home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume20
/
hp2pk
/
part03
/
hp2pk.c
next >
Wrap
C/C++ Source or Header
|
1991-06-02
|
26KB
|
918 lines
/* HP2PK.C - Convert HP soft font files to TeX PK and TFM (or PL) files
***************************************************************************
*
* Sources of information for HP Soft Fonts:
*
* LaserJet Printer Family Technical Reference Manual,
* Hewlett-Packard, January 1986.
*
* LaserJet series II Printer Technical Reference Manual,
* Hewlett-Packard, May 1987.
*
* LaserJet III Technical Reference Manual, Hewlett-Packard,
* March 1990.
*
* HP DeskJet Printer Family Software Developer's Guide,
* Hewlett-Packard, August 1990. (only to interpret values
* of some font header fields--font format is much different
* in general)
*
* Sources of information for TeX font files:
*
* The METAFONTbook by Donald E. Knuth (appendix F)
*
* PLtoTF.WEB by Donald E. Knuth, Leo Guibas, et al.
*
* GFtoPK.WEB by Tomas Rokicki
*
***************************************************************************
* EDIT HISTORY
* 4-Oct-90 SRMc - convert Pascal code left here by Jonathan Kew
* into C, start debugging and adding comments
* 5-Oct-90 SRMc - first successful translation of .SFP file to
* .PK and .PL files
* 6-Oct-90 SRMc - add more comments, convert to dynamic memory
* allocation
* 9-Oct-90 SRMc - add direct output of .TFM file in addition
* to .PL file
* 16-Oct-90 SRMc - fiddle with the user interface
* 19-Oct-90 SRMc - rewrite code for greater modularity and fewer
* global variables (allows for future reuse in
* other "Font A to Font B" conversion programs)
* 20-Oct-90 SRMc - move ctime() call from init_pl_file() to main()
* SRMc - add -b command line option
* 22-Oct-90 SRMc - fight MSDOS cross-compiler code generation bugs
* (or are they obscure features of the C language
* definition? -- some seem to be definite bugs)
* 14-Jan-91 SRMc - add TURBO C patches from Thomas B. Ridgeway
* (ridgeway@blackbox.hacc.washington.edu)
* 15-Jan-91 SRMc - fix for Macintosh Lightspeed THINK C
* 17-Jan-91 SRMc - move version information into PATCHLEVEL.H
* 28-Jan-91 SRMc - add -s option for specifying the width of space,
* as suggested by Chris Paris (cap@cs.cmu.edu)
* 30-Jan-91 SRMc - add -r option for restricting to 7-bit character
* codes in the output file (to support antique
* DVI drivers), as suggested by Kevin A. Streater
* (ba124@uk.ac.city.cs in JANET syntax)
* 31-Jan-91 SRMc - add -h option for getting help
***************************************************************************
* Copyright 1990, 1991 by the Summer Institute of Linguistics, Inc.
* All rights reserved.
*/
/*#define TURBO_C*/ /* uncomment if using MSDOS TURBO C */
#include <stdio.h>
#include <ctype.h>
#ifdef BSD
#include <sys/time.h>
typedef long time_t;
extern time_t time();
extern char *memset(), *memcpy();
extern int memcmp();
#include <strings.h>
#define strchr index
#define strrchr rindex
#else
#include <time.h>
#ifdef TURBO_C
#include <mem.h>
#define MSDOS
#else
#ifndef THINK_C /* THINK C includes memxxx() functions in <string.h> */
#include <memory.h>
#endif
#endif
#include <string.h>
#endif
#ifdef THINK_C
#include <console.h>
#define signed /* keyword not recognized by this compiler */
#define MACINTOSH
#endif
#include "patchlevel.h"
#include "sfp.h"
#include "tfm.h"
#include "pk.h"
#include "bitmap.h"
#ifdef MSDOS
#define DIRSEPCHAR '\\'
#endif
#ifdef UNIX
#define DIRSEPCHAR '/'
#endif
#ifdef MACINTOSH
#define DIRSEPCHAR ':'
#endif
#define NUL '\0'
/************************************************************************/
/* EXTERN DECLARATIONS */
/************************************************************************/
extern void exit();
extern long strtol();
extern int getopt(), optind;
extern char *optarg;
/* from READSFP.C */
extern void read_sfp_font_descriptor();
extern int read_sfp_character();
/* from WRITEPK.C */
extern void init_pk_file(), write_pk_character(), end_pk_file();
/* from WRITEPL.C */
extern void init_pl_file(), write_pl_entry(), end_pl_file();
/* from WRITETFM.C */
extern void write_tfm_data();
/* from MYALLOC.C */
extern char *myalloc(), *myrealloc();
extern void myfree();
/* from FIXNUM.C */
extern fixnum str_to_fixnum();
/************************************************************************/
/* GLOBAL VARIABLES */
/************************************************************************/
/*
* data from input HP Soft Font (.SFP) file
*/
struct hp_font_descriptor hp_font; /* font descriptor */
struct hp_character_descriptor hp_char; /* current character descriptor */
struct character_bitmap bitmap; /* current character bitmap */
char *symbol_set_string = NULL; /* hp_font.symbol_set in English */
/*
* data for the PK font file
*/
struct pk_preamble pk_header; /* font preamble */
struct pk_chardata pk_char; /* current character descriptor */
/*
* data for the TFM and PL files
*/
struct tfm_top top_fm; /* TFM file top information */
struct tfm_header header_fm; /* font descriptor */
struct tfm_param param_fm; /* font parameters */
struct tfm_chardata char_fm[256]; /* array of character metrics */
/*
* global variables set by the command line options
*/
fixnum designsize = 0L; /* -d = font design size */
fixnum spacewidth = 0L; /* -s = width of basic space in font */
long magnification = 0L; /* -m = font magnification */
int verbose = 0; /* -v = program talkativity flag */
int density = 0; /* -d = dots per inch of SFP font */
short restrict_7bit = 0; /* -r = restrict to 128 chars, lower/upper */
#ifdef MACINTOSH
char *fileCreator = NULL; /* -z = Macintosh file type */
#endif
char *sfp_filename = NULL; /* <infile> = input SFP font file's name */
char *pk_filename = NULL; /* -p = output PK font file's name */
char *pl_filename = NULL; /* -l = output PL font metric file's name */
char *tfm_filename = NULL; /* -t = output TFM font metric file's name */
/*
* conversion factor for SFP dimensions to TFM dimensions
* double precision floating point is occasionally useful...
*/
double dot_scale; /* ratio: SFP font dots -> (2**-20) points */
/****************************************************************************
* NAME
* myputs
* ARGUMENTS
* msg - message string
* DESCRIPTION
* Write a string to stdout, inserting linebreaks automatically as needed.
* Also, if the verbose flag is zero, don't print anything.
* RETURN VALUE
* none
*/
void myputs(msg)
char *msg;
{
static int screen_col=0; /* screen column (for linewrap of progress report) */
if (verbose == 0)
return;
if (strcmp(msg,"\n")==0)
{
fputs(msg,stdout);
screen_col = 0;
return;
}
if ((strlen(msg)+screen_col) >= 79)
{
putchar('\n');
screen_col = 0;
}
fputs(msg,stdout);
fflush(stdout);
screen_col += strlen(msg);
}
/****************************************************************************
* NAME
* change_filetype
* ARGUMENTS
* name - pointer to a filename
* type - pointer to replacement filetype (includes '.')
* DESCRIPTION
* Create a new filename based on the old name and new type.
* RETURN VALUE
* pointer to new filename (allocated with malloc())
*/
char *change_filetype(name, type)
char *name;
char *type;
{
char *p;
char *newname; /* pointer to dynamically allocated buffer for result */
newname = strcpy( myalloc((unsigned)(strlen(name)+strlen(type)+1)), name);
p = strchr(newname, DIRSEPCHAR);
if (p == (char *)NULL)
p = newname;
p = strrchr(p, '.');
if (p == (char *)NULL)
strcat(newname, type);
else
strcpy(p, type);
return(newname);
}
/****************************************************************************
* NAME
* fix_filename
* ARGUMENTS
* name - filename
* type - default filename type extension
* mode - mode string for fopen()
* DESCRIPTION
* Fix up a filename based on the name and possibly the type.
* Input files may or may not have have a type extension.
* Output files must have a filetype.
* RETURN VALUE
* FILE pointer to open file
*/
char *fix_filename(name, type, mode)
char *name;
char *type;
char *mode;
{
char *p;
FILE *fp;
if (*mode == 'r')
{
fp = fopen(name, mode);
if (fp == (FILE *)NULL)
{
/*
* see if the user was lazy and omitted the filetype
*/
p = strrchr(name, DIRSEPCHAR);
if (p == (char *)NULL)
p = name;
if (strchr(p, '.') == (char *)NULL)
name = change_filetype(name, type);
}
else
fclose(fp);
return( name );
}
/*
* see if the user was lazy and omitted the filetype
*/
p = strrchr(name, DIRSEPCHAR);
if (p == (char *)NULL)
p = name;
if (strchr(p, '.') == (char *)NULL)
name = change_filetype(name, type);
return( name );
}
/****************************************************************************
* NAME
* sfp_to_tfm_header
* ARGUMENTS
* hpf - pointer to SFP font descriptor structure
* sym_set - font symbol set string
* dsize - font design size (fixed-point, 20-bit fraction)
* tp - pointer to TeX font metric header structure
* DESCRIPTION
* Fill in the TeX font metric header information, using the SFP font
* information already known.
* RETURN VALUE
* none
*/
void sfp_to_tfm_header( hpf, sym_set, dsize, tp )
struct hp_font_descriptor *hpf;
char *sym_set;
fixnum dsize;
struct tfm_header *tp;
{
int i;
tp->tfm_checksum = 0L;
tp->tfm_design_size = dsize;
i = strlen(sym_set);
if (i > 39)
i = 39;
tp->tfm_coding[0] = i;
memcpy( &tp->tfm_coding[1], sym_set, i );
/*
* find the actual length of the stored font name
* if nonzero, store it; otherwise store a default name
*/
for ( i = 15 ;
(i >= 0) && isascii(hpf->font_name[i]) && isspace(hpf->font_name[i]) ;
--i )
;
if (i >= 0)
{
tp->tfm_fontid[0] = i+1;
memcpy( &tp->tfm_fontid[1], hpf->font_name, i+1 );
}
else
{
tp->tfm_fontid[0] = 12;
memcpy( &tp->tfm_fontid[1], "HP SOFT FONT", 12 );
}
tp->tfm_7bitsafe = 0;
tp->tfm_unused[0] = 0;
tp->tfm_unused[1] = 0;
tp->tfm_face = 0;
if (hp_font.width_type < 0)
tp->tfm_face += CONDENSED;
else if (hp_font.width_type > 0)
tp->tfm_face += EXTENDED;
if (hp_font.style == 1)
tp->tfm_face += ITALIC;
if (hp_font.stroke_weight < -1)
tp->tfm_face += LIGHT;
else if (hp_font.stroke_weight > 1)
tp->tfm_face += BOLD;
}
/****************************************************************************
* NAME
* sfp_to_pk
* ARGUMENTS
* cc - current character code
* hpf - pointer to SFP font descriptor structure
* hpc - pointer to SFP font character descriptor structure
* pkc - pointer to PK font character data structure
* DESCRIPTION
* Compute the TeX character information for this SFP character.
* RETURN VALUE
* none
*/
void sfp_to_pk(cc, hpf, hpc, pkc)
int cc;
struct hp_font_descriptor *hpf;
struct hp_character_descriptor *hpc;
struct pk_chardata *pkc;
{
long qdot_width;
double d_wd;
pkc->char_code = cc;
/*
* some compilers need to have these computations split out this way
*/
if (hpf->spacing == 1)
qdot_width = hpc->delta_x;
else
qdot_width = hpf->pitch;
d_wd = ((dot_scale * qdot_width) / 4.0) * TWO_20th;
pkc->tfm_width = d_wd;
pkc->dx = hpc->delta_x;
pkc->dx <<= 16; /* need separate for 16-bit int systems */
pkc->dy = 0L;
pkc->pixel_width = hpc->character_width;
pkc->pixel_height = hpc->character_height;
pkc->hoff = -hpc->left_offset;
pkc->voff = hpc->top_offset;
}
/****************************************************************************
* NAME
* sfp_to_tfm
* ARGUMENTS
* hpf - pointer to SFP font descriptor structure
* hpc - pointer to SFP font character descriptor structure
* pkc - pointer to PK character data structure
* tfc - pointer to TFM character data structure
* tft - pointer to TFM file top information structure
* DESCRIPTION
* Compute the TeX font metric information for this SFP character.
* RETURN VALUE
* none
*/
void sfp_to_tfm(hpf, hpc, pkc, tfc, tft)
struct hp_font_descriptor *hpf;
struct hp_character_descriptor *hpc;
struct pk_chardata *pkc;
struct tfm_chardata *tfc;
struct tfm_top *tft;
{
long qdot_width; /* width of character in quarter-dots */
long x;
double d_wd, d_ht, d_dp, d_ic;
if (hpf->spacing == 1)
qdot_width = hpc->delta_x;
else
qdot_width = hpf->pitch;
/*
* some compilers need to have these computations split out this way
*/
d_wd = ((dot_scale * qdot_width) / 4.0) * TWO_20th;
d_ht = dot_scale * hpc->top_offset * TWO_20th;
/*
* be extremely careful on conversions involving signed and unsigned short
* (this may look paranoid, but some compilers botch the conversions)
*/
x = hpc->character_height;
x -= hpc->top_offset;
if (x > 0L)
d_dp = dot_scale * x * TWO_20th;
else
d_dp = 0.0;
x = hpc->character_width;
x *= 4;
x -= qdot_width;
if (x > 0L)
d_ic = dot_scale * (x / 4.0) * TWO_20th;
else
d_ic = 0.0;
tfc->charwd = d_wd;
tfc->charht = d_ht;
tfc->chardp = d_dp;
tfc->charic = d_ic;
if ((tfc->charic != 0L) && (hpf->style != 1))
{
myputs(
"Warning: character in upright font has nonzero italic correction.");
myputs("\n");
}
/*
* save the smallest and largest character codes encountered
*/
if (pkc->char_code < tft->tfm_bc)
tft->tfm_bc = pkc->char_code;
if (pkc->char_code > tft->tfm_ec)
tft->tfm_ec = pkc->char_code;
}
/****************************************************************************
* NAME
* sfp_to_tfm_param
* ARGUMENTS
* tfp - pointer to TFM font parameter structure
* hpf - pointer to SFP font descriptor structure
* tfc - pointer to array of TFM character data structures
* tft - pointer to TFM file top information structure
* DESCRIPTION
* Compute the TFM font spacing parameter values.
* RETURN VALUE
* none
*/
void sfp_to_tfm_param(tfp, hpf, tfc, tft)
struct tfm_param *tfp;
struct hp_font_descriptor *hpf;
struct tfm_chardata *tfc;
struct tfm_top *tft;
{
double d;
/*
* first, compute the space parameters
*/
if (hpf->spacing == 1)
{
if ((tft->tfm_bc <= ' ')&&(tft->tfm_ec >= ' ')&&(tfc[' '].charwd != 0L))
{
/*
* use space character's width for font spacing parameters
*/
tfp->tfm_space = tfc[' '].charwd;
}
else if (spacewidth != 0L)
{
d = spacewidth;
d /= designsize;
tfp->tfm_space = d * TWO_20th;
}
else if ((tft->tfm_bc <= 'x')&&(tft->tfm_ec >= 'x')&&(tfc['x'].charwd!=0L))
{
/*
* if no space character, use 'x' character's width for spacing
*/
printf("\
Font contains no space; using width of x character for font space.\n");
tfp->tfm_space = tfc['x'].charwd;
}
else
{
/*
* Neither space nor x was available, so we arbitrarily use
* values based on the design size.
*/
printf("\
Font contains no space or x; using 1/2 design size for font space.\n");
tfp->tfm_space = 0x00080000; /* == 0.5 as fixnum */
}
tfp->tfm_space_stretch = tfp->tfm_space / 2;
tfp->tfm_space_shrink = tfp->tfm_space / 3;
tfp->tfm_extra_space = tfp->tfm_space / 3;
}
else
{
/*
* mono-space font
*/
d = ((dot_scale * hpf->pitch) / 4.0) * TWO_20th;
tfp->tfm_space = d;
tfp->tfm_space_stretch = 0L;
tfp->tfm_space_shrink = 0L;
tfp->tfm_extra_space = tfp->tfm_space;
}
/*
* we always set the quad value to twice the basic space value
*/
tfp->tfm_quad = tfp->tfm_space * 2; /* em-space */
/*
* set the x height (used for accent placement)
*/
if ((tft->tfm_bc <= 'x') && (tft->tfm_ec >= 'x') && (tfc['x'].charwd != 0L))
param_fm.tfm_x_height = tfc['x'].charht + tfc['x'].chardp;
else
{
printf("Font contains no x; using 1/2 design size for x-height.\n");
tfp->tfm_x_height = 0x00080000; /* == 0.5 as fixnum */
}
}
#ifdef MACINTOSH
/***************************************************************************
* NAME
* setMacFileType
* ARGUMENTS
* fname - filename string
* type - file type string (4 chars, allcaps)
* creator - file creator string (4 chars, allcaps)
* DESCRIPTION
* For the Macintosh, call the toolbox functions to set the file type and
* creator to the desired values.
* RETURN VALUE
* none
*/
void setMacFileType(fname, type, creator)
char *fname;
char *type;
char *creator;
{
char filename[256];
long err;
long refnum;
struct FInfo {
char fdType[4];
char fdCreator[4];
long fdFlags;
struct { long x; long y; } fdLocation;
long fdFldr;
} finderInfo;
int i;
strcpy(filename+1,fname);
filename[0] = strlen(fname);
refnum = 0;
err = GetFInfo( filename, refnum, &finderInfo );
for ( i = 0 ; i < 4 ; ++i )
{
finderInfo.fdType[i] = ' ';
finderInfo.fdCreator[i] = ' ';
}
for ( i = 0 ; i < 4 ; ++i )
{
if (type[i] == NUL)
break;
finderInfo.fdType[i] = type[i];
}
for ( i = 0 ; i < 4 ; ++i )
{
if (creator[i] == NUL)
break;
finderInfo.fdCreator[i] = creator[i];
}
#ifdef THINK_C
err = SetFInfo( filename, refnum, &finderInfo );
#endif
}
#endif
/****************************************************************************
* NAME
* main
* ARGUMENTS
* argc - number of command line arguments
* argv - pointer to array of command line arguments
* DESCRIPTION
* main procedure for the HP2PK program
* RETURN VALUE
* 0 to indicate success
*/
int main(argc,argv)
int argc;
char **argv;
{
int c;
FILE *sfp_fp = NULL; /* SFP input FILE pointer */
FILE *pk_fp = NULL; /* PK output FILE pointer */
FILE *pl_fp = NULL; /* PL output FILE pointer */
FILE *tfm_fp = NULL; /* TFM output FILE pointer */
double d; /* used in computing design size */
int errflag; /* flag errors in command line parsing */
char buffer[80]; /* scratch buffer for sprintf() output */
time_t job_time; /* time that this job was run, in seconds */
struct tm *tp; /* decoded time that this job was run */
char *date; /* time string for when this job was run */
struct tfm_chardata *cfmp; /* hack for MSDOS compiler bug */
fprintf(stderr, "This is HP2PK, Version %d.%d.%d (%s)\n%s\n",
VERSION, REVISION, PATCHLEVEL, PATCHDATE, COPYRIGHT );
#ifdef THINK_C /* this MUST follow the fprintf() for some reason */
SetWTitle( FrontWindow(), "\pHP2PK" );
argc = ccommand( &argv );
#endif
time( &job_time );
tp = localtime( &job_time );
/*
* parse the command line
*/
errflag = 0;
while ((c = getopt(argc,argv,"b:d:hl:m:p:r:s:t:vz:")) != EOF)
{
switch (c)
{
case 'b': /* pixel density (bits per inch) */
density = (int)strtol(optarg, (char **)NULL, 10);
break;
case 'd': /* design size (in points) */
designsize = str_to_fixnum(optarg);
break;
case 's': /* width of space char (in points) */
spacewidth = str_to_fixnum(optarg);
break;
case 'm': /* magnification * 1000 */
magnification = strtol(optarg, (char **)NULL, 10);
break;
case 'r': /* restrict to lower/upper 128 chars */
if ((*optarg == 'l') || (*optarg == 'u'))
restrict_7bit = *optarg;
else
{
fprintf(stderr,
"The -r option requires either l or u as an argument.\n");
++errflag;
}
break;
case 'p':
pk_filename = optarg;
break;
case 'l':
pl_filename = optarg;
break;
case 't':
tfm_filename = optarg;
break;
case 'v':
verbose = 1;
break;
case 'z':
#ifdef MACINTOSH
fileCreator = optarg;
break;
#else
fprintf(stderr,"The -z option is valid only for the Macintosh.\n");
/* fall through */
#endif
case 'h': /* fall through */
default:
++errflag;
break;
}
}
if (errflag || (optind >= argc))
{
fputs("\
Usage: hp2pk [options] file.sfp\n\
-b density specify pixel density (dots/inch) of the font\n\
-d size specify the design size (in points) of the font\n\
-h ask for help (this display)\n\
-l file.pl specify the output Property List (PL) file\n\
-m mag specify the magnification (* 1000) of the font\n\
", stderr); fputs("\
-p file.pk specify the output PacKed font (PK) file\n\
-r {l|u} ask for only lower 128 or only upper 128 characters\n\
-s sp_width specify the width of a space character (in points)\n\
-t file.tfm specify the output TeX Font Metric (TFM) file\n\
-v request verbose progress report output\n\
", stderr);
#ifdef MACINTOSH
fputs("\
-z CREA set the hidden Macintosh Creator type for output files.\n\
This is usually four letters.\n\
", stderr);
#endif
fputs("\
file.sfp is the input HP Soft Font/Portrait (SFP) file.\n\
\n\
If not specified, hp2pk creates a PK file with the same base name as the\n\
input file, but with a .pk filename extension.\n\
If neither a PL nor a TFM file is specified, hp2pk creates a TFM file with\n\
the same base name as the input file, but with a .tfm filename extension.\n\
", stderr);
fputs("\
The default design size is calculated from the font data.\n\
The default magnification is 1000. The default pixel density is 300 dpi.\n\
If the font contains a space character, its width is always used. Otherwise,\n\
the default width of a space is the width of the 'x' character.\n\
", stderr);
exit(1);
}
/*
* Open the .SFP file
*/
sfp_filename = fix_filename( argv[optind], ".sfp", "rb");
sfp_fp = fopen(sfp_filename, "rb");
if (sfp_fp == (FILE *)NULL)
{
fprintf(stderr, "Cannot open HP soft font file %s\n", sfp_filename);
exit(1);
}
read_sfp_font_descriptor(sfp_fp, &hp_font, &symbol_set_string, verbose );
if (symbol_set_string == (char *)NULL)
symbol_set_string = "UNSPECIFIED";
if (magnification == 0L)
magnification = 1000L;
if (density == 0)
density = 300; /* assume 300 dots per inch */
if (designsize == 0L)
{
/*
* Estimate TeX design size based on font height
* Note: 18.0675 = (72.27 points/inch) / 4 quarter-dots/dot
* and hp_font.height is measured in quarter-dots
*/
d = ((18.0675 / density) * hp_font.height) * (1000.0 / magnification) *
TWO_20th;
designsize = d;
printf("Estimated font design size is %.2f pt.\n", d/TWO_20th );
}
/*
* dot_scale is used to translate dots (pixels) to (2**-20) points
*/
dot_scale = (72.27 / density) * (1000.0 / magnification) *
(TWO_20th / designsize);
sfp_to_tfm_header( &hp_font, symbol_set_string, designsize, &header_fm );
top_fm.tfm_bc = 256; /* larger than any possible value */
top_fm.tfm_ec = -1; /* smaller than any possible value */
/*
* Open the new .PK file
*/
if (pk_filename == (char *)NULL)
pk_filename = change_filetype(sfp_filename, ".pk");
pk_filename = fix_filename( pk_filename, ".pk", "wb");
pk_fp = fopen(pk_filename, "wb");
if (pk_fp == (FILE *)NULL)
{
fprintf(stderr, "Cannot open output PK font file %s\n", pk_filename );
exit(1);
}
/*
* if wanted, open the new .PL file
*/
if (pl_filename != (char *)NULL)
{
pl_filename = fix_filename(pl_filename, ".pl", "w");
pl_fp = fopen(pl_filename, "w");
if (pl_fp == (FILE *)NULL)
{
fprintf(stderr, "Cannot open output PL font metric file %s\n",
pl_filename );
exit(1);
}
}
else
pl_fp = (FILE *)NULL; /* signals that we don't output PL */
/*
* if wanted, open the new .TFM file
*/
if ((tfm_filename == (char *)NULL) && (pl_filename == (char *)NULL))
tfm_filename = change_filetype(sfp_filename, ".tfm");
if (tfm_filename != (char *)NULL)
{
tfm_filename = fix_filename(tfm_filename, ".tfm", "wb");
tfm_fp = fopen(tfm_filename, "wb");
if (tfm_fp == (FILE *)NULL)
{
fprintf(stderr, "Cannot open output TFM font metric file %s\n",
tfm_filename );
exit(1);
}
}
sprintf(buffer, "HP2PK %d.%d.%d (%s) output %4d.%02d.%02d %2d:%02d:%02d",
VERSION, REVISION, PATCHLEVEL, PATCHDATE,
tp->tm_year + 1900, tp->tm_mon + 1, tp->tm_mday,
tp->tm_hour, tp->tm_min, tp->tm_sec );
init_pk_file(pk_fp, buffer, designsize, density, &pk_header);
if (pl_fp != (FILE *)NULL)
{
date = ctime(&job_time);
date[24] = '\0';
init_pl_file(pl_fp, "HP2PK", date, &header_fm );
}
/*
* Process the sfp file to produce the pk file and the pl file
*/
for (;;)
{
/*
* process the data for one character
*/
c = read_sfp_character(sfp_fp, &hp_font, &hp_char, &bitmap );
if (c == -1)
{
if (!feof(sfp_fp))
puts("\nIgnoring junk at the end of the Soft Font/Portrait file.");
break;
}
if ( ((restrict_7bit == 'l') && (c >= 128)) ||
((restrict_7bit == 'u') && (c < 128)) )
continue;
sprintf(buffer, " [%d]", c);
myputs(buffer); /* print the character code on the screen */
if ((restrict_7bit == 'u') && (c >= 128))
c -= 128; /* fix character code for 7-bit output file */
sfp_to_pk(c, &hp_font, &hp_char, &pk_char);
write_pk_character(pk_fp, &pk_char, &bitmap);
cfmp = &char_fm[c]; /* need this to get around MSDOS compiler bug */
sfp_to_tfm(&hp_font, &hp_char, &pk_char, cfmp, &top_fm);
if (pl_fp != (FILE *)NULL)
write_pl_entry(pl_fp, c, cfmp);
}
end_pk_file(pk_fp);
if (verbose)
{
putchar('\n');
printf( "%6ld bytes read from HP soft font file.\n", ftell(sfp_fp) );
printf( "%6ld bytes written to packed font file.\n", ftell(pk_fp) );
}
fclose(sfp_fp);
fclose(pk_fp);
#ifdef MACINTOSH /* set Macintosh file type for PK file */
if (fileCreator != (char *)NULL)
setMacFileType(pk_filename, "BINA", fileCreator );
#endif
sfp_to_tfm_param(¶m_fm, &hp_font, char_fm, &top_fm );
if (pl_fp != (FILE *)NULL)
{
end_pl_file(pl_fp, ¶m_fm);
fclose(pl_fp);
#ifdef MACINTOSH /* set Macintosh file type for PL file */
if (fileCreator != (char *)NULL)
setMacFileType(pl_filename, "TEXT", fileCreator );
#endif
}
/*
* if wanted, write the .TFM file
*/
if (tfm_fp != (FILE *)NULL)
{
write_tfm_data(tfm_fp,&top_fm,&header_fm, char_fm,¶m_fm, designsize);
fclose(tfm_fp);
#ifdef MACINTOSH /* set Macintosh file type for TFM file */
if (fileCreator != (char *)NULL)
setMacFileType(tfm_filename, "BINA", fileCreator );
#endif
}
return(0); /* successful execution */
}