[21757] | 1 | function eps2pdf(source, dest, crop, append, gray, quality, gs_options)
|
---|
[7182] | 2 | %EPS2PDF Convert an eps file to pdf format using ghostscript
|
---|
| 3 | %
|
---|
| 4 | % Examples:
|
---|
| 5 | % eps2pdf source dest
|
---|
| 6 | % eps2pdf(source, dest, crop)
|
---|
| 7 | % eps2pdf(source, dest, crop, append)
|
---|
| 8 | % eps2pdf(source, dest, crop, append, gray)
|
---|
| 9 | % eps2pdf(source, dest, crop, append, gray, quality)
|
---|
[21757] | 10 | % eps2pdf(source, dest, crop, append, gray, quality, gs_options)
|
---|
[7182] | 11 | %
|
---|
| 12 | % This function converts an eps file to pdf format. The output can be
|
---|
| 13 | % optionally cropped and also converted to grayscale. If the output pdf
|
---|
| 14 | % file already exists then the eps file can optionally be appended as a new
|
---|
| 15 | % page on the end of the eps file. The level of bitmap compression can also
|
---|
| 16 | % optionally be set.
|
---|
| 17 | %
|
---|
| 18 | % This function requires that you have ghostscript installed on your
|
---|
| 19 | % system. Ghostscript can be downloaded from: http://www.ghostscript.com
|
---|
| 20 | %
|
---|
[21757] | 21 | % Inputs:
|
---|
| 22 | % source - filename of the source eps file to convert. The filename is
|
---|
| 23 | % assumed to already have the extension ".eps".
|
---|
| 24 | % dest - filename of the destination pdf file. The filename is assumed
|
---|
| 25 | % to already have the extension ".pdf".
|
---|
| 26 | % crop - boolean indicating whether to crop the borders off the pdf.
|
---|
| 27 | % Default: true.
|
---|
| 28 | % append - boolean indicating whether the eps should be appended to the
|
---|
| 29 | % end of the pdf as a new page (if the pdf exists already).
|
---|
| 30 | % Default: false.
|
---|
| 31 | % gray - boolean indicating whether the output pdf should be grayscale
|
---|
| 32 | % or not. Default: false.
|
---|
[7182] | 33 | % quality - scalar indicating the level of image bitmap quality to
|
---|
| 34 | % output. A larger value gives a higher quality. quality > 100
|
---|
| 35 | % gives lossless output. Default: ghostscript prepress default.
|
---|
[21757] | 36 | % gs_options - optional ghostscript options (e.g.: '-dNoOutputFonts'). If
|
---|
| 37 | % multiple options are needed, enclose in call array: {'-a','-b'}
|
---|
[7182] | 38 |
|
---|
[21757] | 39 | % Copyright (C) Oliver Woodford 2009-2014, Yair Altman 2015-
|
---|
[7182] | 40 |
|
---|
| 41 | % Suggestion of appending pdf files provided by Matt C at:
|
---|
| 42 | % http://www.mathworks.com/matlabcentral/fileexchange/23629
|
---|
| 43 |
|
---|
| 44 | % Thank you to Fabio Viola for pointing out compression artifacts, leading
|
---|
| 45 | % to the quality setting.
|
---|
| 46 | % Thank you to Scott for pointing out the subsampling of very small images,
|
---|
| 47 | % which was fixed for lossless compression settings.
|
---|
| 48 |
|
---|
[11803] | 49 | % 9/12/2011 Pass font path to ghostscript.
|
---|
[21757] | 50 | % 26/02/15: If temp dir is not writable, use the dest folder for temp
|
---|
| 51 | % destination files (Javier Paredes)
|
---|
| 52 | % 28/02/15: Enable users to specify optional ghostscript options (issue #36)
|
---|
| 53 | % 01/03/15: Upon GS error, retry without the -sFONTPATH= option (this might solve
|
---|
| 54 | % some /findfont errors according to James Rankin, FEX Comment 23/01/15)
|
---|
| 55 | % 23/06/15: Added extra debug info in case of ghostscript error; code indentation
|
---|
| 56 | % 04/10/15: Suggest a workaround for issue #41 (missing font path; thanks Mariia Fedotenkova)
|
---|
| 57 | % 22/02/16: Bug fix from latest release of this file (workaround for issue #41)
|
---|
| 58 | % 20/03/17: Added informational message in case of GS croak (issue #186)
|
---|
[11803] | 59 |
|
---|
[21757] | 60 | % Intialise the options string for ghostscript
|
---|
| 61 | options = ['-q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sOutputFile="' dest '"'];
|
---|
| 62 | % Set crop option
|
---|
| 63 | if nargin < 3 || crop
|
---|
| 64 | options = [options ' -dEPSCrop'];
|
---|
[7182] | 65 | end
|
---|
[21757] | 66 | % Set the font path
|
---|
| 67 | fp = font_path();
|
---|
| 68 | if ~isempty(fp)
|
---|
| 69 | options = [options ' -sFONTPATH="' fp '"'];
|
---|
| 70 | end
|
---|
| 71 | % Set the grayscale option
|
---|
| 72 | if nargin > 4 && gray
|
---|
| 73 | options = [options ' -sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray'];
|
---|
| 74 | end
|
---|
| 75 | % Set the bitmap quality
|
---|
| 76 | if nargin > 5 && ~isempty(quality)
|
---|
| 77 | options = [options ' -dAutoFilterColorImages=false -dAutoFilterGrayImages=false'];
|
---|
| 78 | if quality > 100
|
---|
| 79 | options = [options ' -dColorImageFilter=/FlateEncode -dGrayImageFilter=/FlateEncode -c ".setpdfwrite << /ColorImageDownsampleThreshold 10 /GrayImageDownsampleThreshold 10 >> setdistillerparams"'];
|
---|
| 80 | else
|
---|
| 81 | options = [options ' -dColorImageFilter=/DCTEncode -dGrayImageFilter=/DCTEncode'];
|
---|
| 82 | v = 1 + (quality < 80);
|
---|
| 83 | quality = 1 - quality / 100;
|
---|
| 84 | s = sprintf('<< /QFactor %.2f /Blend 1 /HSample [%d 1 1 %d] /VSample [%d 1 1 %d] >>', quality, v, v, v, v);
|
---|
| 85 | options = sprintf('%s -c ".setpdfwrite << /ColorImageDict %s /GrayImageDict %s >> setdistillerparams"', options, s, s);
|
---|
| 86 | end
|
---|
| 87 | end
|
---|
| 88 | % Enable users to specify optional ghostscript options (issue #36)
|
---|
| 89 | if nargin > 6 && ~isempty(gs_options)
|
---|
| 90 | if iscell(gs_options)
|
---|
| 91 | gs_options = sprintf(' %s',gs_options{:});
|
---|
| 92 | elseif ~ischar(gs_options)
|
---|
| 93 | error('gs_options input argument must be a string or cell-array of strings');
|
---|
| 94 | else
|
---|
| 95 | gs_options = [' ' gs_options];
|
---|
| 96 | end
|
---|
| 97 | options = [options gs_options];
|
---|
| 98 | end
|
---|
| 99 | % Check if the output file exists
|
---|
| 100 | if nargin > 3 && append && exist(dest, 'file') == 2
|
---|
| 101 | % File exists - append current figure to the end
|
---|
| 102 | tmp_nam = tempname;
|
---|
| 103 | try
|
---|
| 104 | % Ensure that the temp dir is writable (Javier Paredes 26/2/15)
|
---|
| 105 | fid = fopen(tmp_nam,'w');
|
---|
| 106 | fwrite(fid,1);
|
---|
| 107 | fclose(fid);
|
---|
| 108 | delete(tmp_nam);
|
---|
| 109 | catch
|
---|
| 110 | % Temp dir is not writable, so use the dest folder
|
---|
| 111 | [dummy,fname,fext] = fileparts(tmp_nam); %#ok<ASGLU>
|
---|
| 112 | fpath = fileparts(dest);
|
---|
| 113 | tmp_nam = fullfile(fpath,[fname fext]);
|
---|
| 114 | end
|
---|
| 115 | % Copy the file
|
---|
| 116 | copyfile(dest, tmp_nam);
|
---|
| 117 | % Add the output file names
|
---|
| 118 | options = [options ' -f "' tmp_nam '" "' source '"'];
|
---|
| 119 | try
|
---|
| 120 | % Convert to pdf using ghostscript
|
---|
| 121 | [status, message] = ghostscript(options);
|
---|
| 122 | catch me
|
---|
| 123 | % Delete the intermediate file
|
---|
| 124 | delete(tmp_nam);
|
---|
| 125 | rethrow(me);
|
---|
| 126 | end
|
---|
[7182] | 127 | % Delete the intermediate file
|
---|
| 128 | delete(tmp_nam);
|
---|
| 129 | else
|
---|
[21757] | 130 | % File doesn't exist or should be over-written
|
---|
| 131 | % Add the output file names
|
---|
| 132 | options = [options ' -f "' source '"'];
|
---|
| 133 | % Convert to pdf using ghostscript
|
---|
| 134 | [status, message] = ghostscript(options);
|
---|
[7182] | 135 | end
|
---|
[21757] | 136 | % Check for error
|
---|
| 137 | if status
|
---|
| 138 | % Retry without the -sFONTPATH= option (this might solve some GS
|
---|
| 139 | % /findfont errors according to James Rankin, FEX Comment 23/01/15)
|
---|
| 140 | orig_options = options;
|
---|
| 141 | if ~isempty(fp)
|
---|
| 142 | options = regexprep(options, ' -sFONTPATH=[^ ]+ ',' ');
|
---|
| 143 | status = ghostscript(options);
|
---|
| 144 | if ~status, return; end % hurray! (no error)
|
---|
| 145 | end
|
---|
| 146 | % Report error
|
---|
| 147 | if isempty(message)
|
---|
| 148 | error('Unable to generate pdf. Check destination directory is writable.');
|
---|
| 149 | elseif ~isempty(strfind(message,'/typecheck in /findfont'))
|
---|
| 150 | % Suggest a workaround for issue #41 (missing font path)
|
---|
| 151 | font_name = strtrim(regexprep(message,'.*Operand stack:\s*(.*)\s*Execution.*','$1'));
|
---|
| 152 | fprintf(2, 'Ghostscript error: could not find the following font(s): %s\n', font_name);
|
---|
| 153 | fpath = fileparts(mfilename('fullpath'));
|
---|
| 154 | gs_fonts_file = fullfile(fpath, '.ignore', 'gs_font_path.txt');
|
---|
| 155 | fprintf(2, ' try to add the font''s folder to your %s file\n\n', gs_fonts_file);
|
---|
| 156 | error('export_fig error');
|
---|
| 157 | else
|
---|
| 158 | fprintf(2, '\nGhostscript error: perhaps %s is open by another application\n', dest);
|
---|
| 159 | if ~isempty(gs_options)
|
---|
| 160 | fprintf(2, ' or maybe the%s option(s) are not accepted by your GS version\n', gs_options);
|
---|
| 161 | end
|
---|
| 162 | fprintf(2, ' or maybe you have another gs executable in your system''s path\n');
|
---|
| 163 | fprintf(2, 'Ghostscript options: %s\n\n', orig_options);
|
---|
| 164 | error(message);
|
---|
| 165 | end
|
---|
| 166 | end
|
---|
[7182] | 167 | end
|
---|
| 168 |
|
---|
[11803] | 169 | % Function to return (and create, where necessary) the font path
|
---|
| 170 | function fp = font_path()
|
---|
[21757] | 171 | fp = user_string('gs_font_path');
|
---|
[11803] | 172 | if ~isempty(fp)
|
---|
[21757] | 173 | return
|
---|
[11803] | 174 | end
|
---|
[21757] | 175 | % Create the path
|
---|
| 176 | % Start with the default path
|
---|
| 177 | fp = getenv('GS_FONTPATH');
|
---|
| 178 | % Add on the typical directories for a given OS
|
---|
| 179 | if ispc
|
---|
| 180 | if ~isempty(fp)
|
---|
| 181 | fp = [fp ';'];
|
---|
| 182 | end
|
---|
| 183 | fp = [fp getenv('WINDIR') filesep 'Fonts'];
|
---|
| 184 | else
|
---|
| 185 | if ~isempty(fp)
|
---|
| 186 | fp = [fp ':'];
|
---|
| 187 | end
|
---|
| 188 | fp = [fp '/usr/share/fonts:/usr/local/share/fonts:/usr/share/fonts/X11:/usr/local/share/fonts/X11:/usr/share/fonts/truetype:/usr/local/share/fonts/truetype'];
|
---|
[11803] | 189 | end
|
---|
[21757] | 190 | user_string('gs_font_path', fp);
|
---|
[11803] | 191 | end
|
---|