home *** CD-ROM | disk | FTP | other *** search
- /*
- * JET PAK - HP DeskJet and LaserJet series printer utilities
- *
- * JETD2L program - convert from DeskJet to LaserJet soft font file
- *
- * Version 1.1 (Public Domain)
- */
-
- /* system include files */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
-
- /* application include files */
- #include "patchlev.h"
- #include "jetfont.h"
- #include "jetutil.h"
- #include "jetbmp.h"
-
- /*
- * MODULE GLOBAL DATA
- */
-
- /* baseline distance for bottom pass */
- static UNSIGNEDINT baseline;
-
- /* pitch is needed for converting landscape characters */
- static UNSIGNEDINT pitch;
-
- /* height to use for all characters */
- static UNSIGNEDINT cell_height;
-
- /* offsets for passes */
- static UNSIGNEDINT offsets[4];
-
- /* portrait or landscape font */
- static UNSIGNEDBYTE orientation;
-
- /* fixed or proportional spacing font */
- static UNSIGNEDINT spacing;
-
- /* input and output font commands being processed */
- static FONT_COMMAND infc, outfc;
-
- /* output file suffix */
- static char output_suffix[SUFFIX_MAX] = ".d2l";
-
- /* compact bitmap structure */
- typedef struct compact_ljchar_struct {
- SIGNEDINT left_offset;
- SIGNEDINT top_offset;
- UNSIGNEDINT character_width;
- UNSIGNEDINT character_height;
- SIGNEDINT delta_x;
- UNSIGNEDBYTE *bitmap;
- } COMPACT_LJCHAR;
- static COMPACT_LJCHAR ljchars[256] = { 0 };
- #define sizeofljbitmap(w,h) (((w + 7)/8)*h)
-
- /*
- * LOCAL FUNCTIONS
- */
-
- static void usage_wrong()
- {
- /*
- * Print usage message and exit.
- */
- fprintf(stderr, USAGE_HEADER);
- fprintf(stderr, "Usage: JETD2L [-h] [-t filetype] djfontfile [djfontfile...]\n\n");
- fprintf(stderr, "Convert DeskJet font files to LaserJet format\n\n");
- fprintf(stderr, " -h print this usage information\n");
- fprintf(stderr, " -t filetype change output file type (default %s)\n", output_suffix);
- fprintf(stderr, " djfontfile name of DeskJet format soft font file to be converted\n");
- exit(1);
- }
-
- static int ljchar_create(charcode, infcp)
- UNSIGNEDINT charcode;
- FONT_COMMAND *infcp;
- {
- /*
- * Copy the information in a DeskJet character descriptor to
- * a compact LaserJet character structure, allocating space
- * for the bitmap if necessary.
- */
- struct djchar_struct *djp;
- UNSIGNEDINT height;
- int pass;
-
- /* issue a warning if the character descriptor is in a strange format */
- if ( (infcp->data.character.format != DJCHARFORMAT)
- && (infcp->data.character.format != DJPCHARFORMAT)
- && (infcp->data.character.format != DJ500CHARFORMAT) )
- fprintf(stderr, WARNING_BAD_CHAR_FORMAT,
- os_dir, os_file, infcp->data.character.format);
-
- /* check the character code is in range */
- if (charcode >= sizeofarray(ljchars))
- {
- fprintf(stderr, ERROR_CODE_TOO_BIG, os_dir, os_file, charcode);
- return(ERROR);
- }
-
- /* OK to save the information */
- djp = &infcp->data.character.data.djchar;
- switch (djp->char_type)
- {
- case CHAR_TYPE_NORMAL:
- case CHAR_TYPE_PASS1:
- if (orientation == LANDSCAPE)
- {
- ljchars[charcode].left_offset = djp->comp_width/2 - baseline;
- ljchars[charcode].top_offset = pitch;
- ljchars[charcode].character_width = djp->character_width/2;
- ljchars[charcode].character_height = pitch;
- ljchars[charcode].delta_x = pitch*4;
- }
- else
- {
- ljchars[charcode].top_offset = baseline;
- ljchars[charcode].character_width = djp->character_width/2;
- ljchars[charcode].character_height = cell_height;
- if (spacing == FIXED)
- {
- ljchars[charcode].delta_x = pitch*4;
- ljchars[charcode].left_offset = ((SIGNEDINT)(pitch - djp->character_width/2))/2;
- }
- else
- {
- ljchars[charcode].delta_x = 2 * ( djp->right_offset
- + djp->left_offset
- + djp->character_width);
- ljchars[charcode].left_offset = djp->left_offset/2;
- }
- }
-
- if ((ljchars[charcode].bitmap =
- zalloc(sizeofljbitmap(ljchars[charcode].character_width, ljchars[charcode].character_height))) == NULL)
- {
- fprintf(stderr, ERROR_FONT_OUT_OF_HEAP, os_dir, os_file);
- return(ERROR);
- }
-
- /* !! intentional drop-through !! */
- default:
- pass = pass_for_char_type(djp->char_type) % sizeofarray(offsets);
-
- height = ljchars[charcode].character_height - offsets[pass];
- if (height > PASS_HEIGHT)
- height = PASS_HEIGHT;
-
- if (bitmap_dj_to_lj(djp->bitmap, djp->character_width, height,
- offsets[pass], ljchars[charcode].bitmap,
- sizeofljbitmap(ljchars[charcode].character_width,
- ljchars[charcode].character_height)) != OK)
- {
- fprintf(stderr, ERROR_BITMAP_TOO_BIG, os_dir, os_file);
- return(ERROR);
- }
- }
-
- return(OK);
- }
-
- static void ljchar_free_all()
- {
- /*
- * Free the resources used in all the compact LaserJet characters.
- */
- UNSIGNEDINT charcode;
-
- for (charcode = 0; charcode < sizeofarray(ljchars); charcode++)
- {
- if (ljchars[charcode].bitmap != NULL)
- {
- free(ljchars[charcode].bitmap);
- ljchars[charcode].bitmap = NULL;
- }
- }
- }
-
- static int fdc_dj_to_lj(infcp, outfcp)
- FONT_COMMAND *infcp, *outfcp;
- {
- /*
- * Convert a DeskJet font descriptor command to a LaserJet font
- * descriptor command.
- */
- int passes;
- FONT_DESCRIPTOR *fdp;
-
- /* check input file is in correct format */
- if (infcp->data.font.header_format == LJFONTFORMAT)
- {
- fprintf(stderr, ERROR_LASERJET, os_dir, os_file);
- return(ERROR);
- }
- else if ( (infcp->data.font.header_format != DJFONTFORMAT)
- && (infcp->data.font.header_format != DJPFONTFORMAT)
- && (infcp->data.font.header_format != DJ500FONTFORMAT) )
- {
- fprintf(stderr, WARNING_BAD_FONT_FORMAT,
- os_dir, os_file, infcp->data.font.header_format);
- }
-
- outfcp->command_type = infcp->command_type;
- outfcp->number = LJFDSIZE+LJSSIZE;
-
- /* most of the font descriptor fields can be copied straight
- across */
- outfcp->data.font = infcp->data.font;
-
- /* now change the standard font descriptor bits that are different */
- fdp = &outfcp->data.font;
- fdp->header_format = LJFONTFORMAT;
- fdp->size = LJFDSIZE;
-
- /* convert the bitmap related data - depends on orientation */
- if (fdp->orientation == LANDSCAPE)
- {
- fdp->cell_height /= 2; /* -> 300 dpi in X direction */
-
- /* must be a single pass font */
- passes = 1;
- offsets[0] = 0;
- offsets[1] = 0;
- offsets[2] = 0;
- offsets[3] = 0;
- }
- else /* PORTRAIT */
- {
- /* save the pass offsets */
- if (fdp->baseline_offset_4 != 0)
- {
- passes = 4;
- offsets[0] = fdp->baseline_offset_4 - fdp->baseline_distance;
- offsets[1] = fdp->baseline_offset_4 - fdp->baseline_offset_2;
- offsets[2] = fdp->baseline_offset_4 - fdp->baseline_offset_3;
- offsets[3] = 0;
- fdp->baseline_distance = fdp->baseline_offset_4;
- }
- else if (fdp->baseline_offset_3 != 0)
- {
- passes = 3;
- offsets[0] = fdp->baseline_offset_3 - fdp->baseline_distance;
- offsets[1] = fdp->baseline_offset_3 - fdp->baseline_offset_2;
- offsets[2] = 0;
- offsets[3] = 0;
- fdp->baseline_distance = fdp->baseline_offset_3;
- }
- else if (fdp->baseline_offset_2 != 0)
- {
- passes = 2;
- offsets[0] = fdp->baseline_offset_2 - fdp->baseline_distance;
- offsets[1] = 0;
- offsets[2] = 0;
- offsets[3] = 0;
- fdp->baseline_distance = fdp->baseline_offset_2;
- }
- else
- {
- passes = 1;
- offsets[0] = 0;
- offsets[1] = 0;
- offsets[2] = 0;
- offsets[3] = 0;
- }
-
- fdp->cell_width /= 2; /* -> 300 dpi in X direction */
-
- fdp->cell_height = offsets[0] + PASS_HEIGHT;
- }
-
- /* save parameters needed in character descriptor processing */
- baseline = fdp->baseline_distance;
- pitch = fdp->pitch/4;
- orientation = fdp->orientation;
- cell_height = fdp->cell_height;
- spacing = fdp->spacing;
-
- /* add identifying suffix to existing copyright notice */
- if ((strlen(fdp->comment) + sizeof(JETD2L_COMMENT_SUFFIX)) < COMMENT_SIZE_MAX)
- strcat(fdp->comment, JETD2L_COMMENT_SUFFIX);
- outfcp->number += strlen(fdp->comment);
-
- return(passes);
- }
-
- static int cdc_dj_to_lj(inccp, outfcp)
- COMPACT_LJCHAR *inccp;
- FONT_COMMAND *outfcp;
- {
- /*
- * Copy a compact LaserJet character to a real LaserJet character
- * descriptor.
- */
- struct ljchar_struct *ljp;
-
- outfcp->command_type = CDC;
-
- /* deal with the preamble bits */
- outfcp->data.character.format = LJCHARFORMAT;
- outfcp->data.character.continuation = 0;
-
- /* deal with the character descriptor proper */
- ljp = &outfcp->data.character.data.ljchar;
- ljp->descriptor_size = LJCDSIZE;
- ljp->class = 1;
- ljp->orientation = orientation;
- ljp->reserved = 0;
- ljp->left_offset = inccp->left_offset;
- ljp->top_offset = inccp->top_offset;
- ljp->character_width = inccp->character_width;
- ljp->character_height = inccp->character_height;
- ljp->delta_x = inccp->delta_x;
-
- memcpy(ljp->bitmap, inccp->bitmap,
- sizeofljbitmap(ljp->character_width, ljp->character_height));
- outfcp->number = 2 + LJCDSIZE + sizeofljbitmap(ljp->character_width, ljp->character_height);
-
- return(OK);
- }
-
- static void jetd2l()
- {
- char inpath[OS_PATH_LEN], outpath[OS_PATH_LEN], *sp;
- FILE *infp, *outfp;
- int r, npasses = 0;
- UNSIGNEDINT charcode;
-
- /* build the input and output file paths */
- strcpy(inpath, os_dir);
- strcat(inpath, os_file);
- strcpy(outpath, os_file);
- if ((sp = strrchr(outpath, '.')) == NULL)
- strcat(outpath, output_suffix);
- else
- strcpy(sp, output_suffix);
-
- /* rudimentary check for input overwriting output */
- if (strcmp(inpath, outpath) == 0)
- {
- fprintf(stderr, ERROR_OVERWRITE, os_dir, os_file);
- return;
- }
-
- if (!(infp = fopen(inpath, "rb")))
- {
- fprintf(stderr, ERROR_OPEN_READ_FAILED, os_dir, os_file);
- return;
- }
- if (!(outfp = fopen(outpath, "wb")))
- {
- fprintf(stderr, ERROR_OPEN_WRITE_FAILED, os_dir, os_file, outpath);
- fclose(infp);
- return;
- }
-
- /* copy the font header and load the characters into memory */
- while ((r = font_command_read(infp, &infc)) == OK)
- {
- switch(infc.command_type)
- {
- case FDC:
- if ((npasses = fdc_dj_to_lj(&infc, &outfc)) == ERROR)
- {
- ljchar_free_all();
- fclose(infp);
- fclose(outfp);
- return;
- }
- if (font_command_write(outfp, &outfc) == ERROR)
- {
- fprintf(stderr, ERROR_FILE_WRITE_FAILED, os_dir, os_file);
- ljchar_free_all();
- fclose(infp);
- fclose(outfp);
- return;
- }
- break;
- case CCC:
- charcode = infc.number;
- break;
- case CDC:
- if (ljchar_create(charcode, &infc) == ERROR)
- {
- ljchar_free_all();
- fclose(infp);
- fclose(outfp);
- return;
- }
- break;
- }
- }
-
- if (npasses > 0)
- {
- for (charcode = 0; charcode < sizeofarray(ljchars); charcode++)
- {
- if (ljchars[charcode].bitmap != NULL)
- {
- /* output the character code command */
- outfc.command_type = CCC;
- outfc.number = charcode;
- if (font_command_write(outfp, &outfc) == ERROR)
- {
- fprintf(stderr, ERROR_FILE_WRITE_FAILED, os_dir, os_file);
- ljchar_free_all();
- fclose(infp);
- fclose(outfp);
- return;
- }
-
- /* convert the character descriptor and bitmap */
- if (cdc_dj_to_lj(&ljchars[charcode], &outfc) == ERROR)
- {
- ljchar_free_all();
- fclose(infp);
- fclose(outfp);
- return;
- }
-
- /* output the character descriptor and bitmap */
- if (font_command_write(outfp, &outfc) == ERROR)
- {
- fprintf(stderr, ERROR_FILE_WRITE_FAILED, os_dir, os_file);
- ljchar_free_all();
- fclose(infp);
- fclose(outfp);
- return;
- }
- }
- }
- }
-
- if (npasses == 0 || r != EOF)
- /* error scenarios: (npasses == 0) means no font descriptor found,
- probably processing a text file; (r != EOF) means a font
- command escape sequence wasn't read in correctly, probably
- processing a binary file or a truncated soft font file */
- fprintf(stderr, ERROR_FILE_READ_FAILED, os_dir, os_file);
- else
- {
- fprintf(stderr, OK_JETD2L, os_dir, os_file, outpath);
- }
-
- ljchar_free_all();
- fclose(infp);
- fclose(outfp);
- }
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- char c;
-
- /* stop getopt() printing errors */
- opterr = FALSE;
- while ((c = getopt(argc, argv, "t:h")) != EOF)
- {
- switch (c)
- {
- case 't':
- strncpy(output_suffix+1, optarg, SUFFIX_MAX-2);
- output_suffix[SUFFIX_MAX-1] = '\0';
- break;
- case 'h':
- case '?':
- /* help required, or invalid option specified */
- usage_wrong();
- }
- }
-
- /* must specify at least one file */
- if (optind >= argc)
- usage_wrong();
-
- /* process file arguments */
- if (os_findfiles((argc - optind), &argv[optind]) == ERROR)
- fprintf(stderr, ERROR_OUT_OF_HEAP);
-
- while (os_getfile() != EOF)
- jetd2l();
-
- return(0);
- }
-