[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.2

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

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