/*PrintFonts V1.10 (c)1989,1990 by Dave Schreiber.  All rights reserved*/
/*Must be freely distributed, except for shipping, copying, media, and*/
/*related costs.*/
/*V1.00 finished August 30, 1989*/
/*V1.10 finished January 21, 1990*/

/*    New features:  can print in more than one column
                     can determine the maximum number of columns to use
                     can print an alternate description of a font
                        (good for use with unreadable fonts like
                        Cairo or Music).
*/

/*Compiled using Lattice C V5.04*/

#include "setup.h"


int InterpretArgs();
WORD PrintPage();
void DumpWindowToPrinter();

main(argc,argv)
int argc;
char *argv[];
{
   struct AvailFontsHeader *afh;
   ULONG afhsize; /*Size of AvailFontsHeader buffer*/
   ULONG numfonts,curfont;
   BYTE max,readable,both;
   WORD columns;
   WORD maxlen;
   struct AvailFonts *af;
   
   if(argc==2 && argv[1][0]=='?')   /*User wants help*/
   {
      puts("PrintFonts V1.10");
      puts("(c)1989, 1990 by Dave Schreiber.  All rights reserved.");
      puts("Format for use:");
      puts("  1>  PrintFonts [options]");
      puts("Where options are any of the following:");
      puts("  -r:  Print each font's name in a readable format");
      puts(" -c#:  Use # number of columns");
      puts("  -m:  Determine the max number of columns that can be");
      puts("       used and do not print.");
      puts("  -b:  Determines the maximum number of columns and");
      puts("       prints using that number of columns");
      exit(0);
   }
   
      /*Parse the command line arguments and set the appropriate flags*/
   if(!InterpretArgs(argc,argv,&max,&readable,&columns,&both))
      exit(1000);

   if(columns<1)
   {
      puts("You must have at least one column!");
      exit(2000);
   }
   
   startup();  /*Open Libraries, etc.*/
   afhsize=AvailFonts(NULL,NULL,AFF_MEMORY|AFF_DISK);
   
   afh=(struct AvailFontsHeader *)AllocMem(afhsize,MEMF_CLEAR); 
      /*Gets a buffer large enough to hold all the font information*/
      /*(AvailFonts(0,0,[type]) returns the amount of memory needed*/
      /*to hold the information for all the fonts of type [type])  */

   if(afh==NULL)  /*Could't allocate the memory*/
   {
      closeup();
      ExitProg("Couldn't allocate enough memory!");
   }
   
   AvailFonts(afh,afhsize,0xff); /*Get the info for fonts*/

   TopazAttr.ta_Name="topaz.font"; /*Topaz is used if the user wants*/
   TopazAttr.ta_YSize=8;           /*'readable' font names*/
   TopazAttr.ta_Style=0;
   TopazAttr.ta_Flags=FPF_ROMFONT|FPF_DISKFONT;
   
   if((Topaz=(struct TextFont *)OpenFont(&TopazAttr))==NULL)
   {
      FreeMem(afh,afhsize);
      closeup();
      ExitProg("Can't open Topaz 8 point font!!!!!!!!!!!!");
   }
    
   numfonts=afh->afh_NumEntries;  /*Get the number of fonts*/
   curfont=1;                     /*First font*/
   af=(struct AvailFonts *)&afh[curfont];
   while(curfont <= numfonts)
      maxlen=PrintPage(&curfont,numfonts,af,columns,max,readable);
         
   maxlen=MAX_X/maxlen;
   if(maxlen < 1)
      maxlen=1;
      
   if(max)  /*If just finding the max length*/
   {
      printf("These fonts can be printed in %d column",maxlen);
      if(maxlen==1)
         printf(".\n");
      else
         printf("s.\n");
   }
   
   if(both) /*If -b switch, do it again, but print this time*/
   {
      curfont=1;
      af=(struct AvailFonts *)&afh[curfont];
      while(curfont <= numfonts)
         PrintPage(&curfont,numfonts,af,maxlen,FALSE,readable);
   }

   FreeMem(afh,afhsize);    /*Free up the allocated memory*/

   CloseFont(Topaz);
   closeup();
}

int InterpretArgs(argc,argv,max,readable,cols,both)
int argc;
char *argv[];
BYTE *max,*readable,*both;
WORD *cols;
{
   BYTE c;
   int columns;
   
   *cols=1;    /*Load in some defaults*/
   *max=FALSE;
   *readable=FALSE;
   *both=FALSE;
   
   for (c=1;c<argc;c++)    /*For each argument*/
      switch(argv[c][1])   /*Letter after the slash*/
      {
         case 'b':      /*For -b switch, set both*/
         case 'B':
            *both=TRUE; /*AND max*/
         case 'm':   /*Max columns mode*/
         case 'M':   /*Just in case the user typed -T instead of -t*/
            *max=TRUE;
            break;
         case 'r':   /*Readable*/
         case 'R':
            *readable=TRUE;
            break;
         case 'c':   /*Number of columns*/
         case 'C':
            if(argv[c][2]==NULL)
               break;
            stcd_i(&argv[c][2],&columns); /*Convert text to #*/
            *cols=columns;
            break;
         default:
            puts("I don't understand option:");
            puts(argv[c]);
            return(FALSE);
      }
   return(TRUE);
}

   /*Setup and print a page of fonts*/
WORD PrintPage(curfont,numfonts,af,cols,findmax,readable)
ULONG *curfont;
ULONG numfonts;
struct AvailFonts *af;
BYTE findmax,readable;
WORD cols;
{
   
#define FLAGS af->af_Attr.ta_Flags
#define Rp Wdw->RPort

   BYTE Full=FALSE;
   USHORT TextY=STARTINGROW;        /*Current Y coordinate*/
   USHORT LastY;                    /*Last Y coordinate*/
   static WORD max=0;
   WORD length;
   WORD column,StartX;
   WORD ColWidth;
   
   char Master[256],fontstr[256],SizeStr[6],*string;
   struct TextFont *tf;
   struct TextAttr TFont;

   ColWidth=MAX_X/cols; /*Get the # of pixels in each column*/
   
   string = (char *)&Master[1]; /*Initialize a pointer and*/
   Master[0]='(';       /*a string*/
   
   SetAPen(Rp,0);
   RectFill(Rp,0,0,MAX_X-1,MAX_Y-1);
   SetAPen(Rp,1);
   ClearScreen(Rp);     /*Clear the bitmap*/
   af+=(*curfont-1);
   
   
   for(column=StartX=0;column<cols && *curfont <= numfonts;
         StartX=(++column*ColWidth)) /*Loop for each column*/
   {
      TextY=STARTINGROW;
      Full=FALSE;
      
      while(!Full && (*curfont <= numfonts))
      {      
         /*If the font is:  not removed, goes from left to right*/
         /*and is EITHER a disk or memory font, do nothing.*/
         /*(This is partly from the RKM)*/
         if((af->af_Attr.ta_Style==0) &&
         !( ((FLAGS & FPF_REMOVED)||(FLAGS & FPF_REVPATH) ||
               ((FLAGS & FPF_DISKFONT) && (af->af_Type & AFF_MEMORY))) ) )
            if((af->af_Attr.ta_YSize) < (MAX_Y-(4+TextY))) /*If it'll fit...*/
            {
            
               TFont.ta_Name=(char *)af->af_Attr.ta_Name;  /*Get the name*/
               TFont.ta_YSize=af->af_Attr.ta_YSize; /*Get the size*/
               TFont.ta_Style=af->af_Attr.ta_Style; /*Plain style*/
               TFont.ta_Flags=FPF_ROMFONT|FPF_DISKFONT|
                     FPF_PROPORTIONAL|FPF_DESIGNED;  /*Straight from RKM*/
            
               if((tf=(struct TextFont *)OpenDiskFont(&TFont))!=NULL)
               {
                     /*Position 'cursor' at baseline*/
                  TextY+=(LastY=(tf->tf_Baseline));
                  strcpy(fontstr,af->af_Attr.ta_Name);
                  strcpy(string,fontstr);  /*Get font name*/
                  string[strlen(string)-5]=NULL;
                  strcat(string," ");      /*Tack on a space*/
                  stcu_d(SizeStr,af->af_Attr.ta_YSize); /*Get the size in chars*/
                  strcat(string,SizeStr);
                  strcat(string," ");
                  
                  Move(Rp,StartX,TextY);               
                  SetFont(Rp,tf);      /*Set the font*/
                  Text(Rp,string,strlen(string));  /*Print the font info*/
               
                        /*Get the length of the text string in pixels*/
                  length=TextLength(Rp,string,strlen(string));
                  
                  if(readable) /*If -r switch...*/
                  {
                     Master[strlen(Master)-1]=')';
                     SetFont(Rp,Topaz);
                     Text(Rp,Master,strlen(Master));
                     length+=TextLength(Rp,Master,strlen(Master));
                  }
                  
                  if(length > max)
                     max=length; /*And store in max if the biggest*/
   
                     /*Add decender area to height*/
                  TextY+=(LastY=(tf->tf_YSize-tf->tf_Baseline+2));
                  CloseFont(tf);   /*Close the font*/
               }
               (*curfont)++;
               af++;
            }
            else
               Full = TRUE;
         else     
         {
            (*curfont)++;
            af++;
         }  
      }
   }
   
   if(!findmax)   /*Print fonts if -m switch isn't set*/
      DumpWindowToPrinter(Wdw,printerMsg,
            (TextY+LastY>MAX_Y ? MAX_Y : TextY+LastY));
   /*Add a little for serifs, but not more than MAX_Y*/
   return(max); /*And return the max text length*/
}

void DumpWindowToPrinter(Wdw,request,LastY)
struct Window *Wdw;
union printerIO *request;
USHORT LastY;
{
   struct ViewPort *Vp;
   char FormFeed[2];
   FormFeed[0]=0x0c;       /*Form feed character*/
   FormFeed[1]=NULL;       /*NULL terminator*/
   Vp=&Wdw->WScreen->ViewPort;
   /*Set up for dumping the rastport*/
   request->iodrp.io_Command=PRD_DUMPRPORT;
   request->iodrp.io_RastPort=Rp;
   request->iodrp.io_ColorMap=Vp->ColorMap;
   request->iodrp.io_Modes=Vp->Modes;
   request->iodrp.io_SrcX=0;
   request->iodrp.io_SrcY=0;
   request->iodrp.io_SrcWidth=MAX_X;
   request->iodrp.io_SrcHeight=MAX_Y;
   request->iodrp.io_DestCols=0;
   request->iodrp.io_DestRows=0;
   request->iodrp.io_Special=SPECIAL_FULLCOLS|
            SPECIAL_FULLROWS;
   DoIO(request); /*Do the actual dump*/
   
   /*Do a form feed*/
   /*Perhaps this extra step is unnecessary, but I find it works better*/
   /*with my setup (DeskJet+ and Epson LX-800) than leaving out this and*/
   /*the SPECIAL_NOFORMFEED switch above*/
#ifdef FFEW
   request->ios.io_Command=CMD_WRITE;
   request->ios.io_Data=(APTR)FormFeed;
   request->ios.io_Length=-1;  /*-1 == NULL terminated string*/
   DoIO(request); /*Do the form feed*/
#endif
}

