[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     ! 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>