# HG changeset patch
# User Pantxo Diribarne <pantxo.diribarne@gmail.com>
# Date 1510840931 -3600
#      Thu Nov 16 15:02:11 2017 +0100
# Node ID f6aeb190f7cecc47cccda906cbc254559be18de5
# Parent  f3d754deb41dd0a6631a153ae6b2eed09275262f
[mq]: addsvg

diff -r f3d754deb41d -r f6aeb190f7ce scripts/plot/util/print.m
--- a/scripts/plot/util/print.m	Wed Nov 08 16:34:23 2017 +0100
+++ b/scripts/plot/util/print.m	Thu Nov 16 15:02:11 2017 +0100
@@ -84,7 +84,8 @@
 ##
 ## @item -d@var{device}
 ##   The available output format is specified by the option @var{device}, and
-## is one of:
+## is one of (formats marked with an "*" are available only with Gnuplot
+## toolkit):
 ##
 ##   @table @code
 ##   @item  ps
@@ -92,14 +93,19 @@
 ##   @itemx psc
 ##   @itemx psc2
 ##     PostScript (level 1 and 2, mono and color).  The OpenGL-based toolkits
-## always generate PostScript level 3.0.
+## always generate PostScript level 3.0.  The only supported fonts are
+## the base postscript fonts: Helvetica (the default), Times, Courier and their 
+## variants (bold or italic).  Any other font will be replaced by Helvetica.
 ##
 ##   @item  eps
 ##   @itemx eps2
 ##   @itemx epsc
 ##   @itemx epsc2
 ##     Encapsulated PostScript (level 1 and 2, mono and color).  The
-## OpenGL-based toolkits always generate PostScript level 3.0.
+## OpenGL-based toolkits always generate PostScript level 3.0.  The only
+## supported fonts are the base postscript fonts: Helvetica (the
+## default), Times, Courier and their variants (bold or italic).  Any
+## other font will be replaced by Helvetica.
 ##
 ##   @item  pslatex
 ##   @itemx epslatex
@@ -125,31 +131,30 @@
 ## braces).  The @samp{pdflatex} device, and any of the @samp{standalone}
 ## formats, are not available with the Gnuplot toolkit.
 ##
-##   @item  epscairo
-##   @itemx pdfcairo
-##   @itemx epscairolatex
-##   @itemx pdfcairolatex
-##   @itemx epscairolatexstandalone
-##   @itemx pdfcairolatexstandalone
-##     Generate Cairo based output when using the Gnuplot graphics toolkit.
-## The @samp{epscairo} and @samp{pdfcairo} devices are synonymous with
-## the @samp{epsc} device.  The @LaTeX{} variants generate a @LaTeX{} file,
-## @file{@var{filename}.tex}, for the text portions of a plot, and an image
-## file, @file{@var{filename}.(eps|pdf)}, for the graph portion of the plot.
-## The @samp{standalone} variants behave as described for
+##   @item  epscairo*
+##   @itemx pdfcairo*
+##   @itemx epscairolatex*
+##   @itemx pdfcairolatex*
+##   @itemx epscairolatexstandalone*
+##   @itemx pdfcairolatexstandalone*
+##     Generate Cairo based output.  The @samp{epscairo} and
+## @samp{pdfcairo} devices are synonymous with the @samp{epsc} device.
+## The @LaTeX{} variants generate a @LaTeX{} file,
+## @file{@var{filename}.tex}, for the text portions of a plot, and an
+## image file, @file{@var{filename}.(eps|pdf)}, for the graph portion of
+## the plot.  The @samp{standalone} variants behave as described for
 ## @samp{epslatexstandalone} above.
 ##
 ##   @item  ill
 ##   @itemx aifm
-##     Adobe Illustrator (Obsolete for Gnuplot versions > 4.2)
+##     Adobe Illustrator (Obsolete for Gnuplot versions > 4.2).
 ##
-##   @item canvas
-##     Javascript-based drawing on HTML5 canvas viewable in a web browser
-## (only available for the Gnuplot graphics toolkit).
+##   @item canvas*
+##     Javascript-based drawing on HTML5 canvas viewable in a web browser.
 ##
-##   @item  cdr
-##   @itemx @nospell{corel}
-##     CorelDraw
+##   @item  cdr*
+##   @itemx @nospell{corel*}
+##     CorelDraw. 
 ##
 ##   @item dxf
 ##     AutoCAD
@@ -164,8 +169,8 @@
 ## whether the special flag should be set for the text in the figure.
 ## (default is @option{-textnormal})
 ##
-##   @item gif
-##     GIF image (only available for the Gnuplot graphics toolkit)
+##   @item gif*
+##     GIF image.
 ##
 ##   @item hpgl
 ##     HP plotter language
@@ -174,9 +179,8 @@
 ##   @itemx jpeg
 ##     JPEG image
 ##
-##   @item latex
-##     @LaTeX{} picture environment (only available for the Gnuplot graphics
-## toolkit).
+##   @item latex*
+##     @LaTeX{} picture environment.
 ##
 ##   @item mf
 ##     Metafont
@@ -188,18 +192,19 @@
 ##     PBMplus
 ##
 ##   @item pdf
-##     Portable document format
+##   @itemx pdfcrop
+##     Portable document format. The pdfcrop device removes the default
+## surrounding page 
 ##
 ##   @item svg
 ##     Scalable vector graphics
 ##
 ##   @item  tikz
-##   @itemx tikzstandalone
+##   @itemx tikzstandalone*
 ##     Generate a @LaTeX{} file using PGF/TikZ format.  The OpenGL-based
 ## toolkits create a PGF file while Gnuplot creates a TikZ file.  The
 ## @samp{tikzstandalone} device produces a @LaTeX{} document which includes the
-## TikZ file (@samp{tikzstandalone} and is only available for the Gnuplot
-## graphics toolkit).
+## TikZ file.
 ##   @end table
 ##
 ##   If the device is omitted, it is inferred from the file extension,
@@ -210,9 +215,6 @@
 ## Some examples are;
 ##
 ##   @table @code
-##   @item pdfwrite
-##     Produces pdf output from eps
-##
 ##   @item ljet2p
 ##     HP LaserJet @nospell{IIP}
 ##
@@ -336,6 +338,7 @@
   opts.latex_standalone = @latex_standalone;
   opts.lpr_cmd = @lpr;
   opts.epstool_cmd = @epstool;
+  opts.svgconvert_cmd = @svgconvert;
 
   if (isempty (opts.figure) || ! isfigure (opts.figure))
     error ("print: no figure to print");
@@ -387,11 +390,11 @@
       nfig += 1;
     endfor
 
-    ## FIXME: line transparency is only handled for svg output when
-    ## using gl2ps. For other formats, switch grid lines to light gray
+    ## FIXME: line transparency is not handled for postscript output when
+    ## using opengl toolkits. For ps formats, switch grid lines to light gray
     ## so that the image output approximately matches on-screen experience.
     hax = findall (opts.figure, "type", "axes");
-    if (! strcmp (tk, "gnuplot") && ! strcmp (opts.devopt, "svg"))
+    if (! strcmp (tk, "gnuplot") && strcmp (opts.devopt, "ps2write"))
       for n = 1:numel (hax)
         if (strcmp (get (hax(n), "gridcolormode"), "auto"))
           props(end+1).h = hax(n);
@@ -877,3 +880,28 @@
   endif
 
 endfunction
+
+function cmd = svgconvert (opts, devopt)
+
+  cmd = "";
+  
+  if (nargin < 2)
+    devopt = opts.devopt;
+  endif
+
+  if (isempty (opts.svgconvert_binary))
+    warning ("print:nosvgconvert", ...
+             "print.m: falling back to eps convertion");
+  else
+    dos_shell = (ispc () && ! isunix ());
+    font = fullfile (__octave_config_info__ ("datadir"), "font", "FreeSans.otf");
+    cmd = sprintf ("%s - pdf %3.2f %s %d %%s", opts.svgconvert_binary, ...
+                   get (0, "screenpixelsperinch"), font, ...
+                   strcmp (opts.devopt, "pdfwrite"));
+
+    if (opts.debug)
+      fprintf ("svgconvert command: '%s'\n", cmd);
+    endif
+  endif
+
+endfunction
diff -r f3d754deb41d -r f6aeb190f7ce scripts/plot/util/private/__opengl_print__.m
--- a/scripts/plot/util/private/__opengl_print__.m	Wed Nov 08 16:34:23 2017 +0100
+++ b/scripts/plot/util/private/__opengl_print__.m	Thu Nov 16 15:02:11 2017 +0100
@@ -113,10 +113,22 @@
       pipeline = {sprintf("%s > %s", cmd, opts.name)};
     case {"corel", "gif"}
       error ("print:unsupporteddevice",
-             "print.m: %s output is not available for the FLTK graphics toolkit",
+             "print.m: %s output is not available for OpenGL graphics toolkits",
              upper (opts.devopt));
     case opts.ghostscript.device
-      opts.ghostscript.source = "-";
+      ## Except for postscript, use svg format and first convert to pdf
+      ## before going through ghostscript for final adjusments
+      svgcmd = opts.svgconvert_cmd (opts, opts.ghostscript.device);
+      dosvg = ! (strcmp (opts.devopt, "ps2write") || isempty (svgcmd)); 
+      if (! dosvg)
+        opts.ghostscript.source = "-";
+      else
+        tmp = tempname ();
+        opts.ghostscript.source = tmp;
+        opts.unlink = [opts.unlink tmp];
+        svgcmd = sprintf (svgcmd, tmp);
+      endif
+      
       opts.ghostscript.output = opts.name;
       if (opts.send_to_printer)
         opts.unlink(strcmp (opts.unlink, opts.ghostscript.output)) = [];
@@ -126,23 +138,34 @@
       if (opts.send_to_printer || isempty (opts.name))
         cmd_lpr = opts.lpr_cmd (opts);
         cmd = sprintf ("%s | %s", cmd_gs, cmd_lpr);
+      elseif (dosvg)
+        if (dos_shell)
+          cmd = sprintf ("%s & %s", svgcmd, cmd_gs); 
+        else
+          cmd = sprintf ("%s ; %s", svgcmd, cmd_gs); 
+        endif
       else
         cmd = sprintf ("%s", cmd_gs);
       endif
+      
+      if (dosvg)
+        gl2ps_device = {"svg"};
+      else
+        gl2ps_device = {"eps"};
+      endif
+      
       if (! isempty (cmd_cleanup))
-        gl2ps_device = {"eps"};
         if (dos_shell)
           pipeline = {sprintf("%s & %s", cmd, cmd_cleanup)};
         else
           pipeline = {sprintf("%s ; %s", cmd, cmd_cleanup)};
         endif
       else
-        gl2ps_device = {"eps"};
         pipeline = {cmd};
       endif
     otherwise
       error (sprintf ("print:no%soutput", opts.devopt),
-             "print.m: %s output is not available for GL2PS output",
+             "print.m: %s output is not available for OpenGL toolkits",
              upper (opts.devopt));
   endswitch
 
@@ -152,7 +175,7 @@
     if (opts.debug)
       fprintf ("opengl-pipeline: '%s'\n", pipeline{n});
     endif
-
+    
     if (strcmp (get (opts.figure, "visible"), "on"))
       ## Use toolkits "print_figure" method
       drawnow (gl2ps_device{n}, ['|' pipeline{n}]);
diff -r f3d754deb41d -r f6aeb190f7ce scripts/plot/util/private/__print_parse_opts__.m
--- a/scripts/plot/util/private/__print_parse_opts__.m	Wed Nov 08 16:34:23 2017 +0100
+++ b/scripts/plot/util/private/__print_parse_opts__.m	Thu Nov 16 15:02:11 2017 +0100
@@ -60,6 +60,7 @@
   arg_st.printer = "";
   arg_st.send_to_printer = false;
   arg_st.special_flag = "textnormal";
+  arg_st.svgconvert_binary = __quote_path__ (__svg_conv_binary__ ());
   arg_st.tight_flag = false;
   arg_st.use_color = 0; # 0=default, -1=mono, +1=color
 
@@ -211,6 +212,8 @@
     arg_st.devopt = "emf";
   elseif (strcmp (arg_st.devopt, "jpg"))
     arg_st.devopt = "jpeg";
+  elseif (strcmp (arg_st.devopt, "pdfcrop"))
+    arg_st.devopt = "pdfwrite";
   endif
 
   persistent dev_list = {"aifm", "corel", "fig", "png", "jpeg", ...
@@ -219,7 +222,7 @@
               "psc2", "eps", "eps2", "epsc", "epsc2", ...
               "emf", "pdf", "pslatex", "epslatex", "epslatexstandalone", ...
               "pslatexstandalone", "pdflatexstandalone", ...
-              "pstex", "tiff", "tiffn" "tikz", "pcxmono", ...
+              "pstex", "tiff", "tiffn" "tikz", "tikzstandalone", "pcxmono", ...
               "pcx24b", "pcx256", "pcx16", "pgm", "pgmraw", ...
               "ppm", "ppmraw", "pdflatex", "texdraw", ...
               "epscairo", "pdfcairo", "pngcairo", "cairolatex", ...
@@ -454,7 +457,6 @@
 
 endfunction
 
-
 function gs = __ghostscript_binary__ ()
 
   persistent ghostscript_binary = "";
@@ -492,6 +494,32 @@
 
 endfunction
 
+function bin = __svg_conv_binary__ ()
+
+  persistent binary = "";
+  
+  if (isempty (binary))
+    binary = getenv ("OCTAVE_SVGCONVERT");
+    if (isempty (binary))
+      ## Look into bindir
+      binary = fullfile (__octave_config_info__ ("libdir"), ...
+                         "octave_svgconvert");
+    endif
+    
+    if (isempty (binary) || ! exist (binary, "file"))
+      warning ("print:nosvgconvert", ...
+               "print: unable to find octave svg converter binary")
+      binary = "";
+    elseif (! isunix ())
+      ## Unix - Includes Mac OSX and Cygwin.
+      binary = [binary, ".exe"];
+    endif
+  endif
+
+  bin = binary;
+
+endfunction
+
 function bin = __find_binary__ (binary)
 
   persistent data = struct ();
