/* Program to format font IMPAIRED for downloading into a H-P LaserJet2     */
/* printer                                                                  */

/* Coded in Microsoft C 5.1 by Daniel Ross, starting 3/11/88                */
/* Revised 10/10/88    15:30                                                 */

/* Although not explicitly stated in any H-P manual, this code is written    */
/* with the assumption that the MSB of a word is sent before the LSB.        */

#include <STDLIB.H>
#include <STDIO.H>
#include <STRING.H>
#include <MATH.H>
/* More files are included below                                             */

#define IMPAIREDColsPerChar         29
#define IMPAIREDSpaceCols           25
#define IMPAIREDRowsAboveBaseLine   31
#define IMPAIREDDescenderRows       0
#define IMPAIREDRowsPerChar (IMPAIREDRowsAboveBaseLine + IMPAIREDDescenderRows)
#define ColsSeparatingChars         7

long   IMPAIRED [128] [IMPAIREDRowsPerChar]   =
  {
#include "IMPAIRED.C"
  } ;

#define FALSE               0
#define TRUE                1
#define TorF                int

#define Escape              0x1B

#define FontIDNr            13

int     CurrentCharIndex ;
long    CurrentCharPattern [IMPAIREDRowsPerChar] ;
int     BlankRowsOnTop ;
int     BlankRowsOnBottom ;
int     BlankColsOnRight ;
int     PatternWidth_Dots ;
int     PatternWidth_Bytes ;
int     PatternHeight ;
int     TotalPatternBytes ;
FILE    * FileHandle ;
char    FileName []   =   "IMPAIRED.LOD" ;

void   CopyToCurrentCharPattern (void)
  {
    static int   RowIndex ;
    for (RowIndex = 0 ;   RowIndex < IMPAIREDRowsPerChar ;   ++ RowIndex)
      CurrentCharPattern [RowIndex]   =
        IMPAIRED [CurrentCharIndex] [RowIndex];
  }

void   CalcBlankRowsOnTop (void)
  {
    for
      (
        BlankRowsOnTop = 0
          ;
        BlankRowsOnTop < IMPAIREDRowsPerChar
          ;
        ++ BlankRowsOnTop
      )
      {
        if (CurrentCharPattern [BlankRowsOnTop])   return ;
      } ;
  }

void   CalcBlankRowsOnBottom (void)
  {
    for
      (
        BlankRowsOnBottom = 0
          ;
        BlankRowsOnBottom < IMPAIREDRowsPerChar
          ;
        ++ BlankRowsOnBottom
      )
      {
        if (CurrentCharPattern [(IMPAIREDRowsPerChar - 1) - BlankRowsOnBottom])
          return ;
      } ;
  }

void   CalcBlankColsOnRight (void)
  {
    static int    RowIndex ;
    static long   Mask ;
    for
      (
        BlankColsOnRight = 0
          ;
        BlankColsOnRight < IMPAIREDColsPerChar
          ;
        ++ BlankColsOnRight
      )
      {
        Mask   =   0x80000000 >> (31 - BlankColsOnRight) ;
        for (RowIndex = 0 ;   RowIndex < IMPAIREDRowsPerChar ;   ++ RowIndex)
          {
            if (CurrentCharPattern [RowIndex] & Mask)   return ;
          } ;
      } ;
  }

void   JustifyTheCurrentCharPattern (void)
  {
    static int   RowIndex ;
    if (BlankRowsOnTop)
      {
        for
          (
            RowIndex = 0
              ;
            RowIndex < (IMPAIREDRowsPerChar - BlankRowsOnTop)
              ;
            ++ RowIndex
          )
          CurrentCharPattern [RowIndex]   =
            CurrentCharPattern [RowIndex + BlankRowsOnTop] ;
      } ;
  }

void   CalcPatternSizeToSend (void)
  {
    PatternWidth_Dots      = 32 - BlankColsOnRight ;
    PatternWidth_Bytes     =   (PatternWidth_Dots + 7) / 8 ;
    PatternHeight          =
      IMPAIREDRowsPerChar  - BlankRowsOnTop  - BlankRowsOnBottom ;
    TotalPatternBytes      =   PatternWidth_Bytes * PatternHeight ;
  }

void   Print1Byte (int TheByte)
  {
    fprintf (FileHandle, "%c", TheByte & 0xFF) ;
  }

void   Print1Word (int TheWord)
  {
    Print1Byte (TheWord >> 8) ;
    Print1Byte (TheWord) ;
  }

void   PrintTheFontDescriptor (void)
  {
    Print1Word (64) ;                   /* Font descriptor size              */
    Print1Word (0) ;                    /* Reserved byte & font type         */
    Print1Word (0) ;                    /* Reserved word                     */
    Print1Word (IMPAIREDRowsAboveBaseLine - 1) ;
    Print1Word (IMPAIREDColsPerChar) ;
    Print1Word (IMPAIREDRowsPerChar) ;
    Print1Word (1) ;                    /* Orientation & spacing             */
    Print1Word (21) ;                   /* Symbol set                        */
    Print1Word ((IMPAIREDSpaceCols + ColsSeparatingChars) * 4) ;    /* Pitch */
    Print1Word (IMPAIREDRowsPerChar*4); /* Height                            */
    Print1Word (IMPAIREDRowsPerChar*4); /* x height                          */
    Print1Word (0) ;                    /* Width type & style                */
    Print1Word (0) ;                    /* Stroke weight & typeface          */
    Print1Word (2) ;                    /* Reserved byte & serif style       */
    Print1Word (0) ;                    /* Reserved word                     */
    Print1Word (((-3)<<8) + 3) ;        /* Underline distance & height       */
    Print1Word (40 * 4) ;               /* Text height                       */
    Print1Word ((IMPAIREDColsPerChar + ColsSeparatingChars) * 4); /* T width */
    Print1Word (0) ;                    /* Reserved word                     */
    Print1Word (0) ;                    /* Reserved word                     */
    Print1Word (0) ;                    /* Pitch & height extended           */
    Print1Word (0) ;                    /* Reserved word                     */
    Print1Word (0) ;                    /* Reserved word                     */
    Print1Word (0) ;                    /* Reserved word                     */
    fprintf (FileHandle, "%16s", "Impaired        ") ;
  }

void   main (void)
  {
    static int      RowIndex, ByteIndex ;
    static long     CurrentLong ;
    if ( ! (FileHandle = fopen (FileName, "wb")))
      {
        printf ("\nUnable to open font file %s", FileName) ;
        exit (1) ;
      } ;
    /* Print the command to reset the printer                                */
    fprintf (FileHandle, "%cE", Escape) ;
    /* Print the command to select the font                                  */
    fprintf (FileHandle, "%c*c%dD", Escape, FontIDNr) ;
    /* Print the command that precedes the font descriptor                   */
    fprintf (FileHandle, "%c)s64W", Escape) ;
    PrintTheFontDescriptor () ;
    for
      (
        CurrentCharIndex =  '!'
          ;
        CurrentCharIndex != 128
          ;
        ++ CurrentCharIndex
      )
      {
        /* Print the command that selects the character                      */
        fprintf (FileHandle, "%c*c%dE", Escape, CurrentCharIndex) ;
        CopyToCurrentCharPattern        () ;
        CalcBlankRowsOnTop              () ;
        CalcBlankRowsOnBottom           () ;
        CalcBlankColsOnRight            () ;
        JustifyTheCurrentCharPattern    () ;
        CalcPatternSizeToSend           () ;
        /* Print the command that precedes the character descriptor          */
        fprintf
          (
            FileHandle
              ,
            "%c(s%dW"
              ,
            Escape
              ,
            16 + TotalPatternBytes
          ) ;
        /* Print the character descriptor                                    */
        Print1Word ((4<<8) + 0) ;       /* Format & continuation             */
        Print1Word ((14<<8) + 1) ;      /* Descriptor size & class           */
        Print1Word (0) ;                /* Orientation & reserved byte       */
        Print1Word (0) ;                /* Left offset                       */
        Print1Word (IMPAIREDRowsAboveBaseLine - BlankRowsOnTop - 1) ;
        Print1Word (PatternWidth_Dots) ;
        Print1Word (PatternHeight) ;
        Print1Word ((PatternWidth_Dots + ColsSeparatingChars) * 4) ;   /* dX */
        for (RowIndex = 0 ;   RowIndex != PatternHeight ;   ++ RowIndex)
          {
            CurrentLong   =   CurrentCharPattern [RowIndex] ;
            for
              (
                ByteIndex =  0
                  ;
                ByteIndex != PatternWidth_Bytes
                  ;
                ++ ByteIndex
              )
              Print1Byte ((int) (CurrentLong >> (24 - (ByteIndex * 8)))) ;
          } ;
      } ;
    /* Print the command that makes the font permanent                       */
    fprintf (FileHandle, "%c*c5F", Escape) ;
    /* Print the command that makes the font to be the primary selected font */
    fprintf (FileHandle, "%c(%dX", Escape, FontIDNr) ;
    /* Print the command to set vertical motion index                        */
    fprintf (FileHandle, "%c&l6.4C", Escape) ;
    if (fclose (FileHandle))
      {
        printf ("\nError closing font file %s", FileName) ;
        exit (1) ;
      } ;
    exit (0) ;
  }

/* End of file                                                              */
