Annotation of OpenXM_contrib/gnuplot/term/README, Revision 1.1
1.1 ! maekawa 1: DOCUMENTATION FOR GNUPLOT TERMINAL DRIVER WRITERS
! 2: By Russell Lang 1/90
! 3:
! 4: Updated for new file layout by drd 4/95
! 5:
! 6: Paragraphs about inclusion of TERM_HELP added by rcc 1/96
! 7:
! 8: No change to the interface between gnuplot and the terminal drivers,
! 9: but we would like to make the terminal drivers standalone
! 10:
! 11: 1) in order move the support for the terminal drivers outside of the
! 12: support for the main program, thereby encouraging a library of
! 13: contributed drivers
! 14: 2) To make it easy for users to add contributed drivers, by adding
! 15: a single #include line to term.h
! 16: 3) To allow individual compilation on DOS, to save the overlay
! 17: manager from having to load _all_ drivers together.
! 18:
! 19: CORRECTION - scale() interface is no longer supported, since it
! 20: is incompatible with multiplot.
! 21:
! 22: Whole of terminal driver should be contained in one <driver>.trm file,
! 23: with a fairly strict layout as detailed below - this allows the
! 24: gnuplot maintainers to change the way the terminal drivers are
! 25: compiled without having to change the drivers themselves.
! 26:
! 27: term.h, and therefore each file.trm file, may be loaded more than once,
! 28: with different sections selected by macros.
! 29:
! 30: Each driver provides all the functions it needs, and a table of
! 31: function pointers and other data to interface to gnuplot.
! 32: The table entry is currently defined as follows in plot.h:
! 33:
! 34: struct TERMENTRY {
! 35:
! 36: /* required entries */
! 37:
! 38: char *name;
! 39: char *description;
! 40: unsigned int xmax,ymax,v_char,h_char,v_tic,h_tic;
! 41:
! 42: void (*options) __PROTO((void));
! 43: void (*init) __PROTO((void));
! 44: void (*reset) __PROTO((void));
! 45: void (*text) __PROTO((void));
! 46: int (*scale) __PROTO((double, double));
! 47: void (*graphics) __PROTO((void));
! 48: void (*move) __PROTO((unsigned int, unsigned int));
! 49: void (*vector) __PROTO((unsigned int, unsigned int));
! 50: void (*linetype) __PROTO((int));
! 51: void (*put_text) __PROTO((unsigned int, unsigned int,char*));
! 52:
! 53: /* optional entries */
! 54:
! 55: int (*text_angle) __PROTO((int));
! 56: int (*justify_text) __PROTO((enum JUSTIFY));
! 57: void (*point) __PROTO((unsigned int, unsigned int,int));
! 58: void (*arrow) __PROTO((unsigned int, unsigned int, unsigned int,
! 59: unsigned int, int));
! 60: int (*set_font) __PROTO((char *font)); /* "font,size" */
! 61: void (*set_pointsize) __PROTO((double size)); /* notification of set pointsize */
! 62: int flags; /* various flags */
! 63: void (*suspend) __PROTO((void)); /* after one plot of multiplot */
! 64: void (*resume) __PROTO((void)); /* before subsequent plot of multiplot */
! 65: void (*boxfill) __PROTO((int style, unsigned int x1, unsigned int y1, unsigned int width, unsigned int height)); /* clear part of multiplot */
! 66: void (*linewidth) __PROTO((double linewidth));
! 67: void (*pointsize) __PROTO((double pointsize));
! 68: };
! 69:
! 70: One consequence of (1) is that we would like drivers to be backwards
! 71: compatible - drivers in the correct form below should work in future
! 72: versions of gnuplot without change. C compilers guarantee to fill
! 73: unitialised members of a structure to zero, so gnuplot can detect old
! 74: drivers, in which fields have not been initalised, and can point
! 75: new interface entry pointers to dummy functions.
! 76:
! 77: We can add fields to the terminal structure, but only at the end of the list.
! 78: If you design a terminal that cant work without a new interface being defined,
! 79: and consequent changes to the main gnuplot source, please contact
! 80: bug-gnuplot@dartmouth.edu simply to ensure that you have the most
! 81: up to date defn of the terminal structure. Also, please ensure that
! 82: the 'set term' command checks for 0 values in added fields when an
! 83: old driver is selected, and a pointer to a suitable 'cant do' function
! 84: is provided. It is therefore not required (and in fact not possible)
! 85: to add padding fields to the end of all drivers.
! 86:
! 87: Similarly, if you add an optional field to an old driver, take care
! 88: to ensure that all intervening fields are padded with zeros.
! 89:
! 90: Some of the above fields are required - this should not be a problem,
! 91: since they were all required in earlier releases of gnuplot.
! 92: The later fields are interfaces to capabilities that not all devices
! 93: can do, or for which the generic routines provided should be adequate.
! 94: There are several null ('cant do') functions provided by term.c which
! 95: a driver can reference in the table. Similarly, for bitmap devices, there
! 96: are generic routines for lines and text provided by bitmap.c
! 97:
! 98:
! 99:
! 100: Here's a brief description of each variable:
! 101:
! 102: The char *name is a pointer to a string containing the name
! 103: of the terminal. This name is used by the 'set terminal' and
! 104: 'show terminal' commands.
! 105: The name must be unique and must not be confused with an abbreviation
! 106: of another name. For example if the name "postscript" exists, it is not
! 107: possible to have another name "postscript2".
! 108: Keep the name under 15 characters.
! 109:
! 110: The char *description is a pointer to a string containing a
! 111: description of the terminal, which is displayed in response
! 112: to the 'set terminal' command.
! 113: Keep the description under 60 characters.
! 114:
! 115: xmax is the maximum number of points in the x direction.
! 116: The range of points used by gnuplot is 0 to xmax-1.
! 117:
! 118: ymax is the maximum number of points in the y direction.
! 119: The range of points used by gnuplot is 0 to ymax-1.
! 120:
! 121: v_char is the height of characters, in the same units as xmax and ymax.
! 122: The border for labelling at the top and bottom of the plot is
! 123: calculated using v_char.
! 124: v_char is used as the vertical line spacing for characters.
! 125:
! 126: h_char is the width of characters, in the same units as xmax and ymax.
! 127: The border for labelling at the left and right of the plot is
! 128: calculated using h_char, for example.
! 129: If the _justify_text function returns FALSE, h_char is used to justify
! 130: text right or centre. If characters are not fixed width, then the
! 131: _justify_text function must correctly justify the text.
! 132:
! 133: v_tic is the vertical size of tics along the x axis,
! 134: in the same units as ymax.
! 135:
! 136: h_tic is the horizontal size of tics along the y axis,
! 137: in the same units as xmax.
! 138:
! 139: v_tic and h_tic should give tics of the same physical size on the
! 140: output. The ratio of these two quantities is used by gnuplot to set the
! 141: aspect ratio to 1 so that circles appear circular when 'set size square'
! 142: is active.
! 143:
! 144: All the above values need not be static - values can be substituted
! 145: into the table during terminal initialisation, based on options for
! 146: example.
! 147:
! 148:
! 149:
! 150: Here's a brief description of what each term.c function does:
! 151:
! 152: _options() Called when terminal type is selected.
! 153: This procedure should parse options on the command line. A list of the
! 154: currently selected options should be stored in term_options[] in a form
! 155: suitable for use with the set term command. term_options[] is used by
! 156: the save command. Use options_null() if no options are available.
! 157:
! 158: _init() Called once, when the device is first selected. This procedure
! 159: should set up things that only need to be set once, like handshaking and
! 160: character sets etc...
! 161: There is a global variable 'pointsize' which you might want to use here.
! 162: If set pointsize is issued after init has been called, the set_pointsize()
! 163: function is called.
! 164:
! 165: _reset() Called when gnuplot is exited, the output device changed or
! 166: the terminal type changed. This procedure should reset the device,
! 167: possibly flushing a buffer somewhere or generating a form feed.
! 168:
! 169: _scale(xs,ys) Called just before _graphics(). This takes the x and y
! 170: scaling factors as information. If the terminal would like to do its
! 171: own scaling, it returns TRUE. Otherwise, it can ignore the information
! 172: and return FALSE: do_plot will do the scaling for you. null_scale is
! 173: provided to do just this, so most drivers can ignore this function
! 174: entirely. The Latex driver is currently the only one providing its own
! 175: scaling. PLEASE DO NOT USE THIS INTERFACE - IT IS NOT COMPATIBLE WITH
! 176: MULTIPLOT.
! 177:
! 178: _graphics() Called just before a plot is going to be displayed. This
! 179: procedure should set the device into graphics mode. Devices which can't
! 180: be used as terminals (like plotters) will probably be in graphics mode
! 181: always and therefore won't need this.
! 182:
! 183: _text() Called immediately after a plot is displayed. This procedure
! 184: should set the device back into text mode if it is also a terminal, so
! 185: that commands can be seen as they're typed. Again, this will probably
! 186: do nothing if the device can't be used as a terminal. This call can
! 187: be used to trigger conversion and output for bitmap devices.
! 188:
! 189: _move(x,y) Called at the start of a line. The cursor should move to the
! 190: (x,y) position without drawing.
! 191:
! 192: _vector(x,y) Called when a line is to be drawn. This should display a line
! 193: from the last (x,y) position given by _move() or _vector() to this new (x,y)
! 194: position.
! 195:
! 196: _linetype(lt) Called to set the line type before text is displayed or
! 197: line(s) plotted. This procedure should select a pen color or line
! 198: style if the device has these capabilities.
! 199: lt is an integer from -2 to 0 or greater.
! 200: An lt of -2 is used for the border of the plot.
! 201: An lt of -1 is used for the X and Y axes.
! 202: lt 0 and upwards are used for plots 0 and upwards.
! 203: If _linetype() is called with lt greater than the available line types,
! 204: it should map it to one of the available line types.
! 205: Most drivers provide 9 different linetypes (lt is 0 to 8).
! 206:
! 207: _put_text(x,y,str) Called to display text at the (x,y) position,
! 208: while in graphics mode. The text should be vertically (with respect
! 209: to the text) justified about (x,y). The text is rotated according
! 210: to _text_angle and then horizontally (with respect to the text)
! 211: justified according to _justify_text.
! 212:
! 213:
! 214: The following are optional
! 215:
! 216:
! 217: _text_angle(ang) Called to rotate the text angle when placing the y label.
! 218: If ang = 0 then text is horizontal. If ang = 1 then text is vertically
! 219: upwards. Returns TRUE if text can be rotated, FALSE otherwise.
! 220: [But you must return TRUE if called with ang=0]
! 221:
! 222: _justify_text(mode) Called to justify text left, right or centre.
! 223: If mode = LEFT then text placed by _put_text is flushed left against (x,y).
! 224: If mode = CENTRE then centre of text is at (x,y).
! 225: If mode = RIGHT then text is placed flushed right against (x,y).
! 226: Returns TRUE if text can be justified
! 227: Returns FALSE otherwise and then _put_text assumes text is flushed left;
! 228: justification of text is then performed by calculating the text width
! 229: using strlen(text) * h_char.
! 230:
! 231: _point(x,y,point) Called to place a point at position (x,y).
! 232: point is -1 or an integer from 0 upwards.
! 233: At least 6 point types (numbered 0 to 5) are normally provided.
! 234: Point type -1 is a dot.
! 235: If point is more than the available point types then it should
! 236: be mapped back to one of the available points.
! 237: Two _point() functions called do_point() and line_and_point() are
! 238: provided in term.c and should be suitable for most drivers.
! 239: do_point() draws the points in the current line type.
! 240: If your driver uses dotted line types (generally because it is
! 241: monochrome), you should use line_and_point() which changes to
! 242: line type 0 before drawing the point. line type 0 should be solid.
! 243:
! 244: There is a global variable 'pointsize' which is controlled by the
! 245: set pointsize command. If possible, use that. pointsize should be
! 246: examined at terminal init. If it is subsequently changed, the
! 247: set_pointsize() fn will be called.
! 248:
! 249:
! 250: _arrow(sx,sy,ex,ey,head) Called to draw an arrrow from (sx,sy) to (ex,ey).
! 251: A head is drawn on the arrow if head = TRUE.
! 252: An _arrow() function called do_arrow() is provided in term.c which will
! 253: draw arrows using the _move() and _vector() functions.
! 254: Drivers should use do_arrow unless it causes problems.
! 255:
! 256: _set_font() is called to set the font of labels, etc [new 3.7 feature]
! 257: fonts are selected as strings "name,size"
! 258:
! 259: _pointsize() is used to set the pointsize for subsequent points
! 260:
! 261: _flags stores various flags describing driver capabilities. Currently
! 262: three bits are allocated
! 263: - TERM_CAN_MULTIPLOT - driver can do multiplot
! 264: fully-interactively when output is not redirected. ie text and graphics
! 265: go to different places, or driver can flip using suspend.
! 266: - TERM_CANT_MULTIPLOT - driver cannot multiplot, even if output
! 267: is redirected.
! 268: - TERM_BINARY - output file must be opened in binary mode
! 269: Another bit is earmarked for VMS_PASTHRU, but not yet implemented.
! 270:
! 271: _suspend() - called before gnuplot issues a prompt in multiplot mode
! 272: linux vga driver uses this entry point to flip from graphics to
! 273: text mode. X11 driver will take this opportunity to paint the window
! 274: on the display.
! 275:
! 276: _resume() - called after suspend(), before subsequent plots of a multiplot.
! 277:
! 278: _boxfill() - fills a box in given style (currently unimplemented - always
! 279: background colour at present). used by 'clear' in multiplot for
! 280: support of inset graphs
! 281:
! 282: _linewidth() - sets the linewidth
! 283:
! 284: The following should illustrate the order in which calls to these
! 285: routines are made:
! 286:
! 287: _options()
! 288: _init()
! 289: _scale(xs,ys)
! 290: _graphics()
! 291: _linewidth(lw)
! 292: _linetype(lt)
! 293: _move(x,y)
! 294: _vector(x,y)
! 295: _pointsize(size)
! 296: _point(x,y,point)
! 297: _text_angle(angle)
! 298: _justify(mode)
! 299: _set_font(font)
! 300: _put_text(x,y,text)
! 301: _arrow(sx,sy,ex,ey)
! 302: _text()
! 303: _graphics()
! 304: .
! 305: _suspend()
! 306: _set_pointsize()
! 307: _resume()
! 308: .
! 309: _text()
! 310: _reset()
! 311:
! 312:
! 313: ------------------------------------
! 314:
! 315: BITMAP DEVICES
! 316:
! 317: A file bitmap.c is provided, implementing a generic set of bitmap
! 318: routines. It provides all the routines required to generate a
! 319: bitmap in memory, drawing lines and writing text. A simple driver
! 320: need provide only a text() entry point, which converts and outputs
! 321: the stored bitmap in the format required by the device.
! 322:
! 323: Internally, the bitmap is built of one or more planes of 1
! 324: bit per pixel. In fact, I think the library would be easier to
! 325: use if it offered one or more planes of pixels with 1,2,4 or 8
! 326: bits per pixel, since not all bitmap devices are based on planes,
! 327: and the planes have to be recombined at the end at present.
! 328: In general, a device would use either planes or bits-per-pixel,
! 329: though I guess a 24-bit bitmap could use 3 planes of 8 bits
! 330: per pixel..?
! 331:
! 332:
! 333: The pixels are currently organised horizontally packed into bytes.
! 334:
! 335: ie
! 336:
! 337: ********%%%%%%%%$$$$$$$$!!!!!!!! etc
! 338: ^^^^^^^^@@@@@@@@########++++++++ etc
! 339:
! 340: where like symbols are stored in one byte. Vertical packing can be
! 341: arranged by reversing x and y dimensions and setting the global
! 342: b_rastermode to TRUE. (eg epson 8-pin dot-matrix printer)
! 343:
! 344:
! 345: Functions provided are
! 346:
! 347: (internal fns ? - should probably be static, not external ?)
! 348: b_setpixel(x,y,value)
! 349: b_setmaskpixel(x,y,value)
! 350: b_putc(x,y,char,angle)
! 351: b_setvalue(size)
! 352:
! 353: setting up stuff
! 354:
! 355: b_makebitmap(x,y,planes) - make a bitmap of size x * y
! 356: b_freebitmap() - free bitmap
! 357: b_charsize(size)
! 358:
! 359:
! 360: gnuplot driver interface functions (can go straight into gnuplot structure)
! 361:
! 362: b_setlinetype(linetype)
! 363: b_move(x,y)
! 364: b_vector(x,y)
! 365: b_put_text(x,y,*str)
! 366: b_text_angle(ang)
! 367:
! 368:
! 369:
! 370: I think that the library could be made easier to use if we defined
! 371: a structure which described the bitmap (raster mode, planes, bits-per-pixel,
! 372: colours, etc) and then added to the gnuplot term struct a pointer to
! 373: this structure. Then we could have b_graphics() routine which did all
! 374: the initialisation that presently has to be done by the driver graphics()
! 375: entry point. Also, one day I would like to have parsing, including
! 376: terminal driver options, table-driven, but I'm getting ahead of myself
! 377: here.
! 378:
! 379:
! 380: At present, bitmap.c is linked into gnuplot unconditionally. Perhaps
! 381: it should be put into a library, so that it is linked in only if
! 382: any of the user-selected drivers require bitmap support.
! 383:
! 384: There may be scope to do similar things with some of the other
! 385: stuff that is shared by several drivers. Rather than requiring,
! 386: for example, that LATEX driver is required if EMTEX is to be used,
! 387: the shared routines could be extracted to a library and linked
! 388: if any of the drivers which use them are used. Just a thought...
! 389:
! 390: ------------------------------------
! 391:
! 392: FILE LAYOUT
! 393: -----------
! 394:
! 395: I think a file layout like the following will leave most flexibility
! 396: to the gnuplot maintainers. I use REGIS for example.
! 397:
! 398:
! 399: #include "driver.h"
! 400:
! 401:
! 402: #ifdef TERM_REGISTER
! 403: register_term(regis) /* no ; */
! 404: #endif
! 405:
! 406:
! 407: #ifdef TERM_PROTO
! 408: TERM_PUBLIC void REGISinit __PROTO((void));
! 409: TERM_PUBLIC void REGISgraphics __PROTO((void));
! 410: /* etc */
! 411: #define GOT_REGIS_PROTO
! 412: #endif
! 413:
! 414:
! 415: #ifndef TERM_PROTO_ONLY
! 416: #ifdef TERM_BODY
! 417:
! 418: TERM_PUBLIC void REGISinit()
! 419: {
! 420: /* etc */
! 421: }
! 422:
! 423: /* etc */
! 424:
! 425: #endif
! 426:
! 427:
! 428: #ifdef TERM_TABLE
! 429:
! 430: TERM_TABLE_START(regis_driver)
! 431: /* no { */
! 432: "regis", "REGIS graphics language",
! 433: REGISXMAX, /* etc */
! 434: /* no } */
! 435: TERM_TABLE_END(regis_driver)
! 436:
! 437: #undef LAST_TERM
! 438: #define LAST_TERM regis_driver
! 439:
! 440: #endif /* TERM_TABLE */
! 441: #endif /* TERM_PROTO_ONLY */
! 442:
! 443:
! 444:
! 445:
! 446: #ifdef TERM_HELP
! 447: START_HELP(regis)
! 448: "1 regis",
! 449: "?set terminal regis",
! 450: "?regis",
! 451: " The `regis` terminal device generates output in the REGIS graphics language.",
! 452: " It has the option of using 4 (the default) or 16 colors.",
! 453: "",
! 454: " Syntax:",
! 455: " set term regis {4 | 16}"
! 456: END_HELP(regis)
! 457: #endif
! 458:
! 459:
! 460: --------------
! 461:
! 462: The first three lines in the TERM_HELP section must contain the same
! 463: name as that specified by register_term, since this is the name that
! 464: will be entered into the list of available terminals. If more than
! 465: one name is registered, the additional names should have their own
! 466: two "?" lines, but not the "1" line.
! 467:
! 468: Each record is enclosed in double-quotes and (except for the last
! 469: record) followed by a comma. The text is copied as a single string
! 470: into gnuplot.doc, so the syntax must obey the rules of that entity.
! 471: If the text includes double-quotes or backslashes, these must be
! 472: escaped by preceding each occurence with a backslash.
! 473:
! 474: --------------
! 475:
! 476: Rationale:
! 477:
! 478: We may want to compile all drivers into term.c or one driver at a time
! 479: this layout should support both
! 480: TERM_PUBLIC will be static if all modules are in term.c, or blank
! 481: otherwise.
! 482: Please make private support functions static if possible.
! 483:
! 484:
! 485: We may include term.h, and therefore all these files, one or more times.
! 486: If just once (all modules compiled into term.c) putting the four
! 487: parts in this order should make it work.
! 488:
! 489: we may compile the table entries into either an array or a linked list
! 490: This organisation should support both
! 491:
! 492: For separate compilation, we may write a program which
! 493: defines TERM_REGISTER and #include term.h to find out which drivers are
! 494: selected in term.h and thereby generate a makefile.
! 495:
! 496:
! 497:
! 498: For a driver which depends on another (eg enhpost and pslatex on post)
! 499: the driver can do something like
! 500:
! 501: #ifndef GOT_POST_PROTO
! 502: #define TERM_PROTO_ONLY
! 503: #include "post.trm"
! 504: #undef TERM_PROTO_ONLY
! 505: #endif
! 506:
! 507: this is probably needed only in the TERM_TABLE section only, but may
! 508: also be used in the body. The TERM_PROTO_ONLY means that we pick up
! 509: only the protos from post.trm, even if current driver is being compiled
! 510: with TERM_BODY or TERM_TABLE
! 511:
! 512: If we do it the linked-list way, the arg to TERM_TABLE_START will be
! 513: the name of the variable, so any valid, unique name is fine.
! 514: The TERM_TABLE_START macro will do all the work of linking the entries
! 515: together, probably using LAST_TERM
! 516:
! 517: The inclusion of the TERM_HELP section (and removal of terminal documentation
! 518: from the master gnuplot.doc file) means that the online help will include
! 519: discussions of only those terminals available to the user. For generation
! 520: of the printed manual, all can be included.
! 521:
! 522:
! 523: Please make as many things as possible static, but do still try to use unique
! 524: names since all drivers may all be compiled into term.o
! 525:
! 526: The bit in the PROTO section is basically what you would put into a .h
! 527: file if we had them - everything that is needed by the TABLE_ENTRY
! 528: should be defined in this part. In particular, dont forget all the maxes
! 529: and character sizes and things for the table entry.
! 530:
! 531: Dont forget to put TERM_PUBLIC in the defns of the fns as well as the
! 532: prototypes. It will probably always expand to 'static' except for pcs.
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>