/* fig2eng.c -- version 0.4 -- 21:29 GMT +10  Mon 27 June 1994.
 *
 *  fig2eng -- Convert Fig 2.1 code numbers to English.
 *
 *  Geoffrey Tobin
 *  ecsgrt@luxor.latrobe.edu.au
 *
 *  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 */