1 *******************************************************************************
2 *******************************************************************************
4 This file documents shortly some parts of the gnuplot internals.
8 * OVERVIEW OVER CODE STRUCTURE CHANGES AFTER MERGING THE 'AXES' BRANCH
9 * TECHNICAL DETAILS FOR MOUSE COMMUNICATION
10 * TECHNICAL DETAILS FOR FAST MOUSE ROTATION OF 3D SURFACES
11 * TECHNICAL DETAILS ABOUT PM3D
13 Document version: "$Id: README,v 1.7.2.1 2006/12/10 21:44:12 sfeam Exp $"
16 *******************************************************************************
17 *******************************************************************************
20 OVERVIEW OVER CODE STRUCTURE CHANGES AFTER MERGING THE 'AXES' BRANCH
21 ====================================================================
24 CODE structure changes --- an overview:
25 - this is important info if you want to work on gnuplot or merge in patches,
26 - made against gnuplot versions before 3.8e.
28 As of November 1st, 2000, a large set of reorganizational changes to
29 the gnuplot source code, formerly known as 'the axis branch', were
30 folded into the main source tree. This was tagged as beta version 3.8e
31 of the program. Due to the massive amount of changes, this will likely
32 break most patches built against any previous version of gnuplot. To
33 help others in resolving the conflicts that arise, I've set up this
36 The change that is most likely to break your patches is that many
37 variables formerly in setshow.h were renamed and grouped into an array
38 of structures. All status that is set/saved for each individual axis
39 got moved. A little overview:
41 autoscale_* --> axis_array[].autoscale
42 *format --> [].formatstring
43 format_is_numeric[*] --> [].format_is_numeric
45 base_log_* --> [].base
46 log_base_log_* --> [].log_base
50 min_array[] --> [].min
51 max_array[] --> [].max
52 writeback_min[] --> [].writeback_min
53 writeback_max[] --> [].writeback_max
54 *zeroaxis --> [].zeroaxis
56 rotate_*tics --> [].tic_rotate
57 m*tics --> [].minitics
58 m*tfreq --> [].mtic_freq
60 timefmt --> [].timefmt --- one per axis, now!
61 datatype[] --> [].is_timedata
63 Other, general changes:
65 1) All status variables for features that have an axis name
66 in 'set' are now contained in axis.c, and declared
67 in axis.h. Some internal status variables also were moved there.
68 2) plot.h is no longer the 'master include file'. The big collection of
69 type definitions is now in a new file 'gp_types.h'. Only relatively
70 few sources will now want to #include "plot.h", but most will need
71 "gp_types.h". It's often indirectly pulled in through other headers.
72 3) setshow.h now only declares variables that *do* belong to set.c and
73 show.c. All the global status variables are now kept in their
74 respective implementation modules.
75 4) Global variables are now all declared in the .h file of their 'home'
76 module (i.e. if the definition is in foo.c, the decl is in foo.h).
77 5) Frequently repeated code blocks, like log()/pow() conversion of
78 values for log axes, are now macros in axis.h or functions in
80 6) reset_command() moved from set.c to unset.c
81 7) Many status variables and implementations for graphical plot elements
82 that are not axis-specific (the timestamp, the key, the border, and
83 some others) are now in the new source module 'gadgets.h'.
84 8) there's a header file 'version.h' now for the stuff exported by
86 9) Variables and functions only used by one particular source file
87 have been moved into that and made 'static', to improve mutual
88 isolation of the individual source modules.
89 10) Series of #defines that represent different cases have been turned
90 into enums. This makes for easier debugging, and better compiler
91 warnings if you forget to handle some case.
92 11) Default/initial values of variables to be influenced by 'reset'
93 usually have a #define in the .h that is used for both, to avoid
94 'reset' and the initialization getting out of synch.
95 12) Types not needed outside a certain module are defined in the source,
96 where no other modules sees them, rather than in the header.
97 13) If an int was used as a yes/no flag, only, I made it a TBOOLEAN.
105 now in axis.c/h:(new)
110 types ticmark, ticdef, en_minitics_status, tic_callback, AXIS_DEFAULTS
112 axis_array[] --- what it all started about
114 INIT_AXIS_ARRAY() --- set a field a given initial value, for all axes
115 axisname_tbl[] --- for parsing
116 ticscale, miniticscale, tic_in --- tic-related variables
117 default_axis_ticdef, default_axis_label --- for unset/reset
118 default_axis_zeroaxis, default_grid_lp --- dito
119 DEF_FORMAT, TIMEFMT --- dito
120 grid_selection, grid_lp, mgrid_lp, polar_grid_angle --- 'set grid'
121 tic_start, tic_direction, tic_text, rotate_tics, tic_hjust, ...
122 tic_vjust, tic_mirror --- globals for tic callbacks
123 x_axis, y_axis, z_axis --- 'current' x, y and z axis index
124 X_AXIS, Y_AXIS, Z_AXIS --- quick-access macros axis_array[x_axis] etc.
125 AXIS_MAP, AXIS_MAPBACK --- user <-> term coord mapping
126 map_x, map_y --- their old names
128 AXIS_DO_LOG(), AXIS_UNDO_LOG() --- log() a value for an axis' logbas
129 AXIS_LOG_VALUE(), AXIS_DE_LOG_VALUE() --- same, but test if necessary
130 AXIS_INIT3D, AXIS_INIT2D --- prepare axis for use
131 ... and lots of others --- go read axis.h yourself :-)
134 removed from command.c:
137 replot_disabled, MAX_TOKENS
139 removed from contour.c:
149 (dyn_)contour_levels_list
151 removed from datafile.c:
155 plotted_data_from_stdin
157 renamed: pipe_open -> df_pipe_open
167 types position_type, position, text_label, arrow_def, linestyle_def
168 types en_key_horizontal_position, en_key_sample_positioning, key_type
170 EMPTY_LABELSTRUCT --- for initializing/unset/reset
171 key, key_user_pos, key_vpos, key_hpos, key_just, key_swidth
172 key_vert_factor, key_width_fix, key_reverse, key_title
173 default_keybox_lp, key_box --- status variables of 'set key'
174 xleft, xright, ybot, ytop: the graph boundary
175 xsize, ysize, ysize, aspect_ratio --- 'set size'
176 xoffset, xoffset --- 'set offset'
177 lmargin, bmargin,rmargin,tmargin --- set dito
182 timelabel, timelabel_rotate, timelabel_bottom --- 'set timedate'
185 draw_border, border_lp
186 clip_lines1, clip_lines2, clip_points
187 samples_1, samples_2, SAMPLES
188 ang2rad --- 'set angle'
189 data_style, func_style --- 'set style data/func'
191 draw_clip_line, clip_line, clip_point --- moved from util3d.h
192 clip_put_text, clip_put_text_just --- dito (used for 2D, too)
193 clip_move, clip_vector --- from graph3d.h (also 2D usage)
195 now in time.c/gp_time.h:
204 removed from graph3d.c/h:
208 map3d_xy() --- moved to util3d
209 map3d_z(), dbl_raise() --- unused, anyway
210 draw_bottom_grid() --- renamed, now draw3d_graphbox()
212 map_x3d & friend macros
213 move_pos_x, move_pos_y
214 clip_move(), clip_vector()
216 types t_contour_placement, gnuplot_contours, iso_curve, surface_points
217 xscale3d, yscale3d, zscale3d
230 cntr3d_linespoints() --- new
231 cntr3d_dots() --- new
232 setup_3d_box_corners --- new
233 find_maxl_cntr() --- static, moved from misc.c
234 find_maxl_keys3d() --- static, moved from misc.c
235 right_x, right_y, front_x, front_y --- static, new
237 removed from graphics.c/h:
238 statics tic_start, tic_direction, tic_text, rotate_tics, ...
239 tic_hjust, tic_vjust, tic_mirror, ...
240 ticfmt, timelevel, ticstep --- now function-local
241 min_array, max_array, log_array, base_array, scale[] ...
242 log_base_array --- now in 'axis' structure.
243 x_axis, y_axis --- now in axis.c
244 mant_exp() --- now static in axis.c
245 time_tic_just(), timetic_format(), fixup_range() --- dito
246 set_tic(), setup_tics(), gen_tics() --- dito
247 gprintf() --- now in axis.c (but may not stay there)
248 CheckLog() --- renamed, now in axis.c
249 write_multiline() --- now in term.c
250 xleft, xright, xtop, xbot --- now in gadgets.c
251 dbl_raise() --- unused
254 loff, roff, toff, boff
256 find_maxl_keys() --- static, moved from misc.c
259 removed from hidden3d.h:
260 type vertex --- now in util3d.h
265 removed from misc.c/h:
266 static find_maxl_cntr(), find_maxl_keys3d() --- now in graph3d
267 static find_maxl_keys() --- now in graphics
268 cp_alloc(), cp_extend(), cp_free() --- now in plot2d
269 sp_alloc(), sp_extend(), sp_free() --- now in plot3d
270 gp_strcspn --- now in stdfn
272 get_style() --- from set.c
273 lp_use_properties() --- from set.c
274 lp_parse --- from set.c
281 removed from plot.c/h:
282 PROGRAM --- now in show
283 PROMPT --- now in command
284 SAMPLES --- now in gadgets
301 NO_CARET --- now in util.h
303 FIRST_AXES --- now in axis
304 FIRST_Z_AXIS etc. --- now in axis
305 GPHUGE --- now in syscfg
306 HUGE_VAL, VERYLARGE --- dito
308 GPMAX(), GPMIN(), inrange() --- now in stdfn
309 is_comment(), is_system() --- now in syscfg
310 is_jump() --- now in parse
311 ... lots of types --- now in gp_types.h, or gadgets.h
312 type termentry/TERMENTRY --- now in term_api.h
313 ... all declarations of variables from other sources --- now there
315 removed from plot2d.c/h:
316 INIT_ARRAYS(), CHECK_REVERSE(), LOAD_RANGE() --- now in axis
317 STORE_WITH_LOG_AND_FIXUP_RANGE() --- dito
318 FIXUP_RANGE_FOR_LOG() --- dito
319 WRITEBACK(), SAVE_WRITEBACK() --- renamed, now in axis
326 removed from plot3d.c/h:
327 INIT_ARRAYS(), CHECK_REVERSE(), LOAD_RANGE() --- now in axis
328 STORE_WITH_LOG_AND_FIXUP_RANGE() --- dito
329 FIXUP_RANGE_FOR_LOG() --- dito
330 WRITEBACK SAVE_WRITEBACK() --- renamed, now in axis
331 (yes, these were duplicates in plot2d and plot3d...)
338 calculate_set_of_isolines() --- new, isolated from eval_plots()
339 sp_alloc(), sp_extend(), sp_free() --- from misc
343 SAVE_NUM_OR_TIME() --- now in setshow.h
345 removed from set.c/setshow.h:
346 GET_NUM_OR_TIME() --- now in axis
347 reset_command --- now in unset
348 get_writeback_min() and friends --- renamed, now in axis
350 and many globals that are now structure elements in the axis_array[]:
351 autoscale_* --> axis_array[].autoscale
352 *format --> [].formatstring
353 format_is_numeric[*] --> [].format_is_numeric
355 base_log_* --> [].base
356 log_base_log_* --> [].log_base
360 min_array[] --> [].min
361 max_array[] --> [].max
362 writeback_min[] --> [].writeback_min
363 writeback_max[] --> [].writeback_max
364 *zeroaxis --> [].zeroaxis
366 rotate_*tics --> [].tic_rotate
367 m*tics --> [].minitics
368 m*tfreq --> [].mtic_freq
369 *ticdef --> [].ticdef
370 timefmt --> [].timefmt --- one per axis, now!
371 datatype[] --> [].is_timedata
373 all other globals from set.c went to graph2d if they were 2D-releated,
374 graph3d if 3D, gadgets if used by both 2D and 3D.
391 TRUE, FALSE, TBOOLEAN
393 removed from tables.h:
394 set_encoding_tbl, set_encoding_id --- now in term_api.h
396 now in term.c/term_api.h:
401 encoding, encoding_names
402 set_encoding_tbl, set_encoding_id
404 types JUSTIFY, VERT_JUSTIFY, lp_style_type, TERMENTRY/termentry
407 unset_mtics(), unset_tics(), unset_timedata() and others ---
408 replace lots of functions by one, taking an axis_index argument
411 graph_error() --- from graphics
413 removed from util3d.c:
414 clip_point(), draw_clip_line(), clip_put_text(), ...
415 clip_put_text_just(), clip_line() --- caused problems with hidden3d
417 type vertex --- from hidden3d
418 FLAG_VERTEX_AS_UNDEFINED(), VERTEX_IS_UNDEFINED, V_EQUAL --- dito
421 map3d_xy --- from graph3d
422 draw3d_line() --- new
423 draw3d_line_unconditional() --- new
424 draw3d_point() --- new --- these replace the old, removed ones
427 If you've read all through this, you're one determined person ---
430 Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de)
431 Even if all the snow were burnt, ashes would remain.
433 ---------------------------------------------------------------------------
435 2001/07/24: I made a lot of changes in the expression parser /
436 evaluator subsystem. The interface from the expression evaluator to
437 the rest of gnuplot is now through only *one* header file, eval.h. The
438 headers interpol.h, specfun.h and standard.h are now used only for
439 communication to eval.c and its helpers. Other modules should #include
440 only eval.h, or parse.h if they need to handle user input (parse.h
443 I've also renamed all those incomprehendible functions 'aterms()'
444 through 'hterms()' in parser.c, according to the type of expression
445 they actually parse. The expression type names follow those in the C
446 standard grammar. In order of increasing operator precedence:
448 express --> parse_expression
449 xterms --> parse_conditional_expression
450 aterms --> parse_logical_OR_expression
451 bterms --> parse_logical_AND_expression
452 cterms --> parse_inclusive_OR_expression
453 dterms --> parse_exclusive_OR_expression
454 eterms --> parse_AND_expression
455 fterms --> parse_equality_expression
456 gterms --> parse_relational_expression
457 hterms --> parse_additive_expression
458 iterms --> parse_multiplicative_expression
459 unary --> parse_unary_expression
460 factor --> parse_primary_expression
462 Those are the functions that actually parse expressions of a given type
463 based upon lexical symbols found in the input. A second set of functions
464 represent the grammar states:
466 xterm --> accept_logical_OR_expression
467 aterm --> accept_logical_AND_expression
468 bterm --> accept_inclusive_OR_expression
469 cterm --> accept_exclusive_OR_expression
470 dterm --> accept_AND_expression
471 eterm --> accept_equality_expression
472 fterm --> accept_relational_expression
473 gterm --> accept_additive_expression
474 hterm --> accept_multiplicative_expression
478 *******************************************************************************
479 *******************************************************************************
482 TECHNICAL DETAILS FOR HOTKEYS/MOUSE COMMUNICATION
483 =================================================
485 The communication between a mouseable terminal and the main gnuplot core goes
486 via structures defined in mousecmn.h. Further, the following terminal entries
487 are used (see USE_MOUSE #defined code in .trm files):
488 void XX_set_ruler (int, int);
489 void XX_set_cursor (int, int, int);
490 void XX_put_tmptext (int, const char str[]);
491 void XX_set_clipboard (const char[]);
493 On OS/2, the communication of these structures between the stand-alone
494 terminals gnupmdrv.exe or gnuplot_x11.exe and the main gnuplot.exe executable
495 is implemented by shared memory and an event semaphore.
497 On Unix, a bidirectional pipe is implemented for the ipc (inter-process)
498 communication between gnuplot_x11 and gnuplot. The readline interfaces were
499 modified to listen to both stdin and the ipc file descriptor. (Well, that's
500 just the usual way). Note that if compiling with gnu readline, you must have a
501 gnu readline version > 2.2 (3.0). This will not be a major drawback, as 2.2 is
502 out for years now and the current gnu readline version is 4.0.
504 On VGAGL, the communication is done by...?
506 On Windows, the windows terminal is a part of the gnuplot executable
507 wgnuplot.exe. Thus it is possible to call the executing routine do_event(&ge);
508 directly, without any communication at all.
511 History of mouseable terminals:
512 (*) March 1998: Implementation of mousing in OS/2 Presentation Manager terminal
514 (*) April 1999: Proper implementation of the gnupmdrv-gnuplot communication by
515 shared memory and event semaphores (Franz Bakan, Petr Mikulik).
516 (*) October 1999: Mouseable X11 terminal on Unix and OS/2 (Johannes Zellner,
519 The stand-alone terminals gnupmdrv.exe and gnuplot_x11(.exe) had full control
520 over mousing over its displayed graph (all relevant gnuplot structures were
521 passed into the terminal).
523 (*) January 2000: Mousing re-implemented by means of new terminal (.trm)
524 entries, i.e. with a call-back of events passed from the stand-alone terminal
525 to the main gnuplot (Pieter-Tjerk de Boer, Johannes Zellner, Petr Mikulik).
527 (*) January 2000: Implemented mousing in vgagl terminal, the fast linux console
528 terminal (Johannes Zellner).
530 (*) February 2002: Implemented mousing in windows terminal (Petr Mikulik,
531 Hans-Bernhard Broeker).
534 *******************************************************************************
535 *******************************************************************************
538 TECHNICAL DETAILS FOR FAST MOUSE ROTATION OF 3D SURFACES
539 ========================================================
541 For splots (3d) the data of all surfaces of the current graph are cached and
542 can therefore be redrawn very quickly, without rereading and reparsing the
543 input files. This enables smooth rotating and zooming of splots. Note that
544 gnuplot frees the allocated data of the current graph when it starts to plot a
548 *******************************************************************************
549 *******************************************************************************
552 TECHNICAL DETAILS ABOUT PM3D
553 ============================
555 The pm3d splot mode for gray and colour maps and surface (and much later for
556 much more: splots with color lines, plots with filled curves) has been
557 implemented by Petr Mikulik in December 1998 and January 1999. It was released
558 for public on 14. 3. 1999 as a patch for gnuplot 3.7. Below you can find the
559 original notes about the implementation, slightly modified in February 2002.
562 The pm3d algorithm: History and description
563 -------------------------------------------
565 The gnuplot pm3d splot mode is a successor to my pm3d algorithm coded
566 previously in my Turbo Vision Pascal plotting program "pmgraf" for DOS (April
567 1994) and the C++ command line "pm3d" program which is converting the input
568 data into postscript maps (March 1995). Both programs are available on my
571 The pm3d algorithm (in pmgraf, pm3d and now in gnuplot) draws a gray or colour
572 map (or surface, in gnuplot only) of a 3D data, which are supposed to be a
573 sequence of scans. Scan is the same what is called 'iso_curve' in gnuplot.
575 For the given surface, the algorithm takes one scan after the other scan until
576 the last but one. For a scan number K it looks at the subsequent scan K+1. For
577 each (but the last one) point on scan K, it makes a quadrangle with 4 corners:
578 two subsequent points at scan K and two points at scan K+1. (The quadrangle is
579 a rectangle if the data are matrix-like.) The quadrangle is filled by the
580 colour corresponding to the averaged Z coordinate of its 4 corners.
582 Therefore it can plot matricial as well as non-rectangular non-gridded data
583 without any preprocessing, and on single pass through the data. It does not
584 require that the scans have the same number of points (see the details on
585 flushing below or 'set pm3d flush').
588 pm3d implementation in gnuplot
589 ------------------------------
591 Below, you find the basic description of gnuplot implementation of pm3d, colour
592 palette and filled colour polygons.
594 The pm3d implementation in gnuplot is is based on the following terminal
595 entries (see below for more details):
597 term->previous_palette
601 The topmost implementation of colour filled areas in plot3d.c:
603 (*) pm3d mode is set on if (pm3d.where[0]). Its setting, or using 'with ...
604 palette', requests the palette of continuous (smooth) colours for the given
605 terminal according to 'set palette' setup. The palette is created by a call to
606 make_palette(). The routine make_palette() is coded in pm3d.c. It will be
609 (*) pm3d plot for a given surface is called from graph3d.c, just before the
610 stuff for hidden line removal, i.e. before plotting surfaces and contours. For
611 each surface, it calls
612 pm3d_plot( this_plot, pm3d.where[i] );
614 (*) The colour box showing the sequence of continuous colours is drawn in routine
615 draw_color_smooth_box(). Postscript output uses the box implementation directly
616 in the postscript language, see below.
618 (*) Routine term->previous_palette() is called after the plot. Currently, it is
619 needed only for printing the string "grestore" into a postscript file.
622 ----- Implementation of pm3d_plot( this_plot, at_which_z ) in pm3d.c -----
624 (*) This plots the map (for at_which_z=PM3D_AT_BASE or PM3D_AT_TOP) or surface
625 (for at_which_z=PM3D_AT_SURFACE) for the given surface (variable this_plot).
627 (*) The implementation of the pm3d algorithm is schematically:
629 for scan J=1 to scans-1 { /* for each scan in the surface */
630 for pt=1 to min( points(J), points(J+1) ) { /* go over min nb of points */
631 pt' = ...; pt'' = ... /* see below */
633 ptJb = point(J,pt'+1)
634 ptJ+1a = point(J+1,pt'')
635 ptJ+1b = point(J+1,pt'')
636 averagedZ = ( z(ptJa) + z(ptJb) + z(ptJ+1a) + z(ptJ+1b) ) / 4
637 set_color( averagedZ normalized to [0;1] )
638 fill_polygon( 4 corners,
639 those 4 points transformed into coordinates of
640 the map or surface on the terminal )
644 If the two subsequent scans have the same number of points, then pt''=pt'=pt.
645 Otherwise, pt''=pt'=pt if 'scans flushed begin', pt'=points(J)-pt and
646 pt''=points(J+1)-pt if 'scans flushed end', and similarly for 'scans center'.
647 And nothing is drawn if there is only one point in the scan.
650 ----- Implementation of make_palette() in pm3d.c -----
652 (*) Look into color.h, structure t_sm_palette: declaration of smooth palette,
653 i.e. palette for smooth colours. It documents how gray [0,1] is mapped into
654 (R,G,B) = ([0,1], [0,1], [0,1]).
656 (*) Ask for the number of colours that are (still) available on the current
658 i = term->make_palette(NULL);
660 Postscript terminal returns 0 since it supports all RGB values (no limit on
661 discrete number of colours). It has its own mapping: transformation of gray
662 [0,1] is coded as postscript functions, and also in order to make the output
663 size of the postscript file as small as possible, i.e. the same as the output
664 from the pm3d program. Further, not 3 values of the RGB triplet but only 1 gray
665 value is written into the postscript file. This is achieved by the analytical
666 functions: pm3dGetColorValue() are coded as postscript functions, see post.trm:
667 PostScriptColorFormulae[] used in PS_make_palette entry. PS->make_palette()
668 looks itself into sm_palette and writes a header with the appropriate
669 postscript codes for formulaR, formulaG, formulaB transformations. See also
670 post.trm: PostScriptColorFormulae[] used in PS_make_palette. Return from
673 All other terminals have discrete number of colours. Currently an RGB palette
674 is allocated for the number of available colours returned by make_palette(); if
675 pm3d is used in gnuplot's multiplot mode, then the result would be incorrect if
676 the previous palette is not reused or if the number of colours is not limited
677 by 'set palette maxcolors'.
679 Creating the RGB palette: make the array of (RGB) triplets according to items in
680 sm_palette (not for postscript)
681 sm_palette.color = malloc( sm_palette.colors * sizeof(rgb_color) );
684 for (i = 0; i < sm_palette.colors; i++) {
685 gray = (double)i / (sm_palette.colors - 1); /* rescale to [0;1] */
686 if (sm_palette.ColorMode == colorModeGRAY) /* gray scale only */
687 sm_palette.color[i].r = sm_palette.color[i].g = sm_palette.color[i].b
689 else { /* i.e. sm_palette.ColorMode == colorModeRGB */
690 sm_palette.color[i].r = pm3dGetColorValue(sm_palette.formulaR, gray);
691 sm_palette.color[i].g = pm3dGetColorValue(sm_palette.formulaG, gray);
692 sm_palette.color[i].b = pm3dGetColorValue(sm_palette.formulaB, gray);
696 Finally, tell the terminal to allocate the palette for the (RGB) triplets
697 (again, not for postscript)
698 term->make_palette(&sm_palette);
701 ----- Transformation of the z-coordinate to gray and RGB in pm3c.c -----
703 How a colour is transformed from the gray? AveragedZ is mapped into the
704 interval [min_z:max_z] which is transformed into [0:1], see routine
705 double z2gray ( double z )
706 which rescales z into the interval [0,1]. This works fine also for the
707 logarithmic z axis. Later, this is used by
708 gray = z2gray ( avgZ );
709 This value can be used directly as a gray for gray maps. For colour maps
710 it further needs to transform
711 gray -> (R,G,B): [0:1] -> ([0:1], [0:1], [0:1])
712 thus some nice three functions have to be choosen --- see pm3d.c, function
713 pm3dGetColorValue(), for the available mapping functions.
715 Note that after the complete separation of the z and cb axes (cb-axis is the
716 axis of colors) in February 2002, there is a new function z2cb(), and z2gray()
717 was replaced by cb2gray().
720 ----- Implementation of pm3d terminal entries in *.trm -----
722 In this section you will find a brief discussion on the following pm3d-related
725 term->previous_palette
728 which are required to make pm3d to work. Files considered by these functions
729 are color.h, color.c, plot.h, and all .trm which are pm3d-capable. If you are
730 coding pm3d support for a new terminal, then you can have a look at the code
732 gif.trm (bitmap GIF terminal implementation),
733 post.trm (PostScript terminal implementation),
734 pm.trm + gclient.c (OS/2 PM terminal implementation),
735 x11.trm + gplt_x11.c (X11 terminal implementation).
737 The pm3d-specific code is surrounded by #ifdef PM3D ... #endif, so it is
738 possible to compile gnuplot with or without pm3d support just bey (un)defining
741 In plot.h, the following new terminal entries are added into struct TERMENTRY:
743 int (*make_palette) __PROTO((t_sm_palette *palette));
744 1. If palette==NULL, then return nice/suitable maximal number of colours
745 supported by this terminal. Returns 0 if it can make colours without
746 palette (like postscript).
747 2. If palette!=NULL, then allocate its own palette return value is
749 3. Available: some negative values of max_colors for whatever it can be
752 Some particular notes:
753 (*) Terminals with palette (GIF, PM): there are already some basic colours
754 allocated (see gnuplot command 'test'), thus an offset for the `part with
755 smooth colours' is needed.
756 (*) GIF: can allocate up to 256 colours, i.e. discrete number of colours.
757 (*) PM: discrete number of colours. Passes the rgbTable through the pipe
758 into standalone gnupmdrv driver. X11 should be implemented in the same
760 (*) PostScript: continuous colours, as "setrgbcolor" PS command takes the
761 triplet of intervals [0,1].
763 void (*previous_palette) __PROTO((void));
764 Release the palette that the above routine allocated and get back the
765 palette that was active before. Some terminals, like displays, may draw
766 parts of the figure using their own palette. The terminals possessing only
767 one palette for the whole plot don't need this routine.
769 Actually, this routine is currently used only for postscript terminal,
770 where it writes "grestore" as make_palette() starts its postscript
771 definitions by "gsave"... that's because there are the analytical mapping
772 functions gray->RGB defined in the local header.
774 void (*set_color) __PROTO((double gray));
775 The value of gray is [0;1]. The terminal uses its color palette or any
776 other way to transform in into true gray or to r,g,b. This terminal entry
777 remembers (or not) this colour so that it can reuse it for a subsequent
778 drawing (for each terminal separately).
780 void (*filled_polygon) __PROTO((int points, gpiPoint *corners));
781 The declaration has been made the same as in GIF's gd.h. It fills the given
782 polygon according to color set by the previous call to set_color().
785 *******************************************************************************
786 *******************************************************************************
788 TECHNICAL DETAILS ABOUT PLOT WITH IMAGE
789 =======================================
791 The plot_image() routine in graphics.c was added by Daniel Sebald on October
792 30, 2003. It is intended for plotting images if the terminal driver supports
793 images, otherwise it reverts to pm3d color boxes if possible. A large part of
794 the routine checks that the visible points form a valid rectangular grid.
795 Because the data is in the form of 2D/3D point structures, this must be done.
796 (A future feature might be the ability to circumvent the large storage
797 requirements of 2D/3D point structures and the need to check whether data
798 forms a grid whenever the user supplies image data in a known matrix format.)
800 If a grid aligned with the Cartesian axes is not given, plot_image() will
801 revert to plotting color boxes using Petr Mikulik's pm3d features, provided
802 the user has selected palette image, as opposed to RGB image.
804 Only details about the "tricky" algorithms are given here.
806 There are eight valid ways that pixel grid information can be entered via the
807 plot->points[] array. These are based upon the scanning direction (i.e., along
808 one of the dimensions) and the two directions (positive vs. negative) along
809 the dimensions that the points are entered.
813 K = input scan line length (i.e., number of samples along line)
814 L = input plane length (i.e., number of scan lines)
815 dim = dimension (0 means increments along x, 1 means increments along y)
816 dxg0 = delta x grid along the scan line (can be positive or negative)
817 dyg0 = delta y grid along the scan line (can be positive or negative)
818 dxg1 = delta x grid between scan lines (can be positive or negative)
819 dyg1 = delta y grid between scan lines (can be positive or negative)
820 sgn() = sign of variable (- represented as 0, + represented as 1)
821 a^b = raise a to the power b
822 M = output row length (i.e., number of columns)
823 N = output column length (i.e., number of rows)
825 The goal is to move the data from the plot->points[] array to the matrix pixel
826 grid in the order (1,1), (1,2), (1,3), ..., (M,N-1), (M,N) forming the M x N
835 (Note that the terminal scale, positive or negative, has an influence on the
836 orientation of pixels. Ignore this temporarily for simplicity. Formulas are
837 augmented later to account for axes directions.) The approach is to step
838 through the plot points and copy each visible point to its appropriate spot in
839 the image matrix array. The routine that does this is fundamentally
841 for (i=0, j=line_length, i_image=i_start; i < plot->p_count; i++) {
842 image[i_image] = plot->points[i].CRD_COLOR;
843 i_image += i_delta_pixel;
846 i_image += i_delta_line;
851 Thus the indexing parameters i_start, line_length, i_delta_pixel and
852 i_delta_line must be determined. line_length is solely dependent upon the
853 dimension; K if dimension = 0 (i.e., increment along a row) and L if
854 dimension = 1 (i.e., along column). The other relationships can be determined
855 by looking at the eight 4 x 2 illustrations which follow. Assume points are
856 entered 0, 1, 2, 3, 4, 5, 6, 7, then the various ways of entry are:
858 (1) (2) (3) (4) (5) (6) (7) (8)
860 3 2 1 0 7 6 5 4 0 1 2 3 4 5 6 7 6 4 2 0 7 5 3 1 0 2 4 6 1 3 5 7
861 7 6 5 4 3 2 1 0 4 5 6 7 0 1 2 3 7 5 3 1 6 4 2 0 1 3 5 7 0 2 4 6
867 sgn(dyg0)-- | | i_delta_pixel
869 | | | | i_start | | | i_delta_line
870 --- --- --- --- | -------------------- | ------- | ---------------
871 (1) - 0 0 - | K - 1 = K*1 - 1 | -1 | 2*K = K + K
872 (2) - 0 0 + | K*L - 1 = K*L - 1 | -1 | 0 = K - K
873 (3) + 0 0 - | 0 = K*1 - K | 1 | 0 = -K + K
874 (4) + 0 0 + | K*(L-1) = K*L - K | 1 | -2*K = -K - K
876 (5) 0 - - 0 | (L-1)*K = K*L - K | -K | K*L + 1
877 (6) 0 + - 0 | K*L - 1 = K*L - 1 | -K | K*L - 1
878 (7) 0 - + 0 | 0 = K*1 - K | K | -K*L + 1
879 (8) 0 + + 0 | K - 1 = K*1 - 1 | K | -K*L - 1
883 There is a clear distinction between formulas based upon dimension.
887 dimension = 0 (x changing)
888 -------------------------------------------------------
891 i_start: L^(dyg1 > 0) * K - K^(dxg0 > 0)
893 i_delta_pixel: (-1)^(dxg0 < 0)
895 i_delta_line: K*[(-1)^(dxg0 > 0) + (-1)^(dyg1 > 0)]
896 -------------------------------------------------------
900 dimension = 1 (y changing)
901 -------------------------------------------------------
904 i_start: L^(dxg1 < 0) * K - K^(dyg0 < 0)
906 i_delta_pixel: K*(-1)^(dxg1 < 0)
908 i_delta_line: K*L*(-1)^(dxg1 > 0) + (-1)^(dyg0 > 0)
909 -------------------------------------------------------
912 The above formulas are what appear preceding the for() loop in the actual code
913 except for one detail, the terminal scale, i.e., direction for which the axes
914 are increasing. Simply note that if terminal scale is negative the orientation
915 swaps along the related direction. Thus augmenting the sign tests in the above
916 equations will account for the terminal scale. For example, let xsts and ysts
917 be the sign of the x and y terminal scale, respectively. Then the formula for
918 i_start when x is changing (dimension 0) becomes:
920 i_start: L^(dyg1*ysts > 0) * K - K^(dxg0*xsts > 0)
925 /***** NOTE: Info between starred comments was original method and now a
926 simple, but less efficient, method of finding the corners by
927 conditional tests while rearranging the points is done. So
928 the following is obsolete... but may come back to it at some
929 point. But if this has been sitting around for quite a while
930 now, feel free to delete what is between the stars.
932 There is also the matter of computing what points in the array of plot->point[]
933 constitute pixels (1,1) and (N,M). There are four grid corners determined on
934 the first pass through the data. However, what these map to also depend upon
935 the three variables dim, d_x_g and d_y_g. Again, looking at the illustrations:
937 dim sgn(d_x_g) sgn(d_y_g) | pixel_1_1 | pixel_M_N
938 --- ---------- ---------- | --------- | ---------
949 These functions are implemented by table look up. With
951 int pixel_1_1_logic[2][2][2] = {1, 3, 0, 2, 2, 3, 0, 1};
952 int pixel_M_N_logic[2][2][2] = {2, 0, 3, 1, 1, 0, 3, 2};
954 The following yields the desired functions:
957 grid_corner[ pixel_1_1_logic[dimension][delta_x_grid > 0][delta_y_grid > 0] ];
959 grid_corner[ pixel_M_N_logic[dimension][delta_x_grid > 0][delta_y_grid > 0] ];
964 TECHNICAL DETAILS ABOUT TERMINAL DRIVER FUNCTION image
965 ======================================================
967 Support for images in the X11 driver was added by Daniel Sebald on February
968 27, 2003. The function
970 void (*image) __PROTO((unsigned M, unsigned N, coordval *image,
971 gpiPoint *corner, int color_mode));
973 is the terminal driver routine for displaying an image. 'M' is the number of
974 rows, 'N' is the number of columns, 'image' is a pointer to image data stored
975 with upper left pixel first and scanning horizontally from left to right,
978 corner[0].x upper left pixel (1,1) location (extent) of image
980 corner[1].x lower right pixel (M,N) location (extent) of image
982 corner[2].x upper left corner of visible window
984 corner[3].x lower right corner of visible window
987 and 'color_mode' indicates if the image should use RGB triples or palette
990 Image samples are a coordval which is a float. Image data attempts to be
991 consistent with the color schemes of Petr Mikulik's pm3d. Therefore, the
992 values in the image array are in the range [0.0,1.0] and the terminal driver
993 routine can handle this data by mapping this range to a range appropriate for
996 If `color_mode` is IC_RGB, the `image` array should be treated as triples of
997 floats. That is, rather than the length of the image array being M*N, as is
998 the case when `color_mode` is IC_PALETTE, the length of the array is 3*M*N.
999 Triples are of the form
1002 image[1] = green 1,1
1005 image[4] = green 1,2
1009 When in IC_PALETTE mode, image data should be used as an index into the
1010 palette constructed by the make_palette() terminal routine. That is, one
1011 should multiply the value by the palette size minus one, cast to an integer
1012 and range check (good practice) the index.
1014 The meaning of the corners is that the first two represent the outer extent of
1015 the pixels representing the image; not the centers of the pixels on the outer
1016 edge, but the outer edge of the pixels on the outer edge. The next two corners
1017 represent the extent of the visual, or clipping region. Thus, on the outer
1018 edge of the image may be pixels which are only fractionally displayed.
1021 TECHNICAL DETAILS ABOUT X11 IMAGE DRIVER
1022 ========================================
1024 Support for images in the X11 driver was added by Daniel Sebald on February
1027 For X11, this image terminal function is X11_image(). Because of the large
1028 amount of data associated with an image, the routine avoids using floats and
1029 avoids using formatted I/O representation for numbers. The "scanf" function
1030 is a very inefficient routine for large amounts of data.
1032 To avoid using floats, the maximum resolution of the color plane of the X11
1033 device is assumed to be 16 bits. (Not an unreasonable assumption.) The image
1034 data is converted to short by multiplying by the maximum palette value. On
1035 the gplt_x11.c side of the pipe, these unsigned short values are shifted to
1036 the right to match the size of its palette.
1038 To avoid using formatted I/O. A simple encoding scheme is used to eliminate
1039 all image data values having a value equivalent to a '\n' character or a '\0'
1040 character because the core gplt_x11.c routine interprets these characters in
1041 a special way. The scheme is as follows: if the character '\n' or '\0' are
1042 found, they are replaced by a two byte representation (CODE_WORD,value+1).
1043 On the receiving side, if the CODE_WORD is found, the next byte after it minus
1044 one is the decoded character. Naturally, the CODE_WORD itself must also be
1045 encoded so as to not lose those in the data stream.
1047 An additional step is to first translate the data before sending it over the
1048 pipe. This is done by subtracting a constant. The constant is added back
1049 in on the other side. The reason for this is that image data often contains
1050 many 0 characters (e.g., upper 8 bits). Thus the character '\0' is prevalent
1051 in image data, and without translation, the encoding scheme would result in
1052 noticable expansion of the data stream. The encoding is meant to cut down the
1053 amount of data that is stored in the gplt_x11.c replot buffers.
1055 Because there may be an endianess problem if the gnuplot and gnuplot_x11
1056 programs were compiled under different compilers, Petr and Dan added an endian
1057 check command. If this check finds it is necessary to swap bytes in encoded
1058 binary data coming across the pipe, then gnuplot_x11 will do so for those
1059 commands using encoded binary. In most cases, these programs will have been
1060 compiled with the same compiler so byte swapping will not be done. But it is
1063 The X11 color bit packing is a bit tricky. It attempts to be portable, but I'm
1064 sure there are peculiar hardware formats out there that will not work properly
1065 as it currently exists. (Some additions and tweaking will probably be need,
1066 but without examples of every hardware configuration it is difficult to program
1067 for them.) Basically, shifts and masking for packing the bits from the RGB
1068 data (16 bits per channel) are derived from the masks of the X11 display
1069 information. Also, there is hardware option of byte order: most significant
1070 byte first or least significant byte first. The routine will swap bytes if
1071 necessary. However, if the bytes need to be swapped and the RGB masks are all
1072 8 bits, then the swapping can be done inherently by appropriately altering the
1073 bit shifts. For example, say the masks are R: 0xff0000, G: 0xff00, B: 0xff
1074 and bytes need to be swapped. Rather than using these masks and swapping
1075 bytes, the masks could be changed to R: 0xff00, G: 0xff0000, B: 0xff000000.
1079 The method works rather well, short of a more direct method of storing image
1080 data in gplt_x11.c without having to pull the data out of the replot buffer for
1081 every refresh. The new 2D binary data file entry (well documented in the
1082 gnuplot.doc file) in concert with the image routines was suppose to make Octave
1083 fast at drawing images. However, Octave needs some reworking yet to make this
1084 happen seamlessly. The problem is that Octave does not yet use binary data but
1085 instead uses ASCII data files to get information to Gnuplot. I've attempted to
1086 write data to a file in binary format using Octave's fwrite() routine then use
1087 Octave's graw() routine. This speeds things up somewhat, but I still think
1088 this interface can be improved at a later time.
1091 TECHNICAL DETAILS ABOUT POSTSCRIPT IMAGE DRIVER
1092 ===============================================
1094 The PostScript image driver is rather straightforward. Its main processing
1095 involves encoding the data in ASCII85 format. No compression scheme is used
1096 currently. Run length encoding hardly seems worth the effort because in most
1097 cases the amount of compression won't be too significant, I'm guessing. For
1098 image data, other than the single bit variety such as a facsimile, other forms
1099 of compression are more efficient.
1102 COMMENTS ABOUT BINARY DATA FILE SYNTAX
1103 ======================================
1105 A keyword for binary data indicates which way to scan within the file. The
1106 Cartesian variables x, y, and z are analogous to the cylindrical variables
1107 t (theta), r, and z internally. However, the common math convention for
1108 listing triples in these coordinate systems is (x,y,z) and (r,t,z). It may
1109 be worth switching the role of theta and r inside the program. (If done,
1110 change the `scan` note inside the `binary` documentation.)
1112 *******************************************************************************
1113 *******************************************************************************