From 71922741dffdf34d6230d95be26ffa7e7405d300 Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Mon, 22 Jul 2024 13:53:57 -0700
Subject: [PATCH 01/40] contours: allow contour to follow edge of z-clipped
surface
Since gnuplot 4.0, contour lines were not generated for surface tiles
that were clipped against z because this could result in contour lines
outside the surface tiling. See commmit 6e6c67e9
Now that we can do smooth clipping against z it makes more sense to
generate the full bounding contour line. Maybe the previous treatment
is still a better match for "set pm3d clip1in" or "set pm3d clip4in"
but IMHO those modes are rarely desirable.
The change is visible in demos contours.dem (parametric mode plot
"contour of data grid plotting", not pm3d), vector.demi (no surface),
and contourfill.dem (pm3d).
---
src/contour.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/contour.c b/src/contour.c
index 68740c66b..d68f3b48b 100644
--- a/src/contour.c
+++ b/src/contour.c
@@ -786,12 +786,13 @@ add_edge(
{
edge_struct *pe_temp = NULL;
-#if 1
- if (point0->type == INRANGE && point1->type == INRANGE)
-#else
- if (point0->type != UNDEFINED && point1->type != UNDEFINED)
-#endif
- {
+ /* version 6: now that we can do smooth clipping on z,
+ * outrange points are not such a problem.
+ * Previously the test was
+ * if (point0->type == INRANGE && point1->type == INRANGE)
+ * If necessary, the test could be contingent on (pm3d.clip == PM3D_CLIP_Z)
+ */
+ if (point0->type != UNDEFINED && point1->type != UNDEFINED) {
pe_temp = gp_alloc(sizeof(edge_struct), "contour edge");
pe_temp->poly[0] = NULL; /* clear links */
@@ -807,7 +808,6 @@ add_edge(
(*p_edge) = pe_temp; /* start new list if empty */
}
(*pe_tail) = pe_temp; /* continue to last record. */
-
}
return pe_temp; /* returns NULL, if no edge allocated */
}
From 1ffd58257337fbdfd6d64fa1f7e9c7086fdec5d0 Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Thu, 18 Jul 2024 22:22:54 -0700
Subject: [PATCH 02/40] move action table pointer for "plot with table if
()" to plot header
set table
plot FOO using ... if ()
This feature (marked EXPERIMENTAL) has been using a global action table.
Move this into the plot header for both 2D and 3D in preparation for
extending the "plot .. if" syntax to plot styles other than "with table".
---
src/graph3d.h | 5 +++--
src/graphics.h | 5 +++--
src/plot2d.c | 11 ++++-------
src/plot3d.c | 1 +
src/tabulate.c | 7 +++----
src/tabulate.h | 3 +--
6 files changed, 15 insertions(+), 17 deletions(-)
diff --git a/src/graph3d.h b/src/graph3d.h
index 93faf60cf..c4a7fd837 100644
--- a/src/graph3d.h
+++ b/src/graph3d.h
@@ -104,8 +104,9 @@ typedef struct surface_points {
struct udvt_entry *sample_var; /* used by '+' if plot has private sampling range */
struct udvt_entry *sample_var2; /* used by '++' if plot has private sampling range */
struct udft_entry plot_function; /* action table and dummy variables for function plot */
- enum PLOT_FILTER plot_filter; /* currently only "mask" */
- enum PLOT_SMOOTH plot_smooth; /* smooth lines in 3D */
+ enum PLOT_FILTER plot_filter; /* currently only "mask" */
+ enum PLOT_SMOOTH plot_smooth; /* smooth lines in 3D */
+ struct at_type *if_filter_at; /* plot ... if () */
/* 2D and 3D plot structure fields overlay only to this point */
diff --git a/src/graphics.h b/src/graphics.h
index bb7f637d9..4eacce0a8 100644
--- a/src/graphics.h
+++ b/src/graphics.h
@@ -64,8 +64,9 @@ typedef struct curve_points {
struct udvt_entry *sample_var; /* used by '+' if plot has private sampling range */
struct udvt_entry *sample_var2; /* used by '++'if plot has private sampling range */
struct udft_entry plot_function; /* action table and dummy variables for function plot */
- enum PLOT_FILTER plot_filter; /* which filter was specified? */
- enum PLOT_SMOOTH plot_smooth; /* which "smooth" method to be used? */
+ enum PLOT_FILTER plot_filter; /* which filter was specified? */
+ enum PLOT_SMOOTH plot_smooth; /* which "smooth" method to be used? */
+ struct at_type *if_filter_at; /* plot ... if () */
/* 2D and 3D plot structure fields overlay only to this point */
diff --git a/src/plot2d.c b/src/plot2d.c
index 6eb17a759..9b82315c9 100644
--- a/src/plot2d.c
+++ b/src/plot2d.c
@@ -201,6 +201,7 @@ cp_free(struct curve_points *cp)
free_labels(cp->labels);
cp->labels = NULL;
free_at(cp->plot_function.at);
+ free_at(cp->if_filter_at);
free_watchlist(cp->watchlist);
cp->watchlist = NULL;
@@ -812,7 +813,7 @@ get_data(struct curve_points *current_plot)
/* "plot ... with table" bypasses all the column interpretation */
if (current_plot->plot_style == TABLESTYLE) {
- tabulate_one_line(v, df_strings, j);
+ tabulate_one_line(current_plot, v, df_strings, j);
continue;
}
@@ -2458,10 +2459,6 @@ eval_plots()
this_plot->filledcurves_options = filledcurves_opts_data;
this_plot->marks_options = (struct marks_options) DEFAULT_MARKS_OPTS;
- /* Only relevant to "with table" */
- free_at(table_filter_at);
- table_filter_at = NULL;
-
/* Mechanism for deferred evaluation of plot title */
free_at(df_plot_title_at);
@@ -2806,12 +2803,12 @@ eval_plots()
if (this_plot->plot_style == TABLESTYLE) {
if (equals(c_token,"if")) {
- if (table_filter_at) {
+ if (this_plot->if_filter_at) {
duplication = TRUE;
break;
}
c_token++;
- table_filter_at = perm_at();
+ this_plot->if_filter_at = perm_at();
continue;
}
}
diff --git a/src/plot3d.c b/src/plot3d.c
index c87dbe7d4..1e93a7785 100644
--- a/src/plot3d.c
+++ b/src/plot3d.c
@@ -232,6 +232,7 @@ sp_free(struct surface_points *sp)
}
free_at(sp->plot_function.at);
+ free_at(sp->if_filter_at);
free(sp->zclip);
free(sp);
diff --git a/src/tabulate.c b/src/tabulate.c
index 83470e978..3a3d937a8 100644
--- a/src/tabulate.c
+++ b/src/tabulate.c
@@ -59,7 +59,6 @@ FILE *table_outfile = NULL;
udvt_entry *table_var = NULL;
TBOOLEAN table_mode = FALSE;
char *table_sep = NULL;
-struct at_type *table_filter_at = NULL;
static char *expand_newline(const char *in);
static TBOOLEAN blanks_needed(curve_points *this_plot);
@@ -603,15 +602,15 @@ blanks_needed(curve_points *this_plot)
* Called from plot2d.c (get_data) for "plot with table"
*/
TBOOLEAN
-tabulate_one_line(double v[], struct value str[], int ncols)
+tabulate_one_line(struct curve_points *plot, double v[], struct value str[], int ncols)
{
int col;
FILE *outfile = (table_outfile) ? table_outfile : gpoutfile;
struct value keep;
- if (table_filter_at) {
+ if (plot->if_filter_at) {
evaluate_inside_using = TRUE;
- evaluate_at(table_filter_at, &keep);
+ evaluate_at(plot->if_filter_at, &keep);
evaluate_inside_using = FALSE;
if (undefined || isnan(real(&keep)) || real(&keep) == 0)
return FALSE;
diff --git a/src/tabulate.h b/src/tabulate.h
index 7adfd323d..ecee51bcf 100644
--- a/src/tabulate.h
+++ b/src/tabulate.h
@@ -9,12 +9,11 @@
void print_table(struct curve_points * first_plot, int plot_num);
void print_3dtable(int pcount);
-TBOOLEAN tabulate_one_line(double v[], struct value str[], int ncols);
+TBOOLEAN tabulate_one_line(struct curve_points *plot, double v[], struct value str[], int ncols);
extern FILE *table_outfile;
extern udvt_entry *table_var;
extern TBOOLEAN table_mode;
extern char *table_sep;
-extern struct at_type *table_filter_at;
#endif /* GNUPLOT_TABULATE_H */
From c26256999890fdfcbc2f91431a8117b461802957 Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Fri, 19 Jul 2024 09:20:42 -0700
Subject: [PATCH 03/40] "plot ... if ()"
Move the check for an if condition out of table-specific code into
the main parsing loop for "plot" commands.
The "if" restriction is accepted only for data plots.
Input lines that satisfy the if condition are processed as usual.
Lines that fail are essentially ignored, equivalent to matching
the "set datafile missing" condition".
TODO: It might be useful in some cases to have the rejects treated as NaN/
undefined rather than missing. Perhaps this could be indicated by
the filter expression returning NaN rather than 0 or 1.
It's not obvious how to do this while preserving the actual input
content however.
---
src/plot2d.c | 45 ++++++++++++++++++++++++++++-----------------
src/tabulate.c | 9 ---------
2 files changed, 28 insertions(+), 26 deletions(-)
diff --git a/src/plot2d.c b/src/plot2d.c
index 9b82315c9..1074d20a0 100644
--- a/src/plot2d.c
+++ b/src/plot2d.c
@@ -757,10 +757,6 @@ get_data(struct curve_points *current_plot)
current_plot->points[i].type = UNDEFINED;
i++;
}
- if (current_plot->plot_style == TABLESTYLE) {
- j = df_no_use_specs;
- break;
- }
continue;
case DF_FIRST_BLANK:
@@ -808,7 +804,21 @@ get_data(struct curve_points *current_plot)
break; /* Not continue!! */
}
- /* We now know that j > 0, i.e. there is some data on this input line */
+ /* We now know that j > 0, i.e. there is some data on this input line.
+ * However it is still possible that the user wants to skip this line
+ * because it fails to satisfy the "plot .. if ()" condition.
+ * FIXME: This treats filtered points as if they were missing;
+ * alternatively we could keep them but mark as undefined.
+ */
+ if (current_plot->if_filter_at) {
+ struct value keep;
+ evaluate_inside_using = TRUE;
+ evaluate_at(current_plot->if_filter_at, &keep);
+ evaluate_inside_using = FALSE;
+ if (undefined || isnan(real(&keep)) || real(&keep) == 0)
+ continue;
+ }
+
ngood++;
/* "plot ... with table" bypasses all the column interpretation */
@@ -2801,18 +2811,6 @@ eval_plots()
continue;
}
- if (this_plot->plot_style == TABLESTYLE) {
- if (equals(c_token,"if")) {
- if (this_plot->if_filter_at) {
- duplication = TRUE;
- break;
- }
- c_token++;
- this_plot->if_filter_at = perm_at();
- continue;
- }
- }
-
/* pick up line/point specs and other style-specific keywords
* - point spec allowed if style uses points, ie style&2 != 0
* - keywords for lt and pt are optional
@@ -3019,6 +3017,19 @@ eval_plots()
}
#endif
+ /* EXPERIMENTAL filter plot ... if () */
+ if (equals(c_token,"if")) {
+ if (this_plot->plot_type != DATA)
+ int_error(c_token, "'if' restriction not possible here");
+ if (this_plot->if_filter_at) {
+ duplication = TRUE;
+ break;
+ }
+ c_token++;
+ this_plot->if_filter_at = perm_at();
+ continue;
+ }
+
break; /* unknown option */
} /* while (!END_OF_COMMAND) */
diff --git a/src/tabulate.c b/src/tabulate.c
index 3a3d937a8..c7f01c45a 100644
--- a/src/tabulate.c
+++ b/src/tabulate.c
@@ -606,15 +606,6 @@ tabulate_one_line(struct curve_points *plot, double v[], struct value str[], int
{
int col;
FILE *outfile = (table_outfile) ? table_outfile : gpoutfile;
- struct value keep;
-
- if (plot->if_filter_at) {
- evaluate_inside_using = TRUE;
- evaluate_at(plot->if_filter_at, &keep);
- evaluate_inside_using = FALSE;
- if (undefined || isnan(real(&keep)) || real(&keep) == 0)
- return FALSE;
- }
if (table_var == NULL) {
char sep = (table_sep && *table_sep) ? *table_sep : '\t';
From 06c2af67a23cf63b92f168f799d44c2a04b9ac01 Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Fri, 19 Jul 2024 12:10:46 -0700
Subject: [PATCH 04/40] "splot ... if (type = INRANGE; /* unless we find out different */
- /* EAM Oct 2004 - Substantially rework this section */
- /* now that there are many more plot types. */
+ /* EXPERIMENTAL "splot .. if ()" */
+ if (this_plot->if_filter_at) {
+ struct value keep;
+ evaluate_inside_using = TRUE;
+ evaluate_at(this_plot->if_filter_at, &keep);
+ evaluate_inside_using = FALSE;
+ if (undefined || isnan(real(&keep)) || real(&keep) == 0) {
+ cp->type = UNDEFINED;
+ goto come_here_if_undefined;
+ }
+ }
x = y = z = 0.0;
xtail = ytail = ztail = 0.0;
+ cp->type = INRANGE; /* unless we find out otherwise */
/* The x, y, z coordinates depend on the mapping type */
switch (mapping3d) {
@@ -2180,6 +2189,19 @@ eval_3dplots()
continue;
}
+ /* EXPERIMENTAL filter splot ... if () */
+ if (equals(c_token,"if")) {
+ if (this_plot->plot_type != DATA3D)
+ int_error(c_token, "'if' restriction not possible here");
+ if (this_plot->if_filter_at) {
+ duplication = TRUE;
+ break;
+ }
+ c_token++;
+ this_plot->if_filter_at = perm_at();
+ continue;
+ }
+
break; /* unknown option */
} /* while (!END_OF_COMMAND)*/
From de4dff37dc9a73c433ed6a545b5ac33637ad0de8 Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Fri, 19 Jul 2024 13:27:12 -0700
Subject: [PATCH 05/40] document filter "if ()" for plot and splot
---
docs/gnuplot.doc | 80 +++++++++++++++++++++++++++++++++++-------------
1 file changed, 59 insertions(+), 21 deletions(-)
diff --git a/docs/gnuplot.doc b/docs/gnuplot.doc
index 4776ce89a..b15e25ee4 100644
--- a/docs/gnuplot.doc
+++ b/docs/gnuplot.doc
@@ -540,6 +540,8 @@ D epi_data 1
#b The position of the key box can be manually tweaked by specifying an
## offset to be added to whatever position the program would otherwise use.
## See `set key offset`.
+#b `plot .. if ()` New filter for plot and splot commands to select
+## only those input lines that match a target expression. See `filters if`.
#end
3 Brief summary of features introduced in version 5
@@ -8352,31 +8354,36 @@ Ffigure_zerror
{bins }
{mask}
{volatile} {zsort} {noautoscale}
+ {if ()}
The modifiers `binary`, `index`, `every`, `skip`, `using`, `smooth`, `bins`,
- `mask`, `convexhull`, `concavehull`, and `zsort` are discussed separately.
- In brief
+ `mask`, `convexhull`, `concavehull`, `zsort`, and `if` are discussed
+ separately.
+ In brief:
#start
#b `skip N` tells the program to ignore N lines at the start of the input file
#b `binary` indicates that the file contains binary data rather than text
-#b `index` selects which data sets in a multi-data-set file are to be plotted
+#b `bins` sorts individual input points into equal-sized intervals along x and
+## plots a single accumulated value per interval
#b `every` specifies which points within a single data set are to be plotted
-#b `using` specifies which columns in the file are to be used in which order
+#b `if ()` filters the input data to accept only lines that
+## satisfy a certain condition.
+#b `index` selects which data sets in a multi-data-set file are to be plotted
#b `smooth` performs simple filtering, interpolation, or curve-fitting of the
## data prior to plotting
-#b `convexhull` either alone or in combination with `smooth` replaces the
-## points in the input data set with a new set of points that constitute the
-## vertices of a bounding polygon.
-#b `bins` sorts individual input points into equal-sized intervals along x and
-## plots a single accumulated value per interval
+#b `convexhull` and `concavehull`, either alone or in combination with `smooth`,
+## replaces the points in the input data set with a new set of points that
+## constitute the vertices of a bounding polygon.
#b `mask` filters the data through a previously defined mask to plot only a
## selected subset of pixels in an image or a selected region of a pm3d surface.
+#b `using` specifies which columns in the file are to be used in which order
#b `volatile` indicates that the content of the file may not be available to
## reread later and therefore it should be retained internally for re-use.
+#b `zsort` sorts each block of input data on z
#end
- `splot` has a similar syntax but does not support `bins` and supports only a
- few `smooth` options.
+ `splot` has a similar syntax but supports only some of the filter and smoothing
+ options.
The `noautoscale` keyword means that the points making up this plot will be
ignored when automatically determining axis range limits.
@@ -8583,7 +8590,7 @@ Ffigure_zerror
In general the purpose of a filter is to replace the original full set of
input points with a selected subset of points, possibly modified, regrouped,
or reordered,
- The filters currently supported are `bins`, `convexhull`, `concavehull`,
+ The filters currently supported are `bins`, `convexhull`, `concavehull`, `if`,
`mask`, `sharpen`, and `zsort`.
5 bins
?commands plot datafile filters bins
@@ -8764,6 +8771,41 @@ Ffigure_concave_hull_2
the function with periodic sharp minima that reach y=0.
D sharpen 1
+5 if
+?commands plot datafile filters if
+?plot datafile filters if
+?plot filters if
+?data-file if
+?datafile if
+?filters if
+ plot ... if ()
+ splot ... if ()
+ For each line of input data the expression in the `if` filter is evaluated
+ and the line is accepted only if the resulting value is true (non-zero).
+ Any function or variable that would be valid inside a `using` specifier is
+ also valid in the filter expression, including data columns that are not
+ otherwise used for plotting.
+
+ Data lines for which the expression evaluates to false (zero) are treated
+ as if they were not present in the file (see `missing`). This provides a
+ more readable equivalent to the previously supported method that inserted
+ a logical test inside one of the `using` specifiers.
+
+ Old syntax (still accepted):
+ set datafile missing NaN
+ plot FOO using (strcol(1) eq "ABC" ? $2 : NaN):3 with linespoints
+ plot $DATA using 1:($2 < 999. ? $2 : NaN)
+ New syntax:
+ plot FOO using 2:3 with linespoints if (strcol(1) eq "ABC")
+ plot $DATA using 1:2 if ($2 < 999.)
+ Both the old and new examples select only the lines in input file FOO
+ that have `ABC` in the first column, and only lines in $DATA where the
+ value in column 2 is less than 999.
+
+ This filter is also accepted for splot commands, with the slight difference
+ that when the filter expression returns 0 (false) the point is treated as
+ undefined rather than missing.
+
5 zsort
?commands plot datafile filters zsort
?plot datafile filters zsort
@@ -16357,11 +16399,8 @@ Ffigure_polar_grid
set table "tab.csv" separator comma
plot using 1:2:3:4 with table
- [EXPERIMENTAL] To select only a subset of the data points for tabulation you
- can provide an input filter condition (`if `) at the end of the
- command. Note that the input filter may reference data columns that are not
- part of the output. This feature may change substantially before appearing in
- a released version of gnuplot.
+ To select only a subset of the data points for tabulation you can provide an
+ input filter condition (`if `) as part of the plot command.
plot using 1:2:($4+$5) with table if (strcol(3) eq "Red")
plot using 1:2:($4+$5) with table if (10. < $1 && $1 < 100.)
@@ -18222,11 +18261,10 @@ Ffigure_walls
`Splot`, like `plot`, can display from a file.
Syntax:
- splot '' {binary }
- {{nonuniform|sparse} matrix}
- {index }
- {every }
+ splot '' {binary } {{nonuniform|sparse} matrix}
+ {index } {every }
{using }
+ {smooth
^
Copyright (C) 1986 - 1993, 1998 - 2004 Thomas Williams, Colin Kelley
-^ Copyright (C) 2004 - 2023 various authors
+^ Copyright (C) 2004 - 2024 various authors
^
Mailing list for comments: gnuplot-info@lists.sourceforge.net
^ Gnuplot home page
^ Issue trackers:
@@ -32,7 +32,7 @@ C
?copyright
?license
Copyright (C) 1986 - 1993, 1998, 2004, 2007 Thomas Williams, Colin Kelley
- Copyright (C) 2004-2023 various authors
+ Copyright (C) 2004-2024 various authors
Permission to use, copy, and distribute this software and its
documentation for any purpose with or without fee is hereby granted,
diff --git a/docs/titlepag.tex b/docs/titlepag.tex
index 14d14a096..716501ea8 100644
--- a/docs/titlepag.tex
+++ b/docs/titlepag.tex
@@ -187,7 +187,7 @@
Alex Woo,
Johannes Zellner\\
Copyright {\copyright} 1986 - 1993, 1998, 2004 Thomas Williams, Colin Kelley\\
- Copyright {\copyright} 2004 - 2023 various authors\\
+ Copyright {\copyright} 2004 - 2024 various authors\\
\vspace{2ex}
@@ -199,7 +199,7 @@
\vspace{2ex}
-% March 2023 Version 6.1
+% July 2024 Version 6.1
Version {\gpVersion} (development snapshot)
\end{center}
diff --git a/src/filters.c b/src/filters.c
index abf94fc6d..6794ca448 100644
--- a/src/filters.c
+++ b/src/filters.c
@@ -1,7 +1,7 @@
/* GNUPLOT - filters.c */
/*[
- * Copyright Ethan A Merritt 2013 - 2023
+ * Copyright Ethan A Merritt 2013 - 2024
* All code in this file is dual-licensed.
*
* Gnuplot license:
diff --git a/src/version.c b/src/version.c
index 751602213..41f973511 100644
--- a/src/version.c
+++ b/src/version.c
@@ -41,9 +41,9 @@ const char gnuplot_patchlevel[] = "0";
#ifdef DEVELOPMENT_VERSION
#include "timestamp.h"
#else
-const char gnuplot_date[] = "2023-06-22 ";
+const char gnuplot_date[] = "2024-07-24 ";
#endif
-const char gnuplot_copyright[] = "Copyright (C) 1986-1993, 1998, 2004, 2007-2023";
+const char gnuplot_copyright[] = "Copyright (C) 1986-1993, 1998, 2004, 2007-2024";
const char faq_location[] = FAQ_LOCATION;
From fd2f315220c802fbdbc86dc0296ffb2e0820c48d Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Wed, 24 Jul 2024 17:23:06 -0700
Subject: [PATCH 08/40] x11: handle mousing of logscale axes in inactive plot
window
When mousing an inactive plot window, the axis limits and scaling
are retrieved from a per-plot structure initially sent by x11.trm
and stored by gnuplot_x11. However only the limits and scaling for
the user-visible axis were sent, not the underlying primary axis.
This was a oversight from all the way back to version 5.
In the case of logscale this is easy to fix - we just send the
primary axis info instead and let gnuplot_x11 do the conversion
user_coord = primary_coord ** logbase.
In the case of other nonlinear or linked axes the necessary
"via" and "inv" functions are not available to gnuplot_x11.
For now this results in the coordinate being reported as NaN.
Bug 2723
---
src/gplt_x11.c | 14 ++++--------
term/x11.trm | 58 +++++++++++++++++++++++++++++---------------------
2 files changed, 38 insertions(+), 34 deletions(-)
diff --git a/src/gplt_x11.c b/src/gplt_x11.c
index 6928a0587..64d397726 100644
--- a/src/gplt_x11.c
+++ b/src/gplt_x11.c
@@ -1572,10 +1572,6 @@ record()
do_raise = tmp_do_raise;
if (UNSET != tmp_persist)
persist = tmp_persist;
-/* Version 5 - always enabled
- if (UNSET != tmp_dashed)
- dashedlines = tmp_dashed;
- */
if (UNSET != tmp_ctrlq)
ctrlq = tmp_ctrlq;
if (UNSET != tmp_replot_on_resize)
@@ -5600,12 +5596,6 @@ pr_dashes()
int n, j, l, ok;
char option[20], *v;
-/* Version 5 - always enabled
- if (pr_GetR(db, ".dashed")) {
- dashedlines = (!strncasecmp(value.addr, "on", 2) || !strncasecmp(value.addr, "true", 4));
- }
- */
-
for (n = 0; n < Ndashes; n++) {
strcpy(option, ".");
strcat(option, dash_keys[n]);
@@ -6635,6 +6625,10 @@ mouse_to_axis(int mouse_coord, axis_scale_t *axis)
if (axis->term_scale == 0.0)
return 0.;
+ /* nonlinear axis is flagged by logbase < 0 */
+ if (axis->logbase < 0)
+ return NAN;
+
axis_coord = ((double)(mouse_coord - axis->term_lower)) / axis->term_scale + axis->min;
if (axis->logbase > 0.0)
axis_coord = exp(axis_coord * axis->logbase);
diff --git a/term/x11.trm b/term/x11.trm
index 8029a7f2b..de248fe8b 100644
--- a/term/x11.trm
+++ b/term/x11.trm
@@ -1448,6 +1448,31 @@ X11_graphics()
X11_INVALIDATE_CURRENT_RGB;
}
+/*
+ * Send over a snapshot of the final axis scaling.
+ * Jul 2024: Special case for logscale axes (log_base = axis->log_base)
+ * Special case for other nonlinear axes (log_base = -1)
+ */
+#ifdef USE_MOUSE
+static void X11_send_axis_state(int axis_index)
+{
+ double log_base;
+ struct axis *mousing_axis = &axis_array[axis_index];
+
+ if (mousing_axis->log)
+ log_base = mousing_axis->log_base;
+ else if (nonlinear(mousing_axis))
+ log_base = -1;
+ else
+ log_base = 0;
+ if (mousing_axis->log && mousing_axis->linked_to_primary)
+ mousing_axis = mousing_axis->linked_to_primary;
+ PRINT5("S %2d %16.6g %14d %16.6g %16.6g\n", axis_index,
+ mousing_axis->min, mousing_axis->term_lower,
+ mousing_axis->term_scale, log_base);
+}
+#endif
+
TERM_PUBLIC void
X11_text()
{
@@ -1455,9 +1480,9 @@ X11_text()
return;
#ifdef USE_MOUSE
- /* EAM July 2003: send over a snapshot of the final axis scaling
- * so that subsequent mouse events can be transformed into plot
- * coordinates even though the plot is no longer active.
+ /* Send over a snapshot of the final axis scaling so that subsequent
+ * mouse events can be transformed into plot coordinates even though
+ * the plot is no longer active.
*/
#ifdef PIPE_IPC
if (ipc_back_fd >= 0)
@@ -1467,32 +1492,17 @@ X11_text()
int axis_mask = 0;
AXIS_INDEX i;
- for (i = (AXIS_INDEX)0; i < NUMBER_OF_MAIN_VISIBLE_AXES; i++) {
+ for (i = 0; i < NUMBER_OF_MAIN_VISIBLE_AXES; i++) {
if (axis_array[i].ticmode != NO_TICS)
axis_mask |= (1 << i);
}
PRINT2("S %2d %d\n", -2, ALMOST2D);
PRINT2("S %2d %d\n", -1, axis_mask);
- PRINT5("S %2d %16.6g %14d %16.6g %16.6g\n", FIRST_X_AXIS,
- axis_array[FIRST_X_AXIS].min,
- axis_array[FIRST_X_AXIS].term_lower,
- axis_array[FIRST_X_AXIS].term_scale,
- axis_array[FIRST_X_AXIS].log ? axis_array[FIRST_X_AXIS].log_base : 0);
- PRINT5("S %2d %16.6g %14d %16.6g %16.6g\n", FIRST_Y_AXIS,
- axis_array[FIRST_Y_AXIS].min,
- axis_array[FIRST_Y_AXIS].term_lower,
- axis_array[FIRST_Y_AXIS].term_scale,
- axis_array[FIRST_Y_AXIS].log ? axis_array[FIRST_Y_AXIS].log_base : 0);
- PRINT5("S %2d %16.6g %14d %16.6g %16.6g\n", SECOND_X_AXIS,
- axis_array[SECOND_X_AXIS].min,
- axis_array[SECOND_X_AXIS].term_lower,
- axis_array[SECOND_X_AXIS].term_scale,
- axis_array[SECOND_X_AXIS].log ? axis_array[SECOND_X_AXIS].log_base : 0);
- PRINT5("S %2d %16.6g %14d %16.6g %16.6g\n", SECOND_Y_AXIS,
- axis_array[SECOND_Y_AXIS].min,
- axis_array[SECOND_Y_AXIS].term_lower,
- axis_array[SECOND_Y_AXIS].term_scale,
- axis_array[SECOND_Y_AXIS].log ? axis_array[SECOND_Y_AXIS].log_base : 0);
+
+ X11_send_axis_state(FIRST_X_AXIS);
+ X11_send_axis_state(FIRST_Y_AXIS);
+ X11_send_axis_state(SECOND_X_AXIS);
+ X11_send_axis_state(SECOND_Y_AXIS);
}
#endif
From ade27cc274a5d15a7542a3ec4ef2a7bed2ca99d5 Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Wed, 24 Jul 2024 20:00:43 -0700
Subject: [PATCH 09/40] qt: handle mousing of logscale axes in inactive plot
window
When mousing an inactive plot window, the axis limits and scaling
are retrieved from a per-plot structure initially sent by qt_term
and stored by gnuplot_qt. However only the limits and scaling for
the user-visible axis were sent, not the underlying primary axis.
This was a oversight from all the way back to version 5.
In the case of logscale this is easy to fix - we just send the
primary axis info instead and let gnuplot_qt do the conversion
user_coord = primary_coord ** logbase.
In the case of other nonlinear or linked axes the necessary
"via" and "inv" functions are not available to gnuplot_qt.
For now this results in the coordinate being reported as NaN.
Bug 2723
---
src/qtterminal/QtGnuplotScene.cpp | 2 ++
src/qtterminal/qt_term.cpp | 22 +++++++++++++++++-----
2 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/src/qtterminal/QtGnuplotScene.cpp b/src/qtterminal/QtGnuplotScene.cpp
index 030c50de4..467a16aa3 100644
--- a/src/qtterminal/QtGnuplotScene.cpp
+++ b/src/qtterminal/QtGnuplotScene.cpp
@@ -1127,6 +1127,8 @@ double QtGnuplotScene::sceneToGraph(int axis, double coord) const
return 0;
double result = m_axisMin[axis] + (coord - m_axisLower[axis])/m_axisScale[axis];
+ if (m_axisLog[axis] < 0.)
+ result = NAN;
if (m_axisLog[axis] > 0.)
result = exp(result * m_axisLog[axis]);
diff --git a/src/qtterminal/qt_term.cpp b/src/qtterminal/qt_term.cpp
index 84f70c9c9..fb3f1f62a 100644
--- a/src/qtterminal/qt_term.cpp
+++ b/src/qtterminal/qt_term.cpp
@@ -636,10 +636,22 @@ void qt_text_wrapper()
for (int i = 0; i < 4; i++)
{
- qt->out << (axis_array[axis_order[i]].ticmode != NO_TICS); // Axis active or not
- qt->out << axis_array[axis_order[i]].min;
- double lower = double(axis_array[axis_order[i]].term_lower);
- double scale = double(axis_array[axis_order[i]].term_scale);
+ struct axis *mousing_axis = &axis_array[axis_order[i]];
+ double log_base;
+
+ qt->out << (mousing_axis->ticmode != NO_TICS); // Axis active or not
+
+ if (mousing_axis->log)
+ log_base = mousing_axis->log_base;
+ else if (nonlinear(mousing_axis))
+ log_base = -1;
+ else
+ log_base = 0;
+ if (mousing_axis->log && mousing_axis->linked_to_primary)
+ mousing_axis = mousing_axis->linked_to_primary;
+ qt->out << mousing_axis->min;
+ double lower = mousing_axis->term_lower;
+ double scale = mousing_axis->term_scale;
// Reverse the y axis
if (i % 2)
{
@@ -647,7 +659,7 @@ void qt_text_wrapper()
scale *= -1;
}
qt->out << lower/qt_oversamplingF << scale/qt_oversamplingF;
- qt->out << (axis_array[axis_order[i]].log ? axis_array[axis_order[i]].log_base : 0.);
+ qt->out << log_base;
}
// Flag whether this was a 3D plot (not mousable in 'persist' mode)
qt->out << qt_is_3Dplot;
From 0dcc78ebdb92ec740c75cee9536a3e4493e5a08d Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Wed, 24 Jul 2024 20:24:14 -0700
Subject: [PATCH 10/40] wxt: handle mousing of logscale axes in inactive plot
window
When mousing an inactive plot window, the axis limits and scaling
are retrieved from a per-plot structure initially sent by wxt.trm
and stored wxt_axis_state[]. However only the limits and scaling for
the user-visible axis were sent, not the underlying primary axis.
This was a oversight from all the way back to version 5.
In the case of logscale this is easy to fix - we just send the
primary axis info instead and let wxt_gui do the conversion
user_coord = primary_coord ** logbase.
In the case of other nonlinear or linked axes the necessary
"via" and "inv" functions are not available to wxt_gui.
For now this results in the coordinate being reported as NaN.
Bug 2723
---
src/wxterminal/wxt_gui.cpp | 5 ++++-
term/wxt.trm | 19 ++++++++++++++-----
2 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/src/wxterminal/wxt_gui.cpp b/src/wxterminal/wxt_gui.cpp
index 5122f20b1..161100a70 100644
--- a/src/wxterminal/wxt_gui.cpp
+++ b/src/wxterminal/wxt_gui.cpp
@@ -2066,7 +2066,8 @@ void wxt_text()
#ifdef USE_MOUSE
/* Save a snapshot of the axis state so that we can continue
- * to update mouse cursor coordinates even though the plot is not active */
+ * to update mouse cursor coordinates even though the plot is not active
+ */
wxt_current_window->axis_mask = wxt_axis_mask;
memcpy( wxt_current_window->axis_state,
wxt_axis_state, sizeof(wxt_axis_state) );
@@ -3287,6 +3288,8 @@ static double mouse_to_axis(int mouse_coord, wxt_axis_state_t *axis)
return 0;
axis_coord = axis->min
+ ((double)mouse_coord - axis->term_lower) / axis->term_scale;
+ if (axis->logbase < 0)
+ axis_coord = NAN;
if (axis->logbase > 0)
axis_coord = exp(axis_coord * axis->logbase);
diff --git a/term/wxt.trm b/term/wxt.trm
index 0ac56b16e..097ccdb85 100644
--- a/term/wxt.trm
+++ b/term/wxt.trm
@@ -450,11 +450,20 @@ TERM_PUBLIC void wxt_text_wrapper()
}
for (i=0; i<4; i++) {
- wxt_axis_state[i].min = axis_array[axis_order[i]].min;
- wxt_axis_state[i].term_lower = axis_array[axis_order[i]].term_lower;
- wxt_axis_state[i].term_scale = axis_array[axis_order[i]].term_scale;
- wxt_axis_state[i].logbase = axis_array[axis_order[i]].log
- ? axis_array[axis_order[i]].log_base : 0;
+ struct axis *mousing_axis = &axis_array[axis_order[i]];
+ double log_base;
+ if (mousing_axis->log)
+ log_base = mousing_axis->log_base;
+ else if (nonlinear(mousing_axis))
+ log_base = -1;
+ else
+ log_base = 0;
+ if (mousing_axis->log && mousing_axis->linked_to_primary)
+ mousing_axis = mousing_axis->linked_to_primary;
+ wxt_axis_state[i].min = mousing_axis->min;
+ wxt_axis_state[i].term_lower = mousing_axis->term_lower;
+ wxt_axis_state[i].term_scale = mousing_axis->term_scale;
+ wxt_axis_state[i].logbase = log_base;
}
#endif
From 96d580c5088e5cb2f091afa267780b2185339682 Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Thu, 25 Jul 2024 14:32:43 -0700
Subject: [PATCH 11/40] more consistent use of safe_strncpy()
In preparation for using strlcpy() wherever possible, audit all uses
of strcpy() strncpy(). Replace with safe_strncpy() where appropriate.
Some places (mostly in *.trm) used strncpy to replace one or two
characters inside a known-length string. Replace these with strcpy().
Because strncpy and strlcpy disagree on what value is returned,
this is potentially a concern for wholesale replacement.
However only a single call site in command.c:do_shell() actually
uses the return value. Recode safe_strncpy as to have no return value
void safe_strncpy(dst, src, len)
and modify the one call site that cares.
---
docs/termdoc.c | 11 +++--------
src/axis.c | 2 +-
src/breaders.c | 3 +--
src/color.c | 2 +-
src/command.c | 11 +++++------
src/datafile.c | 3 +--
src/internal.c | 6 +++---
src/misc.c | 2 +-
src/plot2d.c | 2 +-
src/qtterminal/qt_term.cpp | 2 +-
src/stats.c | 3 +--
src/stdfn.c | 8 ++------
src/stdfn.h | 3 ++-
src/term.c | 3 +--
src/util.c | 2 +-
src/wxterminal/wxt_gui.cpp | 2 +-
term/aquaterm.trm | 2 +-
term/caca.trm | 2 +-
term/cairo.trm | 4 ++--
term/canvas.trm | 2 +-
term/context.trm | 6 ++----
term/djsvga.trm | 2 +-
term/dumb.trm | 2 +-
term/estimate.trm | 2 +-
term/gd.trm | 2 +-
term/hpgl.trm | 4 ++--
term/lua.trm | 5 ++---
term/pm.trm | 2 +-
term/post.trm | 5 ++---
term/svg.trm | 2 +-
term/tkcanvas.trm | 4 ++--
term/x11.trm | 6 +++---
32 files changed, 50 insertions(+), 67 deletions(-)
diff --git a/docs/termdoc.c b/docs/termdoc.c
index 699d04faf..756a906a2 100644
--- a/docs/termdoc.c
+++ b/docs/termdoc.c
@@ -178,19 +178,14 @@ get_line( char *buffer, int max, FILE *fp)
/* Safe, '\0'-terminated version of strncpy()
* safe_strncpy(dest, src, n), where n = sizeof(dest)
- * This is basically the old fit.c(copy_max) function
+ * This is basically strlcpy except for the return value.
*/
-
-char *
+void
safe_strncpy( char *d, const char *s, size_t n)
{
- char *ret;
-
- ret = strncpy(d, s, n);
+ strncpy(d, s, n);
if (strlen(s) >= n)
d[n-1] = NUL;
-
- return ret;
}
diff --git a/src/axis.c b/src/axis.c
index f1d620021..a2f69ec3b 100644
--- a/src/axis.c
+++ b/src/axis.c
@@ -609,7 +609,7 @@ copy_or_invent_formatstring(struct axis *this_axis)
if (this_axis->tictype != DT_TIMEDATE
|| !looks_like_numeric(this_axis->formatstring)) {
/* The simple case: formatstring is usable, so use it! */
- strncpy(tempfmt, this_axis->formatstring, MAX_ID_LEN);
+ safe_strncpy(tempfmt, this_axis->formatstring, MAX_ID_LEN);
/* Ensure enough precision to distinguish tics */
if (!strcmp(tempfmt, DEF_FORMAT)) {
double axmin = this_axis->min;
diff --git a/src/breaders.c b/src/breaders.c
index 8d8c0a904..8972744db 100644
--- a/src/breaders.c
+++ b/src/breaders.c
@@ -176,8 +176,7 @@ edf_filetype_function(void)
if ((p = edf_findInHeader(header, "EDF_BinaryFileName"))) {
int plen = strcspn(p, " ;\n");
df_filename = gp_realloc(df_filename, plen+1, "datafile name");
- strncpy(df_filename, p, plen);
- df_filename[plen] = '\0';
+ safe_strncpy(df_filename, p, plen);
if ((p = edf_findInHeader(header, "EDF_BinaryFilePosition")))
df_bin_record[0].scan_skip[0] = atoi(p);
else
diff --git a/src/color.c b/src/color.c
index 175c6f18b..dd304040f 100644
--- a/src/color.c
+++ b/src/color.c
@@ -1394,7 +1394,7 @@ set_palette_function()
strcpy( saved_dummy_var, c_dummy_var[0]);
/* set dummy variable */
- strncpy( c_dummy_var[0], "gray", MAX_ID_LEN );
+ strcpy( c_dummy_var[0], "gray" );
/* Afunc */
start_token = c_token;
diff --git a/src/command.c b/src/command.c
index cb5b85df4..92b2671eb 100644
--- a/src/command.c
+++ b/src/command.c
@@ -1037,8 +1037,7 @@ bind_command()
char *first = gp_input_line + token[c_token].start_index;
int size = strcspn(first, " \";");
lhs = gp_alloc(size + 1, "bind_command->lhs");
- strncpy(lhs, first, size);
- lhs[size] = '\0';
+ safe_strncpy(lhs, first, size);
FPRINTF((stderr,"Got bind unquoted lhs = \"%s\"\n",lhs));
while (gp_input_line + token[c_token].start_index < first+size)
c_token++;
@@ -3580,8 +3579,9 @@ do_shell()
c_token++;
if (user_shell) {
- if (system(safe_strncpy(&exec[sizeof(EXEC) - 1], user_shell,
- sizeof(exec) - sizeof(EXEC) - 1)))
+ safe_strncpy(&exec[sizeof(EXEC) - 1], user_shell,
+ sizeof(exec) - sizeof(EXEC) - 1);
+ if (system(exec))
os_error(NO_CARET, "system() failed");
}
(void) putc('\n', stderr);
@@ -3795,8 +3795,7 @@ expand_1level_macros()
temp_string = gp_alloc(gp_input_line_len,"string variable");
len = strlen(gp_input_line);
if (len >= gp_input_line_len) len = gp_input_line_len-1;
- strncpy(temp_string,gp_input_line,len);
- temp_string[len] = '\0';
+ safe_strncpy(temp_string,gp_input_line,len);
for (c=temp_string; len && c && *c; c++, len--) {
switch (*c) {
diff --git a/src/datafile.c b/src/datafile.c
index 5eebe8729..5c1e7d12f 100644
--- a/src/datafile.c
+++ b/src/datafile.c
@@ -3220,8 +3220,7 @@ df_parse_string_field(char *field)
}
temp_string = malloc(length+1);
- strncpy(temp_string, field, length);
- temp_string[length] = '\0';
+ safe_strncpy(temp_string, field, length);
parse_esc(temp_string);
diff --git a/src/internal.c b/src/internal.c
index 3e419f75c..ef6174e28 100644
--- a/src/internal.c
+++ b/src/internal.c
@@ -1767,7 +1767,7 @@ f_sprintf(union argument *arg)
int int_spec_pos = strcspn(next_start, "diouxX");
char *newformat = gp_alloc(strlen(next_start) + strlen(PRId64) + 1, NULL);
char *new_int_spec;
- strncpy(newformat, next_start, int_spec_pos);
+ safe_strncpy(newformat, next_start, int_spec_pos);
switch (next_start[int_spec_pos]) {
default:
case 'd': new_int_spec = PRId64; break;
@@ -1777,7 +1777,7 @@ f_sprintf(union argument *arg)
case 'x': new_int_spec = PRIx64; break;
case 'X': new_int_spec = PRIX64; break;
}
- strncpy(newformat+int_spec_pos, new_int_spec, strlen(new_int_spec)+1);
+ safe_strncpy(newformat+int_spec_pos, new_int_spec, strlen(new_int_spec)+1);
strcat(newformat, next_start+int_spec_pos+1);
snprintf(outpos, bufsize-(outpos-buffer), newformat, int64_val);
free(newformat);
@@ -1912,7 +1912,7 @@ f_strftime(union argument *arg)
*/
fmtlen = strlen(fmt.v.string_val) + 1;
fmtstr = gp_alloc(fmtlen + 1, "f_strftime: fmt");
- strncpy(fmtstr, fmt.v.string_val, fmtlen);
+ safe_strncpy(fmtstr, fmt.v.string_val, fmtlen);
strncat(fmtstr, " ", fmtlen);
buflen = 80 + 2*fmtlen;
buffer = gp_alloc(buflen, "f_strftime: buffer");
diff --git a/src/misc.c b/src/misc.c
index c69e9f7de..574e92faa 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -317,7 +317,7 @@ load_file(FILE *fp, char *name, int calltype)
* continuation request.
*/
if (!fp && datablock_input_line) {
- strncpy(&(gp_input_line[start]), *datablock_input_line, left);
+ safe_strncpy(&(gp_input_line[start]), *datablock_input_line, left);
datablock_input_line++;
}
inline_num++;
diff --git a/src/plot2d.c b/src/plot2d.c
index 1074d20a0..4e55a365b 100644
--- a/src/plot2d.c
+++ b/src/plot2d.c
@@ -2198,7 +2198,7 @@ store_label(
textlen -= 2, string++;
tl->text = gp_alloc(textlen+1,"labelpoint text");
- strncpy( tl->text, string, textlen );
+ safe_strncpy( tl->text, string, textlen );
tl->text[textlen] = '\0';
parse_esc(tl->text);
diff --git a/src/qtterminal/qt_term.cpp b/src/qtterminal/qt_term.cpp
index fb3f1f62a..2f4115a73 100644
--- a/src/qtterminal/qt_term.cpp
+++ b/src/qtterminal/qt_term.cpp
@@ -760,7 +760,7 @@ void qt_put_text(unsigned int x, unsigned int y, const char* string)
// set up the global variables needed by enhanced_recursion()
enhanced_fontscale = 1.0;
- strncpy(enhanced_escape_format, "%c", sizeof(enhanced_escape_format));
+ safe_strncpy(enhanced_escape_format, "%c", sizeof(enhanced_escape_format));
// Baseline correction
qt_max_pos_base = qt_max_neg_base = 0.0;
diff --git a/src/stats.c b/src/stats.c
index a1c971158..f184d4b4e 100644
--- a/src/stats.c
+++ b/src/stats.c
@@ -537,8 +537,7 @@ two_column_output( struct sgl_column_stats x,
}
/* Create a string of blanks of the required length */
- strncpy( blank, " ", width+4 );
- blank[width+4] = '\0';
+ safe_strncpy( blank, " ", width+4 );
ensure_output();
diff --git a/src/stdfn.c b/src/stdfn.c
index c7653aaab..831850a87 100644
--- a/src/stdfn.c
+++ b/src/stdfn.c
@@ -329,16 +329,12 @@ strndup(const char * str, size_t n)
/* Safe, '\0'-terminated version of strncpy()
* safe_strncpy(dest, src, n), where n = sizeof(dest)
*/
-char *
+void
safe_strncpy(char *d, const char *s, size_t n)
{
- char *ret;
-
- ret = strncpy(d, s, n);
+ strncpy(d, s, n);
if (strlen(s) >= n)
d[n > 0 ? n - 1 : 0] = NUL;
-
- return ret;
}
diff --git a/src/stdfn.h b/src/stdfn.h
index 7389e916e..4bf4a0785 100644
--- a/src/stdfn.h
+++ b/src/stdfn.h
@@ -580,7 +580,8 @@ void gp_rewinddir(GPDIR *);
/* Prototypes from "stdfn.c" */
-char *safe_strncpy(char *, const char *, size_t);
+void safe_strncpy(char *, const char *, size_t);
+
#ifndef HAVE_SLEEP
unsigned int sleep(unsigned int);
#endif
diff --git a/src/term.c b/src/term.c
index 79d270a35..4537a437a 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2398,8 +2398,7 @@ enhanced_recursion(
/* We found a new font name {/Font ...} */
int len = end_of_fontname - start_of_fontname;
localfontname = gp_alloc(len+1,"localfontname");
- strncpy(localfontname, start_of_fontname, len);
- localfontname[len] = '\0';
+ safe_strncpy(localfontname, start_of_fontname, len);
}
}
/*}}}*/
diff --git a/src/util.c b/src/util.c
index 808bd3717..07b56b7d6 100644
--- a/src/util.c
+++ b/src/util.c
@@ -698,7 +698,7 @@ gprintf_value(
if (bracket_flag)
tmp2[j++] = '}';
tmp2[j] = '\0';
- strncpy(dest, tmp2, remaining_space);
+ safe_strncpy(dest, tmp2, remaining_space);
#undef LOCAL_BUFFER_SIZE
}
diff --git a/src/wxterminal/wxt_gui.cpp b/src/wxterminal/wxt_gui.cpp
index 161100a70..048905950 100644
--- a/src/wxterminal/wxt_gui.cpp
+++ b/src/wxterminal/wxt_gui.cpp
@@ -2203,7 +2203,7 @@ void wxt_put_text(unsigned int x, unsigned int y, const char * string)
/* set up the global variables needed by enhanced_recursion() */
enhanced_fontscale = 1.0;
- strncpy(enhanced_escape_format, "%c", sizeof(enhanced_escape_format));
+ safe_strncpy(enhanced_escape_format, "%c", sizeof(enhanced_escape_format));
/* Set the recursion going. We say to keep going until a
* closing brace, but we don't really expect to find one.
diff --git a/term/aquaterm.trm b/term/aquaterm.trm
index e2060b8ad..15d2fba6c 100644
--- a/term/aquaterm.trm
+++ b/term/aquaterm.trm
@@ -921,7 +921,7 @@ ENHAQUA_put_text(unsigned int x, unsigned int y, const char str[])
/* set up the global variables needed by enhanced_recursion() */
enhanced_fontscale = 1;
- strncpy(enhanced_escape_format,"\\%o",sizeof(enhanced_escape_format));
+ strcpy(enhanced_escape_format,"\\%o");
/* Clear the attributed string */
[enhString release];
diff --git a/term/caca.trm b/term/caca.trm
index 1d4d90ed0..d8b1f033a 100644
--- a/term/caca.trm
+++ b/term/caca.trm
@@ -2744,7 +2744,7 @@ CACA_enhanced_put_text(unsigned int x, unsigned int y, const char *str)
/* Set up global variables needed by enhanced_recursion() */
enhanced_fontscale = 1.0;
CACA_enhanced_opened_string = FALSE;
- strncpy(enhanced_escape_format, "%c", sizeof(enhanced_escape_format));
+ strcpy(enhanced_escape_format, "%c");
CACA_x = x;
CACA_y = y;
diff --git a/term/cairo.trm b/term/cairo.trm
index 686714287..182987cd9 100644
--- a/term/cairo.trm
+++ b/term/cairo.trm
@@ -702,7 +702,7 @@ TERM_PUBLIC void cairotrm_options()
if (!cairo_params->fontname)
ps_params->font[0] = '\0';
else
- strncpy(ps_params->font, cairo_params->fontname, sizeof(ps_params->font) - 1);
+ safe_strncpy(ps_params->font, cairo_params->fontname, sizeof(ps_params->font) - 1);
ps_params->fontsize = cairo_params->fontsize;
ps_params->fontscale = cairo_params->fontscale;
if (cairo_params->transparent) {
@@ -1180,7 +1180,7 @@ void cairotrm_put_text(unsigned int x, unsigned int y, const char * string)
/* set up the global variables needed by enhanced_recursion() */
enhanced_fontscale = cairo_params->fontscale;
- strncpy(enhanced_escape_format, "%c", sizeof(enhanced_escape_format));
+ strcpy(enhanced_escape_format, "%c");
/* Set the recursion going. We say to keep going until a closing brace,
* but we don't really expect to find one. If the return value is not
diff --git a/term/canvas.trm b/term/canvas.trm
index 3fe1f8a35..a919b09bd 100644
--- a/term/canvas.trm
+++ b/term/canvas.trm
@@ -1558,7 +1558,7 @@ ENHCANVAS_put_text(unsigned int x, unsigned int y, const char *str)
/* Set up global variables needed by enhanced_recursion() */
enhanced_fontscale = 1.0;
- strncpy(enhanced_escape_format,"%c",sizeof(enhanced_escape_format));
+ strcpy(enhanced_escape_format,"%c");
ENHCANVAS_opened_string = FALSE;
ENHCANVAS_fontsize = canvas_font_size;
if (!strcmp(canvas_justify,"Right") || !strcmp(canvas_justify,"Center"))
diff --git a/term/context.trm b/term/context.trm
index 76e3f7e0a..16b0d66ff 100644
--- a/term/context.trm
+++ b/term/context.trm
@@ -763,15 +763,13 @@ CONTEXT_init()
/* .xx.png; must be at least 7 characters long */
CONTEXT_image_filename = (char *)gp_alloc(CONTEXT_image_filename_length + 10, "ConTeXt image filename");
- strncpy(CONTEXT_image_filename, outstr, CONTEXT_image_filename_length);
- CONTEXT_image_filename[CONTEXT_image_filename_length] = 0;
+ safe_strncpy(CONTEXT_image_filename, outstr, CONTEXT_image_filename_length);
} else {
CONTEXT_image_filename_length = strlen("gp_image");
CONTEXT_image_filename_start = 0;
/* .xx.png; must be at least 7 characters long */
CONTEXT_image_filename = (char *)gp_alloc(CONTEXT_image_filename_length + 10, "ConTeXt image filename");
- strncpy(CONTEXT_image_filename, "gp_image", CONTEXT_image_filename_length);
- CONTEXT_image_filename[CONTEXT_image_filename_length] = 0;
+ safe_strncpy(CONTEXT_image_filename, "gp_image", CONTEXT_image_filename_length);
}
}
#endif
diff --git a/term/djsvga.trm b/term/djsvga.trm
index d41e91b6c..6cd6161d9 100644
--- a/term/djsvga.trm
+++ b/term/djsvga.trm
@@ -1269,7 +1269,7 @@ DJSVGA_enhanced_put_text(unsigned int x, unsigned int y, const char *str)
/* Set up global variables needed by enhanced_recursion() */
enhanced_fontscale = 1.0;
dj_enhanced_opened_string = FALSE;
- safe_strncpy(enhanced_escape_format, "%c", sizeof(enhanced_escape_format));
+ strcpy(enhanced_escape_format, "%c");
dj_x = x;
dj_y = y;
diff --git a/term/dumb.trm b/term/dumb.trm
index 2f7534ecc..498e27fc6 100644
--- a/term/dumb.trm
+++ b/term/dumb.trm
@@ -995,7 +995,7 @@ ENHdumb_put_text(unsigned int x, unsigned int y, const char *str)
/* Set up global variables needed by enhanced_recursion() */
enhanced_fontscale = 1.0;
ENHdumb_opened_string = FALSE;
- strncpy(enhanced_escape_format, "%c", sizeof(enhanced_escape_format));
+ strcpy(enhanced_escape_format, "%c");
DUMB_move(x,y);
diff --git a/term/estimate.trm b/term/estimate.trm
index edd07d7a8..b24a8b019 100644
--- a/term/estimate.trm
+++ b/term/estimate.trm
@@ -129,7 +129,7 @@ ENHest_put_text(unsigned int x, unsigned int y, const char *str)
ENHest_max_height = ENHest_fontsize;
ENHest_min_height = 0.0;
ENHest_total_width = 0.0;
- strncpy(enhanced_escape_format,".",sizeof(enhanced_escape_format));
+ strcpy(enhanced_escape_format,".");
/* buffer in which we will return plaintext version of enhanced text string */
while (ENHest_plaintext_buflen <= strlen(str)) {
diff --git a/term/gd.trm b/term/gd.trm
index 26d530dd9..858434c04 100644
--- a/term/gd.trm
+++ b/term/gd.trm
@@ -2202,7 +2202,7 @@ ENHGD_put_text(unsigned int x, unsigned int y, const char *str)
/* set up the global variables needed by enhanced_recursion() */
enhanced_fontscale = png_state.fontscale;
- strncpy(enhanced_escape_format,"%2.2x;",sizeof(enhanced_escape_format));
+ safe_strncpy(enhanced_escape_format,"%2.2x;",sizeof(enhanced_escape_format));
ENHgd_opened_string = FALSE;
ENHgd_show = TRUE;
diff --git a/term/hpgl.trm b/term/hpgl.trm
index 3e751f666..e96bb1c95 100644
--- a/term/hpgl.trm
+++ b/term/hpgl.trm
@@ -1661,7 +1661,7 @@ HPGL2_set_font(const char *font)
font = "";
sep = strcspn(font, ",");
- strncpy(name, font, sizeof(name)-1);
+ safe_strncpy(name, font, sizeof(name)-1);
if (sep < sizeof(name))
name[sep] = NUL;
@@ -3080,7 +3080,7 @@ HPGL2_enh_put_text(unsigned int x, unsigned int y, const char str[])
enhanced_fontscale = 1.0;
HPGL2_opened_string = FALSE;
HPGL2_base = 0.;
- strncpy(enhanced_escape_format, "%c", sizeof(enhanced_escape_format));
+ strcpy(enhanced_escape_format, "%c");
/* Text justification requires two passes. During the first pass we */
/* don't draw anything, we just move the "cursor". */
diff --git a/term/lua.trm b/term/lua.trm
index f258fd87e..09d492897 100644
--- a/term/lua.trm
+++ b/term/lua.trm
@@ -194,8 +194,7 @@ LUA_GP_term_options(lua_State *L) {
if (n > MAX_LINE_LEN)
return luaL_error(L, "Option string consists of %d characters but only %d are allowed", n, MAX_LINE_LEN);
- strncpy(term_options, opt_str, MAX_LINE_LEN);
- term_options[MAX_LINE_LEN] = '\0';
+ safe_strncpy(term_options, opt_str, MAX_LINE_LEN);
return(0);
}
@@ -1310,7 +1309,7 @@ LUA_image (unsigned m, unsigned n, coordval *image, gpiPoint *corner, t_imagecol
if ((idx = strrchr(outstr, '.')) == NULL)
idx = strchr(outstr, '\0');
image_file = (char*)gp_alloc((idx-outstr)+10, "LUA_image");
- strncpy(image_file, outstr, (idx-outstr) + 1);
+ safe_strncpy(image_file, outstr, (idx-outstr) + 1);
snprintf(image_file+(idx-outstr), 9, ".%03d.png", (unsigned char)(++image_cnt));
write_png_image (m, n, image, color_mode, image_file);
diff --git a/term/pm.trm b/term/pm.trm
index 922abb81f..054ce1795 100644
--- a/term/pm.trm
+++ b/term/pm.trm
@@ -1447,7 +1447,7 @@ PM_enhanced_put_text(unsigned int x, unsigned int y, const char *str)
/* Set up global variables needed by enhanced_recursion() */
ENHpm_opened_string = FALSE;
enhanced_fontscale = 1.0;
- safe_strncpy(enhanced_escape_format, "%c", sizeof(enhanced_escape_format));
+ strcpy(enhanced_escape_format, "%c");
/* Tell the terminal to move the drawing position */
/* we store the current position to PM_x and PM_y */
diff --git a/term/post.trm b/term/post.trm
index 1e7d6c9c7..16b21db90 100644
--- a/term/post.trm
+++ b/term/post.trm
@@ -2822,7 +2822,7 @@ ENHPS_put_text(unsigned int x, unsigned int y, const char *str)
enhanced_max_height = -1000;
enhanced_min_height = 1000;
enhanced_fontscale = PS_SCF;
- safe_strncpy(enhanced_escape_format,"\\%o",sizeof(enhanced_escape_format));
+ strcpy(enhanced_escape_format,"\\%o");
ENHps_opened_string = FALSE;
@@ -4330,8 +4330,7 @@ PS_load_glyphlist()
next++;
len = strchr(next,';') - next;
- strncpy(glyph_name, next, len);
- glyph_name[len] = '\0';
+ safe_strncpy(glyph_name, next, len);
FPRINTF((stderr, "%04X %s\n", code, glyph_name));
if (aglist_size + sizeof(ps_glyph) > aglist_alloc) {
aglist_alloc += 2048;
diff --git a/term/svg.trm b/term/svg.trm
index a2cf307be..80500d966 100644
--- a/term/svg.trm
+++ b/term/svg.trm
@@ -2114,7 +2114,7 @@ ENHsvg_put_text(unsigned int x, unsigned int y, const char *str)
/* Set up global variables needed by enhanced_recursion() */
ENHsvg_charcount = 0;
enhanced_fontscale = 1.0;
- strncpy(enhanced_escape_format,"%c",sizeof(enhanced_escape_format));
+ strcpy(enhanced_escape_format,"%c");
while (*(str = enhanced_recursion((char *)str, TRUE,
fontname, fontsize, 0.0, TRUE, TRUE, 0))) {
diff --git a/term/tkcanvas.trm b/term/tkcanvas.trm
index fc0cdbfec..3924691be 100644
--- a/term/tkcanvas.trm
+++ b/term/tkcanvas.trm
@@ -684,7 +684,7 @@ TK_dashtype(int dt, t_dashtype *custom_dash_pattern)
} else if (dt == DASHTYPE_CUSTOM) {
if (custom_dash_pattern->dstring[0] != NUL) {
/* Tk and gnuplot support the very same dash pattern syntax. */
- strncpy(tmp_dashpattern, custom_dash_pattern->dstring, sizeof(tmp_dashpattern)-1);
+ safe_strncpy(tmp_dashpattern, custom_dash_pattern->dstring, sizeof(tmp_dashpattern));
preserve = TRUE; /* do not change pattern */
} else {
tmp_dashpattern[0] = NUL;
@@ -1438,7 +1438,7 @@ TK_put_enhanced_text(unsigned int x, unsigned int y, const char *str)
{
/* Set up global variables needed by enhanced_recursion() */
enhanced_fontscale = 1.0;
- strncpy(enhanced_escape_format, "%c", sizeof(enhanced_escape_format));
+ strcpy(enhanced_escape_format, "%c");
tk_enhanced_opened_string = FALSE;
tk_lastx = x;
diff --git a/term/x11.trm b/term/x11.trm
index de248fe8b..411fb11fd 100644
--- a/term/x11.trm
+++ b/term/x11.trm
@@ -538,7 +538,7 @@ X11_options()
if (END_OF_COMMAND)
int_error(c_token, "expecting font name");
if (isstringvalue(c_token) && (s = try_to_get_string())) {
- strncpy(X11_default_font, s, sizeof(X11_default_font)-1);
+ safe_strncpy(X11_default_font, s, sizeof(X11_default_font)-1);
free(s);
} else {
copy_str(X11_default_font, c_token, sizeof(X11_default_font));
@@ -1639,7 +1639,7 @@ TERM_PUBLIC int
X11_set_font(const char *fontname)
{
PRINT1("QF%s\n", fontname?fontname:"");
- strncpy(X11_next_font_used,fontname?fontname:"",sizeof(X11_next_font_used)-1);
+ safe_strncpy(X11_next_font_used,fontname?fontname:"",sizeof(X11_next_font_used)-1);
return(TRUE);
}
@@ -2076,7 +2076,7 @@ ENHX11_put_text(unsigned int x, unsigned int y, const char *str)
/* set up the global variables needed by enhanced_recursion() */
enhanced_fontscale = 1.25;
ENHx11_opened_string = FALSE;
- strncpy(enhanced_escape_format,"%c",sizeof(enhanced_escape_format));
+ strcpy(enhanced_escape_format,"%c");
/* Terrible, horrible, no good, very bad hack to fix wonky rotation of
* enhanced text. This should be done, and done better, in gnuplot_x11.
From 76498bf8b4e6a45888f79db04bb0de8645fd2e2a Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Thu, 25 Jul 2024 13:52:30 -0700
Subject: [PATCH 12/40] use strlcpy() for safe_strncpy() if the system provides
it
strlcpy() is finally in glibc as of glibc version 2.38
Use it if present rather than the open-coded equivalent in
stdfn.c:safe_strncpy.
---
configure.ac | 2 +-
docs/termdoc.c | 4 +++-
src/stdfn.c | 3 +++
src/stdfn.h | 6 +++++-
4 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/configure.ac b/configure.ac
index 7f5660fd8..5cd7480bb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -296,7 +296,7 @@ AC_CHECK_FUNCS(atexit memcpy memmove memset \
setvbuf strerror strchr strrchr strstr \
index rindex \
erf erfc gamma lgamma tgamma \
- getcwd poll pclose popen fdopen select sleep stpcpy \
+ getcwd poll pclose popen fdopen select sleep stpcpy strlcpy \
strcspn strdup strndup strnlen strcasecmp stricmp strncasecmp strnicmp \
sysinfo tcgetattr vfprintf doprnt uname usleep \
cbrt jn
diff --git a/docs/termdoc.c b/docs/termdoc.c
index 756a906a2..f204c93e9 100644
--- a/docs/termdoc.c
+++ b/docs/termdoc.c
@@ -178,8 +178,9 @@ get_line( char *buffer, int max, FILE *fp)
/* Safe, '\0'-terminated version of strncpy()
* safe_strncpy(dest, src, n), where n = sizeof(dest)
- * This is basically strlcpy except for the return value.
+ * This is basically strlcpy() except for the [lack of] return value.
*/
+#ifndef HAVE_STRLCPY
void
safe_strncpy( char *d, const char *s, size_t n)
{
@@ -187,6 +188,7 @@ safe_strncpy( char *d, const char *s, size_t n)
if (strlen(s) >= n)
d[n-1] = NUL;
}
+#endif
#ifdef TEST_TERMDOC
diff --git a/src/stdfn.c b/src/stdfn.c
index 831850a87..6737b493f 100644
--- a/src/stdfn.c
+++ b/src/stdfn.c
@@ -328,7 +328,9 @@ strndup(const char * str, size_t n)
/* Safe, '\0'-terminated version of strncpy()
* safe_strncpy(dest, src, n), where n = sizeof(dest)
+ * This is basically strlcpy() except for the (lack of) return value
*/
+#ifndef HAVE_STRLCPY
void
safe_strncpy(char *d, const char *s, size_t n)
{
@@ -336,6 +338,7 @@ safe_strncpy(char *d, const char *s, size_t n)
if (strlen(s) >= n)
d[n > 0 ? n - 1 : 0] = NUL;
}
+#endif
#ifndef HAVE_STRCSPN
diff --git a/src/stdfn.h b/src/stdfn.h
index 4bf4a0785..96a3e02b2 100644
--- a/src/stdfn.h
+++ b/src/stdfn.h
@@ -580,7 +580,11 @@ void gp_rewinddir(GPDIR *);
/* Prototypes from "stdfn.c" */
-void safe_strncpy(char *, const char *, size_t);
+#ifdef HAVE_STRLCPY
+ #define safe_strncpy(dest, src, len) strlcpy(dest, src, len)
+#else
+ void safe_strncpy(char *, const char *, size_t);
+#endif
#ifndef HAVE_SLEEP
unsigned int sleep(unsigned int);
From 4e3aec4d9d2f16e31062f9dc6d04af7e2dbd12ee Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Fri, 26 Jul 2024 10:11:42 -0700
Subject: [PATCH 13/40] "set tics scale" should not change other axis
properties
"for backwards compatibility" this command forced tics on and
turned off mirroring. The claimed reason was to allow
"set tics scale 0.0" to do the equivalent of "set _range extend" on all axes.
But it hasn't worked for that purpose since I don't know when.
Bug 2724
---
src/set.c | 7 -------
1 file changed, 7 deletions(-)
diff --git a/src/set.c b/src/set.c
index 8d8e659a5..288362b58 100644
--- a/src/set.c
+++ b/src/set.c
@@ -5419,13 +5419,6 @@ set_ticscale()
for (i = 0; i < NUMBER_OF_MAIN_VISIBLE_AXES; ++i) {
axis_array[i].ticscale = lticscale;
axis_array[i].miniticscale = lminiticscale;
- /* For backward compatibility, setting tic scale has the side
- * effect of reenabling display of tics that had been "unset".
- * This allows auto-extension of axes with tic scale 0.
- * NB: The old code also turned on mirroring; now we don't.
- */
- if (i != SECOND_X_AXIS && i != SECOND_Y_AXIS)
- axis_array[i].ticmode = TICS_ON_BORDER;
}
ticlevel = 2;
while (equals(c_token, ",")) {
From 3b5165a4e9a76f506c9b8abf41e906bc1efc6d20 Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Fri, 26 Jul 2024 16:37:18 -0700
Subject: [PATCH 14/40] "set tics scale" should not change other axis
properties
... continued from commit 4e3aec4d
Except it seems people (including our demo collection) use "set tics scale 0"
instead of just "set tics" to turn on the tics again after "unset tics".
I don't know why. Nevertheless to avoid breaking existing scripts
let's have "set tics scale ..." re-enable x1 y1 z cb axis tics.
In accordance with the bug fix, do not change the state of mirroring
or the TICS_ON_AXIS flag bit.
Bug 2724
---
demo/tics.dem | 2 +-
src/set.c | 9 ++++++++-
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/demo/tics.dem b/demo/tics.dem
index 2f9a94bd1..c5b1836fd 100644
--- a/demo/tics.dem
+++ b/demo/tics.dem
@@ -11,7 +11,7 @@ plot sin(sqrt(x**2))/sqrt(x**2) notitle
pause -1 "Hit return to continue"
set title "Different modification of tics settings"
-set tics scale 3,2 rotate by 45
+set tics scale 3,2 rotate by 45 nomirror
set xtics out offset 0,-1.0
replot
pause -1 "Hit return to continue"
diff --git a/src/set.c b/src/set.c
index 288362b58..52dd08c63 100644
--- a/src/set.c
+++ b/src/set.c
@@ -5352,7 +5352,7 @@ static void
set_tics()
{
int i;
- int save_token = c_token;
+ int save_token = c_token++;
/* On a bare "set tics" command, reset the default on/off/placement/mirror
* state of the visible axes.
@@ -5419,6 +5419,13 @@ set_ticscale()
for (i = 0; i < NUMBER_OF_MAIN_VISIBLE_AXES; ++i) {
axis_array[i].ticscale = lticscale;
axis_array[i].miniticscale = lminiticscale;
+ /* Setting tic scale has the side effect of reenabling display of
+ * tics that had been "unset".
+ * FIXME: IMHO this is crazy, but apparently people are used to it
+ * and thus do "set tics scale 0" rather than just "set tics".
+ */
+ if (i != SECOND_X_AXIS && i != SECOND_Y_AXIS)
+ axis_array[i].ticmode |= TICS_ON_BORDER;
}
ticlevel = 2;
while (equals(c_token, ",")) {
From ec758cd2fc1c030166232c2a54881139b990daf6 Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Fri, 26 Jul 2024 14:34:24 -0700
Subject: [PATCH 15/40] fixup - safe_strncpy
sorry, sorry. I inadvertantly pushed the safe_strncpy revision
before having finished debugging it.
These are necessary corrections to commit 96d580c5
---
src/command.c | 3 ++-
src/datafile.c | 3 ++-
src/internal.c | 6 +++---
src/plot2d.c | 2 +-
src/stats.c | 3 ++-
src/term.c | 3 ++-
term/cairo.trm | 2 +-
term/hpgl.trm | 2 +-
term/x11.trm | 4 ++--
9 files changed, 16 insertions(+), 12 deletions(-)
diff --git a/src/command.c b/src/command.c
index 92b2671eb..f985bf5a0 100644
--- a/src/command.c
+++ b/src/command.c
@@ -3795,7 +3795,8 @@ expand_1level_macros()
temp_string = gp_alloc(gp_input_line_len,"string variable");
len = strlen(gp_input_line);
if (len >= gp_input_line_len) len = gp_input_line_len-1;
- safe_strncpy(temp_string,gp_input_line,len);
+ strncpy(temp_string, gp_input_line, len); /* NOT safe_strncpy */
+ temp_string[len] = '\0';
for (c=temp_string; len && c && *c; c++, len--) {
switch (*c) {
diff --git a/src/datafile.c b/src/datafile.c
index 5c1e7d12f..4dad674aa 100644
--- a/src/datafile.c
+++ b/src/datafile.c
@@ -3220,7 +3220,8 @@ df_parse_string_field(char *field)
}
temp_string = malloc(length+1);
- safe_strncpy(temp_string, field, length);
+ strncpy(temp_string, field, length); /* NOT safe_strncpy */
+ temp_string[length] = '\0';
parse_esc(temp_string);
diff --git a/src/internal.c b/src/internal.c
index ef6174e28..53be8d409 100644
--- a/src/internal.c
+++ b/src/internal.c
@@ -1767,7 +1767,7 @@ f_sprintf(union argument *arg)
int int_spec_pos = strcspn(next_start, "diouxX");
char *newformat = gp_alloc(strlen(next_start) + strlen(PRId64) + 1, NULL);
char *new_int_spec;
- safe_strncpy(newformat, next_start, int_spec_pos);
+ strncpy(newformat, next_start, int_spec_pos); /* NOT safe_strncpy */
switch (next_start[int_spec_pos]) {
default:
case 'd': new_int_spec = PRId64; break;
@@ -1777,7 +1777,7 @@ f_sprintf(union argument *arg)
case 'x': new_int_spec = PRIx64; break;
case 'X': new_int_spec = PRIX64; break;
}
- safe_strncpy(newformat+int_spec_pos, new_int_spec, strlen(new_int_spec)+1);
+ strncpy(newformat+int_spec_pos, new_int_spec, strlen(new_int_spec)+1);
strcat(newformat, next_start+int_spec_pos+1);
snprintf(outpos, bufsize-(outpos-buffer), newformat, int64_val);
free(newformat);
@@ -1912,7 +1912,7 @@ f_strftime(union argument *arg)
*/
fmtlen = strlen(fmt.v.string_val) + 1;
fmtstr = gp_alloc(fmtlen + 1, "f_strftime: fmt");
- safe_strncpy(fmtstr, fmt.v.string_val, fmtlen);
+ strncpy(fmtstr, fmt.v.string_val, fmtlen);
strncat(fmtstr, " ", fmtlen);
buflen = 80 + 2*fmtlen;
buffer = gp_alloc(buflen, "f_strftime: buffer");
diff --git a/src/plot2d.c b/src/plot2d.c
index 4e55a365b..0610a0971 100644
--- a/src/plot2d.c
+++ b/src/plot2d.c
@@ -2198,7 +2198,7 @@ store_label(
textlen -= 2, string++;
tl->text = gp_alloc(textlen+1,"labelpoint text");
- safe_strncpy( tl->text, string, textlen );
+ strncpy( tl->text, string, textlen ); /* NOT safe_strncpy */
tl->text[textlen] = '\0';
parse_esc(tl->text);
diff --git a/src/stats.c b/src/stats.c
index f184d4b4e..009b2b184 100644
--- a/src/stats.c
+++ b/src/stats.c
@@ -537,7 +537,8 @@ two_column_output( struct sgl_column_stats x,
}
/* Create a string of blanks of the required length */
- safe_strncpy( blank, " ", width+4 );
+ strncpy( blank, " ", width+4 ); /* NOT safe_strncpy */
+ blank[width+4] = '\0';
ensure_output();
diff --git a/src/term.c b/src/term.c
index 4537a437a..4fc5bf5d8 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2398,7 +2398,8 @@ enhanced_recursion(
/* We found a new font name {/Font ...} */
int len = end_of_fontname - start_of_fontname;
localfontname = gp_alloc(len+1,"localfontname");
- safe_strncpy(localfontname, start_of_fontname, len);
+ strncpy(localfontname, start_of_fontname, len); /* NOT safe_strncpy */
+ localfontname[len] = '\0';
}
}
/*}}}*/
diff --git a/term/cairo.trm b/term/cairo.trm
index 182987cd9..c8774d2d0 100644
--- a/term/cairo.trm
+++ b/term/cairo.trm
@@ -702,7 +702,7 @@ TERM_PUBLIC void cairotrm_options()
if (!cairo_params->fontname)
ps_params->font[0] = '\0';
else
- safe_strncpy(ps_params->font, cairo_params->fontname, sizeof(ps_params->font) - 1);
+ safe_strncpy(ps_params->font, cairo_params->fontname, sizeof(ps_params->font));
ps_params->fontsize = cairo_params->fontsize;
ps_params->fontscale = cairo_params->fontscale;
if (cairo_params->transparent) {
diff --git a/term/hpgl.trm b/term/hpgl.trm
index e96bb1c95..8e763d174 100644
--- a/term/hpgl.trm
+++ b/term/hpgl.trm
@@ -1661,7 +1661,7 @@ HPGL2_set_font(const char *font)
font = "";
sep = strcspn(font, ",");
- safe_strncpy(name, font, sizeof(name)-1);
+ safe_strncpy(name, font, sizeof(name));
if (sep < sizeof(name))
name[sep] = NUL;
diff --git a/term/x11.trm b/term/x11.trm
index 411fb11fd..8648abf0a 100644
--- a/term/x11.trm
+++ b/term/x11.trm
@@ -538,7 +538,7 @@ X11_options()
if (END_OF_COMMAND)
int_error(c_token, "expecting font name");
if (isstringvalue(c_token) && (s = try_to_get_string())) {
- safe_strncpy(X11_default_font, s, sizeof(X11_default_font)-1);
+ safe_strncpy(X11_default_font, s, sizeof(X11_default_font));
free(s);
} else {
copy_str(X11_default_font, c_token, sizeof(X11_default_font));
@@ -1639,7 +1639,7 @@ TERM_PUBLIC int
X11_set_font(const char *fontname)
{
PRINT1("QF%s\n", fontname?fontname:"");
- safe_strncpy(X11_next_font_used,fontname?fontname:"",sizeof(X11_next_font_used)-1);
+ safe_strncpy(X11_next_font_used,fontname?fontname:"",sizeof(X11_next_font_used));
return(TRUE);
}
From e102837ccb06b395165c4b7770be3f1642a5cf8d Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Sat, 27 Jul 2024 11:21:28 -0700
Subject: [PATCH 16/40] tweak demo
---
demo/mask_pm3d.dem | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/demo/mask_pm3d.dem b/demo/mask_pm3d.dem
index 45c540a26..3b51ce3d3 100644
--- a/demo/mask_pm3d.dem
+++ b/demo/mask_pm3d.dem
@@ -16,7 +16,7 @@ set tics scale 0
set title "Convex hull constructed around scattered points"
plot 'mask_pm3d.dat' using 1:2:3 with points lc palette pt 7 ps 2, \
- '' using 1:2 convexhull lc "black" lw 3
+ '' using 1:2 convexhull with lines lc "black" lw 3
set table $HULL
plot 'mask_pm3d.dat' using 1:2 convexhull with lines title "Convex hull"
From 9170fcae250db9fe7c3b1329726feadad6fb49b5 Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Mon, 29 Jul 2024 16:53:06 -0700
Subject: [PATCH 17/40] Do not draw zero-lenth axis tick marks
avoids wasted set linetype + move + (no actual draw) + stroke
---
src/color.c | 8 +++--
src/graph3d.c | 90 ++++++++++++++++++++++++++++----------------------
src/graphics.c | 4 +--
3 files changed, 57 insertions(+), 45 deletions(-)
diff --git a/src/color.c b/src/color.c
index dd304040f..169f01b8a 100644
--- a/src/color.c
+++ b/src/color.c
@@ -675,8 +675,10 @@ cbtick_callback(
}
/* draw tic */
- (*term->move) (x1, y1);
- (*term->vector) (x2, y2);
+ if (len != 0) {
+ (*term->move) (x1, y1);
+ (*term->vector) (x2, y2);
+ }
/* draw label */
if (text) {
@@ -732,7 +734,7 @@ cbtick_callback(
}
/* draw tic on the mirror side */
- if (this_axis->ticmode & TICS_MIRROR) {
+ if ((this_axis->ticmode & TICS_MIRROR) && (len != 0)) {
if (color_box.rotation == 'h') {
y1 = color_box.bounds.ytop;
y2 = color_box.bounds.ytop + len;
diff --git a/src/graph3d.c b/src/graph3d.c
index 65751a1a3..fe6050b62 100644
--- a/src/graph3d.c
+++ b/src/graph3d.c
@@ -3120,25 +3120,29 @@ xtick_callback(
/* Draw bottom tic mark */
if ((this_axis->index == FIRST_X_AXIS)
|| (this_axis->index == SECOND_X_AXIS && (this_axis->ticmode & TICS_MIRROR))) {
- v2.x = v1.x + tic_unitx * scale * t->v_tic ;
- v2.y = v1.y + tic_unity * scale * t->v_tic ;
- v2.z = v1.z + tic_unitz * scale * t->v_tic ;
- v2.real_z = v1.real_z;
- draw3d_line(&v1, &v2, &border_lp);
+ if (scale != 0) {
+ v2.x = v1.x + tic_unitx * scale * t->v_tic ;
+ v2.y = v1.y + tic_unity * scale * t->v_tic ;
+ v2.z = v1.z + tic_unitz * scale * t->v_tic ;
+ v2.real_z = v1.real_z;
+ draw3d_line(&v1, &v2, &border_lp);
+ }
}
/* Draw top tic mark */
if ((this_axis->index == SECOND_X_AXIS)
|| (this_axis->index == FIRST_X_AXIS && (this_axis->ticmode & TICS_MIRROR))) {
- if (xz_projection || zx_projection) {
- map3d_xyz(place, 0, Z_AXIS.max, &v3);
- } else
- map3d_xyz(place, other_end, base_z, &v3);
- v4.x = v3.x - tic_unitx * scale * t->v_tic;
- v4.y = v3.y - tic_unity * scale * t->v_tic;
- v4.z = v3.z - tic_unitz * scale * t->v_tic;
- v4.real_z = v3.real_z;
- draw3d_line(&v3, &v4, &border_lp);
+ if (scale != 0) {
+ if (xz_projection || zx_projection) {
+ map3d_xyz(place, 0, Z_AXIS.max, &v3);
+ } else
+ map3d_xyz(place, other_end, base_z, &v3);
+ v4.x = v3.x - tic_unitx * scale * t->v_tic;
+ v4.y = v3.y - tic_unity * scale * t->v_tic;
+ v4.z = v3.z - tic_unitz * scale * t->v_tic;
+ v4.real_z = v3.real_z;
+ draw3d_line(&v3, &v4, &border_lp);
+ }
}
/* Draw tic label */
@@ -3255,25 +3259,29 @@ ytick_callback(
/* Draw left tic mark */
if ((this_axis->index == FIRST_Y_AXIS)
|| (this_axis->index == SECOND_Y_AXIS && (this_axis->ticmode & TICS_MIRROR))) {
- v2.x = v1.x + tic_unitx * scale * t->h_tic;
- v2.y = v1.y + tic_unity * scale * t->h_tic;
- v2.z = v1.z + tic_unitz * scale * t->h_tic;
- v2.real_z = v1.real_z;
- draw3d_line(&v1, &v2, &border_lp);
+ if (scale != 0) {
+ v2.x = v1.x + tic_unitx * scale * t->h_tic;
+ v2.y = v1.y + tic_unity * scale * t->h_tic;
+ v2.z = v1.z + tic_unitz * scale * t->h_tic;
+ v2.real_z = v1.real_z;
+ draw3d_line(&v1, &v2, &border_lp);
+ }
}
/* Draw right tic mark */
if ((this_axis->index == SECOND_Y_AXIS)
|| (this_axis->index == FIRST_Y_AXIS && (this_axis->ticmode & TICS_MIRROR))) {
- if (yz_projection)
- map3d_xyz(other_end, place, Z_AXIS.min, &v3);
- else
- map3d_xyz(other_end, place, base_z, &v3);
- v4.x = v3.x - tic_unitx * scale * t->h_tic;
- v4.y = v3.y - tic_unity * scale * t->h_tic;
- v4.z = v3.z - tic_unitz * scale * t->h_tic;
- v4.real_z = v3.real_z;
- draw3d_line(&v3, &v4, &border_lp);
+ if (scale != 0) {
+ if (yz_projection)
+ map3d_xyz(other_end, place, Z_AXIS.min, &v3);
+ else
+ map3d_xyz(other_end, place, base_z, &v3);
+ v4.x = v3.x - tic_unitx * scale * t->h_tic;
+ v4.y = v3.y - tic_unity * scale * t->h_tic;
+ v4.z = v3.z - tic_unitz * scale * t->h_tic;
+ v4.real_z = v3.real_z;
+ draw3d_line(&v3, &v4, &border_lp);
+ }
}
/* Draw tic label */
@@ -3432,18 +3440,20 @@ ztick_callback(
}
if (Z_AXIS.ticmode & TICS_MIRROR) {
- if (azimuth != 0) {
- v2.x = v3.x + (v1.x - v3.x) * len / xyscaler;
- v2.y = v3.y + (v1.y - v3.y) * len / xyscaler;
- v2.z = v3.z + (v1.z - v3.z) * len / xyscaler;
- draw3d_line(&v3, &v2, &border_lp);
- } else {
- map3d_xyz(right_x, right_y, place, &v1);
- v2.x = v1.x - len / (double)xscaler;
- v2.y = v1.y;
- v2.z = v1.z;
- v2.real_z = v1.real_z;
- draw3d_line(&v1, &v2, &border_lp);
+ if (len != 0) {
+ if (azimuth != 0) {
+ v2.x = v3.x + (v1.x - v3.x) * len / xyscaler;
+ v2.y = v3.y + (v1.y - v3.y) * len / xyscaler;
+ v2.z = v3.z + (v1.z - v3.z) * len / xyscaler;
+ draw3d_line(&v3, &v2, &border_lp);
+ } else {
+ map3d_xyz(right_x, right_y, place, &v1);
+ v2.x = v1.x - len / (double)xscaler;
+ v2.y = v1.y;
+ v2.z = v1.z;
+ v2.real_z = v1.real_z;
+ draw3d_line(&v1, &v2, &border_lp);
+ }
}
}
}
diff --git a/src/graphics.c b/src/graphics.c
index fda1035c8..28699329b 100644
--- a/src/graphics.c
+++ b/src/graphics.c
@@ -4477,7 +4477,7 @@ xtick2d_callback(
(*t->move) (x, tic_start);
(*t->vector) (x, tic_start + ticsize);
- if (tic_mirror >= 0) {
+ if ((tic_mirror >= 0) && (ticsize != 0)) {
(*t->move) (x, tic_mirror);
(*t->vector) (x, tic_mirror - ticsize);
}
@@ -4563,7 +4563,7 @@ ytick2d_callback(
(*t->move) (tic_start, y);
(*t->vector) (tic_start + ticsize, y);
- if (tic_mirror >= 0) {
+ if ((tic_mirror >= 0) && (ticsize != 0)) {
(*t->move) (tic_mirror, y);
(*t->vector) (tic_mirror - ticsize, y);
}
From a48c0e223d523dda1298b5065d627a9331f333d8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ulrich=20M=C3=BCller?=
Date: Sat, 3 Aug 2024 12:42:48 -0700
Subject: [PATCH 18/40] watchpoints demo plot 5 depends on HAVE_LIBCERF
Skip this plot if libcerf is not found during configuration
---
demo/watchpoints.dem | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/demo/watchpoints.dem b/demo/watchpoints.dem
index 3faa50819..2f23bead7 100644
--- a/demo/watchpoints.dem
+++ b/demo/watchpoints.dem
@@ -63,6 +63,12 @@ plot 'silver.dat' using 1:2 lw 2, '' using 1:($0+$3) lw 2, \
pause -1 " to continue"
reset
+
+if (!strstrt(GPVAL_COMPILE_OPTIONS, "+LIBCERF")) {
+ print "This copy of gnuplot does not support FresnelC, FresnelS"
+ exit;
+}
+
unset key
set title "Find y intercepts of a parametric function" offset 0,-1
set xrange [-0.1 : 0.9]
From 61786ea116636c905a2e503d09767b36568ca50c Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Wed, 7 Aug 2024 22:55:17 -0700
Subject: [PATCH 19/40] fixes for "splot with circles"
"splot with circles" should honor a per-plot fill style
"splot with circles" show allow "fillcolor palette z"
---
src/graph3d.c | 9 ++++++---
src/plot3d.c | 2 +-
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/src/graph3d.c b/src/graph3d.c
index fe6050b62..81e5c3907 100644
--- a/src/graph3d.c
+++ b/src/graph3d.c
@@ -2171,13 +2171,14 @@ plot3d_points(struct surface_points *plot)
/* We could dummy up circles as a point of type 7, but this way */
/* the radius can use x-axis coordinates rather than pointsize. */
- /* FIXME: track per-plot fillstyle */
+ /* FIXME: if no radius given, pull it from "set style circle". */
if (plot->plot_style == CIRCLES) {
+ struct fill_style_type *fillstyle = &plot->fill_properties;
double radius = point->CRD_PTSIZE * radius_scaler;
do_arc(x, y, radius, 0., 360.,
- style_from_fill(&default_fillstyle), FALSE);
+ style_from_fill(fillstyle), FALSE);
/* Retrace the border if the style requests it */
- if (need_fill_border(&default_fillstyle))
+ if (need_fill_border(fillstyle))
do_arc(x, y, radius, 0., 360., 0, FALSE);
continue;
}
@@ -4389,6 +4390,8 @@ check3d_for_variable_color(struct surface_points *plot, struct coordinate *point
set_rgbcolor_var( (unsigned int)point->CRD_COLOR );
break;
case TC_Z:
+ set_color( cb2gray(point->z) );
+ break;
case TC_DEFAULT: /* pm3d mode assumes this is default */
if (plot->pm3d_color_from_column)
set_color( cb2gray(point->CRD_COLOR) );
diff --git a/src/plot3d.c b/src/plot3d.c
index 0161b8800..b24b10d46 100644
--- a/src/plot3d.c
+++ b/src/plot3d.c
@@ -1166,7 +1166,7 @@ get_3ddata(struct surface_points *this_plot)
if (j < varcol)
int_error(NO_CARET, "Not enough input columns");
if (j == varcol)
- color = this_plot->fill_properties.border_color.lt;
+ color = z;
else
color = v[varcol];
color_from_column(TRUE);
From 2d17f4c83cb716c175c407247687b4350b8b8d70 Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Sun, 11 Aug 2024 17:54:43 -0700
Subject: [PATCH 20/40] Remove flag RANGE_WRITEBACK and associated code
Since version 5.2.4 (2018) every plot command sets flag
RANGE_WRITEBACK for all "true" axes (i.e. not T U V ...).
See commit 36a2407e
"Rework the refresh command to use autoscaled axis writeback/restore"
This fixed many problems with interactive refresh and replot,
but it made the commands "set ... [no]writeback" rather pointless.
Now we finally get around to removing the flag altogether since
it is essentially always in effect.
- Commands "set *range writeback" and "set *range nowriteback"
are now silently ignored.
- The complementary command "set *range restore" is retained.
---
docs/gnuplot.doc | 27 +++++++++------------------
src/axis.c | 17 +++++------------
src/axis.h | 5 ++---
src/plot2d.c | 9 ---------
src/plot3d.c | 9 ---------
src/save.c | 5 ++---
src/set.c | 15 +++++----------
7 files changed, 23 insertions(+), 64 deletions(-)
diff --git a/docs/gnuplot.doc b/docs/gnuplot.doc
index 536b26b19..67da5cab3 100644
--- a/docs/gnuplot.doc
+++ b/docs/gnuplot.doc
@@ -17287,7 +17287,6 @@ Ffigure_walls
?set xrange
?show xrange
?set range
-?writeback
?restore
?xrange
The `set xrange` command sets the horizontal range that will be displayed.
@@ -17295,7 +17294,7 @@ Ffigure_walls
polar radius r and the parametric variables t, u, and v.
Syntax:
- set xrange [{{}:{}}] {{no}reverse} {{no}writeback} {{no}extend}
+ set xrange [{{}:{}}] {{no}reverse} {{no}extend}
| restore
show xrange
@@ -17331,22 +17330,8 @@ Ffigure_walls
a limit on the range, to clip outliers, or to guarantee a minimum range
that will be displayed even if the data would not need such a big range.
- The `writeback` option essentially saves the range found by `autoscale` in
- the buffers that would be filled by `set xrange`. This is useful if you wish
- to plot several functions together but have the range determined by only
- some of them. The `writeback` operation is performed during the `plot`
- execution, so it must be specified before that command. To restore,
- the last saved horizontal range use `set xrange restore`. For example,
-
- set xrange [-10:10]
- set yrange [] writeback
- plot sin(x)
- set yrange restore
- replot x/2
-
- results in a yrange of [-1:1] as found only from the range of sin(x); the
- [-5:5] range of x/2 is ignored. Executing `show yrange` after each command
- in the above example should help you understand what is going on.
+ The command `set xrange restore` overwrites the current range min and max
+ with the values found during the most recent autoscaling operation.
In 2D, `xrange` and `yrange` determine the extent of the axes, `trange`
determines the range of the parametric variable in parametric mode or the
@@ -17408,6 +17393,12 @@ Ffigure_walls
?xrange extend
`set xrange noextend` is the same as `set autoscale x noextend`.
See `noextend`.
+4 writeback
+?set range writeback
+?set xrange writeback
+ The commands "set xrange writeback" and "set xrange nowriteback"
+ are retained for backward compatibility, but have had no effect
+ on plotting since gnuplot version 5.2.4.
3 xtics
?commands set xtics
?commands unset xtics
diff --git a/src/axis.c b/src/axis.c
index a2f69ec3b..512c14df3 100644
--- a/src/axis.c
+++ b/src/axis.c
@@ -2077,21 +2077,14 @@ tic_count_callback(struct axis *this_axis, double place, char *text,
axis_tic_count++;
}
-/*
- * get and set routines for range writeback
- * ULIG *
- */
-
void
save_writeback_all_axes()
{
- AXIS_INDEX axis;
-
- for (axis = 0; axis < AXIS_ARRAY_SIZE; axis++)
- if (axis_array[axis].range_flags & RANGE_WRITEBACK) {
- axis_array[axis].writeback_min = axis_array[axis].min;
- axis_array[axis].writeback_max = axis_array[axis].max;
- }
+ /* version 6.1 note: this used to only include NUMBER_OF_MAIN_VISIBLE_AXES */
+ for (AXIS_INDEX axis = 0; axis < AXIS_ARRAY_SIZE; axis++) {
+ axis_array[axis].writeback_min = axis_array[axis].min;
+ axis_array[axis].writeback_max = axis_array[axis].max;
+ }
}
void
diff --git a/src/axis.h b/src/axis.h
index 270d5ee60..403d2b425 100644
--- a/src/axis.h
+++ b/src/axis.h
@@ -185,9 +185,8 @@ typedef struct axis {
/* range of this axis */
t_autoscale autoscale; /* Which end(s) are autoscaled? */
t_autoscale set_autoscale; /* what does 'set' think autoscale to be? */
- int range_flags; /* flag bits about autoscale/writeback: */
- /* write auto-ed ranges back to variables for autoscale */
-#define RANGE_WRITEBACK 1
+ int range_flags; /* autoscale and range flag bits */
+#undef RANGE_WRITEBACK /* no longer used */
#define RANGE_SAMPLED 2
#define RANGE_IS_REVERSED 4
double min; /* 'transient' axis extremal values */
diff --git a/src/plot2d.c b/src/plot2d.c
index 0610a0971..7cecca2d2 100644
--- a/src/plot2d.c
+++ b/src/plot2d.c
@@ -240,15 +240,6 @@ plotrequest()
axis_init(&axis_array[POLAR_AXIS], TRUE);
axis_init(&axis_array[COLOR_AXIS], TRUE);
- /* Always be prepared to restore the autoscaled values on "refresh"
- * Dima Kogan April 2018
- */
- for (axis = 0; axis < NUMBER_OF_MAIN_VISIBLE_AXES; axis++) {
- AXIS *this_axis = &axis_array[axis];
- if (this_axis->set_autoscale != AUTOSCALE_NONE)
- this_axis->range_flags |= RANGE_WRITEBACK;
- }
-
/* Nonlinear mapping of x or y via linkage to a hidden primary axis. */
/* The user set autoscale for the visible axis; apply it also to the hidden axis. */
for (axis = 0; axis < NUMBER_OF_MAIN_VISIBLE_AXES; axis++) {
diff --git a/src/plot3d.c b/src/plot3d.c
index b24b10d46..b23f268fd 100644
--- a/src/plot3d.c
+++ b/src/plot3d.c
@@ -327,15 +327,6 @@ plot3drequest()
axis_init(&axis_array[SECOND_Y_AXIS], FALSE);
}
- /* Always be prepared to restore the autoscaled values on "refresh"
- * Dima Kogan April 2018
- */
- for (axis = 0; axis < NUMBER_OF_MAIN_VISIBLE_AXES; axis++) {
- AXIS *this_axis = &axis_array[axis];
- if (this_axis->set_autoscale != AUTOSCALE_NONE)
- this_axis->range_flags |= RANGE_WRITEBACK;
- }
-
/* Nonlinear mapping of x or y via linkage to a hidden primary axis. */
/* The user set autoscale for the visible axis; apply it also to the hidden axis. */
for (axis = 0; axis < NUMBER_OF_MAIN_VISIBLE_AXES; axis++) {
diff --git a/src/save.c b/src/save.c
index 35c84e497..43db01ee5 100644
--- a/src/save.c
+++ b/src/save.c
@@ -1436,9 +1436,8 @@ save_prange(FILE *fp, struct axis *this_axis)
}
if (this_axis->index < PARALLEL_AXES)
- fprintf(fp, " ] %sreverse %swriteback",
- ((this_axis->range_flags & RANGE_IS_REVERSED)) ? "" : "no",
- this_axis->range_flags & RANGE_WRITEBACK ? "" : "no");
+ fprintf(fp, " ] %sreverse",
+ ((this_axis->range_flags & RANGE_IS_REVERSED)) ? "" : "no");
else
fprintf(fp, " ] ");
diff --git a/src/set.c b/src/set.c
index 52dd08c63..310ed9e5c 100644
--- a/src/set.c
+++ b/src/set.c
@@ -5720,25 +5720,20 @@ set_range(struct axis *this_axis)
}
while (!END_OF_COMMAND) {
if (almost_equals(c_token, "rev$erse")) {
- ++c_token;
this_axis->range_flags |= RANGE_IS_REVERSED;
} else if (almost_equals(c_token, "norev$erse")) {
- ++c_token;
this_axis->range_flags &= ~RANGE_IS_REVERSED;
- } else if (almost_equals(c_token, "wr$iteback")) {
- ++c_token;
- this_axis->range_flags |= RANGE_WRITEBACK;
- } else if (almost_equals(c_token, "nowri$teback")) {
- ++c_token;
- this_axis->range_flags &= ~RANGE_WRITEBACK;
} else if (almost_equals(c_token, "ext$end")) {
- ++c_token;
this_axis->set_autoscale &= ~(AUTOSCALE_FIXMIN | AUTOSCALE_FIXMAX);
} else if (almost_equals(c_token, "noext$end")) {
- ++c_token;
this_axis->set_autoscale |= AUTOSCALE_FIXMIN | AUTOSCALE_FIXMAX;
+ } else if (almost_equals(c_token, "wr$iteback")) {
+ /* ignore */
+ } else if (almost_equals(c_token, "nowri$teback")) {
+ /* ignore */
} else
int_error(c_token,"unrecognized option");
+ ++c_token;
}
}
From c35add0c5e3687f4ca3cb95dae690bc2e6deabc2 Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Sun, 11 Aug 2024 20:58:39 -0700
Subject: [PATCH 21/40] remove "range nowriteback" from demo scripts
---
demo/animate2.dem | 4 ++--
demo/cerf.dem | 2 +-
demo/clip_radial.dem | 12 ++++++------
demo/expint.dem | 2 +-
demo/heatmap_4D.dem | 6 +++---
demo/hidden_compare.dem | 4 ++--
demo/invibeta.dem | 4 ++--
demo/piecewise.dem | 2 +-
demo/sampling.dem | 2 +-
demo/world2.dem | 6 +++---
demo/zeta.dem | 2 +-
11 files changed, 23 insertions(+), 23 deletions(-)
diff --git a/demo/animate2.dem b/demo/animate2.dem
index 5857d15a4..5e4b7f96f 100644
--- a/demo/animate2.dem
+++ b/demo/animate2.dem
@@ -28,8 +28,8 @@ set samples 64,64
set isosamples 13,13
set mapping spherical
set dummy u,v
-set urange [ -90.0000 : 90.0000 ] noreverse nowriteback
-set vrange [ 0.00000 : 360.000 ] noreverse nowriteback
+set urange [ -90.0000 : 90.0000 ]
+set vrange [ 0.00000 : 360.000 ]
set style data line
# Defines for gnuplot.rot script
diff --git a/demo/cerf.dem b/demo/cerf.dem
index 41c02d24f..94e380988 100644
--- a/demo/cerf.dem
+++ b/demo/cerf.dem
@@ -66,7 +66,7 @@ set vrange [ -3 : 3 ]
set tics scale 0
set cblabel "Phase Angle"
set cblabel offset character -2, 0, 0 font "" textcolor lt -1 rotate by -270
-set cbrange [ -pi : pi ] noreverse nowriteback
+set cbrange [ -pi : pi ]
set contour
set cntrparam levels discrete 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, 100, 200, 500
diff --git a/demo/clip_radial.dem b/demo/clip_radial.dem
index fdd128c67..ce29f8db4 100644
--- a/demo/clip_radial.dem
+++ b/demo/clip_radial.dem
@@ -15,9 +15,9 @@ set dummy t, y
set angles degrees
set raxis
set polar
-set rrange [ 0.00 : 0.60 ] noreverse nowriteback
-set xrange [ -1.00 : 1.00 ] noreverse nowriteback
-set yrange [ -1.00 : 1.00 ] noreverse nowriteback
+set rrange [ 0.00 : 0.60 ]
+set xrange [ -1.00 : 1.00 ]
+set yrange [ -1.00 : 1.00 ]
set border polar
set size square
#
@@ -28,9 +28,9 @@ unset clip radial
unset polar
plot $DATA using ($2*cos($1)):($2*sin($1)) lw 4 lc "yellow" notitle
set polar
-set rrange [ 0.00 : 0.60 ] noreverse nowriteback
-set xrange [ -1.00 : 1.00 ] noreverse nowriteback
-set yrange [ -1.00 : 1.00 ] noreverse nowriteback
+set rrange [ 0.00 : 0.60 ]
+set xrange [ -1.00 : 1.00 ]
+set yrange [ -1.00 : 1.00 ]
plot $DATA using 1:2:(sprintf("%d",$0)) with labels notitle
set clip radial
set key samplen 2
diff --git a/demo/expint.dem b/demo/expint.dem
index e074724b6..c9c5a4236 100644
--- a/demo/expint.dem
+++ b/demo/expint.dem
@@ -49,7 +49,7 @@ set ylabel "Imag(z)"
set zlabel "Abs(E_2(z))" rotate
set cblabel "Phase Angle"
set cblabel offset -1, 0, 0 rotate
-set cbrange [ -3.14159 : 3.14159 ] noreverse writeback
+set cbrange [ -3.14159 : 3.14159 ]
set pm3d corners2color c1
set palette color model HSV defined ( 0 0 1 1, 1 1 1 1 )
#
diff --git a/demo/heatmap_4D.dem b/demo/heatmap_4D.dem
index 82aa51e1b..c51ad2d3f 100644
--- a/demo/heatmap_4D.dem
+++ b/demo/heatmap_4D.dem
@@ -4,9 +4,9 @@
# This plot is nice for exploring the effect of the 'l' and 'L' hotkeys.
#
set view 49, 28, 1, 1.48
-set urange [ 5 : 35 ] noreverse nowriteback
-set vrange [ 5 : 35 ] noreverse nowriteback
-# set zrange [ 1.0 : 3.0 ] noreverse nowriteback
+set urange [ 5 : 35 ]
+set vrange [ 5 : 35 ]
+# set zrange [ 1.0 : 3.0 ]
set ticslevel 0
set format cb "%4.1f"
set colorbox user size .03, .6 noborder
diff --git a/demo/hidden_compare.dem b/demo/hidden_compare.dem
index 958bc31ec..61b1ed3ce 100644
--- a/demo/hidden_compare.dem
+++ b/demo/hidden_compare.dem
@@ -11,8 +11,8 @@ unset colorbox
set parametric
set dummy u,v
-set urange [ -3.14159 : 3.14159 ] noreverse nowriteback
-set vrange [ 0.250000 : 3.14159 ] noreverse nowriteback
+set urange [ -3.14159 : 3.14159 ]
+set vrange [ 0.250000 : 3.14159 ]
set isosamples 50, 20
set multiplot layout 1,2 margins .05,.95,.2,.8 spacing 0.05
diff --git a/demo/invibeta.dem b/demo/invibeta.dem
index 26f5722d8..24518f10d 100644
--- a/demo/invibeta.dem
+++ b/demo/invibeta.dem
@@ -17,9 +17,9 @@ set style data lines
set xyplane relative 0
set log z
set xlabel "a"
-set xrange [ 0.00000 : 0.200000 ] noreverse writeback
+set xrange [ 0.00000 : 0.200000 ]
set ylabel "b"
-set yrange [ 0.00000 : 0.200000 ] noreverse writeback
+set yrange [ 0.00000 : 0.200000 ]
set zlabel "Residual"
set zlabel offset character -2, 0, 0 font "" textcolor lt -1 rotate
diff --git a/demo/piecewise.dem b/demo/piecewise.dem
index 995b964cf..9db3ae13f 100644
--- a/demo/piecewise.dem
+++ b/demo/piecewise.dem
@@ -9,7 +9,7 @@ set xtics axis out scale 1,8
set xtics add (1.00000 1, 6.28319 1)
set ytics axis
set title "Piecewise function sampling" font ",15"
-set xrange [ -2 : 10 ] noreverse nowriteback
+set xrange [ -2 : 10 ]
plot sample [*:1] x, [1:2.*pi] cos(x), [2.*pi:10] (x-8)**2
diff --git a/demo/sampling.dem b/demo/sampling.dem
index 88b7ec516..c1863a21c 100644
--- a/demo/sampling.dem
+++ b/demo/sampling.dem
@@ -81,7 +81,7 @@ set yzeroaxis
set xtics axis out scale 1,8
set xtics add (1.00000 1, 6.28319 1)
set ytics axis
-set xrange [ .1 : 12 ] noreverse nowriteback
+set xrange [ .1 : 12 ]
diff --git a/demo/world2.dem b/demo/world2.dem
index 1b90cfca6..b56a13409 100644
--- a/demo/world2.dem
+++ b/demo/world2.dem
@@ -15,8 +15,8 @@ unset ytics
unset ztics
set border 0
set title "Labels colored by GeV plotted in spherical coordinate system"
-set urange [ -90.0000 : 90.0000 ] noreverse nowriteback
-set vrange [ 0.00000 : 360.000 ] noreverse nowriteback
+set urange [ -90.0000 : 90.0000 ]
+set vrange [ 0.00000 : 360.000 ]
set cblabel "GeV"
set cbrange [0:8]
set colorb vert user size 0.02, 0.75
@@ -29,4 +29,4 @@ set title "Labels with hidden line removal"
set hidden nooffset
replot
pause -1 "Hit return to continue"
-reset
\ No newline at end of file
+reset
diff --git a/demo/zeta.dem b/demo/zeta.dem
index 6c78a158e..6178a6b88 100644
--- a/demo/zeta.dem
+++ b/demo/zeta.dem
@@ -61,7 +61,7 @@ set key right opaque box samplen 0
set colorbox
set cblabel "Phase Angle"
set cblabel offset -1, 0, 0 rotate
-set cbrange [ -3.14159 : 3.14159 ] noreverse writeback
+set cbrange [ -3.14159 : 3.14159 ]
set cbtics ("-Ï€" -pi, "+Ï€" pi)
set pm3d interp 1,1 nolighting corners2color c1
set palette color model HSV defined ( 0 0 1 1, 1 1 1 1 )
From 69b18a3e52833bf7200d7b5b11ce88c52eebe747 Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Mon, 12 Aug 2024 09:56:52 -0700
Subject: [PATCH 22/40] Save $GPVAL_LAST_MULTIPLOT from "save" command
"save" has always dumped the most recent plot command at the end
of the output save file. Now if the most recent plot was a
multiplot we dump the entire content of $GPVAL_LAST_MULTIPLOT instead.
---
src/save.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/src/save.c b/src/save.c
index 43db01ee5..ee01e1424 100644
--- a/src/save.c
+++ b/src/save.c
@@ -35,6 +35,7 @@
#include "command.h"
#include "contour.h"
#include "datafile.h"
+#include "datablock.h"
#include "eval.h"
#include "filters.h"
#include "fit.h"
@@ -107,11 +108,22 @@ save_all(FILE *fp)
save_variables__sub(fp);
save_colormaps(fp);
save_pixmaps(fp);
- if (df_filename)
- fprintf(fp, "## Last datafile plotted: \"%s\"\n", df_filename);
- fprintf(fp, "%s\n", replot_line);
if (last_fit_command)
fprintf(fp, "## Last fit command: \"%s\"\n", last_fit_command);
+ if (df_filename)
+ fprintf(fp, "## Last datafile plotted: \"%s\"\n", df_filename);
+ if (last_plot_was_multiplot) {
+ char **line;
+ fprintf(fp, "## Last plot was a multiplot\n");
+ line = get_datablock("$GPVAL_LAST_MULTIPLOT");
+ while (line && *line) {
+ fprintf(fp, "%s\n", *line);
+ line++;
+ }
+ } else {
+ fprintf(fp, "## Last plot command\n");
+ fprintf(fp, "%s\n", replot_line);
+ }
fputs("# EOF\n", fp);
}
From 6c92f67b97a31c74b85651a49a671f28fcce95b7 Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Mon, 12 Aug 2024 15:02:20 -0700
Subject: [PATCH 23/40] some key title properties were not displayed by "show"
or "save"
Bug #2729
---
src/save.c | 23 ++++++++++++++++++-----
src/save.h | 1 +
src/show.c | 28 ++++++++--------------------
3 files changed, 27 insertions(+), 25 deletions(-)
diff --git a/src/save.c b/src/save.c
index ee01e1424..3e550d636 100644
--- a/src/save.c
+++ b/src/save.c
@@ -1144,6 +1144,22 @@ save_tics(FILE *fp, struct axis *this_axis)
}
+void
+save_keytitle(FILE *fp)
+{
+ legend_key *key = &keyT;
+
+ fprintf(fp, "\"%s\" ", conv_text(key->title.text));
+ fprintf(fp, "%s ", key->title.noenhanced ? "noenhanced" : "enhanced");
+ if (key->title.font && *(key->title.font))
+ fprintf(fp,"font \"%s\" ", key->title.font);
+ if (key->title.textcolor.type != TC_LT || key->title.textcolor.lt != LT_BLACK)
+ save_textcolor(fp, &key->title.textcolor);
+ fputs(" ", fp);
+ save_justification(key->title.pos, fp);
+ fputs("\n", fp);
+}
+
static void
save_key(FILE *fp)
{
@@ -1152,11 +1168,8 @@ save_key(FILE *fp)
if (key->title.text == NULL)
fprintf(fp, "set key notitle\n");
else {
- fprintf(fp, "set key title \"%s\"", conv_text(key->title.text));
- if (key->title.font)
- fprintf(fp, " font \"%s\" ", key->title.font);
- save_justification(key->title.pos, fp);
- fputs("\n", fp);
+ fprintf(fp, "set key title ");
+ save_keytitle(fp);
}
fputs("set key ", fp);
diff --git a/src/save.h b/src/save.h
index a9a87d6e0..f2f6f8b23 100644
--- a/src/save.h
+++ b/src/save.h
@@ -80,6 +80,7 @@ void save_axis_format(FILE *fp, AXIS_INDEX axis);
void save_bars(FILE *);
void save_array_content(FILE *, struct value *);
void save_label_style( FILE *fp, struct text_label *this_label );
+void save_keytitle(FILE *fp);
void save_contourfill(FILE *fp);
void save_marks(FILE *fp);
diff --git a/src/show.c b/src/show.c
index 27c89fcd8..70934efb7 100644
--- a/src/show.c
+++ b/src/show.c
@@ -108,7 +108,6 @@ static void show_raxis(void);
static void show_paxis(void);
static void show_zeroaxis(AXIS_INDEX);
static void show_label(int tag);
-static void show_keytitle(void);
static void show_key(void);
static void show_logscale(void);
static void show_offsets(void);
@@ -1915,22 +1914,6 @@ show_arrow(int tag)
int_error(c_token, "arrow not found");
}
-
-/* process 'show keytitle' command */
-static void
-show_keytitle()
-{
- legend_key *key = &keyT;
- SHOW_ALL_NL;
-
- fprintf(stderr, "\tkey title is \"%s\" ", conv_text(key->title.text));
- if (key->title.font && *(key->title.font))
- fprintf(stderr,"font \"%s\" ", key->title.font);
- show_text_justification(key->title.pos);
- fprintf(stderr,"\n");
-}
-
-
/* process 'show key' command */
static void
show_key()
@@ -2066,12 +2049,17 @@ show_key()
if (key->font && *(key->font))
fprintf(stderr,"\t font \"%s\"\n", key->font);
if (key->textcolor.type != TC_LT || key->textcolor.lt != LT_BLACK) {
- fputs("\t ", stderr);
+ fputs("\tentry", stderr);
save_textcolor(stderr, &(key->textcolor));
fputs("\n", stderr);
}
- show_keytitle();
+ if (key->title.text == NULL)
+ fprintf(stderr, "\n\tno key title\n");
+ else {
+ fprintf(stderr, "\n\tkey title is ");
+ save_keytitle(stderr);
+ }
}
@@ -3084,7 +3072,7 @@ show_xyzlabel(const char *name, const char *suffix, text_label *label)
else if (label->rotate)
fprintf(stderr, ", rotated by %g degrees in 2D plots", label->rotate);
- if (label->textcolor.type)
+ if (label->textcolor.type != TC_DEFAULT)
save_textcolor(stderr, &label->textcolor);
if (label->noenhanced)
From 5373a7956c732c9c6fb4a125a18d40dfe73c2c12 Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Tue, 13 Aug 2024 11:20:18 -0700
Subject: [PATCH 24/40] docs: Provide a list of features that are only in 6.1
gnuplot.doc: New section on development version
Splashpage and "gnuplot --version" for the development version
now report the last-modified date instead of a patchlevel.
---
docs/gnuplot.doc | 35 ++++++++++++++++++++++++++++++++++-
docs/titlepag.tex | 2 +-
src/plot.c | 5 +++--
src/show.c | 4 ++--
4 files changed, 40 insertions(+), 6 deletions(-)
diff --git a/docs/gnuplot.doc b/docs/gnuplot.doc
index 67da5cab3..19397096d 100644
--- a/docs/gnuplot.doc
+++ b/docs/gnuplot.doc
@@ -600,7 +600,6 @@ D epi_data 1
#end
2 Differences between versions 5 and 6
-
Some changes introduced in version 5 could cause certain scripts written
for earlier versions of gnuplot to fail or to behave differently.
There are very few such changes in version 6.
@@ -635,6 +634,40 @@ D epi_data 1
Deprecated in version 5.0, removed in 6.0
show palette fit2rgbformulae
+2 Development branch (version 6.1)
+?development
+ Version 6.0 is the most recent gnuplot stable release. Development of new
+ features and potentially disruptive code revision is carried out in a separate
+ branch that self-identifies as version 6.1. Since the development branch code
+ may change at any time, you should also check the "last modified" date
+ reported on startup or by `gnuplot --version`.
+
+ Here is a partial list of features under development that have not yet
+ appeared in a stable release. Items near the top of the list will probably
+ be back-ported to an incremental update to the current release (6.0.x).
+ This copy of the user manual has preliminary documentation for these.
+ Items near the bottom of the list may not appear in a stable release before
+ version 6.2.
+#start
+#b New plot mode "with hsteps".
+#b Revised implementation of local variables
+#b Blank line equivalent for binary data files, needed to support binary
+## input for plot styles that expect a blank line to separate data items
+#b "linestyle variable"
+#b pm3d coloring for 3D polygons (e.g. Delaunay tesselation of surfaces)
+#b splot with contourfill at base
+#b Filter input data to plot and splot through a conditional expression.
+## For example `plot DATA using 2:3 if (stringcolumn(1) eq "ABC")`
+#b New command `save changes` equivalent to the old contributed external script
+## `gpsavediff`
+#b Revised wxt terminal driver with more robust threading
+#b Alternatives to gdlib for handling image files as data
+#b Iteration over array contents `array A; for [e in A] { ... }`
+#b Deprecation of "sample" keyword
+#b New category of graphical objects called "marks" that allow definition
+## of complex symbols used in plots. No documentation or demos yet.
+#end
+
2 Demos and Online Examples
?demos
?online examples
diff --git a/docs/titlepag.tex b/docs/titlepag.tex
index 716501ea8..58c915c18 100644
--- a/docs/titlepag.tex
+++ b/docs/titlepag.tex
@@ -124,7 +124,7 @@
%
% Words that may get hyphenated oddly if TeX is allowed to do so
%
-\hyphenation{gnuplot windrose}
+\hyphenation{gnuplot windrose stringcolumn}
\uchyph=0
\begin{document}
diff --git a/src/plot.c b/src/plot.c
index ebfb8fe51..e41a9274b 100644
--- a/src/plot.c
+++ b/src/plot.c
@@ -335,8 +335,9 @@ main(int argc_orig, char **argv)
}
if (!strcmp(argv[i], "-V") || !strcmp(argv[i], "--version")) {
- printf("gnuplot %s patchlevel %s\n",
- gnuplot_version, gnuplot_patchlevel);
+ /* DEVELOPMENT VERSION */
+ printf("gnuplot %s last modified %s\n",
+ gnuplot_version, gnuplot_date);
return 0;
} else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
diff --git a/src/show.c b/src/show.c
index 70934efb7..092890aab 100644
--- a/src/show.c
+++ b/src/show.c
@@ -1123,7 +1123,7 @@ show_version(FILE *fp)
strcpy(fmt, "\
%s\n\
%s\t%s\n\
-%s\tVersion %s patchlevel %s last modified %s\n\
+%s\tVersion %s last modified %s\n\
%s\n\
%s\t%s\n\
%s\tThomas Williams, Colin Kelley and many others\n\
@@ -1141,7 +1141,7 @@ show_version(FILE *fp)
fprintf(fp, fmt,
p, /* empty line */
p, PROGRAM,
- p, gnuplot_version, gnuplot_patchlevel, gnuplot_date,
+ p, gnuplot_version, gnuplot_date,
p, /* empty line */
p, gnuplot_copyright,
p, /* authors */
From f34557951cd67694ad06f027d5b749eec472315e Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Tue, 13 Aug 2024 19:33:30 -0700
Subject: [PATCH 25/40] Documentation and fixes for iteration over array
elements
This is a fix for commit f8b5a883 that handles the case of array elements
that are undefined.
array A = [,,,1,2,3,,,,7,8,9]
do for [n in A] { ... }
Undefined elements are silently skipped.
Iteration over array elements is documented as EXPERIMENTAL.
---
docs/gnuplot.doc | 20 ++++++++++++++++----
src/parse.c | 32 ++++++++++++++++++++++++++------
2 files changed, 42 insertions(+), 10 deletions(-)
diff --git a/docs/gnuplot.doc b/docs/gnuplot.doc
index 19397096d..3b2d4fd66 100644
--- a/docs/gnuplot.doc
+++ b/docs/gnuplot.doc
@@ -3620,16 +3620,20 @@ Ffigure_newsyntax
Iteration is controlled by an iteration specifier with syntax
for [ in "string of N elements"]
-
- or
-
for [ = : { : }]
+ or
+ for [ in Array]
In the first case is a string variable that successively evaluates to
single-word substrings 1 to N of the string in the iteration specifier.
In the second case , , and are integers or integer
expressions.
+ In the third case is set to successive elements of the array regardless
+ of whether the element is a number or a string. Any undefined array elements
+ are silently skipperd. Iteration over array elements is EXPERIMENTAL
+ (details may change before it appears in a stable gnuplot release version.
+
=scope
The scope of the iteration variable is private to that iteration. See `scope`.
You cannot permanently change the value of the iteration variable inside the
@@ -7761,10 +7765,11 @@ Ffigure_zerror
multiple times, each time re-evaluating any expressions that make use of the
iteration control variable. Iteration of arbitrary command sequences can be
requested using the `do` command.
- Two forms of iteration clause are currently supported:
+ Three forms of iteration clause are currently supported:
for [intvar = start:end{:increment}]
for [stringvar in "A B C D"]
+ for [element in Array]
Examples:
@@ -7772,6 +7777,12 @@ Ffigure_zerror
plot for [basename in "A B C"] basename.".dat" using 1:2 with lines
set for [i = 1:10] style line i lc rgb "blue"
unset for [tag = 100:200] label tag
+ Array animals = ["dog", "cat", "mouse", "llama"]
+ do for [creature in animals] {
+ INFILE = creature.".dat"
+ OUTFILE = creature.".pdf"
+ plot INFILE with boxes title creature
+ }
Nested iteration is supported:
@@ -9830,6 +9841,7 @@ Ffigure_smooth_path
Syntax:
plot for [ = : {:}]
plot for [ in "string of words"]
+ plot for [ in Array]
The scope of an iteration ends at the next comma or the end of the command,
whichever comes first. An exception to this is that definitions are grouped
diff --git a/src/parse.c b/src/parse.c
index 5df3d85a4..52dfda7a5 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -1621,8 +1621,16 @@ check_for_iteration()
iteration_start = 1;
iteration_end = v.v.value_array[0].v.int_val;
free_value(&(iteration_udv->udv_value));
- iteration_udv->udv_value = v.v.value_array[1];
- clone_string_value(&(iteration_udv->udv_value));
+ if (iteration_end > 0) {
+ /* Skip to first non-empty entry slot */
+ while ((iteration_start <= iteration_end)
+ && (v.v.value_array[iteration_start].type == NOTDEFINED))
+ iteration_start++;
+ if (iteration_start <= iteration_end) {
+ iteration_udv->udv_value = v.v.value_array[iteration_start];
+ clone_string_value(&(iteration_udv->udv_value));
+ }
+ }
} else {
int_error(c_token-1, errormsg);
}
@@ -1707,8 +1715,16 @@ reevaluate_iteration_limits(t_iterator *iter)
iter->iteration_array = v;
iter->iteration_start = 1;
iter->iteration_end = v.v.value_array[0].v.int_val;
- iter->iteration_udv->udv_value = v.v.value_array[1];
- clone_string_value(&(iter->iteration_udv->udv_value));
+ if (iter->iteration_end > 0) {
+ /* Skip to first non-empty entry slot */
+ while ((iter->iteration_start <= iter->iteration_end)
+ && (v.v.value_array[iter->iteration_start].type == NOTDEFINED))
+ iter->iteration_start++;
+ if (iter->iteration_start <= iter->iteration_end) {
+ iter->iteration_udv->udv_value = v.v.value_array[iter->iteration_start];
+ clone_string_value(&(iter->iteration_udv->udv_value));
+ }
+ }
} else {
iter->iteration_start = real(&v);
}
@@ -1823,9 +1839,13 @@ next_iteration(t_iterator *iter)
Gstring(&(iter->iteration_udv->udv_value),
gp_word(iter->iteration_string, iter->iteration_current));
} else if (iter->iteration_array.type == ARRAY) {
+ struct value *array = iter->iteration_array.v.value_array;
+ /* Skip empty array entry slots */
+ while ((iter->iteration_current <= iter->iteration_end)
+ && (array[iter->iteration_current].type == NOTDEFINED))
+ iter->iteration_current++;
if (iter->iteration_current <= iter->iteration_end) {
- iter->iteration_udv->udv_value =
- iter->iteration_array.v.value_array[iter->iteration_current];
+ iter->iteration_udv->udv_value = array[iter->iteration_current];
clone_string_value(&(iter->iteration_udv->udv_value));
}
} else {
From 70d60361d4de7f193f6f77b3b120f6b6c600427c Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Wed, 14 Aug 2024 16:36:32 -0700
Subject: [PATCH 26/40] sanity check type of variable in "print $variable"
---
src/command.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/command.c b/src/command.c
index f985bf5a0..e1e3d44eb 100644
--- a/src/command.c
+++ b/src/command.c
@@ -2233,7 +2233,10 @@ print_command()
line = block->udv_value.v.functionblock.data_array;
} else
#endif /* USE_FUNCTIONBLOCKS */
+ if (block->udv_value.type == DATABLOCK)
line = block->udv_value.v.data_array;
+ else
+ int_error(c_token, "%s is not printable", datablock_name);
/* Printing a datablock into itself would cause infinite recursion */
if (print_out_var && !strcmp(datablock_name, print_out_name))
From 8150843680ca47d5dbfc2cf3433da29680591e6a Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Sun, 11 Aug 2024 11:22:23 -0700
Subject: [PATCH 27/40] New command "save changes "
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is an internal implementation of Petr MikulÃk's gpsavediff
utility script. The current output from "save" is compared to
the output from "save" run at the start of the session.
Only the changes are saved to the output file.
Output to a pipe is OK.
The two save files are opened by fp=tmpfile() and subsequently
accessed as "/dev/fd/".
Their content is piped through /usr/bin/diff and /usr/bin/sed
to generate the output stream.
The details of this method make it not suitable for Windows or OS2.
I have not tested on MacOS or any other non-linux systems.
Please report success or failure.
Example:
save datablocks "myplot.gp"
save changes "myplot.gp" append
...
reset session
load "myplot.gp"
Advantages:
The full "save" command produces about 200 lines of output and it can
be very hard to determine which lines are specifically relevant to
reproducing the final plot. The output from "save changes" is much
shorter and thus easier to understand and edit if necessary.
Disadvantages:
Since only the changes relative to the initial session state are saved,
loading the saved file without resetting the session may not duplicate
the saved plot. If you want to restore the full context independent of
the current session state, the complete output from "save" is better.
---
docs/gnuplot.doc | 14 +++++++++---
src/command.c | 6 +++++
src/plot.c | 15 ++++++++++++
src/save.c | 59 ++++++++++++++++++++++++++++++++++++++++++++----
src/save.h | 2 ++
src/tables.c | 1 +
src/tables.h | 2 +-
7 files changed, 91 insertions(+), 8 deletions(-)
diff --git a/docs/gnuplot.doc b/docs/gnuplot.doc
index 3b2d4fd66..923e9a4c2 100644
--- a/docs/gnuplot.doc
+++ b/docs/gnuplot.doc
@@ -10343,12 +10343,20 @@ Ffigure_smooth_path
save {functions | variables | terminal | set | fit | datablocks}
'' {append}
+ save changes '' {append}
+
If no option is specified, `gnuplot` saves functions, user variables,
`set` options and the most recent `plot` or `splot` command.
The current status of `set term` and `set output` is written as a comment.
-
- Saved files are written in text format and may be read by the
- `load` command.
+ The saved file contains a series of gnuplot commands in plain text that
+ can be used as input to the `load` command.
+
+ `save changes "savefile.gp"` writes out only those functions, variables,
+ and settings that are different from the program state at the start of the
+ gnuplot session. This makes for a much shorter output file that should still
+ be sufficient to allow `reset session; load "savefile.gp"` to recreate the
+ current plot and program state. This command is not supported on all systems;
+ it may not be available in your copy of gnuplot.
`save terminal` will write out just the `terminal` status, without
the comment marker in front of it. This is mainly useful for
diff --git a/src/command.c b/src/command.c
index e1e3d44eb..936005bd2 100644
--- a/src/command.c
+++ b/src/command.c
@@ -2511,6 +2511,7 @@ save_command()
FILE *fp;
char *save_file = NULL;
TBOOLEAN append = FALSE;
+ TBOOLEAN ispipe = FALSE;
int what;
c_token++;
@@ -2523,6 +2524,7 @@ save_command()
case SAVE_VARS:
case SAVE_FIT:
case SAVE_DATABLOCKS:
+ case SAVE_CHANGES:
case SAVE_MARKS:
c_token++;
break;
@@ -2541,6 +2543,7 @@ save_command()
if (save_file[0]=='|') {
restrict_popen();
fp = popen(save_file+1,"w");
+ ispipe = TRUE;
} else
#endif
{
@@ -2576,6 +2579,9 @@ save_command()
case SAVE_DATABLOCKS:
save_datablocks(fp);
break;
+ case SAVE_CHANGES:
+ save_changes(fp, ispipe);
+ break;
case SAVE_MARKS:
save_marks(fp);
break;
diff --git a/src/plot.c b/src/plot.c
index e41a9274b..ee92e11ae 100644
--- a/src/plot.c
+++ b/src/plot.c
@@ -48,6 +48,7 @@
#include "version.h"
#include "voxelgrid.h"
#include "encoding.h"
+#include "save.h"
#include "xdg.h"
#include
@@ -783,6 +784,20 @@ init_session()
load_rcfile(2); /* ~/.gnuplot */
load_rcfile(3); /* ~/.config/gnuplot/gnuplotrc */
+
+#if !defined(WIN32) && !defined(OS2) && !defined(MSDOS)
+ /* Save initial state variables to a file so that later
+ * "save changes" can use them to determine what has changed.
+ */
+ if (savefp == NULL) {
+ if (!(savefp = tmpfile()))
+ perror("Cannot open initial state save file");
+ else {
+ save_all(savefp);
+ fflush(savefp);
+ }
+ }
+#endif
}
/*
diff --git a/src/save.c b/src/save.c
index 3e550d636..a8bbfbb78 100644
--- a/src/save.c
+++ b/src/save.c
@@ -1621,11 +1621,11 @@ save_pm3dcolor(FILE *fp, const struct t_colorspec *tc)
if (tc->value < 0)
fprintf(fp," rgb variable ");
else if (*color)
- fprintf(fp," rgb \"%s\" ", color);
+ fprintf(fp," rgb \"%s\" ", color);
else
- fprintf(fp," rgb \"#%6.6x\" ", tc->lt);
+ fprintf(fp," rgb \"#%6.6x\" ", tc->lt);
break;
- }
+ }
default: break;
}
}
@@ -1974,7 +1974,7 @@ save_walls(FILE *fp)
int i;
for (i = 0; i < 5; i++) {
- this_object = &grid_wall[i];
+ this_object = &grid_wall[i];
if (this_object->layer == LAYER_FRONTBACK) {
fprintf(fp, "set wall %s ", wall_name[i]);
fprintf(fp, " fc ");
@@ -2073,6 +2073,57 @@ save_contourfill(FILE *fp)
fprintf(fp, "set contourfill palette\n");
}
+/* Internal implementation of contributed script "gpsavediff".
+ * Not supported on Windows because it shuffles output via
+ * /dev/fd/ a.k.a. /proc/self/fd
+ * to access the initial state that was saved to stream savefp=tmpfile()
+ * when the program was started and another tmpfile opened here.
+ * Also we depend on shell access to standard utilities diff and sed.
+ */
+FILE *savefp = NULL; /* tmpfile used by "save changes" */
+
+void
+save_changes(FILE *outfp, TBOOLEAN ispipe)
+{
+#if !defined(WIN32) && !defined(OS2) && !defined(MSDOS)
+ FILE *currentfp;
+ char command[1024];
+ char *output; /* text returned by do_system_func() */
+
+ /* Original state was saved to tmpfile savefp */
+ if (!savefp)
+ int_error(NO_CARET, "No reference file was saved at start of session");
+ rewind(savefp);
+
+ /* Save current state to tmpfile currentfp */
+ currentfp = tmpfile();
+ save_all(currentfp);
+ fflush(currentfp);
+ rewind(currentfp);
+
+ /* Compare current state to saved state */
+ if (ispipe)
+ sprintf(command,
+ "/usr/bin/diff -w /dev/fd/%d /dev/fd/%d | "
+ "/usr/bin/sed \"/^[^>]/d;s/^> //\"",
+ fileno(savefp), fileno(currentfp));
+ else
+ sprintf(command,
+ "/usr/bin/diff -w /dev/fd/%d /dev/fd/%d | "
+ "/usr/bin/sed \"/^[^>]/d;s/^> //\" >> /dev/fd/%d",
+ fileno(savefp), fileno(currentfp), fileno(outfp));
+ do_system_func(command, &output);
+
+ if (ispipe)
+ fputs(output, outfp);
+
+ /* Clean up */
+ fclose(currentfp);
+#else
+ int_warn(c_token, "This copy of gnuplot does not support 'save changes'");
+#endif
+}
+
void
save_marks(FILE *fp)
{
diff --git a/src/save.h b/src/save.h
index f2f6f8b23..d6129325c 100644
--- a/src/save.h
+++ b/src/save.h
@@ -44,6 +44,7 @@
/* Variables of save.c needed by other modules: */
extern const char *coord_msg[];
+extern FILE *savefp; /* tmpfile used by "save changes" */
/* Prototypes of functions exported by save.c */
void save_functions(FILE *fp);
@@ -82,6 +83,7 @@ void save_array_content(FILE *, struct value *);
void save_label_style( FILE *fp, struct text_label *this_label );
void save_keytitle(FILE *fp);
void save_contourfill(FILE *fp);
+void save_changes(FILE *fp, TBOOLEAN ispipe);
void save_marks(FILE *fp);
#endif /* GNUPLOT_SAVE_H */
diff --git a/src/tables.c b/src/tables.c
index 2205fdf2e..92102d2c7 100644
--- a/src/tables.c
+++ b/src/tables.c
@@ -167,6 +167,7 @@ const struct gen_table save_tbl[] =
{ "set", SAVE_SET },
{ "ter$minal", SAVE_TERMINAL },
{ "var$iables", SAVE_VARS },
+ { "change$s", SAVE_CHANGES },
{ NULL, SAVE_INVALID }
};
diff --git a/src/tables.h b/src/tables.h
index 3a22bc8d6..0943c07da 100644
--- a/src/tables.h
+++ b/src/tables.h
@@ -65,7 +65,7 @@ enum plot_axes_id {
/* options for 'save' command */
enum save_id { SAVE_INVALID, SAVE_FUNCS, SAVE_TERMINAL, SAVE_SET, SAVE_VARS,
- SAVE_FIT, SAVE_DATABLOCKS, SAVE_MARKS };
+ SAVE_FIT, SAVE_DATABLOCKS, SAVE_CHANGES, SAVE_MARKS };
/* options for 'show' and 'set' commands
* this is rather big, we might be better off with a hash table */
From e6facf21e157d3f329170fe4939d3860ab56b365 Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Mon, 19 Aug 2024 13:40:24 -0700
Subject: [PATCH 28/40] Allow filter "delaunay" in 3D plots
As with the 2D equivalent, this filter reads in a list of points
and replaces it internally with a list of triangles.
Probably "splot with polygons" is the only useful thing to do with this list.
splot FOO using 1:2:3 delaunay with polygons
---
src/filters.c | 71 +++++++++++++++++++++++++++++++++++++++++++--------
src/filters.h | 1 +
src/plot3d.c | 36 +++++++++++++++++++++++---
src/plot3d.h | 1 +
4 files changed, 96 insertions(+), 13 deletions(-)
diff --git a/src/filters.c b/src/filters.c
index 6794ca448..10c9d0cba 100644
--- a/src/filters.c
+++ b/src/filters.c
@@ -64,6 +64,7 @@
#include "alloc.h"
#include "datafile.h" /* for blank_data_line */
#include "plot2d.h" /* for cp_extend() */
+#include "plot3d.h" /* for iso_alloc() */
#include "watch.h" /* for bisect_target() */
/*
@@ -1282,8 +1283,9 @@ reset_hulls( TBOOLEAN reset )
void
delaunay_triangulation( struct curve_points *plot )
{
+ struct surface_points *plot3D = (struct surface_points *)plot;
struct coordinate *points;
- int N = plot->p_count;
+ int N;
t_edge *edges = NULL;
int nedges;
@@ -1295,18 +1297,27 @@ delaunay_triangulation( struct curve_points *plot )
/* Clear out any previous storage */
reset_hulls(FALSE);
- /* Pull color out of the varcolor array and copy it into point.CRD_COLOR
- * so that it isn't lost during sort.
+ /* This routine handles both 2D and 3D plots.
+ * For 2D plots we pull color information from the varcolor array
+ * and copy it into point.CRD_COLOR so that it isn't lost during sort.
*/
- if (plot->varcolor)
- for (i = 0; i < plot->p_count; i++)
- plot->points[i].CRD_COLOR = plot->varcolor[i];
+ if (plot->plot_type == DATA) {
+ points = plot->points;
+ N = plot->p_count;
+ if (plot->varcolor)
+ for (i = 0; i < plot->p_count; i++)
+ points[i].CRD_COLOR = plot->varcolor[i];
+ } else if (plot3D->plot_type == DATA3D) {
+ points = plot3D->iso_crvs[0].points;
+ N = plot3D->iso_crvs[0].p_count;
+ } else
+ return;
/* Sort the points on x.
* This allows us to reduce the time required from O(N^2) to
* approximately O(NlogN).
*/
- gp_qsort(plot->points, N, sizeof(struct coordinate), compare_xyz);
+ gp_qsort(points, N, sizeof(struct coordinate), compare_xyz);
/* Construct a triangle "sufficiently big" to enclose the set of points.
* That means each bounding vertex must be far enough away from the data
@@ -1319,8 +1330,12 @@ delaunay_triangulation( struct curve_points *plot )
double xdelta, ydelta, gap;
/* Allocate 4 additional points for the two triangles */
- cp_extend(plot, N+4);
- points = plot->points;
+ points = gp_realloc(points, (N+4)*sizeof(points[0]), "expanding 2D points");
+ if (plot->plot_type == DATA) {
+ plot->points = points;
+ } else {
+ plot3D->iso_crvs[0].points = points;
+ }
for (p = points; p < &points[N]; p++) {
if (p->type == UNDEFINED)
@@ -1464,7 +1479,7 @@ delaunay_triangulation( struct curve_points *plot )
edges[nedges].v2 = v2;
points[v1].extra = HULL_POINT;
points[v2].extra = HULL_POINT;
- edges[nedges].length = edge_length( &edges[nedges], plot->points );
+ edges[nedges].length = edge_length( &edges[nedges], points );
nedges++;
}
bounding_edges = edges;
@@ -1808,4 +1823,40 @@ save_delaunay_triangles( struct curve_points *plot )
plot->p_max = outp;
}
+/*
+ * 3D polygons are stored one polygon per iso_curve.
+ * On entry to this routine each triangle in the list of good_triangles
+ * lists the indices of its vertices stored in plot->iso_crvs[0].points.
+ * This routine breaks them out into one triangle per iso_curve.
+ */
+void
+save3d_delaunay_triangles( struct surface_points *plot )
+{
+ struct coordinate *point = plot->iso_crvs[0].points;
+
+ /* Clear first iso_curve */
+ if (plot->num_iso_read > 1)
+ fprintf(stderr, "Delaunay filter can only handle one data set per file (found %d)",
+ plot->num_iso_read);
+ free(plot->iso_crvs);
+ plot->iso_crvs = NULL;
+ plot->num_iso_read = 0;
+
+ for (triangle *t = good_triangles.next; t; t = t->next) {
+ struct iso_curve *new_iso = iso_alloc(4);
+ new_iso->p_count = 4;
+ new_iso->next = plot->iso_crvs;
+ plot->iso_crvs = new_iso;
+ plot->num_iso_read++;
+
+ new_iso->points[0] = point[t->v1];
+ new_iso->points[1] = point[t->v2];
+ new_iso->points[2] = point[t->v3];
+ new_iso->points[3] = point[t->v1];
+ }
+
+ /* We no longer need the original list of points */
+ free(point);
+}
+
#endif /* WITH_CHI_SHAPES */
diff --git a/src/filters.h b/src/filters.h
index 39cb5a2c6..ea0df899d 100644
--- a/src/filters.h
+++ b/src/filters.h
@@ -38,6 +38,7 @@ void sharpen(struct curve_points *plot);
#ifdef WITH_CHI_SHAPES
void delaunay_triangulation( struct curve_points *plot );
void save_delaunay_triangles( struct curve_points *plot );
+void save3d_delaunay_triangles( struct surface_points *plot );
void concave_hull( struct curve_points *plot );
void reset_hulls( TBOOLEAN reset );
diff --git a/src/plot3d.c b/src/plot3d.c
index b23f268fd..a069e0329 100644
--- a/src/plot3d.c
+++ b/src/plot3d.c
@@ -88,7 +88,6 @@ static void parametric_3dfixup(struct surface_points * start_plot, int *plot_num
static struct surface_points * sp_alloc(int num_samp_1, int num_iso_1, int num_samp_2, int num_iso_2);
static void sp_replace(struct surface_points *sp, int num_samp_1, int num_iso_1, int num_samp_2, int num_iso_2);
-static struct iso_curve * iso_alloc(int num);
static void iso_extend(struct iso_curve *ip, int num);
static void iso_free(struct iso_curve *ip);
@@ -244,7 +243,7 @@ sp_free(struct surface_points *sp)
* iso_alloc() allocates a iso_curve structure that can hold 'num'
* points.
*/
-static struct iso_curve *
+struct iso_curve *
iso_alloc(int num)
{
struct iso_curve *ip;
@@ -897,8 +896,12 @@ get_3ddata(struct surface_points *this_plot)
int_warn(NO_CARET, "Bad data on line %d of file %s",
df_line_number, df_filename ? df_filename : "");
- if (j == DF_SECOND_BLANK)
+ if (j == DF_SECOND_BLANK) {
+ if (this_plot->plot_filter == FILTER_DELAUNAY)
+ continue;
break; /* two blank lines */
+ }
+
if (j == DF_FIRST_BLANK) {
/* Images are in a sense similar to isocurves.
@@ -914,6 +917,14 @@ get_3ddata(struct surface_points *this_plot)
|| (this_plot->plot_style == RGBA_IMAGE))
continue;
+ /* The Delaunay triangulation filter will replace the input
+ * list of points with a set of iso_curves, one per triangle.
+ * It can only handle one list of input points, so ignore
+ * any blank lines. Selecting one set by "index n" still works.
+ */
+ if (this_plot->plot_filter == FILTER_DELAUNAY)
+ continue;
+
if (this_plot->plot_style == VECTOR)
continue;
@@ -1892,6 +1903,15 @@ eval_3dplots()
if (save_token != c_token)
continue;
+ /* filter options for splot */
+#ifdef WITH_CHI_SHAPES
+ if (equals(c_token, "delaunay")) {
+ this_plot->plot_filter = FILTER_DELAUNAY;
+ c_token++;
+ continue;
+ }
+#endif
+
/* smoothing options for splot */
if (equals(c_token, "smooth")) {
if (set_smooth)
@@ -2433,6 +2453,16 @@ eval_3dplots()
df_close();
+ /* Filter operations are performed immediately after
+ * reading in the data, before any smoothing.
+ */
+#ifdef WITH_CHI_SHAPES
+ if (this_plot->plot_filter == FILTER_DELAUNAY) {
+ delaunay_triangulation( (struct curve_points *)this_plot );
+ save3d_delaunay_triangles(this_plot);
+ }
+#endif
+
/* Plot-type specific range-fiddling */
if (!axis_array[FIRST_Z_AXIS].log
&& (this_plot->plot_style == IMPULSES
diff --git a/src/plot3d.h b/src/plot3d.h
index 71ffd4115..e5ceebd63 100644
--- a/src/plot3d.h
+++ b/src/plot3d.h
@@ -65,5 +65,6 @@ extern double boxdepth;
void plot3drequest(void);
void refresh_3dbounds(struct surface_points *first_plot, int nplots);
void sp_free(struct surface_points *sp);
+struct iso_curve *iso_alloc(int size);
#endif /* GNUPLOT_PLOT3D_H */
From b4b1fc1471d104a35ebea32552cfb07055e55a89 Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Mon, 19 Aug 2024 13:41:10 -0700
Subject: [PATCH 29/40] docs and demo for support of Delaunay triangulation
Delaunay triangulation was added as a filter operation used as a
first step in generating concave hulls. However the filter itself
has not been documented as a separate operation available to the user.
Modify the demo file "delaunay.dem" in the demo collection and refer
to it as an example in the user manual.
Still marked EXPERIMENTAL and depends on ./configure --enable-chi-shapes
---
demo/all.dem | 4 +++
demo/delaunay.dem | 19 +++++---------
demo/html/Makefile | 2 +-
docs/gnuplot.doc | 64 ++++++++++++++++++++++++++++++++++++----------
4 files changed, 63 insertions(+), 26 deletions(-)
diff --git a/demo/all.dem b/demo/all.dem
index af6f592ce..52b169e57 100644
--- a/demo/all.dem
+++ b/demo/all.dem
@@ -208,6 +208,10 @@ load "binary.dem"
load "binary_polygon.dem"
reset
+print "*********** 3D polygons from Delaunay tesselation ***********"
+load "delaunay.dem"
+reset
+
print "******************** hsteps demos ********************"
load "steps.dem"
load "hsteps.dem"
diff --git a/demo/delaunay.dem b/demo/delaunay.dem
index 868431475..3fcaf8519 100644
--- a/demo/delaunay.dem
+++ b/demo/delaunay.dem
@@ -1,23 +1,18 @@
#
-# The Delaunay triangulation filter is an undocumented adjunct to the
-# support for concave hulls. It may become a fully supported feature
-# after some cleanup, modifications to make it easier to use, and
-# documentation.
+# The Delaunay triangulation filter is an adjunct to the support for
+# concave hulls. It can be used on its own either for original use
+# in 2D plots or as a way to generate a triangular tesselation for
+# a 3D surface defined by a scattered set of points as shown here.
#
if (!strstrt(GPVAL_COMPILE_OPTIONS, "+CHI_SHAPES")) {
print "Your copy of gnuplot was not built with support for chi shapes"
} else {
- set table $hemisphere
- plot 'hemisphr.dat' using 1:2:3 delaunay with polygons
- unset table
-
- set pm3d lighting primary 0.5 spec 0.2 spec2 0.3
set pm3d border lc "black" lw 0.5
set palette viridis
set xyplane 0
set isotropic
- set view 60,127, 1.63
+ set view 60,127, 1.55
set border 15
set tics format ""
unset ztics
@@ -26,10 +21,10 @@ if (!strstrt(GPVAL_COMPILE_OPTIONS, "+CHI_SHAPES")) {
set multiplot layout 1,2
set pm3d lighting primary 0.5 spec 0.2 spec2 0.3
- splot $hemisphere with polygons title "pm3d lighting"
+ splot 'hemisphr.dat' using 1:2:3 delaunay with polygons title "pm3d lighting"
set pm3d nolighting
- splot $hemisphere with polygons title "no lighting model"
+ splot 'hemisphr.dat' using 1:2:3 delaunay with polygons title "no lighting model"
unset multiplot
}
diff --git a/demo/html/Makefile b/demo/html/Makefile
index 844c04f30..de44ca0cd 100644
--- a/demo/html/Makefile
+++ b/demo/html/Makefile
@@ -12,7 +12,7 @@ GNUPLOT_LIB = ..
# Several of the demos need manual intervention:
# fontfile vector epslatex
#
-html: airfoil.html animation.html approximate.html armillary.html array.html arrowstyle.html barchart_art.html binary.html bins.html bivariat.html boxplot.html boxclusters.html candlesticks.html chi_shapes.html circles.html cities.html columnhead.html contourfill.html contours.html convex_hull.html custom_contours.html controls.html custom_key.html dashtypes.html datastrings.html dgrid3d.html discrete.html electron.html ellipse.html enhanced_utf8.html epslatex.html errorbars.html fenceplot.html fillbetween.html fillcrvs.html fillstyle.html finance.html fit.html function_block.html hidden.html hidden2.html hidden_compare.html histograms.html histograms2.html histerror.html histogram_colors.html hsteps.html histeps_histogram.html gantt.html image.html image2.html imageNaN.html index.html iris.html iterate.html jitter.html keyentry.html label_stacked_histograms.html layout.html lines_arrows.html linkedaxes.html logic_timing.html map_projection.html margins.html mask_pm3d.html monotonic_spline.html multiaxis.html multiplt.html named_palettes.html nokey.html nonlinear1.html nonlinear2.html nonlinear3.html parallel.html param.html piecewise.html pixmap.html pm3dcolors.html pm3d.html pm3dgamma.html pm3d_clip.html pm3d_lighting.html pointsize.html polar.html polargrid.html poldat.html polar_quadrants.html polygons.html prob2.html prob.html projection.html rainbow.html random.html rank_sequence.html rectangle.html rgba_lines.html argb_hexdata.html rgb_variable.html rotate_labels.html rugplot.html running_avg.html sampling.html scatter.html simple.html singulr.html sectors.html sharpen.html spotlight.html smooth.html smooth_path.html solar_path.html spiderplot.html spline.html smooth_splines.html steps.html stringvar.html surface1.html surface2.html azimuth.html transparent.html transparent_solids.html textbox.html tics.html timedat.html ttics.html using.html varcolor.html vector.html violinplot.html walls.html world.html heatmaps.html heatmap_4D.html heatmap_points.html stats.html unicode.html viridis.html windrose.html zerror.html boxes3d.html voxel.html vplot.html isosurface.html
+html: airfoil.html animation.html approximate.html armillary.html array.html arrowstyle.html barchart_art.html binary.html bins.html bivariat.html boxplot.html boxclusters.html candlesticks.html chi_shapes.html circles.html cities.html columnhead.html concave_hull.html contourfill.html contours.html convex_hull.html custom_contours.html controls.html custom_key.html dashtypes.html datastrings.html dgrid3d.html discrete.html electron.html ellipse.html enhanced_utf8.html epslatex.html errorbars.html fenceplot.html fillbetween.html fillcrvs.html fillstyle.html finance.html fit.html function_block.html hidden.html hidden2.html hidden_compare.html histograms.html histograms2.html histerror.html histogram_colors.html hsteps.html histeps_histogram.html gantt.html image.html image2.html imageNaN.html index.html iris.html iterate.html jitter.html keyentry.html label_stacked_histograms.html layout.html lines_arrows.html linkedaxes.html logic_timing.html map_projection.html margins.html mask_pm3d.html monotonic_spline.html multiaxis.html multiplt.html named_palettes.html nokey.html nonlinear1.html nonlinear2.html nonlinear3.html parallel.html param.html piecewise.html pixmap.html pm3dcolors.html pm3d.html pm3dgamma.html pm3d_clip.html pm3d_lighting.html pointsize.html polar.html polargrid.html poldat.html polar_quadrants.html polygons.html prob2.html prob.html projection.html rainbow.html random.html rank_sequence.html rectangle.html rgba_lines.html argb_hexdata.html rgb_variable.html rotate_labels.html rugplot.html running_avg.html sampling.html scatter.html simple.html singulr.html sectors.html sharpen.html spotlight.html smooth.html smooth_path.html solar_path.html spiderplot.html spline.html smooth_splines.html steps.html stringvar.html surface1.html surface2.html azimuth.html transparent.html transparent_solids.html textbox.html tics.html timedat.html ttics.html using.html varcolor.html vector.html violinplot.html walls.html world.html heatmaps.html heatmap_4D.html heatmap_points.html stats.html unicode.html viridis.html windrose.html zerror.html boxes3d.html voxel.html vplot.html isosurface.html
index.html: index.save
cp index.save index.html
diff --git a/docs/gnuplot.doc b/docs/gnuplot.doc
index 923e9a4c2..e054331e6 100644
--- a/docs/gnuplot.doc
+++ b/docs/gnuplot.doc
@@ -649,21 +649,28 @@ D epi_data 1
Items near the bottom of the list may not appear in a stable release before
version 6.2.
#start
-#b New plot mode "with hsteps".
-#b Revised implementation of local variables
+#b New 2D plot style `with hsteps` allows construction of step-like plots with
+## a variety of representations in addition to those offered by existing styles
+## `steps`, `histeps`, `fsteps`, and `fillsteps`. See `hsteps`.
#b Blank line equivalent for binary data files, needed to support binary
-## input for plot styles that expect a blank line to separate data items
-#b "linestyle variable"
-#b pm3d coloring for 3D polygons (e.g. Delaunay tesselation of surfaces)
+## input for plot styles that expect a blank line to separate data items.
+## See `binary blank`.
+#b pm3d coloring for 3D polygons (e.g. Delaunay tesselation of surfaces).
+## See `delaunay`.
#b splot with contourfill at base
-#b Filter input data to plot and splot through a conditional expression.
-## For example `plot DATA using 2:3 if (stringcolumn(1) eq "ABC")`
+#b Revised implementation of local variables (faster, more well-defined scope).
+#b "linestyle variable"
+#b Filter input data to plot and splot through a conditional expression outside
+## the "using" section. For example:
+## `plot DATA using 2:3 with boxes if (stringcolumn(1) eq "ABC")`
#b New command `save changes` equivalent to the old contributed external script
-## `gpsavediff`
-#b Revised wxt terminal driver with more robust threading
+## `gpsavediff`. This command saves only the program settings, variables, and
+## functions that distinguish the current state from the program state at the
+## start of the current gnuplot session. See `save changes`.
+#b Revised wxt terminal driver with more robust threading and error recovery.
#b Alternatives to gdlib for handling image files as data
#b Iteration over array contents `array A; for [e in A] { ... }`
-#b Deprecation of "sample" keyword
+#b Deprecation of the "sample" keyword
#b New category of graphical objects called "marks" that allow definition
## of complex symbols used in plots. No documentation or demos yet.
#end
@@ -6197,7 +6204,8 @@ Ffigure_points
and larger polygons in 3D. These may be facets of a 3D surface or isolated
shapes. The code assumes that the vertices lie in a plane.
Vertices defining individual polygons are read from successive records of the
- input file. A blank line separates one polygon from the next.
+ input file. A blank line separates one polygon from the next. For the case
+ of binary input files, see `binary blank`.
The fill style and color may be specified in the splot command, otherwise the
global fillstyle from `set style fill` is used. Due to limitations in the
@@ -8634,8 +8642,8 @@ Ffigure_zerror
In general the purpose of a filter is to replace the original full set of
input points with a selected subset of points, possibly modified, regrouped,
or reordered,
- The filters currently supported are `bins`, `convexhull`, `concavehull`, `if`,
- `mask`, `sharpen`, and `zsort`.
+ The filters currently supported are `bins`, `convexhull`, `concavehull`,
+ `delaunay`, `if`, `mask`, `sharpen`, and `zsort`.
5 bins
?commands plot datafile filters bins
?plot datafile filters bins
@@ -8777,6 +8785,35 @@ Ffigure_concave_hull_2
points describing a closed curve that lies outside all of the original points.
It can be combined with `smooth path`.
+5 delaunay
+?commands plot datafile filters delaunay
+?plot datafile filters delaunay
+?plot filters delaunay
+?data-file filters delaunay
+?datafile filters delaunay
+?filters delaunay
+?delaunay
+
+ Delaunay triangulation subdivides a set of 2D points into sets of three points
+ such that no other point in the original set lies within the circumcircle of
+ the triangle that these three points define. It is implemented in gnuplot as
+ a filter operation that replaces the input set of points with a list of
+ triangles in the format expected by plot style "with polygons".
+ This filter is used as a first step in finding concave hulls using χ-shapes
+ (see `concavehull`). It may also be applied explicitly to a projection of a
+ set of 3D points onto the xy plane in order to create a tesselated 3D surface.
+
+ EXPERIMENTAL (implementation details may change in a future release).
+ Present only if your copy of gnuplot was configured --enable-chi-shapes.
+
+ 2D example
+ plot POINTS using 1:2 delaunay with polygons fs empty
+
+ 3D example
+ splot 'hemisphere.dat' using 1:2:3 delaunay with polygons
+D concave_hull 3
+D delaunay 1
+
5 mask
?commands plot datafile filters mask
?plot datafile filters mask
@@ -10339,6 +10376,7 @@ Ffigure_smooth_path
?save set
?save
?save fit
+?save changes
Syntax:
save {functions | variables | terminal | set | fit | datablocks}
'' {append}
From b712c99a6a9a9ba7ebc0c327e435fb7694b431c4 Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Thu, 8 Aug 2024 15:08:39 -0700
Subject: [PATCH 30/40] Implement "splot with filledcurves" as a varant of
zerrorfill
The primary motivation is to make it easy to create waterfall plots.
set style fill solid border lc "black"
splot for [scan=N:1:-1] DATA index scan \
using 1:2:3 with filledcurves fc background
Apart from being easier to explain than the 5-column zerror equivalent
this has the advantage of drawing only the curves, not a closed polygon
that connects the endpoints of each curve.
Note: I do not know why these are called "waterfall" plots.
I am familiar with them as a way to show the evolution of a signal
over time, or to compare spectra recorded sequentially as something
changes. They are similar to "fence" plots.
---
demo/all.dem | 1 +
demo/waterfallplot.dem | 45 ++++++++++++++++++++++++++
docs/gnuplot.doc | 71 +++++++++++++++++++++++++++++-------------
src/graph3d.c | 4 +--
src/plot3d.c | 15 +++++++--
5 files changed, 111 insertions(+), 25 deletions(-)
create mode 100644 demo/waterfallplot.dem
diff --git a/demo/all.dem b/demo/all.dem
index 52b169e57..ebbff5da7 100644
--- a/demo/all.dem
+++ b/demo/all.dem
@@ -26,6 +26,7 @@ reset
print "******************** file fillcvrs.dem ********************"
load "fillcrvs.dem"
load "fillbetween.dem"
+load "waterfallplot.dem"
reset
print "******************** file candlesticks.dem ********************"
diff --git a/demo/waterfallplot.dem b/demo/waterfallplot.dem
new file mode 100644
index 000000000..2b9a42df4
--- /dev/null
+++ b/demo/waterfallplot.dem
@@ -0,0 +1,45 @@
+# Waterfall plot created using plot style "splot with filledcurves"
+#
+# Note that scan lines must be plotted from back to front
+# in order for the depth-occlusion visual effect to work.
+#
+
+# Generate data
+Gauss(x,mu,sigma) = 1./(sigma*sqrt(2*pi)) * exp( -(x-mu)**2 / (2*sigma**2) )
+A(x) = Gauss(x, 0.2, 0.05)
+B(x) = 0.8 * Gauss(x, 0.2 + s, 0.03)
+C(x) = 0.1 * Gauss(x, 0.2 + 1.5*s, 0.02)
+
+set xrange [0.0:1.0]
+set sample 101
+
+set table $DATA
+s = 0.0
+do for [j=1:50] {
+ f = (75-j)/75.
+ F(x) = f * A(x) + (1-f) * B(x) + C(x)
+ plot F(x)
+ s = s + 0.005
+}
+unset table
+
+# set print "DATA"
+# print $DATA
+
+set title "Waterfall plot" offset 0,-5
+unset key
+set view 42, 27, 1, 1.2
+set xyplane at 0
+set xtics scale 0
+set ytics scale 0 10,10,50
+set xrange [0:0.9]
+set yrange [0:50]
+set zrange [ 0.0 : 15.0 ]
+set xlabel 'x'
+set ylabel 'scan'
+
+splot for [scan=48:2:-2] $DATA index scan \
+ using 1:(scan):2 with filledcurves lc "black" fc background
+
+pause -1 " to continue"
+reset
diff --git a/docs/gnuplot.doc b/docs/gnuplot.doc
index e054331e6..e9cdf1246 100644
--- a/docs/gnuplot.doc
+++ b/docs/gnuplot.doc
@@ -3729,7 +3729,7 @@ Ffigure_newsyntax
palette z
palette # use named colormap rather than current palette
variable # color index is read from input file
- bgnd # background color
+ background or bgnd # background color
black
The "" is the linetype number the color of which is used, see `test`.
@@ -3765,20 +3765,21 @@ Ffigure_newsyntax
from an extra column of data (not all 2D plot styles allow an extra column).
=bgnd
=black
- There are two special color specifiers: `bgnd` for background color and `black`.
+ There are two special color specifiers: `background` (short form `bgnd`)
+ for background color and `black`.
4 background color
?background
?bgnd
Most terminals allow you to set an explicit background color for the plot.
- The special linetype `bgnd` will draw in this color, and `bgnd` is also
- recognized as a color.
+ The special linetype `background` (short form `bgnd`) will draw in this color,
+ and is also recognized as a color name.
Examples:
# This will erase a section of the canvas by writing over it in the
# background color
set term wxt background rgb "gray75"
set object 1 rectangle from x0,y0 to x1,y1 fillstyle solid fillcolor bgnd
# Draw an "invisible" line at y=0, erasing whatever was underneath
- plot 0 lt bgnd
+ plot 0 lt background
4 linecolor variable
?linecolor variable
?linestyle variable
@@ -5209,13 +5210,16 @@ Ffigure_ellipses
?with filledcurves
?filledcurves
Ffigure_filledcurves
- The `filledcurves` style is only used for 2D plotting. It has three variants.
- The first two variants require either a single function or two columns (x,y)
- of input data, and may be further modified by the options listed below.
+ The `filledcurves` style is available in both 2D and (since version 6.1) 3D.
- Syntax:
+ The 2D style has three variants. The first two variants require either a
+ single function or two columns (x,y) of input data.
+
+ Syntax for 2D:
- plot ... with filledcurves [option]
+ plot f(x) with filledcurves [option]
+ plot DATA using 1:2 with filledcurves [option]
+ plot DATA using 1:2:3 with filledcurves [option]
where the option can be one of the following
@@ -5238,23 +5242,25 @@ Ffigure_filledcurves
filledcurves xy=10,20 ... point 10,20 of x1,y1 axes (arc-like shape).
filledcurves above r=1.5 the area of a polar plot outside radius 1.5
-Ffigure_yerrorfill
The third variant fills the area between two curves sampled at the same set of
x coordinates. It requires three columns of input data (x, y1, y2).
This is the default if there are three or more columns of input data.
+Ffigure_yerrorfill
If you have a y value in column 2 and an associated error value in column 3
- the area of uncertainty can be represented by shading.
+ the three column variant can be used in combination with a solid line to show
+ the area of uncertainty on either side of that line.
See also the similar 3D plot style `zerrorfill`.
- 3 columns: x y yerror
-
plot $DAT using 1:($2-$3):($2+$3) with filledcurves, \
$DAT using 1:2 smooth mcs with lines
+3 above/below
+?filledcurves above
+?filledcurves below
The `above` and `below` options apply both to commands of the form
- ... filledcurves above {x1|x2|y|r}=
+ plot f(x) with filledcurves {above|below} {y|r}=
and to commands of the form
- ... using 1:2:3 with filledcurves below
+ plot DATA with filledcurves using 1:2:3 with filledcurves {above|below}
In either case the option limits the filled area to one side of the bounding
line or curve.
@@ -5264,6 +5270,27 @@ Ffigure_yerrorfill
If the values , , or are outside the drawing boundary they are
moved to the graph boundary. Then the actual fill area in the case
of option xy=, will depend on xrange and yrange.
+
+3 3D waterfall plots
+?filledcurves 3D
+?filledcurves waterfall
+?waterfallplots
+ set style fill solid border lc "black"
+ splot for [scan=N:1:-1] DATA index scan \
+ using x:y:z with filledcurves fc background
+
+ In gnuplot 6.1 the 3D `filledcurves` plot style is designed to display a
+ set of two-dimensional curves that are incrementally displaced along an
+ orthogonal axis. Normally x or y is a fixed value for each curve so that
+ the lines either represent z=f(x) at sequential y values or z=f(y) at
+ sequential x values. This is convenient for drawing waterfall plots.
+
+ In order to ensure that foreground curves occlude more distant ones it is
+ important to order the sequence of curves from back to front.
+
+ See also `fenceplots`.
+D waterfallplot 1
+
3 fill properties
?filledcurves border
=border
@@ -6693,11 +6720,12 @@ Ffigure_zerror
If there are multiple curves in the splot command each new curve may occlude
all previous curves. To get proper depth sorting so that curves can only be
- occluded by curves closer to the viewer, use `set pm3d depthorder base`.
- Unfortunately this causes all the filled areas to be drawn after all of the
- corresponding lines of z values. In order to see both the lines and the
- depth-sorted fill areas you probably will need to make the fill areas
- partially transparent or use pattern fill rather than solid fill.
+ occluded by curves closer to the viewer, it is best to order the curves from
+ back to front. Alternatively you can use `set pm3d depthorder base` to sort
+ them automatically, but unfortunately this causes all the filled areas to be
+ drawn after all of the corresponding lines of z values. In order to see both
+ the lines and the depth-sorted fill areas you probably will need to make the
+ fill areas partially transparent.
The fill area in the first two examples below is the same.
@@ -6707,6 +6735,7 @@ Ffigure_zerror
splot for [k=1:5] datafile[k] with zerrorfill lt black fc lt (k+1)
This plot style can also be used to create fence plots. See `fenceplots`.
+ See also `waterfallplots`.
2 Animation
?animation
diff --git a/src/graph3d.c b/src/graph3d.c
index 81e5c3907..57b109dca 100644
--- a/src/graph3d.c
+++ b/src/graph3d.c
@@ -1196,7 +1196,6 @@ do_3dplot(
/* First draw the graph plot itself */
if (!key_pass && this_plot->plot_type != KEYENTRY && this_plot->plot_type != VOXELDATA)
switch (this_plot->plot_style) {
- case FILLEDCURVES: /* same, but maybe we could dummy up ZERRORFILL? */
case IMPULSES:
if (!hidden3d)
plot3d_impulses(this_plot);
@@ -1249,6 +1248,7 @@ do_3dplot(
break;
case ZERRORFILL:
+ case FILLEDCURVES:
if (term->filled_polygon)
plot3d_zerrorfill(this_plot);
term_apply_lp_properties(&(this_plot->lp_properties));
@@ -1362,7 +1362,6 @@ do_3dplot(
term_apply_lp_properties(&this_plot->lp_properties);
switch (this_plot->plot_style) {
- case FILLEDCURVES:
case IMPULSES:
if (!(hidden3d && draw_this_surface))
key_sample_line(xl, yl);
@@ -1441,6 +1440,7 @@ do_3dplot(
break;
case ZERRORFILL:
+ case FILLEDCURVES:
/* zerrorfill colors are weird (as in "backwards") */
apply_pm3dcolor(&this_plot->lp_properties.pm3d_color);
key_sample_fill(xl, yl, this_plot);
diff --git a/src/plot3d.c b/src/plot3d.c
index a069e0329..3b0b12365 100644
--- a/src/plot3d.c
+++ b/src/plot3d.c
@@ -1188,6 +1188,14 @@ get_3ddata(struct surface_points *this_plot)
color_from_column(FALSE);
}
+ } else if (this_plot->plot_style == FILLEDCURVES) {
+ if (j != 3)
+ int_error(NO_CARET, "this plot style wants 3 input columns x:y:z");
+ zlow = 0.0;
+ zhigh = v[2];
+ color_from_column(FALSE);
+ track_pm3d_quadrangles = TRUE;
+
} else if (this_plot->plot_style == ZERRORFILL) {
if (j == 4) {
zlow = v[2] - v[3];
@@ -1325,7 +1333,8 @@ get_3ddata(struct surface_points *this_plot)
this_plot->noautoscale,
cp->z=0;goto come_here_if_undefined);
- if (this_plot->plot_style == ZERRORFILL) {
+ if ((this_plot->plot_style == ZERRORFILL)
+ || (this_plot->plot_style == FILLEDCURVES)) {
STORE_AND_UPDATE_RANGE(cp->CRD_ZLOW, zlow, cp->type, z_axis,
this_plot->noautoscale, goto come_here_if_undefined);
STORE_AND_UPDATE_RANGE(cp->CRD_ZHIGH, zhigh, cp->type, z_axis,
@@ -2298,7 +2307,9 @@ eval_3dplots()
* ZERRORFILL and CONTOURFILL are weird.
*/
if ((this_plot->plot_style & PLOT_STYLE_HAS_FILL) && set_fillcolor) {
- if (this_plot->plot_style == ZERRORFILL || this_plot->plot_style == CONTOURFILL) {
+ if (this_plot->plot_style == ZERRORFILL
+ || this_plot->plot_style == FILLEDCURVES
+ || this_plot->plot_style == CONTOURFILL) {
this_plot->fill_properties.border_color = this_plot->lp_properties.pm3d_color;
this_plot->lp_properties.pm3d_color = fillcolor;
} else if (this_plot->plot_style == BOXES) {
From 38cea1a9a86643c5eddf9a2587b3cbb338297dd6 Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Wed, 21 Aug 2024 21:14:07 -0700
Subject: [PATCH 31/40] demos: clean up primary Makefile; add waterfallplot to
the web page
---
demo/html/Makefile | 34 ++++++++++++++++++++++++++++++-
demo/html/Makefile.svg | 2 +-
demo/html/index.6new | 3 ++-
demo/html/index.special_functions | 3 ++-
demo/html/index.svg | 3 ++-
5 files changed, 40 insertions(+), 5 deletions(-)
diff --git a/demo/html/Makefile b/demo/html/Makefile
index de44ca0cd..8c919c672 100644
--- a/demo/html/Makefile
+++ b/demo/html/Makefile
@@ -12,7 +12,39 @@ GNUPLOT_LIB = ..
# Several of the demos need manual intervention:
# fontfile vector epslatex
#
-html: airfoil.html animation.html approximate.html armillary.html array.html arrowstyle.html barchart_art.html binary.html bins.html bivariat.html boxplot.html boxclusters.html candlesticks.html chi_shapes.html circles.html cities.html columnhead.html concave_hull.html contourfill.html contours.html convex_hull.html custom_contours.html controls.html custom_key.html dashtypes.html datastrings.html dgrid3d.html discrete.html electron.html ellipse.html enhanced_utf8.html epslatex.html errorbars.html fenceplot.html fillbetween.html fillcrvs.html fillstyle.html finance.html fit.html function_block.html hidden.html hidden2.html hidden_compare.html histograms.html histograms2.html histerror.html histogram_colors.html hsteps.html histeps_histogram.html gantt.html image.html image2.html imageNaN.html index.html iris.html iterate.html jitter.html keyentry.html label_stacked_histograms.html layout.html lines_arrows.html linkedaxes.html logic_timing.html map_projection.html margins.html mask_pm3d.html monotonic_spline.html multiaxis.html multiplt.html named_palettes.html nokey.html nonlinear1.html nonlinear2.html nonlinear3.html parallel.html param.html piecewise.html pixmap.html pm3dcolors.html pm3d.html pm3dgamma.html pm3d_clip.html pm3d_lighting.html pointsize.html polar.html polargrid.html poldat.html polar_quadrants.html polygons.html prob2.html prob.html projection.html rainbow.html random.html rank_sequence.html rectangle.html rgba_lines.html argb_hexdata.html rgb_variable.html rotate_labels.html rugplot.html running_avg.html sampling.html scatter.html simple.html singulr.html sectors.html sharpen.html spotlight.html smooth.html smooth_path.html solar_path.html spiderplot.html spline.html smooth_splines.html steps.html stringvar.html surface1.html surface2.html azimuth.html transparent.html transparent_solids.html textbox.html tics.html timedat.html ttics.html using.html varcolor.html vector.html violinplot.html walls.html world.html heatmaps.html heatmap_4D.html heatmap_points.html stats.html unicode.html viridis.html windrose.html zerror.html boxes3d.html voxel.html vplot.html isosurface.html
+html: airfoil.html animation.html approximate.html armillary.html array.html arrowstyle.html \
+ barchart_art.html binary.html bins.html bivariat.html boxplot.html boxclusters.html \
+ candlesticks.html chi_shapes.html circles.html cities.html columnhead.html \
+ concave_hull.html contourfill.html contours.html convex_hull.html \
+ custom_contours.html controls.html custom_key.html \
+ dashtypes.html datastrings.html dgrid3d.html delaunay.html discrete.html \
+ electron.html ellipse.html enhanced_utf8.html epslatex.html errorbars.html \
+ fenceplot.html fillbetween.html fillcrvs.html fillstyle.html finance.html \
+ fit.html function_block.html gantt.html \
+ heatmaps.html heatmap_4D.html heatmap_points.html \
+ hidden.html hidden2.html hidden_compare.html histograms.html histograms2.html \
+ histerror.html histogram_colors.html hsteps.html hsteps_histogram.html \
+ image.html image2.html imageNaN.html index.html iris.html iterate.html \
+ jitter.html keyentry.html label_stacked_histograms.html layout.html \
+ lines_arrows.html linkedaxes.html logic_timing.html \
+ map_projection.html margins.html mask_pm3d.html monotonic_spline.html \
+ multiaxis.html multiplt.html \
+ named_palettes.html nokey.html nonlinear1.html nonlinear2.html nonlinear3.html \
+ parallel.html param.html piecewise.html pixmap.html pm3dcolors.html pm3d.html \
+ pm3dgamma.html pm3d_clip.html pm3d_lighting.html pointsize.html polar.html \
+ polargrid.html poldat.html polar_quadrants.html polygons.html prob2.html \
+ prob.html projection.html \
+ rainbow.html random.html rank_sequence.html rectangle.html rgba_lines.html \
+ argb_hexdata.html rgb_variable.html rotate_labels.html rugplot.html running_avg.html \
+ sampling.html scatter.html simple.html singulr.html sectors.html sharpen.html \
+ spotlight.html smooth.html smooth_path.html solar_path.html spiderplot.html \
+ spline.html smooth_splines.html steps.html stringvar.html stats.html \
+ surface1.html surface2.html \
+ transparent.html transparent_solids.html textbox.html tics.html timedat.html ttics.html \
+ unicode.html using.html \
+ varcolor.html vector.html violinplot.html viridis.html voxel.html vplot.html \
+ walls.html waterfallplot.html windrose.html world.html zerror.html \
+ isosurface.html azimuth.html boxes3d.html
index.html: index.save
cp index.save index.html
diff --git a/demo/html/Makefile.svg b/demo/html/Makefile.svg
index aef8abd8e..e93ad5ef0 100644
--- a/demo/html/Makefile.svg
+++ b/demo/html/Makefile.svg
@@ -9,7 +9,7 @@ GNUPLOT_LIB = ..
#
# Auto-generation of the svg demo set.
#
-html: airfoil.html approximate.html armillary.html array.html barchart_art.html binary.html bins.html bivariat.html boxplot.html boxclusters.html candlesticks.html cerf.html chi_shapes.html circles.html cities.html columnhead.html contourfill.html contours.html custom_contours.html controls.html convex_hull.html custom_key.html dashtypes.html datastrings.html discrete.html electron.html enhanced_utf8.html errorbars.html fenceplot.html fillbetween.html fillcrvs.html fillstyle.html finance.html hidden.html hidden2.html hidden_compare.html histograms.html histograms2.html histerror.html histogram_colors.html hsteps.html hsteps_histogram.html hypertext.html hypertext_surface.html gantt.html imageNaN.html index.html iris.html iterate.html jitter.html keyentry.html label_stacked_histograms.html layout.html lines_arrows.html linkedaxes.html logic_timing.html map_projection.html margins.html mask_pm3d.html monotonic_spline.html multiaxis.html multiplt.html nonlinear1.html nonlinear2.html nonlinear3.html named_palettes.html nokey.html parallel.html param.html piecewise.html pixmap.html pm3dcolors.html pm3d.html pm3d_clip.html pm3d_lighting.html pointsize.html polar.html polargrid.html poldat.html polar_quadrants.html polygons.html prob2.html prob.html rainbow.html random.html rank_sequence.html rectangle.html rgba_lines.html argb_hexdata.html rgb_variable.html rotate_labels.html rugplot.html running_avg.html sampling.html scatter.html simple.html singulr.html sectors.html sharpen.html smooth.html smooth_path.html smooth_splines.html spiderplot.html spline.html solar_path.html steps.html stringvar.html surface1.html surface2.html azimuth.html projection.html textbox.html transparent.html transparent_solids.html tics.html timedat.html ttics.html using.html varcolor.html vector.html violinplot.html walls.html world.html heatmaps.html heatmap_4D.html heatmap_points.html ellipse.html stats.html unicode.html windrose.html zerror.html boxes3d.html
+html: airfoil.html approximate.html armillary.html array.html barchart_art.html binary.html bins.html bivariat.html boxplot.html boxclusters.html candlesticks.html cerf.html chi_shapes.html circles.html cities.html columnhead.html contourfill.html contours.html custom_contours.html controls.html convex_hull.html custom_key.html dashtypes.html datastrings.html discrete.html electron.html enhanced_utf8.html errorbars.html fenceplot.html fillbetween.html fillcrvs.html fillstyle.html finance.html hidden.html hidden2.html hidden_compare.html histograms.html histograms2.html histerror.html histogram_colors.html hsteps.html hsteps_histogram.html hypertext.html hypertext_surface.html gantt.html imageNaN.html index.html iris.html iterate.html jitter.html keyentry.html label_stacked_histograms.html layout.html lines_arrows.html linkedaxes.html logic_timing.html map_projection.html margins.html mask_pm3d.html monotonic_spline.html multiaxis.html multiplt.html nonlinear1.html nonlinear2.html nonlinear3.html named_palettes.html nokey.html parallel.html param.html piecewise.html pixmap.html pm3dcolors.html pm3d.html pm3d_clip.html pm3d_lighting.html pointsize.html polar.html polargrid.html poldat.html polar_quadrants.html polygons.html prob2.html prob.html rainbow.html random.html rank_sequence.html rectangle.html rgba_lines.html argb_hexdata.html rgb_variable.html rotate_labels.html rugplot.html running_avg.html sampling.html scatter.html simple.html singulr.html sectors.html sharpen.html smooth.html smooth_path.html smooth_splines.html spiderplot.html spline.html solar_path.html steps.html stringvar.html surface1.html surface2.html azimuth.html projection.html textbox.html transparent.html transparent_solids.html tics.html timedat.html ttics.html using.html varcolor.html vector.html violinplot.html walls.html world.html heatmaps.html heatmap_4D.html heatmap_points.html ellipse.html stats.html unicode.html windrose.html zerror.html boxes3d.html waterfallplot.html
index.html: index.svg
cp index.svg index.html
diff --git a/demo/html/index.6new b/demo/html/index.6new
index 7075d5743..18a6770e6 100644
--- a/demo/html/index.6new
+++ b/demo/html/index.6new
@@ -194,6 +194,7 @@
- This page generated August 2023
+ This page generated August 2024
From 7ab7aff41a58eaba5374d55896727b2bc56b36de Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Mon, 19 Aug 2024 23:17:22 -0700
Subject: [PATCH 32/40] move check for "palette " from lp_parse
to parse_colorspec
This potentailly catches more circumstances where a named palette
might be requested.
At this time most of the relevant places go through lp_parse anyhow,
which in turn calls parse_colorspec. So the actual benefit will
come later when we make more of a distinction between "line properties"
and "[fill] color".
---
src/misc.c | 36 ++++++++++++++++++++----------------
src/plot2d.c | 2 ++
src/plot3d.c | 4 ++++
3 files changed, 26 insertions(+), 16 deletions(-)
diff --git a/src/misc.c b/src/misc.c
index 574e92faa..25b970c11 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -975,9 +975,11 @@ parse_dashtype(struct t_dashtype *dt)
}
/*
- * destination_class tells us whether we are filling in a line style ('set style line'),
- * a persistent linetype ('set linetype') or an ad hoc set of properties for a single
- * use ('plot ... lc foo lw baz').
+ * destination_class tells the purpose of this call
+ * LP_TYPE - a persistent linetype ('set linetype')
+ * LP_STYLE - ('set style line')
+ * LP_ADHOC - properties for a single use ('plot ... lc foo lw baz').
+ * LP_NOFILL - caller is expecting a line color, so ignore "fc" or "fillcolor"
* allow_point controls whether we accept a point attribute in this lp_style.
*/
int
@@ -1070,11 +1072,11 @@ lp_parse(struct lp_style_type *lp, lp_class destination_class, TBOOLEAN allow_po
* fc colorspec as a line property. We need to parse it later as a
* _fill_ property. Also prevents "plot ... fc fs lw "
* from generating an error claiming redundant line properties.
+ * FIXME: Why exclude "fc palette"??
*/
if ((destination_class == LP_NOFILL || destination_class == LP_ADHOC)
- && (equals(c_token,"fc") || almost_equals(c_token,"fillc$olor"))
&& (!almost_equals(c_token+1, "pal$ette"))
- && (!almost_equals(c_token+1, "var$iable")) ) {
+ && (equals(c_token,"fc") || almost_equals(c_token,"fillc$olor"))) {
FPRINTF((stderr, "ignoring 'fc' request\n"));
break;
}
@@ -1090,18 +1092,11 @@ lp_parse(struct lp_style_type *lp, lp_class destination_class, TBOOLEAN allow_po
c_token--;
parse_colorspec(&(newlp.pm3d_color), TC_RGB);
} else if (almost_equals(c_token, "pal$ette")) {
- /* The next word could be any of {z|cb|frac|}.
- * Check first for a colormap name.
- */
- udvt_entry *colormap = get_colormap(c_token+1);
- if (colormap) {
- newlp.pm3d_color.type = TC_COLORMAP;
- newlp.colormap = colormap;
+ c_token--;
+ parse_colorspec(&(newlp.pm3d_color), TC_Z);
+ if (newlp.pm3d_color.type == TC_COLORMAP) {
+ newlp.colormap = get_colormap(c_token++);
set_colormap++;
- c_token += 2;
- } else {
- c_token--;
- parse_colorspec(&(newlp.pm3d_color), TC_Z);
}
} else if (equals(c_token,"bgnd") || equals(c_token,"background")) {
newlp.pm3d_color.type = TC_LT;
@@ -1463,7 +1458,16 @@ parse_colorspec(struct t_colorspec *tc, int options)
tc->lt = parse_color_name();
}
} else if (almost_equals(c_token,"pal$ette")) {
+ /* The next word could be any of {z|cb|frac|}.
+ * Check first for a colormap name.
+ * Caveat: we only set the type here; the caller will have to
+ * re-read the colormap name.
+ */
c_token++;
+ if (get_colormap(c_token)) {
+ tc->type = TC_COLORMAP;
+ return;
+ }
if (equals(c_token,"z")) {
/* The actual z value is not yet known, fill it in later */
if (options >= TC_Z) {
diff --git a/src/plot2d.c b/src/plot2d.c
index 7cecca2d2..fdf7d9326 100644
--- a/src/plot2d.c
+++ b/src/plot2d.c
@@ -2990,6 +2990,8 @@ eval_plots()
}
if (equals(c_token,"fc") || almost_equals(c_token,"fillc$olor")) {
parse_colorspec(&fillcolor, TC_VARIABLE);
+ if (fillcolor.type == TC_COLORMAP)
+ this_plot->lp_properties.colormap = get_colormap(c_token++);
set_fillcolor = TRUE;
if (fillcolor.type == TC_VARIABLE) {
this_plot->lp_properties.l_type = LT_COLORFROMCOLUMN;
diff --git a/src/plot3d.c b/src/plot3d.c
index 3b0b12365..809752022 100644
--- a/src/plot3d.c
+++ b/src/plot3d.c
@@ -2202,6 +2202,10 @@ eval_3dplots()
this_plot->fill_properties.border_color.type = TC_DEFAULT;
if (equals(c_token,"fc") || almost_equals(c_token,"fillc$olor")) {
parse_colorspec(&fillcolor, TC_RGB);
+ /* FIXME: can't happen because we limited the options to TC_RGB
+ if (fillcolor.type == TC_COLORMAP)
+ this_plot->lp_properties.colormap = get_colormap(c_token++);
+ */
set_fillstyle = TRUE;
set_fillcolor = TRUE;
}
From 4bdea1636da8863d7725ecf7e9371f0b42d11487 Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Fri, 16 Aug 2024 14:14:41 -0700
Subject: [PATCH 33/40] 3D polygon objects can have individual border color and
linewidth
Previously all 3D polygon objects shared the properties from "set pm3d".
This limitation has been documented as an implementation glitch to be
removed at some point. Now it is partially relaxed.
The border linewidth and color for 3D polygon objects is now taken from
the values given in "set object".
The polygons demo is changed accordingly to set the border linewidth
and color via "set object".
"splot with polygons" is not affected by this commit.
These polygons still use the border properties from "set pm3d".
---
demo/polygons.dem | 7 +++++--
docs/gnuplot.doc | 17 ++++++++++++++---
src/graphics.c | 17 ++++++++++++++---
src/pm3d.c | 11 ++++++++++-
4 files changed, 43 insertions(+), 9 deletions(-)
diff --git a/demo/polygons.dem b/demo/polygons.dem
index bd358bef4..0f6b7eb0b 100644
--- a/demo/polygons.dem
+++ b/demo/polygons.dem
@@ -61,8 +61,11 @@ do for [i=1:5] {
eval( sprintf("set obj %d polygon from v9[1], v9[2], v9[3] to v3[1],v3[2],v3[3] to v6[1],v6[2],v6[3]", n) )
n = n+1
-set for [o=1:n] obj o polygon depthorder fs transparent solid 0.8 fc "gray75"
-set pm3d depthorder border lc "black" lw 2
+# border color and linewidth is now per-object rather than taken from pm3d
+set for [o=1:n] obj o polygon depthorder fc "gray75"
+set for [o=1:n] obj o polygon fs transparent solid 0.8 border lc "black" lw 2.0
+
+set pm3d depthorder border lc "black" lw 2 # old version
set xrange [-2:2]; set yrange [-2:2]; set zrange [-2:2]
set view equal xyz
diff --git a/docs/gnuplot.doc b/docs/gnuplot.doc
index e9cdf1246..5173e7e73 100644
--- a/docs/gnuplot.doc
+++ b/docs/gnuplot.doc
@@ -655,6 +655,12 @@ D epi_data 1
#b Blank line equivalent for binary data files, needed to support binary
## input for plot styles that expect a blank line to separate data items.
## See `binary blank`.
+#b In previous gnuplot versions all 3D polygons shared a single border color
+## and linewidth taken from "set pm3d". Now individual 3D polygon objects take
+## their fill border and line width from "set object".
+#b splot with contourfill at base
+#b Revised implementation of local variables (faster, more well-defined scope).
+#b "linestyle variable"
#b pm3d coloring for 3D polygons (e.g. Delaunay tesselation of surfaces).
## See `delaunay`.
#b splot with contourfill at base
@@ -6237,8 +6243,8 @@ Ffigure_points
The fill style and color may be specified in the splot command, otherwise the
global fillstyle from `set style fill` is used. Due to limitations in the
pm3d code, a single border line style from `set pm3d border` is applied to all
- 3D polygons. This restriction may be removed in a later gnuplot version,
- which will impose a distinction between the linecolor and fillcolor properties.
+ polygons from `splot with polygons`. This restriction may be relaxed in a later
+ gnuplot version, that more strongly distinguishes line color from fill color.
Each polygon may be assigned a separate fill color by providing a fourth using
specifier and the keywords `fc variable` (value is interpreted as a linetype)
@@ -8831,14 +8837,19 @@ Ffigure_concave_hull_2
This filter is used as a first step in finding concave hulls using χ-shapes
(see `concavehull`). It may also be applied explicitly to a projection of a
set of 3D points onto the xy plane in order to create a tesselated 3D surface.
+ See
+^
+ delaunay.dem
+^
EXPERIMENTAL (implementation details may change in a future release).
Present only if your copy of gnuplot was configured --enable-chi-shapes.
2D example
- plot POINTS using 1:2 delaunay with polygons fs empty
+ plot POINTS using 1:2 delaunay with polygons fillstyle empty
3D example
+ set pm3d border lc "black" lw 2
splot 'hemisphere.dat' using 1:2:3 delaunay with polygons
D concave_hull 3
D delaunay 1
diff --git a/src/graphics.c b/src/graphics.c
index 28699329b..c0b4018df 100644
--- a/src/graphics.c
+++ b/src/graphics.c
@@ -5523,7 +5523,7 @@ do_polygon( int dimensions, t_object *this_object, int style, int facing )
clpcorn[0].style = style;
if ((this_object->layer == LAYER_DEPTHORDER) && (vertices < 12)) {
- /* FIXME - size arbitrary limit */
+ /* NB: the size limit of 12 vertices is arbitrary */
gpdPoint quad[12];
for (nv=0; nv < vertices; nv++) {
quad[nv].x = p->vertex[nv].x;
@@ -5552,8 +5552,19 @@ do_polygon( int dimensions, t_object *this_object, int style, int facing )
quad[0].c = face.pm3d_color.lt;
}
- /* FIXME: could we pass through a per-quadrangle border style also? */
- quad[1].c = style;
+ /* NB: This is the only call site where pm3d_add_polygon() is called with
+ * plot == NULL to indicate it is from an object rather than a plot component.
+ * As of now there is no provision to pass in a pointer to the object instead,
+ * so we smuggle in fillstyle and border properties via quad[n].c.
+ */
+ if (1) {
+ t_colorspec *border = &this_object->fillstyle.border_color;
+ quad[1].c = style;
+ quad[2].c = ( (border->type == TC_LT && border->lt == LT_NODRAW)
+ || (border->type == TC_DEFAULT))
+ ? LT_NODRAW : border->lt;
+ quad[3].c = this_object->lp_properties.l_width;
+ }
pm3d_add_polygon( NULL, quad, vertices );
} else { /* Not depth-sorted; draw it now */
diff --git a/src/pm3d.c b/src/pm3d.c
index 14ae7c819..8a3a5483e 100644
--- a/src/pm3d.c
+++ b/src/pm3d.c
@@ -1712,7 +1712,16 @@ filled_polygon(struct surface_points *from_plot, int index, gpdPoint *corners, i
term->filled_polygon(nv, icorners);
- if (from_plot && (from_plot->plot_style == CONTOURFILL)) {
+ if (!from_plot) {
+ /* This is an object rather than a plot component.
+ * Object border properties have been smuggled in via corners 1 and 2.
+ * See graphics.c:do_polygon()
+ */
+ if ((int)(corners[2].c) == LT_NODRAW)
+ return;
+ term->linewidth(corners[3].c);
+ set_rgbcolor_const( (unsigned int)(corners[2].c) );
+ } else if (from_plot->plot_style == CONTOURFILL) {
t_colorspec *bordercolor = &(from_plot->fill_properties.border_color);
if (bordercolor->type == TC_LT && bordercolor->lt == LT_NODRAW)
return;
From fc98188b6f484cfaeba007bb4cb7669cbf4009bf Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Tue, 20 Aug 2024 21:12:24 -0700
Subject: [PATCH 34/40] 3D polygons from "splot with polygons" use per-plot
border color and linewidth
Previously all 3D polygons shared the border properties from "set pm3d".
This limitation has been documented as an implementation glitch to be
removed at some point. Now it is relaxed for polygons from "splot with polygons".
The border linewidth and color are taken from the splot command line, if present,
otherwise from "set style fill".
Modify delaunay demo to specify fillcolor in splot command
Modify polygons demo to specify linewidth in splot command
Notes:
- I do not understand the visible change to lines drawn by the polygon whale demo
---
demo/delaunay.dem | 7 +--
demo/polygons.dem | 11 ++---
docs/gnuplot.doc | 26 +++++++-----
src/graph3d.c | 7 +--
src/misc.c | 2 -
src/plot3d.c | 106 +++++++++++++++++++++++++++-------------------
src/pm3d.c | 3 +-
7 files changed, 94 insertions(+), 68 deletions(-)
diff --git a/demo/delaunay.dem b/demo/delaunay.dem
index 3fcaf8519..a3e40b695 100644
--- a/demo/delaunay.dem
+++ b/demo/delaunay.dem
@@ -8,7 +8,8 @@
if (!strstrt(GPVAL_COMPILE_OPTIONS, "+CHI_SHAPES")) {
print "Your copy of gnuplot was not built with support for chi shapes"
} else {
- set pm3d border lc "black" lw 0.5
+ set style fill solid border lc "black"
+ unset colorbox
set palette viridis
set xyplane 0
set isotropic
@@ -21,10 +22,10 @@ if (!strstrt(GPVAL_COMPILE_OPTIONS, "+CHI_SHAPES")) {
set multiplot layout 1,2
set pm3d lighting primary 0.5 spec 0.2 spec2 0.3
- splot 'hemisphr.dat' using 1:2:3 delaunay with polygons title "pm3d lighting"
+ splot 'hemisphr.dat' using 1:2:3 delaunay with polygons fc palette z title "pm3d lighting"
set pm3d nolighting
- splot 'hemisphr.dat' using 1:2:3 delaunay with polygons title "no lighting model"
+ splot 'hemisphr.dat' using 1:2:3 delaunay with polygons fc palette z title "no lighting model"
unset multiplot
}
diff --git a/demo/polygons.dem b/demo/polygons.dem
index 0f6b7eb0b..3e51960a7 100644
--- a/demo/polygons.dem
+++ b/demo/polygons.dem
@@ -71,6 +71,7 @@ set xrange [-2:2]; set yrange [-2:2]; set zrange [-2:2]
set view equal xyz
set view 30,30,1.5
unset border
+unset colorbox
unset tics
unset key
unset label
@@ -94,23 +95,23 @@ set pm3d lighting spec2 0.6
set title "splot icosahedron.dat with polygons"
-splot 'icosahedron.dat' with polygons fc "gray75"
+splot 'icosahedron.dat' with polygons fc "gray75" lw 2
pause -1 "Hit return to continue"
-set title "splot dodecahedron.dat with polygons lc variable"
+set title "splot dodecahedron.dat with polygons fc variable"
set view 148, 55, 2.7
set pm3d lighting spec2 0.3
set palette cubehelix
set for [i=1:12] linetype 99+i lc palette frac i/12.
-splot 'dodecahedron.dat' using 1:2:3:(column(-1)+3) with polygons lc variable
+splot 'dodecahedron.dat' using 1:2:3:(column(-1)+3) with polygons fc variable lw 2
pause -1 "Hit return to continue"
set title "splot dodecahedron with polygons fc rgb variable"
-splot 'dodecahedron.dat' using 1:2:3:(0xffffff * rand(0)) with polygons fc rgb variable
+splot 'dodecahedron.dat' using 1:2:3:(0xffffff * rand(0)) with polygons fc rgb variable lw 2
pause -1 "Hit return to continue"
@@ -119,7 +120,7 @@ set view 36, 60, 4.2
set style fill transparent solid 0.75
set pm3d nolighting border lt -1 lw 2
-splot 'truncated_cube.dat' using ($1-0.5):($2-0.5):($3-0.5) with polygons fc bgnd
+splot 'truncated_cube.dat' using ($1-0.5):($2-0.5):($3-0.5) with polygons fc bgnd lw 2
pause -1 "Hit return to continue"
diff --git a/docs/gnuplot.doc b/docs/gnuplot.doc
index 5173e7e73..b5dd88d14 100644
--- a/docs/gnuplot.doc
+++ b/docs/gnuplot.doc
@@ -655,9 +655,11 @@ D epi_data 1
#b Blank line equivalent for binary data files, needed to support binary
## input for plot styles that expect a blank line to separate data items.
## See `binary blank`.
-#b In previous gnuplot versions all 3D polygons shared a single border color
-## and linewidth taken from "set pm3d". Now individual 3D polygon objects take
-## their fill border and line width from "set object".
+#b In previous gnuplot versions all 3D polygons, objects, and filled areas
+## shared a single border color and linewidth taken from "set pm3d".
+## This limitation is now removed; border properties can be specified per-plot
+## or per-object. This change affects any scripts that expected "set pm3d" to
+## affect the borders of 3D polygons and boxes.
#b splot with contourfill at base
#b Revised implementation of local variables (faster, more well-defined scope).
#b "linestyle variable"
@@ -6240,11 +6242,14 @@ Ffigure_points
input file. A blank line separates one polygon from the next. For the case
of binary input files, see `binary blank`.
- The fill style and color may be specified in the splot command, otherwise the
- global fillstyle from `set style fill` is used. Due to limitations in the
- pm3d code, a single border line style from `set pm3d border` is applied to all
- polygons from `splot with polygons`. This restriction may be relaxed in a later
- gnuplot version, that more strongly distinguishes line color from fill color.
+ Note: Previous gnuplot versions suffered from a limitation that all 3D polygons
+ shared a single set of fill border proporties taken from `set pm3d border`.
+ This limitation is no longer present.
+ Polygon fill style, border color, and border linewidth may now be specified in
+ the splot command, otherwise they are taken from the global settings of
+ `set style fill` (not from `set pm3d`).
+ The fill style, border color, and border linewidth for polygon objects are
+ specified in the `set object` command.
Each polygon may be assigned a separate fill color by providing a fourth using
specifier and the keywords `fc variable` (value is interpreted as a linetype)
@@ -6260,9 +6265,8 @@ Ffigure_polygons
unset border
unset tics
set pm3d depth
- set pm3d border lc "black" lw 1.5
- splot 'icosahedron.dat' with polygons \
- fs transparent solid 0.8 fc bgnd
+ splot 'icosahedron.dat' with polygons fc bgnd \
+ fs transparent solid 0.8 border lc "black" lw 2
2 rgbalpha
?plotting styles rgbalpha
diff --git a/src/graph3d.c b/src/graph3d.c
index 57b109dca..69b2a88df 100644
--- a/src/graph3d.c
+++ b/src/graph3d.c
@@ -4229,14 +4229,15 @@ plot3d_polygons(struct surface_points *plot)
if (nv < 3)
continue;
- /* Coloring piggybacks on options for isosurface */
+ /* Coloring taken from fillstyle (which confusingly is in plot->lp_properties) */
if (plot->pm3d_color_from_column && !isnan(points[0].CRD_COLOR))
quad[0].c = points[0].CRD_COLOR;
- else if (plot->fill_properties.border_color.type == TC_DEFAULT) {
+ else if (plot->lp_properties.pm3d_color.type == TC_Z
+ || plot->lp_properties.pm3d_color.type == TC_DEFAULT) {
double z = pm3d_assign_triangle_z(points[0].z, points[1].z, points[2].z);
quad[0].c = rgb_from_gray(cb2gray(z));
} else
- quad[0].c = plot->fill_properties.border_color.lt;
+ quad[0].c = plot->lp_properties.pm3d_color.lt;
quad[1].c = style;
pm3d_add_polygon( plot, quad, nv );
}
diff --git a/src/misc.c b/src/misc.c
index 25b970c11..a9320b26a 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -1072,10 +1072,8 @@ lp_parse(struct lp_style_type *lp, lp_class destination_class, TBOOLEAN allow_po
* fc colorspec as a line property. We need to parse it later as a
* _fill_ property. Also prevents "plot ... fc fs lw "
* from generating an error claiming redundant line properties.
- * FIXME: Why exclude "fc palette"??
*/
if ((destination_class == LP_NOFILL || destination_class == LP_ADHOC)
- && (!almost_equals(c_token+1, "pal$ette"))
&& (equals(c_token,"fc") || almost_equals(c_token,"fillc$olor"))) {
FPRINTF((stderr, "ignoring 'fc' request\n"));
break;
diff --git a/src/plot3d.c b/src/plot3d.c
index 809752022..927e8d5ef 100644
--- a/src/plot3d.c
+++ b/src/plot3d.c
@@ -1272,6 +1272,13 @@ get_3ddata(struct surface_points *this_plot)
color = v[3];
color_from_column(TRUE);
}
+ /* This handles "with polygons fc variable" */
+ if (this_plot->lp_properties.pm3d_color.type == TC_VARIABLE) {
+ struct lp_style_type lptmp;
+ load_linetype(&lptmp, (int)(v[3]));
+ color = lptmp.pm3d_color.lt;
+ color_from_column(TRUE);
+ }
/* This handles "with polygons fc rgb variable" */
if (this_plot->fill_properties.border_color.type == TC_RGB
&& this_plot->fill_properties.border_color.value < 0) {
@@ -1688,6 +1695,7 @@ eval_3dplots()
TBOOLEAN set_labelstyle = FALSE;
TBOOLEAN set_fillstyle = FALSE;
TBOOLEAN set_fillcolor = FALSE;
+ TBOOLEAN set_lc = FALSE;
t_colorspec fillcolor = DEFAULT_COLORSPEC;
TBOOLEAN set_smooth = FALSE;
@@ -2113,6 +2121,7 @@ eval_3dplots()
if (this_plot->plot_style != LABELPOINTS) {
int stored_token = c_token;
struct lp_style_type lp = DEFAULT_LP_STYLE_TYPE;
+ t_colorspec starting_lc;
int new_lt = 0;
lp.l_type = line_num;
@@ -2120,12 +2129,15 @@ eval_3dplots()
lp.d_type = line_num;
load_linetype(&lp, line_num+1);
+ starting_lc = lp.pm3d_color;
new_lt = lp_parse(&lp, LP_ADHOC,
this_plot->plot_style & PLOT_STYLE_HAS_POINT);
checked_once = TRUE;
if (stored_token != c_token) {
+ if (memcmp(&starting_lc, &lp.pm3d_color, sizeof(t_colorspec)))
+ set_lc = TRUE;
if (set_lpstyle) {
duplication=TRUE;
break;
@@ -2176,41 +2188,41 @@ eval_3dplots()
}
/* Some plots have a fill style as well */
- if ((this_plot->plot_style & PLOT_STYLE_HAS_FILL) && !set_fillstyle){
- int stored_token = c_token;
+ if (!set_fillstyle) {
+ if ((this_plot->plot_style & PLOT_STYLE_HAS_FILL)
+ || (pm3d.implicit == PM3D_IMPLICIT)) {
+ int stored_token = c_token;
- if (this_plot->plot_style == CONTOURFILL) {
- this_plot->fill_properties.fillstyle = FS_SOLID;
- this_plot->fill_properties.filldensity = 100;
- if (!set_lpstyle) {
- /* TC_DEFAULT indicates "retrace", TC_LT would give "noborder" */
+ if (this_plot->plot_style == CONTOURFILL) {
+ this_plot->fill_properties.fillstyle = FS_SOLID;
+ this_plot->fill_properties.filldensity = 100;
+ if (!set_lpstyle) {
+ /* TC_DEFAULT indicates "retrace", TC_LT would give "noborder" */
+ this_plot->fill_properties.border_color.type = TC_DEFAULT;
+ this_plot->fill_properties.border_color.lt = LT_NODRAW;
+ }
+ } else {
+ this_plot->fill_properties.fillstyle = default_fillstyle.fillstyle;
+ this_plot->fill_properties.filldensity = default_fillstyle.filldensity;
+ this_plot->fill_properties.fillpattern = 1;
+ if (this_plot->fill_properties.fillstyle == FS_EMPTY)
+ this_plot->fill_properties.fillstyle = FS_SOLID;
+ }
+ if (equals(c_token,"fs") || almost_equals(c_token,"fill$style")) {
+ parse_fillstyle(&this_plot->fill_properties);
+ set_fillstyle = TRUE;
+ }
+ if (this_plot->plot_style == PM3DSURFACE)
this_plot->fill_properties.border_color.type = TC_DEFAULT;
- this_plot->fill_properties.border_color.lt = LT_NODRAW;
+ if (equals(c_token,"fc") || almost_equals(c_token,"fillc$olor")) {
+ parse_colorspec(&fillcolor, TC_VARIABLE);
+ if (fillcolor.type == TC_COLORMAP)
+ this_plot->lp_properties.colormap = get_colormap(c_token++);
+ set_fillcolor = TRUE;
}
- } else {
- this_plot->fill_properties.fillstyle = default_fillstyle.fillstyle;
- this_plot->fill_properties.filldensity = default_fillstyle.filldensity;
- this_plot->fill_properties.fillpattern = 1;
- if (this_plot->fill_properties.fillstyle == FS_EMPTY)
- this_plot->fill_properties.fillstyle = FS_SOLID;
- }
- if (equals(c_token,"fs") || almost_equals(c_token,"fill$style")) {
- parse_fillstyle(&this_plot->fill_properties);
- set_fillstyle = TRUE;
- }
- if (this_plot->plot_style == PM3DSURFACE)
- this_plot->fill_properties.border_color.type = TC_DEFAULT;
- if (equals(c_token,"fc") || almost_equals(c_token,"fillc$olor")) {
- parse_colorspec(&fillcolor, TC_RGB);
- /* FIXME: can't happen because we limited the options to TC_RGB
- if (fillcolor.type == TC_COLORMAP)
- this_plot->lp_properties.colormap = get_colormap(c_token++);
- */
- set_fillstyle = TRUE;
- set_fillcolor = TRUE;
+ if (stored_token != c_token)
+ continue;
}
- if (stored_token != c_token)
- continue;
}
/* EXPERIMENTAL filter splot ... if () */
@@ -2307,19 +2319,27 @@ eval_3dplots()
/* If this plot style uses a fillstyle and we saw an explicit
* fill color, save it in lp_properties now.
- * FIXME: make other plot styles work like BOXES.
- * ZERRORFILL and CONTOURFILL are weird.
+ * FIXME: some styles still expect fillcolor to be in border_color.
*/
- if ((this_plot->plot_style & PLOT_STYLE_HAS_FILL) && set_fillcolor) {
- if (this_plot->plot_style == ZERRORFILL
- || this_plot->plot_style == FILLEDCURVES
- || this_plot->plot_style == CONTOURFILL) {
- this_plot->fill_properties.border_color = this_plot->lp_properties.pm3d_color;
- this_plot->lp_properties.pm3d_color = fillcolor;
- } else if (this_plot->plot_style == BOXES) {
- this_plot->lp_properties.pm3d_color = fillcolor;
- } else {
- this_plot->fill_properties.border_color = fillcolor;
+ if (set_fillcolor) {
+ if ((this_plot->plot_style & PLOT_STYLE_HAS_FILL)
+ || (pm3d.implicit == PM3D_IMPLICIT)) {
+ if (this_plot->plot_style == ZERRORFILL
+ || this_plot->plot_style == FILLEDCURVES
+ || this_plot->plot_style == CONTOURFILL) {
+ this_plot->fill_properties.border_color
+ = this_plot->lp_properties.pm3d_color;
+ this_plot->lp_properties.pm3d_color = fillcolor;
+ } else if (this_plot->plot_style == BOXES) {
+ this_plot->lp_properties.pm3d_color = fillcolor;
+ } else if (this_plot->plot_style == POLYGONS) {
+ if (set_lc && !set_fillstyle)
+ this_plot->fill_properties.border_color
+ = this_plot->lp_properties.pm3d_color;
+ this_plot->lp_properties.pm3d_color = fillcolor;
+ } else {
+ this_plot->fill_properties.border_color = fillcolor;
+ }
}
}
diff --git a/src/pm3d.c b/src/pm3d.c
index 8a3a5483e..2ea971d06 100644
--- a/src/pm3d.c
+++ b/src/pm3d.c
@@ -1727,7 +1727,8 @@ filled_polygon(struct surface_points *from_plot, int index, gpdPoint *corners, i
return;
if (bordercolor->type != TC_DEFAULT)
apply_pm3dcolor(bordercolor);
- } else if (from_plot && (from_plot->plot_style == BOXES)) {
+ } else if ((from_plot->plot_style == BOXES)
+ || (from_plot->plot_style == POLYGONS)) {
t_colorspec *bordercolor = &(from_plot->fill_properties.border_color);
if (bordercolor->type == TC_LT && bordercolor->lt == LT_NODRAW)
return;
From b7850204c570888aae50f12a85a4459065a4c91f Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Thu, 22 Aug 2024 11:05:11 -0700
Subject: [PATCH 35/40] fixes for various problems seen for "splot with
circles"
It would be nice if all the 3D plot styles with fill properties
would use the same conventions for where to store the colors
and what field + flag is used to indicate variable color.
But they don't.
So these fixes address only problems for "splot with circles".
Some of these issues are only partially fixed.
- support for per-plot fill style
- variable fill color inconsistently applied (fc variable, fc rgb variable)
- "lc " is sometimes required even though "fc " is intended
- key sample does not always match the plot
- "fs solid border lc variable" is probably hopeless
---
src/graph3d.c | 8 ++++----
src/plot3d.c | 23 ++++++++++++-----------
src/save.c | 3 +++
3 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/src/graph3d.c b/src/graph3d.c
index 69b2a88df..edea35ac3 100644
--- a/src/graph3d.c
+++ b/src/graph3d.c
@@ -2137,9 +2137,7 @@ plot3d_points(struct surface_points *plot)
const char *ptchar;
/* Apply constant color outside of the loop */
- if (plot->plot_style == CIRCLES)
- set_rgbcolor_const( plot->fill_properties.border_color.lt );
- else if (colortype == TC_RGB)
+ if (colortype == TC_RGB)
set_rgbcolor_const( plot->lp_properties.pm3d_color.lt );
for (i = 0; i < icrvs->p_count; i++) {
@@ -2178,8 +2176,10 @@ plot3d_points(struct surface_points *plot)
do_arc(x, y, radius, 0., 360.,
style_from_fill(fillstyle), FALSE);
/* Retrace the border if the style requests it */
- if (need_fill_border(fillstyle))
+ if (need_fill_border(fillstyle)) {
do_arc(x, y, radius, 0., 360., 0, FALSE);
+ set_rgbcolor_const(plot->lp_properties.pm3d_color.lt);
+ }
continue;
}
diff --git a/src/plot3d.c b/src/plot3d.c
index 927e8d5ef..2f82f059e 100644
--- a/src/plot3d.c
+++ b/src/plot3d.c
@@ -1264,7 +1264,8 @@ get_3ddata(struct surface_points *this_plot)
color = rgb_from_colorspec( &lptmp.pm3d_color );
color_from_column(TRUE);
}
- /* This allows "with polygons lc rgb variable" to set fillcolor.
+ /* This handles "with polygons fc rgb variable".
+ * However, it also allows "with polygons lc rgb variable" to set fillcolor.
* FIXME: I'd rather that "lc" affected border color.
*/
if (this_plot->lp_properties.pm3d_color.type == TC_RGB
@@ -1279,12 +1280,6 @@ get_3ddata(struct surface_points *this_plot)
color = lptmp.pm3d_color.lt;
color_from_column(TRUE);
}
- /* This handles "with polygons fc rgb variable" */
- if (this_plot->fill_properties.border_color.type == TC_RGB
- && this_plot->fill_properties.border_color.value < 0) {
- color = v[3];
- color_from_column(TRUE);
- }
}
} else { /* all other plot styles */
@@ -2319,11 +2314,12 @@ eval_3dplots()
/* If this plot style uses a fillstyle and we saw an explicit
* fill color, save it in lp_properties now.
- * FIXME: some styles still expect fillcolor to be in border_color.
+ * FIXME: a separate fillcolor field in the plot header would
+ * reduce the inconsistency in where it is stored.
*/
- if (set_fillcolor) {
- if ((this_plot->plot_style & PLOT_STYLE_HAS_FILL)
- || (pm3d.implicit == PM3D_IMPLICIT)) {
+ if ((this_plot->plot_style & PLOT_STYLE_HAS_FILL)
+ || (pm3d.implicit == PM3D_IMPLICIT)) {
+ if (set_fillcolor) {
if (this_plot->plot_style == ZERRORFILL
|| this_plot->plot_style == FILLEDCURVES
|| this_plot->plot_style == CONTOURFILL) {
@@ -2332,6 +2328,11 @@ eval_3dplots()
this_plot->lp_properties.pm3d_color = fillcolor;
} else if (this_plot->plot_style == BOXES) {
this_plot->lp_properties.pm3d_color = fillcolor;
+ } else if (this_plot->plot_style == CIRCLES) {
+ if (fillcolor.type == TC_VARIABLE)
+ this_plot->lp_properties.pm3d_color.type = TC_LINESTYLE;
+ else
+ this_plot->lp_properties.pm3d_color = fillcolor;
} else if (this_plot->plot_style == POLYGONS) {
if (set_lc && !set_fillstyle)
this_plot->fill_properties.border_color
diff --git a/src/save.c b/src/save.c
index a8bbfbb78..378d4ff60 100644
--- a/src/save.c
+++ b/src/save.c
@@ -1626,6 +1626,9 @@ save_pm3dcolor(FILE *fp, const struct t_colorspec *tc)
fprintf(fp," rgb \"#%6.6x\" ", tc->lt);
break;
}
+ case TC_VARIABLE:
+ fprintf(fp," variable ");
+ break;
default: break;
}
}
From f7bfc71ea18670d792e7208a322ba2a0e95928db Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Thu, 22 Aug 2024 19:04:26 -0700
Subject: [PATCH 36/40] Ignore $GPVAL_* datablocks in "save datablocks"
The only one at present is $GPVAL_LAST_MULTIPLOT.
---
src/save.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/save.c b/src/save.c
index 378d4ff60..27f700d2f 100644
--- a/src/save.c
+++ b/src/save.c
@@ -133,7 +133,8 @@ save_datablocks(FILE *fp)
struct udvt_entry *udv = first_udv->next_udv;
while (udv) {
- if (udv->udv_value.type == DATABLOCK) {
+ if ((udv->udv_value.type == DATABLOCK)
+ && (strncmp(udv->udv_name, "$GPVAL", 6) != 0)) {
char **line = udv->udv_value.v.data_array;
fprintf(fp, "%s << EOD\n", udv->udv_name);
while (line && *line) {
From da4e754d7c4841eb002ef16e96a671055a4a87c7 Mon Sep 17 00:00:00 2001
From: Ethan A Merritt
Date: Fri, 23 Aug 2024 14:10:02 -0700
Subject: [PATCH 37/40] docs, demos: typos
Thanks to Shigeharu Takeno for finding many of these
---
demo/all.dem | 2 +-
demo/delaunay.dem | 2 +-
docs/gnuplot.doc | 32 ++++++++++++++++----------------
docs/plotstyles.gnu | 4 ++--
4 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/demo/all.dem b/demo/all.dem
index ebbff5da7..558ad8609 100644
--- a/demo/all.dem
+++ b/demo/all.dem
@@ -209,7 +209,7 @@ load "binary.dem"
load "binary_polygon.dem"
reset
-print "*********** 3D polygons from Delaunay tesselation ***********"
+print "*********** 3D polygons from Delaunay tessellation ***********"
load "delaunay.dem"
reset
diff --git a/demo/delaunay.dem b/demo/delaunay.dem
index a3e40b695..3ce7f3789 100644
--- a/demo/delaunay.dem
+++ b/demo/delaunay.dem
@@ -1,7 +1,7 @@
#
# The Delaunay triangulation filter is an adjunct to the support for
# concave hulls. It can be used on its own either for original use
-# in 2D plots or as a way to generate a triangular tesselation for
+# in 2D plots or as a way to generate a triangular tessellation for
# a 3D surface defined by a scattered set of points as shown here.
#
diff --git a/docs/gnuplot.doc b/docs/gnuplot.doc
index b5dd88d14..ad86c48f5 100644
--- a/docs/gnuplot.doc
+++ b/docs/gnuplot.doc
@@ -534,7 +534,7 @@ D epi_data 1
#b `set isotropic` adjusts the axis scaling in both 2D and 3D plots such that
## the x, y, and z axes all have the same scale.
#b Change: Text rotation angle is not limited to integral degrees.
-#b Special (non-numerical) linetypes `lt nodraw`, `lt black`, `lt bgnd`
+#b Special (non-numerical) linetypes `lt nodraw`, `lt black`, `lt background`
## See `special_linetypes`.
#b Data-driven color assignments in histogram plots. See `histograms colors`.
#b The position of the key box can be manually tweaked by specifying an
@@ -663,7 +663,7 @@ D epi_data 1
#b splot with contourfill at base
#b Revised implementation of local variables (faster, more well-defined scope).
#b "linestyle variable"
-#b pm3d coloring for 3D polygons (e.g. Delaunay tesselation of surfaces).
+#b pm3d coloring for 3D polygons (e.g. Delaunay tessellation of surfaces).
## See `delaunay`.
#b splot with contourfill at base
#b Revised implementation of local variables (faster, more well-defined scope).
@@ -677,7 +677,7 @@ D epi_data 1
## start of the current gnuplot session. See `save changes`.
#b Revised wxt terminal driver with more robust threading and error recovery.
#b Alternatives to gdlib for handling image files as data
-#b Iteration over array contents `array A; for [e in A] { ... }`
+#b Iteration over array contents `array A; for [e in A] { ... }` [EXPERIMENTAL]
#b Deprecation of the "sample" keyword
#b New category of graphical objects called "marks" that allow definition
## of complex symbols used in plots. No documentation or demos yet.
@@ -3363,7 +3363,7 @@ C ... and restart the table:
array are not limited to a single type of variable. Arrays must be created
explicitly before being referenced. The size of an array cannot be changed
after creation. Array elements are initially undefined unless they are
- provided in the array declaragion.
+ provided in the array declaration.
In most places an array element can be used instead of a named user variable.
The cardinality (number of elements) of array A is given by the expression |A|.
@@ -3830,7 +3830,7 @@ Ffigure_newsyntax
`palette` and `palette z` both map the z coordinate of the plot element being
colored onto the current palette. If z is outside cbrange it is by default
- mapped to palette fraction 0 or palette franction 1. If the option
+ mapped to palette fraction 0 or palette fraction 1. If the option
`set pm3d noclipcb` is set, then quadrangles in a pm3d plot whose z values
are out of range will not be drawn at all.
@@ -3932,8 +3932,8 @@ Ffigure_newsyntax
`lt black` specifies a solid black line.
- `lt bgnd` specifies a solid line with the background color of the current
- terminal. See `background`.
+ `lt background` or `lt bgnd` specifies a solid line with the background color
+ of the current terminal. See `background`.
`lt nodraw` skips drawing the line altogether. This is useful in conjunction
with plot style `linespoints`. It allows you to suppress the line component
@@ -5121,7 +5121,7 @@ Ffigure_contourfill
This style can be combined with `set contours` to superimpose contour
lines that bound the slices. Care must be taken that the slice boundaries
- from `set contourfill` match the contour bounaries from `set cntrparam`.
+ from `set contourfill` match the contour boundaries from `set cntrparam`.
# slice boundaries determined by ztics
# coloring set by palette mapping the slice midpoint z value
@@ -5138,7 +5138,7 @@ Ffigure_contourfill
Plotting `with contourfill at base` instead projects the colored surface onto
the base plane. To draw both a surface and its projected contour coloring
set hidden3d front
- splot f(x,y) using lines, f(x,y) using contourfill at base
+ splot f(x,y) with lines, f(x,y) with contourfill at base
2 dots
?plotting styles dots
@@ -6148,7 +6148,7 @@ Ffigure_points
The point type defaults to that of the corresponding linetype. See `linetypes`.
Alternatively the plot command can specify a specific point type or size.
The most flexible alternative is to specify `pointtype variable` or
- `pointsize variable` in the plot command and provide provide the corresponding
+ `pointsize variable` in the plot command and provide the corresponding
per-datum point properties in additional columns of the `using` specifier.
In this case, input data columns are interpreted implicitly in the order
`x y pointsize pointtype color` (see `pointtype variable` below).
@@ -6187,7 +6187,7 @@ Ffigure_points
?variable
?pointtype variable
?pointsize variable
- Plot styles that contain a point symbol optionally accept addtional data
+ Plot styles that contain a point symbol optionally accept additional data
columns in the `using` specifier to control the appearance of that point.
This is indicated by modifying the keywords `pointtype`, `pointsize`, or
`linecolor` in the plot command with the additional keyword `variable`
@@ -6265,7 +6265,7 @@ Ffigure_polygons
unset border
unset tics
set pm3d depth
- splot 'icosahedron.dat' with polygons fc bgnd \
+ splot 'icosahedron.dat' with polygons fc background \
fs transparent solid 0.8 border lc "black" lw 2
2 rgbalpha
@@ -8840,7 +8840,7 @@ Ffigure_concave_hull_2
triangles in the format expected by plot style "with polygons".
This filter is used as a first step in finding concave hulls using χ-shapes
(see `concavehull`). It may also be applied explicitly to a projection of a
- set of 3D points onto the xy plane in order to create a tesselated 3D surface.
+ set of 3D points onto the xy plane in order to create a tessellated 3D surface.
See
^
delaunay.dem
@@ -10308,7 +10308,7 @@ Ffigure_smooth_path
multiplot. See `new multiplots`.
EXPERIMENTAL: `remultiplot` is invoked implicitly from `replot` if the
- immediately preceeding plot command was part of a completed multiplot.
+ immediately preceding plot command was part of a completed multiplot.
2 replot
?commands replot
@@ -15999,7 +15999,7 @@ Ffigure_polar_grid
If you want no median line, set this to 0.
If the using specification for a boxplot contains a fourth column, the values
- in that column will be interpreted as the discrete leveles of a factor
+ in that column will be interpreted as the discrete levels of a factor
variable. In this case more than one boxplots may be drawn, as many as the
number of levels of the factor variable. These boxplots will be drawn next to
each other, the distance between them is 1.0 by default (in x-axis units).
@@ -16302,7 +16302,7 @@ Ffigure_polar_grid
Examples:
set style rectangle back fc rgb "white" fs solid 1.0 border lt -1
- set style rectangle fc linsestyle 3 fs pattern 2 noborder
+ set style rectangle fc linestyle 3 fs pattern 2 noborder
The default values correspond to solid fill with the background color and a
black border.
diff --git a/docs/plotstyles.gnu b/docs/plotstyles.gnu
index 658b14ea9..dd2aa0b6d 100644
--- a/docs/plotstyles.gnu
+++ b/docs/plotstyles.gnu
@@ -172,8 +172,8 @@ set border 2
set lmargin at screen 0.3
unset key
set style data boxplot
-plot 'silver.dat' using (1):2:(.25) ps 0.3, \
- '' using (1.5):(5*$3):(.25) ps 0.3
+plot 'silver.dat' using (1):2:(.25) ps 0.3 lt black, \
+ '' using (1.5):(5*$3):(.25) ps 0.3 lt black
#
# Dots
From ed15ee6012e86dc2efd9e4df989c08ec3e60a9d8 Mon Sep 17 00:00:00 2001
From: Shigeharu TAKENO
Date: Fri, 23 Aug 2024 16:26:36 -0700
Subject: [PATCH 38/40] docs: sync Japanese documentation to gnuplot.doc
2024-08-22
---
docs/gnuplot-ja.doc | 336 +++++++++++++++++++++++++++++++------------
docs/term-ja.diff | 337 +++++++++++++++++++++-----------------------
2 files changed, 406 insertions(+), 267 deletions(-)
diff --git a/docs/gnuplot-ja.doc b/docs/gnuplot-ja.doc
index 0ab524b93..b409c289d 100644
--- a/docs/gnuplot-ja.doc
+++ b/docs/gnuplot-ja.doc
@@ -1,5 +1,5 @@
-C RCS $Id: gnuplot-ja.doc,v 1.805 2023-11-28 18:28:17+09 shige Exp $
-C corresponding original gnuplot.doc at 2023-11-28
+C RCS $Id: gnuplot-ja.doc,v 1.815 2024-08-23 14:05:54+09 shige Exp $
+C corresponding original gnuplot.doc at 2024-08-22
C
C Copyright (C) 1986 - 1993, 1998, 1999, 2000, 2001, 2004 Thomas Williams, Colin Kelley et al.
C
@@ -27,7 +27,7 @@ C
^ James R. Van Zandt, Alex Woo, Johannes Zellner
^
^