/* Das Programm ASC2TeX dient zum Konvertieren von Text-Bildschirm-
  Hardcopies. Das "Bild" mu� als ASCII-Datei vorliegen und den
  Suffix ".SCR" haben.
  Aufruf: ASC2TEX Datei_ohne_Suffix */

#include<stdio.h>
#include<string.h>
#include<string2.h>

/* Ascii - Codes f�r die einfachen Linien */
#define ObLi  218  /* Ecke Oben Links: � */
#define ObRe  191  /* Ecke Oben Rechts: � */
#define UnLi  192  /* Ecke Unten Links: � */
#define UnRe  217  /* Ecke Unten Rechts: � */
#define Hori  196  /* Horizontale Linie: � */
#define Senk  179  /* Senkrechte Linie: � */
#define TOb   194  /* T-St�ck Oben: � */
#define TUn   193  /* T-St�ck Unten: � */
#define TLi   195  /* T-St�ck Links: � */
#define TRe   180  /* T-St�ck Rechts: � */
#define Kreuz 197  /* Kreuz zw. Hori und Senk: � */

/* Ascii - Codes f�r die doppelten Linien */
#define DoObLi  201  /* Ecke Oben Links: � */
#define DoObRe  187  /* Ecke Oben Rechts: � */
#define DoUnLi  200  /* Ecke Unten Links: � */
#define DoUnRe  188  /* Ecke Unten Rechts: � */
#define DoHori  205  /* Horizontale Linie: � */
#define DoSenk  186  /* Senkrechte Linie: � */
#define DoTOb   203  /* T-St�ck Oben: � */
#define DoTUn   202  /* T-St�ck Unten: � */
#define DoTLi   204  /* T-St�ck Links: � */
#define DoTRe   185  /* T-St�ck Rechts: � */
#define DoKreuz 206  /* Kreuz zw. Hori und Senk: � */

#define Unterstrich 95  /* _ */

#define Muster1 176     /* d�nnes Punktmuster � */
#define Muster2 177     /* mitteldichtes Punktmuster � */
#define Muster3 178     /* dichtes Punktmuster �*/
#define Block   219     /* dichter gehts nicht � */
#define Topblock 223    /* obere H�lfte � */
#define Buttomblock 220 /* untere H�lfte � */

#define ZeichBreite (long)122
#define ZeichHoehe  (long)235

/* Hintergrundzeichen, die in Leerzeichen gewandelt werden sollen,
  und zwar bevor das Bild um unn�tze Leerzeichen verkleinert wird. */
#define hi0 1
#define hi1 2
#define hi2 7
#define hi3 8
#define hi4 9
#define hi5 16
#define hi6 17
#define hi7 127
#define hi8 32
#define hi9 32


unsigned char codepage850 [256][40] =
/*       0            1            2            3            4     */
/*       5            6            7            8            9     */
/* 0*/ {""          ,""          ,""       ,"$\\heartsuit$","$\\diamondsuit$",
    "$\\clubsuit$","$\\spadesuit$",""          ,""          ,""     ,

/* 1*/  ""          ,""          ,""          ,""          ,""       ,
       ""          ,""          ,""          ,"$\\updownarrow$",""  ,

/* 2*/  "\\P"       ,"\\S"       ,""          ,""              ,"$\\uparrow$",
     "$\\downarrow$","$\\rightarrow$","$\\leftarrow$","","$\\leftrightarrow$",

/* 3*/  ""          ,""          ,""         ,"!"          ,"{\\dq}",
       "\\#"      ,"\\$"        ,"\\%"      ,"\\&"        ,"\'"    ,

/* 4*/  "("         ,")"         ,"*"        ,"+"          ,","     ,
       "-"         ,"."         ,"/"        ,"0"          ,"1"     ,

/* 5*/  "2"         ,"3"         ,"4"        ,"5"          ,"6"     ,
       "7"         ,"8"         ,"9"        ,":"          ,";"     ,

/* 6*/  "$<$"       ,"="         ,"$>$"      ,"?"          ,"@"     ,
       "A"         ,"B"         ,"C"        ,"D"          ,"E"     ,

/* 7*/  "F"         ,"G"         ,"H"        ,"I"          ,"J"     ,
       "K"         ,"L"         ,"M"        ,"N"          ,"O"     ,

/* 8*/  "P"         ,"Q"         ,"R"        ,"S"          ,"T"     ,
       "U"         ,"V"         ,"W"        ,"X"          ,"Y"     ,

/* 9*/  "Z"         ,"["         ,"$\\backslash$","]"      ,"\\^{}" ,
       ""          ,"\\`{\\ }"  ,"a"        ,"b"          ,"c"     ,

/*10*/  "d"         ,"e"         ,"f"        ,"g"          ,"h"     ,
       "i"         ,"j"         ,"k"        ,"l"          ,"m"     ,

/*11*/  "n"         ,"o"         ,"p"        ,"q"          ,"r"     ,
       "s"         ,"t"         ,"u"        ,"v"          ,"w"     ,

/*12*/  "x"         ,"y"         ,"z"        ,"\\{"        ,"{|}"   ,
       "\\}"       ,"$\\tilde{\\ }$",""     ,"\\c{C}"     ,"\\\"u" ,

/*13*/  "\\\'e"     ,"\\^a"      ,"\\\"a"     ,"\\`a"      ,"{\\aa}",
       "\\c{c}"    ,"\\^e"      ,"\\\"e"     ,"\\`e"      ,"\\\"{\\i}",

/*14*/  "\\^{\\i}"  ,"\\`{\\i}"  ,"\\\"A"     ,"{\\AA}"    ,"\\\'E"  ,
       "{\\ae}"    ,"{\\AE}"    ,"\\^o"      ,"\\\"o"     ,"\\`o"   ,

/*15*/  "\\^u"      ,"\\`u"      ,"\\\"y"     ,"\\\"O"     ,"\\\"U"  ,
       "{\\o}"     ,"\\pounds"  ,"{\\O}"     ,"$\\times$" ,"$f$"    ,

/*16*/  "\\\'a"     ,"\\\'{\\i}" ,"\\\'o"     ,"\\\'u"     ,"\\~n"   ,
       "\\~N"      ,"$^a$"      ,"$^\\circ$" ,"?`"        ,"$\\bigcirc\\!\\!\\!\\!\\!{\\rm R}$",

/*17*/  "$\\neg$","$\\frac{1}{2}$","$\\frac{1}{4}$","!`"   ,"{\\flqq}",
       "{\\frqq}"  ,""          ,""          ,""          ,""       ,

/*18*/  ""          ,"\\\'A"     ,"\\^A"      ,"\\`A"      ,"{\\copyright}",
       ""          ,""          ,""          ,""          ,""       ,

/*19*/  "Y"         ,""          ,""          ,""          ,""       ,
       ""          ,""          ,""          ,"\\~a"      ,"\\~A"   ,

/*20*/  ""          ,""          ,""          ,""          ,""       ,
       ""          ,""          ,""          ,""          ,""       ,

/*21*/  "\\^E"      ,"\\\"E"     ,"\\`E"      ,"\\i"       ,"\\\'I"  ,
       "\\^I"      ,"\\\"I"     ,""          ,""          ,"",

/*22*/  "",""          ,"\\`I"      ,"","\\\'O"  ,
       "{\\ss}"    ,"\\^O"      ,"\\`O"      ,"\\~o"      ,"\\~O"   ,

/*23*/  "$\\mu$"    ,""          ,""          ,"\\\'U"     ,"\\^U"   ,
       "\\`U"      ,"\\\'y"     ,"\\\'Y"     ,""          ,""       ,

/*24*/  "-"         ,"$\\pm$"    ,"$_=$"   ,"$\\frac{3}{4}$","\\P"    ,
       "\\S"       ,"$\\div$"   ,""          ,""          ,""       ,

/*25*/  ""          ,"$^1$"      ,"$^2$"      ,"$^3$"      ,""       ,
       ""                 };



struct tFlaeche { long int x1, y1, x2, y2, flaeche; };
struct tzeile { unsigned char zeile[256]; };
struct tzeile bild[101];
long int breite;
long int hoehe;


int BildLaden ( char *name )
{
 long int x = -1;
 long int y = 0;
 char dateiname[255];
 FILE *datei;
 long int zeichen;

 strcpy (dateiname, name); strcat (dateiname, ".SCR");
 if ( (datei = fopen (dateiname, "rb")) == NULL ) {
   printf ("Fehler beim �ffnen der Quelldatei %s", dateiname);
   return -1;
 };

 do {
   zeichen = getc (datei);
   if (zeichen == 13 || zeichen == EOF) {
     x++;
     bild[y].zeile[x] = '\0';
     x = -1; y++;
   }
   else if (zeichen != 10) {
     x++;
     bild[y].zeile[x] = (unsigned char) zeichen;
   };
 } while ( zeichen != EOF );
 bild[y].zeile[0] = (unsigned char) 255;

 /* Ist ein eof-Zeichen (26) am Ende der Datei gewesen ? */
 y--;
 if ( y >= 0 ) {
   for ( x = 0; bild[y].zeile[x] != '\0'; x++ );
   x--;
   if ( x >= 0 && bild[y].zeile[x] == (unsigned char) 26 ) {
     bild[y].zeile[x] = '\0';
   };
 };
 return 0;
};


int KopfSchreiben ( FILE *datei )
{
 fprintf ( datei, "\\begin{tt}\n" );
 fprintf ( datei, "\\unitlength=1.00ex\n" );
 fprintf ( datei, "\\begin{picture}" );
 return 0;
};


int RestSchreiben ( FILE *datei )
{
 fprintf ( datei, "\\end{picture}\n" );
 fprintf ( datei, "\\end{tt}\n" );
 return 0;
};


int LeerzeichenSetzen ()
/* Bild wird gescannt, die oben definierten Zeichen
  werden in Leerzeichen umgesetzt */
{
 long int x = 0;
 long int y = 0;

 do {
   if ( bild[y].zeile[x] == hi0 || bild[y].zeile[x] == hi1 ||
        bild[y].zeile[x] == hi2 || bild[y].zeile[x] == hi3 ||
        bild[y].zeile[x] == hi4 || bild[y].zeile[x] == hi5 ||
        bild[y].zeile[x] == hi6 || bild[y].zeile[x] == hi7 ||
        bild[y].zeile[x] == hi8 || bild[y].zeile[x] == hi9 )
   {
     bild [y].zeile[x] = (unsigned char) 32;
     x++;
   }
   else if ( bild [y].zeile[x] == 0 ) {
     y++; x = 0;
   }
   else {
     x++;
   }
 } while ( bild [y].zeile[x] != (unsigned char) 255 );
 return 0;
};


int BildAusgeben ()
{
 long int y = 0;
 while ( bild[y].zeile[0] != 255 ) {
   printf ("%s\n", bild[y].zeile);
   y++;
 };
 return 0;
};


int BildGroesseFeststellen ( FILE *datei, long int ZeiBrei,
                            long int ZeiHoe )
{
 long int x;
 long int y;

 breite = 0;
 y = 0;
 while ( bild[y].zeile[0] != 255 ) {
   x = strlen ( bild[y].zeile );
   if ( x > breite )
     breite = x;
   y++;
 };
 hoehe = y;
 printf ( "Breite des Bildes: %4.2f ex, H�he des Bildes: %4.2f ex\n",
           ((float) (breite * ZeiBrei)) / 100.0,
           ((float) (y * ZeiHoe)) / 100.0 );
 fprintf ( datei, "(%4.2f, %4.2f)\n",
           ((float) (breite * ZeiBrei)) / 100.0,
           ((float) (y * ZeiHoe)) / 100.0 );
 return 0;
};

/* ------------------------------------------------------------------ */
/* Leerzeichen (und -zeilen) ringsherum l�schen: */

int RechtsLoeschen ()
{
 long int y = 0;
 while ( bild[y].zeile[0] != 255 ) {
   strcut ( bild[y].zeile );
   y++;
 };
 return 0;
};

int LinksLoeschen ()
{
 long int x = 0;
 long int y = 0;
 long int minleer = 256;
 while ( bild[y].zeile[0] != 255 ) {
   if ( bild[y].zeile[0] != '\0' ) {
     for ( x = 0; bild[y].zeile[x] == 32; x++ );
     if ( x < minleer )
       minleer = x;
   };
   y++;
 };
 y = 0;
 while ( bild[y].zeile[0] != 255 ) {
   if ( bild[y].zeile[0] != '\0' ) {
     for ( x = 0; x < minleer; x++ )
       strdel ( bild[y].zeile );
   };
   y++;
 };
 return 0;
};


int UntenLoeschen ()
{
 long int y = 0;
 while ( bild[y].zeile[0] != 255 ) {
   y++;
 };
 y--;
 while ( bild[y].zeile[0] == '\0' && y >= 0 ) {
   bild[y].zeile[0] = 255;
   y--;
 };
 return 0;
};

int ObenLoeschen ()
{
 long int y = 0;
 while ( bild[0].zeile[0] == '\0' ) {
   y = 0;
   while ( bild[y].zeile[0] != 255 ) {
     strcpy (bild[y].zeile, bild[y+1].zeile);
     y++;
   };
 };
 return 0;
};

int LeerzeichenAbschneiden ()
{
 RechtsLoeschen ();
 LinksLoeschen ();
 UntenLoeschen ();
 ObenLoeschen ();
 return 0;
};

/* -------------------------------------------------------------- */
/* Linien Scannen: */

int HorLinie ( FILE *datei, long int ZeiBrei, long int ZeiHoe,
              long int start, long int ziel, long int y,
              long int offsetZaehlerStart, long int offsetTeilerStart,
              long int offsetZaehlerEnd, long int offsetTeilerEnd,
              long int offsetZaehlerY, long int offsetTeilerY  )
{
 fprintf ( datei, "  \\put(%4.2f, %4.2f)",
           ((float) ((start * ZeiBrei)
            + ((ZeiBrei * offsetZaehlerStart) / offsetTeilerStart))) / 100.0,
           ((float) (((hoehe - y) * ZeiHoe)
            - ((ZeiHoe * offsetZaehlerY) / offsetTeilerY))) / 100.0 );
 fprintf ( datei, "{\\line(1,0){%4.2f}}\n",
           ((float) (((ziel - start) * ZeiBrei)
           - ((ZeiBrei * offsetZaehlerStart) / offsetTeilerStart)
           + ((ZeiBrei * offsetZaehlerEnd) / offsetTeilerEnd))) / 100.0  );
 return 0;
};


int VerLinie ( FILE *datei, long int ZeiBrei, long int ZeiHoe,
              long int x, long int start, long int ziel,
              long int offsetZaehlerX, long int offsetTeilerX,
              long int offsetZaehlerStart, long int offsetTeilerStart,
              long int offsetZaehlerEnd, long int offsetTeilerEnd  )
{
 fprintf ( datei, "  \\put(%4.2f, %4.2f)",
           ((float) ((x * ZeiBrei)
             + ((ZeiBrei * offsetZaehlerX) / offsetTeilerX))) / 100.0,
           ((float) (((hoehe - start) * ZeiHoe)
           - ((ZeiHoe * offsetZaehlerStart) / offsetTeilerStart))) / 100.0 );
 fprintf ( datei, "{\\line(0,-1){%4.2f}}\n",
           ((float) (((ziel - start) * ZeiHoe)
           - ((ZeiHoe * offsetZaehlerStart) / offsetTeilerStart)
           + ((ZeiHoe * offsetZaehlerEnd) / offsetTeilerEnd))) / 100.0 );
 return 0;
};


int EinfHorLinie ( FILE *datei, long int ZeiBrei, long int ZeiHoe,
                  long int *x, long int *y,
                  long int offsetZaehler, long int offsetTeiler   )
{
 long int start;

 start = *x;
 if ( bild[*y].zeile[*x] != ObRe && bild[*y].zeile[*x] != UnRe &&
      bild[*y].zeile[*x] != TRe )
 {
   *x += 1;
 };

 while ( bild[*y].zeile[*x] == Hori || bild[*y].zeile[*x] == TOb ||
         bild[*y].zeile[*x] == TUn  || bild[*y].zeile[*x] == Kreuz )
 {
   *x += 1;
 };
 if ( bild[*y].zeile[*x] == ObRe || bild[*y].zeile[*x] == UnRe ||
      bild[*y].zeile[*x] == TRe )
 {
   HorLinie ( datei, ZeiBrei, ZeiHoe, start, *x, *y,
              offsetZaehler, offsetTeiler, (long) 1, (long) 2,
              (long) 1, (long) 2 );
 }
 else {
   HorLinie ( datei, ZeiBrei, ZeiHoe, start, *x, *y,
              offsetZaehler, offsetTeiler, (long) 0, (long) 1,
              (long) 1, (long) 2 );
 };
 if ( bild[*y].zeile[*x] == ObRe || bild[*y].zeile[*x] == UnRe ||
      bild[*y].zeile[*x] == TRe )
 {
   *x += 1;
 };
 return 0;
};


int EinfHorLinienScannen ( FILE *datei,
                          long int ZeiBrei, long int ZeiHoe )
{
 long int y;
 long int x;

 y = 0;
 while ( bild[y].zeile[0] != 255 ) {
   x = 0;
   while ( bild[y].zeile[x] != '\0' ) {
     if ( bild[y].zeile[x] == ObLi || bild[y].zeile[x] == UnLi ||
          bild[y].zeile[x] == TLi )
     {
       EinfHorLinie ( datei, ZeiBrei, ZeiHoe, &x, &y, (long) 1, (long) 2 );
     }
     else if ( bild[y].zeile[x] == ObRe || bild[y].zeile[x] == UnRe ||
               bild[y].zeile[x] == TRe  || bild[y].zeile[x] == Hori ||
               bild[y].zeile[x] == TOb  || bild[y].zeile[x] == TUn  ||
               bild[y].zeile[x] == Kreuz )
     {
       EinfHorLinie ( datei, ZeiBrei, ZeiHoe, &x, &y, (long) 0, (long) 1 );
     }
     else {
       x++;
     };
   };
   y++;
 };
 return 0;
};


int EinfVerLinie ( FILE *datei, long int ZeiBrei, long int ZeiHoe,
                  long int *x, long int *y,
                  long int offsetZaehler, long int offsetTeiler   )
{
 long int start;
 long int offsetZaehlerEnd;
 long int offsetTeilerEnd;

 start = *y;
 if ( bild[*y].zeile[*x] != UnLi && bild[*y].zeile[*x] != UnRe &&
      bild[*y].zeile[*x] != TUn )
 {
   *y += 1;
 };

 while ( bild[*y].zeile[*x] == Senk || bild[*y].zeile[*x] == TRe ||
         bild[*y].zeile[*x] == TLi  || bild[*y].zeile[*x] == Kreuz )
 {
   *y += 1;
 };
 if ( bild[*y].zeile[*x] == UnLi || bild[*y].zeile[*x] == UnRe ||
      bild[*y].zeile[*x] == TUn )
 {
   offsetZaehlerEnd = 1;
   offsetTeilerEnd = 2;
 }
 else {
   offsetZaehlerEnd = 0;
   offsetTeilerEnd = 1;
 };
 VerLinie ( datei, ZeiBrei, ZeiHoe, *x, start, *y, (long) 1, (long) 2,
            offsetZaehler, offsetTeiler,
            offsetZaehlerEnd, offsetTeilerEnd );
 if ( bild[*y].zeile[*x] == UnLi || bild[*y].zeile[*x] == UnRe ||
      bild[*y].zeile[*x] == TUn )
 {
   *y += 1;
 };
 return 0;
};


int EinfVerLinienScannen ( FILE *datei,
                          long int ZeiBrei, long int ZeiHoe )
{
 long int y;
 long int x;

 x = 0;
 while ( x < breite ) {
   y = 0;
   while ( y < hoehe ) {
     if ( bild[y].zeile[x] == ObLi || bild[y].zeile[x] == ObRe ||
          bild[y].zeile[x] == TOb )
     {
       EinfVerLinie ( datei, ZeiBrei, ZeiHoe, &x, &y, (long) 1, (long) 2 );
     }
     else if ( bild[y].zeile[x] == UnLi || bild[y].zeile[x] == UnRe ||
               bild[y].zeile[x] == TRe  || bild[y].zeile[x] == Senk ||
               bild[y].zeile[x] == TLi  || bild[y].zeile[x] == TUn  ||
               bild[y].zeile[x] == Kreuz )
     {
       EinfVerLinie ( datei, ZeiBrei, ZeiHoe, &x, &y, (long) 0, (long) 1 );
     }
     else {
       y++;
     };
   };
   x++;
 };
 return 0;
};


int DoppHorLinie ( FILE *datei, long int ZeiBrei, long int ZeiHoe,
                  long int *x, long int *y,
                  long int offsetZaehler1, long int offsetTeiler1,
                  long int offsetZaehler2, long int offsetTeiler2   )
{
 long int start1;
 long int start2;

 start1 = *x;
 start2 = *x;
 if ( bild[*y].zeile[*x] == DoObLi || bild[*y].zeile[*x] == DoUnLi ||
      bild[*y].zeile[*x] == DoTLi )
 {
   *x += 1;
 };

 while ( bild[*y].zeile[*x] == DoHori || bild[*y].zeile[*x] == DoTOb ||
         bild[*y].zeile[*x] == DoTUn  || bild[*y].zeile[*x] == DoKreuz )
 {
   if ( bild[*y].zeile[*x] == DoTUn || bild[*y].zeile[*x] == DoKreuz ) {
     HorLinie ( datei, ZeiBrei, ZeiHoe, start1, *x, *y,
                offsetZaehler1, offsetTeiler1,
                (long) 1, (long) 3, (long) 2, (long) 5  );
     start1 = *x;
     offsetZaehler1 = 2;
     offsetTeiler1 = 3;
   };
   if ( bild[*y].zeile[*x] == DoTOb || bild[*y].zeile[*x] == DoKreuz ) {
     HorLinie ( datei, ZeiBrei, ZeiHoe, start2, *x, *y,
                offsetZaehler2, offsetTeiler2,
                (long) 1, (long) 3, (long) 3, (long) 5  );
     start2 = *x;
     offsetZaehler2 = 2;
     offsetTeiler2 = 3;
   };
   *x += 1;
 }; /* while */
 if ( bild[*y].zeile[*x] == DoObRe ) {
   HorLinie ( datei, ZeiBrei, ZeiHoe, start1, *x, *y,
              offsetZaehler1, offsetTeiler1,
              (long) 2, (long) 3, (long) 2, (long) 5  );
   HorLinie ( datei, ZeiBrei, ZeiHoe, start2, *x, *y,
              offsetZaehler2, offsetTeiler2,
              (long) 1, (long) 3, (long) 3, (long) 5  );
 }
 else if ( bild[*y].zeile[*x] == DoUnRe ) {
   HorLinie ( datei, ZeiBrei, ZeiHoe, start1, *x, *y,
              offsetZaehler1, offsetTeiler1,
              (long) 1, (long) 3, (long) 2, (long) 5  );
   HorLinie ( datei, ZeiBrei, ZeiHoe, start2, *x, *y,
              offsetZaehler2, offsetTeiler2,
              (long) 2, (long) 3, (long) 3, (long) 5  );
 }
 else if ( bild[*y].zeile[*x] == DoTRe ) {
   HorLinie ( datei, ZeiBrei, ZeiHoe, start1, *x, *y,
              offsetZaehler1, offsetTeiler1,
              (long) 1, (long) 3, (long) 2, (long) 5  );
   HorLinie ( datei, ZeiBrei, ZeiHoe, start2, *x, *y,
              offsetZaehler2, offsetTeiler2,
              (long) 1, (long) 3, (long) 3, (long) 5  );
 }
 else {
   HorLinie ( datei, ZeiBrei, ZeiHoe, start1, *x, *y,
              offsetZaehler1, offsetTeiler1,
              (long) 0, (long) 1, (long) 2, (long) 5  );
   HorLinie ( datei, ZeiBrei, ZeiHoe, start2, *x, *y,
              offsetZaehler2, offsetTeiler2,
              (long) 0, (long) 1, (long) 3, (long) 5  );
 };
 if ( bild[*y].zeile[*x] == DoObRe || bild[*y].zeile[*x] == DoUnRe ||
      bild[*y].zeile[*x] == DoTRe )
 {
   *x += 1;
 };
 return 0;
};


int DoppHorLinienScannen ( FILE *datei,
                          long int ZeiBrei, long int ZeiHoe )
{
 long int y;
 long int x;

 y = 0;
 while ( bild[y].zeile[0] != 255 ) {
   x = 0;
   while ( bild[y].zeile[x] != '\0' ) {
     if ( bild[y].zeile[x] == DoObLi ) {
       DoppHorLinie ( datei, ZeiBrei, ZeiHoe, &x, &y,
                      (long) 1, (long) 3, (long) 2, (long) 3 );
     }
     else if ( bild[y].zeile[x] == DoUnLi ) {
       DoppHorLinie ( datei, ZeiBrei, ZeiHoe, &x, &y,
                      (long) 2, (long) 3, (long) 1, (long) 3 );
     }
     else if ( bild[y].zeile[x] == DoTLi ) {
       DoppHorLinie ( datei, ZeiBrei, ZeiHoe, &x, &y,
                      (long) 2, (long) 3, (long) 2, (long) 3 );
     }
     else if ( bild[y].zeile[x] == DoObRe || bild[y].zeile[x] == DoUnRe ||
               bild[y].zeile[x] == DoTRe  || bild[y].zeile[x] == DoHori ||
               bild[y].zeile[x] == DoTOb  || bild[y].zeile[x] == DoTUn  ||
               bild[y].zeile[x] == DoKreuz )
     {
       DoppHorLinie ( datei, ZeiBrei, ZeiHoe, &x, &y,
                      (long) 0, (long) 1, (long) 0, (long) 1 );
     }
     else {
       x++;
     };
   };
   y++;
 };
 return 0;
};


int DoppVerLinie ( FILE *datei, long int ZeiBrei, long int ZeiHoe,
                  long int *x, long int *y,
                  long int offsetZaehler1, long int offsetTeiler1,
                  long int offsetZaehler2, long int offsetTeiler2   )
{
 long int start1;
 long int start2;

 start1 = *y;
 start2 = *y;
 if ( bild[*y].zeile[*x] == DoObLi || bild[*y].zeile[*x] == DoObRe ||
      bild[*y].zeile[*x] == DoTOb )
 {
   *y += 1;
 };

 while ( bild[*y].zeile[*x] == DoSenk || bild[*y].zeile[*x] == DoTLi ||
         bild[*y].zeile[*x] == DoTRe  || bild[*y].zeile[*x] == DoKreuz )
 {
   if ( bild[*y].zeile[*x] == DoTRe || bild[*y].zeile[*x] == DoKreuz ) {
     VerLinie ( datei, ZeiBrei, ZeiHoe, *x, start1, *y, (long) 1, (long) 3,
                offsetZaehler1, offsetTeiler1,
                (long) 2, (long) 5 );
     start1 = *y;
     offsetZaehler1 = 3;
     offsetTeiler1 = 5;
   };
   if ( bild[*y].zeile[*x] == DoTLi || bild[*y].zeile[*x] == DoKreuz ) {
     VerLinie ( datei, ZeiBrei, ZeiHoe, *x, start2, *y, (long) 2, (long) 3,
                offsetZaehler2, offsetTeiler2,
                (long) 2, (long) 5 );
     start2 = *y;
     offsetZaehler2 = 3;
     offsetTeiler2 = 5;
   };
   *y += 1;
 }; /* while */
 if ( bild[*y].zeile[*x] == DoUnLi ) {
   VerLinie ( datei, ZeiBrei, ZeiHoe, *x, start1, *y, (long) 1, (long) 3,
              offsetZaehler1, offsetTeiler1,
              (long) 3, (long) 5 );
   VerLinie ( datei, ZeiBrei, ZeiHoe, *x, start2, *y, (long) 2, (long) 3,
              offsetZaehler2, offsetTeiler2,
              (long) 2, (long) 5 );
 }
 else if ( bild[*y].zeile[*x] == DoUnRe ) {
   VerLinie ( datei, ZeiBrei, ZeiHoe, *x, start1, *y, (long) 1, (long) 3,
              offsetZaehler1, offsetTeiler1,
              (long) 2, (long) 5 );
   VerLinie ( datei, ZeiBrei, ZeiHoe, *x, start2, *y, (long) 2, (long) 3,
              offsetZaehler2, offsetTeiler2,
              (long) 3, (long) 5 );
 }
 else if ( bild[*y].zeile[*x] == DoTUn ) {
   VerLinie ( datei, ZeiBrei, ZeiHoe, *x, start1, *y, (long) 1, (long) 3,
              offsetZaehler1, offsetTeiler1,
              (long) 2, (long) 5 );
   VerLinie ( datei, ZeiBrei, ZeiHoe, *x, start2, *y, (long) 2, (long) 3,
              offsetZaehler2, offsetTeiler2,
              (long) 2, (long) 5 );
 }
 else {
   VerLinie ( datei, ZeiBrei, ZeiHoe, *x, start1, *y, (long) 1, (long) 3,
              offsetZaehler1, offsetTeiler1,
              (long) 0, (long) 1 );
   VerLinie ( datei, ZeiBrei, ZeiHoe, *x, start2, *y, (long) 2, (long) 3,
              offsetZaehler2, offsetTeiler2,
              (long) 0, (long) 1 );
 };
 if ( bild[*y].zeile[*x] == DoUnLi || bild[*y].zeile[*x] == DoUnRe ||
      bild[*y].zeile[*x] == DoTUn )
 {
   *y += 1;
 };
 return 0;
};


int DoppVerLinienScannen ( FILE *datei,
                          long int ZeiBrei, long int ZeiHoe )
{
 long int y;
 long int x;

 x = 0;
 while ( x < breite ) {
   y = 0;
   while ( y < hoehe ) {
     if ( bild[y].zeile[x] == DoObLi ) {
       DoppVerLinie ( datei, ZeiBrei, ZeiHoe, &x, &y,
                      (long) 2, (long) 5, (long) 3, (long) 5 );
     }
     else if ( bild[y].zeile[x] == DoObRe ) {
       DoppVerLinie ( datei, ZeiBrei, ZeiHoe, &x, &y,
                      (long) 3, (long) 5, (long) 2, (long) 5 );
     }
     else if ( bild[y].zeile[x] == DoTOb ) {
       DoppVerLinie ( datei, ZeiBrei, ZeiHoe, &x, &y,
                      (long) 3, (long) 5, (long) 3, (long) 5 );
     }
     else if ( bild[y].zeile[x] == DoUnLi || bild[y].zeile[x] == DoUnRe ||
               bild[y].zeile[x] == DoTUn  || bild[y].zeile[x] == DoSenk ||
               bild[y].zeile[x] == DoTLi  || bild[y].zeile[x] == DoTRe  ||
               bild[y].zeile[x] == DoKreuz )
     {
       DoppVerLinie ( datei, ZeiBrei, ZeiHoe, &x, &y,
                      (long) 0, (long) 1, (long) 0, (long) 1 );
     }
     else {
       y++;
     };
   };
   x++;
 };
 return 0;
};


int UnterstricheScannen ( FILE *datei,
                         long int ZeiBrei, long int ZeiHoe )
{
 long int y;
 long int x;
 long int start;

 start = -1;
 for ( y = 0; y < hoehe; y++ ) {
   for ( x = 0; x <= breite; x++ ) {
     if ( bild[y].zeile[x] == Unterstrich ) {
       if ( start == -1 )
         start = x;
     }
     else if ( start > -1 ) {
       HorLinie ( datei, ZeiBrei, ZeiHoe, start, x, y,
                  (long) 0, (long) 1, (long) 0, (long) 1,
                  (long) 9, (long) 10 );
       start = -1;
     };
   };  /* for ( x = 0...) */
 };  /* for ( y = 0...) */
 return 0;
};

int LinienScannen ( FILE *datei,
                   long int ZeiBrei, long int ZeiHoe )
{
 long int y;
 long int x;
 for ( y = 0; y < hoehe; y++ )
   strextend ( bild[y].zeile, (short) breite );
 for ( x = 0; x <= breite; x++ )
   bild[y].zeile[x] = (unsigned char) 255;
 EinfHorLinienScannen ( datei, ZeiBrei, ZeiHoe );
 EinfVerLinienScannen ( datei, ZeiBrei, ZeiHoe );
 DoppHorLinienScannen ( datei, ZeiBrei, ZeiHoe );
 DoppVerLinienScannen ( datei, ZeiBrei, ZeiHoe );
 UnterstricheScannen  ( datei, ZeiBrei, ZeiHoe );
 return 0;
};


/* -------------------------------------------------------------------- */
/* Bl�cke Scannen (Punktmuster und Vollbl�cke) */

int DotsSchreiben
  ( FILE *datei, long int ZeiBrei, long int ZeiHoe,
    long int x1, long int y1, long int x2, long int y2,
    float xBrei, float yHoe )
/* Schreibt die geeigneten TeX-Befehle in die datei, so da�
  ein Punktemuster auf der Fl�che lo=(x1,y1) bis ru=(x2,y2)
  entsteht. Einschl. lu und ro */
{
 float yLauf;
 float yDistanz;
 float xLauf;
 float xDistanz;
 int xAnzahl;
 int yAnzahl;
 int i;

 if ( (y2 - y1 + 1) * (long) 2 <= (x2 - x1 + 1) * (long) 3 )
 /* Ist die Fl�che mehr horizontal oder mehr vertikal ?
    Es sollen m�glichst wenige Multiputs verwendet werden.
    Es werden ben�tigt: Breite * 6 Multiputs oder
    H�he * 4 Multiputs */
 {  /* eine eher breite Box */
   yLauf = ((float) ((hoehe - y2) * ZeiHoe)) / 100.0;
   yDistanz = ((float) ZeiHoe) / 400.0;
   xLauf = ((float) x1 * ZeiBrei) / 100.0;
   xDistanz = ((float) ZeiBrei) / 300.0;
   yAnzahl = ((int) y2 - (int) y1 + 1) * 2;
   xAnzahl = ((int) x2 - (int) x1 + 1) * 3;
   for ( i = 0; i < yAnzahl; i++ ) {
     fprintf ( datei,
            "  \\multiput(%6.4f, %6.4f)(%6.4f, 0.00){%2d}{\\rule{%4.2f\\unitlength}{%4.2f\\unitlength}}\n",
            xLauf + 0.5 * xDistanz, yLauf, xDistanz, xAnzahl, xBrei, yHoe );
     yLauf = yLauf + yDistanz;
     fprintf ( datei,
            "  \\multiput(%6.4f, %6.4f)(%6.4f, 0.00){%2d}{\\rule{%4.2f\\unitlength}{%4.2f\\unitlength}}\n",
            xLauf, yLauf, xDistanz, xAnzahl, xBrei, yHoe );
     yLauf = yLauf + yDistanz;
   };
 }
 else {  /* Eine mehr vertikale Fl�che */
   yLauf = ((float) ((hoehe - y2) * ZeiHoe)) / 100.0;
   yDistanz = ((float) ZeiHoe) / 200.0;
   xLauf = ((float) x1 * ZeiBrei) / 100.0;
   xDistanz = ((float) ZeiBrei) / 600.0;
   yAnzahl = ((int) y2 - (int) y1 + 1) * 2;
   xAnzahl = ((int) x2 - (int) x1 + 1) * 3;
   for ( i = 0; i < xAnzahl; i++ ) {
     fprintf ( datei,
            "  \\multiput(%6.4f, %6.4f)(0.00, %6.4f){%2d}{\\rule{%4.2f\\unitlength}{%4.2f\\unitlength}}\n",
            xLauf, yLauf + 0.5 * yDistanz, yDistanz, yAnzahl, xBrei, yHoe );
     xLauf = xLauf + xDistanz;
     fprintf ( datei,
            "  \\multiput(%6.4f, %6.4f)(0.00, %6.4f){%2d}{\\rule{%4.2f\\unitlength}{%4.2f\\unitlength}}\n",
            xLauf, yLauf, yDistanz, yAnzahl, xBrei, yHoe );
     xLauf = xLauf + xDistanz;
   };
 };
 return 0;
};

int DuennBlockSchreiben
  ( FILE *datei, long int ZeiBrei, long int ZeiHoe,
    long int x1, long int y1, long int x2, long int y2 )
{
 return DotsSchreiben
        (datei, ZeiBrei, ZeiHoe, x1, y1, x2, y2, (float) 0.15, (float) 0.2);
};

int MittelBlockSchreiben
  ( FILE *datei, long int ZeiBrei, long int ZeiHoe,
    long int x1, long int y1, long int x2, long int y2 )
{
 return DotsSchreiben
        (datei, ZeiBrei, ZeiHoe, x1, y1, x2, y2, (float) 0.2, (float) 0.3);
};

int DickBlockSchreiben
  ( FILE *datei, long int ZeiBrei, long int ZeiHoe,
    long int x1, long int y1, long int x2, long int y2 )
{
 return DotsSchreiben
        (datei, ZeiBrei, ZeiHoe, x1, y1, x2, y2, (float) 0.25, (float) 0.4);
};

int VollBlockSchreiben
  ( FILE *datei, long int ZeiBrei, long int ZeiHoe,
    long int x1, long int y1, long int x2, long int y2 )
{
 fprintf ( datei,
           "  \\put(%6.4f, %6.4f){\\rule{%4.2f\\unitlength}{%4.2f\\unitlength}}\n",
           ((float) x1 * ZeiBrei) / 100.0,
           ((float) ((hoehe - y2) * ZeiHoe)) / 100.0,
           ((float) (x2 - x1 + 1) * ZeiBrei) / 100.0,
           ((float) (y2 - y1 + 1) * ZeiHoe)  / 100.0  );
 return 0;
};

/* Nur f�r Debugging-Zwecke :
int RahmenBlockSchreiben
  ( FILE *datei, long int ZeiBrei, long int ZeiHoe,
    long int x1, long int y1, long int x2, long int y2 )
{
 static int i = 0;
 i++;
 fprintf ( datei,
           "  \\put(%6.4f, %6.4f){\\framebox(%4.2f, %4.2f){%2d}}\n",
           ((float) x1 * ZeiBrei) / 100.0,
           ((float) ((hoehe - y2) * ZeiHoe)) / 100.0,
           ((float) (x2 - x1 + 1) * ZeiBrei) / 100.0,
           ((float) (y2 - y1 + 1) * ZeiHoe)  / 100.0,
           i );
 return 0;
};
*/


int TopBlockSchreiben
  ( FILE *datei, long int ZeiBrei, long int ZeiHoe,
    long int x1, long int y1, long int x2, long int y2 )
{
 if (y1 == y2) {
   fprintf ( datei,
           "  \\put(%6.4f, %6.4f){\\rule{%4.2f\\unitlength}{%4.2f\\unitlength}}\n",
         ((float) x1 * ZeiBrei) / 100.0,
         (((float) ((hoehe - y2) * ZeiHoe))
          + (float) ZeiHoe / 2.0)
         / 100.0,
         ((float) (x2 - x1 + 1) * ZeiBrei) / 100.0,
         (float) ZeiHoe / 200.0  );
 }
 else {
   fprintf ( datei,
           "  \\multiput(%6.4f, %6.4f)(0.00, %6.4f){%2d}{\\rule{%4.2f\\unitlength}{%4.2f\\unitlength}}\n",
         ((float) x1 * ZeiBrei) / 100.0,
         (((float) ((hoehe - y2) * ZeiHoe))
          + (float) ZeiHoe / 2.0)
         / 100.0,
         (float) ZeiHoe / 100.0,
         (int) y2 - (int) y1 + 1,
         ((float) (x2 - x1 + 1) * ZeiBrei) / 100.0,
         (float) ZeiHoe / 200.0  );
 };
 return 0;
};


int ButtomBlockSchreiben
  ( FILE *datei, long int ZeiBrei, long int ZeiHoe,
    long int x1, long int y1, long int x2, long int y2 )
{
 if (y1 == y2) {
   fprintf ( datei,
           "  \\put(%6.4f, %6.4f){\\rule{%4.2f\\unitlength}{%4.2f\\unitlength}}\n",
         ((float) x1 * ZeiBrei) / 100.0,
         ((float) ((hoehe - y2) * ZeiHoe)) / 100.0,
         ((float) (x2 - x1 + 1) * ZeiBrei) / 100.0,
         (float) ZeiHoe / 200.0  );
 }
 else {
   fprintf ( datei,
           "  \\multiput(%6.4f, %6.4f)(0.00, %6.4f){%2d}{\\rule{%4.2f\\unitlength}{%4.2f\\unitlength}}\n",
         ((float) x1 * ZeiBrei) / 100.0,
         ((float) ((hoehe - y2) * ZeiHoe)) / 100.0,
         (float) ZeiHoe / 100.0,
         (int) y2 - (int) y1 + 1,
         ((float) (x2 - x1 + 1) * ZeiBrei) / 100.0,
         (float) ZeiHoe / 200.0  );
 };
 return 0;
};


int EinBlockScannen
  ( unsigned char Zeichen, long int x, long int y,
    struct tFlaeche *flaeche )
{
 struct tFlaeche flaeche1, flaeche2;
 long int br1, br2, i;
 int ende;

 flaeche1.x1 = x;
 flaeche1.y1 = y;
 flaeche2.x1 = -1;  /* Um zu erkennen, ob beschreiben */
 /* potentielle Breite feststellen: */
 for (br1 = 0 ; bild[y].zeile[x+br1] == Zeichen; br1++ );
 ende = 0;
 do {
   y++;
   for (br2 = 0 ; bild[y].zeile[x+br2] == Zeichen; br2++ );
   /* Nimmt man die neue Zeile dazu, darf die Fl�che nicht
      kleiner werden:  */
   if ( (y - flaeche1.y1 + 1) * br2 < (y - flaeche1.y1) * br1 ) {
     flaeche1.y2 = y - 1;
     flaeche1.x2 = flaeche1.x1 + br1 - 1;
     flaeche1.flaeche = (y - flaeche1.y1) * br1;
     ende = 1;
   }
   else {
     if ( br2 < br1 )
       br1 = br2;
   };
   /* Einen Tip feststellen */
   if ( flaeche2.x1 == -1 && bild[y].zeile[x] == Zeichen ) {
     i = x;
     for (; i >= 0 && bild[y].zeile[i] == Zeichen; i-- );
     i++;
     for (br2 = 0 ; bild[y].zeile[i+br2] == Zeichen; br2++ );
     if ( br2 > br1 ) {
       /* Dann ist's ein Tip f�r eine gr��ere Fl�che */
       flaeche2.x1 = i;
       flaeche2.y1 = y;
     };
   };
 } while (!ende);
 if ( flaeche2.x1 == -1 ) {  /* kein (weiterer) Tip, also vorbei */
   *flaeche = flaeche1;
 }
 else {
   EinBlockScannen ( Zeichen,flaeche2.x1,flaeche2.y1,&flaeche2 );
   if (flaeche1.flaeche >= flaeche2.flaeche)
     *flaeche = flaeche1;
   else
     *flaeche = flaeche2;
 };
 return 0;
};


int BlockRausnehmen ( struct tFlaeche flaeche )
{
 long int x, y;

 for ( y = flaeche.y1; y <= flaeche.y2; y++ ) {
   for ( x = flaeche.x1; x <= flaeche.x2; x++ ) {
     bild[y].zeile[x] = ' ';
   };
 };
 return 0;
};


int BlockZeichenScannen
  ( FILE *datei, long int ZeiBrei, long int ZeiHoe,
    unsigned char Zeichen, int Schreiben() )
{
 long int x, y;
 struct tFlaeche flaeche;

 do {
   y = 0; x = 0;
   while ( y < hoehe && bild[y].zeile[x] != Zeichen ) {
     x++;
     if ( x == breite ) {
       y++; x = 0;
     };
   };
   if ( y < hoehe ) {   /* Was gefunden */
     EinBlockScannen ( Zeichen, x, y, &flaeche );
     Schreiben ( datei, ZeiBrei, ZeiHoe, flaeche.x1, flaeche.y1+1,
                 flaeche.x2, flaeche.y2+1 );
     BlockRausnehmen ( flaeche );
   };
 } while ( y < hoehe );
 return 0;
};



int BloeckeScannen ( FILE *datei, long int ZeiBrei, long int ZeiHoe)
{
 BlockZeichenScannen
  ( datei, ZeiBrei, ZeiHoe, Muster1, DuennBlockSchreiben );
 BlockZeichenScannen
  ( datei, ZeiBrei, ZeiHoe, Muster2, MittelBlockSchreiben );
 BlockZeichenScannen
  ( datei, ZeiBrei, ZeiHoe, Muster3, DickBlockSchreiben );
 BlockZeichenScannen
  ( datei, ZeiBrei, ZeiHoe, Block, VollBlockSchreiben );
 BlockZeichenScannen
  ( datei, ZeiBrei, ZeiHoe, Topblock, TopBlockSchreiben );
 BlockZeichenScannen
  ( datei, ZeiBrei, ZeiHoe, Buttomblock, ButtomBlockSchreiben );
 return 0;
};


/* -------------------------------------------------------------------- */
/* Text Scannen */


int WortScannen ( FILE *datei, long int ZeiBrei, long int ZeiHoe,
                 long int *x, long int *y )
{
 long int start;
 unsigned char zeile [2048];
 int zeichen;

 zeile[0] = '\0';
 start = *x;

 zeichen = (int) bild[(int)*y].zeile[(int)*x];
 while ( strcmp (codepage850 [zeichen], "") != 0 )
 {
   strcat ( zeile, codepage850 [zeichen] );
   *x += 1;
   zeichen = (int) bild[(int)*y].zeile[(int)*x];
 };
 fprintf ( datei, "  \\put(%4.2f, %4.2f){\\makebox(%4.2f, %4.2f)[lb]{%s}}\n",
           ((float) (start * ZeiBrei)) / 100.0,
           ((float) ((hoehe - *y) * ZeiHoe
                   - (ZeiHoe * (long)7) / (long)10)) / 100.0,
           ((float) ((*x - start) * ZeiBrei)) / 100.0,
           ((float) ZeiHoe) / 100.0,
           zeile );
 return 0;
};


int TextScannen ( FILE *datei, long int ZeiBrei, long int ZeiHoe )
{
 long int y;
 long int x;
 int zeichen;

 y = 0;
 while ( bild[y].zeile[0] != 255 ) {
   x = 0;
   while ( bild[y].zeile[x] != '\0' ) {
     zeichen = (int) bild[(int)y].zeile[(int)x];
     if ( strcmp (codepage850 [zeichen], "") != 0 )
     {
        WortScannen ( datei, ZeiBrei, ZeiHoe, &x, &y );
     }
     else
       x++;
   };  /* while */
   y++;
 };
 return 0;
};


/* -------------------------------------------------------------------- */
/* Pascal-like: Das Hauptprogramm am Ende */

int main ( int argc, char *argv[] )
{
 char dateiname [256];
 FILE *datei;
 long int ZeiBrei = ZeichBreite;
 long int ZeiHoe = ZeichHoehe;

 if ( argc < 2 ) {
   printf ( "Aufruf: ASC2TEX Datei_ohne_Suffix\n" );
   printf ( "Die Datei mu� den Suffix \".SCR\" haben.\n" );
   return -1;
 }

 if ( BildLaden ( argv[1] ) < 0 )
   return -1;
 strcpy ( dateiname, argv[1] );
 strcat ( dateiname, ".TEX" );
 if ( (datei = fopen (dateiname, "w")) == NULL ) {
   printf ("Fehler beim �ffnen von %s\n", dateiname);
   return -1;
 };
 KopfSchreiben ( datei ); fflush ( datei );

 LeerzeichenSetzen ();
 LeerzeichenAbschneiden ();
 BildAusgeben ();
 printf ("Erzeuge Datei %s\n", dateiname );
 BildGroesseFeststellen ( datei, ZeiBrei, ZeiHoe );
 LinienScannen ( datei, ZeiBrei, ZeiHoe );
 BloeckeScannen ( datei, ZeiBrei, ZeiHoe );
 TextScannen ( datei, ZeiBrei, ZeiHoe );
 RestSchreiben ( datei );
 fclose (datei);
 return 0;
};