summaryrefslogtreecommitdiff
path: root/cd/src/drv/cgm.c
diff options
context:
space:
mode:
authorPixel <pixel@nobis-crew.org>2009-11-04 11:56:41 -0800
committerPixel <pixel@nobis-crew.org>2009-11-04 11:59:33 -0800
commitd577d991b97ae2b5ee1af23641bcffc3f83af5b2 (patch)
tree590639d50205d1bcfaff2a7d2dc6ebf3f373c7ed /cd/src/drv/cgm.c
Initial import. Contains the im, cd and iup librairies, and a "working" Makefile for them under linux.
Diffstat (limited to 'cd/src/drv/cgm.c')
-rwxr-xr-xcd/src/drv/cgm.c2280
1 files changed, 2280 insertions, 0 deletions
diff --git a/cd/src/drv/cgm.c b/cd/src/drv/cgm.c
new file mode 100755
index 0000000..e86baaf
--- /dev/null
+++ b/cd/src/drv/cgm.c
@@ -0,0 +1,2280 @@
+/** \file
+ * \brief CGM library
+ * Extracted from GKS/PUC
+ *
+ * See Copyright Notice in cd.h
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include <float.h>
+#include <limits.h>
+
+#include "cgm.h"
+
+
+struct _cgmFunc
+{
+ /* write command header */
+ void (*wch)( CGM *, int, int, int );
+
+ /* put colour index at colour index precision */
+ void (*ci)( CGM *, unsigned long );
+
+ /* put color direct at colour direct precision */
+ void (*cd)( CGM *, double );
+
+ /* put color direct at colour direct precision */
+ void (*rgb)( CGM *, double, double, double );
+
+ /* put index at index precision */
+ void (*ix)( CGM *, long );
+
+ /* put enum ( int*2 ) */
+ void (*e)( CGM *, int, const char *l[] );
+
+ /* put int ( integer precision ) */
+ void (*i)( CGM *, long );
+
+ /* put unsigned int ( integer precision ) */
+ void (*u)( CGM *, unsigned long );
+
+ /* put real ( real precision ) */
+ void (*r)( CGM *, double );
+
+ /* put string */
+ void (*s)( CGM *, const char *, int );
+
+ /* put VDC at VDC mode and precision */
+ void (*vdc)( CGM *, double );
+
+ /* put point at VDC mode and precision */
+ void (*p)( CGM *, double, double );
+
+ /* put colour at colour mode and precision */
+ void (*co)( CGM *, const void * );
+
+ /* put separator */
+ void (*sep)( CGM *, const char * );
+
+ /* get column position */
+ int (*get_col)( CGM * );
+
+ /* align at column number */
+ void (*align)( CGM *, int );
+
+ /* nova linha */
+ void (*nl)( CGM * );
+
+ /* terminate element */
+ int (*term)( CGM * );
+};
+
+typedef struct _cgmCommand
+{
+ const char *ct;
+ const char *c;
+} cgmCommand;
+
+/************************************************
+* *
+* Dados para nao-binario *
+* *
+************************************************/
+
+/* delimiter elements */
+
+static const cgmCommand _cgmX_NULL = { "" , "" };
+static const cgmCommand _cgmX_BEGMF = { "BEGMF" , "\x30\x20" };
+static const cgmCommand _cgmX_ENDMF = { "ENDMF" , "\x30\x21" };
+static const cgmCommand _cgmX_BEG_PIC = { "BEG_PIC" , "\x30\x22" };
+static const cgmCommand _cgmX_BEG_PIC_BODY = { "BEG_PIC_BODY" , "\x30\x23" };
+static const cgmCommand _cgmX_END_PIC = { "END_PIC" , "\x30\x24" };
+
+/* metafile descriptor elements */
+
+static const cgmCommand _cgmX_MF_VERSION = { "MF_VERSION" , "\x31\x20" };
+static const cgmCommand _cgmX_MF_DESC = { "MF_DESC" , "\x31\x21" };
+static const cgmCommand _cgmX_VDC_TYPE = { "VDC_TYPE" , "\x31\x22" };
+static const cgmCommand _cgmX_INTEGER_PREC = { "INTEGER_PREC" , "\x31\x23" };
+static const cgmCommand _cgmX_REAL_PREC = { "REAL_PREC" , "\x31\x24" };
+static const cgmCommand _cgmX_INDEX_PREC = { "INDEX_PREC" , "\x31\x25" };
+static const cgmCommand _cgmX_COLR_PREC = { "COLR_PREC" , "\x31\x26" };
+static const cgmCommand _cgmX_COLR_INDEX_PREC = { "COLR_INDEX_PREC" , "\x31\x27" };
+static const cgmCommand _cgmX_MAX_COLR_INDEX = { "MAX_COLR_INDEX" , "\x31\x28" };
+static const cgmCommand _cgmX_COLR_VALUE_EXT = { "COLR_VALUE_EXT" , "\x31\x29" };
+static const cgmCommand _cgmX_MF_ELEM_LIST = { "MF_ELEM_LIST" , "\x31\x2a" };
+static const cgmCommand _cgmX_BEG_MF_DEFAULTS = { "BEG_MF_DEFAULTS" , "\x31\x2b" };
+static const cgmCommand _cgmX_END_MF_DEFAULTS = { "END_MF_DEFAULTS" , "\x31\x2c" };
+static const cgmCommand _cgmX_FONT_LIST = { "FONT_LIST" , "\x31\x2d" };
+static const cgmCommand _cgmX_CHAR_SET_LIST = { "CHAR_SET_LIST" , "\x31\x2e" };
+static const cgmCommand _cgmX_CHAR_CODING = { "CHAR_CODING" , "\x31\x2f" };
+
+/* picture descriptor elements */
+
+static const cgmCommand _cgmX_SCALE_MODE = { "SCALE_MODE" , "\x30\x20" };
+static const cgmCommand _cgmX_COLR_MODE = { "COLR_MODE" , "\x30\x21" };
+static const cgmCommand _cgmX_LINE_WIDTH_MODE = { "LINE_WIDTH_MODE" , "\x30\x22" };
+static const cgmCommand _cgmX_MARKER_SIZE_MODE = { "MARKER_SIZE_MODE" , "\x30\x23" };
+static const cgmCommand _cgmX_EDGE_WIDTH_MODE = { "EDGE_WIDTH_MODE" , "\x30\x24" };
+static const cgmCommand _cgmX_VDC_EXTENT = { "VDC_EXT" , "\x30\x25" };
+static const cgmCommand _cgmX_BACK_COLR = { "BACK_COLR" , "\x30\x26" };
+
+/* control elements */
+
+static const cgmCommand _cgmX_VDC_INTEGER_PREC = { "VDC_INTEGER_PREC" , "\x30\x20" };
+static const cgmCommand _cgmX_VDC_REAL_PREC = { "VDC_REAL_PREC" , "\x30\x21" };
+static const cgmCommand _cgmX_AUX_COLR = { "AUX_COLR" , "\x30\x22" };
+static const cgmCommand _cgmX_TRANSPARENCY = { "TRANSPARENCY" , "\x30\x23" };
+static const cgmCommand _cgmX_CLIP_RECT = { "CLIP_RECT" , "\x30\x24" };
+static const cgmCommand _cgmX_CLIP = { "CLIP" , "\x30\x25" };
+
+/* primitive elements */
+
+static const cgmCommand _cgmX_LINE = { "LINE" , "\x20" };
+static const cgmCommand _cgmX_DISJT_LINE = { "DISJT_LINE" , "\x21" };
+static const cgmCommand _cgmX_MARKER = { "MARKER" , "\x22" };
+static const cgmCommand _cgmX_TEXT = { "TEXT" , "\x23" };
+static const cgmCommand _cgmX_RESTR_TEXT = { "RESTR_TEXT" , "\x24" };
+static const cgmCommand _cgmX_APND_TEXT = { "APND_TEXT" , "\x25" };
+static const cgmCommand _cgmX_POLYGON = { "POLYGON" , "\x26" };
+static const cgmCommand _cgmX_POLYGON_SET = { "POLYGON_SET" , "\x27" };
+static const cgmCommand _cgmX_CELL_ARRAY = { "CELL_ARRAY" , "\x28" };
+static const cgmCommand _cgmX_GDP = { "GDP" , "\x29" };
+static const cgmCommand _cgmX_RECT = { "RECT" , "\x2a" };
+static const cgmCommand _cgmX_CIRCLE = { "CIRCLE" , "\x34\x20" };
+static const cgmCommand _cgmX_ARC_3_PT = { "ARC_3_PT" , "\x34\x21" };
+static const cgmCommand _cgmX_ARC_3_PT_CLOSE = { "ARC_3_PT_CLOSE" , "\x34\x22" };
+static const cgmCommand _cgmX_ARC_CTR = { "ARC_CTR" , "\x34\x23" };
+static const cgmCommand _cgmX_ARC_CTR_CLOSE = { "ARC_CTR_CLOSE" , "\x34\x24" };
+static const cgmCommand _cgmX_ELLIPSE = { "ELLIPSE" , "\x34\x25" };
+static const cgmCommand _cgmX_ELLIP_ARC = { "ELLIP_ARC" , "\x34\x26" };
+static const cgmCommand _cgmX_ELLIP_ARC_CLOSE = { "ELLIP_ARC_CLOSE" , "\x34\x27" };
+
+/* attribute elements */
+
+static const cgmCommand _cgmX_LINE_INDEX = { "LINE_INDEX" , "\x35\x20" };
+static const cgmCommand _cgmX_LINE_TYPE = { "LINE_TYPE" , "\x35\x21" };
+static const cgmCommand _cgmX_LINE_WIDTH = { "LINE_WIDTH" , "\x35\x22" };
+static const cgmCommand _cgmX_LINE_COLR = { "LINE_COLR" , "\x35\x23" };
+static const cgmCommand _cgmX_MARKER_INDEX = { "MARKER_INDEX" , "\x35\x24" };
+static const cgmCommand _cgmX_MARKER_TYPE = { "MARKER_TYPE" , "\x35\x25" };
+static const cgmCommand _cgmX_MARKER_WIDTH = { "MARKER_SIZE" , "\x35\x26" };
+static const cgmCommand _cgmX_MARKER_COLR = { "MARKER_COLR" , "\x35\x27" };
+static const cgmCommand _cgmX_TEXT_INDEX = { "TEXT_INDEX" , "\x35\x30" };
+static const cgmCommand _cgmX_TEXT_FONT_INDEX = { "TEXT_FONT_INDEX" , "\x35\x31" };
+static const cgmCommand _cgmX_TEXT_PREC = { "TEXT_PREC" , "\x35\x32" };
+static const cgmCommand _cgmX_CHAR_EXPAN = { "CHAR_EXPAN" , "\x35\x33" };
+static const cgmCommand _cgmX_CHAR_SPACE = { "CHAR_SPACE" , "\x35\x34" };
+static const cgmCommand _cgmX_TEXT_COLR = { "TEXT_COLR" , "\x35\x35" };
+static const cgmCommand _cgmX_CHAR_HEIGHT = { "CHAR_HEIGHT" , "\x35\x36" };
+static const cgmCommand _cgmX_CHAR_ORI = { "CHAR_ORI" , "\x35\x37" };
+static const cgmCommand _cgmX_TEXT_PATH = { "TEXT_PATH" , "\x35\x38" };
+static const cgmCommand _cgmX_TEXT_ALIGN = { "TEXT_ALIGN" , "\x35\x39" };
+static const cgmCommand _cgmX_CHAR_SET_INDEX = { "CHAR_SET_INDEX" , "\x35\x3a" };
+static const cgmCommand _cgmX_ALT_CHAR_SET = { "ALT_CHAR_SET_INDEX" , "\x35\x3b" };
+static const cgmCommand _cgmX_FILL_INDEX = { "FILL_INDEX" , "\x36\x20" };
+static const cgmCommand _cgmX_INT_STYLE = { "INT_STYLE" , "\x36\x21" };
+static const cgmCommand _cgmX_FILL_COLR = { "FILL_COLR" , "\x36\x22" };
+static const cgmCommand _cgmX_HATCH_INDEX = { "HATCH_INDEX" , "\x36\x23" };
+static const cgmCommand _cgmX_PAT_INDEX = { "PAT_INDEX" , "\x36\x24" };
+static const cgmCommand _cgmX_EDGE_INDEX = { "EDGE_INDEX" , "\x36\x25" };
+static const cgmCommand _cgmX_EDGE_TYPE = { "EDGE_TYPE" , "\x36\x26" };
+static const cgmCommand _cgmX_EDGE_WIDTH = { "EDGE_WIDTH" , "\x36\x27" };
+static const cgmCommand _cgmX_EDGE_COLR = { "EDGE_COLR" , "\x36\x28" };
+static const cgmCommand _cgmX_EDGE_VIS = { "EDGE_VIS" , "\x36\x29" };
+static const cgmCommand _cgmX_FILL_REF_PT = { "FILL_REF_PT" , "\x36\x2a" };
+static const cgmCommand _cgmX_PAT_TABLE = { "PAT_TABLE" , "\x36\x2b" };
+static const cgmCommand _cgmX_PAT_SIZE = { "PAT_SIZE" , "\x36\x2c" };
+static const cgmCommand _cgmX_COLR_TABLE = { "COLR_TABLE" , "\x36\x30" };
+static const cgmCommand _cgmX_ASF = { "ASF" , "\x36\x31" };
+
+/* escape elements */
+
+static const cgmCommand _cgmX_ESCAPE = { "ESCAPE" , "\x37\x20" };
+static const cgmCommand _cgmX_DOMAIN_RING = { "DOMAIN_RING" , "\x37\x30" };
+
+/* external elements */
+
+static const cgmCommand _cgmX_MESSAGE = { "MESSAGE" , "\x37\x21" };
+static const cgmCommand _cgmX_APPL_DATA = { "APPL_DATA" , "\x37\x22" };
+
+/* drawing sets */
+static const cgmCommand _cgmX_DRAWING_SET = { "drawing_set" , "\x40" };
+static const cgmCommand _cgmX_DRAWING_PLUS = { "drawing_plus" , "\x41" };
+
+static const cgmCommand *_elements_list_sets[] = {
+ & _cgmX_DRAWING_SET,
+ & _cgmX_DRAWING_PLUS,
+ NULL };
+
+
+static const cgmCommand *delimiter[] = {
+ & _cgmX_NULL,
+ & _cgmX_BEGMF,
+ & _cgmX_ENDMF,
+ & _cgmX_BEG_PIC,
+ & _cgmX_BEG_PIC_BODY,
+ & _cgmX_END_PIC,
+ NULL };
+
+static const cgmCommand *metafile[] = {
+ & _cgmX_END_MF_DEFAULTS,
+ & _cgmX_MF_VERSION,
+ & _cgmX_MF_DESC,
+ & _cgmX_VDC_TYPE,
+ & _cgmX_INTEGER_PREC,
+ & _cgmX_REAL_PREC,
+ & _cgmX_INDEX_PREC,
+ & _cgmX_COLR_PREC,
+ & _cgmX_COLR_INDEX_PREC,
+ & _cgmX_MAX_COLR_INDEX,
+ & _cgmX_COLR_VALUE_EXT,
+ & _cgmX_MF_ELEM_LIST,
+ & _cgmX_BEG_MF_DEFAULTS,
+ & _cgmX_FONT_LIST,
+ & _cgmX_CHAR_SET_LIST,
+ & _cgmX_CHAR_CODING,
+ NULL };
+
+static const cgmCommand *picture[] = {
+ & _cgmX_NULL,
+ & _cgmX_SCALE_MODE,
+ & _cgmX_COLR_MODE,
+ & _cgmX_LINE_WIDTH_MODE,
+ & _cgmX_MARKER_SIZE_MODE,
+ & _cgmX_EDGE_WIDTH_MODE,
+ & _cgmX_VDC_EXTENT,
+ & _cgmX_BACK_COLR,
+ NULL };
+
+static const cgmCommand *control[] = {
+ & _cgmX_NULL,
+ & _cgmX_VDC_INTEGER_PREC,
+ & _cgmX_VDC_REAL_PREC,
+ & _cgmX_AUX_COLR,
+ & _cgmX_TRANSPARENCY,
+ & _cgmX_CLIP_RECT,
+ & _cgmX_CLIP,
+ NULL };
+
+static const cgmCommand *primitive[] = {
+ & _cgmX_NULL,
+ & _cgmX_LINE,
+ & _cgmX_DISJT_LINE,
+ & _cgmX_MARKER,
+ & _cgmX_TEXT,
+ & _cgmX_RESTR_TEXT,
+ & _cgmX_APND_TEXT,
+ & _cgmX_POLYGON,
+ & _cgmX_POLYGON_SET,
+ & _cgmX_CELL_ARRAY,
+ & _cgmX_GDP,
+ & _cgmX_RECT,
+ & _cgmX_CIRCLE,
+ & _cgmX_ARC_3_PT,
+ & _cgmX_ARC_3_PT_CLOSE,
+ & _cgmX_ARC_CTR,
+ & _cgmX_ARC_CTR_CLOSE,
+ & _cgmX_ELLIPSE,
+ & _cgmX_ELLIP_ARC,
+ & _cgmX_ELLIP_ARC_CLOSE,
+ NULL };
+
+static const cgmCommand *attributes[] = {
+ & _cgmX_NULL,
+ & _cgmX_LINE_INDEX,
+ & _cgmX_LINE_TYPE,
+ & _cgmX_LINE_WIDTH,
+ & _cgmX_LINE_COLR,
+ & _cgmX_MARKER_INDEX,
+ & _cgmX_MARKER_TYPE,
+ & _cgmX_MARKER_WIDTH,
+ & _cgmX_MARKER_COLR,
+ & _cgmX_TEXT_INDEX,
+ & _cgmX_TEXT_FONT_INDEX,
+ & _cgmX_TEXT_PREC,
+ & _cgmX_CHAR_EXPAN,
+ & _cgmX_CHAR_SPACE,
+ & _cgmX_TEXT_COLR,
+ & _cgmX_CHAR_HEIGHT,
+ & _cgmX_CHAR_ORI,
+ & _cgmX_TEXT_PATH,
+ & _cgmX_TEXT_ALIGN,
+ & _cgmX_CHAR_SET_INDEX,
+ & _cgmX_ALT_CHAR_SET,
+ & _cgmX_FILL_INDEX,
+ & _cgmX_INT_STYLE,
+ & _cgmX_FILL_COLR,
+ & _cgmX_HATCH_INDEX,
+ & _cgmX_PAT_INDEX,
+ & _cgmX_EDGE_INDEX,
+ & _cgmX_EDGE_TYPE,
+ & _cgmX_EDGE_WIDTH,
+ & _cgmX_EDGE_COLR,
+ & _cgmX_EDGE_VIS,
+ & _cgmX_FILL_REF_PT,
+ & _cgmX_PAT_TABLE,
+ & _cgmX_PAT_SIZE,
+ & _cgmX_COLR_TABLE,
+ & _cgmX_ASF,
+ NULL };
+
+static const cgmCommand *escape[] = {
+ & _cgmX_NULL,
+ & _cgmX_ESCAPE,
+ & _cgmX_DOMAIN_RING,
+ NULL };
+
+static const cgmCommand *external[] = {
+ & _cgmX_NULL,
+ & _cgmX_MESSAGE,
+ & _cgmX_APPL_DATA,
+ NULL };
+
+static const cgmCommand **comandos[] = {
+ _elements_list_sets,
+ delimiter,
+ metafile,
+ picture,
+ control,
+ primitive,
+ attributes,
+ escape,
+ external,
+ NULL };
+
+#define unit (cgm->file)
+
+/************************************************
+* *
+* listas de funcoes necessarias *
+* *
+************************************************/
+
+
+static void cgmb_wch ( CGM *, int, int, int ); /* write command header */
+static void cgmb_ci ( CGM *, unsigned long ); /* put colour index at colour index precision */
+static void cgmb_cd ( CGM *, double ); /* put color direct at colour direct precision */
+static void cgmb_rgb ( CGM *, double, double, double ); /* put color direct (rgb) at colour direct precision */
+static void cgmb_ix ( CGM *, long ); /* put index at index precision */
+static void cgmb_e ( CGM *, int, const char *l[] ); /* put enum ( int*2 ) */
+static void cgmb_i ( CGM *, long ); /* put int ( integer precision ) */
+static void cgmb_u ( CGM *, unsigned long ); /* put unsigned int ( integer precision ) */
+static void cgmb_r ( CGM *, double ); /* put real ( real precision ) */
+static void cgmb_s ( CGM *, const char *, int ); /* put string */
+static void cgmb_vdc ( CGM *, double ); /* put VDC at VDC mode and precision */
+static void cgmb_p ( CGM *, double, double ); /* put point at VDC mode and precision */
+static void cgmb_co ( CGM *, const void * ); /* put colour at colour mode and precision */
+static void cgmb_sep ( CGM *, const char * ); /* put separator */
+static int cgmb_get_col ( CGM * ); /* get column position */
+static void cgmb_align ( CGM *, int ); /* align at column number */
+static void cgmb_nl ( CGM * ); /* new line */
+static int cgmb_term ( CGM * ); /* terminate element */
+
+static const CGMFUNC cgmf_binary = {
+ cgmb_wch ,
+ cgmb_ci ,
+ cgmb_cd ,
+ cgmb_rgb ,
+ cgmb_ix ,
+ cgmb_e ,
+ cgmb_i ,
+ cgmb_u ,
+ cgmb_r ,
+ cgmb_s ,
+ cgmb_vdc ,
+ cgmb_p ,
+ cgmb_co ,
+ cgmb_sep ,
+ cgmb_get_col,
+ cgmb_align ,
+ cgmb_nl ,
+ cgmb_term
+ };
+
+static void cgmt_wch ( CGM *, int, int, int ); /* write command header */
+static void cgmt_ci ( CGM *, unsigned long ); /* put colour index at colour index precision */
+static void cgmt_cd ( CGM *, double ); /* put color direct at colour direct precision */
+static void cgmt_rgb ( CGM *, double, double, double ); /* put color direct (rgb) at colour direct precision */
+static void cgmt_ix ( CGM *, long ); /* put index at index precision */
+static void cgmt_e ( CGM *, int, const char *l[] ); /* put enum ( int*2 ) */
+static void cgmt_i ( CGM *, long ); /* put int ( integer precision ) */
+static void cgmt_u ( CGM *, unsigned long ); /* put unsigned int ( integer precision ) */
+static void cgmt_r ( CGM *, double ); /* put real ( real precision ) */
+static void cgmt_s ( CGM *, const char *, int ); /* put string */
+static void cgmt_vdc ( CGM *, double ); /* put VDC at VDC mode and precision */
+static void cgmt_p ( CGM *, double, double ); /* put point at VDC mode and precision */
+static void cgmt_co ( CGM *, const void * ); /* put colour at colour mode and precision */
+static void cgmt_sep ( CGM *, const char * ); /* put separator */
+static int cgmt_get_col ( CGM * ); /* get column position */
+static void cgmt_align ( CGM *, int ); /* align at column number */
+static void cgmt_nl ( CGM * ); /* new line */
+static int cgmt_term ( CGM * ); /* terminate element */
+
+static const CGMFUNC cgmf_clear_text = {
+ cgmt_wch ,
+ cgmt_ci ,
+ cgmt_cd ,
+ cgmt_rgb ,
+ cgmt_ix ,
+ cgmt_e ,
+ cgmt_i ,
+ cgmt_u ,
+ cgmt_r ,
+ cgmt_s ,
+ cgmt_vdc ,
+ cgmt_p ,
+ cgmt_co ,
+ cgmt_sep ,
+ cgmt_get_col,
+ cgmt_align ,
+ cgmt_nl ,
+ cgmt_term
+ };
+
+static void cgmc_wch ( CGM *, int, int, int ); /* write command header */
+static void cgmc_ci ( CGM *, unsigned long ); /* put colour index at colour index precision */
+static void cgmc_cd ( CGM *, double ); /* put color direct at colour direct precision */
+static void cgmc_rgb ( CGM *, double, double, double ); /* put color direct (rgb) at colour direct precision */
+static void cgmc_ix ( CGM *, long ); /* put index at index precision */
+static void cgmc_e ( CGM *, int, const char *l[] ); /* put enum ( int*2 ) */
+static void cgmc_i ( CGM *, long ); /* put int ( integer precision ) */
+static void cgmc_u ( CGM *, unsigned long ); /* put unsigned int ( integer precision ) */
+static void cgmc_r ( CGM *, double ); /* put real ( real precision ) */
+static void cgmc_s ( CGM *, const char *, int ); /* put string */
+static void cgmc_vdc ( CGM *, double ); /* put VDC at VDC mode and precision */
+static void cgmc_p ( CGM *, double, double ); /* put point at VDC mode and precision */
+static void cgmc_co ( CGM *, const void * ); /* put colour at colour mode and precision */
+static void cgmc_sep ( CGM *, const char * ); /* put separator */
+static int cgmc_get_col ( CGM * ); /* get column position */
+static void cgmc_align ( CGM *, int ); /* align at column number */
+static void cgmc_nl ( CGM * ); /* new line */
+static int cgmc_term ( CGM * ); /* terminate element */
+
+static const CGMFUNC cgmf_character = {
+ cgmc_wch ,
+ cgmc_ci ,
+ cgmc_cd ,
+ cgmc_rgb ,
+ cgmc_ix ,
+ cgmc_e ,
+ cgmc_i ,
+ cgmc_u ,
+ cgmc_r ,
+ cgmc_s ,
+ cgmc_vdc ,
+ cgmc_p ,
+ cgmc_co ,
+ cgmc_sep ,
+ cgmc_get_col,
+ cgmc_align ,
+ cgmc_nl ,
+ cgmc_term
+ };
+
+static const CGMFUNC *cgmf[] = { &cgmf_character, &cgmf_binary, &cgmf_clear_text };
+
+/************************************************
+* *
+* Funcoes para binario *
+* *
+************************************************/
+
+#define cgmb_putw cgmb_putu16
+#define cgmb_putb(a,b) cgmb_putc((a),(int)(b))
+
+static void cgmb_putw ( CGM *, unsigned );
+
+static void cgmb_putc ( CGM *cgm, int b )
+{
+ if ( cgm->op != -1 )
+ {
+ register int i;
+ for ( i=cgm->op; i>=0; i-- )
+ {
+ if ( cgm->bc[i] == 32766 - 2*i )
+ {
+ long po = ftell(unit);
+ int op = cgm->op;
+
+ cgm->op = -1;
+ fseek(unit, cgm->po[i] , SEEK_SET);
+ cgmb_putw ( cgm, (1 << 15) | (cgm->bc[i]) );
+
+ cgm->op = i - 1;
+ fseek(unit, po, SEEK_SET);
+ cgmb_putw ( cgm, 0 );
+
+ cgm->op = op;
+ cgm->bc[i] = 0;
+ cgm->po[i] = po;
+ }
+ cgm->bc[i] ++;
+ }
+ }
+
+ fputc ( b, unit );
+}
+
+
+static void cgmb_puti8 ( CGM *cgm, int b )
+{
+ cgmb_putb ( cgm, b );
+}
+
+static void cgmb_puti16 ( CGM *cgm, int b )
+{
+ cgmb_putb ( cgm, b >> 8 );
+ cgmb_putb ( cgm, b );
+}
+
+static void cgmb_puti24 ( CGM *cgm, long b )
+{
+ cgmb_putb ( cgm, b >> 16 );
+ cgmb_putb ( cgm, b >> 8 );
+ cgmb_putb ( cgm, b );
+}
+
+static void cgmb_puti32 ( CGM *cgm, long b )
+{
+ cgmb_putb ( cgm, b >> 24 );
+ cgmb_putb ( cgm, b >> 16 );
+ cgmb_putb ( cgm, b >> 8 );
+ cgmb_putb ( cgm, b );
+}
+
+static void cgmb_putu8 ( CGM *cgm, unsigned int b )
+{
+ cgmb_putb ( cgm, b );
+}
+
+static void cgmb_putu16 ( CGM *cgm, unsigned int b )
+{
+ cgmb_putb ( cgm, b >> 8 );
+ cgmb_putb ( cgm, b );
+}
+
+static void cgmb_putu24 ( CGM *cgm, unsigned long b )
+{
+ cgmb_putb ( cgm, b >> 16 );
+ cgmb_putb ( cgm, b >> 8 );
+ cgmb_putb ( cgm, b );
+}
+
+static void cgmb_putu32 ( CGM *cgm, unsigned long b )
+{
+ cgmb_putb ( cgm, b >> 24 );
+ cgmb_putb ( cgm, b >> 16 );
+ cgmb_putb ( cgm, b >> 8 );
+ cgmb_putb ( cgm, b );
+}
+
+static void cgmb_putfl32 ( CGM *cgm, float b )
+{
+ union {
+ float func;
+ long l;
+ } r;
+ r.func = b;
+ cgmb_putb ( cgm, r.l >> 24 );
+ cgmb_putb ( cgm, r.l >> 16 );
+ cgmb_putb ( cgm, r.l >> 8 );
+ cgmb_putb ( cgm, r.l );
+}
+
+static void cgmb_putfl64 ( CGM *cgm, double b )
+{
+ union {
+ double d;
+ long l[2];
+ } r;
+ r.d = b;
+ cgmb_putb ( cgm, r.l[1] >> 24 );
+ cgmb_putb ( cgm, r.l[1] >> 16 );
+ cgmb_putb ( cgm, r.l[1] >> 8 );
+ cgmb_putb ( cgm, r.l[1] );
+ cgmb_putb ( cgm, r.l[0] >> 24 );
+ cgmb_putb ( cgm, r.l[0] >> 16 );
+ cgmb_putb ( cgm, r.l[0] >> 8 );
+ cgmb_putb ( cgm, r.l[0] );
+}
+
+static void cgmb_putfx32 ( CGM *cgm, float b )
+{
+ int si = ( int ) floor ( b );
+ unsigned int ui = ( unsigned int ) ( (b - si) * 65536.0 );
+
+ cgmb_puti16 ( cgm, si );
+ cgmb_puti16 ( cgm, ui );
+}
+
+static void cgmb_putfx64 ( CGM *cgm, double b )
+{
+ long si = ( long ) floor ( b );
+ unsigned long ui = ( unsigned long ) ( (b - si) * 65536.0 * 65536.0 );
+
+ cgmb_puti32 ( cgm, si );
+ cgmb_puti32 ( cgm, ui );
+}
+
+static void cgmb_wch ( CGM* cgm, int c, int id, int len )
+{
+
+ /* if ( len & 1 ) len ++; */ /* word aligned */
+
+ if ( len > 30 )
+ cgmb_putw ( cgm, (c << 12) | ( id << 5 ) | 31 );
+ else
+ cgmb_putw ( cgm, (c << 12) | ( id << 5 ) | (int)(len) );
+
+
+ cgm->op++;
+
+ if ( len > 30 )
+ {
+ cgm->po[cgm->op] = ftell(unit);
+ cgmb_putw ( cgm, 0 );
+ }
+ else
+ cgm->po[cgm->op] = 0L;
+
+ cgm->bc[cgm->op] = 0;
+
+}
+
+static void cgmb_ci ( CGM *cgm, unsigned long ci )
+{
+ switch ( cgm->cix_prec )
+ {
+ case 0: cgmb_putu8 ( cgm, (unsigned)ci ); break;
+ case 1: cgmb_putu16 ( cgm, (unsigned)ci ); break;
+ case 2: cgmb_putu24 ( cgm, ci ); break;
+ case 3: cgmb_putu32 ( cgm, ci ); break;
+ }
+}
+
+static void cgmb_cd ( CGM *cgm, double cd )
+{
+ unsigned long cv = (unsigned long) (cd * (pow(2.0, (cgm->cd_prec + 1) * 8.0) - 1));
+ switch ( cgm->cd_prec )
+ {
+ case 0: cgmb_putu8 ( cgm, (unsigned)cv ); break;
+ case 1: cgmb_putu16 ( cgm, (unsigned)cv ); break;
+ case 2: cgmb_putu24 ( cgm, cv ); break;
+ case 3: cgmb_putu32 ( cgm, cv ); break;
+ }
+}
+
+static void cgmb_rgb ( CGM *cgm, double r, double g, double b )
+{
+ cgmb_cd ( cgm, r );
+ cgmb_cd ( cgm, g );
+ cgmb_cd ( cgm, b );
+}
+
+static void cgmb_ix ( CGM *cgm, long ix )
+{
+ switch ( cgm->ix_prec )
+ {
+ case 0: cgmb_puti8 ( cgm, (int)ix ); break;
+ case 1: cgmb_puti16 ( cgm, (int)ix ); break;
+ case 2: cgmb_puti24 ( cgm, ix ); break;
+ case 3: cgmb_puti32 ( cgm, ix ); break;
+ }
+}
+
+static void cgmb_e ( CGM *cgm, int e, const char *el[] )
+{
+ cgmb_puti16 ( cgm, e );
+}
+
+static void cgmb_i ( CGM *cgm, long i )
+{
+ switch ( cgm->int_prec )
+ {
+ case 0: cgmb_puti8 ( cgm, (int)i ); break;
+ case 1: cgmb_puti16 ( cgm, (int)i ); break;
+ case 2: cgmb_puti24 ( cgm, i ); break;
+ case 3: cgmb_puti32 ( cgm, i ); break;
+ }
+}
+
+static void cgmb_u ( CGM *cgm, unsigned long i )
+{
+ switch ( cgm->int_prec )
+ {
+ case 0: cgmb_putu8 ( cgm, (unsigned)i ); break;
+ case 1: cgmb_putu16 ( cgm, (unsigned)i ); break;
+ case 2: cgmb_putu24 ( cgm, i ); break;
+ case 3: cgmb_putu32 ( cgm, i ); break;
+ }
+}
+
+static void cgmb_r ( CGM *cgm, double func )
+{
+ switch ( cgm->real_prec )
+ {
+ case 0: cgmb_putfl32 ( cgm, (float )func ); break;
+ case 1: cgmb_putfl64 ( cgm, (double)func ); break;
+ case 2: cgmb_putfx32 ( cgm, (float )func ); break;
+ case 3: cgmb_putfx64 ( cgm, (double)func ); break;
+ }
+}
+
+static void cgmb_s ( CGM *cgm, const char *s, int len )
+{
+ register unsigned i;
+ unsigned l = len;
+ int bc = 0;
+
+ if ( l > 254 )
+ {
+ cgmb_putu8(cgm,255);
+ if ( l > 32763 )
+ cgmb_putu16 ( cgm, (1<<16) | 32763 );
+ else
+ cgmb_putu16 ( cgm, l );
+ bc = 1;
+ }
+ else
+ cgmb_putu8(cgm,l);
+
+ for ( i=0; i<len; s++ )
+ {
+ if ( (i + bc) == 32766 )
+ {
+ l -= i;
+ s += i;
+ i = 0;
+ bc = 0;
+ if ( l > 32764 )
+ cgmb_putu16 ( cgm, (1<<16) | 32764 );
+ else
+ cgmb_putu16 ( cgm, l );
+ }
+ cgmb_putc ( cgm, s[i] );
+ }
+}
+
+static void cgmb_vdc ( CGM *cgm, double vdc)
+{
+ if ( cgm->vdc_type == 0 )
+ switch ( cgm->vdc_int )
+ {
+ case 0: cgmb_puti8 ( cgm, (int )vdc ); break;
+ case 1:
+ /* Evita overflow em ambientes de 32 bits */
+ if (vdc < -32768) vdc = -32768;
+ else if (vdc > 32767) vdc = +32767;
+ cgmb_puti16 ( cgm, (int) vdc );
+ break;
+ case 2: cgmb_puti24 ( cgm, (long)vdc ); break;
+ case 3:
+ /* Evita overflow em ambientes de 32 bits */
+ if (vdc < (double)-2147483648.0) vdc = (double)-2147483648.0;
+ else if (vdc > (double)2147483647.0) vdc = (double)2147483647.0;
+ cgmb_puti32 ( cgm, (long)vdc );
+ break;
+
+ }
+ else
+ switch ( cgm->vdc_real )
+ {
+ case 0: cgmb_putfl32 ( cgm, (float )vdc ); break;
+ case 1: cgmb_putfl64 ( cgm, (double)vdc ); break;
+ case 2: cgmb_putfx32 ( cgm, (float )vdc ); break;
+ case 3: cgmb_putfx64 ( cgm, (double)vdc ); break;
+ }
+
+}
+
+static void cgmb_p ( CGM *cgm, double x, double y)
+{
+ cgmb_vdc ( cgm, x );
+ cgmb_vdc ( cgm, y );
+}
+
+static void cgmb_co ( CGM *cgm, const void * co)
+{
+ if ( cgm->clrsm == 0 ) /* indexed */
+ {
+ unsigned long ci = *(unsigned long *)co;
+ cgmb_ci ( cgm, ci );
+ }
+ else
+ {
+ double *cb = (double *) co;
+ cgmb_rgb ( cgm, cb[0], cb[1], cb[2] );
+ }
+}
+
+static void cgmb_sep ( CGM *cgm, const char * sep )
+{}
+
+static int cgmb_get_col ( CGM *cgm )
+{
+ return 0;
+}
+
+static void cgmb_align ( CGM *cgm, int n )
+{}
+
+static void cgmb_nl ( CGM *cgm )
+{}
+
+static int cgmb_term ( CGM *cgm )
+{
+ if ( cgm->op != -1 )
+ {
+ if ( cgm->bc[cgm->op] & 1 )
+ {
+ cgmb_putb( cgm, 0 );
+ cgm->bc[cgm->op] --;
+ }
+
+ if ( cgm->po[cgm->op] != 0L )
+ {
+ long po = ftell(unit);
+ int op = cgm->op;
+
+ cgm->op = -1;
+ fseek ( unit, cgm->po[op], SEEK_SET);
+ cgmb_putw ( cgm, cgm->bc[op] );
+
+ fseek ( unit, po, SEEK_SET );
+ cgm->op = op;
+ }
+ cgm->op --;
+ }
+
+ return 0;
+}
+
+/************************************************
+* *
+* Funcoes para clear text *
+* *
+************************************************/
+
+static void cgmt_wch ( CGM* cgm, int c, int id, int len )
+{
+ cgm->cl += fprintf ( unit, "%s", comandos[c+1][id]->ct );
+}
+
+static void cgmt_ci ( CGM *cgm, unsigned long ci )
+{
+ cgm->func->u ( cgm, ci );
+}
+
+static void cgmt_cd ( CGM *cgm, double cd )
+{
+ unsigned long cv = (unsigned long) (cd * (pow(2.0, (cgm->cd_prec + 1) * 8.0) - 1));
+
+ cgm->func->u ( cgm, cv );
+}
+
+static void cgmt_rgb ( CGM *cgm, double r, double g, double b )
+{
+ cgm->func->cd ( cgm, r );
+ cgm->func->cd ( cgm, g );
+ cgm->func->cd ( cgm, b );
+}
+
+static void cgmt_ix ( CGM *cgm, long ix )
+{
+ cgm->func->i ( cgm, ix );
+}
+
+static void cgmt_e ( CGM *cgm, int e, const char *el[] )
+{
+ cgm->cl += fprintf ( unit, " %s", el[e] );
+}
+
+static void cgmt_i ( CGM *cgm, long i )
+{
+ cgm->cl += fprintf ( unit, " %ld", i );
+}
+
+static void cgmt_u ( CGM *cgm, unsigned long i )
+{
+ cgm->cl += fprintf ( unit, " %lu", i );
+}
+
+static void cgmt_r ( CGM *cgm, double func )
+{
+ cgm->cl += fprintf ( unit, " %g", func );
+}
+
+static void cgmt_s ( CGM *cgm, const char *s, int len )
+{
+ register unsigned i;
+ fputc ( 34, unit );
+
+ for ( i=0; i<len; i++ )
+ {
+ if ( s[i] == 34 )
+ {
+ fputc ( 34, unit );
+ cgm->cl ++;
+ }
+ fputc ( s[i], unit );
+ }
+
+ fputc ( 34, unit );
+ cgm->cl += len + 2;
+}
+
+static void cgmt_vdc ( CGM *cgm, double vdc)
+{
+ if ( cgm->vdc_type == 0 )
+ {
+ /* Evita overflow em ambientes de 32 bits */
+ if (vdc < (double)-2147483648.0) vdc = (double)-2147483648.0;
+ else if (vdc > (double)2147483647.0) vdc = (double)2147483647.0;
+
+ cgm->func->i ( cgm, (long) vdc );
+ }
+ else
+ cgm->func->r ( cgm, vdc );
+}
+
+static void cgmt_p ( CGM *cgm, double x, double y)
+{
+ cgm->func->sep ( cgm, "(" );
+ cgm->func->vdc ( cgm, x );
+ cgm->func->sep ( cgm, "," );
+ cgm->func->vdc ( cgm, y );
+ cgm->func->sep ( cgm, ")" );
+}
+
+static void cgmt_co ( CGM *cgm, const void * co)
+{
+ if ( cgm->clrsm == 0 ) /* indexed */
+ {
+ unsigned long ci = *(unsigned *)co;
+ cgm->func->ci ( cgm, ci );
+ }
+ else
+ {
+ double *cb = (double *) co;
+ cgm->func->rgb ( cgm, cb[0], cb[1], cb[2] );
+ }
+}
+
+static void cgmt_sep ( CGM *cgm, const char * sep )
+{
+ cgm->cl += fprintf ( unit, " %s", sep );
+}
+
+static int cgmt_get_col ( CGM *cgm )
+{
+ return cgm->cl;
+}
+
+static void cgmt_align ( CGM *cgm, int n )
+{
+ for ( ; cgm->cl < n ; cgm->cl ++ )
+ fputc ( ' ', unit );
+}
+
+static void cgmt_nl ( CGM *cgm )
+{
+ fputc ( '\n', unit );
+ cgm->cl = 1;
+}
+
+static int cgmt_term ( CGM *cgm )
+{
+ fputc ( ';', unit );
+ cgm->func->nl(cgm);
+ return 0;
+}
+
+/************************************************
+* *
+* Funcoes para character *
+* *
+************************************************/
+
+static void cgmc_wch ( CGM* cgm, int c, int id, int len )
+{
+ cgm->cl += fprintf ( unit, "%s", comandos[c+1][id]->ct );
+}
+
+static void cgmc_ci ( CGM *cgm, unsigned long ci )
+{
+ cgm->func->u ( cgm, ci );
+}
+
+static void cgmc_cd ( CGM *cgm, double cd )
+{
+ cgm->func->r ( cgm, cd );
+}
+
+static void cgmc_rgb ( CGM *cgm, double r, double g, double b )
+{
+ cgm->func->cd ( cgm, r );
+ cgm->func->sep ( cgm, "," );
+ cgm->func->cd ( cgm, g );
+ cgm->func->sep ( cgm, "," );
+ cgm->func->cd ( cgm, b );
+}
+
+static void cgmc_ix ( CGM *cgm, long ix )
+{
+ cgm->func->i ( cgm, ix );
+}
+
+static void cgmc_e ( CGM *cgm, int e, const char *el[] )
+{
+ cgm->cl += fprintf ( unit, " %s", el[e] );
+}
+
+static void cgmc_i ( CGM *cgm, long i )
+{
+ cgm->cl += fprintf ( unit, " %ld", i );
+}
+
+static void cgmc_u ( CGM *cgm, unsigned long i )
+{
+ cgm->cl += fprintf ( unit, " %lu", i );
+}
+
+static void cgmc_r ( CGM *cgm, double func )
+{
+ cgm->cl += fprintf ( unit, " %g", func );
+}
+
+static void cgmc_s ( CGM *cgm, const char *s, int len )
+{
+ register unsigned i;
+ fputc ( 34, unit );
+
+ for ( i=0; i<len; i++ )
+ {
+ if ( s[i] == 34 )
+ {
+ fputc ( 34, unit );
+ cgm->cl ++;
+ }
+ fputc ( s[i], unit );
+ }
+
+ fputc ( 34, unit );
+ cgm->cl += len + 2;
+}
+
+static void cgmc_vdc ( CGM *cgm, double vdc)
+{
+ if ( cgm->vdc_type == 0 )
+ cgm->func->i ( cgm, (long) vdc );
+ else
+ cgm->func->r ( cgm, vdc );
+}
+
+static void cgmc_p ( CGM *cgm, double x, double y)
+{
+ cgm->func->sep ( cgm, "(" );
+ cgm->func->vdc ( cgm, x );
+ cgm->func->sep ( cgm, "," );
+ cgm->func->vdc ( cgm, y );
+ cgm->func->sep ( cgm, ")" );
+}
+
+static void cgmc_co ( CGM *cgm, const void * co)
+{
+ if ( cgm->clrsm == 0 ) /* indexed */
+ {
+ unsigned long ci = *(unsigned long *)co;
+ cgm->func->ci ( cgm, ci );
+ }
+ else
+ {
+ double *cb = (double *) co;
+ cgm->func->rgb ( cgm, cb[0], cb[1], cb[2] );
+ }
+}
+
+static void cgmc_sep ( CGM *cgm, const char * sep )
+{
+ cgm->cl += fprintf ( unit, " %s", sep );
+}
+
+static int cgmc_get_col ( CGM *cgm )
+{
+ return cgm->cl;
+}
+
+static void cgmc_align ( CGM *cgm, int n )
+{
+ for ( ; cgm->cl < n ; cgm->cl ++ )
+ fputc ( ' ', unit );
+}
+
+static void cgmc_nl ( CGM *cgm )
+{
+ fputc ( '\n', unit );
+ cgm->cl = 1;
+}
+
+static int cgmc_term ( CGM *cgm )
+{
+ fputc ( ';', unit );
+ cgm->func->nl(cgm);
+ return 0;
+}
+
+/************************************************
+* *
+* independente de codificacao *
+* *
+************************************************/
+
+
+/* Definicoes de precisao */
+
+static const long _cgm_int_precs[][2] = {
+ { -128, 127 }, /* 8 */
+ { -32768L, 32767 }, /* 16 */
+ { LONG_MIN >> 8, LONG_MAX >> 8 }, /* 24 */
+ { LONG_MIN , LONG_MAX } }; /* 32 */
+
+static int _cgm_ireal_precs[][4] = {
+ { 0, 9, 23, 0 }, /* float*32 */
+ { 0, 12, 52, 0 }, /* float*64 */
+ { 1, 16, 16, 5 }, /* fixed*32 */
+ { 1, 32, 32, 9 } }; /* fixed*64 */
+
+static double _cgm_rreal_precs[][2] = {
+ /* float*32 */ { 0, 0 }, /* Em Turbo C, FLT_MAX e DLB_MAX sao */
+ /* float*64 */ { 0, 0 }, /* DEFINES para variaveis externas */
+ /* fixed*32 */ { - (32769.0 - 1.0 / 65536.0),
+ 32768.0 - 1.0 / 65536.0 },
+ /* fixed*64 */ { (double)(LONG_MIN) - ( 1 - 1 / ( 65536.0 * 65536.0 ) ),
+ (double)(LONG_MAX) + ( 1 - 1 / ( 65536.0 * 65536.0 ) ) } };
+
+/* Enumeraveis genericos */
+
+static const char *offon[] = { "OFF", "ON" };
+
+/*********************
+* Delimiter elements *
+*********************/
+
+CGM *cgm_begin_metafile ( char *file, int mode, char *header )
+{
+ CGM *cgm;
+ int len;
+
+ if ( (cgm = (CGM *)malloc ( sizeof (CGM) ) ) == NULL )
+ return NULL;
+
+#ifdef __VAXC__
+
+ if ( mode == 2 )
+ cgm->file = fopen ( file , "w" , "rfm=var", "rat=cr" );
+ else
+ cgm->file = fopen ( file , "w+b", "rfm=var", "ctx=stm" );
+
+#else
+
+ if ( mode == 2 )
+ cgm->file = fopen ( file , "w" );
+ else
+ cgm->file = fopen ( file , "w+b" );
+
+#endif
+
+ if ( cgm->file == NULL )
+ {
+ free ( cgm );
+ return NULL;
+ }
+
+ cgm->mode = mode;
+ cgm->func = cgmf[mode];
+
+ cgm->vdc_type = 0;
+ cgm->int_prec = 1;
+ cgm->real_prec = 2;
+ cgm->ix_prec = 1;
+ cgm->cd_prec = 0;
+ cgm->cix_prec = 0;
+ cgm->max_cix = 63;
+
+ cgm->clrsm = 0;
+ cgm->lnwsm = 1;
+ cgm->mkssm = 1;
+ cgm->edwsm = 1;
+ cgm->vdc_int = 1;
+ cgm->vdc_real = 2;
+
+ cgm->vdc_size = 2;
+ cgm->int_size = 2;
+ cgm->real_size = 4;
+ cgm->ix_size = 3;
+ cgm->cd_size = 3;
+ cgm->cix_size = 1;
+ cgm->clr_size = 1;
+ cgm->lnw_size = 4;
+ cgm->mks_size = 4;
+ cgm->edw_size = 4;
+
+ cgm->cl = 1;
+
+ cgm->op = -1;
+
+ len = strlen(header);
+ cgm->func->wch ( cgm, 0, 1, len+1 );
+
+ cgm->func->s ( cgm, header, len );
+
+ cgm->func->term ( cgm );
+
+ _cgm_ireal_precs[0][3] = FLT_DIG;
+ _cgm_ireal_precs[1][3] = DBL_DIG;
+
+ _cgm_rreal_precs[0][0] = - FLT_MAX;
+ _cgm_rreal_precs[0][1] = FLT_MAX;
+ _cgm_rreal_precs[1][0] = - DBL_MAX;
+ _cgm_rreal_precs[1][1] = DBL_MAX;
+
+ return cgm;
+}
+
+int cgm_end_metafile ( CGM *cgm )
+{
+ cgm->func->wch ( cgm, 0, 2, 0 );
+ cgm->func->term ( cgm );
+
+ fclose ( cgm->file );
+ cgm->file = NULL;
+ free ( cgm );
+
+ return 0;
+}
+
+int cgm_begin_picture (CGM *cgm, const char *s )
+{
+ int len = strlen(s);
+ cgm->func->wch ( cgm, 0, 3, len+1 );
+ cgm->func->s ( cgm, s, len );
+ return cgm->func->term(cgm);
+}
+
+int cgm_begin_picture_body ( CGM *cgm )
+{
+ cgm->func->wch ( cgm, 0, 4, 0 );
+ return cgm->func->term(cgm);
+}
+
+int cgm_end_picture ( CGM *cgm )
+{
+ cgm->func->wch ( cgm, 0, 5, 0 );
+ return cgm->func->term(cgm);
+}
+
+/*******************************
+* Metafile Descriptor Elements *
+*******************************/
+
+int cgm_metafile_version ( CGM *cgm, long version )
+{
+ cgm->func->wch ( cgm, 1, 1, cgm->int_size );
+
+ cgm->func->i ( cgm, version );
+
+ return cgm->func->term(cgm);
+}
+
+int cgm_metafile_description ( CGM *cgm, const char *s )
+{
+ int len = strlen(s);
+ cgm->func->wch ( cgm, 1, 2, 1+len);
+ cgm->func->s ( cgm, s, len );
+ return cgm->func->term(cgm);
+}
+
+int cgm_vdc_type ( CGM *cgm, int mode )
+{
+ static const char *vdct[] = { "integer", "real" };
+ cgm->func->wch ( cgm, 1, 3, 2 );
+ cgm->func->e ( cgm, mode, vdct );
+
+ cgm->vdc_type = mode;
+ if ( cgm->vdc_type == 0 ) /* integer */
+ cgm->vdc_size = cgm->vdc_int + 1;
+ else
+ cgm->vdc_size = ( _cgm_ireal_precs[cgm->vdc_real][1] +
+ _cgm_ireal_precs[cgm->vdc_real][2]) / 8;
+
+ return cgm->func->term(cgm);
+}
+
+int cgm_integer_precision ( CGM *cgm, int prec )
+{
+ cgm->func->wch ( cgm, 1, 4, cgm->int_size );
+
+ switch ( cgm->mode )
+ {
+ case 0: /* character */
+ break;
+
+ case 1: /* binary */
+ cgm->func->i ( cgm, (long)(prec) );
+ break;
+
+ case 2: /* clear text */
+ cgm->func->i ( cgm, _cgm_int_precs[prec/8 - 1][0] );
+ cgm->func->sep ( cgm, "," );
+ cgm->func->i ( cgm, _cgm_int_precs[prec/8 - 1][1] );
+ break;
+ }
+
+ cgm->int_prec = prec/8-1;
+ cgm->int_size = prec/8;
+
+ return cgm->func->term(cgm);
+}
+
+int cgm_real_precision ( CGM *cgm, int mode )
+{
+ cgm->func->wch ( cgm, 1, 5, 2 + 2*cgm->int_size );
+ switch ( cgm->mode )
+ {
+ case 0: /* character */
+ break;
+
+ case 1: /* binary */
+ cgm->func->e ( cgm, _cgm_ireal_precs[mode][0] , NULL );
+ cgm->func->i ( cgm, (long)(_cgm_ireal_precs[mode][1]) );
+ cgm->func->i ( cgm, (long)(_cgm_ireal_precs[mode][2]) );
+ break;
+
+ case 2: /* clear text */
+ cgm->func->r ( cgm, _cgm_rreal_precs[mode][0] );
+ cgm->func->sep ( cgm, "," );
+ cgm->func->r ( cgm, _cgm_rreal_precs[mode][1] );
+ cgm->func->sep ( cgm, "," );
+ cgm->func->i ( cgm, (long)(_cgm_ireal_precs[mode][3]) );
+ break;
+ }
+
+ cgm->real_prec = mode;
+ cgm->real_size = ( _cgm_ireal_precs[mode][1] + _cgm_ireal_precs[mode][2]) / 8;
+
+ /* absolute scaling modes */
+ if ( cgm->lnwsm == 1 ) cgm->lnw_size = cgm->real_size;
+ if ( cgm->mkssm == 1 ) cgm->mks_size = cgm->real_size;
+ if ( cgm->edwsm == 1 ) cgm->edw_size = cgm->real_size;
+
+ return cgm->func->term(cgm);
+}
+
+int cgm_index_precision ( CGM *cgm, int prec )
+{
+ cgm->func->wch ( cgm, 1, 6, cgm->int_size );
+ switch ( cgm->mode )
+ {
+ case 0: /* character */
+ break;
+
+ case 1: /* binary */
+ cgm->func->i ( cgm, (long)(prec) );
+ break;
+
+ case 2: /* clear text */
+ cgm->func->i ( cgm, _cgm_int_precs[prec/8 - 1][0] );
+ cgm->func->sep ( cgm, "," );
+ cgm->func->i ( cgm, _cgm_int_precs[prec/8 - 1][1] );
+ break;
+ }
+
+ cgm->ix_prec = prec/8-1;
+ cgm->ix_size = prec/8;
+ return cgm->func->term(cgm);
+}
+
+int cgm_colour_precision ( CGM *cgm, int prec )
+{
+ cgm->func->wch ( cgm, 1, 7, cgm->int_size );
+ switch ( cgm->mode )
+ {
+ case 0: /* character */
+ break;
+
+ case 1: /* binary */
+ cgm->func->i ( cgm, (long)(prec) );
+ break;
+
+ case 2: /* clear text */
+ cgm->func->i ( cgm, 1ul+ 2ul * (unsigned long)_cgm_int_precs[prec/8 - 1][1] );
+ break;
+ }
+
+ cgm->cd_prec = prec/8-1;
+ cgm->cd_size = 3*(prec/8);
+
+ if ( cgm->clrsm == 1 ) /* direct */
+ cgm->clr_size = cgm->cd_size;
+
+ return cgm->func->term(cgm);
+}
+
+int cgm_colour_index_precision ( CGM *cgm, int prec )
+{
+ cgm->func->wch ( cgm, 1, 8, cgm->int_size );
+
+ switch ( cgm->mode )
+ {
+ case 0: /* character */
+ break;
+
+ case 1: /* binary */
+ cgm->func->i ( cgm, (long)(prec) );
+ break;
+
+ case 2: /* clear text */
+ cgm->func->i ( cgm, 1ul+ 2ul * (unsigned long)_cgm_int_precs[prec/8 - 1][1] );
+ break;
+ }
+
+ cgm->cix_prec = prec/8-1;
+ cgm->cix_size = prec/8;
+
+ if ( cgm->clrsm == 0 ) /* indexed */
+ cgm->clr_size = cgm->cix_size;
+
+ return cgm->func->term(cgm);
+}
+
+int cgm_maximum_colour_index ( CGM *cgm, unsigned long ci )
+{
+ cgm->func->wch ( cgm, 1, 9, cgm->cix_size );
+ cgm->func->ci ( cgm, ci );
+ return cgm->func->term(cgm);
+}
+
+int cgm_colour_value_extent ( CGM *cgm, const double *black,
+ const double *white)
+{
+ cgm->func->wch ( cgm, 1, 10, 2 * cgm->cd_size );
+ cgm->func->rgb ( cgm, black[0], black[1], black[2] );
+ cgm->func->nl ( cgm );
+ cgm->func->align ( cgm, 15 );
+ cgm->func->rgb ( cgm, white[0], white[1], white[2] );
+ return cgm->func->term(cgm);
+}
+
+int cgm_metafile_element_list ( CGM *cgm, int n, const int *group, const int *element )
+{
+ register int i;
+ cgm->func->wch ( cgm, 1, 11, 31 );
+ cgm->func->sep ( cgm, "\x22" ); /* aspas */
+ if ( cgm->mode == 1 ) cgm->func->i ( cgm, n );
+ for ( i=0; i<n; i++ )
+ {
+ if ( cgm->mode == 1 ) /* binario */
+ {
+ cgm->func->ix ( cgm, group[i] );
+ cgm->func->ix ( cgm, element[i] );
+ cgm->func->term( cgm );
+ }
+ else
+ {
+ cgm->func->wch ( cgm, group[i], element[i], 0 );
+ cgm->func->sep ( cgm, "" );
+ }
+ }
+ cgm->func->sep ( cgm, "\x22" ); /* aspas */
+ return cgm->func->term(cgm);
+}
+
+int cgm_begin_metafile_defaults ( CGM *cgm )
+{
+ cgm->func->wch ( cgm, 1, 12, 31 );
+
+ /* modo binario - deixa aberto */
+ if ( cgm->mode == 1 ) /* binario */
+ return 0;
+
+ return cgm->func->term(cgm);
+}
+
+int cgm_end_metafile_defaults ( CGM *cgm )
+{
+ /* modo binario - ja estava aberto */
+ if ( cgm->mode != 1 ) /* binario */
+ cgm->func->wch ( cgm, 1, 0, 0 );
+
+ return cgm->func->term(cgm);
+}
+
+int cgm_font_list ( CGM *cgm, const char *fl[] )
+{
+ register int i;
+
+ cgm->func->wch ( cgm, 1, 13, 31 );
+
+ for ( i=0; fl[i] != NULL; i++ )
+ {
+ cgm->func->nl ( cgm );
+ cgm->func->align ( cgm, 10 );
+ cgm->func->s ( cgm, fl[i], strlen(fl[i]) );
+ }
+
+ return cgm->func->term(cgm);
+}
+
+/******************************
+* Picture Descriptor Elements *
+******************************/
+
+int cgm_scaling_mode ( CGM *cgm, int mode, float metric )
+{
+ static const char *sm[] = { "abstract", "metric" };
+ cgm->func->wch ( cgm, 2, 1, 2 + 4 );
+ cgm->func->e ( cgm, mode, sm );
+ if ( cgm->mode == 1 )
+ cgmb_putfl32 ( cgm, metric );
+ else
+ cgm->func->r ( cgm, metric );
+ return cgm->func->term(cgm);
+}
+
+int cgm_colour_selection_mode ( CGM *cgm, int mode)
+{
+ static const char *csm[] = { "indexed", "direct" };
+ cgm->func->wch ( cgm, 2, 2, 2 );
+ cgm->func->e ( cgm, mode, csm );
+
+ cgm->clrsm = mode;
+ if ( mode == 0 ) /* indexed */
+ cgm->clr_size = cgm->cix_size;
+ else
+ cgm->clr_size = cgm->cd_size;
+
+ return cgm->func->term(cgm);
+}
+
+static int _cgm_width_specify_mode ( CGM *cgm, int t, int mode)
+{
+ static const char *sm[] = { "abstract", "scaled" };
+ cgm->func->wch ( cgm, 2, t, 2 );
+ cgm->func->e ( cgm, mode, sm );
+ return cgm->func->term(cgm);
+}
+
+int cgm_line_width_specify_mode ( CGM *cgm, int mode)
+{
+ cgm->lnwsm = mode;
+ if ( mode == 0 )
+ cgm->lnw_size = cgm->vdc_size;
+ else
+ cgm->lnw_size = cgm->real_size;
+ return _cgm_width_specify_mode ( cgm, 3, mode );
+}
+
+int cgm_marker_size_specify_mode ( CGM *cgm, int mode)
+{
+ cgm->mkssm = mode;
+ if ( mode == 0 )
+ cgm->mks_size = cgm->vdc_size;
+ else
+ cgm->mks_size = cgm->real_size;
+ return _cgm_width_specify_mode ( cgm, 4, mode );
+}
+
+int cgm_edge_width_specify_mode ( CGM *cgm, int mode)
+{
+ cgm->edwsm = mode;
+ if ( mode == 0 )
+ cgm->edw_size = cgm->vdc_size;
+ else
+ cgm->edw_size = cgm->real_size;
+ return _cgm_width_specify_mode ( cgm, 5, mode );
+}
+
+int cgm_vdc_extent ( CGM *cgm, double xmin, double ymin,
+ double xmax, double ymax )
+{
+ cgm->func->wch ( cgm, 2, 6, 2*2*cgm->vdc_size );
+ cgm->func->vdc ( cgm, xmin );
+ cgm->func->vdc ( cgm, ymin );
+ cgm->func->vdc ( cgm, xmax );
+ cgm->func->vdc ( cgm, ymax );
+ return cgm->func->term(cgm);
+}
+
+int cgm_backgound_colour ( CGM *cgm, const double *cr )
+{
+ cgm->func->wch ( cgm, 2, 7, cgm->cd_size );
+ cgm->func->rgb ( cgm , cr[0], cr[1], cr[2] );
+ return cgm->func->term(cgm);
+}
+
+/*******************
+* Control Elements *
+*******************/
+
+int cgm_vdc_integer_precision ( CGM *cgm, int prec )
+{
+ cgm->func->wch ( cgm, 3, 1, cgm->int_size );
+ switch ( cgm->mode )
+ {
+ case 0: /* character */
+ break;
+
+ case 1: /* binary */
+ cgm->func->i ( cgm, (long)(prec) );
+ break;
+
+ case 2: /* clear text */
+ cgm->func->i ( cgm, _cgm_int_precs[prec/8 - 1][0] );
+ cgm->func->sep ( cgm, "," );
+ cgm->func->i ( cgm, _cgm_int_precs[prec/8 - 1][1] );
+ break;
+ }
+
+ if ( cgm->vdc_type == 0 )
+ cgm->vdc_size = prec/8;
+
+ cgm->vdc_int = prec/8 - 1;
+
+ if ( cgm->lnwsm == 0 && cgm->vdc_type == 0 ) cgm->lnw_size = cgm->vdc_size;
+ if ( cgm->mkssm == 0 && cgm->vdc_type == 0 ) cgm->mks_size = cgm->vdc_size;
+ if ( cgm->edwsm == 0 && cgm->vdc_type == 0 ) cgm->edw_size = cgm->vdc_size;
+
+ return cgm->func->term(cgm);
+}
+
+int cgm_vdc_real_precision ( CGM *cgm, int mode )
+{
+ cgm->func->wch ( cgm, 3, 2, 2 + 2*cgm->int_size );
+ switch ( cgm->mode )
+ {
+ case 0: /* character */
+ break;
+
+ case 1: /* binary */
+ cgm->func->e ( cgm, _cgm_ireal_precs[mode][0] , NULL );
+ cgm->func->i ( cgm, (long)(_cgm_ireal_precs[mode][1]) );
+ cgm->func->i ( cgm, (long)(_cgm_ireal_precs[mode][2]) );
+ break;
+
+ case 2: /* clear text */
+ cgm->func->r ( cgm, _cgm_rreal_precs[mode][0] );
+ cgm->func->sep ( cgm, "," );
+ cgm->func->r ( cgm, _cgm_rreal_precs[mode][1] );
+ cgm->func->sep ( cgm, "," );
+ cgm->func->i ( cgm, (long)(_cgm_ireal_precs[mode][3]) );
+ break;
+ }
+
+ if ( cgm->vdc_type == 1 )
+ cgm->vdc_size = ( _cgm_ireal_precs[mode][1] + _cgm_ireal_precs[mode][2]) / 8;
+
+ cgm->vdc_real = mode;
+
+ if ( cgm->lnwsm == 0 && cgm->vdc_type == 1 ) cgm->lnw_size = cgm->vdc_size;
+ if ( cgm->mkssm == 0 && cgm->vdc_type == 1 ) cgm->mks_size = cgm->vdc_size;
+ if ( cgm->edwsm == 0 && cgm->vdc_type == 1 ) cgm->edw_size = cgm->vdc_size;
+
+ return cgm->func->term(cgm);
+}
+
+int cgm_auxiliary_colour ( CGM *cgm, const void *c )
+{
+ cgm->func->wch ( cgm, 3, 3, cgm->clr_size );
+
+ cgm->func->co ( cgm, c ) ;
+
+ return cgm->func->term(cgm);
+}
+
+int cgm_transparency ( CGM *cgm, int mode )
+{
+ cgm->func->wch ( cgm, 3, 4, 2 );
+
+ cgm->func->e ( cgm, mode, offon );
+
+ return cgm->func->term(cgm);
+}
+
+int cgm_clip_rectangle ( CGM *cgm, double xmin, double ymin,
+ double xmax, double ymax )
+{
+ cgm->func->wch ( cgm, 3, 5, 4 * cgm->vdc_size );
+
+ cgm->func->vdc ( cgm, xmin );
+ cgm->func->vdc ( cgm, ymin );
+ cgm->func->vdc ( cgm, xmax );
+ cgm->func->vdc ( cgm, ymax );
+
+ return cgm->func->term(cgm);
+}
+
+int cgm_clip_indicator ( CGM *cgm, int mode )
+{
+ cgm->func->wch ( cgm, 3, 6, 2 );
+
+ cgm->func->e ( cgm, mode, offon );
+
+ return cgm->func->term(cgm);
+}
+
+/*******************************
+* Graphical Primitive Elements *
+*******************************/
+
+static int _cgm_point ( CGM *cgm, double x, double y )
+{
+ cgm->func->p ( cgm, x, y );
+ return 0;
+}
+
+static int _cgm_point_list ( CGM *cgm, int element, int n, const double *p)
+{
+ register int i;
+ cgm->func->wch ( cgm, 4, element, 2*n*cgm->vdc_size );
+
+ for ( i=0; i < 2*n; i+=2 )
+ {
+ cgm->func->nl ( cgm );
+ cgm->func->align ( cgm, 8 );
+ _cgm_point ( cgm, p[i], p[i+1] );
+ }
+ return cgm->func->term(cgm);
+}
+
+int cgm_polyline ( CGM *cgm, int n, const double *p )
+{
+ return _cgm_point_list ( cgm, 1, n, p );
+}
+
+int cgm_polymarker ( CGM *cgm, int n, const double *p )
+{
+ return _cgm_point_list ( cgm, 3, n, p );
+}
+
+static int _cgm_text_piece ( CGM *cgm, int t, const char *s, int len)
+{
+ static const char *tt[] = { "NOT_FINAL", " FINAL" };
+ cgm->func->e ( cgm, t, tt );
+ cgm->func->s ( cgm, s , len);
+ return cgm->func->term(cgm);
+}
+
+int cgm_text ( CGM *cgm, int tt, double x, double y, const char *s, int len )
+{
+ cgm->func->wch ( cgm, 4, 4, 2 * cgm->vdc_size + len + 3 );
+ cgm->func->p ( cgm, x, y );
+ cgm->func->nl ( cgm );
+ cgm->func->align ( cgm, 10 );
+
+ if ( cgm->mode == 2 ) /* clear text */
+ {
+ while ( len > 50 )
+ {
+ _cgm_text_piece ( cgm, 0, s, 50);
+ s += 50;
+ len -= 50;
+
+ cgm->func->wch ( cgm, 4, 6, 2 * cgm->vdc_size + len + 1 );
+ }
+ }
+
+ return _cgm_text_piece ( cgm, tt, s, len );
+}
+
+int cgm_polygon ( CGM *cgm, int n, const double *p )
+{
+ return _cgm_point_list ( cgm, 7, n, p );
+}
+
+static int _cgm_cell_rows ( CGM *cgm, long sx, long sy, int prec, const void *c )
+{
+ register long i,j, brk;
+
+ cgm->func->nl ( cgm );
+ cgm->func->sep ( cgm, "(" );
+
+ if ( cgm->clrsm )
+ brk = 5;
+ else
+ brk = 12;
+
+ for ( i=0; i < sy; i++ )
+ {
+ if ( i )
+ {
+ cgm->func->nl ( cgm );
+ cgm->func->align ( cgm, 3 );
+ }
+
+ for ( j=0; j < sx; j++)
+ {
+ if ( j && ( j % brk == 0 ) )
+ {
+ cgm->func->nl ( cgm );
+ cgm->func->align ( cgm, 3 );
+ }
+
+ cgm->func->co ( cgm, c );
+ c = (void*)((char*)c+ (cgm->clrsm ? (3*sizeof(double)) : sizeof(int)));
+
+ if ( i<sy-1 || j<sx-1 ) cgm->func->sep ( cgm, "," );
+ }
+ }
+
+ cgm->func->sep ( cgm, ")" );
+
+ return 0;
+}
+
+int cgm_cell_array ( CGM *cgm, const double *p, long sx, long sy, int prec, const void *c )
+{
+ register int i;
+ static const char *repmode[] = { "run lenght", "packed" };
+
+ cgm->func->wch ( cgm, 4, 9, 31 );
+
+ for ( i=0; i<3*2; i+=2 )
+ _cgm_point ( cgm, p[i], p[i+1] );
+
+ cgm->func->nl (cgm );
+
+ cgm->func->i ( cgm, sx );
+ cgm->func->i ( cgm, sy );
+
+ if ( prec == 0 )
+ cgm->func->i ( cgm, (long)(prec) );
+ else
+ {
+ switch ( cgm->mode )
+ {
+ case 0: /* character */
+ break;
+
+ case 1: /* binary */
+ cgm->func->i ( cgm, (long)(prec) );
+ break;
+
+ case 2: /* clear text */
+ cgm->func->i ( cgm, 2 * ( _cgm_int_precs[prec/8 - 1][1] + 1) );
+ break;
+ }
+ }
+
+ if ( cgm->mode==1 ) cgm->func->e ( cgm, 1, repmode );
+
+ _cgm_cell_rows( cgm, sx, sy, prec, c );
+
+ return cgm->func->term(cgm);
+}
+
+int cgm_rectangle ( CGM *cgm, const double *p )
+{
+ return _cgm_point_list ( cgm, 11, 2, p );
+}
+
+static int _cgm_ellipse_CDP ( CGM *cgm, const double *c, const double *p1,
+ const double *p2 )
+{
+ _cgm_point ( cgm, c[0], c[1] );
+ _cgm_point ( cgm, p1[0], p1[1] );
+ _cgm_point ( cgm, p2[0], p2[1] );
+
+ return 0;
+}
+
+static int _cgm_ellipse_vectors ( CGM *cgm, double dxs, double dys, double dxe,
+ double dye )
+{
+ cgm->func->vdc ( cgm, dxs );
+ cgm->func->vdc ( cgm, dys );
+ cgm->func->vdc ( cgm, dxe );
+ cgm->func->vdc ( cgm, dye );
+
+ return 0;
+}
+
+int cgm_elliptical_arc ( CGM *cgm, const double *c, const double *p1,
+ const double *p2, double dxs, double dys, double dxe,
+ double dye )
+{
+ cgm->func->wch ( cgm, 4, 18, 10*cgm->vdc_size );
+
+ _cgm_ellipse_CDP ( cgm, c, p1, p2 );
+
+ _cgm_ellipse_vectors ( cgm, dxs, dys, dxe, dye );
+
+ return cgm->func->term(cgm);
+}
+
+int cgm_elliptical_arc_close ( CGM *cgm, const double *c, const double *p1,
+ const double *p2, double dxs, double dys,
+ double dxe, double dye, int type )
+{
+ static const char *ct[] = { "pie", "chord" };
+
+ cgm->func->wch ( cgm, 4, 19, 10*cgm->vdc_size + 2 );
+
+ _cgm_ellipse_CDP ( cgm, c, p1, p2 );
+
+ _cgm_ellipse_vectors ( cgm, dxs, dys, dxe, dye );
+
+ cgm->func->e ( cgm, type, ct );
+
+ return cgm->func->term(cgm);
+}
+
+/*********************
+* Attribute Elements *
+*********************/
+
+int cgm_line_bundle_index( CGM *cgm, long li)
+{
+ cgm->func->wch ( cgm, 5, 1, cgm->ix_size );
+ cgm->func->ix ( cgm, li );
+ return cgm->func->term(cgm);
+}
+
+int cgm_line_type( CGM *cgm, long lt)
+{
+ cgm->func->wch ( cgm, 5, 2, cgm->ix_size );
+ cgm->func->ix ( cgm, lt );
+ return cgm->func->term(cgm);
+}
+
+int cgm_line_width( CGM *cgm, double lw)
+{
+ cgm->func->wch ( cgm, 5, 3, cgm->lnw_size );
+
+ if ( cgm->lnwsm == 0 ) /* absolute */
+ cgm->func->vdc ( cgm, lw );
+ else
+ cgm->func->r ( cgm, lw );
+
+ return cgm->func->term(cgm);
+}
+
+int cgm_line_colour( CGM *cgm, const void *lc)
+{
+ cgm->func->wch ( cgm, 5, 4, cgm->clr_size );
+ cgm->func->co ( cgm, lc );
+ return cgm->func->term(cgm);
+}
+
+int cgm_marker_bundle_index( CGM *cgm, long mi)
+{
+ cgm->func->wch ( cgm, 5, 5, cgm->ix_size );
+ cgm->func->ix ( cgm, mi );
+ return cgm->func->term(cgm);
+}
+
+int cgm_marker_type( CGM *cgm, long mt)
+{
+ cgm->func->wch ( cgm, 5, 6, cgm->ix_size );
+ cgm->func->ix ( cgm, mt );
+ return cgm->func->term(cgm);
+}
+
+int cgm_marker_size( CGM *cgm, double ms)
+{
+ cgm->func->wch ( cgm, 5, 7, cgm->mks_size );
+
+ if ( cgm->mkssm == 0 ) /* absolute */
+ cgm->func->vdc ( cgm, ms );
+ else
+ cgm->func->r ( cgm, ms );
+
+ return cgm->func->term(cgm);
+}
+
+int cgm_marker_colour( CGM *cgm, const void *mc)
+{
+ cgm->func->wch ( cgm, 5, 8, cgm->clr_size );
+ cgm->func->co ( cgm, mc );
+ return cgm->func->term(cgm);
+}
+
+int cgm_text_bundle_index( CGM *cgm, long ti)
+{
+ cgm->func->wch ( cgm, 5, 9, cgm->ix_size );
+ cgm->func->ix ( cgm, ti );
+ return cgm->func->term(cgm);
+}
+
+int cgm_text_font_index( CGM *cgm, long fi)
+{
+ cgm->func->wch ( cgm, 5, 10, cgm->ix_size );
+ cgm->func->ix ( cgm, fi );
+ return cgm->func->term(cgm);
+}
+
+int cgm_text_precision( CGM *cgm, int tp)
+{
+ static const char *txprec[] = { "STRING", "CHAR", "STROKE" };
+ cgm->func->wch ( cgm, 5, 11, 2 );
+ cgm->func->e ( cgm, tp, txprec );
+ return cgm->func->term(cgm);
+}
+
+int cgm_char_expansion_factor ( CGM *cgm, double expan )
+{
+ cgm->func->wch ( cgm, 5, 12, cgm->real_size );
+ cgm->func->r ( cgm, expan );
+ return cgm->func->term(cgm);
+}
+
+int cgm_char_spacing ( CGM *cgm, double spacing )
+{
+ cgm->func->wch ( cgm, 5, 13, cgm->real_size );
+ cgm->func->r ( cgm, spacing );
+ return cgm->func->term(cgm);
+}
+
+int cgm_text_colour( CGM *cgm, const void *tc)
+{
+ cgm->func->wch ( cgm, 5, 14, cgm->clr_size );
+ cgm->func->co ( cgm, tc );
+ return cgm->func->term(cgm);
+}
+
+int cgm_char_height ( CGM *cgm, double height )
+{
+ cgm->func->wch ( cgm, 5, 15, cgm->vdc_size );
+ cgm->func->vdc ( cgm, height );
+ return cgm->func->term(cgm);
+}
+
+int cgm_char_orientation ( CGM *cgm, double chupx, double chupy,
+ double chbsx, double chbsy )
+{
+ cgm->func->wch ( cgm, 5, 16, 4*cgm->vdc_size );
+ cgm->func->sep ( cgm, "% char up %" );
+ cgm->func->vdc ( cgm, chupx );
+ cgm->func->sep ( cgm, "," );
+ cgm->func->vdc ( cgm, chupy );
+ cgm->func->nl ( cgm );
+ cgm->func->align ( cgm, 8 );
+ cgm->func->sep ( cgm, "% char base %" );
+ cgm->func->vdc ( cgm, chbsx );
+ cgm->func->sep ( cgm, "," );
+ cgm->func->vdc ( cgm, chbsy );
+ return cgm->func->term(cgm);
+}
+
+int cgm_text_path ( CGM *cgm, int tp)
+{
+ static const char *txpath[] = { "RIGHT", "LEFT", "UP", "DOWN" };
+ cgm->func->wch ( cgm, 5, 17, 2 );
+ cgm->func->e ( cgm, tp, txpath );
+ return cgm->func->term(cgm);
+}
+
+int cgm_text_alignment ( CGM *cgm, int hor, int ver , double ch, double cv)
+{
+ static const char *txhor[] = { "NORMHORIZ", "LEFT", "CTR", "RIGHT", "CONTHORIZ" };
+ static const char *txver[] = { "NORMVERT", "TOP", "CAP", "HALF", "BASE",
+ "BOTTOM", "CONTHORIZ" };
+
+ cgm->func->wch ( cgm, 5, 18, 2*2 + 2*cgm->real_size );
+ cgm->func->e ( cgm, hor, txhor );
+ cgm->func->e ( cgm, ver, txver );
+ cgm->func->r ( cgm, ch );
+ cgm->func->r ( cgm, cv );
+ return cgm->func->term(cgm);
+}
+
+int cgm_fill_bundle_index( CGM *cgm, long fi)
+{
+ cgm->func->wch ( cgm, 5, 21, cgm->ix_size );
+ cgm->func->ix ( cgm, fi );
+ return cgm->func->term(cgm);
+}
+
+int cgm_interior_style( CGM *cgm, int is)
+{
+ static const char *style[]= { "HOLLOW", "SOLID", "PAT", "HATCH", "EMPTY" };
+ cgm->func->wch ( cgm, 5, 22, 2 );
+ cgm->func->e ( cgm, is, style );
+ return cgm->func->term(cgm);
+}
+
+int cgm_fill_colour( CGM *cgm, const void *fc)
+{
+ cgm->func->wch ( cgm, 5, 23, cgm->clr_size );
+ cgm->func->co ( cgm, fc );
+ return cgm->func->term(cgm);
+}
+
+int cgm_hatch_index( CGM *cgm, long hi)
+{
+ cgm->func->wch ( cgm, 5, 24, cgm->ix_size );
+ cgm->func->ix ( cgm, hi );
+ return cgm->func->term(cgm);
+}
+
+int cgm_pattern_index( CGM *cgm, long pi)
+{
+ cgm->func->wch ( cgm, 5, 25, cgm->ix_size );
+ cgm->func->ix ( cgm, pi );
+ return cgm->func->term(cgm);
+}
+
+int cgm_edge_width( CGM *cgm, double ew)
+{
+ cgm->func->wch ( cgm, 5, 28, cgm->edw_size );
+
+ if ( cgm->lnwsm == 0 ) /* absolute */
+ cgm->func->vdc ( cgm, ew );
+ else
+ cgm->func->r ( cgm, ew );
+
+ return cgm->func->term(cgm);
+}
+
+int cgm_edge_colour( CGM *cgm, const void *ec)
+{
+ cgm->func->wch ( cgm, 5, 29, cgm->clr_size );
+ cgm->func->co ( cgm, ec );
+ return cgm->func->term(cgm);
+}
+
+int cgm_edge_visibility ( CGM *cgm, int mode )
+{
+ cgm->func->wch ( cgm, 5, 30, 2 );
+ cgm->func->e ( cgm, mode, offon );
+ return cgm->func->term(cgm);
+}
+
+int cgm_fill_reference_point ( CGM *cgm, double rpx, double rpy )
+{
+ cgm->func->wch ( cgm, 5, 31, 2*cgm->vdc_size );
+ _cgm_point ( cgm, rpx, rpy );
+ return cgm->func->term(cgm);
+}
+
+int cgm_pattern_table ( CGM *cgm, long pi, long sx, long sy, int prec, const void *c)
+{
+ cgm->func->wch ( cgm, 5, 32, 31 );
+ cgm->func->ix ( cgm, pi );
+
+ cgm->func->i ( cgm, sx );
+ cgm->func->i ( cgm, sy );
+
+ if ( prec == 0 )
+ cgm->func->i ( cgm, (long)(prec) );
+ else
+ {
+ switch ( cgm->mode )
+ {
+ case 0: /* character */
+ break;
+
+ case 1: /* binary */
+ cgm->func->i ( cgm, (long)(prec) );
+ break;
+
+ case 2: /* clear text */
+ cgm->func->i ( cgm, 2 * ( _cgm_int_precs[prec/8 - 1][1] + 1) );
+ break;
+ }
+ }
+
+ _cgm_cell_rows( cgm, sx, sy, prec, c );
+
+ return cgm->func->term(cgm);
+}
+
+int cgm_pattern_size ( CGM *cgm, double hx, double hy, double wx, double wy )
+{
+ cgm->func->wch ( cgm, 5, 33, 4*cgm->vdc_size );
+ cgm->func->sep ( cgm, "% height %" );
+ cgm->func->vdc ( cgm, hx );
+ cgm->func->sep ( cgm, "," );
+ cgm->func->vdc ( cgm, hy );
+ cgm->func->nl ( cgm );
+ cgm->func->align ( cgm, 8 );
+ cgm->func->sep ( cgm, "% width %" );
+ cgm->func->vdc ( cgm, wx );
+ cgm->func->sep ( cgm, "," );
+ cgm->func->vdc ( cgm, wy );
+ return cgm->func->term(cgm);
+}
+
+int cgm_colour_table ( CGM *cgm, long ci, long n, const double *cb )
+{
+ register long i=n;
+
+ if ( n > 31 ) n = 31;
+
+ cgm->func->wch ( cgm, 5, 34, cgm->int_size+n*cgm->cd_size );
+ cgm->func->i ( cgm, ci );
+
+ n = i;
+
+ for ( i=0; i<n; i++ )
+ {
+ if ( i )
+ {
+ cgm->func->nl ( cgm );
+ cgm->func->align ( cgm, 18 );
+ }
+ cgm->func->rgb ( cgm, cb[(int)i], cb[(int)i+1], cb[(int)i+2] );
+ }
+
+ return cgm->func->term(cgm);
+}
+
+static void _cgm_asf_pair ( CGM *cgm, int asft, int asfv )
+{
+ static const char *asfvl[] = { "INDIV", "BUNDLED" };
+ static const char *asftl[] = {
+ "LINE_TYPE", "LINE_WIDTH", "LINE_COLR",
+ "MARKER_TYPE", "MARKER_SIZE", "MARKER_COLR",
+ "TEXT_FONT_INDEX", "TEXT_PREC", "CHAR_EXP", "CHAR_SPACE", "TEXT_COLR",
+ "INT_STYLE", "FILL_COLR", "HATCH_INDEX", "PAT_INDEX",
+ "EDGE_TYPE", "EDGE_WIDTH", "EDGE_COLR",
+ "ALL", "ALL_LINE", "ALL_MARKER", "ALL_TEXT", "ALL_FILL", "ALL_EDGE"
+ };
+
+ cgm->func->nl ( cgm );
+ cgm->func->align ( cgm, 4 );
+ cgm->func->e ( cgm, asft, asftl );
+ cgm->func->e ( cgm, asfv, asfvl );
+}
+
+int cgm_asfs ( CGM *cgm, int n, const int *asfts, const int* asfvs )
+{
+ register int i;
+ cgm->func->wch ( cgm, 5, 35, 2*n* 2 );
+
+ for ( i=0; i<n; i++ )
+ _cgm_asf_pair ( cgm, asfts[i], asfvs[i] );
+
+ return cgm->func->term(cgm);
+}
+
+/*****************
+* Escape Element *
+*****************/
+
+/********************
+* External elements *
+********************/
+
+int cgm_message ( CGM *cgm, int action, const char *s)
+{
+ static const char *ac[] = { "NOACTION", "ACTION" };
+ cgm->func->wch ( cgm, 7, 2, 2 + strlen(s)+1 );
+ cgm->func->e ( cgm, action, ac );
+ cgm->func->s ( cgm, s, strlen(s) );
+ return cgm->func->term(cgm);
+}