/*
 *----------------------------------------------------------------------
 *
 * PROGRAM	: gksmc
 *
 * FILE		: cgm.c
 *
 * CONTENTS	: Routines to write CGM items which have no direct
 *		  Annex E equivalent.
 *
 * GLOBALS USED : mf_name, mf_version, mf_descr, mf_category, vdc_type,
 *		  MinInt, MaxInt, MaxIntBits, MinReal, MaxReal,
 *		  SigPlaces, MinRealCode, MaxRealCode, DefaultExponent,
 *		  max_colr, picture_name, VDC_lower, VDC_upper.
 *
 * DATE		: 24th April 1988
 *
 *----------------------------------------------------------------------
 */

#include <stdio.h>
#include "cgm.h"
#include "defns.h"
#include "tables.h"
#include "annexe.h"

extern FILE *MF_infile,
       *MF_outfile;



/*
 *-------------------------------------------------------------------------
 * CGMbegin_metafile:
 *	Writes the BEGIN METAFILE element used to mark the start of a CGM.
 * The clear text version has a 'name' string parameter, the character
 * encoding item has the substitution string followed by the name. The
 * substitution string gives the two character sequences to be substituted
 * for certain control characters.
 *-------------------------------------------------------------------------
 */
CGMbegin_metafile()
{
	write_item_name(MF_outfile, CGM_TABLE, BEGMF);
	if (Encoding == CLEAR_TEXT)
	{
		write_separator(MF_outfile, OPTSEP);
		write_CGM_string(MF_outfile, mf_name, DEFAULT);
		write_separator(MF_outfile, TERMINATOR);
	}
	else
	{
		write_CGM_string(MF_outfile, "", NO_SOS);	/* Substitution string */
		write_CGM_string(MF_outfile, mf_name, DEFAULT);
	}
}


/*
 *-------------------------------------------------------------------------
 * CGMmetafile_version:
 *	Writes the METAFILE VERSION item. The version number is held in the
 * global mf_version, set in tables.c.
 *-------------------------------------------------------------------------
 */
CGMmetafile_version()
{
	write_item_name(MF_outfile, CGM_TABLE, MFVERSION);
	write_separator(MF_outfile, SOFTSEP);
	write_int(MF_outfile, mf_version);
	write_separator(MF_outfile, TERMINATOR);
}


/*
 *-------------------------------------------------------------------------
 * CGMmetafile_description:
 *	Writes the METAFILE DESCRIPTION item which has a string parameter,
 * defined in tables.c. The string can be redefined in the defaults file.
 *-------------------------------------------------------------------------
 */
CGMmetafile_description()
{
	write_item_name(MF_outfile, CGM_TABLE, MFDESC);
	write_separator(MF_outfile, OPTSEP);
	write_CGM_string(MF_outfile, mf_descr, DEFAULT);
	write_separator(MF_outfile, TERMINATOR);
}


/*
 *-------------------------------------------------------------------------
 * CGMmetafile_category:
 *	Writes the METAFILE CATEGORY item. Current legal categories are
 *	CGM     : Metafile conforms to ISO 8632, first CGM standard.
 *	GKSM    : Metafile can be used as a GKS metafile.
 *	CGMEXT1 : Metafile conforms to the functional spec in Addendum 1.
 * This program produces a metafile of category CGMEXT1.
 *-------------------------------------------------------------------------
 */
CGMmetafile_category()
{
	write_item_name(MF_outfile, CGM_TABLE, MFCATEGORY);
	write_separator(MF_outfile, SOFTSEP);
	write_enum_value(MF_outfile, E_MFCAT, mf_category);
	write_separator(MF_outfile, TERMINATOR);
}


/*
 *-------------------------------------------------------------------------
 * CGMmetafile_element_list:
 *	Writes the METAFILE ELEMENT LIST item, which lists the items
 * occuring in the metafile in a string parameter. The words DRAWINGSET
 * and DRAWINGPLUS may be used, as described in ISO 8632.
 *-------------------------------------------------------------------------
 */
CGMmetafile_element_list()
{
	write_item_name(MF_outfile, CGM_TABLE, MFELEMLIST);
	write_separator(MF_outfile, OPTSEP);
	if (Encoding == CLEAR_TEXT)
		fprintf(MF_outfile, "\"");
	else
		fprintf(MF_outfile, "%s", SOS);
	write_enum_value(MF_outfile, E_ELEMGROUP, DRAWINGPLUS);
	if (Encoding == CLEAR_TEXT)
		fprintf(MF_outfile, "\"");
	else
		fprintf(MF_outfile, "%s", ST);
	write_separator(MF_outfile, TERMINATOR);
}


/*
 *-------------------------------------------------------------------------
 * CGMchar_coding_announcer:
 *	Writes the CHARACTER CODING ANNOUNCER item, which informs the
 * metafile interpreter of the code extension capabilities assumed by the
 * metafile generator.
 *-------------------------------------------------------------------------
 */
CGMchar_coding_announcer()
{
	write_item_name(MF_outfile, CGM_TABLE, CHARCODING);
	write_separator(MF_outfile, SOFTSEP);
	write_enum_value(MF_outfile, E_CHARCODING, EXTD7BIT);
	write_separator(MF_outfile, TERMINATOR);
}


/*
 *-------------------------------------------------------------------------
 * CGMvdc_type:
 *	Writes the VDC TYPE item, which specifies whether VDC values are
 * to be given as reals or integers.
 *-------------------------------------------------------------------------
 */
CGMvdc_type()
{
	write_item_name(MF_outfile, CGM_TABLE, VDCTYPE);
	write_separator(MF_outfile, SOFTSEP);
	write_enum_value(MF_outfile, E_VDCTYPE, vdc_type);
	write_separator(MF_outfile, TERMINATOR);
}


/*
 *-------------------------------------------------------------------------
 * CGMinteger_precision:
 *	Writes the INTEGER PRECISION item, giving the range of integers
 * permissible in the metafile.
 *-------------------------------------------------------------------------
 */
CGMinteger_precision()
{
	write_item_name(MF_outfile, CGM_TABLE, INTEGERPREC);
	if (Encoding == CLEAR_TEXT)
	{
		write_separator(MF_outfile, SOFTSEP);
		write_int(MF_outfile, MinInt);
		write_separator(MF_outfile, SEP);
		write_int(MF_outfile, MaxInt);
		write_separator(MF_outfile, TERMINATOR);
	}
	else
		write_int(MF_outfile, MaxIntBits + 1);
}


/*
 *-------------------------------------------------------------------------
 * CGMreal_precision:
 *	Writes the REAL PRECISION item, which specifies the range of reals
 * permissible in the metafile, and the number of decimal places used.
 *-------------------------------------------------------------------------
 */
CGMreal_precision()
{
	write_item_name(MF_outfile, CGM_TABLE, REALPREC);
	if (Encoding == CLEAR_TEXT)
	{
		write_separator(MF_outfile, SOFTSEP);
		write_real(MF_outfile, MinReal);
		write_separator(MF_outfile, SEP);
		write_real(MF_outfile, MaxReal);
		write_separator(MF_outfile, SEP);
		write_int(MF_outfile, SigPlaces);
		write_separator(MF_outfile, TERMINATOR);
	}
	else
	{
		write_int(MF_outfile, MaxRealCode + 1);
		write_int(MF_outfile, MinRealCode);
		write_int(MF_outfile, DefaultExponent);
		write_int(MF_outfile, ALLOWED);
	}
}


/*
 *-------------------------------------------------------------------------
 * CGMvdc_integer_precision:
 *	Writes the VDC INTEGER PRECISION item, which gives the range of
 * integers used for VDC values if VDC type = integer. The range given is
 * the same as that for INTEGER PRECISION.
 *-------------------------------------------------------------------------
 */
CGMvdc_integer_precision()
{
	write_item_name(MF_outfile, CGM_TABLE, VDCINTEGERPREC);
	if (Encoding == CLEAR_TEXT)
	{
		write_separator(MF_outfile, SOFTSEP);
		write_int(MF_outfile, MinInt);
		write_separator(MF_outfile, SEP);
		write_int(MF_outfile, MaxInt);
		write_separator(MF_outfile, TERMINATOR);
	}
	else
		write_int(MF_outfile, MaxIntBits + 1);
}


/*
 *-------------------------------------------------------------------------
 * CGMvdc_real_precision:
 *	Writes the VDC REAL PRECISION item, specifying the range of reals
 * used for VDC values if VDC type = real. The range given is the same as
 * that for REAL PRECISION.
 *-------------------------------------------------------------------------
 */
CGMvdc_real_precision()
{
	write_item_name(MF_outfile, CGM_TABLE, VDCREALPREC);
	if (Encoding == CLEAR_TEXT)
	{
		write_separator(MF_outfile, SOFTSEP);
		write_real(MF_outfile, MinReal);
		write_separator(MF_outfile, SEP);
		write_real(MF_outfile, MaxReal);
		write_separator(MF_outfile, SEP);
		write_int(MF_outfile, SigPlaces);
		write_separator(MF_outfile, TERMINATOR);
	}
	else
	{
		write_int(MF_outfile, MaxRealCode + 1);
		write_int(MF_outfile, MinRealCode);
		write_int(MF_outfile, DefaultExponent);
		write_int(MF_outfile, ALLOWED);
	}
}


/*
 *-------------------------------------------------------------------------
 * CGMindex_precision:
 *	Writes the INDEX PRECISION item, which defines the range of
 * integers that can be used to specify an index value, such as a colour
 * index. The range used tis the same as for INTEGER PRECISION.
 *-------------------------------------------------------------------------
 */
CGMindex_precision()
{
	write_item_name(MF_outfile, CGM_TABLE, INDEXPREC);
	if (Encoding == CLEAR_TEXT)
	{
		write_separator(MF_outfile, SOFTSEP);
		write_int(MF_outfile, MinInt);
		write_separator(MF_outfile, SEP);
		write_int(MF_outfile, MaxInt);
		write_separator(MF_outfile, TERMINATOR);
	}
	else
		write_int(MF_outfile, MaxIntBits + 1);
}


/*
 *-------------------------------------------------------------------------
 * CGMcolour_precision:
 *	Writes the COLOUR PRECSION item, which gives the maximum integer
 * that can be used as a red, green or blue intensity.
 *-------------------------------------------------------------------------
 */
CGMcolour_precision()
{
	write_item_name(MF_outfile, CGM_TABLE, COLRPREC);
	if (Encoding == CLEAR_TEXT)
	{
		write_separator(MF_outfile, SOFTSEP);
		write_int(MF_outfile, colr_prec);
		write_separator(MF_outfile, TERMINATOR);
	}
	else
		write_int(MF_outfile, NumColrBits);
}


/*
 *-------------------------------------------------------------------------
 * CGMsegment_priority_extent:
 *	Writes the SEGMENT PRIORITY EXTENT item, which defines the range of
 * integers that can be used to specify segment priorities. The range used
 * is the positive half of that used for INTEGER PRECISION, ie 0..MaxInt.
 *-------------------------------------------------------------------------
 */
CGMsegment_priority_extent()
{
	write_item_name(MF_outfile, CGM_TABLE, SEGPRIEXT);
	write_separator(MF_outfile, SOFTSEP);
	write_int(MF_outfile, 0);
	write_separator(MF_outfile, SEP);
	write_int(MF_outfile, MaxInt);
	write_separator(MF_outfile, TERMINATOR);
}


/*
 *-------------------------------------------------------------------------
 * CGMmax_colour_index:
 *	Writes the MAXIMUM COLOUR INDEX item, which specifies the range of
 * colours available. The default is 127, declared in tables.c, but can
 * be redefined in the defaults file.
 *-------------------------------------------------------------------------
 */
CGMmax_colour_index()
{
	write_item_name(MF_outfile, CGM_TABLE, MAXCOLRINDEX);
	write_separator(MF_outfile, SOFTSEP);
	write_int(MF_outfile, max_colr);
	write_separator(MF_outfile, TERMINATOR);
}


/*
 *-------------------------------------------------------------------------
 * CGMbegin_picture:
 *	Writes the BEGIN PICTURE followed by the Picture Name string,
 * declared in tables.c. The string can be redefined in the defaults file.
 *-------------------------------------------------------------------------
 */
CGMbegin_picture()
{
	write_item_name(MF_outfile, CGM_TABLE, BEGPIC);
	write_separator(MF_outfile, OPTSEP);
	write_CGM_string(MF_outfile, picture_name, DEFAULT);
	write_separator(MF_outfile, TERMINATOR);
}


/*
 *-------------------------------------------------------------------------
 * CGMscaling_mode:
 *	Writes the SCALING MODE item, which defines the meaning associated
 * with the VDC. If ABSTRACT, VDC is dimensionless. If METRIC, VDC has
 * implied size, the metric scale factor parameter represents the distance
 * (in mm) on the displayed picture of 1 VDC unit.
 *-------------------------------------------------------------------------
 */
CGMscaling_mode()
{
	write_item_name(MF_outfile, CGM_TABLE, SCALEMODE);
	write_separator(MF_outfile, SOFTSEP);
	write_enum_value(MF_outfile, E_SCALESPEC, ABSTRACT);
	write_separator(MF_outfile, SEP);
	write_real(MF_outfile, 1.0);
	write_separator(MF_outfile, TERMINATOR);
}


/*
 *-------------------------------------------------------------------------
 * CGMcolour_selection_mode:
 *	Writes the COLOUR SELECTION MODE item, which can either be INDEXED
 * or DIRECT. INDEXED is always selected, since this is the method used
 * in Annex E.
 *-------------------------------------------------------------------------
 */
CGMcolour_selection_mode()
{
	write_item_name(MF_outfile, CGM_TABLE, COLRMODE);
	write_separator(MF_outfile, SOFTSEP);
	write_enum_value(MF_outfile, E_COLRSEL, INDEXED);
	write_separator(MF_outfile, TERMINATOR);
}


/*
 *-------------------------------------------------------------------------
 * CGMline_width_spec_mode:
 *	Writes the LINE WIDTH SPECIFICATION MODE item. The parameter is
 * always set to SCALED, following Annex E.
 *-------------------------------------------------------------------------
 */
CGMline_width_spec_mode()
{
	write_item_name(MF_outfile, CGM_TABLE, LINEWIDTHMODE);
	write_separator(MF_outfile, SOFTSEP);
	write_enum_value(MF_outfile, E_SPEC, SCALED);
	write_separator(MF_outfile, TERMINATOR);
}


/*
 *-------------------------------------------------------------------------
 * CGMmarker_size_spec_mode:
 *	Writes the MARKER SIZE SPECIFICATION MODE item, which is always
 * set to SCALED.
 *-------------------------------------------------------------------------
 */
CGMmarker_size_spec_mode()
{
	write_item_name(MF_outfile, CGM_TABLE, MARKERSIZEMODE);
	write_separator(MF_outfile, SOFTSEP);
	write_enum_value(MF_outfile, E_SPEC, SCALED);
	write_separator(MF_outfile, TERMINATOR);
}


/*
 *-------------------------------------------------------------------------
 * CGMvdc_extent:
 *	Writes the CGM EXTENT item, which defines the range of VDC values
 * used for a picture.
 *-------------------------------------------------------------------------
 */
CGMvdc_extent()
{
	write_item_name(MF_outfile, CGM_TABLE, VDCEXT);
	write_separator(MF_outfile, SOFTSEP);
	write_point(MF_outfile, VDC_lower);
	write_separator(MF_outfile, SEP);
	write_point(MF_outfile, VDC_upper);
	write_separator(MF_outfile, TERMINATOR);
}


/*
 *-------------------------------------------------------------------------
 * CGMbegin_picture_body:
 * 	Writes the BEGIN PICTURE BODY item, which markes the end of the
 * Picture Descriptor section of a picture.
 *-------------------------------------------------------------------------
 */
CGMbegin_picture_body()
{
	write_item_name(MF_outfile, CGM_TABLE, BEGPICBODY);
	write_separator(MF_outfile, TERMINATOR);
}


/*
 *-------------------------------------------------------------------------
 * CGMprep_surface:
 *	Writes the PREPARE VIEW SURFACE item, which empties the buffer,
 * then clears the screen. The operation for Hardcopy devices is controlled
 * by the parameter.
 *-------------------------------------------------------------------------
 */
CGMprep_surface(flag)
	int     flag;
{
	write_item_name(MF_outfile, CGM_TABLE, PREPAREVIEWSURFACE);
	write_separator(MF_outfile, SOFTSEP);
	write_enum_value(MF_outfile, E_PREPVS, flag);
	write_separator(MF_outfile, TERMINATOR);
}


/*
 *-------------------------------------------------------------------------
 * CGMclip_rectangle:
 *	Writes the CLIP RECTANGLE item which defines the boundary at which
 * clipping should be performed.
 *-------------------------------------------------------------------------
 */
CGMclip_rectangle(lower, upper)
	Point   lower,
	        upper;
{
	write_item_name(MF_outfile, OP_TABLE, CLIP_RECT);
	write_separator(MF_outfile, SOFTSEP);
	write_point(MF_outfile, lower);
	write_separator(MF_outfile, SEP);
	write_point(MF_outfile, upper);
}
