[comp.sources.misc] v20i034: hp2pk - HP font conversion tool, Part04/04

steve@txsil.sil.org (Steve McConnel) (06/03/91)

Submitted-by: Steve McConnel <steve@txsil.sil.org>
Posting-number: Volume 20, Issue 34
Archive-name: hp2pk/part04

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 4 (of 4)."
# Contents:  readsfp.c
# Wrapped by steve@txsil on Thu May 30 10:36:56 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'readsfp.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'readsfp.c'\"
else
echo shar: Extracting \"'readsfp.c'\" \(34298 characters\)
sed "s/^X//" >'readsfp.c' <<'END_OF_FILE'
X/*  READSFP.C - Read data from HP soft font files
X ***************************************************************************
X *
X *	void read_sfp_font_descriptor(fp, hpf, symbol_set_string, verbose)
X *	FILE *fp;
X *	struct hp_font_descriptor *hpf;
X *	char **symbol_set_string;
X *	int verbose;
X *
X *	int read_sfp_character(fp, hpf, hpc, bmp)
X *	FILE *fp;
X *	struct hp_font_descriptor *hpf;
X *	struct hp_character_descriptor *hpc;
X *	struct character_bitmap *bmp;
X *
X ***************************************************************************
X *
X *	Sources of information for HP Soft Fonts:
X *
X *		LaserJet Printer Family Technical Reference Manual,
X *		Hewlett-Packard, January 1986.
X *
X *		LaserJet series II Printer Technical Reference Manual,
X *		Hewlett-Packard, May 1987.
X *
X *		LaserJet III Technical Reference Manual, Hewlett-Packard,
X *		March 1990.
X *
X *		HP DeskJet Printer Family Software Developer's Guide,
X *		Hewlett-Packard, August 1990.  (only to interpret values
X *		of some font header fields--font format is much different
X *		in general)
X *
X ***************************************************************************
X *	EDIT HISTORY
X *	19-Oct-90	SRMc - split out from HP2PK.C for modularity
X *	20-Oct-90	SRMc - add some more commentary
X *	22-Oct-90	SRMc - add explicit check for bitmap > 32767 bytes
X *	14-Jan-91	SRMc - add TURBO C patches from Thomas B. Ridgeway
X *				(ridgeway@blackbox.hacc.washington.edu)
X *			     - fix bug reported by Klaus U. Schallhorn
X *				<cnix!klaus@relay.EU.net> in reading headers
X *				from old font files with 26-byte font
X *				descriptors
X *	15-Jan-91	SRMc - fix for Macintosh Lightspeed THINK C
X *	30-Jan-91	SRMc - add support for "Class 2 Compressed Bitmap
X *				Character Data", as suggested by Kevin A.
X *				Streater (ba124@uk.ac.city.cs in JANET syntax)
X *			     - revise show_sfp_font_descriptor() according to
X *				information in LaserJet III Tech. Ref. Manual
X *	31-Jan-91	SRMc - finish adding information from LaserJet III
X *				manual, remove last vestiges of HP2TEX.PAS
X *				dependency (except for small #ifdef section)
X *	 4-Feb-91	SRMc - fix bug in "Class 2 Compressed Bitmap..." code
X *	 9-Feb-91	SRMc - add hack to handle input files that erroneously
X *				claim that header size is 64 rather than 26
X ***************************************************************************
X * Copyright 1990, 1991 by the Summer Institute of Linguistics, Inc.
X * All rights reserved.
X */
X/*#define TURBO_C*/		/* uncomment if using MSDOS TURBO C */
X#include <stdio.h>
X#include <ctype.h>
X#ifdef BSD
Xextern char *memset();
X#include <strings.h>
X#else
X#ifdef TURBO_C
X#include <mem.h>
X#define MSDOS
X#else
X#ifndef THINK_C		/* THINK C includes memxxx() functions in <string.h> */
X#include <memory.h>
X#endif
X#endif
X#include <string.h>
X#endif
X#ifdef THINK_C
X#define signed		/* keyword not recognized by this compiler */
X#endif
X
X#include "sfp.h"
X#include "bitmap.h"
X
X/************************************************************************/
X/*			   EXTERN DECLARATIONS				*/
X/************************************************************************/
X
Xextern void exit();
X
X/* from BIGENDIO.C */
Xextern unsigned long get_ufullword();
Xextern unsigned short get_uhalfword();
Xextern short get_halfword();
Xextern unsigned char get_ubyte();
Xextern signed char get_byte();
X
X/* from MYALLOC.C */
Xextern void myfree();
Xextern char *myalloc();
X
X/****************************************************************************
X * NAME
X *    static badseq
X * ARGUMENTS
X *    seq - pointer to ESCAPE Sequence string (minus ESC char itself)
X *    loc - byte address of location in the input file
X * DESCRIPTION
X *    Complain about an invalid escape sequence in the input file and die.
X * RETURN VALUE
X *    none
X */
Xstatic void badseq(seq,loc)
Xchar *seq;
Xlong loc;
X{
Xfflush(stdout);
Xfprintf(stderr, 
X"Unrecognized ESCAPE Sequence \"%s\" at location %ld in input file\n",
X	seq, loc );
X}
X
X/****************************************************************************
X * NAME
X *    static read_esc_sequence
X * ARGUMENTS
X *    fp - FILE pointer for HP Soft Font input file
X * DESCRIPTION
X *    Read an ESCAPE sequence from the file.
X *    See pages 1-5 through 1-8 of the HP LaserJet series II Printer Technical
X *    Reference Manual for a description of the syntax of its escape sequences.
X * RETURN VALUE
X *    pointer to escape sequence (minus the ESC character itself), or NULL
X *    if an error occurred
X */
Xstatic char *read_esc_sequence(fp)
XFILE *fp;
X{
Xstatic char seqbuf[100];
Xint i;
Xint c;
X
Xmemset(seqbuf, 0 , 100);
Xi = 0;
Xif ((c = getc(fp)) != '\033')
X    {
X    if (c != EOF)
X	{
X	ungetc(c, fp);
X	fflush(stdout);
X	fprintf(stderr,
X		"\nExpected ESCAPE Sequence at location %ld of input file\n",
X		ftell(fp) );
X	}
X    return( (char *)NULL );
X    }
Xc = getc(fp);
Xif (c == EOF)
X    {
X    badseq(seqbuf, ftell(fp));
X    return( (char *)NULL );
X    }
Xelse
X    seqbuf[i++] = c;
X
Xif ((c >= '!') && (c <= '/'))
X    {
X    /*
X     *  read a "parameterized" escape sequence
X     */
X    c = getc(fp);
X    if (c != EOF)
X	seqbuf[i++] = c;
X    if ((c < '`') || (c > '~'))
X	{
X	badseq(seqbuf,ftell(fp));
X	return( (char *)NULL );
X	}
Xcombined_sequence:
X    do  {
X	c = getc(fp);
X	if (c != EOF)
X	    seqbuf[i++] = c;
X	} while (isascii(c) && (isdigit(c) ||
X				(c == '+') || (c == '-') || (c == '.')) );
X    if ((c >= '`') && (c <= '~'))
X	goto combined_sequence;		/* we have a "combined" sequence */
X    else if ((c < '@') || (c > '^'))
X	{
X	badseq(seqbuf,ftell(fp));
X	return( (char *)NULL );
X	}
X    }
X/*
X *  all other escape sequences are assumed to be only two characters long
X */
Xreturn( seqbuf );
X}
X
X/****************************************************************************
X * NAME
X *    static skip_bytes
X * ARGUMENTS
X *    num     - number of bytes to skip
X *    fp      - input FILE pointer
X *    verbose - flag whether or not to display the bytes being skipped
X * DESCRIPTION
X *    Skip over some bytes of unknown content in the .SFP file.
X *    Since there may be a copyright notice hidden in these bytes,
X *    display whatever printable ASCII characters are encountered if
X *    the verbose flag is nonzero.
X * RETURN VALUE
X *    none
X */
Xstatic void skip_bytes(num, fp, verbose)
Xint num;
XFILE *fp;
Xint verbose;
X{
Xint i;
Xunsigned char c;
X
Xif (verbose)
X    printf( "Skipping %d bytes in the SFP file\n", num);
Xfor ( i = 0 ; i < num ; ++i )
X    {
X    c = get_ubyte(fp);
X    if (verbose && isascii(c) && (isprint(c) || isspace(c)))
X	putchar(c);
X    }
Xif (verbose)
X    putchar('\n');
X}
X
X/****************************************************************************
X * NAME
X *    static show_sfp_font_descriptor
X * ARGUMENTS
X *    hpf               - pointer to hp_font_descriptor structure
X *    symbol_set_string - address of pointer to font symbol set string
X *    verbose           - flag whether to actually display info
X * DESCRIPTION
X *    Convert SFP font descriptor into English, possibly displaying it.
X * RETURN VALUE
X *    none
X */
Xstatic void show_sfp_font_descriptor( hpf, symbol_set_string, verbose )
Xstruct hp_font_descriptor *hpf;
Xchar **symbol_set_string;
Xint verbose;
X{
Xchar *sss;
Xint i;
X
Xif (verbose)
X    {
X    printf("HP Soft Font characteristics:\n");
X    printf("    Font Descriptor Size = %d\n", hpf->font_descriptor_size );
X    if (hpf->header_format != 0)
X	{
X	if (hpf->header_format == 10)
X	    printf("    Font Format = Intellifont Scalable\n");
X	else
X	    printf("    Font Format = Unknown (%d)\n", hpf->header_format );
X	printf("Sorry, this program can handle only bitmap fonts!\n");
X	exit(1);
X	}
X    printf("    Font Type = ");
X    switch (hpf->font_type)
X	{
X	case 0:	printf("7 bit (96 characters [32-127])\n");		break;
X	case 1:	printf("8 bit (192 characters [32-127,160-255])\n");	break;
X	case 2:	printf("8 bit (256 characters [0-255])\n");		break;
X	default:
X	    fflush(stdout);
X	    fprintf(stderr,"UNKNOWN (%d) -- Invalid SFP file.\n",
X						hpf->font_type);
X	    exit(1);
X	}
X    if (hpf->reserved_fd_5 != 0)
X	printf("(ostensibly reserved field = 0x%02x)\n",
X						hpf->reserved_fd_5);
X    printf("    Baseline Distance = %d dots\n", hpf->baseline_distance );
X    printf("    Cell Width = %d dots\n",	hpf->cell_width );
X    printf("    Cell Height = %d dots\n",	hpf->cell_height );
X    printf("    Orientation = ");
X    switch (hpf->orientation)
X	{
X	case 0:	printf("portrait\n");			break;
X	case 1:
X	    fflush(stdout);
X	    fprintf(stderr, "landscape -- NOT SUPPORTED.\n");
X	    exit(1);
X	    break;
X	case 2:
X	    fflush(stdout);
X	    fprintf(stderr, "reverse portrait -- NOT SUPPORTED.\n");
X	    exit(1);
X	    break;
X	case 3:
X	    fflush(stdout);
X	    fprintf(stderr, "reverse landscape -- NOT SUPPORTED.\n");
X	    exit(1);
X	    break;
X	default:
X	    fflush(stdout);
X	    fprintf(stderr,"UNKNOWN (%d) -- Invalid SFP file.\n",
X						hpf->orientation);
X	    exit(1);
X	    break;
X	}
X    printf("    Spacing = ");
X    switch (hpf->spacing)
X	{
X	case 0:	printf("fixed\n");		break;
X	case 1:	printf("proportional\n");	break;
X	default:
X	    fflush(stdout);
X	    fprintf(stderr, "UNKNOWN (%d) -- Invalid SFP file.\n",
X						hpf->spacing);
X	    exit(1);
X	    break;
X	}
X    if (hpf->symbol_set > 2047)
X	{
X	fflush(stdout);
X	fprintf(stderr, "Invalid SFP file: Symbol Set code > 2047 (%d)\n",
X						hpf->symbol_set );
X	exit(1);
X	}
X    }
X/*
X *  the following string assignment is wanted for outside use
X */
Xswitch (hpf->symbol_set)
X    {
X    /*
X     * from HP LaserJet III Technical Reference Manual, March 1990, and/or
X     *      HP DeskJet Printer Family Software Developer's Guide, 1990
X     */
X    case 0:	sss = "\"Default Set\"";		break;	/* 0@ */
X    case 1:	sss = "Math-7";				break;	/* 0A */
X    case 2:	sss = "Line Draw-7";			break;	/* 0B */
X    case 3:    sss="HP Large Characters (264x Terminals)";break;/* 0C */
X    case 4:	sss = "ISO 60: Danish/Norwegian";	break;	/* 0D */
X    case 36:	sss = "ISO 61: Norwegian version 2";	break;	/* 1D */ /**/
X    case 5:	sss = "Roman Extensions";		break;	/* 0E */ /**/
X    case 37:	sss = "ISO 4: United Kingdom";		break;	/* 1E */
X    case 6:	sss = "ISO 25: French";			break;	/* 0F */ /**/
X    case 38:	sss = "ISO 69: French";			break;	/* 1F */
X    case 7:	sss = "HP German";			break;	/* 0G */ /**/
X    case 39:	sss = "ISO 21: German";			break;	/* 1G */
X    case 263:	sss = "Greek-8";			break;	/* 8G */
X    case 8:	sss = "Hebrew-7";			break;	/* 0H */
X    case 264:	sss = "Hebrew-8";			break;	/* 8H */
X    case 9:	sss = "ISO 15: Italian";		break;	/* 0I */
X    case 202:	sss = "Microsoft Publishing";		break;	/* 6J */
X    case 234:	sss = "DeskTop";			break;	/* 7J */
X    case 266:	sss = "Document";			break;	/* 8J */
X    case 330:	sss = "PS Text";			break;	/* 10J */
X    case 426:	sss = "Ventura International";		break;	/* 13J */
X    case 458:	sss = "Ventura US";			break;	/* 14J */
X    case 11:	sss = "ISO 14: JIS ASCII";		break;	/* 0K */ /**/
X    case 43:	sss = "ISO 13: Katakana";		break;	/* 1K */ /**/
X    case 75:	sss = "ISO 57: Chinese";		break;	/* 2K */ /**/
X    case 267:	sss = "Kana-8";				break;	/* 8K */
X    case 299:	sss = "Korean-8";			break;	/* 9K */
X    case 12:	sss = "Line Draw-7 (DeskJet)";		break;	/* 0L */
X    case 44:	sss = "HP Block Characters";		break;	/* 1L */
X    case 76:	sss = "Tax Line Draw";			break;	/* 2L */
X    case 268:	sss = "Line Draw-8";			break;	/* 8L */
X    case 300:	sss = "Ventura ITC Zapf Dingbats";	break;	/* 9L */
X    case 332:	sss = "PS ITC Zapf Dingbats";		break;	/* 10L */
X    case 364:	sss = "ITC Zapf Dingbats Series 100";	break;	/* 11L */
X    case 396:	sss = "ITC Zapf Dingbats Series 200";	break;	/* 12L */
X    case 428:	sss = "ITC Zapf Dingbats Series 300";	break;	/* 13L */
X    case 13:	sss = "Math-7 (DeskJet)";		break;	/* 0M */
X    case 45:	sss = "Technical-7";			break;	/* 1M */
X    case 173:	sss = "PS Math";			break;	/* 5M */
X    case 205:	sss = "Ventura Math";			break;	/* 6M */
X    case 269:	sss = "Math-8";				break;	/* 8M */
X    case 14:	sss = "ECMA-94 Latin 1 [ISO 8859/1]";	break;	/* 0N */
X    case 78:	sss = "ECMA-94 Latin 2 [ISO 8859/2]";	break;	/* 2N */
X    case 174:	sss = "ECMA-128 Latin 5 [ISO 8859/9]";	break;	/* 5N */
X    case 334:	sss="ECMA-113/88 Latin/Cyrillic [ISO 8859/5.2]";break;/* 10N */
X    case 15:	sss = "OCR A";				break;	/* 0O */
X    case 47:	sss = "OCR B";				break;	/* 1O */
X    case 79:	sss = "OCR M";				break;	/* 2O */
X    case 16:	sss = "APL [Typewriter Paired]";	break;	/* 0P */
X    case 48:	sss = "APL [Bit Paired]";		break;	/* 1P */
X    case 17:	sss = "HP Math-8a (DeskJet)";		break;	/* 0Q */
X    case 49:	sss = "HP Math-8b (DeskJet)";		break;	/* 1Q */
X    case 81:	sss = "HP Pi Font a (DeskJet)";		break;	/* 2Q */
X    case 18:sss="Cyrillic ASCII [ECMA-113/86, ISO 8859/5]";break;/*0R */
X    case 50:	sss = "Cyrillic";			break;	/* 1R */
X    case 114:	sss = "PC Cyrillic";			break;	/* 3R */
X    case 19:	sss = "ISO 11: Swedish for Names";	break;	/* 0S */
X    case 51:	sss = "HP Spanish";			break;	/* 1S */ /**/
X    case 83:	sss = "ISO 17: Spanish";		break;	/* 2S */
X    case 115:	sss = "ISO 10: Swedish";		break;	/* 3S */ /**/
X    case 147:	sss = "ISO 16: Portugese";		break;	/* 4S */ /**/
X    case 179:	sss = "ISO 84: Portugese";		break;	/* 5S */ /**/
X    case 211:	sss = "ISO 85: Spanish";		break;	/* 6S */ /**/
X    case 243:	sss = "HP European Spanish";		break;	/* 7S */
X    case 275:	sss = "HP Latin Spanish";		break;	/* 8S */
X    case 531:	sss = "HP-GL Download";			break;	/* 16S */
X    case 563:	sss = "HP-GL Drafting";			break;	/* 17S */
X    case 595:	sss = "HP-GL Special Symbols";		break;	/* 18S */
X    case 20:	sss = "Thai-8";				break;	/* 0T */
X    case 276:	sss = "Turkish-8";			break;	/* 8T */
X    case 21:	sss = "ISO 6: ASCII";			break;	/* 0U */
X    case 53:	sss = "Legal";				break;	/* 1U */
X    case 85: sss="ISO 2: International Reference Version";break;/* 2U */ /**/
X    case 181:	sss = "HPL Language Set";		break;	/* 5U */
X    case 245:	sss = "OEM-1";				break;	/* 7U */
X    case 277:	sss = "Roman-8";			break;	/* 8U */
X    case 309:	sss = "Windows";			break;	/* 9U */
X    case 341:	sss = "PC-8 [USA]";			break;	/* 10U */
X    case 373:	sss = "PC-8 D/N [Danish/Norwegian]";	break;	/* 11U */
X    case 405:	sss = "PC-850";				break;	/* 12U */
X    case 565:	sss = "PC-852";				break;	/* 17U */
X    case 501:	sss = "Pi Font";			break;	/* 15U */
X    case 22:	sss = "Arabic [McKay's version]";	break;	/* 0V */
X    case 278:	sss = "Arabic-8";			break;	/* 8V */
X    case 25:	sss = "3 of 9 Barcode";			break;	/* 0Y */
X    case 57:	sss = "Industrial 2 of 5 Barcode";	break;	/* 1Y */
X    case 89:	sss = "Matrix 2 of 5 Barcode";		break;	/* 2Y */
X    case 153:	sss = "Interleaved 2 of 5 Barcode";	break;	/* 4Y */
X    case 185:	sss = "CODABAR Barcode";		break;	/* 5Y */
X    case 217:	sss = "MSI/Plessey Barcode";		break;	/* 6Y */
X    case 249:	sss = "Code 11 Barcode";		break;	/* 7Y */
X    case 281:	sss = "UPC/EAN Barcode";		break;	/* 8Y */
X    case 505:	sss = "USPS Zip";			break;	/* 15Y */
X#ifdef USE_HP2TEX_INFO
X    /*
X     *  information from HP2TEX.PAS by David Strip and Dimitri L. Vulis
X     */
X    case 46:	sss = "ECMA-94 Latin 2, ISO #101";	break;	/* 1N */
X    case 110:	sss = "ECMA-94 Latin 4, ISO #110";	break;	/* 3N */
X    case 142:	sss = "ECMA Latin/Greek";		break;	/* 4N */
X    case 206:	sss = "ECMA Latin/Arabic";		break;	/* 6N */
X#endif
X    default:	sss = (char *)NULL;			break;
X    }
X*symbol_set_string = sss;
X
Xif (verbose)
X    {
X    printf("    Symbol Set = ");
X    if (sss == (char *)NULL)
X	printf("UNKNOWN (%d)\n", hpf->symbol_set );
X    else
X	printf( "%s\n", sss );
X    printf("    Pitch = %d/4 dots\n",	hpf->pitch );
X    printf("    Height = %d/4 dots\n",	hpf->height );
X    if (hpf->xheight != 0)
X	printf("    xHeight = %d/4 dots\n", hpf->xheight );
X    printf("    Width Type = ");
X    switch (hpf->width_type)
X	{
X	case -5:	printf( "Ultra Compressed\n");			break;
X	case -4:	printf( "Extra Compressed\n");			break;
X	case -3:	printf( "Compressed\n");			break;
X	case -2:	printf( "Condensed\n");				break;
X	case -1:	printf( "Semi-Condensed\n");			break;
X	case  0:	printf( "Normal\n");				break;
X	case  1:	printf( "Semi-Expanded\n");			break;
X	case  2:	printf( "Expanded\n");				break;
X	case  3:	printf( "Extra Expanded\n");			break;
X	default:	printf("unknown (%d)\n", hpf->width_type );	break;
X	}
X    printf("    Style = ");
X    i = hpf->style + (hpf->style_msb << 8);
X    switch (i & 03)
X	{
X	case 0:		printf("Upright");		break;
X	case 1:		printf("Italic");		break;
X	case 2:		printf("Alternate Italic");	break;
X	}
X    i >>= 2;
X    switch (i & 07)
X	{
X	case 0:		printf(" Normal");		break;
X	case 1:		printf(" Condensed");		break;
X	case 2:		printf(" Compressed");		break;
X	case 3:		printf(" Extra Compressed");	break;
X	case 4:		printf(" Ultra Compressed");	break;
X	case 6:		printf(" Expanded");		break;
X	case 7:		printf(" Extra Expanded");	break;
X	}
X    i >>= 3;
X    switch (i & 037)
X	{
X	case 0:		printf(" Solid");		break;
X	case 1:		printf(" Outline");		break;
X	case 2:		printf(" Inline");		break;
X	case 3:		printf(" Contour");		break;
X	case 4:		printf(" Solid with Shadow");	break;
X	case 5:		printf(" Outline with Shadow");	break;
X	case 6:		printf(" Inline with Shadow");	break;
X	case 7:		printf(" Contour with Shadow");	break;
X	case 8:		/* fall through */
X	case 9:		/* fall through */
X	case 10:	/* fall through */
X	case 11:	printf(" Patterned");			break;
X	case 12:	/* fall through */
X	case 13:	/* fall through */
X	case 14:	/* fall through */
X	case 15:	printf(" Patterned with Shadow");	break;
X	case 16:	printf(" Inverse");			break;
X	case 17:	printf(" Inverse in Open Border");	break;
X	}
X    printf("\n\
X    Stroke Weight = %d (-7..7, normal = 0, thinnest = -7, thickest = +7)\n",
X						hpf->stroke_weight );
X    printf("    Typeface = ");
X    i = hpf->typeface + (hpf->typeface_msb << 8);
X    switch (i & 0x1FF)
X	{
X	/*
X	 * from HP LaserJet III Technical Reference Manual, March 1990
X	 */
X	case   0:	printf("Line Printer");			break;
X	case   1:	printf("Pica");				break;
X	case   2:	printf("Elite");			break;
X	case   3:	printf("Courier");			break;
X	case   4:	printf("Helvetica");			break;
X	case   5:	printf("Times Roman");			break;
X	case   6:	printf("Letter Gothic");		break;
X	case   7:	printf("Script");			break;
X	case   8:	printf("Prestige");			break;
X	case   9:	printf("Caslon");			break;
X	case  10:	printf("Orator");			break;
X	case  11:	printf("Presentation");			break;
X	case  12:	printf("Helvetica Condensed");		break; /**/
X	case  13:	printf("Serifa");			break;
X	case  14:	printf("Futura");			break;
X	case  15:	printf("Palatino");			break;
X	case  16:	printf("ITC Souvenir");			break;
X	case  17:	printf("Optima");			break;
X	case  18:	printf("ITC Garamond");			break;
X	case  19:	printf("Cooper Black");			break; /**/
X	case  20:	printf("Coronet");			break;
X	case  21:	printf("Broadway");			break;
X	case  22:	printf("Bauer Bodoni Black Condensed");	break; /**/
X	case  23:	printf("Century Schoolbook");		break;
X	case  24:	printf("University Roman");		break;
X	case  25:	printf("Helvetica Outline");		break; /**/
X	case  26:	printf("Futura Condensed");		break; /**/
X	case  27:	printf("ITC Korinna");			break;
X	case  28:	printf("Naskh");			break;
X	case  29:	printf("Cloister Black");		break;
X	case  30:	printf("ITC Galliard");			break;
X	case  31:	printf("ITC Avant Garde Gothic");	break;
X	case  32:	printf("Brush");			break;
X	case  33:	printf("Blippo");			break;
X	case  34:	printf("Hobo");				break;
X	case  35:	printf("Windsor");			break;
X	case  36:	printf("Helvetica Compressed");		break; /**/
X	case  37:	printf("Helvetica Extra Compressed");	break; /**/
X	case  38:	printf("Peignot");			break;
X	case  39:	printf("Baskerville");			break;
X	case  40:	printf("ITC Garamond Condensed");	break; /**/
X	case  41:	printf("Trade Gothic");			break;
X	case  42:	printf("Goudy Old Style");		break;
X	case  43:	printf("ITC Zapf Chancery");		break;
X	case  44:	printf("Clarendon");			break;
X	case  45:	printf("ITC Zapf Dingbats");		break;
X/*****************************************************************************/
X	case  46:	printf("Cooper");			break;
X	case  47:	printf("ITC Bookman");			break;
X	case  48:	printf("Stick");			break;
X	case  49:	printf("HP-GL Drafting");		break;
X	case  50:	printf("HP-GL Spline");			break;
X	case  51:	printf("Gill Sans");			break;
X	case  52:	printf("Univers");			break;
X	case  53:	printf("Bodoni");			break;
X	case  54:	printf("Rockwell");			break;
X	case  55:	printf("Melior");			break;
X	case  56:	printf("ITC Tiffany");			break;
X	case  57:	printf("ITC Clearface");		break;
X	case  58:	printf("Amelia");			break;
X	case  59:	printf("Park Avenue");			break;
X	case  60:	printf("Handel Gothic");		break;
X	case  61:	printf("Dom Casual");			break;
X	case  62:	printf("ITC Benguiat");			break;
X	case  63:	printf("ITC Cheltenham");		break;
X	case  64:	printf("Century Expanded");		break;
X	case  65:	printf("Franklin Gothic");		break;
X	case  66:	printf("Franklin Gothic Expressed");	break; /**/
X	case  67:	printf("Franklin Gothic Extra Condensed"); break; /**/
X	case  68:	printf("Plantin");			break;
X	case  69:	printf("Trump Mediaeval");		break;
X	case  70:	printf("Futura Black");			break;
X	case  72:	printf("Antique Olive");		break;
X	case  73:	printf("Uncial");			break;
X	case  74:	printf("ITC Bauhaus");			break;
X	case  75:	printf("Century Oldstyle");		break;
X	case  76:	printf("ITC Eras");			break;
X	case  77:	printf("Friz Ouadrata (ITC)");		break;
X	case  78:	printf("ITC Lubalin Graph");		break;
X	case  79:	printf("Eurostile");			break;
X	case  80:	printf("Mincho");			break;
X	case  81:	printf("ITC Serif Gothic");		break;
X	case  82:	printf("Signet Roundhand");		break;
X	case  83:	printf("Souvenir Gothic");		break;
X	case  84:	printf("Stymie");			break;
X	case  87:	printf("Bernhard Modern");		break;
X	case  89:	printf("Excelsior");			break;
X	case  90:	printf("Gando Ronda Script");		break;
X	case  91:	printf("Ondine");			break;
X	case  92:	printf("P.T. Barnum");			break;
X	case  93:	printf("Kaufman");			break;
X	case  94:	printf("ITC Bolt Bold");		break;
X	case  96:	printf("Helvetica Monospaced");		break; /**/
X	case  97:	printf("Revue");			break;
X	case 101:	printf("Garamond (Stempel)");		break;
X	case 102:	printf("Garth Graphic");		break;
X	case 103:	printf("ITC Ronda");			break;
X	case 104:	printf("OCR-A");			break;
X	case 106:	printf("Englische Schreibschrift");	break;
X	case 107:	printf("Flash");			break;
X	case 108:	printf("Gothic Outline (URW)");		break;
X	case 109:	printf("Stencil (ATF)");		break;
X	case 110:	printf("OCR-B");			break;
X	case 111:	printf("Akzidenz-Grotesk");		break;
X	case 112:	printf("TD Logos");			break;
X	case 113:	printf("Shannon");			break;
X	case 114:	printf("ITC Century");			break;
X	case 152:	printf("Maru Gosikku");			break;
X	case 153:	printf("Gossikku");			break;
X	case 154:	printf("Socho");			break;
X	case 155:	printf("Kyokasho");			break;
X	case 156:	printf("Kaisho");			break;
X	case 157:	printf("Traditional Arabic Script");	break;
X	case 158:	printf("Arabic News");			break;
X	case 160:	printf("Devanagari (Hindi)");		break;
X	case 161:	printf("Krishna (Gujarati)");		break;
X	case 162:	printf("Ranjit (Gurmukhi)");		break;
X	case 163:	printf("Raj Raja (Tamil)");		break;
X	case 164:	printf("Gyosho");			break;
X	case 165:	printf("Hebrew");			break;
X	case 166:	printf("Nork");				break;
X	case 167:	printf("Ousbouh");			break;
X	case 168:	printf("Koufi");			break;
X	case 261:	printf("Greek Times");			break;
X/*****************************************************************************/
X
X	case  85:	printf("Univers Condensed");		break;
X
X	default:	printf("unknown (%d)", hpf->typeface ); break;
X	}
X    if (hpf->typeface_msb)
X	{
X	/*
X	 *  decode Vendor information
X	 */
X	i = (hpf->typeface_msb >> 3) & 017;
X	switch (i)
X	    {
X	    case 0:						break;
X	    case 2:	printf(", from AGFA Compugraphic");	break;
X	    default:	printf(", from unknown vendor (%d)",i);	break;
X	    }
X	i = (hpf->typeface_msb >> 1) & 03;
X	if (i)
X	    printf(", vendor's version %d", i+1 );
X	}
X    printf("\n");
X
X    if (hpf->font_name[0])
X	{
X	printf( "    Font Name = \"");
X	for ( i = 0 ; i < 16 ; ++i )
X	    putchar(hpf->font_name[i]);
X	printf( "\"\n");
X	}
X    }
X}
X
X/****************************************************************************
X * NAME
X *    read_sfp_font_descriptor
X * ARGUMENTS
X *    fp                - input FILE pointer
X *    hpf               - pointer to hp_font_descriptor structure
X *    symbol_set_string - address of pointer to font symbol set string
X *    verbose           - flag whether or not to be talkative
X * DESCRIPTION
X *    Read the font descriptor from the .SFP file.
X * RETURN VALUE
X *    none
X */
Xvoid read_sfp_font_descriptor(fp, hpf, symbol_set_string, verbose)
XFILE *fp;
Xstruct hp_font_descriptor *hpf;
Xchar **symbol_set_string;
Xint verbose;
X{
Xint hdr_len;
Xint i;
Xchar *p;
X
Xhdr_len = 0;
Xi = 2;
Xp = read_esc_sequence(fp);
Xif ((p != (char *)NULL) && (p[0] == ')') && (p[1] == 's'))
X    {
X    for ( ; isascii(p[i]) && isdigit(p[i]) ; ++i )
X	{
X	hdr_len *= 10;
X	hdr_len += p[i] - '0';
X	}
X    }
Xif (	(p == (char *)NULL) ||
X	(p[0] != ')') || (p[1] != 's') || (hdr_len < 26) || (p[i] != 'W') )
X    {
X    fflush(stdout);
X    fprintf(stderr,
X	    "Invalid SFP file:  Font header missing or mangled.\n");
X    exit(1);
X    }
X/*
X * read the data from the file into memory
X */
Xhpf->font_descriptor_size = get_uhalfword(fp);
Xif (hpf->font_descriptor_size > hdr_len)
X    {
X    fflush(stdout);
X    if (hpf->font_descriptor_size != 64)
X	{
X	fprintf(stderr,
X	    "ERROR: Font descriptor size is larger than header length!\n");
X	exit(1);
X	}
X    else
X	{
X	fprintf(stderr,
X"WARNING: Font descriptor size is larger than header length--truncating to 26.\n");
X	fprintf(stderr, "    TAKE NOTE: The output may well be garbage!\n");
X	hpf->font_descriptor_size = 26;
X	}
X    }
Xif ((hpf->font_descriptor_size != 26) && (hpf->font_descriptor_size != 64))
X    {
X    fflush(stdout);
X    fprintf(stderr, "Warning: unusual font descriptor size = %d\n",
X	    hpf->font_descriptor_size );
X    }
Xhpf->header_format = get_ubyte(fp);
Xhpf->font_type = get_ubyte(fp);
Xhpf->style_msb = get_ubyte(fp);
Xhpf->reserved_fd_5 = get_ubyte(fp);
Xhpf->baseline_distance = get_uhalfword(fp);
Xhpf->cell_width = get_uhalfword(fp);
Xhpf->cell_height = get_uhalfword(fp);
Xhpf->orientation = get_ubyte(fp);
Xhpf->spacing = get_ubyte(fp);
Xhpf->symbol_set = get_uhalfword(fp);
Xhpf->pitch = get_uhalfword(fp);
Xhpf->height = get_uhalfword(fp);
Xhpf->xheight = get_uhalfword(fp);
Xhpf->width_type = get_byte(fp);
Xhpf->style = get_ubyte(fp);
Xhpf->stroke_weight = get_byte(fp);
Xhpf->typeface = get_ubyte(fp);
Xif (hpf->font_descriptor_size > 26)  hpf->typeface_msb = get_ubyte(fp);
Xif (hpf->font_descriptor_size > 27)  hpf->serif_style = get_ubyte(fp);
Xif (hpf->font_descriptor_size > 28)  hpf->quality = get_ubyte(fp);
Xif (hpf->font_descriptor_size > 29)  hpf->placement = get_ubyte(fp);
Xif (hpf->font_descriptor_size > 30)  hpf->underline_distance = get_byte(fp);
Xif (hpf->font_descriptor_size > 31)  hpf->underline_height = get_ubyte(fp);
Xif (hpf->font_descriptor_size > 33)  hpf->text_height = get_halfword(fp);
Xif (hpf->font_descriptor_size > 35)  hpf->text_width = get_halfword(fp);
Xif (hpf->font_descriptor_size > 37)  hpf->firstcode = get_halfword(fp);
Xif (hpf->font_descriptor_size > 39)  hpf->lastcode = get_halfword(fp);
Xif (hpf->font_descriptor_size > 40)  hpf->pitch_extended = get_ubyte(fp);
Xif (hpf->font_descriptor_size > 41)  hpf->height_extended = get_ubyte(fp);
Xif (hpf->font_descriptor_size > 43)  hpf->cap_height = get_uhalfword(fp);
Xif (hpf->font_descriptor_size > 47)  hpf->font_number = get_ufullword(fp);
Xif (hpf->font_descriptor_size > 63)
X    {
X    for ( i = 0 ; i < 16 ; ++i )
X	hpf->font_name[i] = get_ubyte(fp);
X    }
Xelse
X    memset(hpf->font_name, ' ', 16);
X
Xshow_sfp_font_descriptor( hpf, symbol_set_string, verbose );
X
Xif (hdr_len > hpf->font_descriptor_size)
X    skip_bytes(hdr_len - hpf->font_descriptor_size, fp, verbose);
X}
X
X/****************************************************************************
X * NAME
X *    read_sfp_character
X * ARGUMENTS
X *    fp  - .SFP input FILE pointer
X *    hpf - pointer to HP font descriptor
X *    hpc - pointer to HP font character structure
X *    bmp - pointer to bitmap structure
X * DESCRIPTION
X *    Read all of a character's data.
X * RETURN VALUE
X *    the character code, or -1 if problems arise or EOF
X */
Xint read_sfp_character(fp, hpf, hpc, bmp)
XFILE *fp;
Xstruct hp_font_descriptor *hpf;
Xstruct hp_character_descriptor *hpc;
Xstruct character_bitmap *bmp;
X{
Xint char_code;
Xint char_len;
Xint i, j;
Xlong ltemp;
Xlong *pr;
Xchar *p;
X/*  maximum dot width is 4200.  8 dots/byte => 525 bytes maximum.
X *  however, need to pad array out to a multiple of 4.
X */
Xstatic unsigned char buffer[528];
Xint byte_width;		/* number of 8-bit bytes wide in a bitmap row */
X/*
X *  variables used to decode "Class 2 Compressed Bitmap Character Data"
X */
Xunsigned char row_repeat;	/* number of extra times row is repeated */
Xint this_bit;			/* either 0 or 1 */
Xint total_bits;			/* number of bits seen in this row so far */
Xint num_bits;			/* number of bits in this run */
Xunsigned bit_idx;		/* bit index into buffer[] */
Xstatic unsigned char bits[8] = { 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 };
X/*
X * Get the char code and print message
X */
Xloop_1:
Xi = 2;
Xchar_code = 0;
Xp = read_esc_sequence(fp);
Xif ((p != (char *)NULL) && (p[0] == '*') && (p[1] == 'c'))
X    {
X    for ( ; isascii(p[i]) && isdigit(p[i]) ; ++i )
X	{
X	char_code *= 10;
X	char_code += p[i] - '0';
X	}
X    }
Xif (	(p == (char *)NULL) || (p[0] != '*') || (p[1] != 'c') ||
X	!(isascii(p[2]) && isdigit(p[2])) || (p[i] != 'E') )
X    {
X    if (p != (char *)NULL)
X	{
X	badseq(p, ftell(fp) );
X	fprintf(stderr, "    Expected character code assignment \"*c#E\"\n");
X	goto loop_1;
X	}
X    /*
X     *  we don't abort, but merely exit (it could well be EOF)
X     */
X    return( -1 );
X    }
X/*
X * Now read the character header
X */
Xloop_2:
Xi = 2;
Xchar_len = 0;
Xp = read_esc_sequence(fp);
Xif ((p != (char *)NULL) && (p[0] == '(') && (p[1] == 's'))
X    {
X    for ( ; isascii(p[i]) && isdigit(p[i]) ; ++i )
X	{
X	char_len *= 10;
X	char_len += p[i] - '0';
X	}
X    }
Xif (	(p == (char *)NULL) || (p[0] != '(') || (p[1] != 's') ||
X	!(isascii(p[2]) && isdigit(p[2])) || (p[i] != 'W') )
X    {
X    if (p != (char *)NULL)
X	{
X	badseq(p, ftell(fp) );
X	fprintf(stderr, "    Expected character header \"(s#W\"\n");
X	goto loop_2;
X	}
X    /*
X     *  we don't abort, but merely exit (it could well be EOF)
X     */
X    return( -1 );
X    }
X
Xhpc->format = get_ubyte(fp);
Xhpc->continuation = get_ubyte(fp);
Xhpc->descriptor_size = get_ubyte(fp);
Xhpc->class = get_ubyte(fp);
Xhpc->orientation = get_ubyte(fp);
Xhpc->reserved_cd_5 = get_ubyte(fp);
Xhpc->left_offset = get_halfword(fp);
Xhpc->top_offset = get_halfword(fp);
Xhpc->character_width = get_uhalfword(fp);
Xhpc->character_height = get_uhalfword(fp);
Xhpc->delta_x = get_halfword(fp);
Xchar_len -= sizeof(struct hp_character_descriptor);
X/*
X *  check for valid data
X */
Xif (hpc->character_width > 4200)
X    {
X    fflush(stdout);
X    fprintf(stderr,"Invalid SFP file: Character wider than 4200 dots (%d).\n",
X					hpc->character_width );
X    exit(1);
X    }
Xif (hpc->character_height > 4200)
X    {
X    fflush(stdout);
X    fprintf(stderr,"Invalid SFP file: Character higher than 4200 dots (%d).\n",
X					hpc->character_height );
X    exit(1);
X    }
Xif (hpc->orientation != hpf->orientation)
X    {
X    fflush(stdout);
X    fprintf(stderr, 
X"Invalid SFP file: Character orientation does not match font orientation\n");
X    exit(1);
X    }
Xif ((hpc->character_width == 0) || (hpc->character_height == 0))
X    {
X    if (char_len > 0)
X	skip_bytes(char_len, fp);
X/*  hpc->character_width  = 0;*/
X/*  hpc->character_height = 0;*/
X    }
X/*
X *  load the bitmap data
X */
Xif ((hpc->character_width != 0))
X    {
X    byte_width = (hpc->character_width + 7) >> 3;
X    bmp->raster_width = (hpc->character_width + 31) >> 5;
X    bmp->raster_height = hpc->character_height;
X    /*
X     *  if necessary, initialize the padding for the row storage
X     */
X    i = byte_width & 0x3;
X    if (i > 0)
X	{
X	i = byte_width + 4 - i;		/* padding required */
X	for ( j = byte_width ; j < i ; ++j )
X	    buffer[j] = 0;			/* add the padding */
X	}
X    /*
X     *  make sure we have enough memory allocated for bitmap
X     */
X    ltemp = (long)bmp->raster_width * (long)bmp->raster_height * sizeof(long);
X    if (bmp->raster_size < ltemp)
X	{
X	if (bmp->raster)		/* need to reallocate */
X	    myfree(bmp->raster);
X	bmp->raster_size = ltemp;
X	if (bmp->raster_size != ltemp)
X	    {				/* let's be totally paranoid! */
X	    fflush(stdout);
X	    fprintf(stderr,
X	    "Cannot allocate enough memory for bitmap raster (%ld).\n",ltemp);
X	    exit(1);
X	    }
X	bmp->raster = (long *)myalloc( bmp->raster_size );
X	}
X    if (ltemp > 32767)
X	{
X	fflush(stdout);
X	fprintf(stderr,
X		"Sorry, I cannot handle bitmaps larger than 32767 bytes\n\
XThe bitmap for character %d occupies %ld bytes.\n", char_code, ltemp );
X	}
X    /*
X     *  copy pixels from sfp_fp to raster, padding out the rows
X     */
X    pr = bmp->raster;
X    for ( i = 0 ; i < hpc->character_height ; )
X	{
X	row_repeat = 1;		/* row always used at least once */
X	if (hpc->class == 1)
X	    {
X	    for ( j = 0 ; j < byte_width ; ++j )
X		buffer[j] = get_ubyte(fp);
X	    char_len -= byte_width;
X	    }
X	else if (hpc->class == 2)
X	    {
X	    memset(buffer,0,byte_width);
X	    row_repeat += get_ubyte(fp);	/* 0 => once, 1 => twice,... */
X	    --char_len;
X	    for (   total_bits = 0, this_bit = 0, bit_idx = 0 ;
X		    total_bits < hpc->character_width ;
X		    total_bits += num_bits, this_bit ^= 1 )
X		{
X		num_bits = get_ubyte(fp);
X		--char_len;
X		if (this_bit)
X		    {
X		    for ( j = 0 ; j < num_bits ; ++j )
X			{
X			buffer[bit_idx/8] |= bits[bit_idx%8];
X			++bit_idx;
X			}
X		    }
X		else
X		    bit_idx += num_bits;
X		}
X	    }
X	else
X	    {
X	    fflush(stdout);
X	    fprintf(stderr,
X"Invalid SFP file: Character class = %d; only classes 1 and 2 can be handled.\n",
X		    hpc->class );
X	    exit(1);
X	    }
X	while (row_repeat--)
X	    {
X	    for ( j = 0 ; j < byte_width ; j += 4 )
X		{
X		ltemp = buffer[j];
X		ltemp <<= 8;
X		ltemp |= buffer[j+1];
X		ltemp <<= 8;
X		ltemp |= buffer[j+2];
X		ltemp <<= 8;
X		ltemp |= buffer[j+3];
X		*pr++ = ltemp;
X		}
X	    ++i;		/* increment the row counter */
X	    }
X	if (char_len < 0)
X	    {
X	    fflush(stdout);
X	    fprintf(stderr, "Invalid SFP file: Raster too short.\n");
X	    exit(1);
X	    }
X	}
X    if (char_len > 0)
X	skip_bytes(char_len, fp);
X    }
Xreturn(char_code);
X}
END_OF_FILE
if test 34298 -ne `wc -c <'readsfp.c'`; then
    echo shar: \"'readsfp.c'\" unpacked with wrong size!
fi
# end of 'readsfp.c'
fi
echo shar: End of archive 4 \(of 4\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 4 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0

exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.