# HG changeset patch
# User Daniel J Sebald <daniel.sebald@ieee.org>
# Date 1435377666 18000
# Node ID 953ea5c0bbb00a7d16690f9d3a391cf63b1efb58
# Parent  c2206fda3986c552a41b62e9e53d7e54c9258199
Fix gnuplot toolkit face/edgecolor and linestyle/width for surf() (bug #34523)

* __gnuplot_has_feature__.m (__gnuplot_has_feature__): Add "linetype" and
"dashtype" to list of 'features' string cell array, "4.6" and "5.0" to
'versions' string cell array, and ">=", ">=" to 'operators' string cell array.

* __go_draw_axes__.m (__go_draw_axes__): Keep hidden line removal for case of
line in 3D plot.  Get style index as part of do_linestyle_command call.
Determine style command, 'linetype' or 'linestyle' depending on gnuplot feature
support, and place in the withclause{} strings.  Move linestyle property
translation to its own function gnuplot_linetype() and call that function.  For
a surface, do not initialize withclause{} to pm3d and drop withpm3d logical
variable.  Move flat_interp_face, flat_interp_edge and facecolor_none_or_white
definitions to sooner point in flow.  If the surface has a face color, set the
fourth data column to the same 24-bit RGB face color value.  Consolidate 'unset
pm3d' at one location prior to conditional tests.  After using style{1}, remove
it from cell list.  If surface has no face color, add "nohidden3d" to the
withclause{}.  If surface has face color, set hidden_removal to true and use
pm3d with the "linecolor RGB variable" mode option in the withclause{}.  Move
"set pm3d explicit etc." to after the conditional statements and change the
first test to negative logic.  Condense the additional style{} processing into
a for-loop.  Add "front nooffset" when setting hidden3d.  Place a newline
character at the end of the data sent to gnuplot.
(do_linestyle_command): Return the style indeces, ltidx, in addition to style
strings.  Add 8 to the index to keep first 8 linetypes intact.  Choose style
command according to gnuplot feature support, 'linetype' or 'line style'.  Use
new function gnuplot_linetype() to generate line pattern command and send to
gnuplot if not empty.  Add index to ltidx[] when string is added to style{}.
(gnuplot_linetype): New function containing switch statements for translating
linestyle to a gnuplot command option, either 'dashtype', 'linetype' or empty
depending upon whether gnuplot has the recent dashtype or linetype features.

diff --git a/scripts/plot/util/private/__gnuplot_has_feature__.m b/scripts/plot/util/private/__gnuplot_has_feature__.m
--- a/scripts/plot/util/private/__gnuplot_has_feature__.m
+++ b/scripts/plot/util/private/__gnuplot_has_feature__.m
@@ -35,7 +35,9 @@ function res = __gnuplot_has_feature__ (
                          "variable_GPVAL_TERMINALS",
                          "key_has_font_properties",
                          "windows_figure_position",
-                         "has_termoption_dashed"};
+                         "has_termoption_dashed",
+                         "linetype",
+                         "dashtype"};
   persistent has_features;
 
   if (isempty (has_features))
@@ -45,8 +47,8 @@ function res = __gnuplot_has_feature__ (
       ## Don't throw an error if gnuplot isn't installed
       gnuplot_version = "0.0.0";
     end_try_catch
-    versions = {"4.2.5", "4.4", "4.4", "4.4", "4.2", "4.2", "4.4", "4.4", "4.4", "4.4", "4.3"};
-    operators = {">=", ">=", ">=", ">=", ">=", ">=", ">=", ">=", ">=", ">=", ">="};
+    versions = {"4.2.5", "4.4", "4.4", "4.4", "4.2", "4.2", "4.4", "4.4", "4.4", "4.4", "4.3", "4.6", "5.0"};
+    operators = {">=", ">=", ">=", ">=", ">=", ">=", ">=", ">=", ">=", ">=", ">=", ">=", ">="};
     have_features = false (size (features));
     for n = 1 : numel (have_features)
       has_features(n) = compare_versions (gnuplot_version, versions{n}, operators{n});
diff --git a/scripts/plot/util/private/__go_draw_axes__.m b/scripts/plot/util/private/__go_draw_axes__.m
--- a/scripts/plot/util/private/__go_draw_axes__.m
+++ b/scripts/plot/util/private/__go_draw_axes__.m
@@ -590,7 +590,6 @@ function __go_draw_axes__ (h, plot_strea
           data{data_idx} = [xdat, ydat, zdat]';
           usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3)",
                                            numel (xdat));
-          hidden_removal = false;
           ## fputs (plot_stream, "set parametric;\n");
         else
           xdat = obj.xdata(:);
@@ -601,11 +600,16 @@ function __go_draw_axes__ (h, plot_strea
                      rows (xdat), xaxisloc_using, yaxisloc_using);
         endif
 
-        style = do_linestyle_command (obj, obj.color, data_idx, mono,
-                                      plot_stream, errbars);
+        [style, sidx] = do_linestyle_command (obj, obj.color, data_idx, mono,
+                                              plot_stream, errbars);
+        if (__gnuplot_has_feature__ ("linetype"))
+          scmd = "linetype";
+        else
+          scmd = "linestyle";
+        endif
 
-        withclause{data_idx} = sprintf ("with %s linestyle %d",
-                                        style{1}, data_idx);
+        withclause{data_idx} = sprintf ("with %s %s %d",
+                                        style{1}, scmd, sidx(1));
 
         if (length (style) > 1)
           data_idx++;
@@ -616,8 +620,8 @@ function __go_draw_axes__ (h, plot_strea
           titlespec{data_idx} = "title \"\"";
           usingclause{data_idx} = usingclause{data_idx - 1};
           data{data_idx} = data{data_idx - 1};
-          withclause{data_idx} = sprintf ("with %s linestyle %d",
-                                          style{2}, data_idx);
+          withclause{data_idx} = sprintf ("with %s %s %d",
+                                          style{2}, scmd, sidx(2));
         endif
         if (length (style) > 2)
           data_idx++;
@@ -628,8 +632,8 @@ function __go_draw_axes__ (h, plot_strea
           titlespec{data_idx} = "title \"\"";
           usingclause{data_idx} = usingclause{data_idx - 1};
           data{data_idx} = data{data_idx - 1};
-          withclause{data_idx} = sprintf ("with %s linestyle %d",
-                                          style{3}, data_idx);
+          withclause{data_idx} = sprintf ("with %s %s %d",
+                                          style{3}, scmd, sidx(3));
         endif
 
      case "patch"
@@ -884,24 +888,7 @@ function __go_draw_axes__ (h, plot_strea
              color = [0, 0, 0];
            endif
 
-           if (isfield (obj, "linestyle"))
-             switch (obj.linestyle)
-               case "-"
-                 lt = "lt 1";
-               case "--"
-                 lt = "lt 2";
-               case ":"
-                 lt = "lt 3";
-               case "-."
-                 lt = "lt 6";
-               case "none"
-                 lt = "";
-               otherwise
-                 lt = "";
-             endswitch
-           else
-             lt = "";
-           endif
+           lt = gnuplot_linetype (obj);
 
            if (isfield (obj, "linewidth"))
              lw = sprintf ("linewidth %f", obj.linewidth);
@@ -1128,9 +1115,14 @@ function __go_draw_axes__ (h, plot_strea
           parametric(data_idx) = false;
           have_cdata(data_idx) = true;
           have_3d_patch(data_idx) = false;
-          style = do_linestyle_command (obj, obj.edgecolor,
-                                        data_idx, mono,
-                                        plot_stream);
+          [style, sidx] = do_linestyle_command (obj, obj.edgecolor,
+                                                data_idx, mono,
+                                                plot_stream);
+          if (__gnuplot_has_feature__ ("linetype"))
+            scmd = "linetype";
+          else
+            scmd = "linestyle";
+          endif
 
           if (isempty (obj.displayname))
             titlespec{data_idx} = "title \"\"";
@@ -1140,11 +1132,15 @@ function __go_draw_axes__ (h, plot_strea
                   );
             titlespec{data_idx} = ['title "' tmp '"'];
           endif
-          withclause{data_idx} = sprintf ("with pm3d linestyle %d",
-                                          data_idx);
-          withpm3d = true;
-          pm3didx = data_idx;
 
+          flat_interp_face = (strcmp (obj.facecolor, "flat")
+                              || strcmp (obj.facecolor, "interp"));
+          flat_interp_edge = (strcmp (obj.edgecolor, "flat")
+                              || strcmp (obj.edgecolor, "interp"));
+
+          facecolor_none_or_white = (strcmp (obj.facecolor, "none")
+                                     || (isnumeric (obj.facecolor)
+                                         && all (obj.facecolor == 1)));
           xdat = obj.xdata;
           ydat = obj.ydata;
           zdat = obj.zdata;
@@ -1182,7 +1178,13 @@ function __go_draw_axes__ (h, plot_strea
               zz(:,kk)   = xdat(:,k);
               zz(:,kk+1) = ydat(:,k);
               zz(:,kk+2) = zdat(:,k);
-              zz(:,kk+3) = cdat(:,k);
+              if (facecolor_none_or_white)
+                zz(:,kk+3) = cdat(:,k);
+              else
+                ## Convert color to 24-bit RGB
+                zz(:,kk+3) = hex2dec (sprintf ("%02x%02x%02x",
+                                               round (255*obj.facecolor)));
+              endif
               k++;
             endfor
             data{data_idx} = zz.';
@@ -1196,73 +1198,73 @@ function __go_draw_axes__ (h, plot_strea
           endif
           usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3):($4)", ylen, xlen);
 
-          flat_interp_face = (strcmp (obj.facecolor, "flat")
-                              || strcmp (obj.facecolor, "interp"));
-          flat_interp_edge = (strcmp (obj.edgecolor, "flat")
-                              || strcmp (obj.edgecolor, "interp"));
-
-          facecolor_none_or_white = (strcmp (obj.facecolor, "none")
-                                     || (isnumeric (obj.facecolor)
-                                         && all (obj.facecolor == 1)));
-          hidden_removal = false;
+          fputs (plot_stream, "unset pm3d\n");
           fputs (plot_stream, "set style increment default;\n");
           if (flat_interp_edge && facecolor_none_or_white)
-            withpm3d = false;
             withclause{data_idx} = sprintf ("with %s palette", style{1});
-            fputs (plot_stream, "unset pm3d\n");
+            if (length (style) > 1)
+              style = style{2:end};
+              sidx = sidx(2:end);
+            else
+              style = {};
+              sidx = [];
+            end
             if (all (obj.facecolor == 1))
               hidden_removal = true;
+            else
+              withclause{data_idx} = [withclause{dataidx} " nohidden3d"];
             endif
           elseif (facecolor_none_or_white)
+            fputs (plot_stream,"set style increment user;\n");
+            withclause{data_idx} = sprintf ("with %s %s %d",
+                                            style{1}, scmd, sidx(1));
+            if (length (style) > 1)
+              style = style{2:end};
+              sidx = sidx(2:end);
+            else
+              style = {};
+              sidx = [];
+            end
             if (all (obj.facecolor == 1))
               hidden_removal = true;
+            else
+              withclause{data_idx} = [withclause{dataidx} " nohidden3d"];
             endif
-            fputs (plot_stream,"unset pm3d;\n");
-            fputs (plot_stream,"set style increment user;\n");
-            withpm3d = false;
-            withclause{data_idx} = sprintf ("with %s linestyle %d",
-                                            style{1}, data_idx);
-            fputs (plot_stream, "unset pm3d\n");
-          endif
+          else
+            hidden_removal = true;
+            withclause{data_idx} = sprintf ("with pm3d linecolor rgb variable");
 
-          if (doing_interp_color)
-            ## "depthorder" interferes with interpolation of colors.
-            dord = "scansautomatic";
-          else
-            dord = "depthorder";
-          endif
+            if (doing_interp_color)
+              ## "depthorder" interferes with interpolation of colors.
+              dord = "scansautomatic";
+            else
+              dord = "depthorder";
+            endif
 
-          if (flat_interp_face && strcmp (obj.edgecolor, "flat"))
+            if (! (flat_interp_face && strcmp (obj.edgecolor, "flat"))
+                && ! facecolor_none_or_white)
+              if (strcmp (obj.edgecolor, "none"))
+                if (__gnuplot_has_feature__ ("transparent_surface")
+                    && isscalar (obj.facealpha))
+                  fprintf (plot_stream,
+                           "set style fill transparent solid %f;\n",
+                           obj.facealpha);
+                endif
+              else
+                if (__gnuplot_has_feature__ ("transparent_surface")
+                    && isscalar (obj.facealpha))
+                  fprintf (plot_stream,
+                           "set style fill transparent solid %f;\n",
+                           obj.facealpha);
+                endif
+              endif
+            endif
             fprintf (plot_stream,
                      "set pm3d explicit at s %s %s corners2color c3;\n",
                      interp_str, dord);
-          elseif (! facecolor_none_or_white)
-            if (strcmp (obj.edgecolor, "none"))
-              if (__gnuplot_has_feature__ ("transparent_surface")
-                  && isscalar (obj.facealpha))
-                fprintf (plot_stream,
-                         "set style fill transparent solid %f;\n",
-                         obj.facealpha);
-              endif
-              fprintf (plot_stream,
-                       "set pm3d explicit at s %s corners2color c3;\n",
-                       interp_str, dord);
-            else
-              fprintf (plot_stream,
-                       "set pm3d explicit at s hidden3d %d %s %s corners2color c3;\n",
-                       data_idx, interp_str, dord);
-
-              if (__gnuplot_has_feature__ ("transparent_surface")
-                  && isscalar (obj.facealpha))
-                fprintf (plot_stream,
-                         "set style fill transparent solid %f;\n",
-                         obj.facealpha);
-              endif
-            endif
           endif
 
-          zz = [];
-          if (length (style) > 1)
+          for i_stl = 1:length (style)
             len = 3 * xlen;
             zz = zeros (ylen, len);
             k = 1;
@@ -1282,46 +1284,9 @@ function __go_draw_axes__ (h, plot_strea
             titlespec{data_idx} = "title \"\"";
             usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3)", ylen, xlen);
             data{data_idx} = zz;
-            withclause{data_idx} = sprintf ("with %s linestyle %d",
-                                            style{2}, data_idx);
-
-          endif
-          if (length (style) > 2)
-            data_idx++;
-            is_image_data(data_idx) = is_image_data(data_idx - 1);
-            parametric(data_idx) = parametric(data_idx - 1);
-            have_cdata(data_idx) = false;
-            have_3d_patch(data_idx) = have_3d_patch(data_idx - 1);
-            titlespec{data_idx} = "title \"\"";
-            usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3)", ylen, xlen);
-            data{data_idx} = zz;
-            withclause{data_idx} = sprintf ("with %s linestyle %d",
-                                            style{3}, data_idx);
-          endif
-          if (withpm3d && strcmp (style{1}, "linespoints"))
-            if (isempty (zz))
-              len = 3 * xlen;
-              zz = zeros (ylen, len);
-              k = 1;
-              for kk = 1:3:len
-                zz(:,kk)   = xdat(:,k);
-                zz(:,kk+1) = ydat(:,k);
-                zz(:,kk+2) = zdat(:,k);
-                k++;
-              endfor
-              zz = zz.';
-            endif
-            data_idx++;
-            is_image_data(data_idx) = is_image_data(data_idx - 1);
-            parametric(data_idx) = parametric(data_idx - 1);
-            have_cdata(data_idx) = false;
-            have_3d_patch(data_idx) = have_3d_patch(data_idx - 1);
-            titlespec{data_idx} = "title \"\"";
-            usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3)", ylen, xlen);
-            data{data_idx} = zz;
-            withclause{data_idx} = sprintf ("with points linestyle %d",
-                                            pm3didx);
-          endif
+            withclause{data_idx} = sprintf ("with %s %s %d",
+                                            style{i_stl}, scmd, sidx(i_stl));
+          endfor
         endif
 
       case "text"
@@ -1403,7 +1368,7 @@ function __go_draw_axes__ (h, plot_strea
 
   endwhile
 
-  ## This is need to prevent warnings for rotations in 3D plots, while
+  ## This is needed to prevent warnings for rotations in 3D plots, while
   ## allowing colorbars with contours.
   if (nd == 2 || (data_idx > 1 && ! view_map))
     fputs (plot_stream, "set pm3d implicit;\n");
@@ -1412,7 +1377,7 @@ function __go_draw_axes__ (h, plot_strea
   endif
 
   if (isnan (hidden_removal) || hidden_removal)
-    fputs (plot_stream, "set hidden3d;\n");
+    fputs (plot_stream, "set hidden3d front nooffset;\n");
   else
     fputs (plot_stream, "unset hidden3d;\n");
   endif
@@ -1748,6 +1713,7 @@ function __go_draw_axes__ (h, plot_strea
                                 have_cdata(i));
       endif
     endfor
+    fputs (plot_stream, "\n");
   else
     fputs (plot_stream, "plot \"-\";\nInf Inf\ne\n");
   endif
@@ -1799,12 +1765,20 @@ function fontspec = create_fontspec (f, 
   endif
 endfunction
 
-function style = do_linestyle_command (obj, linecolor, idx, mono,
-                                       plot_stream, errbars = "")
+function [style, ltidx] = do_linestyle_command (obj, linecolor, idx, mono,
+                                                plot_stream, errbars = "")
+  idx = idx + 8;
+
   style = {};
+  ltidx = [];
 
-  fprintf (plot_stream, "set style line %d default;\n", idx);
-  fprintf (plot_stream, "set style line %d", idx);
+  if (__gnuplot_has_feature__ ("linetype"))
+    scommand = "linetype";
+  else
+    scommand = "line style";
+  endif
+  fprintf (plot_stream, "set %s %d default;\n", scommand, idx);
+  fprintf (plot_stream, "set %s %d", scommand, idx);
 
   found_style = false;
   if (isnumeric (linecolor))
@@ -1817,28 +1791,9 @@ function style = do_linestyle_command (o
     color = [0, 0, 0];
   endif
 
-  if (isfield (obj, "linestyle"))
-    switch (obj.linestyle)
-      case "-"
-        lt = "1";
-      case "--"
-        lt = "2";
-      case ":"
-        lt = "3";
-      case "-."
-        lt = "6";
-      case "none"
-        lt = "";
-      otherwise
-        lt = "";
-    endswitch
-
-    if (! isempty (lt))
-      fprintf (plot_stream, " linetype %s", lt);
-    endif
-
-  else
-    lt = "";
+  lt = gnuplot_linetype (obj);
+  if (! isempty (lt))
+    fprintf (plot_stream, " %s", lt);
   endif
   if (! isempty (errbars))
     found_style = true;
@@ -1862,6 +1817,7 @@ function style = do_linestyle_command (o
     else
       style{sidx} = "lines";
     endif
+    ltidx(sidx) = idx;
 
     facesame = true;
     if (! isequal (pt, pt2) && isfield (obj, "markerfacecolor")
@@ -1889,14 +1845,15 @@ function style = do_linestyle_command (o
         else
           fputs (plot_stream, ";\n");
         endif
-        fprintf (plot_stream, "set style line %d default;\n", idx);
-        fprintf (plot_stream, "set style line %d", idx);
+        fprintf (plot_stream, "set %s %d default;\n", scommand, idx);
+        fprintf (plot_stream, "set %s %d", scommand, idx);
         if (isnumeric (obj.markerfacecolor) && ! mono)
           fprintf (plot_stream, " linecolor rgb \"#%02x%02x%02x\"",
                    round (255*obj.markerfacecolor));
         endif
         if (! isempty (pt2))
           style{sidx} = "points";
+          ltidx(sidx) = idx;
           fprintf (plot_stream, " pointtype %s", pt2);
         endif
         if (isfield (obj, "markersize"))
@@ -1932,8 +1889,8 @@ function style = do_linestyle_command (o
         else
           fputs (plot_stream, ";\n");
         endif
-        fprintf (plot_stream, "set style line %d default;\n", idx);
-        fprintf (plot_stream, "set style line %d", idx);
+        fprintf (plot_stream, "set %s %d default;\n", scommand, idx);
+        fprintf (plot_stream, "set %s %d", scommand, idx);
         if (! mono)
           if (strcmp (obj.markeredgecolor, "auto"))
             fprintf (plot_stream, " linecolor rgb \"#%02x%02x%02x\"",
@@ -1945,6 +1902,7 @@ function style = do_linestyle_command (o
         endif
         if (! isempty (pt))
           style{sidx} = "points";
+          ltidx(sidx) = idx;
           fprintf (plot_stream, " pointtype %s", pt);
         endif
         if (isfield (obj, "markersize"))
@@ -1954,6 +1912,7 @@ function style = do_linestyle_command (o
     endif
   else
     style{1} = errbars;
+    ltidx(1) = idx;
     fputs (plot_stream, " pointtype 0");
   endif
 
@@ -1965,6 +1924,51 @@ function style = do_linestyle_command (o
 
 endfunction
 
+function [lt] = gnuplot_linetype (obj)
+  if (isfield (obj, "linestyle"))
+    if (__gnuplot_has_feature__ ("dashtype"))
+      opt = "dashtype";
+      switch (obj.linestyle)
+        case "-"
+          lt = "1";
+        case "--"
+          lt = "2";
+        case ":"
+          lt = "3";
+        case "-."
+          lt = "4";
+        case "none"
+          lt = "";
+        otherwise
+          lt = "";
+      endswitch
+    elseif (__gnuplot_has_feature__ ("linetype"))
+      opt = "linetype";
+      switch (obj.linestyle)
+        case "-"
+          lt = "1";
+        case "--"
+          lt = "2";
+        case ":"
+          lt = "3";
+        case "-."
+          lt = "6";
+        case "none"
+          lt = "";
+        otherwise
+          lt = "";
+      endswitch
+    else
+      lt = "";
+    endif
+    if (! isempty (lt))
+      lt = sprintf ("%s %s", opt, lt);
+    endif
+  else
+    lt = "";
+  endif
+endfunction
+
 function [pt, pt2, obj] = gnuplot_pointtype (obj)
   if (isfield (obj, "marker"))
     switch (obj.marker)
exporting patch:
<fdopen>
