Mercurial > hg > octave-max
changeset 10854:d5a7db05d591
Add PS and PDF output for the fltk backend.
author | Ben Abbott <bpabbott@mac.com> |
---|---|
date | Wed, 04 Aug 2010 20:32:49 -0400 |
parents | c3813056f94f |
children | 5162c67c949e |
files | scripts/ChangeLog scripts/plot/__fltk_print__.m scripts/plot/__gnuplot_print__.m scripts/plot/__print_parse_opts__.m scripts/plot/print.m scripts/plot/private/__ghostscript__.m |
diffstat | 6 files changed, 400 insertions(+), 220 deletions(-) [+] |
line wrap: on
line diff
--- a/scripts/ChangeLog +++ b/scripts/ChangeLog @@ -3,6 +3,13 @@ * general/sortrows.m: Don't actually permute the rows if not requested. +2010-08-04 Ben Abbott <bpabbott@mac.com> + + * /plot/print.m, plot/__print_parse_opts__.m, plot/__gnuplot_print__.m, + plot/private/__ghostscript__.m: plot/__fltk_print__.m: Add ps and pdf + output for fltk backend, improved use of ghostscript, and minor + improvements. + 2010-08-01 Rik <octave@nomad.inbox5.com> * deprecated/intwarning.m, general/arrayfun.m, general/cplxpair.m,
--- a/scripts/plot/__fltk_print__.m +++ b/scripts/plot/__fltk_print__.m @@ -23,11 +23,14 @@ function __fltk_print__ (opts) - if (opts.debug) - fprintf ("FLTK backend: output file = '%s' for device '%s'\n", opts.name, opts.devopt); + file2unlink = ""; + + if (! isempty (opts.fig2dev_binary)) + fig2dev_devices = {"pstex", "mf", "emf"}; + else + ## If no fig2dev is present, support emf using pstoedit. + fig2dev_devices = {"pstex", "mf"}; endif - - file2unlink = ""; switch lower (opts.devopt) case {"eps", "eps2", "epsc", "epsc2"} @@ -44,41 +47,66 @@ case {"tikz"} ## FIXME - format GL2PS_PGF if not implemented drawnow ("pgf", opts.name); - case {"ps", "ps2", "psc", "psc2"} - ## FIXME - format GL2PS_PS if not implemented - drawnow ("ps", opts.name); - case {"pdf"} - ## FIXME - format GL2PS_PDF if not implemented - drawnow ("pdf", opts.name); + case {"ps", "ps2", "psc", "psc2", "pdf"} + opts.ghostscript.source = strcat (tmpnam (), ".eps"); + file2unlink = opts.ghostscript.source; + if (strcmp (opts.devopt, "pdf")) + opts.ghostscript.device = "pdfwrite"; + else + opts.ghostscript.device = "pswrite"; + endif + opts.ghostscript.output = opts.name; + drawnow ("eps", opts.ghostscript.source); + if (opts.tight_flag) + __tight_eps_bbox__ (opts, opts.ghostscript.source); + endif case {"svg"} ## FIXME - format GL2PS_SVG if not implemented drawnow ("svg", opts.name); - case {"gif", "jpeg", "png", "pbm"} - opts.ghostscript_device = opts.devopt; - opts.ghostscript_output = opts.name; - opts.name = strcat (tmpnam (), ".eps"); - file2unlink = opts.name; - opts.devopt = "epsc"; - drawnow ("eps", opts.name); + case {"jpeg", "pbm", "pbmraw", "pcx24b", "pcx256", "pcx16", ... + "pgm", "pgmraw", "png", "ppm", "ppmraw", "pdfwrite", ... + "tiff", "tiffn"} + switch opts.devopt + case "png" + opts.ghostscript.device = "png256"; + case {"tiff", "tiffn"} + opts.ghostscript.device = "tiff24nc"; + otherwise + opts.ghostscript.device = opts.devopt; + endswitch + opts.ghostscript.output = opts.name; + opts.ghostscript.source = strcat (tmpnam (), ".eps"); + opts.ghostscript.epscrop = true; + file2unlink = opts.ghostscript.source; + drawnow ("eps", opts.ghostscript.source) if (opts.tight_flag) - __tight_eps_bbox__ (opts, opts.name); + __tight_eps_bbox__ (opts, opts.ghostscript.source); endif - case {"aifm", "dxf", "emf", "fig", "hpgl"} - status = __pstoedit__ (opts); - case {"pstex", "mf", "emf"} + case fig2dev_devices tmp_figfile = strcat (tmpnam (), ".fig"); file2unlink = tmp_figfile; status = __pstoedit__ (opts, "fig", tmp_figfile); if (status == 0) status = __fig2dev__ (opts, tmp_figfile); endif + case {"aifm", "dxf", "emf", "fig", "hpgl"}; + status = __pstoedit__ (opts); otherwise - error ("print:unavailabledevice", - "print.m: device '%s' is unavailable for the fltk backend.", opts.devopt) + ## various ghostscript devices for printers + opts.ghostscript.device = opts.devopt; + opts.ghostscript.output = opts.name; + opts.ghostscript.epscrop = false; + opts.ghostscript.source = strcat (tmpnam (), ".eps"); + file2unlink = opts.ghostscript.source; + drawnow ("eps", opts.ghostscript.source) + if (opts.tight_flag) + __tight_eps_bbox__ (opts, opts.ghostscript.source); + endif endswitch - if (! isempty (opts.ghostscript_device)) - __ghostscript__ (opts); + ## FIXME - warning: unrecognized escape sequence `\P' -- converting to `P' + if (! isempty (opts.ghostscript.device)) + status = __ghostscript__ (opts.ghostscript); endif if (! isempty (file2unlink))
--- a/scripts/plot/__gnuplot_print__.m +++ b/scripts/plot/__gnuplot_print__.m @@ -25,13 +25,12 @@ ## Author: Daniel Heiserer <Daniel.heiserer@physik.tu-muenchen.de> ## Adapted-By: jwe -function __gnuplot_print__ (varargin) +function __gnuplot_print__ (opts) persistent warn_on_inconsistent_orientation = true old_fig = get (0, "currentfigure"); unwind_protect - opts = __print_parse_opts__ (varargin{:}); have_ghostscript = ! isempty (opts.ghostscript_binary); doprint = isempty (opts.name); @@ -255,7 +254,7 @@ options = ""; end if (! isempty (opts.canvas_size)) - options = cstrcat (options, " size ", opts.canvas_size); + options = sprintf ("%s size %d, %d", options, opts.canvas_size); endif elseif (any (strcmp (dev, {"dxf", "mf", "hpgl"}))) @@ -395,7 +394,7 @@ ## render an image the size of the paperposition box. ## Trigger the listener to convert all paper props to inches. if (! isempty (opts.canvas_size)) - size_in_pixels = sscanf (opts.canvas_size ,"%d, %d"); + size_in_pixels = opts.canvas_size; size_in_pixels = reshape (size_in_pixels, [1, numel(size_in_pixels)]); papersize_in_inches = size_in_pixels ./ opts.resolution; paperposition_in_inches = [0, 0, papersize_in_inches];
--- a/scripts/plot/__print_parse_opts__.m +++ b/scripts/plot/__print_parse_opts__.m @@ -26,9 +26,8 @@ function arg_st = __print_parse_opts__ (varargin) - ## FIXME - change to numeric values: `canvas_size', `resolution', `fontsize' arg_st.append_to_file = false; - arg_st.canvas_size = ""; + arg_st.canvas_size = []; arg_st.debug = false; arg_st.debug_file = "octave-print-commands.log"; arg_st.devopt = ""; @@ -37,14 +36,18 @@ arg_st.fontsize = ""; arg_st.font = ""; arg_st.force_solid = 0; # 0=default, -1=dashed, +1=solid - arg_st.ghostscript_binary = __ghostscript_binary__ (); - arg_st.ghostscript_device = ""; # gs converts eps/ps to this format/printer-language - arg_st.ghostscript_output = ""; # gs converts arg_st.name to arg_st.ghostscript_output + arg_st.ghostscript.binary = __ghostscript_binary__ (); + arg_st.ghostscript.device = ""; + arg_st.ghostscript.output = ""; + arg_st.ghostscript.papersize = ""; + arg_st.ghostscript.pageoffset = []; + arg_st.ghostscript.debug = false; + arg_st.ghostscript.epscrop = false; + arg_st.ghostscript.resolution = 150; + arg_st.orientation = ""; arg_st.pstoedit_binary = __find_binary__ ("pstoedit"); - arg_st.name = ""; # This is the file produced by the backend - arg_st.orientation = ""; + arg_st.name = ""; arg_st.printer = ""; - arg_st.resolution = num2str (get (0, "screenpixelsperinch")); arg_st.special_flag = "textnormal"; arg_st.tight_flag = false; arg_st.use_color = 0; # 0=default, -1=mono, +1=color @@ -73,9 +76,9 @@ arg_st.force_solid = 1; elseif (strcmp (arg, "-dashed")) arg_st.force_solid = -1; - elseif (strcmp (arg, "-portrait")) + elseif (strncmp (arg, "-portrait", numel (arg))) arg_st.orientation = "portrait"; - elseif (strcmp (arg, "-landscape")) + elseif (strncmp (arg, "-landscape", numel (arg))) arg_st.orientation = "landscape"; elseif (strcmp (arg, "-tight")) arg_st.tight_flag = true; @@ -83,6 +86,7 @@ arg_st.special_flag = "textspecial"; elseif (strncmp (arg, "-debug", 6)) arg_st.debug = true; + arg_st.ghostscript.debug = true; if (length (arg) > 7) arg_st.debug_file = arg(8:end); endif @@ -91,25 +95,25 @@ elseif (length (arg) > 2 && arg(1:2) == "-P") arg_st.printer = arg; elseif ((length (arg) > 2) && arg(1:2) == "-G") - arg_st.ghostscript_binary = arg(3:end); - if (exist (arg_st.ghostscript_binary, "file") != 2) - arg_st.ghostscript_binary = file_in_path (EXEC_PATH, arg_st.ghostscript_binary); + arg_st.ghostscript.binary = arg(3:end); + if (exist (arg_st.ghostscript.binary, "file") != 2) + arg_st.ghostscript.binary = file_in_path (EXEC_PATH, arg_st.ghostscript.binary); endif - if (isempty (arg_st.ghostscript_binary)) + if (isempty (arg_st.ghostscript.binary)) error ("print: Ghostscript binary ""%s"" could not be located", arg(3:end)) endif elseif (length (arg) > 2 && arg(1:2) == "-F") idx = rindex (arg, ":"); if (idx) arg_st.font = arg(3:idx-1); - arg_st.fontsize = arg(idx+1:length(arg)); + arg_st.fontsize = str2num (arg(idx+1:end)); else - arg_st.font = arg(3:length(arg)); + arg_st.font = arg(3:end); endif elseif (length (arg) > 2 && arg(1:2) == "-S") - arg_st.canvas_size = arg(3:length(arg)); + arg_st.canvas_size = str2num (arg(3:end)); elseif (length (arg) > 2 && arg(1:2) == "-r") - arg_st.resolution = arg(3:length(arg)); + arg_st.ghostscript.resolution = arg(3:end); elseif (length (arg) > 2 && arg(1:2) == "-f") arg_st.figure = str2num (arg(3:end)); elseif (length (arg) >= 1 && arg(1) == "-") @@ -124,17 +128,22 @@ endif endfor + if (arg_st.ghostscript.resolution == 0) + ## Do as Matlab does. + arg_st.ghostscript.resolution = num2str (get (0, "screenpixelsperinch")); + endif + if (isempty (arg_st.orientation)) if (isfigure (arg_st.figure)) arg_st.orientation = get (arg_st.figure, "paperorientation"); else ## Allows tests to be run without error. - arg_st.orientation = get (0, "defaultfigurepaperorientation"); + arg_st.orientation = get (0, "portrait"); endif endif - if (isempty (arg_st.ghostscript_binary)) - arg_st.ghostscript_binary = __ghostscript_binary__ (); + if (isempty (arg_st.ghostscript.binary)) + arg_st.ghostscript.binary = __ghostscript_binary__ (); endif dot = rindex (arg_st.name, "."); @@ -146,8 +155,8 @@ endif endif - if (any (strcmp ({"ps", "ps2", "eps", "eps2"}, arg_st.devopt)) - || (! isempty (strfind (arg_st.devopt, "tex")) && arg_st.use_color == 0)) + if ((any (strcmp ({"ps", "ps2", "eps", "eps2"}, arg_st.devopt)) + || (! isempty (strfind (arg_st.devopt, "tex")))) && arg_st.use_color == 0) ## Mono is the default for ps, eps, and the tex/latex, devices arg_st.use_color = -1; elseif (arg_st.use_color == 0) @@ -155,14 +164,20 @@ endif if (arg_st.append_to_file) - if (any (strcmpi (arg_st.devopt, {"ps", "ps2", "psc", "psc2", "pdf"}))) + if (isempty (arg_st.name)) + arg_st.append_to_file = false; + elseif (any (strcmpi (arg_st.devopt, {"eps", "eps2", "epsc", "epsc2", ... + "ps", "ps2", "psc", "psc2", "pdf"}))) have_ghostscript = ! isempty (__ghostscript_binary__ ()); if (have_ghostscript) file_exists = ((numel (dir (arg_st.name)) == 1) && (! isdir (arg_st.name))); if (! file_exists) arg_st.append_to_file = false; end - end + else + arg_st.append_to_file = false; + warning ("print.m: appended output requires ghostscript to be installed.") + endif else warning ("print.m: appended output is not supported for device '%s'", arg_st.devopt) arg_st.append_to_file = false; @@ -189,16 +204,22 @@ endif dev_list = {"aifm", "corel", "fig", "png", "jpeg", ... - "gif", "pbm", "dxf", "mf", "svg", "hpgl", ... - "ps", "ps2", "psc", "psc2", "eps", "eps2", ... - "epsc", "epsc2", "emf", "pdf", "pslatex", ... - "epslatex", "epslatexstandalone", "pstex", "tikz"}; + "gif", "pbm", "pbmraw", "dxf", "mf", ... + "svg", "hpgl", "ps", "ps2", "psc", ... + "psc2", "eps", "eps2", "epsc", "epsc2", ... + "emf", "pdf", "pslatex", "epslatex", "epslatexstandalone", ... + "pstex", "tiff", "tiffn" "tikz", "pcxmono", ... + "pcx24b", "pcx256", "pcx16", "pgm", "pgmraw", ... + "ppm", "ppmraw"}; suffixes = {"ai", "cdr", "fig", "png", "jpg", ... - "gif", "pbm", "dxf", "mf", "svg", "hpgl", ... - "ps", "ps", "ps", "ps", "eps", "eps", ... - "eps", "eps", "emf", "pdf", "tex", ... - "tex", "tex", "tex", "tikz"}; + "gif", "pbm", "pbm", "dxf", "mf", ... + "svg", "hpgl", "ps", "ps", "ps", ... + "ps", "eps", "eps", "eps", "eps", ... + "emf", "pdf", "tex", "tex", "tex", ... + "tex", "tiff", "tiff", "tikz", "pcx", ... + "pcx", "pcx", "pcx", "pgm", "pgm", ... + "ppm", "ppm"}; match = strcmpi (dev_list, arg_st.devopt); if (any (match)) @@ -220,34 +241,29 @@ endif if (all (! strcmp (arg_st.devopt, dev_list))) - arg_st.ghostscript_device = arg_st.devopt; - arg_st.ghostscript_output = arg_st.name; - ## FIXME - This will not work correctly if GS is used to produce a print - ## stream that is saved to a file and not sent to the printer. - if (arg_st.send_to_printer) - arg_st.devopt = "psc"; - arg_st.name = strcat (tmpnam (), ".ps"); - arg_st.unlink{end+1} = arg_st.name; - else - ## Assume the user desires only the figuure. This is useful for producing - ## pdf figures for pdflatex - ## octave:#> print -f1 -dpdfwrite figure1.pdf - arg_st.devopt = "epsc"; - arg_st.name = strcat (tmpnam (), ".eps"); - arg_st.unlink{end+1} = arg_st.name; - endif + arg_st.ghostscript.device = arg_st.devopt; + arg_st.ghostscript.output = arg_st.name; endif - if (any (strncmp (arg_st.devopt(1:2), {"ps", "pdf"}, 2))) - arg_st.paperoutput = true; + if (isempty (arg_st.canvas_size)) + if (isfigure (arg_st.figure)) + [arg_st.ghostscript.papersize, paperposition] = gs_papersize (arg_st.figure, + arg_st.orientation); + else + ## allows tests to be run + arg_st.ghostscript.papersize = "letter"; + paperposition = [0.25, 2.50, 8.00, 6.00] * 72; + endif + arg_st.canvas_size = paperposition(3:4); + arg_st.ghostscript.pageoffset = paperposition(1:2); else - arg_st.paperoutput = false; + ## Canvas size in points. + arg_st.canvas_size = arg_st.canvas_size * 72 / arg_st.ghostscript.resolution; + arg_st.ghostscript.papersize = arg_st.canvas_size; + arg_st.ghostscript.epscrop = true; + arg_st.ghostscript.pageoffset = [0, 0]; endif - if (arg_st.debug) - disp ("Printing options"); - disp (arg_st) - endif endfunction %!test @@ -255,20 +271,25 @@ %! assert (opts.devopt, "psc"); %! assert (opts.use_color, 1); %! assert (opts.send_to_printer, true); -%! assert (opts.paperoutput, true); %! assert (opts.name, opts.unlink{1}) +%! assert (opts.canvas_size, [576, 432]); +%! assert (opts.ghostscript.device, "") %! for n = 1:numel(opts.unlink) %! unlink (opts.unlink{n}); %! endfor %!test +%! opts = __print_parse_opts__ ("test.pdf", "-SX640,Y480"); +%! assert (opts.canvas_size, [307.2, 230.4], 0.1); + +%!test %! opts = __print_parse_opts__ ("-dpsc", "-append"); %! assert (opts.devopt, "psc"); %! assert (opts.name(end+(-2:0)), ".ps"); %! assert (opts.send_to_printer, true); %! assert (opts.use_color, 1); %! assert (opts.append_to_file, false); -%! assert (opts.paperoutput, true); +%! assert (opts.ghostscript.device, "") %! for n = 1:numel(opts.unlink) %! unlink (opts.unlink{n}); %! endfor @@ -277,9 +298,9 @@ %! opts = __print_parse_opts__ ("-deps", "-tight"); %! assert (opts.name, opts.unlink{1}) %! assert (opts.tight_flag, true); -%! assert (opts.paperoutput, false) %! assert (opts.send_to_printer, true); %! assert (opts.use_color, -1); +%! assert (opts.ghostscript.device, "") %! for n = 1:numel(opts.unlink) %! unlink (opts.unlink{n}); %! endfor @@ -288,31 +309,29 @@ %! opts = __print_parse_opts__ ("-djpg", "foobar", "-mono"); %! assert (opts.devopt, "jpeg") %! assert (opts.name, "foobar.jpg") -%! assert (opts.ghostscript_device, "") +%! assert (opts.ghostscript.device, "") %! assert (opts.send_to_printer, false); %! assert (opts.printer, ""); -%! assert (opts.paperoutput, false) %! assert (opts.use_color, -1); +%! assert (opts.ghostscript.device, "") %!test %! opts = __print_parse_opts__ ("-ddeskjet", "foobar", "-mono", "-Pmyprinter"); -%! assert (opts.ghostscript_output, "foobar.deskjet") -%! assert (opts.ghostscript_device, "deskjet") -%! assert (opts.devopt, "psc") +%! assert (opts.ghostscript.output, "foobar.deskjet") +%! assert (opts.ghostscript.device, "deskjet") +%! assert (opts.devopt, "deskjet") %! assert (opts.send_to_printer, true); %! assert (opts.printer, "-Pmyprinter"); -%! assert (opts.paperoutput, true) %! assert (opts.use_color, -1); %!test %! opts = __print_parse_opts__ ("-f5", "-dljet3"); -%! assert (opts.name, opts.unlink{2}) -%! assert (opts.ghostscript_output, opts.unlink{1}) -%! assert (strfind (opts.ghostscript_output, ".ljet3")) -%! assert (strfind (opts.name, ".ps")) -%! assert (opts.devopt, "psc") +%! assert (opts.name, opts.unlink{1}) +%! assert (opts.ghostscript.output, opts.unlink{1}) +%! assert (opts.ghostscript.device, "ljet3") +%! assert (strfind (opts.ghostscript.output, ".ljet3")) +%! assert (opts.devopt, "ljet3") %! assert (opts.send_to_printer, true); -%! assert (opts.paperoutput, true) %! assert (opts.figure, 5) %! for n = 1:numel(opts.unlink) %! unlink (opts.unlink{n}); @@ -393,4 +412,79 @@ endfunction +function [papersize, paperposition] = gs_papersize (hfig, paperorientation) + persistent papertypes papersizes + if (isempty (papertypes)) + papertypes = {"usletter", "uslegal", "a0", "a1", ... + "a2", "a3", "a4", "a5", ... + "b0", "b1", "b2", "b3", ... + "b4", "b5", "arch-a", "arch-b", ... + "arch-c", "arch-d", "arch-e", "a", ... + "b", "c", "d", "e", ... + "tabloid"}; + papersizes = [ 8.5, 11.0; 8.5, 14.0; 33.1, 46.8; 23.4, 33.1; + 16.5, 23.4; 11.7, 16.5; 8.3, 11.7; 5.8, 8.3; + 39.4, 55.7; 27.8, 39.4; 19.7, 27.8; 13.9, 19.7; + 9.8, 13.9; 6.9, 9.8; 9.0, 12.0; 12.0, 18.0; + 18.0, 24.0; 24.0, 36.0; 36.0, 48.0; 8.5, 11.0; + 11.0, 17.0; 18.0, 24.0; 24.0, 36.0; 36.0, 48.0; + 11.0, 17.0] * 72; + endif + + papertype = get (hfig, "papertype"); + paperunits = get (hfig, "paperunits"); + paperposition = get (hfig, "paperposition"); + if (strcmp (papertype, "<custom>")) + papersize = get (hfig, "papersize"); + papersize = convert2points (papersize , paperunits); + else + papersize = papersizes (strcmp (papertypes, papertype), :); + endif + + if (strcmp (paperunits, "normalized")) + paperposition = paperposition .* papersize([1,2,1,2]); + else + paperposition = convert2points (paperposition, paperunits); + endif + + ## FIXME - This will be obsoleted by listeners for paper properties. + ## Papersize is tall when portrait,and wide when landscape. + if ((papersize(1) > papersize(2) && strcmpi (paperorientation, "portrait")) + || (papersize(1) < papersize(2) && strcmpi (paperorientation, "landscape"))) + papersize = papersize ([2,1]); + paperposition = paperposition([2,1,4,3]); + endif + + if ((! strcmp (papertype, "<custom>")) && (strcmp (paperorientation, "portrait"))) + ## For portrait use the ghostscript name + papersize = papertype; + papersize(papersize=="-") = ""; + papersize = strrep (papersize, "us", ""); + switch papersize + case "a" + papersize = "letter"; + case {"b", "tabloid"} + papersize = "11x17"; + case {"c", "d", "e"} + papersize = strcat ("arch", papersize); + endswitch + if (strncmp (papersize, "arch", 4)) + papersize(end) = upper (papersize(end)); + endif + endif + +endfunction + +function value = convert2points (value, units) + switch units + case {"inches"} + value = value * 72; + case {"centimeters"} + value = value * 72 / 25.4; + case {"normalized"} + error ("print:customnormalized", + "print.m: papersize=='<custom>' and paperunits='normalized' may not be combined.") + endswitch +endfunction +
--- a/scripts/plot/print.m +++ b/scripts/plot/print.m @@ -21,42 +21,46 @@ ## @deftypefnx {Function File} {} print (@var{options}) ## @deftypefnx {Function File} {} print (@var{filename}, @var{options}) ## @deftypefnx {Function File} {} print (@var{h}, @var{filename}, @var{options}) -## Print a plot, or save it to a file. +## Print a graph, or save it to a file ## -## @var{filename} specifies the name of the output file. If the -## file name has no suffix, then one is inferred from the specified +## @var{filename} defines the file name of the output file. If the +## file name has no suffix, one is inferred from the specified ## device and appended to the file name. If no -## filename is specified the output is sent to the printer. +## filename is specified, the output is sent to the printer. ## -## @var{h} specifies the figure handle to print. If no handle is specified +## @var{h} specifies the figure handle. If no handle is specified ## 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. +## 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 plot is sent when no -## @var{filename} is specified. +## Set the @var{printer} name to which the graph is sent if no +## @var{filename} is specified. ## ## @item -G@var{ghostscript_command} -## Specify the command for invoking Ghostscript. The defaults for Unix and -## Windows are 'gs' and 'gswin32c' respectively. +## Specify the command for calling Ghostscript. For Unix and Windows, +## the defaults are 'gs' and 'gswin32c', respectively. ## ## @item -color ## @itemx -mono -## Print monochrome or color lines. +## Monochrome or color output. ## ## @item -solid ## @itemx -dashed -## Print solid or dashed lines. +## Forces all lines to be solid or dashed, respectively. ## ## @item -portrait ## @itemx -landscape -## Specify the orientation of the plot for printed output. +## Specify the orientation of the plot for printed output. For +## non-printed output the aspect ratio of the output corresponds to +## the plot area defined by the "paperposition" property in the +## orientation specified. This options is equivalent to changing +## the figure's "paperorientation" property. ## ## @item -d@var{device} ## Output device, where @var{device} is one of: @@ -65,13 +69,15 @@ ## @itemx ps2 ## @itemx psc ## @itemx psc2 -## Postscript (level 1 and 2, mono and color) +## Postscript (level 1 and 2, mono and color). The FLTK backend +## generates Postscript level 3.0. ## ## @item eps ## @itemx eps2 ## @itemx epsc ## @itemx epsc2 -## Encapsulated postscript (level 1 and 2, mono and color) +## Encapsulated postscript (level 1 and 2, mono and color). The FLTK backend +## generates Postscript level 3.0. ## ## @item tex ## @itemx epslatex @@ -103,10 +109,10 @@ ## Microsoft Enhanced Metafile ## ## @item fig -## XFig. If this format is selected the additional options -## @option{-textspecial} or @option{-textnormal} can be used to control -## whether the special flag should be set for the text in -## the figure (default is @option{-textnormal}). +## XFig. For the Gnuplot backend, the additional options +## @option{-textspecial} or @option{-textnormal} can be used to control +## whether the special flag should be set for the text in +## the figure (default is @option{-textnormal}). ## ## @item hpgl ## HP plotter language @@ -122,7 +128,7 @@ ## JPEG image ## ## @item gif -## GIF image +## GIF image (only available for the Gnuplot backend) ## ## @item pbm ## PBMplus @@ -138,8 +144,8 @@ ## or if there is no filename it is sent to the printer as postscript. ## ## @item -d@var{ghostscript_device} -## Specify an output device supported by Ghostscript. -## Some examples are: +## Additional devices are supported by Ghostscript. +## Some examples are; ## ## @table @code ## @item ljet2p @@ -164,46 +170,44 @@ ## Portable Pixel Map file format ## ## @item pdfwrite -## Converts ps or eps to pdf +## Produces pdf output from eps ## @end table ## -## For a complete list of available formats and devices type -## @samp{system ("gs -h")}. +## For a complete list, type `system ("gs -h")' to see what formats +## and devices are available. ## ## When Ghostscript output is sent to a printer the size is determined ## by the figure's "papersize" property. When the output -## is sent to a file the size is determined by the figure's -## "paperposition" property. +## is sent to a file the size is determined by the plot box defined by +## the figure's "paperposition" property. ## -## @item -append -## Append the output to a pre-existing file. Only PDF -## and Postscript files are currently supported. +## @itemx -append +## Appends the PS, PDF, or EPS output to a pre-existing file of the +## same type. ## -## @item -r@var{NUM} +## @itemx -r@var{NUM} ## Resolution of bitmaps in pixels per inch. For both metafiles and -## SVG the default is the screen resolution, for others it is 150 dpi. +## SVG the default is the screen resolution, for other it is 150 dpi. ## To specify screen resolution, use "-r0". ## ## @item -tight -## Force a tight bounding box for eps-files. Because the Ghostscript -## devices are conversions of an eps-file, this option works for those +## Forces a tight bounding box for eps-files. Since Ghostscript +## is used to produce other devices, this option works for those ## devices as well. ## ## @item -S@var{xsize},@var{ysize} -## Specify plot size in pixels for EMF, GIF, JPEG, PBM, PNG and SVG@. If -## using the command form of the print function, the @var{xsize},@var{ysize} -## option must be quoted. For example, by writing -## @w{@code{"-S640,480"}}. The size defaults to that specified by the -## figure's paperposition property. +## Plot size in pixels for EMF, GIF, JPEG, PBM, PNG and SVG. For +## PS, EPS, PDF, and other vector formats the plot size is in points. +## This option is equivalent to changing the size of the plot box +## associated with "paperposition" property. Using the command form of +## the print function, you must quote the @var{xsize},@var{ysize} +## option. For example, by writing @w{@code{"-S640,480"}}. ## -## @item -F@var{fontname} +## @item -F@var{fontname} ## @itemx -F@var{fontname}:@var{size} ## @itemx -F:@var{size} -## Set the postscript font to @var{fontname} (for use with postscript, -## aifm, @nospell{corel} and fig). By default, 'Helvetica' is set for PS/aifm, -## and 'SwitzerlandLight' for Corel. It can also be 'Times-Roman'. -## @var{size} is given in points. @var{fontname} is ignored for the -## fig device. +## Associates all text with the @var{fontname} and/or @var{fontsize}. +## @var{fontname} is ignored for some devices; dxf, fig, hpgl, etc. ## @end table ## ## The filename and options can be given in any order. @@ -225,25 +229,34 @@ if (strcmp (backend, "gnuplot")) ## FIXME - this can be removed when __gnuplot_print__ has been modified ## to work consistently with __fltk_print__ - __gnuplot_print__ (varargin{:}); + opts.ghostscript_binary = opts.ghostscript.binary; + opts.resolution = opts.ghostscript.resolution; + opts.canvas_size = opts.canvas_size * opts.resolution / 72; + opts.resolution = sprintf ("%d", opts.resolution); + opts.fontsize = sprintf ("%d", opts.fontsize); + if (strcmp (opts.devopt, "tiff")) + error ("print:notiffoutput", + "print.m: TIFF output is not available for the Gnuplot backend.") + endif + __gnuplot_print__ (opts); return + else + if (strcmp (opts.devopt, "gif")) + error ("print:notiffoutput", + "print.m: GIF output is not available for the FLTK backend.") + endif 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); + if (opts.append_to_file && ! (strncmp (opts.devopt, "pdf", 3) + || strncmp (opts.devopt(1:2), "ps", 2))) + warning ("print:cannotappendfile", + "print.m: Cannot append files of type '%s'.", opts.devopt) + opts.append_to_file = false; endif if (opts.append_to_file) saved_original_file = strcat (tmpnam (), ".", opts.devopt); - opts.unlink(end+1) = {save_original_file}; + opts.unlink(end+1) = {saved_original_file}; movefile (opts.name, saved_original_file); endif @@ -251,41 +264,13 @@ ## 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 + ## backend tranlates figure position to eps bbox in points + fpos = get (opts.figure, "position"); + props(1).h = opts.figure; + props(1).name = "position"; + props(1).value = {fpos}; + fpos(3:4) = opts.canvas_size; + set (opts.figure, "position", fpos) if (opts.force_solid != 0) h = findobj (opts.figure, "-property", "linestyle"); @@ -364,10 +349,10 @@ ## Send to the printer if (opts.send_to_printer) - if (isempty (opts.ghostscript_output)) + if (isempty (opts.ghostscript.output)) prn_datafile = opts.name; else - prn_datafile = opts.ghostscript_output; + prn_datafile = opts.ghostscript.output; endif if (isempty (opts.printer)) prn_cmd = sprintf ("lpr %s '%s' 2>&1", opts.lpr_options, prn_datafile); @@ -377,6 +362,8 @@ endif if (opts.debug) fprintf ("lpr command: %s\n", prn_cmd) + [status, output] = system ("lpq"); + disp (output) endif [status, output] = system (prn_cmd); if (status != 0) @@ -387,16 +374,21 @@ ## Append to file using GS if (opts.append_to_file) - if (strcmp (opts.devopt, "pdf")) + if (strncmp (opts.devopt, "pdf", 3)) suffix = "pdf"; - elseif (strcmp (opts.devopt(1:2), "ps")) + device = suffix; + elseif (strncmp (opts.devopt(1:2), "ps", 2)) + ## FIXME - For FLTK the fonts get mangled + ## See the seciton "How to concatenate several PS files" at the link, + ## http://en.wikibooks.org/wiki/PostScript_FAQ suffix = "ps"; + device = suffix; endif tmp_combined_file = strcat (tmpnam (), ".", suffix); opts.unlink{end+1} = tmp_combined_file; - gs_opts = "-q -dNOPAUSE -dBATCH"; + gs_opts = "-dQUIET -dNOPAUSE -dBATCH -dSAFER -dFIXEDMEDIA"; gs_cmd = sprintf ("%s %s -sDEVICE=%swrite -sOutputFile=%s %s %s", - opts.ghostscript_binary, gs_opts, suffix, tmp_combined_file, + opts.ghostscript.binary, gs_opts, device, tmp_combined_file, saved_original_file, opts.name); [status, output] = system (gs_cmd); if (opts.debug) @@ -405,9 +397,9 @@ if (status != 0) warning ("print:failedtoappendfile", "print.m: failed to append output to file '%s'.", opts.name) - movefile (saved_original_file, opts.name); + copyfile (saved_original_file, opts.name); else - movefile (tmp_combined_file, opts.name); + copyfile (tmp_combined_file, opts.name); endif endif @@ -416,7 +408,7 @@ [status, output] = unlink (opts.unlink{n}); if (status != 0) disp (output) - warning ("print.m: failed to delete temporay file, '%s'.", opts.name) + warning ("print.m: failed to delete temporay file, '%s'.", opts.unlink{n}) endif endfor
--- a/scripts/plot/private/__ghostscript__.m +++ b/scripts/plot/private/__ghostscript__.m @@ -22,29 +22,87 @@ ## Author: Ben Abbott <bpabbott@mac.com> ## Created: 2010-07-26 -function status = __ghostscript__ (opts, varargin); +function status = __ghostscript__ (varargin); - if (nargin > 1) - opts.name = varargin{1}; + opts.binary = ""; + opts.source = ""; + opts.output = ""; + opts.device = ""; + opts.epscrop = false; + opts.antialiasing = false; + opts.resolution = 150; + opts.papersize = ""; + opts.pageoffset = [0 0]; + opts.debug = false; + + offsetfile = ""; + + args = varargin; + n = find (cellfun (@isstruct, args)); + if (! isempty (n)) + f = fieldnames (args{n}); + for m = 1:numel(f) + opts.(f{m}) = args{n}.(f{m}); + endfor + args(n) = []; endif - if (nargin > 2) - opts.ghostscript_device = varargin{2}; - endif - if (nargin > 3) - opts.ghostscript_output = varargin{3}; + for n = 1:2:numel(args) + opts.(args{n}) = args{n+1}; + endfor + + gs_opts = sprintf ("-dQUIET -dNOPAUSE -dBATCH -dSAFER -sDEVICE=%s", opts.device); + if (opts.antialiasing) + gs_opts = sprintf ("%s -dTextAlphaBits=4 -dGraphicsAlphaBits=4", gs_opts); + gs_opts = sprintf ("%s -r%dx%d", gs_opts, [1, 1] * opts.resolution); + elseif (any (strcmp (opts.device, {"pswrite", "ps2write", "pdfwrite"}))) + gs_opts = sprintf ("%s -dEmbedAllFonts=true", gs_opts); + if (strcmp (opts.device, "pdfwrite")) + ## Optimize for loading + gs_opts = sprintf ("%s -dOptimize=true", gs_opts); + endif endif - if (strncmp (opts.devopt, "eps", 3)) - ## "eps" files - gs_opts = "-q -dNOPAUSE -dBATCH -dSAFER -dEPSCrop"; - else - ## "ps" or "pdf" files - gs_opts = "-q -dNOPAUSE -dBATCH -dSAFER"; + if (opts.epscrop) + ## papersize is specified by the eps bbox + gs_opts = sprintf ("%s -dEPSCrop", gs_opts); + elseif (! isempty (opts.papersize)) + if (ischar (opts.papersize)) + gs_opts = sprintf ("%s -sPAPERSIZE=%s", gs_opts, opts.papersize); + elseif (isnumeric (opts.papersize) && numel (opts.papersize) == 2) + gs_opts = sprintf ("%s -dDEVICEWIDTHPOINTS=%d -dDEVICEHEIGHTPOINTS=%d", gs_opts, opts.papersize); + if (opts.papersize(1) > opts.papersize(2)) + ## Lanscape mode: This option will result in automatic rotation of the document page if the + ## requested page size matches one of the default page sizes + gs_opts = sprintf ("%s -dNORANGEPAGESIZE", gs_opts); + endif + else + error ("print:badpapersize", "__ghostscript__.m: invalid 'papersize'") + endif + gs_opts = sprintf ("%s -dFIXEDMEDIA", gs_opts); + offsetfile = strcat (tmpnam (), ".ps"); + fid = fopen (offsetfile, "w"); + if (fid == -1) + error ("print:fopenfailed", "__ghostscript__.m: fopen() failed."); + endif + fprintf (fid, "%s\n", "%!PS-Adobe-3.0") + fprintf (fid, "%s [%d %d] %s\n", "<< /Margins [0 0] /.HWMargins [0 0 0 0] /PageOffset", + opts.pageoffset, ">> setpagedevice"); + fprintf (fid, "%%EOF"); + status = fclose (fid); + if (status == -1) + error ("print:fclosefailed", "__ghostscript__.m: fclose() failed."); + endif + if (opts.debug) + [~,output] = system (sprintf ("cat %s", offsetfile)); + fprintf ("---- begin %s ----\n", offsetfile) + disp (output) + fprintf ("----- end %s -----\n", offsetfile) + endif endif - cmd = sprintf ("%s %s -sDEVICE=%s -r%d -sOutputFile=%s %s", - opts.ghostscript_binary, gs_opts, opts.ghostscript_device, - opts.resolution, opts.ghostscript_output, opts.name); + cmd = sprintf ("%s %s -sOutputFile=%s %s %s", + opts.binary, gs_opts, + opts.output, offsetfile, opts.source); if (opts.debug) fprintf ("Ghostscript command: %s\n", cmd); @@ -54,7 +112,9 @@ if (status != 0) warning ("print:ghostscripterror", - "print.m: gs failed to convert output to file '%s'.", opts.ghostscript_output) + "print.m: ghostscript failed to convert output to file '%s'.", opts.output) endif endfunction + +