/* fig2eng.c -- version 0.4 -- 21:29 GMT +10  Mon 27 June 1994.
*
*  fig2eng -- Convert Fig 2.1 code numbers to English.
*
*  Geoffrey Tobin
*  [email protected]
*
*  Version History:
*
*  0.0 -- initial attempt, working from Fig2MF 0.04 gt mod 1x.
*
*  0.1 -- fix for arrows in splines.  (fa, ba were wrongly read as
*         floats.)
*      -- EPS line, if present, must _precede_ the points line.
*         (This is contrary to both the Transfig Manual, 2.1.8, and
*         xfig/Doc/FORMAT2.1 file for xfig 2.1.8, but it is what the
*         `readme.c' file in transfig 2.1.8 does, so!)
*
*  0.2 -- count objects from 1, not 0 as before.
*
*  0.3 -- state arrow direction before detailed arrow information.
*      -- tabs in this C source replaced by spaces.
*
*  0.4 -- fig2eng.c has prototypes, and detects ANSI (or non-ANSI) C
*         compiler.
*/

#include <stdio.h>


#define OUTPUT      printf

#define put_msg(x)  fputs (x, stderr); \
 fprintf (stderr, \
 " in file \"%s\" \n", figfile)

#define dofill()  (1.2 - ((double) area_fill / (double) FILL_BLACK))

#define dopen(x)  (((x-1)*PEN_INCR) + DEF_PEN)

#define FIG_HEADER_LEN  8
#define TITLE           "fig2eng"
#define VERSION         "0.4  Mon 27 June 1994"
#define BUF_SIZE        1024
#define O_ELLIPSE       1
#define O_POLYLINE      2
#define O_SPLINE        3
#define O_TEXT          4
#define O_ARC           5
#define O_COMP          6
#define O_ECOMP       (-6)
#define FILL_BLACK      21
#define N_CURVE         11
#define N_POLYLINE      12
#define N_ELLIPSE       19
#define N_ARC           20
#define DEF_PEN         0.5
#define PEN_INCR        0.10


char *progname = "";
char *figfile = "";

int ppi;


#define OK     0
#define FAIL (-1)


/* Function prototypes */

#ifdef __STDC__
#define __(X) X
#define Void void
#else
#define __(X) ()
#define Void int
#endif

int main __((int argc, char * argv[]));
int skipspaces __((FILE * fp));
int process __((char * filename));
int compound __((FILE * fp));
Void end_compound __((void));
int common_fields __((FILE * fp));
int arrow __((FILE * fp));
int points __((FILE * fp, int * p_npts));
int arrow_check __((int fa, int ba));
int polyline __((FILE * fp));
int spline __((FILE * fp));
int ellipse __((FILE * fp));
int arc __((FILE * fp));
int text __((FILE * fp));


/* Function code */

int
main
#ifdef __STDC__
 (int argc, char * argv[])
#else
 (argc, argv)
   int  argc;
   char * argv[];
#endif
{
   FILE * fp;
   int i;

   progname = argv[0];
   figfile = "Standard Input";

   OUTPUT ("%%\n%% %s:  %s version %s \n%%\n",
       progname, TITLE, VERSION);

   if (argc < 2)
       process ("-");
   else
   {
       for (i=1; i < argc; i++)
           process (argv[i]);
   }

   return (0);
} /* main */


int
skipspaces
#ifdef __STDC__
 (fp)
   FILE * fp;
#else
 (FILE * fp)
#endif
{
   int ch;
   while (((ch = getc (fp)) != EOF || !feof (fp)) && isspace (ch))
       ;
   /* if not at end of file, ch is now a nonspace */
   if (ch != EOF || !feof (fp))
   {
       if (ungetc (ch, fp) == EOF)
       {
           put_msg ("FATAL ERROR:  ungetc failed!");
           OUTPUT ("FATAL ERROR:  ungetc failed\n");
           return FAIL;
       }
   }
} /* skipspaces */

int
process
#ifdef __STDC__
 (char * filename)
#else
 (filename)
   char * filename;
#endif
{
   int status = OK;
   FILE * fp = (FILE *) NULL;
   int ch;
   char tmpbuf[FIG_HEADER_LEN+2];  /* possible newline, plus ascii nul */
   int nobjs = 0;  /* counts objects in Fig file */
   int coord_sys;
   int object;

   if (filename[0] == '-')
   {
       figfile = "Standard Input";
       fp = stdin;
   }
   else
   {
       figfile=filename;
       if ((fp = fopen (filename, "r")) == NULL)
       {
           fprintf (stderr,
               "%s: cannot open the input file \"%s\"\n",
               progname, filename);
           status = FAIL;
           goto LabelFail;
       }
   }

   /* gt - input Fig file */

   OUTPUT ("\n");
   OUTPUT ("%% Interpreting Fig file:\n");
   OUTPUT ("%% \n");
   OUTPUT ("%% `%s' \n", figfile);
   OUTPUT ("\n");

   fgets (tmpbuf, sizeof (tmpbuf), fp);

   if (strncmp (tmpbuf, "#FIG 2.1", FIG_HEADER_LEN) != 0)
   {
       put_msg ("Header is not the expected `#FIG 2.1'!");
       OUTPUT ("Header is `%s', but expected `#FIG 2.1'\n", tmpbuf);
       status = FAIL;
       goto LabelFail;
   }

   OUTPUT ("Fig 2.1\n");

   if (fscanf (fp, "%d%d", &ppi, &coord_sys) != 2)
   {
       put_msg ("INCOMPLETE ppi and coord_sys data!");
       status = FAIL;
       goto LabelFail;
   }

   OUTPUT ("%d pixels per inch\n", ppi);

   switch (coord_sys)
   {
       case 1:   OUTPUT ("origin at lower left corner");  break;
       case 2:   OUTPUT ("origin at upper left corner");  break;
       default:
             OUTPUT ("INVALID coordinate system");
             put_msg ("INVALID coordinate system!");
             status = FAIL;
             goto LabelFail;
             break;
   }
   OUTPUT ("\n");

   OUTPUT ("%% Note:  Numbering objects from 0.\n");

   for (nobjs = 0;  (ch = getc (fp)) != EOF || ! feof (fp);  nobjs++)
   {
       if (ungetc (ch, fp) == EOF)
       {
           put_msg ("FATAL ERROR:  ungetc failed!");
           OUTPUT ("FATAL ERROR:  ungetc failed\n");
           status = FAIL;
           goto LabelFail;
       }

       OUTPUT ("\n");  /* empty line before each object */
       if (fscanf (fp, "%d", &object) != 1)
       {
           put_msg ("ERROR:  object needs to be an integer!");
           OUTPUT ("ERROR:  object # %d needs to be an integer\n",
               nobjs+1);
           status = FAIL;
           goto LabelFail;
       }

       OUTPUT ("Object # %d: \n", nobjs+1);
       OUTPUT ("\n");
       switch (object)
       {
           case O_ELLIPSE:
               if (ellipse (fp) == FAIL)
               {
                   status = FAIL;
                   goto LabelFail;
               }
               break;
           case O_POLYLINE:
               if (polyline (fp) == FAIL)
               {
                   status = FAIL;
                   goto LabelFail;
               }
               break;
           case O_SPLINE:
               if (spline (fp) == FAIL)
               {
                   status = FAIL;
                   goto LabelFail;
               }
               break;
           case O_TEXT:
               if (text (fp) == FAIL)
               {
                   status = FAIL;
                   goto LabelFail;
               }
               break;
           case O_ARC:
               if (arc (fp) == FAIL)
               {
                   status = FAIL;
                   goto LabelFail;
               }
               break;
           case O_COMP:
               if (compound (fp) == FAIL)
               {
                   status = FAIL;
                   goto LabelFail;
               }
               break;
           case O_ECOMP:
               end_compound ();
               break;
           default:
               fprintf (stderr, "object (# %d) = %d is an ",
                   nobjs+1, object);
               put_msg ("UNKNOWN object!");
               status = FAIL;
               goto LabelFail;
               break;
       }
       /* skip whitespaces, including end of line */
       if (skipspaces (fp) == FAIL)
       {
           status = FAIL;
           goto LabelFail;
       }
       if (object != O_COMP && object != O_ECOMP)
       {
           OUTPUT ("\n");
           OUTPUT ("End of object # %d.\n", nobjs+1);
       }
   }

   if (fp != stdin)
       fclose (fp);

   OUTPUT ("\n");
   OUTPUT ("%% Finished reading Fig file `%s'. \n", figfile);
   OUTPUT ("\n");

   return OK;

LabelFail:

   OUTPUT ("\n");
   OUTPUT ("%% An Error interrupted reading Fig file `%s'. \n", figfile);
   OUTPUT ("\n");

   return FAIL;

} /* process */


int
compound
#ifdef __STDC__
 (FILE * fp)
#else
 (fp)
   FILE * fp;
#endif
{
   int urx, ury;
   int llx, lly;

   OUTPUT ("Compound Object:\n");

   fscanf (fp, "%d", &urx);
   fscanf (fp, "%d", &ury);
   fscanf (fp, "%d", &llx);
   fscanf (fp, "%d", &lly);

   OUTPUT ("Bounding box corners:\n");
   OUTPUT ("Upper right =  (%d, %d) \n", urx, ury);
   OUTPUT ("Lower left  =  (%d, %d) \n", llx, lly);

   return OK;

} /* compound */


Void
end_compound __((void))
{
   OUTPUT ("End Compound Object.\n");

} /* end_compound */


#define SOLID_LINE   0
#define DASH_LINE    1
#define DOTTED_LINE  2

#define DEFAULT_COLOR  (-1)
#define BLACK    0
#define BLUE     1
#define GREEN    2
#define CYAN     3
#define RED      4
#define MAGENTA  5
#define YELLOW   6
#define WHITE    7

#define DEFAULT_PEN  0

#define DEFAULT_FILL   0
#define WHITE_FILL     1
#define BLACK_FILL    21


int
common_fields
#ifdef __STDC__
 (FILE * fp)
#else
 (fp)
   FILE * fp;
#endif
{
   int line_style,
       line_thickness,
       color,
       depth,
       pen,
       area_fill;

   float style_val;

   fscanf (fp, "%d", &line_style);
   fscanf (fp, "%d", &line_thickness);
   fscanf (fp, "%d", &color);
   fscanf (fp, "%d", &depth);
   fscanf (fp, "%d", &pen);
   fscanf (fp, "%d", &area_fill);
   fscanf (fp, "%f", &style_val);

   OUTPUT ("line style = ");
   switch (line_style)
   {
       case SOLID_LINE :  OUTPUT ("solid");   break;
       case DASH_LINE:    OUTPUT ("dash");    break;
       case DOTTED_LINE:  OUTPUT ("dotted");  break;
       default:
                  OUTPUT ("INVALID");
                  put_msg ("INVALID line style!");
                  return FAIL;
                  break;
   }
   OUTPUT ("\n");

   OUTPUT ("line thickness = %d pixels\n", line_thickness);

   OUTPUT ("color = ");
   switch (color)
   {
       case DEFAULT_COLOR:  OUTPUT ("default");  break;
       case BLACK:    OUTPUT ("black");  break;
       case BLUE:     OUTPUT ("blue");  break;
       case GREEN:    OUTPUT ("green");  break;
       case CYAN:     OUTPUT ("cyan");  break;
       case RED:      OUTPUT ("red");  break;
       case MAGENTA:  OUTPUT ("magenta");  break;
       case YELLOW:   OUTPUT ("yellow");  break;
       case WHITE:    OUTPUT ("white");  break;
       default:
           OUTPUT ("INVALID");
           put_msg ("INVALID color!");
           return FAIL;
           break;
   }
   OUTPUT ("\n");

   OUTPUT ("depth = layer %d\n", depth);

   OUTPUT ("pen = %d  (0 and -1 are the default values) \n", pen);

   OUTPUT ("area fill = ");
   switch (area_fill)
   {
       case DEFAULT_FILL:  OUTPUT ("default");  break;
       case WHITE_FILL:    OUTPUT ("white");  break;
       case BLACK_FILL:    OUTPUT ("black");  break;
       default:
           if (area_fill > WHITE_FILL && area_fill < BLACK_FILL)
           {
               OUTPUT ("grey, darkness = %d", area_fill);
               OUTPUT ("  (range : 1 to 21)");
           }
           else
           {
               OUTPUT ("INVALID");
               put_msg ("INVALID area fill!");
               return FAIL;
           }
           break;
   }
   OUTPUT ("\n");

   OUTPUT ("style value = %.3f", style_val);
   if (line_style == DASH_LINE)
       OUTPUT (" = dash length");
   else if (line_style == DOTTED_LINE)
       OUTPUT (" = gap between dots");
   else
       OUTPUT (" : ignored");
   OUTPUT ("\n");

   return OK;
} /* common_fields */

int
arrow
#ifdef __STDC__
 (FILE * fp)
#else
 (fp)
   FILE * fp;
#endif
{
   int at, as;
   float athick, awidth, aht;

   fscanf (fp, "%d", &at);
   fscanf (fp, "%d", &as);
   fscanf (fp, "%f", &athick);
   fscanf (fp, "%f", &awidth);
   fscanf (fp, "%f", &aht);

   OUTPUT ("arrow_type = %d  (default is 0 or -1)\n", at);
   OUTPUT ("arrow_style = %d  (default is 0 or -1)\n", as);
   OUTPUT ("arrow_thickness = %.3f  (default is 0 or -1, I think)\n", athick);
   OUTPUT ("arrow_width = %.3f\n", awidth);
   OUTPUT ("arrow_height = %.3f\n", aht);

   return OK;
} /* arrow */


int
points
#ifdef __STDC__
 (FILE * fp, int * p_npts)
#else
 (fp, p_npts)
   FILE * fp;
   int * p_npts;
#endif
{
   int npts;

   for (npts = 0; ; npts++)
   {
       int x, y;

       if (fscanf (fp, "%d%d", &x, &y) != 2)
       {
           OUTPUT ("INCOMPLETE points line!\n");
           put_msg ("INCOMPLETE points line!");
           return FAIL;
       }

       if (x == 9999)
           break;

       OUTPUT ("    (%d, %d)\n", x, y);
   }

   * p_npts = npts;  /* number of points */

   return OK;

} /* points */


#define NO_ARROW  0
#define ARROW     1

int
arrow_check
#ifdef __STDC__
 (int fa, int ba)
#else
 (fa, ba)
   int fa, ba;
#endif
{
   OUTPUT ("forward arrow :  ");
   switch (fa)
   {
       case ARROW:
           OUTPUT ("yes");
           break;
       case NO_ARROW:
           OUTPUT ("no");
           break;
       default:
           OUTPUT ("INVALID  (fa = %d)  !", fa);
           put_msg ("INVALID forward arrow code!");
           return FAIL;
           break;
   }
   OUTPUT ("\n");

   OUTPUT ("backward arrow :  ");
   switch (ba)
   {
       case ARROW:
           OUTPUT ("yes");
           break;
       case NO_ARROW:
           OUTPUT ("no");
           break;
       default:
           OUTPUT ("INVALID  (ba = %d)  !", ba);
           put_msg ("INVALID backward arrow code!");
           return FAIL;
           break;
   }
   OUTPUT ("\n");

   return OK;

}  /* arrow_check */


#define T_POLYLINE  1
#define T_BOX       2
#define T_POLYGON   3
#define T_ARC_BOX   4
#define T_EPS_BOX   5

#define EPS_UPRIGHT  0
#define EPS_FLIPPED  1

int
polyline
#ifdef __STDC__
 (FILE * fp)
#else
 (fp)
   FILE * fp;
#endif
{
   int    sub_type;
   int    radius;
   int    fa,
       ba;
   int    flipped;
   char    epsfile[100 + 1];
   int     npts;

   OUTPUT ("Polyline Object:\n");

   fscanf (fp, "%d", &sub_type);

   OUTPUT ("sub_type = ");
   switch (sub_type)
   {
       case T_POLYLINE:  OUTPUT ("polyline");  break;
       case T_BOX:       OUTPUT ("box");  break;
       case T_POLYGON:   OUTPUT ("polygon");  break;
       case T_ARC_BOX:   OUTPUT ("arc_box");  break;
       case T_EPS_BOX:   OUTPUT ("eps_box");  break;
       default:
           OUTPUT ("INVALID");
           put_msg ("INVALID polyline subtype!");
           return FAIL;
           break;
   }
   OUTPUT ("\n");

   if (common_fields (fp) == FAIL)
       return FAIL;

   fscanf (fp, "%d", &radius);
   OUTPUT ("radius = %d\n", radius);

   fscanf (fp, "%d", &fa);
   fscanf (fp, "%d", &ba);

   if (arrow_check (fa, ba) == FAIL)
       return FAIL;

   if (fa == ARROW)
   {
     OUTPUT ("forward arrow has:\n");
     if (arrow (fp) == FAIL)
       return FAIL;
   }

   if (ba == ARROW)
   {
     OUTPUT ("backward arrow has:\n");
     if (arrow (fp) == FAIL)
       return FAIL;
   }

   /* Transfig Manual and xfig's FORMAT2.1 for version 2.1.8 */
   /* disagree with transfig's read.c and xfig/Example/logo.fig; */
   /* I go with the latter, until proven otherwise. */

   if (sub_type == T_EPS_BOX)
   {
       int ch;

       fscanf (fp, "%d", &flipped);

       fscanf (fp, "%100s", epsfile);

       /* skip any remaining characters in EPS filename */
       while (! isspace (ch = getc(fp)))
           ;

       OUTPUT ("EPS orientation = ");
       switch (flipped)
       {
           case EPS_UPRIGHT:
               OUTPUT ("upright");
               break;
           case EPS_FLIPPED:
               OUTPUT ("flipped");
               break;
           default:
               OUTPUT ("INVALID");
               put_msg ("INVALID EPS orientation!");
               return FAIL;
               break;
       }
       OUTPUT ("\n");
       OUTPUT ("EPS filename = `%s'\n", epsfile);
   }

   OUTPUT ("Corner points:\n");
   if (points (fp, &npts) == FAIL)
       return FAIL;

   return OK;

} /* polyline */


#define T_OPEN_NORMAL      0
#define T_CLOSED_NORMAL    1
#define T_OPEN_INTERPOLATED    2
#define T_CLOSED_INTERPOLATED  3

int
spline
#ifdef __STDC__
 (FILE * fp)
#else
 (fp)
   FILE * fp;
#endif
{
   int  sub_type;
   int  fa,
        ba;
   int  nkeys;

   OUTPUT ("Spline Object:\n");

   fscanf (fp, "%d", &sub_type);

   switch (sub_type)
   {
       case T_OPEN_NORMAL:
           OUTPUT ("open B-spline");
           break;
       case T_CLOSED_NORMAL:
           OUTPUT ("closed B-spline");
           break;
       case T_OPEN_INTERPOLATED:
           OUTPUT ("open interpolated spline");
           break;
       case T_CLOSED_INTERPOLATED:
           OUTPUT ("closed interpolated spline");
           break;
       default:
           OUTPUT ("INVALID spline sub_type");
           put_msg ("INVALID spline sub_type!");
           return FAIL;
           break;
   }
   OUTPUT ("\n");

   if (common_fields (fp) == FAIL)
       return FAIL;

   fscanf (fp, "%d", &fa);
   fscanf (fp, "%d", &ba);

   if (arrow_check (fa, ba) == FAIL)
       return FAIL;

   if (fa == ARROW)
   {
     OUTPUT ("forward arrow has:\n");
     if (arrow (fp) == FAIL)
       return FAIL;
   }

   if (ba == ARROW)
   {
     OUTPUT ("backward arrow has:\n");
     if (arrow (fp) == FAIL)
       return FAIL;
   }

   OUTPUT ("Key points:\n");
   if (points (fp, &nkeys) == FAIL)
       return FAIL;

   switch (sub_type)
   {
       case T_OPEN_INTERPOLATED:
       case T_CLOSED_INTERPOLATED:
       {
           int i;
           OUTPUT ("Control points:\n");
           for (i=0; i < nkeys; i++)
           {
               int j;
               /* two control points per key point */
               for (j=0; j < 2; j++)
               {
                   float    x, y;
                   fscanf (fp, "%f", &x);
                   fscanf (fp, "%f", &y);
                   OUTPUT ("(%.3f, %.3f)  ", x, y);
               }
               OUTPUT ("\n");
           }
       }
   }

   return OK;

} /* spline */


#define T_ELLIPSE_BY_RAD  1
#define T_ELLIPSE_BY_DIA  2
#define T_CIRCLE_BY_RAD   3
#define T_CIRCLE_BY_DIA   4

int
ellipse
#ifdef __STDC__
 (FILE * fp)
#else
 (fp)
   FILE * fp;
#endif
{
   int    sub_type;
   int    direction;
   float  angle;
   int    cx, cy,
          rx, ry,
          sx, sy,
          ex, ey;

   OUTPUT ("Ellipse Object:\n");

   fscanf (fp, "%d", &sub_type);

   switch (sub_type)
   {
       case T_ELLIPSE_BY_RAD:
           OUTPUT ("ellipse by radius");
           break;
       case T_ELLIPSE_BY_DIA:
           OUTPUT ("ellipse by diameter");
           break;
       case T_CIRCLE_BY_RAD:
           OUTPUT ("circle by radius");
           break;
       case T_CIRCLE_BY_DIA:
           OUTPUT ("circle by diameter");
           break;
       default:
           OUTPUT ("INVALID ellipse sub_type");
           put_msg ("INVALID ellipse sub_type!");
           return FAIL;
           break;
   }
   OUTPUT ("\n");

   if (common_fields (fp) == FAIL)
       return FAIL;

   fscanf (fp, "%d", &direction);
   OUTPUT ("direction = %d  (should be fixed at 1) \n", direction);

   fscanf (fp, "%f", &angle);
   OUTPUT ("angle = %.3f radians\n", angle);

   fscanf (fp, "%d", &cx);
   fscanf (fp, "%d", &cy);
   OUTPUT ("centre = (%d,%d) \n", cx, cy);

   fscanf (fp, "%d", &rx);
   fscanf (fp, "%d", &ry);
   OUTPUT ("radii = (%d,%d) \n", rx, ry);

   fscanf (fp, "%d", &sx);
   fscanf (fp, "%d", &sy);
   OUTPUT ("(Fig internal) start = (%d,%d) \n", sx, sy);

   fscanf (fp, "%d", &ex);
   fscanf (fp, "%d", &ey);
   OUTPUT ("(Fig internal) end = (%d,%d) \n", ex, ey);

   return OK;

} /* ellipse */


#define T_3_POINT_ARC  1

#define CLOCKWISE  0
#define COUNTER    1

int
arc
#ifdef __STDC__
 (FILE * fp)
#else
 (fp)
   FILE * fp;
#endif
{
   int    sub_type;
   int    direction;
   int    fa, ba;
   float  cx, cy;
   int    x1, y1,
          x2, y2,
          x3, y3;

   OUTPUT ("Arc Object:\n");

   fscanf (fp, "%d", &sub_type);

   if (sub_type == T_3_POINT_ARC)
       OUTPUT ("three point arc\n");
   else
   {
       OUTPUT ("INVALID arc sub_type %d\n", sub_type);
       put_msg ("INVALID arc sub_type!");
       return FAIL;
   }

   if (common_fields (fp) == FAIL)
       return FAIL;

   fscanf (fp, "%d", &direction);
   OUTPUT ("direction = ");
   switch (direction)
   {
       case CLOCKWISE:
           OUTPUT ("clockwise");
           break;
       case COUNTER:
           OUTPUT ("counter clockwise");
           break;
       default:
           OUTPUT ("INVALID (%d)", direction);
           put_msg ("INVALID direction!");
           return FAIL;
           break;
   }
   OUTPUT ("\n");

   fscanf (fp, "%d", &fa);
   fscanf (fp, "%d", &ba);

   if (arrow_check (fa, ba) == FAIL)
       return FAIL;

   fscanf (fp, "%f", &cx);
   fscanf (fp, "%f", &cy);
   OUTPUT ("centre = (%.3f, %.3f)\n", cx, cy);

   fscanf (fp, "%d", &x1);
   fscanf (fp, "%d", &y1);
   OUTPUT ("point 1 = (%d, %d)\n", x1, y1);

   fscanf (fp, "%d", &x2);
   fscanf (fp, "%d", &y2);
   OUTPUT ("point 2 = (%d, %d)\n", x2, y2);

   fscanf (fp, "%d", &x3);
   fscanf (fp, "%d", &y3);
   OUTPUT ("point 3 = (%d, %d)\n", x3, y3);

   if (fa == ARROW)
   {
     OUTPUT ("forward arrow has:\n");
     if (arrow (fp) == FAIL)
       return FAIL;
   }

   if (ba == ARROW)
   {
     OUTPUT ("backward arrow has:\n");
     if (arrow (fp) == FAIL)
       return FAIL;
   }

   return OK;

} /* arc */


#define T_LEFT_JUSTIFIED    0
#define T_CENTER_JUSTIFIED  1
#define T_RIGHT_JUSTIFIED   2

#define DEFAULT_FONT_0  0
#define DEFAULT_FONT_1  (-1)

#define ROMAN       1
#define BOLD        2
#define ITALICS     3
#define MODERN      4
#define TYPEWRITER  5

#define NO_TEXT       0
#define RIGID_TEXT    1
#define SPECIAL_TEXT  2
#define PSFONT_TEXT   4
#define HIDDEN_TEXT   8

#define TR       1
#define TI       2
#define TB       3
#define TBI      4
#define AG       5
#define AGBO     6
#define AGD      7
#define AGDO     8
#define BKL      9
#define BKLI    10
#define BKD     11
#define BKDI    12
#define COUR    13
#define COURO   14
#define COURB   15
#define COURBI  16
#define HV      17
#define HVO     18
#define HVB     19
#define HVBO    20
#define HVN     21
#define HVNO    22
#define HVNB    23
#define HVNBO   24
#define NCR     25
#define NCI     26
#define NCB     27
#define NCBI    28
#define PLR     29
#define PLI     30
#define PLB     31
#define PLBI    32
#define SYMBOL  33
#define ZCMI    34
#define ZDING   35

int
text
#ifdef __STDC__
 (FILE * fp)
#else
 (fp)
   FILE * fp;
#endif
{
   int    sub_type;
   int    font;
   float  size;
   int    pen,
          color,
          depth;
   float  angle;
   int    text_flags;
   float  height, length;
   int    x, y;

   char     text[80],    /* WARNING:  THIS MAY NOT BE BIG ENOUGH! */
       junk[2];

   OUTPUT ("Text Object:\n");

   fscanf (fp, "%d", &sub_type);
   OUTPUT ("sub_type = ");
   switch (sub_type)
   {
       case T_LEFT_JUSTIFIED:
           OUTPUT ("left justified");
           break;
       case T_CENTER_JUSTIFIED:
           OUTPUT ("centre justified");
           break;
       case T_RIGHT_JUSTIFIED:
           OUTPUT ("right justified");
           break;
       default:
           OUTPUT ("INVALID text sub_type = %d", sub_type);
           put_msg ("INVALID text sub_type!");
           return FAIL;
           break;
   }
   OUTPUT ("\n");

   fscanf (fp, "%d", &font);

   OUTPUT ("font = %d  (this code is to be interpreted below)\n", font);

   fscanf (fp, "%f", &size);
   OUTPUT ("font size = %.3f\n", size);

   fscanf (fp, "%d", &pen);
   OUTPUT ("pen = %d  (should be default = 0 or -1) \n", pen);

   fscanf (fp, "%d", &color);
   OUTPUT ("color = %d  (should be default = 0 or -1) \n", color);

   fscanf (fp, "%d", &depth);
   OUTPUT ("depth = level %d\n", depth);

   fscanf (fp, "%f", &angle);
   OUTPUT ("angle = %.3f radians\n", angle);

   fscanf (fp, "%d", &text_flags);
   OUTPUT ("text flags:  ");
   if (text_flags == NO_TEXT)
       OUTPUT ("none");
   else
   {
       if (text_flags & RIGID_TEXT)
           OUTPUT ("rigid ");
       if (text_flags & SPECIAL_TEXT)
           OUTPUT ("special ");
       if (text_flags & PSFONT_TEXT)
           OUTPUT ("PostScript ");
       if (text_flags & HIDDEN_TEXT)
           OUTPUT ("hidden ");
   }
   OUTPUT ("\n");

   OUTPUT ("font name = ");
   if (text_flags & PSFONT_TEXT)
   {
       switch (font)
       {
           case DEFAULT_FONT_0:
           case DEFAULT_FONT_1:
               OUTPUT ("default");
               break;
           case TR:
               OUTPUT ("Times-Roman");
               break;
           case TI:
               OUTPUT ("Times-Italic");
               break;
           case TB:
               OUTPUT ("Times-Bold");
               break;
           case TBI:
               OUTPUT ("Times-Bold-Italic");
               break;
           case AG:
               OUTPUT ("AvantGarde");
               break;
           case AGBO:
               OUTPUT ("AvantGarde-BookOblique");
               break;
           case AGD:
               OUTPUT ("AvantGarde-Demi");
               break;
           case AGDO:
               OUTPUT ("AvantGarde-DemiOblique");
               break;
           case BKL:
               OUTPUT ("Bookman-Light");
               break;
           case BKLI:
               OUTPUT ("Bookman-LightItalic");
               break;
           case BKD:
               OUTPUT ("Bookman-Demi");
               break;
           case BKDI:
               OUTPUT ("Bookman-DemiItalic");
               break;
           case COUR:
               OUTPUT ("Courier");
               break;
           case COURO:
               OUTPUT ("Courier-Oblique");
               break;
           case COURB:
               OUTPUT ("Courier-Bold");
               break;
           case COURBI:
               OUTPUT ("Courier-BoldItalic");
               break;
           case HV:
               OUTPUT ("Helvetica");
               break;
           case HVO:
               OUTPUT ("Helvetica-Oblique");
               break;
           case HVB:
               OUTPUT ("Helvetica-Bold");
               break;
           case HVBO:
               OUTPUT ("Helvetica-BoldOblique");
               break;
           case HVN:
               OUTPUT ("Helvetica-Narrow");
               break;
           case HVNO:
               OUTPUT ("Helvetica-Narrow-Oblique");
               break;
           case HVNB:
               OUTPUT ("Helvetica-Narrow-Bold");
               break;
           case HVNBO:
               OUTPUT ("Helvetica-Narrow-BoldOblique");
               break;
           case NCR:
               OUTPUT ("NewCenturySchlbk-Roman");
               break;
           case NCI:
               OUTPUT ("NewCenturySchlbk-Italic");
               break;
           case NCB:
               OUTPUT ("NewCenturySchlbk-Bold");
               break;
           case NCBI:
               OUTPUT ("NewCenturySchlbk-BoldItalic");
               break;
           case PLR:
               OUTPUT ("Palatino-Roman");
               break;
           case PLI:
               OUTPUT ("Palatino-Italic");
               break;
           case PLB:
               OUTPUT ("Palatino-Bold");
               break;
           case PLBI:
               OUTPUT ("Palatino-BoldItalic");
               break;
           case SYMBOL:
               OUTPUT ("Symbol");
               break;
           case ZCMI:
               OUTPUT ("ZapfChancery-MediumItalic");
               break;
           case ZDING:
               OUTPUT ("ZapfDingbats");
               break;
           default:
               OUTPUT ("INVALID PostScript font = %d\n", font);
               put_msg ("INVALID PostScript font!");
               return FAIL;
               break;
       }
   }
   else
   {
       switch (font)
       {
           case DEFAULT_FONT_0:
           case DEFAULT_FONT_1:
               OUTPUT ("default");
               break;
           case ROMAN:
               OUTPUT ("Roman");
               break;
           case BOLD:
               OUTPUT ("Bold");
               break;
           case ITALICS:
               OUTPUT ("Italics");
               break;
           case MODERN:
               OUTPUT ("Modern (sans serif)");
               break;
           case TYPEWRITER:
               OUTPUT ("Typewriter");
               break;
           default:
               OUTPUT ("INVALID Fig font = %d", font);
               put_msg ("INVALID Fig font!");
               return FAIL;
               break;
       }
   }
   OUTPUT ("\n");

   fscanf (fp, "%f", &height);
   OUTPUT ("height = %.3f pixels\n", height);

   fscanf (fp, "%f", &length);
   OUTPUT ("length = %.3f pixels\n", length);

   fscanf (fp, "%d", &x);
   fscanf (fp, "%d", &y);
   OUTPUT ("text location = (%d, %d) \n", x, y);

   fscanf (fp, "%[^\1]%[\1]", text, junk);
   OUTPUT ("text = `%s'\n", text);

   return OK;

} /* text */


/* end of fig2eng 0.4 of Mon 27 June 1994 */