diff scripts/plot/print.m @ 10834:05ba991794d4

Improvements for fltk printing.
author Ben Abbott <bpabbott@mac.com>
date Thu, 29 Jul 2010 19:44:07 -0400
parents 693e22af08ae
children 1577accf2ed8
line wrap: on
line diff
--- a/scripts/plot/print.m	Thu Jul 29 17:49:50 2010 -0400
+++ b/scripts/plot/print.m	Thu Jul 29 19:44:07 2010 -0400
@@ -32,7 +32,12 @@
 ## the handle for the current figure is used.
 ##
 ## @var{options}:
+##
 ## @table @code
+## @item -f@var{h}
+##   Specify the handle, @var{h}, of the figure to be printed. The
+##   default is the current figure.
+##
 ## @item -P@var{printer}
 ##   Set the @var{printer} name to which the graph is sent if no
 ##   @var{filename} is specified.
@@ -156,6 +161,9 @@
 ##
 ##   @item ppm
 ##     Portable Pixel Map file format
+##
+##   @item pdfwrite
+##     Converts ps or eps to pdf
 ##   @end table
 ##
 ##   For a complete list, type `system ("gs -h")' to see what formats
@@ -200,13 +208,219 @@
 ## The filename and options can be given in any order.
 ## @end deftypefn
 
-function varargout = print (varargin)
+function print (varargin)
+
+  opts = __print_parse_opts__ (varargin{:});
 
-  f = gcf ();
+  if (! isfigure (opts.figure))
+    error ("print: no figure to print.")
+  endif
+
+  orig_figure = get (0, "currentfigure");
+  figure (opts.figure)
   drawnow ();
-  backend = (get (f, "__backend__"));
+  backend = (get (opts.figure, "__backend__"));
+
+  if (strcmp (backend, "gnuplot"))
+    ## FIXME - this can be removed when __gnuplot_print__ has been modified
+    ##         to work consistently with __fltk_print__
+    __gnuplot_print__ (varargin{:});
+    return
+  endif
+
+  ## FIXME - this can be moved to __print_parse_opts__ when __gnuplot_print__
+  ##         has been modified to work consistently with __fltk_print__
+  if (! isempty (opts.canvas_size) && ischar (opts.resolution))
+    opts.canvas_size = str2num (strrep (strrep (opts.canvas_size, "X", ""), "Y", ""));
+  endif
+  if (! isempty (opts.resolution) && ischar (opts.resolution))
+    opts.resolution = str2num (opts.resolution);
+  endif
+  if (! isempty (opts.fontsize) && ischar (opts.fontsize))
+    opts.fontsize = str2num (opts.fontsize);
+  endif
+
+  if (opts.append_to_file)
+    saved_original_file = strcat (tmpnam (), ".", opts.devopt);
+    opts.unlink(end+1) = {save_original_file};
+    movefile (opts.name, saved_original_file);
+  endif
+
+  ## Modify properties as specified by options
+  ## FIXME - need an unwind_protect block
+  props = [];
+
+  if ((! isempty (opts.canvas_size))
+      || (! strcmpi (get (opts.figure, "paperorientation"), opts.orientation)))
+    m = numel (props);
+    props(m+1).h = opts.figure;
+    props(m+1).name = "paperposition";
+    props(m+1).value = {get(opts.figure, "paperposition")};
+    props(m+2).h = opts.figure;
+    props(m+2).name = "paperunits";
+    props(m+2).value = {get(opts.figure, "paperunits")};
+    props(m+3).h = opts.figure;
+    props(m+3).name = "papersize";
+    props(m+3).value = {get(opts.figure, "papersize")};
+    props(m+4).h = opts.figure;
+    props(m+4).name = "paperorientation";
+    props(m+4).value = {get(opts.figure, "paperorientation")};
+    props(m+5).h = opts.figure;
+    props(m+5).name = "papertype";
+    props(m+5).value = {get(opts.figure, "papertype")};
+    if (! isempty (opts.canvas_size))
+      ## canvas_size is in pixels/points
+      set (opts.figure, "paperorientation", "portrait");
+      set (opts.figure, "paperposition", [0, 0, opts.canvas_size]);
+      set (opts.figure, "paperunits", "points");
+      set (opts.figure, "papersize", opts.canvas_size);
+      fpos = get (opts.figure, "position");
+      props(m+6).h = opts.figure;
+      props(m+6).name = "position";
+      props(m+6).value = {fpos};
+      fpos(3:4) = opts.canvas_size;
+      set (opts.figure, "position", fpos);
+    elseif (opts.paperoutput)
+      ## FIXME - should the backend handle this?
+      orient (opts.orientation)
+    endif
+  endif
+
+  if (opts.force_solid != 0)
+    h = findobj (opts.figure, "-property", "linestyle");
+    m = numel (props);
+    for n = 1:numel(h)
+      props(m+n).h = h(n);
+      props(m+n).name = "linestyle";
+      props(m+n).value = {get(h(n), "linestyle")};
+    endfor
+    if (opts.force_solid > 0)
+      linestyle = "-";
+    else
+      linestyle = "--";
+    endif
+    set (h, "linestyle", linestyle)
+  endif
 
-  varargout = cell (1, nargout);
-  [varargout{:}] = feval (strcat ("__", backend, "_print__"), varargin{:});
+  if (opts.use_color < 0)
+    color_props = {"color", "facecolor", "edgecolor"};
+    for c = 1:numel(color_props)
+      h = findobj (opts.figure, "-property", color_props{c});
+      hnone = findobj (opts.figure, color_props{c}, "none");
+      h = setdiff (h, hnone);
+      m = numel (props);
+      for n = 1:numel(h)
+        rgb = get (h(n), color_props{c});
+        props(m+n).h = h(n);
+        props(m+n).name = color_props{c};
+        props(m+n).value = {get(h(n), color_props{c})};
+        xfer = repmat ([0.30, 0.59, 0.11], size (rgb, 1), 1);
+        ## convert RGB color to RGB gray scale
+        ggg = repmat (sum (xfer .* rgb, 2), 1, 3);
+        set (h(n), color_props{c}, ggg)
+      endfor
+    endfor
+  endif
+
+  if (! isempty (opts.font) || ! isempty (opts.fontsize))
+    h = findobj (opts.figure, "-property", "fontname");
+    m = numel (props);
+    for n = 1:numel(h)
+      if (! isempty (opts.font))
+        props(end+1).h = h(n);
+        props(end).name = "fontname";
+        props(end).value = {get(h(n), "fontname")};
+      endif
+      if (! isempty (opts.fontsize))
+        props(end+1).h = h(n);
+        props(end).name = "fontsize";
+        props(end).value = {get(h(n), "fontsize")};
+      endif
+    endfor
+    if (! isempty (opts.font))
+      set (h, "fontname", opts.font)
+    endif
+    if (! isempty (opts.fontsize))
+      if (ischar (opts.fontsize))
+        fontsize = str2double (opts.fontsize);
+      else
+        fontsize = opts.fontsize;
+      endif
+      set (h, "fontsize", fontsize)
+    endif
+  endif
+
+  ## call the backend print script
+  drawnow ("expose")
+  feval (strcat ("__", backend, "_print__"), opts);
+
+  ## restore modified properties
+  if (isstruct (props))
+    for n = 1:numel(props)
+      set (props(n).h, props(n).name, props(n).value{1})
+    endfor
+  endif
+
+  ## Send to the printer
+  if (opts.send_to_printer)
+    if (isempty (opts.ghostscript_output))
+      prn_datafile = opts.name;
+    else
+      prn_datafile = opts.ghostscript_output;
+    endif
+    if (isempty (opts.printer))
+      prn_cmd = sprintf ("lpr %s '%s' 2>&1", opts.lpr_options, prn_datafile);
+    else
+      prn_cmd = sprintf ("lpr %s -P %s '%s' 2>&1", opts.lpr_options,
+                         opts.printer, prn_datafile);
+    endif
+    if (opts.debug)
+      fprintf ("lpr command: %s\n", prn_cmd)
+    endif
+    [status, output] = system (prn_cmd);
+    if (status != 0)
+      disp (output)
+      warning ("print.m: printing failed.")
+    endif
+  endif
+
+  ## Append to file using GS
+  if (opts.append_to_file)
+    if (strcmp (opts.devopt, "pdf"))
+      suffix = "pdf";
+    elseif (strcmp (opts.devopt(1:2), "ps"))
+      suffix = "ps";
+    endif
+    tmp_combined_file = strcat (tmpnam (), ".", suffix);
+    opts.unlink{end+1} = tmp_combined_file;
+    gs_opts = "-q -dNOPAUSE -dBATCH";
+    gs_cmd = sprintf ("%s %s -sDEVICE=%swrite -sOutputFile=%s %s %s", 
+             opts.ghostscript_binary, gs_opts, suffix, tmp_combined_file,
+             saved_original_file, opts.name);
+    [status, output] = system (gs_cmd);
+    if (opts.debug)
+      fprintf ("Append files: %s\n", gs_cmd);
+    endif
+    if (status != 0)
+      warning ("print:failedtoappendfile", 
+               "print.m: failed to append output to file '%s'.", opts.name)
+      movefile (saved_original_file, opts.name);
+    else
+      movefile (tmp_combined_file, opts.name);
+    endif
+  endif
+
+  ## Unlink temporary files
+  for n = 1:numel(opts.unlink)
+    [status, output] = unlink (opts.unlink{n});
+    if (status != 0)
+      disp (output)
+      warning ("print.m: failed to delete temporay file, '%s'.", opts.name)
+    endif
+  endfor
+
+  if (isfigure (orig_figure))
+    figure (orig_figure);
+  endif
 
 endfunction