/*
 * $Id: dxf.trm,v 3.26 92/03/24 22:34:49 woo Exp Locker: woo $
 */

/* GNUPLOT - dxf.trm */
/*
 * Copyright (C) 1991, 1992
 *
 * Permission to use, copy, and distribute this software and its
 * documentation for any purpose with or without fee is hereby granted,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.
 *
 * Permission to modify the software is granted, but not the right to
 * distribute the modified code.  Modifications are to be distributed
 * as patches to released version.
 *
 * This software  is provided "as is" without express or implied warranty.
 *
 * This file is included by ../term.c.
 *
 * This terminal driver supports:
 *   AutoCad (Release 10.x) dxf file format (import with AutoCad dxfin command)
 *
 *
 * AUTHOR
 *   Florian Hiss  (fhis1231@w204zrz.zrz.tu-berlin.de)
 *
 * send your comments or suggestions to (info-gnuplot@ames.arc.nasa.gov).
*/

#define DXF_UNIT 60.0
#define LINEWIDTH 0.0351  /* default line width is 1 pt */

/* 120 (autocad units) wide by 80 (autocad units) high (default)
   use the GNUPLOT 'set size' command to change the defaults */
#define DXF_XMAX (120.0 * DXF_UNIT)
#define DXF_YMAX (80.0 * DXF_UNIT)
#define DXF_HTIC (0.01 * DXF_XMAX)  /* 1.0 percent */
#define DXF_VTIC (0.01 * DXF_YMAX)  /* 1.0 percent */
#define DXF_HCHAR (0.014 * DXF_XMAX) /* 1.4 percent */
#define DXF_VCHAR (0.026 * DXF_YMAX) /* 2.6 percent */
#define DXF_TEXTHEIGHT (0.7 * DXF_VCHAR) /* actual text height */
#define DXF_TEXTWIDTH (0.7 * DXF_HCHAR) /* actual text width,
 only a guess, we don't know the width of a character of given height
 of the AutoCad STANDARD text font, so change it if you like */
#define DXF_LINE_TYPES 7 /* number of line types we support. see below  */
#define MAX_LAYER 7  /* number of layers used for the drawing. see below */
#define LT_SCALE 1  /* line type scaling */

static unsigned int DXF_posx;
static unsigned int DXF_posy;
static unsigned int dxf_linetype; /* linetype is mapped to a layer. see below. */
enum JUSTIFY dxf_justify = LEFT;
static float dxf_angle = 0.0; /* either 0 (horizontal) or 90.0 (vertical) */

/* text style used in the entire drawing */
static char *text_style = "STANDARD";
/* text always resides on layer 0 */
#define TEXT_LAYER 0
/* each linetype resides on its own layer. each layer has its own color.
   this avoids difficulties that AutoCad has with proper scaling of
   the linetypes.
   change the colors according to your needs */
static char *layer_name[] = {"0","1","2","3","4","5","6"};
/* the colours are white, red, yellow, green, cyan, blue, magenta.
   change them according to your needs.
   when using a black and white plotting device the colours map to different
   line thicknesses. see description of AutoCad print / plot command */
static char *layer_colour[] = {"7","1","2","3","4","5","6"};
/* support line types AutoCad has to offer by default. */
static char *layer_lines[] = {"CONTINUOUS","DASHED","HIDDEN","CENTER","PHANTOM",
			    "DOT","DASHDOT"};

static BOOLEAN vector_was_last = FALSE;

DXF_init()
{
	DXF_posx = DXF_posy = 0;
	dxf_linetype = 0;
	dxf_angle = 0.0;
	vector_was_last = FALSE;
}

DXF_graphics()
{
	register struct termentry *t = &term_tbl[term];
	int i;

	fprintf(outfile,"999\n");
	fprintf(outfile,"%% GNUPLOT: dxf file for AutoCad\n");
	fprintf(outfile,"  0\nSECTION\n  2\nHEADER\n");
	fprintf(outfile,"  9\n$EXTMIN\n");
	fprintf(outfile," 10\n0.000\n 20\n0.000\n");
	fprintf(outfile,"  9\n$EXTMAX\n");
	fprintf(outfile," 10\n%-6.3f\n 20\n%-6.3f\n",t->xmax/DXF_UNIT,t->ymax/DXF_UNIT);
	fprintf(outfile,"  9\n$LIMMIN\n");
	fprintf(outfile," 10\n0.000\n 20\n0.000\n");
	fprintf(outfile,"  9\n$LIMMAX\n");
	fprintf(outfile," 10\n%-6.3f\n 20\n%-6.3f\n",t->xmax/DXF_UNIT,t->ymax/DXF_UNIT);
	fprintf(outfile,"  9\n$TEXTSTYLE\n  7\n%s\n",text_style);
	fprintf(outfile,"  9\n$TEXTSIZE\n 40\n%-6.3f\n",DXF_TEXTHEIGHT/DXF_UNIT);
	fprintf(outfile,"  9\n$PLINEWID\n 40\n%-6.4f\n",LINEWIDTH);
	fprintf(outfile,"  9\n$LTSCALE\n  40\n%-6.3f\n",LT_SCALE);
	fprintf(outfile,"  9\n$COORDS\n 70\n  1\n");
	fprintf(outfile,"  9\n$CELTYPE\n 6\nBYLAYER\n"); /* entity line type name */
	fprintf(outfile,"  9\n$CLAYER\n  8\n0\n"); /* current layer */
	fprintf(outfile,"  9\n$CECOLOR\n 62\n   %s\n",layer_colour[0]);
	fprintf(outfile,"  9\n$MENU\n  1\nacad\n");
	fprintf(outfile,"  0\nENDSEC\n");
	fprintf(outfile,"  0\nSECTION\n  2\nTABLES\n");
	/* the linetype table */
	fprintf(outfile,"0\nTABLE\n  2\nLTYPE\n 70\n    %d\n",DXF_LINE_TYPES);
	fprintf(outfile,"0\nLTYPE\n  2\nCONTINUOUS\n 70\n    64\n");
	fprintf(outfile,"  3\nSolid line\n 72\n    65\n 73\n      0\n 40\n0.0\n");
	fprintf(outfile,"  0\nLTYPE\n  2\nDASHED\n 70\n    64\n");
	fprintf(outfile,"  3\n__ __ __ __ __ __ __ __ __ __ __ __ __ __ __\n");
	fprintf(outfile," 72\n    65\n 73\n     2\n 40\n0.75\n 49\n0.5\n 49\n-0.25\n");
	fprintf(outfile,"  0\nLTYPE\n  2\nHIDDEN\n 70\n    64\n");
	fprintf(outfile,"  3\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _\n");
	fprintf(outfile," 72\n    65\n 73\n     2\n 40\n0.375\n 49\n0.25\n 49\n-0.125\n");
	fprintf(outfile,"  0\nLTYPE\n  2\nCENTER\n 70\n    64\n");
	fprintf(outfile,"  3\n____ _ ____ _ ____ _ ____ _ ____ _ ____ _ ____\n");
	fprintf(outfile," 72\n    65\n 73\n     4\n 40\n2.0\n 49\n1.25\n 49\n-0.25\n");
	fprintf(outfile," 49\n0.25\n 49\n-0.25\n");
	fprintf(outfile,"  0\nLTYPE\n  2\nPHANTOM\n 70\n    64\n");
	fprintf(outfile,"  3\n_____ _ _ _____ _ _ _____ _ _ _____ _ _ ____\n");
	fprintf(outfile," 72\n    65\n 73\n     6\n 40\n2.5\n 49\n1.25\n");
	fprintf(outfile," 49\n-0.25\n 49\n0.25\n 49\n-0.25\n 49\n0.25\n 49\n-0.25\n");
	fprintf(outfile,"  0\nLTYPE\n  2\nDOT\n 70\n    64\n");
	fprintf(outfile,"  3\n...............................................\n");
	fprintf(outfile," 72\n    65\n 73\n     2\n 40\n0.25\n 49\n0.0\n 49\n-0.25\n");
	fprintf(outfile,"  0\nLTYPE\n  2\nDASHDOT\n 70\n    64\n");
	fprintf(outfile,"  3\n__ . __ . __ . __ . __ . __ . __ . __ . __ . __\n");
	fprintf(outfile," 72\n    65\n 73\n     4\n 40\n1.0\n 49\n0.5\n 49\n-0.25\n");
	fprintf(outfile," 49\n0.0\n 49\n-0.25\n");
	fprintf(outfile,"  0\nENDTAB\n");
	/* the layer table */
	fprintf(outfile,"  0\nTABLE\n  2\nLAYER\n 70\n   %-d\n",MAX_LAYER);
	for (i = 1; i <= MAX_LAYER; i++)
		fprintf(outfile,"  0\nLAYER\n  2\n%s\n 70\n   64\n62\n   %s\n  6\n%s\n",
			layer_name[i-1],layer_colour[i-1],layer_lines[i-1]);
	fprintf(outfile,"  0\nENDTAB\n0\nENDSEC\n");
	/* no blocks for insertion */
	fprintf(outfile,"  0\nSECTION\n  2\nBLOCKS\n  0\nENDSEC\n");
	/* start the entity section */
	fprintf(outfile,"  0\nSECTION\n");
	fprintf(outfile,"  2\nENTITIES\n");
}

DXF_text()
{
	if (vector_was_last) fprintf(outfile,"  0\nSEQEND\n");
	fprintf(outfile,"  0\nENDSEC\n  0\nEOF\n");
}

DXF_linetype(linetype)
	int linetype;
{
	linetype = abs(linetype);
	linetype = linetype%DXF_LINE_TYPES;
	dxf_linetype = linetype;
}

DXF_move(x, y)
	unsigned int x, y;
{
	DXF_posx = x;
	DXF_posy = y;
	if (vector_was_last) fprintf(outfile,"  0\nSEQEND\n");
	vector_was_last = FALSE;
	fprintf(outfile,"  0\nPOLYLINE\n  8\n%s\n 66\n   1\n",layer_name[dxf_linetype]);
	fprintf(outfile,"  6\n%s\n",layer_lines[dxf_linetype]);
	fprintf(outfile,"  0\nVERTEX\n  8\n%s\n",layer_name[dxf_linetype]);
	fprintf(outfile,"  6\n%s\n",layer_lines[dxf_linetype]);
	fprintf(outfile," 10\n%-6.3f\n 20\n%-6.3f\n 30\n0.000\n",DXF_posx/DXF_UNIT,DXF_posy/DXF_UNIT);
}

DXF_vector(ux, uy)
	unsigned int ux, uy;
{
	DXF_posx = ux;
	DXF_posy = uy;
	vector_was_last = TRUE;
	fprintf(outfile,"  0\nVERTEX\n  8\n%s\n",layer_name[dxf_linetype]);
	fprintf(outfile,"  6\n%s\n",layer_lines[dxf_linetype]);
	fprintf(outfile,"  10\n%-6.3f\n  20\n%-6.3f\n  30\n0.000\n",
					DXF_posx/DXF_UNIT,DXF_posy/DXF_UNIT);
}

DXF_put_text(x, y, str)
	int x, y;
	char str[];
{
	int stl;
	float xleftpos, yleftpos, xrightpos,yrightpos;
	/* ignore empty strings */
	if (str[0] == '\0') return;

	stl = 0; while (str[stl] != '\0') ++stl; /* get string length */

	if (vector_was_last) fprintf(outfile,"  0\nSEQEND\n");
	vector_was_last = FALSE;
	fprintf(outfile,"  0\nTEXT\n  8\n%s\n",layer_name[TEXT_LAYER]);
	if (dxf_angle != 90.0)
	{
	   switch (dxf_justify)
	   {
	   	case LEFT  : xleftpos = (float) x;
			     yleftpos = (float)(y-DXF_VCHAR/4.0);
			     xrightpos = (float)(x+stl*DXF_TEXTWIDTH);
			     yrightpos = yleftpos; break;
	   	case RIGHT : xleftpos = (float)(x-stl*DXF_TEXTWIDTH);
			     yleftpos = (float)(y-DXF_VCHAR/4.0);
			     xrightpos = (float) x;
			     yrightpos = yleftpos; break;
		case CENTRE: xleftpos = (float)(x-stl*DXF_TEXTWIDTH/2.0);
			     yleftpos = (float)(y-DXF_VCHAR/4.0);
			     xrightpos = (float) x;  /* center point */
			     yrightpos = yleftpos;
			     break;
	    }
	}
	else
	{
	    switch (dxf_justify)
	    {
	   	case LEFT  : xleftpos = (float)(x+DXF_VCHAR/4.0);
			     yleftpos = (float) y;
			     xrightpos = xleftpos;
			     yrightpos = (float)(y+stl*DXF_TEXTWIDTH); break;
	   	case RIGHT : xleftpos = (float)(x+DXF_VCHAR/4.0);
			     yleftpos = (float)(y-stl*DXF_HCHAR);
			     xrightpos = xleftpos;
			     yrightpos = (float) y; break;
		case CENTRE: xleftpos = (float)(x+DXF_VCHAR/4.0);
			     yleftpos = (float)(y-stl*DXF_TEXTWIDTH/2.0);
			     xrightpos = xleftpos;
			     yrightpos = (float) y;  /* center point */
			     break;
	    }
	}
	fprintf(outfile," 10\n%-6.3f\n 20\n%-6.3f\n 30\n0.000\n",
				xleftpos/DXF_UNIT,yleftpos/DXF_UNIT);
	fprintf(outfile," 40\n%-6.3f\n  1\n%s\n 50\n%-6.3f\n",
			DXF_TEXTHEIGHT/DXF_UNIT,str,dxf_angle);
	fprintf(outfile,"  7\n%s\n",text_style);
	if (dxf_justify != LEFT)
	{
		fprintf(outfile," 72\n%d\n",dxf_justify);
		fprintf(outfile," 11\n%-6.3f\n 21\n%-6.3f\n 31\n0.000\n",
				xrightpos/DXF_UNIT,yrightpos/DXF_UNIT);
	}
}

DXF_text_angle(angle)
	int angle;
{
	dxf_angle = 0.0;
	if (angle == 1) dxf_angle = 90.0;
	return(TRUE);
}

DXF_justify_text(mode)
	enum JUSTIFY mode;
{
	dxf_justify = mode;
	return(TRUE);
}

DXF_reset()
{
	DXF_posx = DXF_posy = 0;
}


