[BACK]Return to cgm.trm CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gnuplot / term

Annotation of OpenXM_contrib/gnuplot/term/cgm.trm, Revision 1.1.1.1

1.1       maekawa     1: /* Hey Emacs this is -*- C -*-
                      2:  * $Id: cgm.trm,v 1.16 1998/06/18 14:59:18 ddenholm Exp $
                      3:  */
                      4:
                      5: /* GNUPLOT - cgm.trm */
                      6:
                      7: /*[
                      8:  * Copyright 1998
                      9:  *
                     10:  * Permission to use, copy, and distribute this software and its
                     11:  * documentation for any purpose with or without fee is hereby granted,
                     12:  * provided that the above copyright notice appear in all copies and
                     13:  * that both that copyright notice and this permission notice appear
                     14:  * in supporting documentation.
                     15:  *
                     16:  * Permission to modify the software is granted, but not the right to
                     17:  * distribute the complete modified source code.  Modifications are to
                     18:  * be distributed as patches to the released version.  Permission to
                     19:  * distribute binaries produced by compiling modified sources is granted,
                     20:  * provided you
                     21:  *   1. distribute the corresponding source modifications from the
                     22:  *    released version in the form of a patch file along with the binaries,
                     23:  *   2. add special version identification to distinguish your version
                     24:  *    in addition to the base release version number,
                     25:  *   3. provide your name and address as the primary contact for the
                     26:  *    support of your modified version, and
                     27:  *   4. retain our contact information in regard to use of the base
                     28:  *    software.
                     29:  * Permission to distribute the released version of the source code along
                     30:  * with corresponding source modifications in the form of a patch file is
                     31:  * granted with same provisions 2 through 4 for binary distributions.
                     32:  *
                     33:  * This software is provided "as is" without express or implied warranty
                     34:  * to the extent permitted by applicable law.
                     35: ]*/
                     36:
                     37: /*
                     38:  * This file is included by ../term.c and ../docs/termdoc.c.
                     39:  *
                     40:  * This terminal driver supports:
                     41:  *   Computer Graphics Metafile
                     42:  *
                     43:  * TODO
                     44:  *   better control over plot size (never cutting off labels, correct font
                     45:  *   sizes)
                     46:  *   Fix font sizes for portrait orientation
                     47:  *
                     48:  * AUTHOR
                     49:  *   Jim Van Zandt <jrv@vanzandt.mv.com>
                     50:  *
                     51:  * send your comments or suggestions to (info-gnuplot@dartmouth.edu).
                     52: */
                     53:
                     54: #include "driver.h"
                     55:
                     56: #ifdef TERM_REGISTER
                     57: register_term(cgm)
                     58: #endif
                     59:
                     60: #ifdef TERM_PROTO
                     61: TERM_PUBLIC void CGM_options __PROTO((void));
                     62: TERM_PUBLIC void CGM_init __PROTO((void));
                     63: TERM_PUBLIC void CGM_reset __PROTO((void));
                     64: TERM_PUBLIC void CGM_text __PROTO((void));
                     65: TERM_PUBLIC void CGM_graphics __PROTO((void));
                     66: TERM_PUBLIC void CGM_move __PROTO((unsigned int x, unsigned int y));
                     67: TERM_PUBLIC void CGM_dashed_vector __PROTO((unsigned int ux, unsigned int uy));
                     68: TERM_PUBLIC void CGM_solid_vector __PROTO((unsigned int ux, unsigned int uy));
                     69: TERM_PUBLIC void CGM_linetype __PROTO((int linetype));
                     70: TERM_PUBLIC void CGM_linecolor __PROTO((int color));
                     71: TERM_PUBLIC void CGM_dashtype __PROTO((int dashtype));
                     72: TERM_PUBLIC void CGM_linewidth __PROTO((double width));
                     73: TERM_PUBLIC void CGM_put_text __PROTO((unsigned int x, unsigned int y,
                     74:                                       char *str));
                     75: TERM_PUBLIC int CGM_text_angle __PROTO((int ang));
                     76: TERM_PUBLIC int CGM_justify_text __PROTO((enum JUSTIFY mode));
                     77: TERM_PUBLIC void CGM_point __PROTO((unsigned int x, unsigned int y,
                     78:                                    int number));
                     79: TERM_PUBLIC int CGM_find_font __PROTO((char *font, int numchar));
                     80: TERM_PUBLIC int CGM_set_font __PROTO((char *font));
                     81: TERM_PUBLIC void CGM_set_pointsize __PROTO((double size));
                     82:
                     83: #define CGM_LARGE 32767
                     84: #define CGM_SMALL 32767/18*13  /* aspect ratio 1:.7222 */
                     85: #define CGM_MARGIN (CGM_LARGE/180)
                     86:                                /* convert from plot units to pt */
                     87: #define CGM_PT ((term->xmax + CGM_MARGIN)/cgm_plotwidth)
                     88: #define CGM_LINE_TYPES 9       /* number of line types we support */
                     89: #define CGM_COLORS 7           /* number of colors we support */
                     90: #define CGM_POINTS 8           /* number of markers we support */
                     91: #define CGM_MAX_SEGMENTS 104   /* maximum # polyline coordinates */
                     92: #define CGM_VCHAR (CGM_SMALL/360*12)
                     93: #define CGM_HCHAR (CGM_SMALL/360*12*5/9)
                     94: #define CGM_VTIC (CGM_LARGE/80)
                     95: #define CGM_HTIC (CGM_LARGE/80)
                     96: #endif
                     97:
                     98: #ifndef TERM_PROTO_ONLY
                     99: #ifdef TERM_BODY
                    100:
                    101: /*
                    102:  * on NeXTstep, id is an identifier (in ObjC) and causes a parse error
                    103:  * since some asserts below are mistaken as casts. datum is a type
                    104:  * defined in ndbm.h which also causes a parse error (ndbm.h is
                    105:  * included as part of appkit.h, I think).  Strangely enough, both
                    106:  * errors only happen with cpp-precomp -smart, not with the regular
                    107:  * cpp. (AL)
                    108:  */
                    109:
                    110: #ifdef NEXT
                    111: #define id id_
                    112: #define datum datum_
                    113: #endif
                    114:
                    115: #include <ctype.h>             /* for isspace() */
                    116:
                    117: #ifndef assert
                    118: #define assert(x) 0            /* defeat assertions */
                    119: #endif
                    120:
                    121: /* uncomment the following to enable assertions for this module only,
                    122:    regardless of compiler switches */
                    123: #ifdef NDEBUG
                    124: #define DEFEAT_ASSERTIONS
                    125: #endif
                    126: #undef NDEBUG
                    127: #include <assert.h>
                    128:
                    129:
                    130: #define CGM_ADJ (sizeof(int)/sizeof(short))
                    131:
                    132: static unsigned int cgm_posx;
                    133: static unsigned int cgm_posy;
                    134: static unsigned int cgm_linetype = 1;
                    135: static unsigned int cgm_dashtype = 0;
                    136: static unsigned int cgm_color = 0;
                    137: static int cgm_polyline[CGM_MAX_SEGMENTS];     /* stored polyline coordinates */
                    138: static int cgm_coords = 0;     /* # polyline coordinates saved */
                    139: enum JUSTIFY cgm_justify = LEFT;
                    140: static int cgm_vert_text = 0;  /* text orientation -- nonzero for vertical */
                    141: static int cgm_vert_text_requested = 0;
                    142: static int cgm_step_sizes[8];  /* array of currently used dash
                    143:                                   lengths in plot units */
                    144: static int cgm_step_index = 0; /* index into cgm_step_sizes[] */
                    145: static int cgm_step = 0;       /* amount of current dash not yet
                    146:                                   drawn, in plot units */
                    147: static int cgm_tic, cgm_tic707, cgm_tic866, cgm_tic500, cgm_tic1241, cgm_tic1077, cgm_tic621;  /* marker dimensions */
                    148:        /* Each font string is preceded by a byte with its length */
                    149: static char GPFAR cgm_font_data[] =
                    150: {"\
                    151: \005Arial\
                    152: \014Arial Italic\
                    153: \012Arial Bold\
                    154: \021Arial Bold Italic\
                    155: \013Times Roman\
                    156: \022Times Roman Italic\
                    157: \020Times Roman Bold\
                    158: \027Times Roman Bold Italic\
                    159: \011Helvetica\
                    160: \005Roman\
                    161: "};
                    162:
                    163: /* variables to record the options */
                    164: static char cgm_font[32] = "Arial Bold";
                    165: static unsigned int cgm_fontsize = 10;
                    166: static unsigned cgm_linewidth; /* line width in plot units */
                    167: static unsigned cgm_linewidth_pt = 1;  /* line width in pt */
                    168: static TBOOLEAN cgm_monochrome = FALSE;                /* colors enabled? */
                    169: static int cgm_plotwidth = 432;        /* assumed width of plot in pt. */
                    170: static TBOOLEAN cgm_portrait = FALSE;  /* portrait orientation? */
                    171: static TBOOLEAN cgm_rotate = TRUE;     /* text rotation enabled? */
                    172: static TBOOLEAN cgm_dashed = TRUE;     /* dashed linestyles enabled? */
                    173: static TBOOLEAN cgm_winword6_mode = FALSE;     /* workaround for WinWord bug? */
                    174:
                    175: /* prototypes for static functions */
                    176: static void CGM_flush_polyline __PROTO((void));
                    177: static void CGM_flush_polygon __PROTO((void));
                    178: static void CGM_write_char_record __PROTO((int class, int cgm_id, int length,
                    179:                                           char *data));
                    180: static void CGM_write_code __PROTO((int class, int cgm_id, int length));
                    181: static void CGM_write_int __PROTO((int value));
                    182: static void CGM_write_int_record __PROTO((int class, int cgm_id, int length,
                    183:                                          int *data));
                    184: static void CGM_write_mixed_record __PROTO((int class, int cgm_id,
                    185:                                            int numint, int *int_data,
                    186:                                            int numchar, char *char_data));
                    187:
                    188:
                    189:
                    190: TERM_PUBLIC void CGM_init()
                    191: {
                    192:     cgm_posx = cgm_posy = 0;
                    193:     cgm_linetype = 0;
                    194:     cgm_vert_text = 0;
                    195: }
                    196:
                    197: TERM_PUBLIC void CGM_graphics()
                    198: {
                    199:     register struct termentry *t = term;
                    200:     static int version_data[] = { 1 };
                    201:     static char GPFAR description_data[] = "Computer Graphics Metafile version of Gnuplot";
                    202:     static int vdc_type_data[] = { 0 };
                    203:     static int integer_precision_data[] = { 16 };
                    204:     static int real_precision_data[] = { 1, 16, 16 };
                    205:     static int index_precision_data[] = { 16 };
                    206:     static int color_precision_data[] = { 16 };
                    207:     static int color_index_precision_data[] = { 16 };
                    208:     static int maximum_color_index_data_data[] = { CGM_COLORS };
                    209:     static int scaling_mode_data[] = { 0, 0, 0 };
                    210:     static int color_value_extent_data[] = { 0, 0, 0, 255, 255, 255 };
                    211:     static int GPFAR color_table_data[] =
                    212: /* for testing
                    213:     {
                    214:       8, 0,0,0, 64,64,64, 128,128,128, 196,196,196, 0,255,255, 255,0,255,
                    215:       255,255,0, 255,255,255
                    216:     };
                    217: */
                    218:     {
                    219:        CGM_COLORS,
                    220:        0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 0, 255, 0, 255, 0, 255, 255
                    221: /*    black    red     green    blue      yellow    magenta     cyan  */
                    222:     };
                    223:
                    224:     static int color_selection_mode_data[] = { 0 };
                    225:     static int linewidth_specification_mode_data[] = { 0 };
                    226:     static int marker_size_specification_mode_data[] = { 0 };
                    227:     static int vdc_extent_data[] = { 0, 0, 0, 0 };
                    228:     static int vdc_integer_precision_data[] = { 16 };
                    229:     static int transparency_data[] = { 0 }; /* text background: 1=transparent */
                    230:     static int clip_indicator_data[] = { 0 };
                    231: /*  static int line_color_data[] = { 1 }; */
                    232:     static int line_type_data[] = { 1 };
                    233:     static int interior_style_data[] = { 1 };                  /* 1=filled */
                    234:
                    235:     static int GPFAR elements_list_data[] =
                    236:     {
                    237:        0,                      /* will be set to # elements in this list */
                    238:        0, 1,                   /* Begin Metafile */
                    239:        0, 2,                   /* End Metafile */
                    240:        0, 3,                   /* Begin Picture */
                    241:        0, 4,                   /* Begin Picture Body */
                    242:        0, 5,                   /* End Picture */
                    243:        1, 1,                   /* Metafile Version */
                    244:        1, 2,                   /* Metafile Description */
                    245:        1, 3,                   /* VDC Type */
                    246:        1, 4,                   /* Integer Precision */
                    247:        1, 5,                   /* Real Precision */
                    248:        1, 6,                   /* Index Precision */
                    249:        1, 7,                   /* Color Precision */
                    250:        1, 8,                   /* Color Index Precision */
                    251:        1, 9,                   /* Maximum Color Index */
                    252:        2, 1,                   /* Scaling Mode */
                    253:        2, 2,                   /* Color Selection Mode */
                    254:        2, 3,                   /* Line Width Specification Mode */
                    255:        2, 4,                   /* Marker Size Specification Mode */
                    256:        2, 6,                   /* VDC Extent */
                    257:        3, 1,                   /* VDC Integer Precision */
                    258:        3, 4,                   /* Transparency */
                    259:        3, 6,                   /* Clip Indicator */
                    260:        4, 1,                   /* Polyline */
                    261:        4, 3,                   /* Polymarker */
                    262:        4, 4,                   /* Text */
                    263:        4, 7,                   /* Polygon */
                    264:        4, 11,                  /* Rectangle */
                    265:        4, 12,                  /* Circle */
                    266:        4, 15,                  /* Circular Arc Center */
                    267:        4, 16,                  /* Circular Arc Center Close */
                    268:        4, 17,                  /* Ellipse */
                    269:        4, 18,                  /* Elliptical Arc */
                    270:        4, 19,                  /* Elliptical Arc Close */
                    271:        5, 2,                   /* Line Type */
                    272:        5, 3,                   /* Line Width */
                    273:        5, 4,                   /* Line Color */
                    274:        5, 6,                   /* Marker Type */
                    275:        5, 7,                   /* Marker Size */
                    276:        5, 8,                   /* Marker Color */
                    277:        5, 10,                  /* Text Font Index */
                    278:        5, 14,                  /* Text Color */
                    279:        5, 15,                  /* Character Height */
                    280:        5, 16,                  /* Character Orientation */
                    281:        5, 18,                  /* Text Alignment */
                    282:        5, 22,                  /* Interior Style */
                    283:        5, 23,                  /* Fill Color */
                    284:        5, 24,                  /* Hatch Index */
                    285:        6, 1,                   /* Escape */
                    286:        7, 2                    /* Application Data */
                    287:     };
                    288:
                    289:     /* metafile description (class 1) */
                    290:     if (!outstr)
                    291:        CGM_write_char_record(0, 1, 1, outstr);
                    292:     else
                    293:        CGM_write_char_record(0, 1, strlen(outstr) + 1, outstr);
                    294:     CGM_write_int_record(1, 1, 2, version_data);
                    295:     CGM_write_char_record(1, 2, sizeof(description_data), description_data);
                    296:     CGM_write_int_record(1, 3, 2, vdc_type_data);
                    297:     CGM_write_int_record(1, 4, 2, integer_precision_data);
                    298:     CGM_write_int_record(1, 5, 6, real_precision_data);
                    299:     CGM_write_int_record(1, 6, 2, index_precision_data);
                    300:     CGM_write_int_record(1, 7, 2, color_precision_data);
                    301:     CGM_write_int_record(1, 8, 2, color_index_precision_data);
                    302:     CGM_write_int_record(1, 9, 2, maximum_color_index_data_data);
                    303:     CGM_write_int_record(1, 10, sizeof(color_value_extent_data) / CGM_ADJ,
                    304:                         color_value_extent_data);
                    305:     elements_list_data[0] = (sizeof(elements_list_data) / CGM_ADJ - 2) / 4;
                    306:     CGM_write_int_record(1, 11, sizeof(elements_list_data) / CGM_ADJ,
                    307:                         elements_list_data);
                    308:     if (cgm_winword6_mode == FALSE)
                    309:        CGM_write_char_record(1, 13, strlen(cgm_font_data), cgm_font_data);
                    310:
                    311:     /* picture description (classes 2 and 3) */
                    312:     CGM_write_char_record(0, 3, 8, "PICTURE1");
                    313:     CGM_write_int_record(2, 1, 6, scaling_mode_data);
                    314:     CGM_write_int_record(2, 2, 2, color_selection_mode_data);
                    315:     CGM_write_int_record(2, 3, 2, linewidth_specification_mode_data);
                    316:     CGM_write_int_record(2, 4, 2, marker_size_specification_mode_data);
                    317:     vdc_extent_data[2] = t->xmax + CGM_MARGIN;
                    318:     vdc_extent_data[3] = t->ymax + CGM_MARGIN;
                    319:     CGM_write_int_record(2, 6, 8, vdc_extent_data);
                    320:     CGM_write_int_record(3, 1, 2, vdc_integer_precision_data);
                    321:     CGM_write_int_record(3, 4, sizeof(transparency_data) / CGM_ADJ,
                    322:                         transparency_data);
                    323:     CGM_write_int_record(3, 6, sizeof(clip_indicator_data) / CGM_ADJ,
                    324:                         clip_indicator_data);
                    325:
                    326:     /* picture body (classes 4 and 5) */
                    327:     CGM_write_int_record(0, 4, 0, NULL);
                    328:     /* The WinWord 6.0 and PublishIt input
                    329:        filters seem to mostly ignore the
                    330:        color table.  With the table, WinWord
                    331:        maps color 7 to black. */
                    332:     if (!cgm_winword6_mode)
                    333:        CGM_write_int_record(5, 34, sizeof(color_table_data) / CGM_ADJ,
                    334:                             color_table_data);
                    335:     CGM_write_int_record(5, 2, sizeof(line_type_data) / CGM_ADJ,
                    336:                         line_type_data);
                    337:     cgm_linewidth = cgm_linewidth_pt * CGM_PT;
                    338:     CGM_write_int_record(5, 3, sizeof(cgm_linewidth) / CGM_ADJ,
                    339:                         (int *) &cgm_linewidth);
                    340:     CGM_linecolor(0);
                    341: /*  CGM_write_int_record(5, 4, sizeof(line_color_data)/CGM_ADJ, line_color_data); */
                    342:     CGM_write_int_record(5, 15, 2, (int *) &t->v_char);
                    343:     CGM_write_int_record(5, 22, 2, interior_style_data);
                    344:     {
                    345:        char buf[45];
                    346:        sprintf(buf, "%.31s,%d", cgm_font, cgm_fontsize);
                    347:        CGM_set_font(buf);
                    348:     }
                    349:     CGM_set_pointsize(pointsize);
                    350: }
                    351:
                    352: TERM_PUBLIC int CGM_find_font(font, numchar)
                    353: char *font;
                    354: int numchar;
                    355: {
                    356:     int font_index = 1;
                    357:     char *s;
                    358:     for (s = cgm_font_data; s < cgm_font_data + strlen(cgm_font_data); s += (int) *s + 1) {
                    359:        /* strnicmp is not standard, but defined by stdfn.c if not available */
                    360:        if (numchar == (int) *s && strnicmp(font, s + 1, numchar - 1) == 0)
                    361:            return font_index;
                    362:        font_index++;
                    363:     }
                    364:     return 0;
                    365: }
                    366:
                    367: TERM_PUBLIC int CGM_set_font(font)
                    368: char *font;
                    369: {
                    370:     register struct termentry *t = term;
                    371:     int size, font_index;
                    372:     char *comma;
                    373:     int sep;
                    374:
                    375:     comma = strchr(font, ',');
                    376:     if (comma == NULL)
                    377:        return FALSE;           /* bad format */
                    378:     sep = comma - font;
                    379:     /* find font in font table, or use 1st font */
                    380:     font_index = CGM_find_font(font, sep);
                    381:     if (font_index == 0)
                    382:        font_index = 1;
                    383:     CGM_write_int_record(5, 10, 2, &font_index);
                    384:
                    385:     /* set font size */
                    386:     size = cgm_fontsize;
                    387:     sscanf(comma + 1, "%d", &size);
                    388:     if (sep > 31)
                    389:        sep = 31;
                    390:     strncpy(cgm_font, font, sep);
                    391:     cgm_font[sep] = NUL;
                    392:     t->v_char = size * CGM_PT;
                    393:     t->h_char = (t->v_char * 5) / 9;
                    394:     CGM_write_int_record(5, 15, 2, (int *) &t->v_char);
                    395:     return TRUE;
                    396: }
                    397:
                    398: TERM_PUBLIC void CGM_text()
                    399: {
                    400:     CGM_flush_polyline();
                    401:     CGM_write_int_record(0, 5, 0, NULL);       /* end picture */
                    402:     CGM_write_int_record(0, 2, 0, NULL);       /* end metafile */
                    403: }
                    404:
                    405: TERM_PUBLIC void CGM_linetype(linetype)
                    406: int linetype;
                    407: {
                    408:     assert(linetype >= -2);
                    409:     if (linetype == cgm_linetype)
                    410:        return;
                    411:     cgm_linetype = linetype;
                    412:
                    413:     CGM_linecolor(linetype);
                    414:     if (cgm_dashed) {
                    415:        CGM_dashtype(linetype); /* DBT 10-8-98    use dashes */
                    416:     } else {
                    417:        /* dashes for gridlines, solid for everything else */
                    418:        CGM_dashtype(linetype == -1 ? 2 : 0);
                    419:     }
                    420:     /* CGM_dashtype(cgm_monochrome ? linetype : 0); first fix, color->no dashes */
                    421:     /* CGM_dashtype(linetype);  orig distribution              */
                    422: }
                    423:
                    424: TERM_PUBLIC void CGM_linecolor(linecolor)
                    425: int linecolor;
                    426: {
                    427:     assert(linecolor >= -2);
                    428:     linecolor = (linecolor < 1) ? 1 : linecolor % CGM_COLORS + 1;
                    429:     if (cgm_monochrome || linecolor == cgm_color)
                    430:        return;
                    431:     cgm_color = linecolor;
                    432:
                    433:     CGM_flush_polyline();
                    434:     CGM_write_int_record(5, 4, 2, (int *) &cgm_color);
                    435:     CGM_write_int_record(5, 23, 2, (int *) &cgm_color);
                    436: }
                    437:
                    438: TERM_PUBLIC void CGM_linewidth(width)
                    439: double width;
                    440: {
                    441:     int new_linewidth;
                    442:
                    443:     assert(width >= 1.);
                    444:     new_linewidth = width * cgm_linewidth_pt * CGM_PT;
                    445:     if (new_linewidth == cgm_linewidth)
                    446:        return;
                    447:     cgm_linewidth = new_linewidth;
                    448:     CGM_write_int_record(5, 3, sizeof(cgm_linewidth) / CGM_ADJ,
                    449:                         (int *) &cgm_linewidth);
                    450:     CGM_dashtype(cgm_dashtype);        /* have dash lengths recalculated */
                    451: }
                    452:
                    453: TERM_PUBLIC void CGM_dashtype(dashtype)
                    454: int dashtype;
                    455: {
                    456:     int i, j;
                    457:     /* Each group of 8 entries in dot_length[] defines a dash
                    458:        pattern.  Entries in each group are alternately length of
                    459:        whitespace and length of line, in units of 2/3 of the
                    460:        linewidth. */
                    461:     static int dot_length[CGM_LINE_TYPES * 8] =
                    462:     {                          /* 0 - solid             */
                    463:        5, 8, 5, 8, 5, 8, 5, 8, /* 1 - dashes            */
                    464:        5, 3, 5, 3, 5, 3, 5, 3, /* 2 - short dashes      */
                    465:        4, 1, 4, 1, 4, 1, 4, 1, /* 3 - dotted            */
                    466:        4, 8, 4, 1, 4, 8, 4, 1, /* 4 - dash-dot          */
                    467:        4, 9, 4, 1, 4, 1, 0, 0, /* 5 - dash-dot-dot      */
                    468:        4, 10, 4, 1, 4, 1, 4, 1,        /* 6 - dash-dot-dot-dot  */
                    469:        4, 10, 4, 10, 4, 1, 0, 0,       /* 7 - dash-dash-dot     */
                    470:        4, 10, 4, 10, 4, 1, 4, 1};      /* 8 - dash-dash-dot-dot */
                    471:
                    472:
                    473:     assert(dashtype >= -2);
                    474:     if (dashtype == cgm_dashtype)
                    475:        return;
                    476:     cgm_dashtype = dashtype;
                    477:
                    478:     CGM_flush_polyline();
                    479:
                    480:     if (dashtype >= CGM_LINE_TYPES)
                    481:        dashtype = dashtype % CGM_LINE_TYPES;
                    482:     if (dashtype < 1) {
                    483:        term->vector = CGM_solid_vector;
                    484:        return;
                    485:     }
                    486:     term->vector = CGM_dashed_vector;
                    487:
                    488:     /* set up dash dimensions */
                    489:     j = (dashtype - 1) * 8;
                    490:     for (i = 0; i < 8; i++, j++) {
                    491:        if (dot_length[j])
                    492:            cgm_step_sizes[i] = (dot_length[j] * cgm_linewidth) * 2 / 3;
                    493:        else
                    494:            cgm_step_sizes[i] = 0;
                    495:     }
                    496:     /* first thing drawn will be a line */
                    497:     cgm_step = cgm_step_sizes[1];
                    498:     cgm_step_index = 1;
                    499: }
                    500:
                    501: TERM_PUBLIC void CGM_move(x, y)
                    502: unsigned int x, y;
                    503: {
                    504:     assert(x < term->xmax && y < term->ymax);
                    505:     if (x == cgm_posx && y == cgm_posy)
                    506:        return;
                    507:     CGM_flush_polyline();
                    508:     cgm_posx = x;
                    509:     cgm_posy = y;
                    510: }
                    511:
                    512: static void CGM_flush_polyline()
                    513: {
                    514:     if (cgm_coords == 0)
                    515:        return;
                    516:     CGM_write_int_record(4, 1, cgm_coords * 2, cgm_polyline);
                    517:     cgm_coords = 0;
                    518: }
                    519:
                    520: static void CGM_write_char_record(class, cgm_id, numbytes, data)
                    521: int class, cgm_id, numbytes;
                    522: char *data;
                    523: {
                    524:     int pad, padded_length;
                    525:     static unsigned char flag = 0xff;
                    526:     char short_len;
                    527:
                    528:     pad = 0;
                    529:     padded_length = numbytes + 1;
                    530:     if (numbytes >= 255)
                    531:        padded_length += 2;     /* long string */
                    532:     if (padded_length & 1)
                    533:        padded_length += pad = 1;       /* needs pad */
                    534:     CGM_write_code(class, cgm_id, padded_length);
                    535:     short_len = numbytes;
                    536:     if (numbytes < 255)
                    537:        fwrite(&short_len, 1, 1, gpoutfile);    /* write true length */
                    538:     else {
                    539:        fwrite(&flag, 1, 1, gpoutfile);
                    540:        CGM_write_int(numbytes);
                    541:     }
                    542:     fwrite(data, 1, numbytes + pad, gpoutfile);                /* write string */
                    543: }
                    544:
                    545: static void CGM_write_int_record(class, cgm_id, numbytes, data)
                    546: int class, cgm_id, numbytes, *data;
                    547: {
                    548:     int i;
                    549:     assert((numbytes & 1) == 0);
                    550:     CGM_write_code(class, cgm_id, numbytes);
                    551:     numbytes >>= 1;
                    552:     for (i = 0; i < numbytes; i++)
                    553:        CGM_write_int(data[i]);
                    554: }
                    555:
                    556: static void CGM_write_mixed_record(class, cgm_id, numint, int_data,
                    557:                                   numchar, char_data)
                    558: int class, cgm_id, numint, *int_data, numchar;
                    559: char *char_data;
                    560: {
                    561:     int i, pad, padded_length;
                    562:     static unsigned char flag = 0xff;
                    563:     char short_len;
                    564:
                    565:     pad = 0;
                    566:     padded_length = numchar + 1;
                    567:     if (numchar >= 255)
                    568:        padded_length += 2;     /* long string */
                    569:     if (padded_length & 1)
                    570:        padded_length += pad = 1;       /* needs pad */
                    571:
                    572:     CGM_write_code(class, cgm_id, numint * 2 + padded_length);
                    573:
                    574:     for (i = 0; i < numint; i++)
                    575:        CGM_write_int(int_data[i]);     /* write integers */
                    576:
                    577:     short_len = numchar;
                    578:     if (numchar < 255)
                    579:        fwrite(&short_len, 1, 1, gpoutfile);    /* write string length */
                    580:     else {
                    581:        fwrite(&flag, 1, 1, gpoutfile);
                    582:        CGM_write_int(numchar);
                    583:     }
                    584:     fwrite(char_data, 1, numchar + pad, gpoutfile);    /* write string */
                    585: }
                    586:
                    587: /*
                    588:    Write the code word that starts a CGM record.
                    589:    bits in code word are as follows...
                    590:    cccciiiiiiilllll
                    591:    where
                    592:    cccc is a 4-bit class number
                    593:    iiiiiii is a 7-bit ID number
                    594:    lllll is a 5-bit length (# bytes following the code word, or
                    595:             31 followed by a word with the actual number)
                    596:    */
                    597: static void CGM_write_code(class, cgm_id, length)
                    598: int class, cgm_id, length;
                    599: {
                    600:     unsigned code;
                    601:
                    602:     assert((0 <= class) &&(class <16));
                    603:     assert((0 <= cgm_id) && (cgm_id < 128));
                    604:     assert(0 <= length);
                    605:     if (length < 31) {
                    606:        code = ((class &0x0f) <<12) |
                    607:            ((cgm_id & 0x7f) << 5) |
                    608:            ((length & 0x1f));
                    609:        CGM_write_int(code);
                    610:     } else {
                    611:        code = ((class &0x0f) <<12) |
                    612:            ((cgm_id & 0x7f) << 5) |
                    613:            0x1f;
                    614:        CGM_write_int(code);
                    615:        CGM_write_int(length);
                    616:     }
                    617: }
                    618:
                    619: static void CGM_write_int(value)
                    620: int value;
                    621: {
                    622:     union {
                    623:        short s;
                    624:        char c[2];
                    625:     } u;
                    626:
                    627: #if !defined(DOS16) && !defined(WIN16)
                    628:     assert(-32768 <= value && value <= 32767);
                    629: #endif
                    630:
                    631:     u.c[0] = (value >> 8) & 255;       /* convert to network order */
                    632:     u.c[1] = value & 255;
                    633:
                    634:     fwrite(&u.s, 1, 2, gpoutfile);
                    635: }
                    636:
                    637:        /* Draw a dashed line to (ux,uy).  CGM has linestyles, but
                    638:           they are not usable -- at least with the Word for Windows
                    639:           6.0 filter, where lines of significant width (even 1 pt)
                    640:           always come out solid.  Therefore, we implement dashed
                    641:           lines here instead.  */
                    642: TERM_PUBLIC void CGM_dashed_vector(ux, uy)
                    643: unsigned int ux, uy;
                    644: {
                    645:     int xa, ya;
                    646:     int dx, dy, adx, ady;
                    647:     int dist;                  /* approximate distance in plot units
                    648:                                   from starting point to specified end
                    649:                                   point. */
                    650:     long remain;               /* approximate distance in plot units
                    651:                                   remaining to specified end point. */
                    652:
                    653:     assert(ux < term->xmax && uy < term->ymax);
                    654:
                    655:     dx = (ux - cgm_posx);
                    656:     dy = (uy - cgm_posy);
                    657:     adx = abs(dx);
                    658:     ady = abs(dy * 10);
                    659:
                    660:     /* using the approximation
                    661:        sqrt(x**2 + y**2)  ~  x + (5*x*x)/(12*y)   when x > y.
                    662:        Note ordering of calculations to avoid overflow on 16 bit
                    663:        architectures */
                    664:     if (10 * adx < ady)
                    665:        dist = (ady / 2 + 25 * adx / ady * adx / 6 * 5) / 5;
                    666:     else {
                    667:        if (adx == 0)
                    668:            return;
                    669:        dist = (adx * 10 + (ady / 24) * (ady / adx)) / 10;
                    670:     }
                    671:     remain = dist;
                    672:     xa = cgm_posx;
                    673:     ya = cgm_posy;
                    674:     while (remain > cgm_step) {
                    675:        remain -= cgm_step;
                    676:        if (cgm_step_index & 1)
                    677:            CGM_solid_vector((int) (ux - (remain * dx) / dist),
                    678:                             (int) (uy - (remain * dy) / dist));
                    679:        else {
                    680:            xa = (int) (ux - (remain * dx) / dist);
                    681:            ya = (int) (uy - (remain * dy) / dist);
                    682:            CGM_move(xa, ya);
                    683:        }
                    684:        if (++cgm_step_index >= 8)
                    685:            cgm_step_index = 0;
                    686:        cgm_step = cgm_step_sizes[cgm_step_index];
                    687:     }
                    688:     if (cgm_step_index & 1)
                    689:        CGM_solid_vector(ux, uy);
                    690:     else
                    691:        CGM_move(ux, uy);
                    692:     cgm_step -= (int) remain;
                    693: }
                    694:
                    695: TERM_PUBLIC void CGM_solid_vector(ux, uy)
                    696: unsigned int ux, uy;
                    697: {
                    698:     assert(ux < term->xmax && uy < term->ymax);
                    699:     if (ux == cgm_posx && uy == cgm_posy)
                    700:        return;
                    701:     if (cgm_coords > CGM_MAX_SEGMENTS - 2) {
                    702:        CGM_flush_polyline();
                    703:        cgm_polyline[cgm_coords++] = cgm_posx;
                    704:        cgm_polyline[cgm_coords++] = cgm_posy + CGM_MARGIN;
                    705:     } else if (cgm_coords == 0) {
                    706:        cgm_polyline[cgm_coords++] = cgm_posx;
                    707:        cgm_polyline[cgm_coords++] = cgm_posy + CGM_MARGIN;
                    708:     }
                    709:     cgm_polyline[cgm_coords++] = ux;
                    710:     cgm_polyline[cgm_coords++] = uy + CGM_MARGIN;
                    711:     cgm_posx = ux;
                    712:     cgm_posy = uy;
                    713: }
                    714:
                    715: TERM_PUBLIC void CGM_put_text(x, y, str)
                    716: unsigned int x, y;
                    717: char str[];
                    718: {
                    719:     static int where[3] = { 0, 0, 1 };
                    720:     int data[4];
                    721:     char *s = str;
                    722:
                    723:     while (*s)
                    724:        if (!isspace((int) *s++))
                    725:            goto showit;
                    726:     return;
                    727:
                    728:   showit:
                    729:     if (cgm_vert_text != cgm_vert_text_requested) {
                    730:        cgm_vert_text = cgm_vert_text_requested;
                    731:        if (cgm_vert_text) {
                    732:            data[0] = -term->v_char;
                    733:            data[1] = data[2] = 0;
                    734:            data[3] = term->v_char;
                    735:        } else {
                    736:            data[1] = data[2] = term->v_char;
                    737:            data[0] = data[3] = 0;
                    738:        }
                    739:        CGM_write_int_record(5, 16, 8, data);
                    740:     }
                    741:     CGM_flush_polyline();
                    742:     where[0] = x;
                    743:     where[1] = y + CGM_MARGIN;
                    744:     CGM_write_mixed_record(4, 4, 3, where, strlen(str), str);
                    745:
                    746:     cgm_posx = cgm_posy = -2000;
                    747: }
                    748:
                    749: TERM_PUBLIC int CGM_text_angle(ang)
                    750: int ang;
                    751: {
                    752:     if (cgm_rotate) {
                    753:        cgm_vert_text_requested = ang;
                    754:        return TRUE;
                    755:     }
                    756:     return ang ? FALSE : TRUE;
                    757: }
                    758:
                    759: TERM_PUBLIC int CGM_justify_text(mode)
                    760: enum JUSTIFY mode;
                    761: {
                    762:     static int data[6] = { 1, 3, 0, 0, 0, 0 };
                    763:
                    764:     switch (mode) {
                    765:     case LEFT:
                    766:        data[0] = 1;
                    767:        break;
                    768:     case CENTRE:
                    769:        data[0] = 2;
                    770:        break;
                    771:     case RIGHT:
                    772:        data[0] = 3;
                    773:        break;
                    774:     default:
                    775:        assert(0);
                    776:     }
                    777:     CGM_write_int_record(5, 18, 12, data);
                    778:     return (TRUE);
                    779: }
                    780:
                    781: TERM_PUBLIC void CGM_reset()
                    782: {
                    783:     cgm_posx = cgm_posy = 0;
                    784: }
                    785:
                    786: TERM_PUBLIC void CGM_point(x, y, number)
                    787: unsigned int x, y;
                    788: int number;
                    789: {
                    790:     int old_dashtype;
                    791:
                    792:     if (number < 0) {          /* draw dot */
                    793:        CGM_move(x, y);
                    794:        CGM_solid_vector(x + 1, y);
                    795:        return;
                    796:     }
                    797:     number %= CGM_POINTS;
                    798:
                    799:     CGM_flush_polyline();
                    800:     old_dashtype = cgm_dashtype;
                    801:     CGM_dashtype(0);
                    802:
                    803:     switch (number) {
                    804:     case 0:                    /* draw diamond */
                    805:        CGM_move(x - cgm_tic, y);
                    806:        CGM_solid_vector(x, y - cgm_tic);
                    807:        CGM_solid_vector(x + cgm_tic, y);
                    808:        CGM_solid_vector(x, y + cgm_tic);
                    809:        CGM_flush_polygon();
                    810:        break;
                    811:     case 1:                    /* draw plus */
                    812:        CGM_move(x - cgm_tic, y);
                    813:        CGM_solid_vector(x + cgm_tic, y);
                    814:        CGM_move(x, y - cgm_tic);
                    815:        CGM_solid_vector(x, y + cgm_tic);
                    816:        break;
                    817:     case 2:                    /* draw box */
                    818:        CGM_move(x - cgm_tic707, y - cgm_tic707);
                    819:        CGM_solid_vector(x + cgm_tic707, y - cgm_tic707);
                    820:        CGM_solid_vector(x + cgm_tic707, y + cgm_tic707);
                    821:        CGM_solid_vector(x - cgm_tic707, y + cgm_tic707);
                    822:        CGM_flush_polygon();
                    823:        break;
                    824:     case 3:                    /* draw X */
                    825:        CGM_move(x - cgm_tic707, y - cgm_tic707);
                    826:        CGM_solid_vector(x + cgm_tic707, y + cgm_tic707);
                    827:        CGM_move(x - cgm_tic707, y + cgm_tic707);
                    828:        CGM_solid_vector(x + cgm_tic707, y - cgm_tic707);
                    829:        break;
                    830:     case 4:                    /* draw triangle (point up) */
                    831:        CGM_move(x, y + cgm_tic1241);
                    832:        CGM_solid_vector(x - cgm_tic1077, y - cgm_tic621);
                    833:        CGM_solid_vector(x + cgm_tic1077, y - cgm_tic621);
                    834:        CGM_flush_polygon();
                    835:        break;
                    836:     case 5:                    /* draw star (asterisk) */
                    837:        CGM_move(x, y - cgm_tic);
                    838:        CGM_solid_vector(x, y + cgm_tic);
                    839:        CGM_move(x + cgm_tic866, y - cgm_tic500);
                    840:        CGM_solid_vector(x - cgm_tic866, y + cgm_tic500);
                    841:        CGM_move(x + cgm_tic866, y + cgm_tic500);
                    842:        CGM_solid_vector(x - cgm_tic866, y - cgm_tic500);
                    843:        break;
                    844:     case 6:                    /* draw triangle (point down) */
                    845:        CGM_move(x, y - cgm_tic1241);
                    846:        CGM_solid_vector(x - cgm_tic1077, y + cgm_tic621);
                    847:        CGM_solid_vector(x + cgm_tic1077, y + cgm_tic621);
                    848:        CGM_flush_polygon();
                    849:        break;
                    850:     case 7:                    /* draw circle (actually, dodecagon)
                    851:                                   (WinWord 6 accepts the CGM "circle"
                    852:                                   element, but the resulting circle
                    853:                                   is not correctly centered!) */
                    854:        CGM_move(x, y - cgm_tic);
                    855:        CGM_solid_vector(x + cgm_tic500, y - cgm_tic866);
                    856:        CGM_solid_vector(x + cgm_tic866, y - cgm_tic500);
                    857:        CGM_solid_vector(x + cgm_tic, y);
                    858:        CGM_solid_vector(x + cgm_tic866, y + cgm_tic500);
                    859:        CGM_solid_vector(x + cgm_tic500, y + cgm_tic866);
                    860:        CGM_solid_vector(x, y + cgm_tic);
                    861:        CGM_solid_vector(x - cgm_tic500, y + cgm_tic866);
                    862:        CGM_solid_vector(x - cgm_tic866, y + cgm_tic500);
                    863:        CGM_solid_vector(x - cgm_tic, y);
                    864:        CGM_solid_vector(x - cgm_tic866, y - cgm_tic500);
                    865:        CGM_solid_vector(x - cgm_tic500, y - cgm_tic866);
                    866:        CGM_flush_polygon();
                    867:        break;
                    868:     }
                    869:     CGM_dashtype(old_dashtype);
                    870: }
                    871:
                    872:
                    873: TERM_PUBLIC void CGM_set_pointsize(size)
                    874: double size;
                    875: {
                    876:     /* Markers were chosen to have approximately equal
                    877:        areas.  Dimensions are as follows, in units of
                    878:        cgm_tic:
                    879:
                    880:        plus, diamond: half height = 1
                    881:
                    882:        square, cross: half height = sqrt(1/2) ~ 12/17
                    883:
                    884:        triangle: half width = sqrt(sqrt(4/3)) ~ 14/13,
                    885:        height = sqrt(3*sqrt(4/3)) ~ 54/29
                    886:
                    887:        star: half height = 1, half width = sqrt(3/4) ~ 13/15
                    888:
                    889:        dodecagon: coordinates of vertices are 0,
                    890:        sin(30) = 1/2, cos(30) = sqrt(3/4) ~ 13/15, or 1
                    891:
                    892:        The fractions are approximates of the equivalent
                    893:        continued fractions. */
                    894:     cgm_tic = (size * term->h_tic / 2);
                    895:     cgm_tic707 = cgm_tic * 12 / 17;
                    896:     cgm_tic866 = cgm_tic * 13 / 15;
                    897:     cgm_tic500 = cgm_tic / 2;
                    898:     cgm_tic1241 = cgm_tic * 36 / 29;
                    899:     cgm_tic1077 = cgm_tic * 14 / 13;
                    900:     cgm_tic621 = cgm_tic * 18 / 29;
                    901: }
                    902:
                    903: static void CGM_flush_polygon()
                    904: {
                    905:     if (cgm_coords == 0)
                    906:        return;
                    907:     CGM_write_int_record(4, 7, cgm_coords * 2, cgm_polyline);
                    908:     cgm_coords = 0;
                    909: }
                    910:
                    911: TERM_PUBLIC void CGM_options()
                    912: {
                    913:     strcpy(cgm_font, "Arial Bold");
                    914:     cgm_fontsize = 10;
                    915:     term->v_char = (unsigned int) (cgm_fontsize * CGM_PT);
                    916:     term->h_char = (unsigned int) (cgm_fontsize * CGM_PT * 5 / 9);
                    917:     cgm_linewidth_pt = 1;
                    918:     cgm_monochrome = FALSE;
                    919:     cgm_plotwidth = 6 * 72;
                    920:     cgm_portrait = FALSE;
                    921:     cgm_rotate = TRUE;
                    922:     cgm_dashed = TRUE;
                    923:     cgm_winword6_mode = FALSE;
                    924:     while (!END_OF_COMMAND) {
                    925:        if (almost_equals(c_token, "p$ortrait")) {
                    926:            cgm_portrait = TRUE;
                    927:            c_token++;
                    928:            continue;
                    929:        }
                    930:        if (almost_equals(c_token, "la$ndscape")) {
                    931:            cgm_portrait = FALSE;
                    932:            c_token++;
                    933:            continue;
                    934:        }
                    935:        if (almost_equals(c_token, "de$fault")) {
                    936:            strcpy(cgm_font, "Arial Bold");
                    937:            cgm_fontsize = 10;
                    938:            term->v_char = (unsigned int) (cgm_fontsize * CGM_PT);
                    939:            term->h_char = (unsigned int) (cgm_fontsize * CGM_PT * 5 / 9);
                    940:            cgm_linewidth_pt = 1;
                    941:            cgm_monochrome = FALSE;
                    942:            cgm_plotwidth = 6 * 72;
                    943:            cgm_portrait = FALSE;
                    944:            cgm_rotate = TRUE;
                    945:            cgm_dashed = TRUE;
                    946:            cgm_winword6_mode = FALSE;
                    947:            c_token++;
                    948:            continue;
                    949:        }
                    950:        if (almost_equals(c_token, "w$inword6")) {
                    951:            cgm_winword6_mode = TRUE;
                    952:            c_token++;
                    953:            continue;
                    954:        }
                    955:        if (almost_equals(c_token, "m$onochrome")) {
                    956:            cgm_monochrome = TRUE;
                    957:            c_token++;
                    958:            continue;
                    959:        }
                    960:        if (almost_equals(c_token, "c$olor")
                    961:            || almost_equals(c_token, "c$olour")) {
                    962:            cgm_monochrome = FALSE;
                    963:            c_token++;
                    964:            continue;
                    965:        }
                    966:        if (almost_equals(c_token, "r$otate")) {
                    967:            cgm_rotate = TRUE;
                    968:            c_token++;
                    969:            continue;
                    970:        }
                    971:        if (almost_equals(c_token, "nor$otate")) {
                    972:            cgm_rotate = FALSE;
                    973:            c_token++;
                    974:            continue;
                    975:        }
                    976:        if (almost_equals(c_token, "da$shed")) {
                    977:            cgm_dashed = TRUE;
                    978:            c_token++;
                    979:            continue;
                    980:        }
                    981:        if (almost_equals(c_token, "s$olid")) {
                    982:            cgm_dashed = FALSE;
                    983:            c_token++;
                    984:            continue;
                    985:        }
                    986:        if (almost_equals(c_token, "li$newidth")) {
                    987:            c_token++;
                    988:            if (!END_OF_COMMAND) {
                    989:                struct value a;
                    990:                cgm_linewidth_pt = (unsigned int) real(const_express(&a));
                    991:                if (cgm_linewidth_pt > 10000) {
                    992:                    fputs("gnuplot(cgm.trm): linewidth out of range\n", stderr);
                    993:                    cgm_linewidth_pt = 1;
                    994:                }
                    995:            }
                    996:            continue;
                    997:        }
                    998:        if (almost_equals(c_token, "wid$th")) {
                    999:            c_token++;
                   1000:            if (!END_OF_COMMAND) {
                   1001:                struct value a;
                   1002:                cgm_plotwidth = (int) real(const_express(&a));
                   1003:                if (cgm_plotwidth < 0 || cgm_plotwidth > 10000) {
                   1004:                    fputs("gnuplot(cgm.trm): width out of range\n", stderr);
                   1005:                    cgm_plotwidth = 6 * 72;
                   1006:                }
                   1007:            }
                   1008:            continue;
                   1009:        }
                   1010:        break;
                   1011:     }
                   1012:
                   1013:     if (!END_OF_COMMAND && isstring(c_token)) {
                   1014:        quote_str(cgm_font, c_token, MAX_ID_LEN);
                   1015:        if (CGM_find_font(cgm_font, strlen(cgm_font)) == 0) {
                   1016:            /* insert the font in the font table */
                   1017:            int n;
                   1018:            n = strlen(cgm_font);
                   1019:            if (n + 1 <= sizeof(cgm_font_data) && n <= 255) {
                   1020:                cgm_font_data[0] = n;
                   1021:                strncpy(cgm_font_data + 1, cgm_font, n);
                   1022:                cgm_font_data[n + 1] = 0;
                   1023:            }
                   1024:        }
                   1025:        c_token++;
                   1026:     }
                   1027:     if (!END_OF_COMMAND) {
                   1028:        /* We have font size specified */
                   1029:        struct value a;
                   1030:        cgm_fontsize = (int) real(const_express(&a));
                   1031:        term->v_char = (unsigned int) (cgm_fontsize * CGM_PT);
                   1032:        term->h_char = (unsigned int) (cgm_fontsize * CGM_PT * 5 / 9);
                   1033:     }
                   1034:     if (cgm_portrait) {
                   1035:        term->xmax = CGM_SMALL - CGM_MARGIN;
                   1036:        term->ymax = CGM_LARGE - CGM_MARGIN;
                   1037:     } else {
                   1038:        term->xmax = CGM_LARGE - CGM_MARGIN;
                   1039:        term->ymax = CGM_SMALL - CGM_MARGIN;
                   1040:     }
                   1041:
                   1042:     sprintf(default_font, "%s,%d", cgm_font, cgm_fontsize);
                   1043:     /* default_font holds the font and size set at 'set term' */
                   1044:     sprintf(term_options, "%s %s %s %s %s width %d linewidth %d \"%s\" %d",
                   1045:            cgm_portrait ? "portrait" : "landscape",
                   1046:            cgm_monochrome ? "monochrome" : "color",
                   1047:            cgm_rotate ? "rotate" : "norotate",
                   1048:            cgm_dashed ? "dashed" : "solid",
                   1049:            cgm_winword6_mode ? "winword6" : "",
                   1050:            cgm_plotwidth,
                   1051:            cgm_linewidth_pt,
                   1052:            cgm_font, cgm_fontsize);
                   1053: }
                   1054:
                   1055: #ifdef DEFEAT_ASSERTIONS
                   1056: #define NDEBUG
                   1057: #include <assert.h>
                   1058: #undef DEFEAT_ASSERTIONS
                   1059: #endif /* DEFEAT_ASSERTIONS */
                   1060:
                   1061: #ifdef NEXT
                   1062: #undef id
                   1063: #undef datum
                   1064: #endif
                   1065:
                   1066: #endif /* TERM_BODY */
                   1067:
                   1068: #ifdef TERM_TABLE
                   1069: TERM_TABLE_START(cgm_driver)
                   1070:     "cgm", "Computer Graphics Metafile",
                   1071:     CGM_LARGE - CGM_MARGIN, CGM_SMALL - CGM_MARGIN, CGM_VCHAR, CGM_HCHAR,
                   1072:     CGM_VTIC, CGM_HTIC, CGM_options, CGM_init, CGM_reset,
                   1073:     CGM_text, null_scale, CGM_graphics, CGM_move, CGM_solid_vector,
                   1074:     CGM_linetype, CGM_put_text, CGM_text_angle,
                   1075:     CGM_justify_text, CGM_point, do_arrow, CGM_set_font,
                   1076:     CGM_set_pointsize,
                   1077:     TERM_BINARY,               /* various flags */
                   1078:     NULL,                      /* after one plot of multiplot */
                   1079:     NULL,                      /* before subsequent plot of multiplot */
                   1080:     NULL,                      /* clear part of multiplot */
                   1081:     CGM_linewidth
                   1082: TERM_TABLE_END(cgm_driver)
                   1083:
                   1084: #undef LAST_TERM
                   1085: #define LAST_TERM cgm_driver
                   1086:
                   1087: #endif /* TERM_TABLE */
                   1088: #endif /* TERM_PROTO_ONLY */
                   1089:
                   1090: #ifdef TERM_HELP
                   1091: START_HELP(cgm)
                   1092: "1 cgm",
                   1093: "?commands set terminal cgm",
                   1094: "?set terminal cgm",
                   1095: "?set term cgm",
                   1096: "?terminal cgm",
                   1097: "?term cgm",
                   1098: "?cgm",
                   1099: " The `cgm` terminal generates a Computer Graphics Metafile.  This file format",
                   1100: " is a subset of the ANSI X3.122-1986 standard entitled \"Computer Graphics -",
                   1101: " Metafile for the Storage and Transfer of Picture Description Information\".",
                   1102: " Several options may be set in `cgm`.",
                   1103: "",
                   1104: " Syntax:",
                   1105: "       set terminal cgm {<mode>} {<color>} {<rotation>} {solid | dashed}",
                   1106: "                        {width <plot_width>} {linewidth <line_width>}",
                   1107: "                        {\"<font>\"} {<fontsize>}",
                   1108: "",
                   1109: " where <mode> is `landscape`, `portrait`, or `default`;",
                   1110: " <color> is either `color` or `monochrome`; ",
                   1111: " <rotation> is either `rotate` or `norotate`;",
                   1112: " `solid` draws all curves with solid lines, overriding any dashed patterns;",
                   1113: " <plot_width> is the width of the page in points; ",
                   1114: " <line_width> is the line width in points; ",
                   1115: " <font> is the name of a font; and ",
                   1116: " `<fontsize>` is the size of the font in points.",
                   1117: "",
                   1118: " By default, `cgm` uses rotated text for the Y axis label.",
                   1119: "",
                   1120: " The first six options can be in any order.  Selecting `default` sets all",
                   1121: " options to their default values.",
                   1122: "",
                   1123: " Examples:",
                   1124: "       set terminal cgm landscape color rotate dashed width 432 \\",
                   1125: "                      linewidth 1  'Arial Bold' 12       # defaults",
                   1126: "       set terminal cgm 14 linewidth 2  14  # wider lines & larger font",
                   1127: "       set terminal cgm portrait 'Times Roman Italic' 12",
                   1128: "       set terminal cgm color solid    # no pesky dashes!",
                   1129: "2 font",
                   1130: "?commands set terminal cgm font",
                   1131: "?set terminal cgm font",
                   1132: "?set term cgm font",
                   1133: "?cgm font",
                   1134: " The first part of a Computer Graphics Metafile, the metafile description,",
                   1135: " includes a font table.  In the picture body, a font is designated by an",
                   1136: " index into this table.  By default, this terminal generates a table with",
                   1137: " the following fonts:",
                   1138: "@start table - first is interactive cleartext form",
                   1139: "       Arial",
                   1140: "       Arial Italic",
                   1141: "       Arial Bold",
                   1142: "       Arial Bold Italic",
                   1143: "       Times Roman",
                   1144: "       Times Roman Italic",
                   1145: "       Times Roman Bold",
                   1146: "       Times Roman Bold Italic",
                   1147: "       Helvetica",
                   1148: "       Roman",
                   1149: "#\\begin{tabular}{|ccl|} \\hline",
                   1150: "#\\multicolumn{2}{|c|}{CGM fonts}\\\\",
                   1151: "#&Arial&\\\\",
                   1152: "#&Arial Italic&\\\\",
                   1153: "#&Arial Bold&\\\\",
                   1154: "#&Arial Bold Italic&\\\\",
                   1155: "#&Times Roman&\\\\",
                   1156: "#&Times Roman Italic&\\\\",
                   1157: "#&Times Roman Bold&\\\\",
                   1158: "#&Times Roman Bold Italic&\\\\",
                   1159: "#&Helvetica&\\\\",
                   1160: "#&Roman&\\\\",
                   1161: "%c c l .",
                   1162: "%@@CGM fonts",
                   1163: "%_",
                   1164: "%@@Arial",
                   1165: "%@@Arial Italic",
                   1166: "%@@Arial Bold",
                   1167: "%@@Arial Bold Italic",
                   1168: "%@@Times Roman",
                   1169: "%@@Times Roman Italic",
                   1170: "%@@Times Roman Bold",
                   1171: "%@@Times Roman Bold Italic",
                   1172: "%@@Helvetica",
                   1173: "%@@Roman",
                   1174: "@end table",
                   1175: " Case is not distinct, but the modifiers must appear in the above order (that",
                   1176: " is, not 'Arial Italic Bold').  'Arial Bold' is the default font.",
                   1177: "",
                   1178: " You may also specify a font name which does not appear in the default font",
                   1179: " table.  In that case, a new font table is constructed with the specified",
                   1180: " font as its only entry.  You must ensure that the spelling, capitalization,",
                   1181: " and spacing of the name are appropriate for the application that will read",
                   1182: " the CGM file.",
                   1183: "2 fontsize",
                   1184: "?commands set terminal cgm fontsize",
                   1185: "?set terminal cgm fontsize",
                   1186: "?set term cgm fontsize",
                   1187: "?cgm fontsize",
                   1188: " Fonts are scaled assuming the page is 6 inches wide.  If the `size` command",
                   1189: " is used to change the aspect ratio of the page or the CGM file is converted",
                   1190: " to a different width (e.g. it is imported into a document in which the",
                   1191: " margins are not 6 inches apart), the resulting font sizes will be different.",
                   1192: " To change the assumed width, use the `width` option.",
                   1193: "2 linewidth",
                   1194: "?commands set terminal cgm linewidth",
                   1195: "?set terminal cgm linewidth",
                   1196: "?set term cgm linewidth",
                   1197: "?cgm linewidth",
                   1198: " The `linewidth` option sets the width of lines in pt.  The default width is",
                   1199: " 1 pt.  Scaling is affected by the actual width of the page, as discussed",
                   1200: " under the `fontsize` and `width` options",
                   1201: "2 rotate",
                   1202: "?commands set terminal cgm rotate",
                   1203: "?set terminal cgm rotate",
                   1204: "?set term cgm rotate",
                   1205: "?cgm rotate",
                   1206: " The `norotate` option may be used to disable text rotation.  For example,",
                   1207: " the CGM input filter for Word for Windows 6.0c can accept rotated text, but",
                   1208: " the DRAW editor within Word cannot.  If you edit a graph (for example, to",
                   1209: " label a curve), all rotated text is restored to horizontal.  The Y axis",
                   1210: " label will then extend beyond the clip boundary.  With `norotate`, the Y",
                   1211: " axis label starts in a less attractive location, but the page can be edited",
                   1212: " without damage.  The `rotate` option confirms the default behavior.",
                   1213: "2 solid",
                   1214: "?set terminal cgm solid",
                   1215: "?set term cgm solid",
                   1216: "?cgm solid",
                   1217: " The `solid` option may be used to disable dashed line styles in the",
                   1218: " plots.  This is useful when color is enabled and the dashing of the lines",
                   1219: " detracts from the appearance of the plot. The `dashed` option confirms the",
                   1220: " default behavior, which gives a different dash pattern to each curve.",
                   1221: "2 size",
                   1222: "?commands set terminal cgm size",
                   1223: "?set terminal cgm size",
                   1224: "?set term cgm size",
                   1225: "?scgm size",
                   1226: " Default size of a CGM page is 32599 units wide and 23457 units high for",
                   1227: " landscape, or 23457 units wide by 32599 units high for portrait.",
                   1228: "2 width",
                   1229: "?commands set terminal cgm width",
                   1230: "?set terminal cgm width",
                   1231: "?set term cgm width",
                   1232: "?cgm width",
                   1233: " All distances in the CGM file are in abstract units.  The application that",
                   1234: " reads the file determines the size of the final page.  By default, the width",
                   1235: " of the final page is assumed to be 6 inches (15.24 cm).  This distance is",
                   1236: " used to calculate the correct font size, and may be changed with the `width`",
                   1237: " option.  The keyword should be followed by the width in points.  (Here, a",
                   1238: " point is 1/72 inch, as in PostScript.  This unit is known as a \"big point\"",
                   1239: " in TeX.)  `gnuplot` arithmetic can be used to convert from other units, as",
                   1240: " follows:",
                   1241: "       set terminal cgm width 432            # default",
                   1242: "       set terminal cgm width 6*72           # same as above",
                   1243: "       set terminal cgm width 10/2.54*72     # 10 cm wide",
                   1244: "2 winword6",
                   1245: "?commands set terminal cgm winword6",
                   1246: "?set terminal cgm winword6",
                   1247: "?set term cgm winword6",
                   1248: "?cgm winword6",
                   1249: " The default font table was chosen to match, where possible, the default font",
                   1250: " assignments made by the Computer Graphics Metafile input filter for",
                   1251: " Microsoft Word 6.0c, although the filter makes available only 'Arial' and",
                   1252: " 'Times Roman' fonts and their bold and/or italic variants.  Other fonts such",
                   1253: " as 'Helvetica' and 'Roman' are not available.  If the CGM file includes a",
                   1254: " font table, the filter mostly ignores it.  However, it changes certain font",
                   1255: " assignments so that they disagree with the table.  As a workaround, the",
                   1256: " `winword6` option deletes the font table from the CGM file.  In this case,",
                   1257: " the filter makes predictable font assignments.  'Arial Bold' is correctly",
                   1258: " assigned even with the font table present, which is one reason it was chosen",
                   1259: " as the default.",
                   1260: "",
                   1261: " `winword6` disables the color tables for a similar reason---with the color",
                   1262: " table included, Microsoft Word displays black for color 7.",
                   1263: "",
                   1264: " Linewidths and pointsizes may be changed with `set linestyle`."
                   1265: END_HELP(cgm)
                   1266: #endif /* TERM_HELP */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>