/* Font-Converter V1.11d
 * -------------------
 * Formt die Amiga-Fonts
 * in NEC P6-Fonts um.
 * Anpassung an andere
 * Drucker möglich,da
 * sämtliche Control-
 * Sequences als Variablen
 * definiert sind.
 * Deutsche Texte; unterstützt
 * deutschen Zeichensatz
 * -------------------
 * © 1988 by Tim Pietzcker Software
 * Diese Version 29.12.88 (winzige Änderung : das FontSize-Gadget wird
 * automatisch angewählt und muß nicht extra angeklickt werden (Kludge !) )
 */

#include <intuition/intuition.h>
#include <exec/types.h>
#include <graphics/gfxbase.h>
#include <graphics/text.h>
#include <libraries/diskfont.h>
#include <stdio.h>

#define FNAME 1l     /* Das sind die Gadget-ID's */
#define FSIZE 2l
#define LOAD 3l
#define EH1 4l
#define EH2 5l
#define EH3 6l
#define EV1 7l
#define EV2 8l
#define EV3 9l
#define LSPACE 10l
#define LSDEF 11l
#define OUTPRT 12l
#define OUTFILE 13l
#define FILENAME 14l
#define START 15l
#define TEST 16l
#define QUIT 17l
#define GERM 18l

/* jetzt alle benötigten Printer-Control-Sequences */
/* Der erste Wert stellt jeweils die Anzahl der Steuerzeichen dar */

char setlqpr[] = { 3,27,33,2 };   /* schalte Proportionalschrift ein und
                                     alle Styles (Italic etc.) aus */
char reset[]   = { 2,27,64 };      /* Druckerreset */
char setlf[]   = { 2,27,65 };      /* Zeilenvorschub einstellen (danach folgt
                                      Abstand in 1/60 Zoll-Einheiten ) */
char copyint[] = { 5,27,58,0,0,0 };/* kopiere den internen Zeichensatz in den
                                      benutzerdefinierten Speicher */
char loadcset[]= { 3,27,38,0 };    /* lade neuen Zeichensatz (danach folgen
                                      die Anfangs- und EndASCII-Werte) */
char usercset[]= { 3,27,37,1 };    /* schalte den Benutzer-Zeichensatz ein */
char setgerm[] = { 3,27,82,2 };    /* schalte deutschen Zeichensatz ein */
char cr[] = { 13,0 };

/* jetzt die Puffer für die String-Gadgets */

UBYTE fname[30];     /* Font Name */
UBYTE fsize[4];      /* Font Size */
UBYTE filename[61];  /* Filename des von Font-Converter erstellten Files */
UBYTE lspacestr[4]="8"; /* Line Spacing */
UBYTE undobuf[61];   /* Puffer für Undo (geht mit rechte-Amiga-Q) */

FILE *fopen();       /* öffne File */
FILE *parout,*fileout; /* Dateizeiger */
char *strcat(),*strcpy();     /* stdio-Routinen */
char firstchar,lastchar,linespace;  /* Steuerdaten */
long german,topar,tofile,setspace,fsent,fontopen;   /* Kontrollflags */
int henl,venl,val_henl,val_venl;    /* gewählte und gültige
                                       Vergrößerung des Fonts */
short  AutoRequest(),ReadPixel();     /* System-Routinen */
struct IntuitionBase *IntuitionBase;   /* Zeiger -> Intuition */
struct DiskfontBase  *DiskfontBase;    /*   "    -> Diskfonts */  
struct GfxBase       *GfxBase;         /*   "    -> Graphics */
struct Library       *OpenLibrary();   /* für Aztec 16-bit */
struct Window        *OpenWindow(),*MyWindow;   /* s.o.,Zeiger -> Window */
struct IntuiMessage  *GetMsg(),*msg;   /* s.o.,Zeiger -> Message */
struct RastPort      *rp;              /* Zeiger -> RPort */
struct TextFont      *OpenFont(),*OpenDiskFont(),*NormFont,*ConvFont;
struct TextAttr      MyFont =
                     {  (UBYTE *)"topaz.font",
                        TOPAZ_EIGHTY,FS_NORMAL,FPF_ROMFONT };
                     /* für den Fall,daß 60-Zeichen-Mode gewählt */
struct TextAttr      BoldFont =
                     {  (UBYTE *)"topaz.font",
                        TOPAZ_EIGHTY,FSF_BOLD,FPF_ROMFONT };
struct TextAttr TA;
char comment[14][31]={  " Ich finde diesen Font nicht! ",
                        "   Dieser Font ist zu groß!   ",
                        "Ich kann nicht zu PAR: senden!",
                        "Ich kann nicht zum File senden",
                        "   Hey,kein File gewählt !!   ",
                        "Wohin soll ich ausgeben,bitte?",
                        "Zeilenabstand muß zw. 0 & 128!",
                        "   ....Ich lade den Font....  ",
                        "...Ich wandle die Zeichen um..",
                        "           Fertig !!          ",
                        "   Diese Größe ist ungültig!  ",
                        "  Erst zum Printer ausgeben!  ",
                        " Bitte erst einen Font laden! ",
                        "           READY !!           " };
int power[]= { 1,2,4,8,16,32,64,128 };   /* statt Bitshift (>>) aus Zeit-
                                             gründen */
/* jetzt alle Gadgets ....(nacheinander aber erst die Borders,IntuiTexts,
   StringInfos und den ganzen restlichen Kleinkram ... */

struct IntuiText TextLOAD =
   { 1,0,JAM1,0,0,&MyFont,(UBYTE *)"Lade Font!",NULL };
struct IntuiText TextEHV1 =
   { 1,0,JAM1,4,0,&MyFont,(UBYTE *)"1x",NULL };
struct IntuiText TextEHV2 =
   { 1,0,JAM1,4,0,&MyFont,(UBYTE *)"2x",NULL };
struct IntuiText TextEHV3 =
   { 1,0,JAM1,4,0,&MyFont,(UBYTE *)"3x",NULL };

struct IntuiText TextLSDEF =
   { 1,0,JAM1,16,0,&MyFont,(UBYTE *)"Normal",NULL };

struct IntuiText TextOUTPRT =
   { 1,0,JAM1,16,0,&MyFont,(UBYTE *)"Printer",NULL };
struct IntuiText TextOUTFILE =
   { 1,0,JAM1,0,0,&MyFont,(UBYTE *)" Datei ",NULL };

struct IntuiText TextSTART =
   { 1,0,JAM1,20,0,&BoldFont,(UBYTE *)"Start !",NULL };

struct IntuiText TextTEST1 =
   { 1,0,JAM1,0,4,&MyFont,(UBYTE *)"TESTE DEN",NULL };
struct IntuiText TextTEST =
   { 1,0,JAM1,20,13,&MyFont,(UBYTE *)"FONT",&TextTEST1 };
struct IntuiText TextQUIT =
   { 1,0,JAM1,20,8,&BoldFont,(UBYTE *)"ENDE",NULL };
struct IntuiText TextGERM =
   { 1,0,JAM1,16,0,&MyFont,(UBYTE *)"Deutsch",NULL };

SHORT Koord1[] = {  -2,9, -2,-2, 146,-2, 146,9, -2,9, 0,9, 0,10,
                     148,10, 148,-1, 147,-1, 147,9 };
SHORT Koord2[] = {  -2,9, -2,-2, 26,-2, 26,9, -2,9, 0,9, 0,10,
                     28,10, 28,-1, 27,-1, 27,9 };
SHORT Koord3[] = {  -2,9, -2,-2, 82,-2, 82,9, -2,9, 0,9, 0,10,
                     84,10, 84,-1, 83,-1, 83,9 };
SHORT Koord4[] = {  -2,9, -2,-2, 90,-2, 90,9, -2,9, 0,9, 0,10,
                     92,10, 92,-1, 91,-1, 91,9 };
SHORT Koord5[] = {  -2,9, -2,-2, 58,-2, 58,9, -2,9, 0,9, 0,10,
                     60,10, 60,-1, 59,-1, 59,9 };
SHORT Koord6[] = {  -2,9, -2,-2, 98,-2, 98,9, -2,9, 0,9, 0,10,
                     100,10, 100,-1, 99,-1, 99,9 };
SHORT Koord7[] = {  -2,25, -2,-2, 74,-2, 74,25, -2,25, 0,25, 0,26,
                     76,26, 76,-1, 75,-1, 75,25 };
SHORT Koord8a[]= {  -2,-2, 242,-2, 242,9, -2,9, -2,-2 };
SHORT Koord8[] = {  -1,-1, 241,-1, 241,8, -1,8, -1,-1 };
SHORT Koord9[] = {  -2,-2, 50,-2, 50,25, -2,25, -2,-2 };

struct Border Border1 =
   { 0l,0l,1l,0l,JAM1,11l,Koord1,NULL };
struct Border Border2 =
   { 0l,0l,1l,0l,JAM1,11l,Koord2,NULL };
struct Border Border3 =
   { 0l,0l,1l,0l,JAM1,11l,Koord3,NULL };
struct Border Border4 =
   { 0l,0l,1l,0l,JAM1,11l,Koord4,NULL };
struct Border Border5 =
   { 0l,0l,1l,0l,JAM1,11l,Koord5,NULL };
struct Border Border6 =
   { 0l,0l,1l,0l,JAM1,11l,Koord6,NULL };
struct Border Border7 =
   { 0l,0l,1l,0l,JAM1,11l,Koord7,NULL };
struct Border Border8a=
   { 0l,0l,0l,0l,JAM1,5l,Koord8a,NULL };
struct Border Border8 =
   { 0l,0l,3l,0l,JAM1,5l,Koord8,&Border8a };
struct Border Border9 =
   { 0l,0l,1l,0l,JAM1,5l,Koord9,NULL };

struct StringInfo SInfoFNAME =
   { fname,undobuf,NULL,30l,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
struct StringInfo SInfoFSIZE =
   { fsize,undobuf,NULL,4l,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
struct StringInfo SInfoLSPACE =
   { lspacestr,undobuf,NULL,4l,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
struct StringInfo SInfoFILENAME =
   { filename,undobuf,NULL,61l,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
     NULL };

struct Gadget GadEH1 =
   { NULL,128,47,24,8,GADGHCOMP|SELECTED,GADGIMMEDIATE,BOOLGADGET,
      (APTR)&Border2,NULL,&TextEHV1,NULL,NULL,EH1,NULL };
struct Gadget GadEH2 =
   { &GadEH1,176,47,24,8,GADGHCOMP,GADGIMMEDIATE,BOOLGADGET,
      (APTR)&Border2,NULL,&TextEHV2,NULL,NULL,EH2,NULL };
struct Gadget GadEH3 =
   { &GadEH2,224,47,24,8,GADGHCOMP,GADGIMMEDIATE,BOOLGADGET,
      (APTR)&Border2,NULL,&TextEHV3,NULL,NULL,EH3,NULL };
struct Gadget GadEV1 =
   { &GadEH3,128,62,24,8,GADGHCOMP|SELECTED,GADGIMMEDIATE,BOOLGADGET,
      (APTR)&Border2,NULL,&TextEHV1,NULL,NULL,EV1,NULL };
struct Gadget GadEV2 =
   { &GadEV1,176,62,24,8,GADGHCOMP,GADGIMMEDIATE,BOOLGADGET,
      (APTR)&Border2,NULL,&TextEHV2,NULL,NULL,EV2,NULL };
struct Gadget GadEV3 =
   { &GadEV2,224,62,24,8,GADGHCOMP,GADGIMMEDIATE,BOOLGADGET,
      (APTR)&Border2,NULL,&TextEHV3,NULL,NULL,EV3,NULL };
struct Gadget GadFNAME =
   { &GadEV3,104,14,144,8,GADGHCOMP,RELVERIFY|STRINGCENTER,STRGADGET,
      (APTR)&Border1,NULL,NULL,NULL,(APTR)&SInfoFNAME,FNAME,NULL };
struct Gadget GadFSIZE =
   { &GadFNAME,104,29,24,8,GADGHCOMP,LONGINT,STRGADGET,
      (APTR)&Border2,NULL,NULL,NULL,(APTR)&SInfoFSIZE,FSIZE,NULL };
struct Gadget GadLOAD =
   { &GadFSIZE,168,29,80,8,GADGHCOMP,RELVERIFY,BOOLGADGET,
      (APTR)&Border3,NULL,&TextLOAD,NULL,NULL,LOAD,NULL };
struct Gadget GadLSPACE =
   { &GadLOAD,128,80,24,8,GADGHCOMP,LONGINT,
      STRGADGET,(APTR)&Border2,NULL,NULL,NULL,(APTR)&SInfoLSPACE,LSPACE,
      NULL };
struct Gadget GadLSDEF =
   { &GadLSPACE,168,80,80,8,GADGHCOMP|SELECTED,TOGGLESELECT|RELVERIFY,
      BOOLGADGET,(APTR)&Border3,NULL,&TextLSDEF,NULL,NULL,LSDEF,NULL };
struct Gadget GadOUTPRT =
   { &GadLSDEF,156,100,88,8,GADGHCOMP|SELECTED,TOGGLESELECT|RELVERIFY,
      BOOLGADGET,(APTR)&Border4,NULL,&TextOUTPRT,NULL,NULL,OUTPRT,NULL };
struct Gadget GadOUTFILE =
   { &GadOUTPRT,32,115,56,8,GADGHCOMP,TOGGLESELECT|RELVERIFY,BOOLGADGET,
      (APTR)&Border5,NULL,&TextOUTFILE,NULL,NULL,OUTFILE,NULL };
struct Gadget GadFILENAME =
   { &GadOUTFILE,104,115,144,8,GADGHCOMP,NULL,STRGADGET,
      (APTR)&Border1,NULL,NULL,NULL,(APTR)&SInfoFILENAME,FILENAME,NULL };
struct Gadget GadSTART =
   { &GadFILENAME,152,134,96,8,GADGHCOMP,RELVERIFY,BOOLGADGET,
      (APTR)&Border6,NULL,&TextSTART,NULL,NULL,START,NULL };
struct Gadget GadTEST =
   { &GadSTART,16,161,72,24,GADGHCOMP,RELVERIFY,BOOLGADGET,
      (APTR)&Border7,NULL,&TextTEST,NULL,NULL,TEST,NULL };
struct Gadget GadGERM =
   { &GadTEST,8,134,88,8,GADGHCOMP|SELECTED,TOGGLESELECT|RELVERIFY,
      BOOLGADGET,(APTR)&Border4,NULL,&TextGERM,NULL,NULL,GERM,NULL };
struct Gadget GadQUIT =
   { &GadGERM,168,161,72,24,GADGHCOMP,RELVERIFY,BOOLGADGET,
      (APTR)&Border7,NULL,&TextQUIT,NULL,NULL,QUIT,NULL };

/* Uff ! */

struct NewWindow TheWindow =
{
   190,0,               /* links oben */
   256,190,             /* Breite,Höhe */
   3,2,                 /* Detail- BlockPen */
   GADGETDOWN|GADGETUP, /* IDCMP-Flags */
   WINDOWDRAG|WINDOWDEPTH|SMART_REFRESH|ACTIVATE, /* Flags */
   &GadQUIT,            /* FirstGadget */
   NULL,                /* CheckMark */
   (UBYTE *)"Font-Converter © 1988 TPS",  /* Titel */
   NULL,NULL,           /* Screen,BitMap */
   0,0,0,0,             /* Sizing */
   WBENCHSCREEN,        /* Typ */
};
/* für meinen AutoRequester : */
struct IntuiText BodyText =
   { 1,0,COMPLEMENT,10,6,&MyFont,
     (UBYTE *)"Wollen Sie sicher aufhören ?",NULL };
struct IntuiText PosText  =
   { 1,0,COMPLEMENT,5,3,&MyFont,(UBYTE *)"Ja,aufhören!",NULL };
struct IntuiText NegText  =
   { 1,0,COMPLEMENT,5,3,&BoldFont,(UBYTE *)"Oh nein!",NULL };

openstuff()
{
   if((IntuitionBase = (struct IntuitionBase *)
      OpenLibrary("intuition.library",0l))==NULL) exit(FALSE);
   if((DiskfontBase = (struct DiskfontBase *)
      OpenLibrary("diskfont.library",0l))==NULL) exit(FALSE);
   if((GfxBase = (struct GfxBase *)
      OpenLibrary("graphics.library",0l))==NULL) exit(FALSE);
   if((MyWindow=OpenWindow(&TheWindow))==NULL) exit(FALSE);
   rp=MyWindow->RPort;
   NormFont=OpenFont(&MyFont);   /* da ich öfters zwischen dem Systemfont
                                    und dem geladenen Font umschalten muß */
   ConvFont=OpenFont(&MyFont);   /* zur Sicherheit */
}

init_all()  /* mache das Window startbereit */
{
   SetFont(rp,NormFont);
   SetAPen(rp,2l);
   RectFill(rp,0l,10l,255l,188l);
   RefreshGadgets(&GadQUIT,MyWindow,NULL);
   SetDrMd(rp,JAM1);
   SetAPen(rp,3l);            /* Text erst in Farbe 3 (orange (?)) */
   Move(rp,9l,21l);
   Text(rp,(UBYTE *)"Font-Name :",11l);
   Move(rp,9l,36l);
   Text(rp,(UBYTE *)"Fontgröße :",11l);
   Move(rp,9l,54l);
   Text(rp,(UBYTE *)"x-Vergrößerung",14l);
   Move(rp,9l,69l);
   Text(rp,(UBYTE *)"y-Vergrößerung",14l);
   Move(rp,9l,87l);
   Text(rp,(UBYTE *)"Zeilenabstand",13l);
   Move(rp,9l,107l);
   Text(rp,(UBYTE *)"Ausgabe geht zu :",17l);
   Move(rp,9l,122l);
   Text(rp,(UBYTE *)"in",2l);

   Move(rp,2l,41l);        /* Trennlinien */
   Draw(rp,253l,41l);
   Move(rp,2l,43l);
   Draw(rp,253l,43l);
   Move(rp,2l,74l);
   Draw(rp,253l,74l);
   Move(rp,2l,76l);
   Draw(rp,253l,76l);
   Move(rp,2l,93l);
   Draw(rp,253l,93l);
   Move(rp,2l,95l);
   Draw(rp,253l,95l);
   Move(rp,2l,128l);
   Draw(rp,253l,128l);
   Move(rp,2l,130l);
   Draw(rp,253l,130l);

   SetAPen(rp,1l);         /* und jetzt in Farbe 1 (weiß (?)) */
   Move(rp,8l,20l);
   Text(rp,(UBYTE *)"Font-Name :",11l);
   Move(rp,8l,35l);
   Text(rp,(UBYTE *)"Fontgröße :",11l);
   Move(rp,8l,53l);
   Text(rp,(UBYTE *)"x-Vergrößerung",14l);
   Move(rp,8l,68l);
   Text(rp,(UBYTE *)"y-Vergrößerung",14l);
   Move(rp,8l,86l);
   Text(rp,(UBYTE *)"Zeilenabstand",13l);
   Move(rp,8l,106l);
   Text(rp,(UBYTE *)"Ausgabe geht zu :",17l);
   Move(rp,8l,121l);
   Text(rp,(UBYTE *)"in",2l);

   DrawBorder(rp,&Border8,8l,148l);
   DrawBorder(rp,&Border9,104l,162l);
   SetAPen(rp,0l);
   RectFill(rp,104l,162l,152l,185l);
   SetAPen(rp,1l);
   topar=TRUE;
   parout=fopen("PRT:","w");     /* lade das Printer Device,damit es nachher
                                    nicht die eingestellten Werte rückgängig
                                    machen kann */
   send_out(cr,1);
   fclose(parout);
   topar=FALSE;
   print_message(13);
}

print_message(i)
int i;
{
   SetFont(rp,NormFont);
   SetAPen(rp,2l);
   RectFill(rp,8l,148l,247l,155l);
   SetAPen(rp,1l);
   Move(rp,8l,154l);
   Text(rp,comment[i],30l);
}

GadMXSel(win,gad1,gad2,gad3)        /* Diese Routine löst das Mutual-
                                       Exclude-Problem der `Enlarge'-Gadgs.
                                       Sie wurde leicht verändert von
                                       Willy Langeveld (Fish-Disk 52)
                                       übernommen (DANKE !!) */
struct Window *win;
struct Gadget *gad1,*gad2,*gad3;
{
   static struct Gadget *gadprev;

   gadprev=NULL;
   if (gad1->Flags & SELECTED) return;       /* finde das zuvor selek- */
   if (gad2->Flags & SELECTED) gadprev=gad2; /* tierte Gadget */
   if (gad3->Flags & SELECTED) gadprev=gad3;

   GadMXD(win,gad1,gadprev);
}

GadMXD(win,gad1,gad2)   /* Diese Routine selektiert gad1 und deselektiert
                           gad2. */
struct Window *win;
struct Gadget *gad1,*gad2;
{
   /* Erst gad2 selektieren (ja!) und refreshen */
   RemoveGadget(win,gad2);
   gad2->Flags |= SELECTED;
   AddGadget(win,gad2,-1l);
   RefreshGadgets(gad2,win,NULL);

   /* Jetzt gad1 an und gad2 aus und nochmal refreshen */

   RemoveGadget(win,gad1);
   gad1->Flags |= SELECTED;
   AddGadget(win,gad1,-1l);

   RemoveGadget(win,gad2);
   gad2->Flags &= ~SELECTED;
   AddGadget(win,gad2,-1l);

   RefreshGadgets(gad1,win,NULL);
}

load_font(name,size)         /* lade den gewählten Font von Disk */
char name[40],size[4];
{
   char *path;
   path="                                      ";
   if(fontopen==TRUE)
   {
      CloseFont(ConvFont);
      fontopen=FALSE;
   }
   if (name[0]==NULL) return(4);       /* Error check */
   if (atoi(size)<=NULL) return(10);
   if (atoi(size)>24) return(1);

   strcpy(path,name);
   path = strcat(path,".font");
   TA.ta_Name=(STRPTR)path;
   TA.ta_YSize=(UWORD)(atoi(size));
   TA.ta_Style=FS_NORMAL;
   TA.ta_Flags=FPF_DISKFONT;

   print_message(7);
   if ((ConvFont=OpenDiskFont(&TA))==NULL) return (0);
   fontopen=TRUE;
   if (ConvFont->tf_XSize > 37)
   {
      CloseFont(ConvFont);
      fontopen=FALSE;
      return(1);
   }
   reset_mxgads();
   adjust_to_size((int)(ConvFont->tf_XSize),(int)(ConvFont->tf_YSize));
   return (-1);
}

reset_mxgads()             /* da jeder Font unterschiedliche Eigenschaften
                              hat,müssen die Vergrößerungs-Gadgets jedes Mal
                              neu initialisiert werden */
{
   GadMXSel(MyWindow,&GadEH1,&GadEH2,&GadEH3);
   GadMXSel(MyWindow,&GadEV1,&GadEV2,&GadEV3);

   henl=1,venl=1; /* Vergrößerung zurücksetzen */
   val_henl=1,val_venl=1;  /* erlaubte Werte zurücksetzen */

}

adjust_to_size(xsize,ysize)   /* je nach Fontgröße Vergrößerungen erlauben*/
int xsize,ysize;
{
   if (xsize<19) val_henl=2;
   if (xsize<13) val_henl=3;

   if (ysize<13) val_venl=2;
   if (ysize<9)  val_venl=3;
}

open_output(oppar,opfile)  /* je nach Wahl öffne Drucker, File oder beide */
long oppar,opfile;
{
   if (oppar == TRUE)
      if ((parout=fopen("PAR:","w"))==NULL) return(2);

   if (opfile == TRUE)
   {
      if (filename[0]==0) return(4);
      if ((fileout=fopen(filename,"w"))==NULL)
      {
         if (parout!=NULL) fclose(parout);
         return(3);
      }
      return(-1);
   }
   if (oppar != TRUE) return (5);
   return (-1);
}

close_output(oppar,opfile,opfont)    /* Files und Font schließen */
long oppar,opfile,opfont;
{
   if (oppar==TRUE)
      fclose(parout);
   if (opfile==TRUE)
      fclose(fileout);
   if (opfont==TRUE)
      CloseFont(ConvFont);
}

check_lspace()    /* erlaubter Wert für Line spacing ?? */
{
   if (atoi(lspacestr)<=0 || atoi(lspacestr)>127) return(6);
   return (-1);
}

test()            /* teste den Font */
{
   int error;
   int i;
   if (fsent==NULL) return(11); /* Font noch nicht zum Printer gesendet */
   error=open_output(TRUE,NULL);
   if (error >=0)
      return(error);
   for (i=firstchar;i<=lastchar;i++)   /* Zeichensatz durchschicken */
   {
      error=fputc((char)i,parout);
      if (error==-1) return(2);
   }
   fputc((char)13,parout);             /* Papier vorschieben */
   fputc((char)10,parout);
   fputc((char)10,parout);
   close_output(TRUE,NULL,NULL);
   parout=NULL;
   return(-1);
}

send_out(string,length)    /* schicke einen String zum Drucker oder File */
char *string,length;
{
   char i;
   int error;
   for (i=0;i<length;i++)
   {
      if (topar)
      {
         error=fputc(string[i],parout);
         if (error == -1) return (2);
      }
      if (tofile)
      {
         error=fputc(string[i],fileout);
         if (error == -1) return (3);
      }
   }
   return (-1);
}

start()           /* jetzt geht die eigentliche Konvertierung los */
{
   UWORD bline;
   int i,error,a,b,c,d,count;
   char ch,ysize,datchunk[120];
   if (fontopen==FALSE) return(12); /* Wenn noch keine ausreichenden */
   if (topar==NULL && tofile==NULL) return(5);/* Daten vorhanden,abbrechen */
   error=open_output(topar,tofile);
   if (error>=0) return(error);
   bline=ConvFont->tf_Baseline;
   ysize=(char)(ConvFont->tf_YSize);
   error=send_out(&reset[1],reset[0]);    /* erste Steuerzeichen los */
      if (error >=0) return(co(error));
   if (german==TRUE && ConvFont->tf_HiChar > (char)127)
   {
      error=send_out(&setgerm[1],setgerm[0]);
      if (error >=0) return(co(error));
   }
   error=send_out(&setlqpr[1],setlqpr[0]);
      if (error >=0) return(co(error));
   error=send_out(&copyint[1],copyint[0]);
      if (error >=0) return(co(error));
   firstchar=(char)ConvFont->tf_LoChar; /* finde Anfang und Ende des Font */
   if (ConvFont->tf_HiChar >(char)127) lastchar=127;
   else lastchar=(char)ConvFont->tf_HiChar;
   error=send_out(&loadcset[1],loadcset[0]);
      if (error >=0) return(co(error));
   error=send_out(&firstchar,1);
      if (error >=0) return(co(error));
   error=send_out(&lastchar,1);
      if (error >=0) return(co(error));
   print_message(8);
   SetFont(rp,ConvFont);
   /* Dies waren alle Steuerzeichen die samt Errorcheck zum Printer bzw.
      zum File geschickt werden müssen,um den Drucker zum Empfang des
      Zeichensatzes vorzubereiten. Jetzt werden die Buchstaben der Reihe
      nach `abgetastet' und die Werte entsprechend der gewählten
      Vergrößerung zum Drucker geschickt .
   */

   for ( i=firstchar;i<=lastchar;i++)  /* Zeichen der Reihe nach */
   {
      for (a=0;a<120;a++) datchunk[a]=0;  /* Zeichenmatrix löschen */
      SetAPen(rp,0l);   /* Platz löschen */
      RectFill(rp,104l,162l,152l,185l);
      SetAPen(rp,1l);
      datchunk[0]=2;
      datchunk[1]=37;
      datchunk[2]=2;
      /* Dies sind die Steuerbytes für den Drucker,damit er alles über das
         Zeichen weiß,das ihm anschließend geschickt werden soll .
         Nr.0 : Anzahl Punkte vor dem Zeichen
         Nr.1 : Breite des eigentlichen Zeichens
         Nr.2 : Anzahl Punkte hinter dem Zeichen
      */
      Move(rp,104l,(long)(162+bline));
      ch=(char)i;
      if (german==TRUE && ConvFont->tf_HiChar > (char)127)
      {
         switch (ch)
         {
            case 91:
               ch=196;
               break;
            case 92:
               ch=214;
               break;
            case 93:
               ch=220;
               break;
            case 123:
               ch=228;
               break;
            case 124:
               ch=246;
               break;
            case 125:
               ch=252;
               break;
            case 126:
               ch=223;
               break;
            default:
               break;
         }
      }
      Text(rp,&ch,1l);  /* Warum benutze ich eine int-Variable als Zähl-
                           variable für eine Schleife,in der ein char-Wert
                           benötigt wird und caste erst den int in den
                           char um? Tja,wenn ich i als char definiere,gibt
                           es eine Endlosschleife,da 128 und -1 dann das
                           gleiche sind (siehe for-statement) !!!) */
      if ((rp->cp_x) < 140) datchunk[1]= (char)(((rp->cp_x) - 104)*henl);
      /* Character darstellen */
      count=3;
      for (a=0;a<(int)datchunk[1]/henl;a++) /* Spalte für Spalte wird das
                                               Zeichen jetzt abgetastet */
      {
         for (b=0,c=0,d=8;b<(int)ysize;b++)
         {
            if (--d < 0) d=7,count++;
            datchunk[count]|=(char)(ReadPixel(rp,(long)(104+a),
               (long)(162+b))*power[d]);
            if (venl>1)          /* ggf. vergrößern */
            {
               if (--d < 0) d=7,count++;
               datchunk[count]|=(char)(ReadPixel(rp,(long)(104+a),
                  (long)(162+b))*power[d]);
               if (venl>2)
               {
                  if (--d < 0) d=7,count++;
                  datchunk[count]|=(char)(ReadPixel(rp,(long)(104+a),
                     (long)(162+b))*power[d]);
               }
            }
         }
         while (count%3) count++; /* ggf. Leerstellen füllen */
         if (henl>1)
         {
            datchunk[count]=datchunk[count-3];
            count++;
            datchunk[count]=datchunk[count-3];
            count++;
            datchunk[count]=datchunk[count-3];
            count++;
            if (henl>2)
            {
               datchunk[count]=datchunk[count-3];
               count++;
               datchunk[count]=datchunk[count-3];
               count++;
               datchunk[count]=datchunk[count-3];
               count++;
            }
         }
      }
      error=send_out(datchunk,count);
      if (error>=0) return(co(error));
   }
   /* Alle Zeichen übertragen */
   SetAPen(rp,2l);
   Move(rp,103l,162l);
   Draw(rp,103l,185l);
   SetAPen(rp,1l);
   error=send_out(&usercset[1],usercset[0]);
   if (error>=0) return(co(error));
   if (setspace==TRUE)
   {
      if (check_lspace()>=0) { close_output(topar,tofile,NULL); return(6); }
      error=send_out(&setlf[1],setlf[0]);
      if (error >=0) return(co(error));
      linespace=(char)atoi(lspacestr);
      error=send_out(&linespace,1);
      if (error >=0) return(co(error));
   }
   else
   {
      error=send_out(&setlf[1],setlf[0]);
      if (error >=0) return(co(error));
      linespace=(char)(ysize*venl/3);
      error=send_out(&linespace,1);
      if (error >=0) return(co(error));
   }
   close_output(topar,tofile,NULL);
   parout=NULL,fileout=NULL;
   SetFont(rp,NormFont);
   SetAPen(rp,0l);   /* Platz löschen */
   RectFill(rp,104l,162l,152l,185l);
   SetAPen(rp,1l);
   print_message(9);
   return(-1);
   /* alles geklappt ! */
}

co(error)  /* falls während der Datenübertragung ein Fehler auftritt
              ( z.B. Diskette voll),wird über diese Routine abgebrochen */
int error;
{
   close_output(topar,tofile,NULL);
   return(error);
}

quit()    /* Programm beenden ?? */
{
   short result;
   result=AutoRequest(MyWindow,&BodyText,&PosText,&NegText,NULL,NULL,
      260l,50l);
   if (result == TRUE)
   {
      close_output(NULL,NULL,fontopen);
      end();
   }
}

end()    /* Programm beenden !! */
{
   CloseWindow(MyWindow);
   CloseLibrary(DiskfontBase);
   CloseLibrary(IntuitionBase);
   CloseLibrary(GfxBase);
   exit(TRUE);
}

sw_mxgads()  /* Vergrößerungsgadgets kontrollieren */
{
   switch (((struct Gadget *)(msg->IAddress))->GadgetID)
   {
      case EH1:
         henl=1;
         GadMXSel(MyWindow,&GadEH1,&GadEH2,&GadEH3);
         break;
      case EH2:
         henl=2;
         GadMXSel(MyWindow,&GadEH2,&GadEH1,&GadEH3);
         if (val_henl<2)/* Wenn gewünschte Vergrößerung nicht möglich ist,
                         wird das angewählte Gadget wieder ausgeschaltet */
         {
            GadMXSel(MyWindow,&GadEH1,&GadEH2,&GadEH3);
            henl=1;
         }
         break;
      case EH3:
         henl=3;
         GadMXSel(MyWindow,&GadEH3,&GadEH1,&GadEH2);
         if (val_henl<3)
         {
            GadMXSel(MyWindow,&GadEH1,&GadEH2,&GadEH3);
            henl=1;
         }
         break;
      case EV1:
         venl=1;
         GadMXSel(MyWindow,&GadEV1,&GadEV2,&GadEV3);
         break;
      case EV2:
         venl=2;
         GadMXSel(MyWindow,&GadEV2,&GadEV1,&GadEV3);
         if (val_venl<2)
         {
            GadMXSel(MyWindow,&GadEV1,&GadEV2,&GadEV3);
            venl=1;
         }
         break;
      case EV3:
         venl=3;
         GadMXSel(MyWindow,&GadEV3,&GadEV1,&GadEV2);
         if (val_venl<3)
         {
            GadMXSel(MyWindow,&GadEV1,&GadEV2,&GadEV3);
            venl=1;
         }
         break;
      default:
         break;
   }
}

main()
{
   int error;
   openstuff();
   init_all();
   german=TRUE,fsent=FALSE,fontopen=FALSE;
   setspace=FALSE,topar=TRUE,tofile=FALSE;
   val_henl=1,val_venl=1;
   print_message(13);  /* READY !! */
   for (;;)
   {
      Wait(1l << MyWindow->UserPort->mp_SigBit);
      /* um keine kostbare Prozessorzeit mit Warten (sog. Busy Polling) zu
         verschwenden,lasse ich das Programm Wait()en,bis was passiert */
      while((msg=GetMsg(MyWindow->UserPort))!=NULL)
      {
         switch (msg->Class)
         {
            case GADGETDOWN:
               sw_mxgads();
               print_message(13);
               break;
            case GADGETUP:
               switch (((struct Gadget *)(msg->IAddress))->GadgetID)
               {
                  case FNAME:
		     ActivateGadget(&GadFSIZE,MyWindow,NULL);
		     break;
                  case LOAD:
                     error=load_font((char *)(&fname),(char *)(&fsize));
                     if (error>=0) print_message(error);
                     else print_message(13);
                     break;
                  case LSDEF:
                     setspace=1l-setspace;
                     if (setspace==1l)
                     {
                        error=check_lspace();
                        if (error >=0) print_message(error);
                        else print_message(13);
                     }
                     break;
                  case OUTPRT:
                     topar=1l-topar;
                     print_message(13);
                     break;
                  case OUTFILE:
                     tofile=1l-tofile;
                     print_message(13);
                     break;
                  case START:
                     error=start();
                     if (error >=0) print_message(error),fsent=FALSE;
                     else
                     {
                        if (topar == NULL) fsent=FALSE;
                        else fsent=TRUE;
                     }
                     break;
                  case TEST:
                     error=test();
                     if (error >=0) print_message(error);
                     else print_message(13);
                     break;
                  case QUIT:
                     quit();
                     break;
                  case GERM:
                     german=1l-german;
                     break;
                  default:
                     break;
               }
               break;
            default:
               break;
         }
      ReplyMsg(msg);
      }
   }
}

/* püh ! */
