Changeset 19993
- Timestamp:
- 01/25/16 19:42:49 (9 years ago)
- Location:
- issm/trunk-jpl/externalpackages/export_fig
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/externalpackages/export_fig/LICENSE
r19571 r19993 1 Copyright (c) 2014, Oliver J. Woodford , Yair M. Altman1 Copyright (c) 2014, Oliver J. Woodford 2 2 All rights reserved. 3 3 -
issm/trunk-jpl/externalpackages/export_fig/README.md
r19571 r19993 25 25 |||| 26 26 27 Note that the size and background colour of test2.png (the output of export_fig) are the same as those of the on screen figure, in contrast to test.png. Of course, if you want the figure background to be white (or any other colour) in the exported file then you can set this prior to exporting using:27 Note that the size and background colour of test2.png (the output of export_fig) are the same as those of the on screen figure, in contrast to test.png. Of course, if you want want the figure background to be white (or any other colour) in the exported file then you can set this prior to exporting using: 28 28 ```Matlab 29 29 set(gcf, 'Color', 'w'); … … 171 171 **Specifying the figure/axes** - if you have mutiple figures open you can specify which figure to export using its handle: 172 172 ```Matlab 173 export_fig(figure_handle, filename);173 export_fig(figure_handle, 'filename.fmt'); 174 174 ``` 175 175 Equally, if your figure contains several subplots then you can export just one of them by giving export_fig the handle to the relevant axes: 176 176 ```Matlab 177 export_fig(axes_handle, filename);177 export_fig(axes_handle, 'filename.fmt'); 178 178 ``` 179 179 … … 195 195 **Appending to a file** - you can use the `-append` option to append the figure to the end of an image/document, if it already exists. This is supported for PDF and TIFF files only. Note that if you wish to append a lot of figures consecutively to a PDF, it can be more efficient to save all the figures to PDF separately then append them all in one go at the end (e.g. using [append_pdfs](http://www.mathworks.com/matlabcentral/fileexchange/31215-appendpdfs)). 196 196 197 **Output to clipboard** - you can use the `-clipboard` option to copy the specified figure or axes to the system clipboard, for easy paste into other documents (e.g., Word or PowerPoint). Note that the image is copied in bitmap (not vector) format.198 199 197 **Font size** - if you want to place an exported figure in a document with the font a particular size then you need to set the font to that size in the figure, and not resize the output of export_fig in the document. To avoid resizing, simply make sure that the on screen figure is the size you want the output to be in the document before exporting. 200 198 201 **Renderers** - MATLAB has three renderers for displaying and exporting figures: painters, OpenGL and ZBuffer. The different renderers have different [features](http://www.mathworks.com/access/helpdesk/help/techdoc/creating_plots/f3-84337.html#f3-102410), so if you aren't happy with the result from one renderer try another. By default, vector formats (i.e. PDF and EPS outputs) use the painters renderer, while other formats use the OpenGL renderer. Non-default renderers can be selected by using one of these three export_fig input options: `-painters`, `-opengl`, `-zbuffer`: 202 ```Matlab 203 export_fig test.png -painters 204 ``` 199 **Renderers** - MATLAB has three renderers for displaying and exporting figures: painters, OpenGL and ZBuffer. The different renderers have different [features](http://www.mathworks.com/access/helpdesk/help/techdoc/creating_plots/f3-84337.html#f3-102410), so if you aren't happy with the result from one renderer try another. By default, vector formats (i.e. PDF and EPS outputs) use the painters renderer, while other formats use the OpenGL renderer. Non-default renderers can be selected by using one of these three export_fig input options: `-painters`, `-opengl`, `-zbuffer`. 205 200 206 201 **Artifacts** - sometimes the output that you get from export_fig is not what you expected. If an output file contains artifacts that aren't in the on screen figure then make sure that the renderer used for rendering the figure on screen is the same as that used for exporting. To set the renderer used to display the figure, use: … … 220 215 221 216 **Undefined function errors** - If you download and run export_fig and get an error similar to this: 222 ``` 217 ```Matlab 223 218 ??? Undefined function or method 'print2array' for input arguments of type 'double'. 224 219 ``` … … 226 221 227 222 ### Known issues 228 There are lots of problems with MATLAB's exporting functions, especially `print`. Export_fig is simply a glorified wrapper for MATLAB's `print` function, and doesn't solve all of its bugs(yet?). Some of the problems I know about are:229 230 **Fonts** - when using the painters renderer, MATLAB can only export a small number of fonts, details of which can be found [here](http://www.mathworks.com/ help/releases/R2014a/matlab/creating_plots/choosing-a-printer-driver.html#f3-96545). Export_fig attempts to correct font names in the resulting EPS file (upto a maximum of 11 different fonts in one figure), but this is not always guaranteed to work. In particular, the text positions will be affected. It also does not work for text blocks where the 'Interpreter' property is set to 'latex'.231 232 Also, when using the painters renderer, ghostscript will sometimes throw an error such as `Error: /undefined in /findfont`. This suggests that ghostscript could not find a definition file for one of your fonts. One possible fix for this is to make sure the file `EXPORT_FIG_PATH/.ignore/gs_font_path.txt` exists and contains a list of paths to the folder(s) containing the necessary font definitions (make sure th at they are TrueType definitions!), separated by a semicolon.233 234 **RGB color data not yet supported in Painter's mode** - you will see this as a warning if you try to export a figure which contains patch objects whose face or vertex colors are specified as a n RGB colour, rather than an index into the colormap, using the painters renderer (the default renderer for vector output). This problem can arise if you use `pcolor`, for example. This is a problem with MATLAB's painters renderer, which also affects `print`; there is currently no fix available in export_fig (other than to export to bitmap). The suggested workaround is to avoid colouring patches using RGB. First, try to use colours in the figure's colourmap (instructions [here](http://www.mathworks.co.uk/support/solutions/en/data/1-6OTPQE/)) - change the colourmap, if necessary. If you are using `pcolor`, try using [uimagesc](http://www.mathworks.com/matlabcentral/fileexchange/11368) (on the file exchange) instead.223 There are lots of problems with MATLAB's exporting functions, and unfortunately export_fig, which is simply a glorified wrapper for MATLAB's print function, doesn't solve all of them (yet?). Some of the problems I know about are: 224 225 **Fonts** - when using the painters renderer, MATLAB can only export a small number of fonts, details of which can be found [here](http://www.mathworks.com/access/helpdesk/help/techdoc/creating_plots/f3-103191.html#f3-96545). Export_fig attempts to correct font names in the resulting EPS file (for upto a maximum of 11 different fonts in one figure), but this is not always guaranteed to work. In particular, the text positions will be affected. It also does not work for text blocks where the 'Interpreter' property is set to 'latex'. 226 227 Also, when using the painters renderer, ghostscript will sometimes throw an error such as `Error: /undefined in /findfont`. This suggests that ghostscript could not find a definition file for one of your fonts. One possible fix for this is to make sure the file `EXPORT_FIG_PATH/.ignore/gs_font_path.txt` exists and contains a list of paths to the folder(s) containing the necessary font definitions (make sure they're TrueType definitions), separated by a semicolon. 228 229 **RGB color data not yet supported in Painter's mode** - you will see this as a warning if you try to export a figure which contains patch objects whose face or vertex colors are specified as a an RGB colour, rather than an index into the colormap, using the painters renderer (the default renderer for vector output). This problem can arise if you use `pcolor`, for example. This is a problem with MATLAB's painters renderer, which also affects `print`; there is currently no fix available in export_fig (other than to export to bitmap). The suggested workaround is to avoid colouring patches using RGB. First, try to use colours in the figure's colourmap (instructions [here](http://www.mathworks.co.uk/support/solutions/en/data/1-6OTPQE/)) - change the colourmap, if necessary. If you are using `pcolor`, try using [uimagesc](http://www.mathworks.com/matlabcentral/fileexchange/11368) (on the file exchange) instead. 235 230 236 231 **Dashed contour lines appear solid** - when using the painters renderer, MATLAB cannot generate dashed lines using the `contour` function (either on screen or in exported PDF and EPS files). Details can be found [here](http://www.mathworks.com/support/solutions/en/data/1-14PPHB/?solution=1-14PPHB). … … 238 233 **Text size** - when using the OpenGL or ZBuffer renderers, large text can be resized relative to the figure when exporting at non-screen-resolution (including using anti-alising at screen resolution). This is a feature of MATLAB's `print `function. In this case, try using the `-painters` option. 239 234 240 **Lighting and transparency** - when using the painters renderer, transparency and lighting effects are not supported. Sorry, but this is a n inherent feature of MATLAB's paintersrenderer. To find out more about the capabilities of each rendering method, see [here](http://www.mathworks.com/access/helpdesk/help/techdoc/creating_plots/f3-84337.html#f3-102410). You can still export transparent objects to vector format (SVG) using the excellent [plot2svg](http://www.mathworks.com/matlabcentral/fileexchange/7401) package, then convert this to PDF, for example using [Inkscape](http://inkscape.org/). However, it can't handle lighting.241 242 **Lines in patch objects** - when exporting patch objects to PDF using the painters renderer (default), sometimes the output can appear to have lines across the middle of rectangular patches; these lines are the colour of the background, as if there is a crack in the patch, allowing you to see through. This issue is a feature of the software used to display the PDF, rather than the PDF itself. Sometimes disabling anti-aliasing in this software can get rid of the lines ([discussion](https://github.com/altmany/export_fig/issues/44)).235 **Lighting and transparency** - when using the painters renderer, transparency and lighting effects are not supported. Sorry, but this is a feature of the renderer. To find out more about the capabilities of each rendering method, see [here](http://www.mathworks.com/access/helpdesk/help/techdoc/creating_plots/f3-84337.html#f3-102410). You can still export transparent objects to vector format (SVG) using the excellent [plot2svg](http://www.mathworks.com/matlabcentral/fileexchange/7401) package, then convert this to PDF, for example using [Inkscape](http://inkscape.org/). However, it can't handle lighting. 236 237 **Lines in patch objects** - when exporting patch objects to PDF using the painters renderer (default), sometimes the output can appear to have lines across the middle of rectangular patches; these lines are the colour of the background, as if there is a crack in the patch, allowing you to see through. This issue is a feature of the software used to display the PDF, rather than the PDF itself. Sometimes disabling anti-aliasing in this software can get rid of the lines. 243 238 244 239 **Out of memory** - if you run into memory issues when using export_fig, some ways to get round this are: 245 240 1. Reduce the level of anti-aliasing. 246 2. Reduce the size of the figure. 247 3. Reduce the export resolution (dpi). 248 4. Change the renderer to painters or ZBuffer. 241 2. Reduce the size of the on screen figure. 242 3. Reduce the resolution (dpi) the figure is exported at. 249 243 250 244 **Errors** - the other common type of errors people get with export_fig are OpenGL errors. This isn't a fault of export_fig, but either a bug in MATLAB's `print`, or your graphics driver getting itself into a state. Always make sure your graphics driver is up-to-date. If it still doesn't work, try using the ZBuffer renderer. … … 255 249 Secondly, if exporting to bitmap, do try all the renderers (i.e. try the options `-opengl`, `-zbuffer` and `-painters` separately), to see if one of them does produce an acceptable output, and if so, use that. 256 250 257 If this still does not help, then ensure that you are using the latest version of export_fig, which is available [here](https://github.com/altmany/export_fig/archive/master.zip). 258 259 If the figure looks correct on screen, but an error exists in the exported output (which cannot be solved using a different renderer) then please feel free to raise an [issue](https://github.com/ojwoodford/export_fig/issues). Please be sure to include the .fig file, the export_fig command you use, the output you get, and a description of what you expected. I can't promise anything, but if it's easy to fix I may indeed do it. Often I will find that the error is due to a bug in MATLAB's `print` function, in which case I will suggest you submit it as a bug to TheMathWorks, and inform me of any fix they suggest. Also, if there's a feature you'd like that isn't supported please tell me what it is and I'll consider implementing it. 251 If the figure looks correct on screen, but an error exists in the exported output (which cannot be solved using a different renderer) then please feel free to raise an [issue](https://github.com/ojwoodford/export_fig/issues). Please be sure to include the .fig file, the export_fig command you use, the output you get, and a description of what you expected. I can't promise anything, but if it's easy to fix I probably will do it. Often I will find that the error is due to a bug in MATLAB's print function, in which case I will suggest you submit it as a bug to TheMathWorks, and inform me of any fix they suggest. Also, if there's a feature you'd like that isn't supported please tell me what it is and I'll consider implementing it. 260 252 261 253 ### And finally... … … 263 255  264 256 265 If you've ever wondered what's going on in the logo on the export_fig download page (reproduced here), then this explanantion is for you. The logo is designed to demonstrate as many of export_fig's features as possible: 266 267 Given a figure containing a translucent mesh (top right), export_fig can export to pdf (bottom centre), which allows the figure to be zoomed-in without losing quality (because it's a vector graphic), but isn't able to reproduce the translucency. Also, depending on the PDF viewer program, small gaps appear between the patches, which are seen here as thin white lines. 268 269 By contrast, when exporting to png (top left), translucency is preserved (see how the graphic below shows through), and the figure is anti-aliased. However, zooming-in does not reveal more detail since png is a bitmap format. Also, lines appear less sharp than in the pdf output. 270 257 If you've ever wondered what's going on in the icon on the export_fig download page (reproduced on the left), then this explanantion is for you. The icon is designed to demonstrate as many of export_fig's features as possible. Given a 258 figure containing a translucent mesh (top right), export_fig can export to pdf (bottom centre), which allows the figure to be zoomed in without losing quality (because it's a vector graphic), but isn't able to reproduce the translucency, and also, depending on the viewer, creates small gaps between the patches, which are seen here as thin white lines. By contrast, when exporting to png (top left), translucency is preserved (see how the graphic below shows through), the figure is anti-aliased, but zooming in does not reveal more detail. 259 -
issm/trunk-jpl/externalpackages/export_fig/append_pdfs.m
r19571 r19993 33 33 % setting 34 34 35 % 26/02/15: If temp dir is not writable, use the output folder for temp36 % files when appending (Javier Paredes); sanity check of inputs37 38 35 function append_pdfs(varargin) 39 40 if nargin < 2, return; end % sanity check41 42 36 % Are we appending or creating a new file 43 37 append = exist(varargin{1}, 'file') == 2; 44 output = [tempname '.pdf']; 45 try 46 % Ensure that the temp dir is writable (Javier Paredes 26/2/15) 47 fid = fopen(output,'w'); 48 fwrite(fid,1); 49 fclose(fid); 50 delete(output); 51 isTempDirOk = true; 52 catch 53 % Temp dir is not writable, so use the output folder 54 [dummy,fname,fext] = fileparts(output); %#ok<ASGLU> 55 fpath = fileparts(varargin{1}); 56 output = fullfile(fpath,[fname fext]); 57 isTempDirOk = false; 58 end 59 if ~append 38 if append 39 output = [tempname '.pdf']; 40 else 60 41 output = varargin{1}; 61 42 varargin = varargin(2:end); 62 43 end 63 44 % Create the command file 64 if isTempDirOk 65 cmdfile = [tempname '.txt']; 66 else 67 cmdfile = fullfile(fpath,[fname '.txt']); 68 end 45 cmdfile = [tempname '.txt']; 69 46 fh = fopen(cmdfile, 'w'); 70 47 fprintf(fh, '-q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sOutputFile="%s" -f', output); -
issm/trunk-jpl/externalpackages/export_fig/copyfig.m
r19571 r19993 1 function fh = copyfig(fh)2 1 %COPYFIG Create a copy of a figure, without changing the figure 3 2 % … … 16 15 % Copyright (C) Oliver Woodford 2012 17 16 18 % 26/02/15: If temp dir is not writable, use the dest folder for temp 19 % destination files (Javier Paredes) 20 % 15/04/15: Suppress warnings during copyobj (Dun Kirk comment on FEX page 2013-10-02) 21 22 % Set the default 23 if nargin == 0 24 fh = gcf; 25 end 26 % Is there a legend? 27 if isempty(findall(fh, 'Type', 'axes', 'Tag', 'legend')) 28 % Safe to copy using copyobj 29 oldWarn = warning('off'); %#ok<WNOFF> %Suppress warnings during copyobj (Dun Kirk comment on FEX page 2013-10-02) 30 fh = copyobj(fh, 0); 31 warning(oldWarn); 32 else 33 % copyobj will change the figure, so save and then load it instead 34 tmp_nam = [tempname '.fig']; 35 try 36 % Ensure that the temp dir is writable (Javier Paredes 26/2/15) 37 fid = fopen(tmp_nam,'w'); 38 fwrite(fid,1); 39 fclose(fid); 40 delete(tmp_nam); % cleanup 41 catch 42 % Temp dir is not writable, so use the current folder 43 [dummy,fname,fext] = fileparts(tmp_nam); %#ok<ASGLU> 44 fpath = pwd; 45 tmp_nam = fullfile(fpath,[fname fext]); 46 end 47 hgsave(fh, tmp_nam); 48 fh = hgload(tmp_nam); 49 delete(tmp_nam); 50 end 17 function fh = copyfig(fh) 18 % Set the default 19 if nargin == 0 20 fh = gcf; 51 21 end 22 % Is there a legend? 23 if isempty(findall(fh, 'Type', 'axes', 'Tag', 'legend')) 24 % Safe to copy using copyobj 25 fh = copyobj(fh, 0); 26 else 27 % copyobj will change the figure, so save and then load it instead 28 tmp_nam = [tempname '.fig']; 29 hgsave(fh, tmp_nam); 30 fh = hgload(tmp_nam); 31 delete(tmp_nam); 32 end 33 end -
issm/trunk-jpl/externalpackages/export_fig/crop_borders.m
r19571 r19993 1 function [A, vA, vB, bb_rel] = crop_borders(A, bcol, padding)2 1 %CROP_BORDERS Crop the borders of an image or stack of images 3 2 % 4 % [B, v A, vB, bb_rel] = crop_borders(A, bcol, [padding])3 % [B, v] = crop_borders(A, bcol, [padding]) 5 4 % 6 5 %IN: 7 6 % A - HxWxCxN stack of images. 8 7 % bcol - Cx1 background colour vector. 9 % padding - scalar indicating how much padding to have in relation to 10 % the cropped-image-size (0<=padding<=1). Default: 0 8 % padding - scalar indicating how many pixels padding to have. Default: 0. 11 9 % 12 10 %OUT: 13 11 % B - JxKxCxN cropped stack of images. 14 % vA - coordinates in A that contain the cropped image 15 % vB - coordinates in B where the cropped version of A is placed 16 % bb_rel - relative bounding box (used for eps-cropping) 12 % v - 1x4 vector of start and end indices for first two dimensions, s.t. 13 % B = A(v(1):v(2),v(3):v(4),:,:). 17 14 18 % 06/03/15: Improved image cropping thanks to Oscar Hartogensis 19 % 08/06/15: Fixed issue #76: case of transparent figure bgcolor 20 21 if nargin < 3 22 padding = 0; 23 end 24 [h, w, c, n] = size(A); 25 if isempty(bcol) % case of transparent bgcolor 26 bcol = A(ceil(end/2),1,:,1); 27 end 28 if isscalar(bcol) 29 bcol = bcol(ones(c, 1)); 30 end 31 32 % Crop margin from left 33 bail = false; 34 for l = 1:w 35 for a = 1:c 36 if ~all(col(A(:,l,a,:)) == bcol(a)) 37 bail = true; 38 break; 39 end 40 end 41 if bail 15 function [A, v] = crop_borders(A, bcol, padding) 16 if nargin < 3 17 padding = 0; 18 end 19 [h, w, c, n] = size(A); 20 if isscalar(bcol) 21 bcol = bcol(ones(c, 1)); 22 end 23 bail = false; 24 for l = 1:w 25 for a = 1:c 26 if ~all(col(A(:,l,a,:)) == bcol(a)) 27 bail = true; 42 28 break; 43 29 end 44 30 end 45 46 % Crop margin from right 47 bcol = A(ceil(end/2),w,:,1); 48 bail = false; 49 for r = w:-1:l 50 for a = 1:c 51 if ~all(col(A(:,r,a,:)) == bcol(a)) 52 bail = true; 53 break; 54 end 55 end 56 if bail 31 if bail 32 break; 33 end 34 end 35 bcol = A(ceil(end/2),w,:,1); 36 bail = false; 37 for r = w:-1:l 38 for a = 1:c 39 if ~all(col(A(:,r,a,:)) == bcol(a)) 40 bail = true; 57 41 break; 58 42 end 59 43 end 60 61 % Crop margin from top 62 bcol = A(1,ceil(end/2),:,1); 63 bail = false; 64 for t = 1:h 65 for a = 1:c 66 if ~all(col(A(t,:,a,:)) == bcol(a)) 67 bail = true; 68 break; 69 end 70 end 71 if bail 44 if bail 45 break; 46 end 47 end 48 bcol = A(1,ceil(end/2),:,1); 49 bail = false; 50 for t = 1:h 51 for a = 1:c 52 if ~all(col(A(t,:,a,:)) == bcol(a)) 53 bail = true; 72 54 break; 73 55 end 74 56 end 75 76 % Crop margin from bottom 77 bcol = A(h,ceil(end/2),:,1); 78 bail = false; 79 for b = h:-1:t 80 for a = 1:c 81 if ~all(col(A(b,:,a,:)) == bcol(a)) 82 bail = true; 83 break; 84 end 85 end 86 if bail 57 if bail 58 break; 59 end 60 end 61 bcol = A(h,ceil(end/2),:,1); 62 bail = false; 63 for b = h:-1:t 64 for a = 1:c 65 if ~all(col(A(b,:,a,:)) == bcol(a)) 66 bail = true; 87 67 break; 88 68 end 89 69 end 90 91 % Crop the background, leaving one boundary pixel to avoid bleeding on resize 92 %v = [max(t-padding, 1) min(b+padding, h) max(l-padding, 1) min(r+padding, w)]; 93 %A = A(v(1):v(2),v(3):v(4),:,:); 94 if padding == 0 % no padding 95 padding = 1; 96 elseif abs(padding) < 1 % pad value is a relative fraction of image size 97 padding = sign(padding)*round(mean([b-t r-l])*abs(padding)); % ADJUST PADDING 98 else % pad value is in units of 1/72" points 99 padding = round(padding); % fix cases of non-integer pad value 70 if bail 71 break; 100 72 end 101 102 if padding > 0 % extra padding 103 % Create an empty image, containing the background color, that has the 104 % cropped image size plus the padded border 105 B = repmat(bcol,(b-t)+1+padding*2,(r-l)+1+padding*2); 106 % vA - coordinates in A that contain the cropped image 107 vA = [t b l r]; 108 % vB - coordinates in B where the cropped version of A will be placed 109 vB = [padding+1, (b-t)+1+padding, padding+1, (r-l)+1+padding]; 110 % Place the original image in the empty image 111 B(vB(1):vB(2), vB(3):vB(4), :) = A(vA(1):vA(2), vA(3):vA(4), :); 112 A = B; 113 else % extra cropping 114 vA = [t-padding b+padding l-padding r+padding]; 115 A = A(vA(1):vA(2), vA(3):vA(4), :); 116 vB = [NaN NaN NaN NaN]; 117 end 118 119 % For EPS cropping, determine the relative BoundingBox - bb_rel 120 bb_rel = [l-1 h-b-1 r+1 h-t+1]./[w h w h]; 73 end 74 % Crop the background, leaving one boundary pixel to avoid bleeding on resize 75 v = [max(t-padding, 1) min(b+padding, h) max(l-padding, 1) min(r+padding, w)]; 76 A = A(v(1):v(2),v(3):v(4),:,:); 121 77 end 122 78 123 79 function A = col(A) 124 80 A = A(:); 125 81 end -
issm/trunk-jpl/externalpackages/export_fig/eps2pdf.m
r19571 r19993 1 function eps2pdf(source, dest, crop, append, gray, quality, gs_options)2 1 %EPS2PDF Convert an eps file to pdf format using ghostscript 3 2 % … … 8 7 % eps2pdf(source, dest, crop, append, gray) 9 8 % eps2pdf(source, dest, crop, append, gray, quality) 10 % eps2pdf(source, dest, crop, append, gray, quality, gs_options)11 9 % 12 10 % This function converts an eps file to pdf format. The output can be … … 19 17 % system. Ghostscript can be downloaded from: http://www.ghostscript.com 20 18 % 21 % Inputs:22 % source 23 % 24 % dest - filename of the destination pdf file. The filename is assumed25 % toalready have the extension ".pdf".26 % crop 27 % 28 % append 29 % 30 % 31 % gray - boolean indicating whether the output pdf should be grayscale32 % ornot. Default: false.19 %IN: 20 % source - filename of the source eps file to convert. The filename is 21 % assumed to already have the extension ".eps". 22 % dest - filename of the destination pdf file. The filename is assumed to 23 % already have the extension ".pdf". 24 % crop - boolean indicating whether to crop the borders off the pdf. 25 % Default: true. 26 % append - boolean indicating whether the eps should be appended to the 27 % end of the pdf as a new page (if the pdf exists already). 28 % Default: false. 29 % gray - boolean indicating whether the output pdf should be grayscale or 30 % not. Default: false. 33 31 % quality - scalar indicating the level of image bitmap quality to 34 32 % output. A larger value gives a higher quality. quality > 100 35 33 % gives lossless output. Default: ghostscript prepress default. 36 % gs_options - optional ghostscript options (e.g.: '-dNoOutputFonts'). If37 % multiple options are needed, enclose in call array: {'-a','-b'}38 34 39 % Copyright (C) Oliver Woodford 2009-201 4, Yair Altman 2015-35 % Copyright (C) Oliver Woodford 2009-2011 40 36 41 37 % Suggestion of appending pdf files provided by Matt C at: … … 48 44 49 45 % 9/12/2011 Pass font path to ghostscript. 50 % 26/02/15: If temp dir is not writable, use the dest folder for temp51 % 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 solve54 % 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 indentation56 46 57 % Intialise the options string for ghostscript 58 options = ['-q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sOutputFile="' dest '"']; 59 % Set crop option 60 if nargin < 3 || crop 61 options = [options ' -dEPSCrop']; 47 function eps2pdf(source, dest, crop, append, gray, quality) 48 % Intialise the options string for ghostscript 49 options = ['-q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sOutputFile="' dest '"']; 50 % Set crop option 51 if nargin < 3 || crop 52 options = [options ' -dEPSCrop']; 53 end 54 % Set the font path 55 fp = font_path(); 56 if ~isempty(fp) 57 options = [options ' -sFONTPATH="' fp '"']; 58 end 59 % Set the grayscale option 60 if nargin > 4 && gray 61 options = [options ' -sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray']; 62 end 63 % Set the bitmap quality 64 if nargin > 5 && ~isempty(quality) 65 options = [options ' -dAutoFilterColorImages=false -dAutoFilterGrayImages=false']; 66 if quality > 100 67 options = [options ' -dColorImageFilter=/FlateEncode -dGrayImageFilter=/FlateEncode -c ".setpdfwrite << /ColorImageDownsampleThreshold 10 /GrayImageDownsampleThreshold 10 >> setdistillerparams"']; 68 else 69 options = [options ' -dColorImageFilter=/DCTEncode -dGrayImageFilter=/DCTEncode']; 70 v = 1 + (quality < 80); 71 quality = 1 - quality / 100; 72 s = sprintf('<< /QFactor %.2f /Blend 1 /HSample [%d 1 1 %d] /VSample [%d 1 1 %d] >>', quality, v, v, v, v); 73 options = sprintf('%s -c ".setpdfwrite << /ColorImageDict %s /GrayImageDict %s >> setdistillerparams"', options, s, s); 62 74 end 63 % Set the font path 64 fp = font_path(); 65 if ~isempty(fp) 66 options = [options ' -sFONTPATH="' fp '"']; 67 end 68 % Set the grayscale option 69 if nargin > 4 && gray 70 options = [options ' -sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray']; 71 end 72 % Set the bitmap quality 73 if nargin > 5 && ~isempty(quality) 74 options = [options ' -dAutoFilterColorImages=false -dAutoFilterGrayImages=false']; 75 if quality > 100 76 options = [options ' -dColorImageFilter=/FlateEncode -dGrayImageFilter=/FlateEncode -c ".setpdfwrite << /ColorImageDownsampleThreshold 10 /GrayImageDownsampleThreshold 10 >> setdistillerparams"']; 77 else 78 options = [options ' -dColorImageFilter=/DCTEncode -dGrayImageFilter=/DCTEncode']; 79 v = 1 + (quality < 80); 80 quality = 1 - quality / 100; 81 s = sprintf('<< /QFactor %.2f /Blend 1 /HSample [%d 1 1 %d] /VSample [%d 1 1 %d] >>', quality, v, v, v, v); 82 options = sprintf('%s -c ".setpdfwrite << /ColorImageDict %s /GrayImageDict %s >> setdistillerparams"', options, s, s); 83 end 84 end 85 % Enable users to specify optional ghostscript options (issue #36) 86 if nargin > 6 && ~isempty(gs_options) 87 if iscell(gs_options) 88 gs_options = sprintf(' %s',gs_options{:}); 89 elseif ~ischar(gs_options) 90 error('gs_options input argument must be a string or cell-array of strings'); 91 else 92 gs_options = [' ' gs_options]; 93 end 94 options = [options gs_options]; 95 end 96 % Check if the output file exists 97 if nargin > 3 && append && exist(dest, 'file') == 2 98 % File exists - append current figure to the end 99 tmp_nam = tempname; 100 try 101 % Ensure that the temp dir is writable (Javier Paredes 26/2/15) 102 fid = fopen(tmp_nam,'w'); 103 fwrite(fid,1); 104 fclose(fid); 105 delete(tmp_nam); 106 catch 107 % Temp dir is not writable, so use the dest folder 108 [dummy,fname,fext] = fileparts(tmp_nam); %#ok<ASGLU> 109 fpath = fileparts(dest); 110 tmp_nam = fullfile(fpath,[fname fext]); 111 end 112 % Copy the file 113 copyfile(dest, tmp_nam); 114 % Add the output file names 115 options = [options ' -f "' tmp_nam '" "' source '"']; 116 try 117 % Convert to pdf using ghostscript 118 [status, message] = ghostscript(options); 119 catch me 120 % Delete the intermediate file 121 delete(tmp_nam); 122 rethrow(me); 123 end 75 end 76 % Check if the output file exists 77 if nargin > 3 && append && exist(dest, 'file') == 2 78 % File exists - append current figure to the end 79 tmp_nam = tempname; 80 % Copy the file 81 copyfile(dest, tmp_nam); 82 % Add the output file names 83 options = [options ' -f "' tmp_nam '" "' source '"']; 84 try 85 % Convert to pdf using ghostscript 86 [status, message] = ghostscript(options); 87 catch me 124 88 % Delete the intermediate file 125 89 delete(tmp_nam); 90 rethrow(me); 91 end 92 % Delete the intermediate file 93 delete(tmp_nam); 94 else 95 % File doesn't exist or should be over-written 96 % Add the output file names 97 options = [options ' -f "' source '"']; 98 % Convert to pdf using ghostscript 99 [status, message] = ghostscript(options); 100 end 101 % Check for error 102 if status 103 % Report error 104 if isempty(message) 105 error('Unable to generate pdf. Check destination directory is writable.'); 126 106 else 127 % File doesn't exist or should be over-written 128 % Add the output file names 129 options = [options ' -f "' source '"']; 130 % Convert to pdf using ghostscript 131 [status, message] = ghostscript(options); 107 error(message); 132 108 end 133 % Check for error 134 if status 135 % Retry without the -sFONTPATH= option (this might solve some GS 136 % /findfont errors according to James Rankin, FEX Comment 23/01/15) 137 orig_options = options; 138 if ~isempty(fp) 139 options = regexprep(options, ' -sFONTPATH=[^ ]+ ',' '); 140 status = ghostscript(options); 141 if ~status, return; end % hurray! (no error) 142 end 143 % Report error 144 if isempty(message) 145 error('Unable to generate pdf. Check destination directory is writable.'); 146 else 147 fprintf(2, 'Ghostscript error: perhaps %s is open by another application\n', dest); 148 if ~isempty(gs_options) 149 fprintf(2, ' or maybe the%s option(s) are not accepted by your GS version\n', gs_options); 150 end 151 fprintf(2, 'Ghostscript options: %s\n\n', orig_options); 152 error(message); 153 end 154 end 109 end 155 110 end 156 111 157 112 % Function to return (and create, where necessary) the font path 158 113 function fp = font_path() 159 fp = user_string('gs_font_path'); 114 fp = user_string('gs_font_path'); 115 if ~isempty(fp) 116 return 117 end 118 % Create the path 119 % Start with the default path 120 fp = getenv('GS_FONTPATH'); 121 % Add on the typical directories for a given OS 122 if ispc 160 123 if ~isempty(fp) 161 return124 fp = [fp ';']; 162 125 end 163 % Create the path 164 % Start with the default path 165 fp = getenv('GS_FONTPATH'); 166 % Add on the typical directories for a given OS 167 if ispc 168 if ~isempty(fp) 169 fp = [fp ';']; 170 end 171 fp = [fp getenv('WINDIR') filesep 'Fonts']; 172 else 173 if ~isempty(fp) 174 fp = [fp ':']; 175 end 176 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']; 126 fp = [fp getenv('WINDIR') filesep 'Fonts']; 127 else 128 if ~isempty(fp) 129 fp = [fp ':']; 177 130 end 178 user_string('gs_font_path', fp);131 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']; 179 132 end 133 user_string('gs_font_path', fp); 134 end -
issm/trunk-jpl/externalpackages/export_fig/export_fig.m
r19571 r19993 1 function [imageData, alpha] = export_fig(varargin) 2 %EXPORT_FIG Exports figures in a publication-quality format 1 %EXPORT_FIG Exports figures suitable for publication 3 2 % 4 3 % Examples: 5 % im ageData= export_fig6 % [im ageData,alpha] = export_fig4 % im = export_fig 5 % [im alpha] = export_fig 7 6 % export_fig filename 8 7 % export_fig filename -format1 -format2 … … 15 14 % export_fig ... -q<val> 16 15 % export_fig ... -p<val> 17 % export_fig ... -d<gs_option>18 % export_fig ... -depsc19 16 % export_fig ... -<renderer> 20 17 % export_fig ... -<colorspace> 21 18 % export_fig ... -append 22 19 % export_fig ... -bookmark 23 % export_fig ... -clipboard24 % export_fig ... -update25 % export_fig ... -nofontswap26 20 % export_fig(..., handle) 27 21 % 28 22 % This function saves a figure or single axes to one or more vector and/or 29 % bitmap file formats, and/or outputs a rasterized version to the workspace,30 % w ith the following properties:23 % bitmap file formats, and/or outputs a rasterized version to the 24 % workspace, with the following properties: 31 25 % - Figure/axes reproduced as it appears on screen 32 26 % - Cropped borders (optional) … … 41 35 % - Optionally append to file (pdf, tiff) 42 36 % - Vector formats: pdf, eps 43 % - Bitmap formats: png, tiff, jpg, bmp, export to workspace 44 % 37 % - Bitmap formats: png, tiff, jpg, bmp, export to workspace 38 % 45 39 % This function is especially suited to exporting figures for use in 46 40 % publications and presentations, because of the high quality and … … 52 46 % objects), use the -transparent option or set the figure 'Color' property 53 47 % to 'none'. To make axes transparent set the axes 'Color' property to 54 % 'none'. PDF, EPS and PNG are the only formats that support a transparent 55 % background, while only PNG format supports transparency of patch objects. 48 % 'none'. Pdf, eps and png are the only file formats to support a 49 % transparent background, whilst the png format alone supports transparency 50 % of patch objects. 56 51 % 57 52 % The choice of renderer (opengl, zbuffer or painters) has a large impact 58 % on the quality of output. The default value (opengl for bitmaps, painters59 % for vector formats) generally gives good results, butif you aren't60 % satisfied then try another renderer. Notes: 1) For vector formats ( EPS,61 % PDF), only painters generates vector graphics. 2) For bitmaps, only53 % on the quality of output. Whilst the default value (opengl for bitmaps, 54 % painters for vector formats) generally gives good results, if you aren't 55 % satisfied then try another renderer. Notes: 1) For vector formats (eps, 56 % pdf), only painters generates vector graphics. 2) For bitmaps, only 62 57 % opengl can render transparent patch objects correctly. 3) For bitmaps, 63 58 % only painters will correctly scale line dash and dot lengths when … … 65 60 % using painters. 66 61 % 67 % When exporting to vector format ( PDF & EPS) and bitmap format using the62 % When exporting to vector format (pdf & eps) and bitmap format using the 68 63 % painters renderer, this function requires that ghostscript is installed 69 64 % on your system. You can download this from: … … 73 68 % http://www.foolabs.com/xpdf 74 69 % 75 % Inputs:70 %IN: 76 71 % filename - string containing the name (optionally including full or 77 72 % relative path) of the file the figure is to be saved as. If … … 92 87 % -m<val> - option where val indicates the factor to magnify the 93 88 % on-screen figure pixel dimensions by when generating bitmap 94 % outputs (does not affect vector formats). Default: '-m1'.89 % outputs. Default: '-m1'. 95 90 % -r<val> - option val indicates the resolution (in pixels per inch) to 96 91 % export bitmap and vector outputs at, keeping the dimensions … … 111 106 % use for bitmap outputs. '-a1' means no anti- 112 107 % aliasing; '-a4' is the maximum amount (default). 113 % -<renderer> - option to force a particular renderer (painters, opengl or 114 % zbuffer). Default value: opengl for bitmap formats or 115 % figures with patches and/or transparent annotations; 116 % painters for vector formats without patches/transparencies. 108 % -<renderer> - option to force a particular renderer (painters, opengl 109 % or zbuffer) to be used over the default: opengl for 110 % bitmaps; painters for vector formats. 117 111 % -<colorspace> - option indicating which colorspace color figures should 118 112 % be saved in: RGB (default), CMYK or gray. CMYK is only … … 125 119 % sometimes give a smaller file size than the default lossy 126 120 % compression, depending on the type of images. 127 % -p<val> - option to pad a border of width val to exported files, where 128 % val is either a relative size with respect to cropped image 129 % size (i.e. p=0.01 adds a 1% border). For EPS & PDF formats, 130 % val can also be integer in units of 1/72" points (abs(val)>1). 131 % val can be positive (padding) or negative (extra cropping). 132 % If used, the -nocrop flag will be ignored, i.e. the image will 133 % always be cropped and then padded. Default: 0 (i.e. no padding). 121 % -p<val> - option to add a border of width val to eps and pdf files, 122 % where val is in units of the intermediate eps file. Default: 123 % 0 (i.e. no padding). 134 124 % -append - option indicating that if the file (pdfs only) already 135 125 % exists, the figure is to be appended as a new page, instead … … 137 127 % -bookmark - option to indicate that a bookmark with the name of the 138 128 % figure is to be created in the output file (pdf only). 139 % -clipboard - option to save output as an image on the system clipboard. 140 % Note: background transparency is not preserved in clipboard 141 % -d<gs_option> - option to indicate a ghostscript setting. For example, 142 % -dMaxBitmap=0 or -dNoOutputFonts (Ghostscript 9.15+). 143 % -depsc - option to use EPS level-3 rather than the default level-2 print 144 % device. This solves some bugs with Matlab's default -depsc2 device 145 % such as discolored subplot lines on images (vector formats only). 146 % -update - option to download and install the latest version of export_fig 147 % -nofontswap - option to avoid font swapping. Font swapping is automatically 148 % done in vector formats (only): 11 standard Matlab fonts are 149 % replaced by the original figure fonts. This option prevents this. 150 % handle - The handle of the figure, axes or uipanels (can be an array of 151 % handles, but the objects must be in the same figure) to be 152 % saved. Default: gcf. 153 % 154 % Outputs: 155 % imageData - MxNxC uint8 image array of the exported image. 156 % alpha - MxN single array of alphamatte values in the range [0,1], 157 % for the case when the background is transparent. 129 % handle - The handle of the figure, axes or uipanels (can be an array of 130 % handles, but the objects must be in the same figure) to be 131 % saved. Default: gcf. 132 % 133 %OUT: 134 % im - MxNxC uint8 image array of the figure. 135 % alpha - MxN single array of alphamatte values in range [0,1], for the 136 % case when the background is transparent. 158 137 % 159 138 % Some helpful examples and tips can be found at: 160 % https://github.com/altmany/export_fig 161 % 162 % See also PRINT, SAVEAS, ScreenCapture (on the Matlab File Exchange) 163 164 %{ 165 % Copyright (C) Oliver Woodford 2008-2014, Yair Altman 2015- 139 % https://github.com/ojwoodford/export_fig 140 % 141 % See also PRINT, SAVEAS. 142 143 % Copyright (C) Oliver Woodford 2008-2014 166 144 167 145 % The idea of using ghostscript is inspired by Peder Axensten's SAVEFIG … … 184 162 % Thanks to Tammy Threadgill for reporting a bug where an axes is not 185 163 % isolated from gui objects. 186 %} 187 %{ 164 188 165 % 23/02/12: Ensure that axes limits don't change during printing 189 % 14/03/12: Fix bug in fixing the axes limits (thanks to Tobias Lamour for reporting it). 190 % 02/05/12: Incorporate patch of Petr Nechaev (many thanks), enabling bookmarking of figures in pdf files. 191 % 09/05/12: Incorporate patch of Arcelia Arrieta (many thanks), to keep tick marks fixed. 192 % 12/12/12: Add support for isolating uipanels. Thanks to michael for suggesting it. 193 % 25/09/13: Add support for changing resolution in vector formats. Thanks to Jan Jaap Meijer for suggesting it. 194 % 07/05/14: Add support for '~' at start of path. Thanks to Sally Warner for suggesting it. 195 % 24/02/15: Fix Matlab R2014b bug (issue #34): plot markers are not displayed when ZLimMode='manual' 196 % 25/02/15: Fix issue #4 (using HG2 on R2014a and earlier) 197 % 25/02/15: Fix issue #21 (bold TeX axes labels/titles in R2014b) 198 % 26/02/15: If temp dir is not writable, use the user-specified folder for temporary EPS/PDF files (Javier Paredes) 199 % 27/02/15: Modified repository URL from github.com/ojwoodford to /altmany 200 % Indented main function 201 % Added top-level try-catch block to display useful workarounds 202 % 28/02/15: Enable users to specify optional ghostscript options (issue #36) 203 % 06/03/15: Improved image padding & cropping thanks to Oscar Hartogensis 204 % 26/03/15: Fixed issue #49 (bug with transparent grayscale images); fixed out-of-memory issue 205 % 26/03/15: Fixed issue #42: non-normalized annotations on HG1 206 % 26/03/15: Fixed issue #46: Ghostscript crash if figure units <> pixels 207 % 27/03/15: Fixed issue #39: bad export of transparent annotations/patches 208 % 28/03/15: Fixed issue #50: error on some Matlab versions with the fix for issue #42 209 % 29/03/15: Fixed issue #33: bugs in Matlab's print() function with -cmyk 210 % 29/03/15: Improved processing of input args (accept space between param name & value, related to issue #51) 211 % 30/03/15: When exporting *.fig files, then saveas *.fig if figure is open, otherwise export the specified fig file 212 % 30/03/15: Fixed edge case bug introduced yesterday (commit #ae1755bd2e11dc4e99b95a7681f6e211b3fa9358) 213 % 09/04/15: Consolidated header comment sections; initialize output vars only if requested (nargout>0) 214 % 14/04/15: Workaround for issue #45: lines in image subplots are exported in invalid color 215 % 15/04/15: Fixed edge-case in parsing input parameters; fixed help section to show the -depsc option (issue #45) 216 % 21/04/15: Bug fix: Ghostscript croaks on % chars in output PDF file (reported by Sven on FEX page, 15-Jul-2014) 217 % 22/04/15: Bug fix: Pdftops croaks on relative paths (reported by Tintin Milou on FEX page, 19-Jan-2015) 218 % 04/05/15: Merged fix #63 (Kevin Mattheus Moerman): prevent tick-label changes during export 219 % 07/05/15: Partial fix for issue #65: PDF export used painters rather than opengl renderer (thanks Nguyenr) 220 % 08/05/15: Fixed issue #65: bad PDF append since commit #e9f3cdf 21/04/15 (thanks Robert Nguyen) 221 % 12/05/15: Fixed issue #67: exponent labels cropped in export, since fix #63 (04/05/15) 222 % 28/05/15: Fixed issue #69: set non-bold label font only if the string contains symbols (\beta etc.), followup to issue #21 223 % 29/05/15: Added informative error message in case user requested SVG output (issue #72) 224 % 09/06/15: Fixed issue #58: -transparent removed anti-aliasing when exporting to PNG 225 % 19/06/15: Added -update option to download and install the latest version of export_fig 226 % 07/07/15: Added -nofontswap option to avoid font-swapping in EPS/PDF 227 % 16/07/15: Fixed problem with anti-aliasing on old Matlab releases 228 % 11/09/15: Fixed issue #103: magnification must never become negative; also fixed reported error msg in parsing input params 229 %} 230 231 if nargout 232 [imageData, alpha] = deal([]); 233 end 234 hadError = false; 235 displaySuggestedWorkarounds = true; 236 237 % Ensure the figure is rendered correctly _now_ so that properties like axes limits are up-to-date 238 drawnow; 239 pause(0.05); % this solves timing issues with Java Swing's EDT (http://undocumentedmatlab.com/blog/solving-a-matlab-hang-problem) 240 241 % Parse the input arguments 242 fig = get(0, 'CurrentFigure'); 243 [fig, options] = parse_args(nargout, fig, varargin{:}); 244 245 % Ensure that we have a figure handle 246 if isequal(fig,-1) 247 return; % silent bail-out 248 elseif isempty(fig) 249 error('No figure found'); 250 end 251 252 % Isolate the subplot, if it is one 253 cls = all(ismember(get(fig, 'Type'), {'axes', 'uipanel'})); 254 if cls 255 % Given handles of one or more axes, so isolate them from the rest 256 fig = isolate_axes(fig); 166 % 14/03/12: Fix bug in fixing the axes limits (thanks to Tobias Lamour for 167 % reporting it). 168 % 02/05/12: Incorporate patch of Petr Nechaev (many thanks), enabling 169 % bookmarking of figures in pdf files. 170 % 09/05/12: Incorporate patch of Arcelia Arrieta (many thanks), to keep 171 % tick marks fixed. 172 % 12/12/12: Add support for isolating uipanels. Thanks to michael for 173 % suggesting it. 174 % 25/09/13: Add support for changing resolution in vector formats. Thanks 175 % to Jan Jaap Meijer for suggesting it. 176 % 07/05/14: Add support for '~' at start of path. Thanks to Sally Warner 177 % for suggesting it. 178 179 function [im, alpha] = export_fig(varargin) 180 % Make sure the figure is rendered correctly _now_ so that properties like 181 % axes limits are up-to-date. 182 drawnow; 183 % Parse the input arguments 184 [fig, options] = parse_args(nargout, varargin{:}); 185 % Isolate the subplot, if it is one 186 cls = all(ismember(get(fig, 'Type'), {'axes', 'uipanel'})); 187 if cls 188 % Given handles of one or more axes, so isolate them from the rest 189 fig = isolate_axes(fig); 190 else 191 % Check we have a figure 192 if ~isequal(get(fig, 'Type'), 'figure'); 193 error('Handle must be that of a figure, axes or uipanel'); 194 end 195 % Get the old InvertHardcopy mode 196 old_mode = get(fig, 'InvertHardcopy'); 197 end 198 % Hack the font units where necessary (due to a font rendering bug in 199 % print?). This may not work perfectly in all cases. Also it can change the 200 % figure layout if reverted, so use a copy. 201 magnify = options.magnify * options.aa_factor; 202 if isbitmap(options) && magnify ~= 1 203 fontu = findobj(fig, 'FontUnits', 'normalized'); 204 if ~isempty(fontu) 205 % Some normalized font units found 206 if ~cls 207 fig = copyfig(fig); 208 set(fig, 'Visible', 'off'); 209 fontu = findobj(fig, 'FontUnits', 'normalized'); 210 cls = true; 211 end 212 set(fontu, 'FontUnits', 'points'); 213 end 214 end 215 % MATLAB "feature": axes limits and tick marks can change when printing 216 Hlims = findall(fig, 'Type', 'axes'); 217 if ~cls 218 % Record the old axes limit and tick modes 219 Xlims = make_cell(get(Hlims, 'XLimMode')); 220 Ylims = make_cell(get(Hlims, 'YLimMode')); 221 Zlims = make_cell(get(Hlims, 'ZLimMode')); 222 Xtick = make_cell(get(Hlims, 'XTickMode')); 223 Ytick = make_cell(get(Hlims, 'YTickMode')); 224 Ztick = make_cell(get(Hlims, 'ZTickMode')); 225 end 226 % Set all axes limit and tick modes to manual, so the limits and ticks can't change 227 set(Hlims, 'XLimMode', 'manual', 'YLimMode', 'manual', 'ZLimMode', 'manual'); 228 set_tick_mode(Hlims, 'X'); 229 set_tick_mode(Hlims, 'Y'); 230 set_tick_mode(Hlims, 'Z'); 231 % Set to print exactly what is there 232 set(fig, 'InvertHardcopy', 'off'); 233 % Set the renderer 234 switch options.renderer 235 case 1 236 renderer = '-opengl'; 237 case 2 238 renderer = '-zbuffer'; 239 case 3 240 renderer = '-painters'; 241 otherwise 242 renderer = '-opengl'; % Default for bitmaps 243 end 244 % Do the bitmap formats first 245 if isbitmap(options) 246 % Get the background colour 247 if options.transparent && (options.png || options.alpha) 248 % Get out an alpha channel 249 % MATLAB "feature": black colorbar axes can change to white and vice versa! 250 hCB = findobj(fig, 'Type', 'axes', 'Tag', 'Colorbar'); 251 if isempty(hCB) 252 yCol = []; 253 xCol = []; 254 else 255 yCol = get(hCB, 'YColor'); 256 xCol = get(hCB, 'XColor'); 257 if iscell(yCol) 258 yCol = cell2mat(yCol); 259 xCol = cell2mat(xCol); 260 end 261 yCol = sum(yCol, 2); 262 xCol = sum(xCol, 2); 263 end 264 % MATLAB "feature": apparently figure size can change when changing 265 % colour in -nodisplay mode 266 pos = get(fig, 'Position'); 267 % Set the background colour to black, and set size in case it was 268 % changed internally 269 tcol = get(fig, 'Color'); 270 set(fig, 'Color', 'k', 'Position', pos); 271 % Correct the colorbar axes colours 272 set(hCB(yCol==0), 'YColor', [0 0 0]); 273 set(hCB(xCol==0), 'XColor', [0 0 0]); 274 % Print large version to array 275 B = print2array(fig, magnify, renderer); 276 % Downscale the image 277 B = downsize(single(B), options.aa_factor); 278 % Set background to white (and set size) 279 set(fig, 'Color', 'w', 'Position', pos); 280 % Correct the colorbar axes colours 281 set(hCB(yCol==3), 'YColor', [1 1 1]); 282 set(hCB(xCol==3), 'XColor', [1 1 1]); 283 % Print large version to array 284 A = print2array(fig, magnify, renderer); 285 % Downscale the image 286 A = downsize(single(A), options.aa_factor); 287 % Set the background colour (and size) back to normal 288 set(fig, 'Color', tcol, 'Position', pos); 289 % Compute the alpha map 290 alpha = round(sum(B - A, 3)) / (255 * 3) + 1; 291 A = alpha; 292 A(A==0) = 1; 293 A = B ./ A(:,:,[1 1 1]); 294 clear B 295 % Convert to greyscale 296 if options.colourspace == 2 297 A = rgb2grey(A); 298 end 299 A = uint8(A); 300 % Crop the background 301 if options.crop 302 [alpha, v] = crop_borders(alpha, 0, 1); 303 A = A(v(1):v(2),v(3):v(4),:); 304 end 305 if options.png 306 % Compute the resolution 307 res = options.magnify * get(0, 'ScreenPixelsPerInch') / 25.4e-3; 308 % Save the png 309 imwrite(A, [options.name '.png'], 'Alpha', double(alpha), 'ResolutionUnit', 'meter', 'XResolution', res, 'YResolution', res); 310 % Clear the png bit 311 options.png = false; 312 end 313 % Return only one channel for greyscale 314 if isbitmap(options) 315 A = check_greyscale(A); 316 end 317 if options.alpha 318 % Store the image 319 im = A; 320 % Clear the alpha bit 321 options.alpha = false; 322 end 323 % Get the non-alpha image 324 if isbitmap(options) 325 alph = alpha(:,:,ones(1, size(A, 3))); 326 A = uint8(single(A) .* alph + 255 * (1 - alph)); 327 clear alph 328 end 329 if options.im 330 % Store the new image 331 im = A; 332 end 257 333 else 258 % Check we have a figure 259 if ~isequal(get(fig, 'Type'), 'figure'); 260 error('Handle must be that of a figure, axes or uipanel'); 261 end 262 % Get the old InvertHardcopy mode 263 old_mode = get(fig, 'InvertHardcopy'); 264 end 265 266 % Hack the font units where necessary (due to a font rendering bug in print?). 267 % This may not work perfectly in all cases. 268 % Also it can change the figure layout if reverted, so use a copy. 269 magnify = options.magnify * options.aa_factor; 270 if isbitmap(options) && magnify ~= 1 271 fontu = findall(fig, 'FontUnits', 'normalized'); 272 if ~isempty(fontu) 273 % Some normalized font units found 274 if ~cls 275 fig = copyfig(fig); 276 set(fig, 'Visible', 'off'); 277 fontu = findall(fig, 'FontUnits', 'normalized'); 278 cls = true; 334 % Print large version to array 335 if options.transparent 336 % MATLAB "feature": apparently figure size can change when changing 337 % colour in -nodisplay mode 338 pos = get(fig, 'Position'); 339 tcol = get(fig, 'Color'); 340 set(fig, 'Color', 'w', 'Position', pos); 341 A = print2array(fig, magnify, renderer); 342 set(fig, 'Color', tcol, 'Position', pos); 343 tcol = 255; 344 else 345 [A, tcol] = print2array(fig, magnify, renderer); 346 end 347 % Crop the background 348 if options.crop 349 A = crop_borders(A, tcol, 1); 350 end 351 % Downscale the image 352 A = downsize(A, options.aa_factor); 353 if options.colourspace == 2 354 % Convert to greyscale 355 A = rgb2grey(A); 356 else 357 % Return only one channel for greyscale 358 A = check_greyscale(A); 359 end 360 % Outputs 361 if options.im 362 im = A; 363 end 364 if options.alpha 365 im = A; 366 alpha = zeros(size(A, 1), size(A, 2), 'single'); 367 end 368 end 369 % Save the images 370 if options.png 371 res = options.magnify * get(0, 'ScreenPixelsPerInch') / 25.4e-3; 372 imwrite(A, [options.name '.png'], 'ResolutionUnit', 'meter', 'XResolution', res, 'YResolution', res); 373 end 374 if options.bmp 375 imwrite(A, [options.name '.bmp']); 376 end 377 % Save jpeg with given quality 378 if options.jpg 379 quality = options.quality; 380 if isempty(quality) 381 quality = 95; 382 end 383 if quality > 100 384 imwrite(A, [options.name '.jpg'], 'Mode', 'lossless'); 385 else 386 imwrite(A, [options.name '.jpg'], 'Quality', quality); 387 end 388 end 389 % Save tif images in cmyk if wanted (and possible) 390 if options.tif 391 if options.colourspace == 1 && size(A, 3) == 3 392 A = double(255 - A); 393 K = min(A, [], 3); 394 K_ = 255 ./ max(255 - K, 1); 395 C = (A(:,:,1) - K) .* K_; 396 M = (A(:,:,2) - K) .* K_; 397 Y = (A(:,:,3) - K) .* K_; 398 A = uint8(cat(3, C, M, Y, K)); 399 clear C M Y K K_ 400 end 401 append_mode = {'overwrite', 'append'}; 402 imwrite(A, [options.name '.tif'], 'Resolution', options.magnify*get(0, 'ScreenPixelsPerInch'), 'WriteMode', append_mode{options.append+1}); 403 end 404 end 405 % Now do the vector formats 406 if isvector(options) 407 % Set the default renderer to painters 408 if ~options.renderer 409 renderer = '-painters'; 410 end 411 % Generate some filenames 412 tmp_nam = [tempname '.eps']; 413 if options.pdf 414 pdf_nam = [options.name '.pdf']; 415 else 416 pdf_nam = [tempname '.pdf']; 417 end 418 % Generate the options for print 419 p2eArgs = {renderer, sprintf('-r%d', options.resolution)}; 420 if options.colourspace == 1 421 p2eArgs = [p2eArgs {'-cmyk'}]; 422 end 423 if ~options.crop 424 p2eArgs = [p2eArgs {'-loose'}]; 425 end 426 try 427 % Generate an eps 428 print2eps(tmp_nam, fig, options.bb_padding, p2eArgs{:}); 429 % Remove the background, if desired 430 if options.transparent && ~isequal(get(fig, 'Color'), 'none') 431 eps_remove_background(tmp_nam, 1 + using_hg2(fig)); 432 end 433 % Add a bookmark to the PDF if desired 434 if options.bookmark 435 fig_nam = get(fig, 'Name'); 436 if isempty(fig_nam) 437 warning('export_fig:EmptyBookmark', 'Bookmark requested for figure with no name. Bookmark will be empty.'); 279 438 end 280 set(fontu, 'FontUnits', 'points'); 281 end 282 end 283 284 try 285 % MATLAB "feature": axes limits and tick marks can change when printing 286 Hlims = findall(fig, 'Type', 'axes'); 287 if ~cls 288 % Record the old axes limit and tick modes 289 Xlims = make_cell(get(Hlims, 'XLimMode')); 290 Ylims = make_cell(get(Hlims, 'YLimMode')); 291 Zlims = make_cell(get(Hlims, 'ZLimMode')); 292 Xtick = make_cell(get(Hlims, 'XTickMode')); 293 Ytick = make_cell(get(Hlims, 'YTickMode')); 294 Ztick = make_cell(get(Hlims, 'ZTickMode')); 295 Xlabel = make_cell(get(Hlims, 'XTickLabelMode')); 296 Ylabel = make_cell(get(Hlims, 'YTickLabelMode')); 297 Zlabel = make_cell(get(Hlims, 'ZTickLabelMode')); 298 end 299 300 % Set all axes limit and tick modes to manual, so the limits and ticks can't change 301 % Fix Matlab R2014b bug (issue #34): plot markers are not displayed when ZLimMode='manual' 302 set(Hlims, 'XLimMode', 'manual', 'YLimMode', 'manual'); 303 set_tick_mode(Hlims, 'X'); 304 set_tick_mode(Hlims, 'Y'); 305 if ~using_hg2(fig) 306 set(Hlims,'ZLimMode', 'manual'); 307 set_tick_mode(Hlims, 'Z'); 308 end 309 catch 310 % ignore - fix issue #4 (using HG2 on R2014a and earlier) 311 end 312 313 % Fix issue #21 (bold TeX axes labels/titles in R2014b when exporting to EPS/PDF) 314 try 315 if using_hg2(fig) && isvector(options) 316 % Set the FontWeight of axes labels/titles to 'normal' 317 % Fix issue #69: set non-bold font only if the string contains symbols (\beta etc.) 318 texLabels = findall(fig, 'type','text', 'FontWeight','bold'); 319 symbolIdx = ~cellfun('isempty',strfind({texLabels.String},'\')); 320 set(texLabels(symbolIdx), 'FontWeight','normal'); 321 end 322 catch 323 % ignore 324 end 325 326 % Fix issue #42: non-normalized annotations on HG1 (internal Matlab bug) 327 annotationHandles = []; 328 try 329 if ~using_hg2(fig) 330 annotationHandles = findall(fig,'Type','hggroup','-and','-property','Units','-and','-not','Units','norm'); 331 originalUnits = get(annotationHandles,'Units'); 332 set(annotationHandles,'Units','norm'); 333 end 334 catch 335 % should never happen, but ignore in any case - issue #50 336 end 337 338 % Fix issue #46: Ghostscript crash if figure units <> pixels 339 oldFigUnits = get(fig,'Units'); 340 set(fig,'Units','pixels'); 341 342 % Set to print exactly what is there 343 set(fig, 'InvertHardcopy', 'off'); 344 % Set the renderer 345 switch options.renderer 346 case 1 347 renderer = '-opengl'; 348 case 2 349 renderer = '-zbuffer'; 350 case 3 351 renderer = '-painters'; 352 otherwise 353 renderer = '-opengl'; % Default for bitmaps 354 end 355 356 try 357 % Do the bitmap formats first 358 if isbitmap(options) 359 if abs(options.bb_padding) > 1 360 displaySuggestedWorkarounds = false; 361 error('For bitmap output (png,jpg,tif,bmp) the padding value (-p) must be between -1<p<1') 439 add_bookmark(tmp_nam, fig_nam); 440 end 441 % Generate a pdf 442 eps2pdf(tmp_nam, pdf_nam, 1, options.append, options.colourspace==2, options.quality); 443 catch ex 444 % Delete the eps 445 delete(tmp_nam); 446 rethrow(ex); 447 end 448 % Delete the eps 449 delete(tmp_nam); 450 if options.eps 451 try 452 % Generate an eps from the pdf 453 pdf2eps(pdf_nam, [options.name '.eps']); 454 catch ex 455 if ~options.pdf 456 % Delete the pdf 457 delete(pdf_nam); 362 458 end 363 % Get the background colour 364 if options.transparent && (options.png || options.alpha) 365 % Get out an alpha channel 366 % MATLAB "feature": black colorbar axes can change to white and vice versa! 367 hCB = findall(fig, 'Type','axes', 'Tag','Colorbar'); 368 if isempty(hCB) 369 yCol = []; 370 xCol = []; 371 else 372 yCol = get(hCB, 'YColor'); 373 xCol = get(hCB, 'XColor'); 374 if iscell(yCol) 375 yCol = cell2mat(yCol); 376 xCol = cell2mat(xCol); 459 rethrow(ex); 460 end 461 if ~options.pdf 462 % Delete the pdf 463 delete(pdf_nam); 464 end 465 end 466 end 467 if cls 468 % Close the created figure 469 close(fig); 470 else 471 % Reset the hardcopy mode 472 set(fig, 'InvertHardcopy', old_mode); 473 % Reset the axes limit and tick modes 474 for a = 1:numel(Hlims) 475 set(Hlims(a), 'XLimMode', Xlims{a}, 'YLimMode', Ylims{a}, 'ZLimMode', Zlims{a}, 'XTickMode', Xtick{a}, 'YTickMode', Ytick{a}, 'ZTickMode', Ztick{a}); 476 end 477 end 478 end 479 480 function [fig, options] = parse_args(nout, varargin) 481 % Parse the input arguments 482 % Set the defaults 483 fig = get(0, 'CurrentFigure'); 484 options = struct('name', 'export_fig_out', ... 485 'crop', true, ... 486 'transparent', false, ... 487 'renderer', 0, ... % 0: default, 1: OpenGL, 2: ZBuffer, 3: Painters 488 'pdf', false, ... 489 'eps', false, ... 490 'png', false, ... 491 'tif', false, ... 492 'jpg', false, ... 493 'bmp', false, ... 494 'colourspace', 0, ... % 0: RGB/gray, 1: CMYK, 2: gray 495 'append', false, ... 496 'im', nout == 1, ... 497 'alpha', nout == 2, ... 498 'aa_factor', 0, ... 499 'bb_padding', 0, ... 500 'magnify', [], ... 501 'resolution', [], ... 502 'bookmark', false, ... 503 'quality', []); 504 native = false; % Set resolution to native of an image 505 506 % Go through the other arguments 507 for a = 1:nargin-1 508 if all(ishandle(varargin{a})) 509 fig = varargin{a}; 510 elseif ischar(varargin{a}) && ~isempty(varargin{a}) 511 if varargin{a}(1) == '-' 512 switch lower(varargin{a}(2:end)) 513 case 'nocrop' 514 options.crop = false; 515 case {'trans', 'transparent'} 516 options.transparent = true; 517 case 'opengl' 518 options.renderer = 1; 519 case 'zbuffer' 520 options.renderer = 2; 521 case 'painters' 522 options.renderer = 3; 523 case 'pdf' 524 options.pdf = true; 525 case 'eps' 526 options.eps = true; 527 case 'png' 528 options.png = true; 529 case {'tif', 'tiff'} 530 options.tif = true; 531 case {'jpg', 'jpeg'} 532 options.jpg = true; 533 case 'bmp' 534 options.bmp = true; 535 case 'rgb' 536 options.colourspace = 0; 537 case 'cmyk' 538 options.colourspace = 1; 539 case {'gray', 'grey'} 540 options.colourspace = 2; 541 case {'a1', 'a2', 'a3', 'a4'} 542 options.aa_factor = str2double(varargin{a}(3)); 543 case 'append' 544 options.append = true; 545 case 'bookmark' 546 options.bookmark = true; 547 case 'native' 548 native = true; 549 otherwise 550 val = str2double(regexp(varargin{a}, '(?<=-(m|M|r|R|q|Q|p|P))-?\d*.?\d+', 'match')); 551 if ~isscalar(val) 552 error('option %s not recognised', varargin{a}); 377 553 end 378 yCol = sum(yCol, 2); 379 xCol = sum(xCol, 2); 380 end 381 % MATLAB "feature": apparently figure size can change when changing 382 % colour in -nodisplay mode 383 pos = get(fig, 'Position'); 384 % Set the background colour to black, and set size in case it was 385 % changed internally 386 tcol = get(fig, 'Color'); 387 set(fig, 'Color', 'k', 'Position', pos); 388 % Correct the colorbar axes colours 389 set(hCB(yCol==0), 'YColor', [0 0 0]); 390 set(hCB(xCol==0), 'XColor', [0 0 0]); 391 392 % The following code might cause out-of-memory errors 393 try 394 % Print large version to array 395 B = print2array(fig, magnify, renderer); 396 % Downscale the image 397 B = downsize(single(B), options.aa_factor); 398 catch 399 % This is more conservative in memory, but kills transparency (issue #58) 400 B = single(print2array(fig, magnify/options.aa_factor, renderer)); 401 end 402 403 % Set background to white (and set size) 404 set(fig, 'Color', 'w', 'Position', pos); 405 % Correct the colorbar axes colours 406 set(hCB(yCol==3), 'YColor', [1 1 1]); 407 set(hCB(xCol==3), 'XColor', [1 1 1]); 408 409 % The following code might cause out-of-memory errors 410 try 411 % Print large version to array 412 A = print2array(fig, magnify, renderer); 413 % Downscale the image 414 A = downsize(single(A), options.aa_factor); 415 catch 416 % This is more conservative in memory, but kills transparency (issue #58) 417 A = single(print2array(fig, magnify/options.aa_factor, renderer)); 418 end 419 420 % Set the background colour (and size) back to normal 421 set(fig, 'Color', tcol, 'Position', pos); 422 % Compute the alpha map 423 alpha = round(sum(B - A, 3)) / (255 * 3) + 1; 424 A = alpha; 425 A(A==0) = 1; 426 A = B ./ A(:,:,[1 1 1]); 427 clear B 428 % Convert to greyscale 429 if options.colourspace == 2 430 A = rgb2grey(A); 431 end 432 A = uint8(A); 433 % Crop the background 434 if options.crop 435 %[alpha, v] = crop_borders(alpha, 0, 1); 436 %A = A(v(1):v(2),v(3):v(4),:); 437 [alpha, vA, vB] = crop_borders(alpha, 0, options.bb_padding); 438 if ~any(isnan(vB)) % positive padding 439 B = repmat(uint8(zeros(1,1,size(A,3))),size(alpha)); 440 B(vB(1):vB(2), vB(3):vB(4), :) = A(vA(1):vA(2), vA(3):vA(4), :); % ADDED BY OH 441 A = B; 442 else % negative padding 443 A = A(vA(1):vA(2), vA(3):vA(4), :); 554 switch lower(varargin{a}(2)) 555 case 'm' 556 options.magnify = val; 557 case 'r' 558 options.resolution = val; 559 case 'q' 560 options.quality = max(val, 0); 561 case 'p' 562 options.bb_padding = val; 444 563 end 445 end446 if options.png447 % Compute the resolution448 res = options.magnify * get(0, 'ScreenPixelsPerInch') / 25.4e-3;449 % Save the png450 imwrite(A, [options.name '.png'], 'Alpha', double(alpha), 'ResolutionUnit', 'meter', 'XResolution', res, 'YResolution', res);451 % Clear the png bit452 options.png = false;453 end454 % Return only one channel for greyscale455 if isbitmap(options)456 A = check_greyscale(A);457 end458 if options.alpha459 % Store the image460 imageData = A;461 % Clear the alpha bit462 options.alpha = false;463 end464 % Get the non-alpha image465 if isbitmap(options)466 alph = alpha(:,:,ones(1, size(A, 3)));467 A = uint8(single(A) .* alph + 255 * (1 - alph));468 clear alph469 end470 if options.im471 % Store the new image472 imageData = A;473 end474 else475 % Print large version to array476 if options.transparent477 % MATLAB "feature": apparently figure size can change when changing478 % colour in -nodisplay mode479 pos = get(fig, 'Position');480 tcol = get(fig, 'Color');481 set(fig, 'Color', 'w', 'Position', pos);482 A = print2array(fig, magnify, renderer);483 set(fig, 'Color', tcol, 'Position', pos);484 tcol = 255;485 else486 [A, tcol] = print2array(fig, magnify, renderer);487 end488 % Crop the background489 if options.crop490 A = crop_borders(A, tcol, options.bb_padding);491 end492 % Downscale the image493 A = downsize(A, options.aa_factor);494 if options.colourspace == 2495 % Convert to greyscale496 A = rgb2grey(A);497 else498 % Return only one channel for greyscale499 A = check_greyscale(A);500 end501 % Outputs502 if options.im503 imageData = A;504 end505 if options.alpha506 imageData = A;507 alpha = zeros(size(A, 1), size(A, 2), 'single');508 end509 564 end 510 % Save the images511 if options.png512 res = options.magnify * get(0, 'ScreenPixelsPerInch') / 25.4e-3;513 imwrite(A, [options.name '.png'], 'ResolutionUnit', 'meter', 'XResolution', res, 'YResolution', res);565 else 566 [p, options.name, ext] = fileparts(varargin{a}); 567 if ~isempty(p) 568 options.name = [p filesep options.name]; 514 569 end 515 if options.bmp 516 imwrite(A, [options.name '.bmp']); 570 switch lower(ext) 571 case {'.tif', '.tiff'} 572 options.tif = true; 573 case {'.jpg', '.jpeg'} 574 options.jpg = true; 575 case '.png' 576 options.png = true; 577 case '.bmp' 578 options.bmp = true; 579 case '.eps' 580 options.eps = true; 581 case '.pdf' 582 options.pdf = true; 583 otherwise 584 options.name = varargin{a}; 517 585 end 518 % Save jpeg with given quality 519 if options.jpg 520 quality = options.quality; 521 if isempty(quality) 522 quality = 95; 523 end 524 if quality > 100 525 imwrite(A, [options.name '.jpg'], 'Mode', 'lossless'); 526 else 527 imwrite(A, [options.name '.jpg'], 'Quality', quality); 528 end 529 end 530 % Save tif images in cmyk if wanted (and possible) 531 if options.tif 532 if options.colourspace == 1 && size(A, 3) == 3 533 A = double(255 - A); 534 K = min(A, [], 3); 535 K_ = 255 ./ max(255 - K, 1); 536 C = (A(:,:,1) - K) .* K_; 537 M = (A(:,:,2) - K) .* K_; 538 Y = (A(:,:,3) - K) .* K_; 539 A = uint8(cat(3, C, M, Y, K)); 540 clear C M Y K K_ 541 end 542 append_mode = {'overwrite', 'append'}; 543 imwrite(A, [options.name '.tif'], 'Resolution', options.magnify*get(0, 'ScreenPixelsPerInch'), 'WriteMode', append_mode{options.append+1}); 544 end 545 end 546 547 % Now do the vector formats 548 if isvector(options) 549 % Set the default renderer to painters 550 if ~options.renderer 551 if isempty(findall(fig,'-property','FaceAlpha','-and','-not','FaceAlpha',1)) && ... 552 isempty(findall(fig,'type','patch')) 553 renderer = '-painters'; 554 else 555 % This is *MUCH* slower, but more accurate for patches and transparent annotations (issue #39) 556 renderer = '-opengl'; 557 end 558 end 559 % Generate some filenames 560 tmp_nam = [tempname '.eps']; 561 try 562 % Ensure that the temp dir is writable (Javier Paredes 30/1/15) 563 fid = fopen(tmp_nam,'w'); 564 fwrite(fid,1); 565 fclose(fid); 566 delete(tmp_nam); 567 isTempDirOk = true; 568 catch 569 % Temp dir is not writable, so use the user-specified folder 570 [dummy,fname,fext] = fileparts(tmp_nam); %#ok<ASGLU> 571 fpath = fileparts(options.name); 572 tmp_nam = fullfile(fpath,[fname fext]); 573 isTempDirOk = false; 574 end 575 if isTempDirOk 576 pdf_nam_tmp = [tempname '.pdf']; 577 else 578 pdf_nam_tmp = fullfile(fpath,[fname '.pdf']); 579 end 580 if options.pdf 581 pdf_nam = [options.name '.pdf']; 582 try copyfile(pdf_nam, pdf_nam_tmp, 'f'); catch, end % fix for issue #65 583 else 584 pdf_nam = pdf_nam_tmp; 585 end 586 % Generate the options for print 587 p2eArgs = {renderer, sprintf('-r%d', options.resolution)}; 588 if options.colourspace == 1 % CMYK 589 % Issue #33: due to internal bugs in Matlab's print() function, we can't use its -cmyk option 590 %p2eArgs{end+1} = '-cmyk'; 591 end 592 if ~options.crop 593 % Issue #56: due to internal bugs in Matlab's print() function, we can't use its internal cropping mechanism, 594 % therefore we always use '-loose' (in print2eps.m) and do our own cropping (in crop_borders) 595 %p2eArgs{end+1} = '-loose'; 596 end 597 if any(strcmpi(varargin,'-depsc')) 598 % Issue #45: lines in image subplots are exported in invalid color. 599 % The workaround is to use the -depsc parameter instead of the default -depsc2 600 p2eArgs{end+1} = '-depsc'; 601 end 602 try 603 % Generate an eps 604 print2eps(tmp_nam, fig, [options.bb_padding, options.crop, options.fontswap], p2eArgs{:}); 605 % Remove the background, if desired 606 if options.transparent && ~isequal(get(fig, 'Color'), 'none') 607 eps_remove_background(tmp_nam, 1 + using_hg2(fig)); 608 end 609 % Fix colorspace to CMYK, if requested (workaround for issue #33) 610 if options.colourspace == 1 % CMYK 611 % Issue #33: due to internal bugs in Matlab's print() function, we can't use its -cmyk option 612 change_rgb_to_cmyk(tmp_nam); 613 end 614 % Add a bookmark to the PDF if desired 615 if options.bookmark 616 fig_nam = get(fig, 'Name'); 617 if isempty(fig_nam) 618 warning('export_fig:EmptyBookmark', 'Bookmark requested for figure with no name. Bookmark will be empty.'); 619 end 620 add_bookmark(tmp_nam, fig_nam); 621 end 622 % Generate a pdf 623 eps2pdf(tmp_nam, pdf_nam_tmp, 1, options.append, options.colourspace==2, options.quality, options.gs_options); 624 % Ghostscript croaks on % chars in the output PDF file, so use tempname and then rename the file 625 try movefile(pdf_nam_tmp, pdf_nam, 'f'); catch, end 626 catch ex 627 % Delete the eps 628 delete(tmp_nam); 629 rethrow(ex); 630 end 631 % Delete the eps 632 delete(tmp_nam); 633 if options.eps 634 try 635 % Generate an eps from the pdf 636 % since pdftops can't handle relative paths (e.g., '..\'), use a temp file 637 eps_nam_tmp = strrep(pdf_nam_tmp,'.pdf','.eps'); 638 pdf2eps(pdf_nam, eps_nam_tmp); 639 movefile(eps_nam_tmp, [options.name '.eps'], 'f'); 640 catch ex 641 if ~options.pdf 642 % Delete the pdf 643 delete(pdf_nam); 644 end 645 try delete(eps_nam_tmp); catch, end 646 rethrow(ex); 647 end 648 if ~options.pdf 649 % Delete the pdf 650 delete(pdf_nam); 651 end 652 end 653 end 654 655 % Revert the figure or close it (if requested) 656 if cls || options.closeFig 657 % Close the created figure 658 close(fig); 586 end 587 end 588 end 589 590 % Set default anti-aliasing now we know the renderer 591 if options.aa_factor == 0 592 options.aa_factor = 1 + 2 * (~(using_hg2(fig) && strcmp(get(ancestor(fig, 'figure'), 'GraphicsSmoothing'), 'on')) | (options.renderer == 3)); 593 end 594 595 % Convert user dir '~' to full path 596 if numel(options.name) > 2 && options.name(1) == '~' && (options.name(2) == '/' || options.name(2) == '\') 597 options.name = fullfile(char(java.lang.System.getProperty('user.home')), options.name(2:end)); 598 end 599 600 % Compute the magnification and resolution 601 if isempty(options.magnify) 602 if isempty(options.resolution) 603 options.magnify = 1; 604 options.resolution = 864; 605 else 606 options.magnify = options.resolution ./ get(0, 'ScreenPixelsPerInch'); 607 end 608 elseif isempty(options.resolution) 609 options.resolution = 864; 610 end 611 612 % Check we have a figure handle 613 if isempty(fig) 614 error('No figure found'); 615 end 616 617 % Set the default format 618 if ~isvector(options) && ~isbitmap(options) 619 options.png = true; 620 end 621 622 % Check whether transparent background is wanted (old way) 623 if isequal(get(ancestor(fig(1), 'figure'), 'Color'), 'none') 624 options.transparent = true; 625 end 626 627 % If requested, set the resolution to the native vertical resolution of the 628 % first suitable image found 629 if native && isbitmap(options) 630 % Find a suitable image 631 list = findobj(fig, 'Type', 'image', 'Tag', 'export_fig_native'); 632 if isempty(list) 633 list = findobj(fig, 'Type', 'image', 'Visible', 'on'); 634 end 635 for hIm = list(:)' 636 % Check height is >= 2 637 height = size(get(hIm, 'CData'), 1); 638 if height < 2 639 continue 640 end 641 % Account for the image filling only part of the axes, or vice 642 % versa 643 yl = get(hIm, 'YData'); 644 if isscalar(yl) 645 yl = [yl(1)-0.5 yl(1)+height+0.5]; 659 646 else 660 % Reset the hardcopy mode 661 set(fig, 'InvertHardcopy', old_mode); 662 % Reset the axes limit and tick modes 663 for a = 1:numel(Hlims) 664 try 665 set(Hlims(a), 'XLimMode', Xlims{a}, 'YLimMode', Ylims{a}, 'ZLimMode', Zlims{a},... 666 'XTickMode', Xtick{a}, 'YTickMode', Ytick{a}, 'ZTickMode', Ztick{a},... 667 'XTickLabelMode', Xlabel{a}, 'YTickLabelMode', Ylabel{a}, 'ZTickLabelMode', Zlabel{a}); 668 catch 669 % ignore - fix issue #4 (using HG2 on R2014a and earlier) 670 end 671 end 672 % Revert the tex-labels font weights 673 try set(texLabels, 'FontWeight','bold'); catch, end 674 % Revert annotation units 675 for handleIdx = 1 : numel(annotationHandles) 676 try 677 oldUnits = originalUnits{handleIdx}; 678 catch 679 oldUnits = originalUnits; 680 end 681 try set(annotationHandles(handleIdx),'Units',oldUnits); catch, end 682 end 683 % Revert figure units 684 set(fig,'Units',oldFigUnits); 685 end 686 687 % Output to clipboard (if requested) 688 if options.clipboard 689 % Delete the output file if unchanged from the default name ('export_fig_out.png') 690 if strcmpi(options.name,'export_fig_out') 691 try 692 fileInfo = dir('export_fig_out.png'); 693 if ~isempty(fileInfo) 694 timediff = now - fileInfo.datenum; 695 ONE_SEC = 1/24/60/60; 696 if timediff < ONE_SEC 697 delete('export_fig_out.png'); 698 end 699 end 700 catch 701 % never mind... 702 end 703 end 704 705 % Save the image in the system clipboard 706 % credit: Jiro Doke's IMCLIPBOARD: http://www.mathworks.com/matlabcentral/fileexchange/28708-imclipboard 707 try 708 error(javachk('awt', 'export_fig -clipboard output')); 709 catch 710 warning('export_fig -clipboard output failed: requires Java to work'); 711 return; 712 end 713 try 714 % Import necessary Java classes 715 import java.awt.Toolkit.* 716 import java.awt.image.BufferedImage 717 import java.awt.datatransfer.DataFlavor 718 719 % Get System Clipboard object (java.awt.Toolkit) 720 cb = getDefaultToolkit.getSystemClipboard(); 721 722 % Add java class (ImageSelection) to the path 723 if ~exist('ImageSelection', 'class') 724 javaaddpath(fileparts(which(mfilename)), '-end'); 725 end 726 727 % Get image size 728 ht = size(imageData, 1); 729 wd = size(imageData, 2); 730 731 % Convert to Blue-Green-Red format 732 try 733 imageData2 = imageData(:, :, [3 2 1]); 734 catch 735 % Probably gray-scaled image (2D, without the 3rd [RGB] dimension) 736 imageData2 = imageData(:, :, [1 1 1]); 737 end 738 739 % Convert to 3xWxH format 740 imageData2 = permute(imageData2, [3, 2, 1]); 741 742 % Append Alpha data (unused - transparency is not supported in clipboard copy) 743 alphaData2 = uint8(permute(255*alpha,[3,2,1])); %=255*ones(1,wd,ht,'uint8') 744 imageData2 = cat(1, imageData2, alphaData2); 745 746 % Create image buffer 747 imBuffer = BufferedImage(wd, ht, BufferedImage.TYPE_INT_RGB); 748 imBuffer.setRGB(0, 0, wd, ht, typecast(imageData2(:), 'int32'), 0, wd); 749 750 % Create ImageSelection object from the image buffer 751 imSelection = ImageSelection(imBuffer); 752 753 % Set clipboard content to the image 754 cb.setContents(imSelection, []); 755 catch 756 warning('export_fig -clipboard output failed: %s', lasterr); %#ok<LERR> 757 end 758 end 759 760 % Don't output the data to console unless requested 761 if ~nargout 762 clear imageData alpha 763 end 764 catch err 765 % Display possible workarounds before the error message 766 if displaySuggestedWorkarounds 767 if ~hadError, fprintf(2, 'export_fig error. '); end 768 fprintf(2, 'Please ensure:\n'); 769 fprintf(2, ' that you are using the <a href="https://github.com/altmany/export_fig/archive/master.zip">latest version</a> of export_fig\n'); 770 fprintf(2, ' and that you have <a href="http://www.ghostscript.com">Ghostscript</a> installed\n'); 771 try 772 if options.eps 773 fprintf(2, ' and that you have <a href="http://www.foolabs.com/xpdf">pdftops</a> installed\n'); 774 end 775 catch 776 % ignore - probably an error in parse_args 777 end 778 fprintf(2, ' and that you do not have <a href="matlab:which export_fig -all">multiple versions</a> of export_fig installed by mistake\n'); 779 fprintf(2, ' and that you did not made a mistake in the <a href="matlab:help export_fig">expected input arguments</a>\n'); 780 fprintf(2, '\nIf the problem persists, then please <a href="https://github.com/altmany/export_fig/issues">report a new issue</a>.\n\n'); 781 end 782 rethrow(err) 783 end 784 end 785 786 function [fig, options] = parse_args(nout, fig, varargin) 787 % Parse the input arguments 788 % Set the defaults 789 options = struct(... 790 'name', 'export_fig_out', ... 791 'crop', true, ... 792 'transparent', false, ... 793 'renderer', 0, ... % 0: default, 1: OpenGL, 2: ZBuffer, 3: Painters 794 'pdf', false, ... 795 'eps', false, ... 796 'png', false, ... 797 'tif', false, ... 798 'jpg', false, ... 799 'bmp', false, ... 800 'clipboard', false, ... 801 'colourspace', 0, ... % 0: RGB/gray, 1: CMYK, 2: gray 802 'append', false, ... 803 'im', nout == 1, ... 804 'alpha', nout == 2, ... 805 'aa_factor', 0, ... 806 'bb_padding', 0, ... 807 'magnify', [], ... 808 'resolution', [], ... 809 'bookmark', false, ... 810 'closeFig', false, ... 811 'quality', [], ... 812 'update', false, ... 813 'fontswap', true, ... 814 'gs_options', {{}}); 815 native = false; % Set resolution to native of an image 816 817 % Go through the other arguments 818 skipNext = false; 819 for a = 1:nargin-2 820 if skipNext 821 skipNext = false; 822 continue; 823 end 824 if all(ishandle(varargin{a})) 825 fig = varargin{a}; 826 elseif ischar(varargin{a}) && ~isempty(varargin{a}) 827 if varargin{a}(1) == '-' 828 switch lower(varargin{a}(2:end)) 829 case 'nocrop' 830 options.crop = false; 831 case {'trans', 'transparent'} 832 options.transparent = true; 833 case 'opengl' 834 options.renderer = 1; 835 case 'zbuffer' 836 options.renderer = 2; 837 case 'painters' 838 options.renderer = 3; 839 case 'pdf' 840 options.pdf = true; 841 case 'eps' 842 options.eps = true; 843 case 'png' 844 options.png = true; 845 case {'tif', 'tiff'} 846 options.tif = true; 847 case {'jpg', 'jpeg'} 848 options.jpg = true; 849 case 'bmp' 850 options.bmp = true; 851 case 'rgb' 852 options.colourspace = 0; 853 case 'cmyk' 854 options.colourspace = 1; 855 case {'gray', 'grey'} 856 options.colourspace = 2; 857 case {'a1', 'a2', 'a3', 'a4'} 858 options.aa_factor = str2double(varargin{a}(3)); 859 case 'append' 860 options.append = true; 861 case 'bookmark' 862 options.bookmark = true; 863 case 'native' 864 native = true; 865 case 'clipboard' 866 options.clipboard = true; 867 options.im = true; 868 options.alpha = true; 869 case 'svg' 870 msg = ['SVG output is not supported by export_fig. Use one of the following alternatives:\n' ... 871 ' 1. saveas(gcf,''filename.svg'')\n' ... 872 ' 2. plot2svg utility: http://github.com/jschwizer99/plot2svg\n' ... 873 ' 3. export_fig to EPS/PDF, then convert to SVG using generic (non-Matlab) tools\n']; 874 error(sprintf(msg)); %#ok<SPERR> 875 case 'update' 876 % Download the latest version of export_fig into the export_fig folder 877 try 878 zipFileName = 'https://github.com/altmany/export_fig/archive/master.zip'; 879 folderName = fileparts(which(mfilename('fullpath'))); 880 targetFileName = fullfile(folderName, datestr(now,'yyyy-mm-dd.zip')); 881 urlwrite(zipFileName,targetFileName); 882 catch 883 error('Could not download %s into %s\n',zipFileName,targetFileName); 884 end 885 886 % Unzip the downloaded zip file in the export_fig folder 887 try 888 unzip(targetFileName,folderName); 889 catch 890 error('Could not unzip %s\n',targetFileName); 891 end 892 case 'nofontswap' 893 options.fontswap = false; 894 otherwise 895 try 896 wasError = false; 897 if strcmpi(varargin{a}(1:2),'-d') 898 varargin{a}(2) = 'd'; % ensure lowercase 'd' 899 options.gs_options{end+1} = varargin{a}; 900 else 901 val = str2double(regexp(varargin{a}, '(?<=-(m|M|r|R|q|Q|p|P))-?\d*.?\d+', 'match')); 902 if isempty(val) || isnan(val) 903 % Issue #51: improved processing of input args (accept space between param name & value) 904 val = str2double(varargin{a+1}); 905 if isscalar(val) && ~isnan(val) 906 skipNext = true; 907 end 908 end 909 if ~isscalar(val) || isnan(val) 910 wasError = true; 911 error('option %s is not recognised or cannot be parsed', varargin{a}); 912 end 913 switch lower(varargin{a}(2)) 914 case 'm' 915 % Magnification may never be negative 916 if val <= 0 917 wasError = true; 918 error('Bad magnification value: %g (must be positive)', val); 919 end 920 options.magnify = val; 921 case 'r' 922 options.resolution = val; 923 case 'q' 924 options.quality = max(val, 0); 925 case 'p' 926 options.bb_padding = val; 927 end 928 end 929 catch err 930 % We might have reached here by raising an intentional error 931 if wasError % intentional raise 932 rethrow(err) 933 else % unintentional 934 error(['Unrecognized export_fig input option: ''' varargin{a} '''']); 935 end 936 end 937 end 938 else 939 [p, options.name, ext] = fileparts(varargin{a}); 940 if ~isempty(p) 941 options.name = [p filesep options.name]; 942 end 943 switch lower(ext) 944 case {'.tif', '.tiff'} 945 options.tif = true; 946 case {'.jpg', '.jpeg'} 947 options.jpg = true; 948 case '.png' 949 options.png = true; 950 case '.bmp' 951 options.bmp = true; 952 case '.eps' 953 options.eps = true; 954 case '.pdf' 955 options.pdf = true; 956 case '.fig' 957 % If no open figure, then load the specified .fig file and continue 958 if isempty(fig) 959 fig = openfig(varargin{a},'invisible'); 960 varargin{a} = fig; 961 options.closeFig = true; 962 else 963 % save the current figure as the specified .fig file and exit 964 saveas(fig(1),varargin{a}); 965 fig = -1; 966 return 967 end 968 case '.svg' 969 msg = ['SVG output is not supported by export_fig. Use one of the following alternatives:\n' ... 970 ' 1. saveas(gcf,''filename.svg'')\n' ... 971 ' 2. plot2svg utility: http://github.com/jschwizer99/plot2svg\n' ... 972 ' 3. export_fig to EPS/PDF, then convert to SVG using generic (non-Matlab) tools\n']; 973 error(sprintf(msg)); %#ok<SPERR> 974 otherwise 975 options.name = varargin{a}; 976 end 977 end 978 end 979 end 980 981 % Quick bail-out if no figure found 982 if isempty(fig), return; end 983 984 % Do border padding with repsect to a cropped image 985 if options.bb_padding 986 options.crop = true; 987 end 988 989 % Set default anti-aliasing now we know the renderer 990 if options.aa_factor == 0 991 try isAA = strcmp(get(ancestor(fig, 'figure'), 'GraphicsSmoothing'), 'on'); catch, isAA = false; end 992 options.aa_factor = 1 + 2 * (~(using_hg2(fig) && isAA) | (options.renderer == 3)); 993 end 994 995 % Convert user dir '~' to full path 996 if numel(options.name) > 2 && options.name(1) == '~' && (options.name(2) == '/' || options.name(2) == '\') 997 options.name = fullfile(char(java.lang.System.getProperty('user.home')), options.name(2:end)); 998 end 999 1000 % Compute the magnification and resolution 1001 if isempty(options.magnify) 1002 if isempty(options.resolution) 1003 options.magnify = 1; 1004 options.resolution = 864; 1005 else 1006 options.magnify = options.resolution ./ get(0, 'ScreenPixelsPerInch'); 1007 end 1008 elseif isempty(options.resolution) 1009 options.resolution = 864; 1010 end 1011 1012 % Set the default format 1013 if ~isvector(options) && ~isbitmap(options) 1014 options.png = true; 1015 end 1016 1017 % Check whether transparent background is wanted (old way) 1018 if isequal(get(ancestor(fig(1), 'figure'), 'Color'), 'none') 1019 options.transparent = true; 1020 end 1021 1022 % If requested, set the resolution to the native vertical resolution of the 1023 % first suitable image found 1024 if native && isbitmap(options) 1025 % Find a suitable image 1026 list = findall(fig, 'Type','image', 'Tag','export_fig_native'); 1027 if isempty(list) 1028 list = findall(fig, 'Type','image', 'Visible','on'); 1029 end 1030 for hIm = list(:)' 1031 % Check height is >= 2 1032 height = size(get(hIm, 'CData'), 1); 1033 if height < 2 647 if ~diff(yl) 1034 648 continue 1035 649 end 1036 % Account for the image filling only part of the axes, or vice 1037 % versa 1038 yl = get(hIm, 'YData'); 1039 if isscalar(yl) 1040 yl = [yl(1)-0.5 yl(1)+height+0.5]; 1041 else 1042 if ~diff(yl) 1043 continue 1044 end 1045 yl = yl + [-0.5 0.5] * (diff(yl) / (height - 1)); 1046 end 1047 hAx = get(hIm, 'Parent'); 1048 yl2 = get(hAx, 'YLim'); 1049 % Find the pixel height of the axes 1050 oldUnits = get(hAx, 'Units'); 1051 set(hAx, 'Units', 'pixels'); 1052 pos = get(hAx, 'Position'); 1053 set(hAx, 'Units', oldUnits); 1054 if ~pos(4) 1055 continue 1056 end 1057 % Found a suitable image 1058 % Account for stretch-to-fill being disabled 1059 pbar = get(hAx, 'PlotBoxAspectRatio'); 1060 pos = min(pos(4), pbar(2)*pos(3)/pbar(1)); 1061 % Set the magnification to give native resolution 1062 options.magnify = abs((height * diff(yl2)) / (pos * diff(yl))); % magnification must never be negative: issue #103 1063 break 1064 end 1065 end 650 yl = yl + [-0.5 0.5] * (diff(yl) / (height - 1)); 651 end 652 hAx = get(hIm, 'Parent'); 653 yl2 = get(hAx, 'YLim'); 654 % Find the pixel height of the axes 655 oldUnits = get(hAx, 'Units'); 656 set(hAx, 'Units', 'pixels'); 657 pos = get(hAx, 'Position'); 658 set(hAx, 'Units', oldUnits); 659 if ~pos(4) 660 continue 661 end 662 % Found a suitable image 663 % Account for stretch-to-fill being disabled 664 pbar = get(hAx, 'PlotBoxAspectRatio'); 665 pos = min(pos(4), pbar(2)*pos(3)/pbar(1)); 666 % Set the magnification to give native resolution 667 options.magnify = (height * diff(yl2)) / (pos * diff(yl)); 668 break 669 end 670 end 1066 671 end 1067 672 1068 673 function A = downsize(A, factor) 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 674 % Downsample an image 675 if factor == 1 676 % Nothing to do 677 return 678 end 679 try 680 % Faster, but requires image processing toolbox 681 A = imresize(A, 1/factor, 'bilinear'); 682 catch 683 % No image processing toolbox - resize manually 684 % Lowpass filter - use Gaussian as is separable, so faster 685 % Compute the 1d Gaussian filter 686 filt = (-factor-1:factor+1) / (factor * 0.6); 687 filt = exp(-filt .* filt); 688 % Normalize the filter 689 filt = single(filt / sum(filt)); 690 % Filter the image 691 padding = floor(numel(filt) / 2); 692 for a = 1:size(A, 3) 693 A(:,:,a) = conv2(filt, filt', single(A([ones(1, padding) 1:end repmat(end, 1, padding)],[ones(1, padding) 1:end repmat(end, 1, padding)],a)), 'valid'); 694 end 695 % Subsample 696 A = A(1+floor(mod(end-1, factor)/2):factor:end,1+floor(mod(end-1, factor)/2):factor:end,:); 697 end 1093 698 end 1094 699 1095 700 function A = rgb2grey(A) 1096 A = cast(reshape(reshape(single(A), [], 3) * single([0.299; 0.587; 0.114]), size(A, 1), size(A, 2)), class(A)); %#ok<ZEROLIKE> 701 A = cast(reshape(reshape(single(A), [], 3) * single([0.299; 0.587; 0.114]), size(A, 1), size(A, 2)), class(A)); 1097 702 end 1098 703 1099 704 function A = check_greyscale(A) 1100 1101 1102 1103 1104 1105 705 % Check if the image is greyscale 706 if size(A, 3) == 3 && ... 707 all(reshape(A(:,:,1) == A(:,:,2), [], 1)) && ... 708 all(reshape(A(:,:,2) == A(:,:,3), [], 1)) 709 A = A(:,:,1); % Save only one channel for 8-bit output 710 end 1106 711 end 1107 712 1108 713 function eps_remove_background(fname, count) 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 714 % Remove the background of an eps file 715 % Open the file 716 fh = fopen(fname, 'r+'); 717 if fh == -1 718 error('Not able to open file %s.', fname); 719 end 720 % Read the file line by line 721 while count 722 % Get the next line 723 l = fgets(fh); 724 if isequal(l, -1) 725 break; % Quit, no rectangle found 726 end 727 % Check if the line contains the background rectangle 728 if isequal(regexp(l, ' *0 +0 +\d+ +\d+ +r[fe] *[\n\r]+', 'start'), 1) 729 % Set the line to whitespace and quit 730 l(1:regexp(l, '[\n\r]', 'start', 'once')-1) = ' '; 731 fseek(fh, -numel(l), 0); 732 fprintf(fh, l); 733 % Reduce the count 734 count = count - 1; 735 end 736 end 737 % Close the file 738 fclose(fh); 1134 739 end 1135 740 1136 741 function b = isvector(options) 1137 742 b = options.pdf || options.eps; 1138 743 end 1139 744 1140 745 function b = isbitmap(options) 1141 746 b = options.png || options.tif || options.jpg || options.bmp || options.im || options.alpha; 1142 747 end 1143 748 1144 749 % Helper function 1145 750 function A = make_cell(A) 1146 1147 1148 751 if ~iscell(A) 752 A = {A}; 753 end 1149 754 end 1150 755 1151 756 function add_bookmark(fname, bookmark_text) 1152 % Adds a bookmark to the temporary EPS file after %%EndPageSetup 1153 % Read in the file 1154 fh = fopen(fname, 'r'); 1155 if fh == -1 1156 error('File %s not found.', fname); 1157 end 1158 try 1159 fstrm = fread(fh, '*char')'; 1160 catch ex 1161 fclose(fh); 1162 rethrow(ex); 1163 end 757 % Adds a bookmark to the temporary EPS file after %%EndPageSetup 758 % Read in the file 759 fh = fopen(fname, 'r'); 760 if fh == -1 761 error('File %s not found.', fname); 762 end 763 try 764 fstrm = fread(fh, '*char')'; 765 catch ex 1164 766 fclose(fh); 1165 1166 % Include standard pdfmark prolog to maximize compatibility 1167 fstrm = strrep(fstrm, '%%BeginProlog', sprintf('%%%%BeginProlog\n/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse'));1168 % Add page bookmark 1169 fstrm = strrep(fstrm, '%%EndPageSetup', sprintf('%%%%EndPageSetup\n[ /Title (%s) /OUT pdfmark',bookmark_text)); 1170 1171 % Write out the updated file 1172 fh = fopen(fname, 'w');1173 if fh == -1 1174 error('Unable to open %s for writing.', fname); 1175 end 1176 try 1177 fwrite(fh, fstrm, 'char*1');1178 catch ex 1179 fclose(fh); 1180 rethrow(ex);1181 end 767 rethrow(ex); 768 end 769 fclose(fh); 770 771 % Include standard pdfmark prolog to maximize compatibility 772 fstrm = strrep(fstrm, '%%BeginProlog', sprintf('%%%%BeginProlog\n/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse')); 773 % Add page bookmark 774 fstrm = strrep(fstrm, '%%EndPageSetup', sprintf('%%%%EndPageSetup\n[ /Title (%s) /OUT pdfmark',bookmark_text)); 775 776 % Write out the updated file 777 fh = fopen(fname, 'w'); 778 if fh == -1 779 error('Unable to open %s for writing.', fname); 780 end 781 try 782 fwrite(fh, fstrm, 'char*1'); 783 catch ex 1182 784 fclose(fh); 785 rethrow(ex); 786 end 787 fclose(fh); 1183 788 end 1184 789 1185 790 function set_tick_mode(Hlims, ax) 1186 % Set the tick mode of linear axes to manual 1187 % Leave log axes alone as these are tricky 1188 M = get(Hlims, [ax 'Scale']); 1189 if ~iscell(M) 1190 M = {M}; 1191 end 1192 M = cellfun(@(c) strcmp(c, 'linear'), M); 1193 set(Hlims(M), [ax 'TickMode'], 'manual'); 1194 %set(Hlims(M), [ax 'TickLabelMode'], 'manual'); % this hides exponent label in HG2! 1195 end 1196 1197 function change_rgb_to_cmyk(fname) % convert RGB => CMYK within an EPS file 1198 % Do post-processing on the eps file 1199 try 1200 % Read the EPS file into memory 1201 fstrm = read_write_entire_textfile(fname); 1202 1203 % Replace all gray-scale colors 1204 fstrm = regexprep(fstrm, '\n([\d.]+) +GC\n', '\n0 0 0 ${num2str(1-str2num($1))} CC\n'); 1205 1206 % Replace all RGB colors 1207 fstrm = regexprep(fstrm, '\n[0.]+ +[0.]+ +[0.]+ +RC\n', '\n0 0 0 1 CC\n'); % pure black 1208 fstrm = regexprep(fstrm, '\n([\d.]+) +([\d.]+) +([\d.]+) +RC\n', '\n${sprintf(''%.4g '',[1-[str2num($1),str2num($2),str2num($3)]/max([str2num($1),str2num($2),str2num($3)]),1-max([str2num($1),str2num($2),str2num($3)])])} CC\n'); 1209 1210 % Overwrite the file with the modified contents 1211 read_write_entire_textfile(fname, fstrm); 1212 catch 1213 % never mind - leave as is... 1214 end 1215 end 791 % Set the tick mode of linear axes to manual 792 % Leave log axes alone as these are tricky 793 M = get(Hlims, [ax 'Scale']); 794 if ~iscell(M) 795 M = {M}; 796 end 797 M = cellfun(@(c) strcmp(c, 'linear'), M); 798 set(Hlims(M), [ax 'TickMode'], 'manual'); 799 end -
issm/trunk-jpl/externalpackages/export_fig/fix_lines.m
r19571 r19993 38 38 % opened. 39 39 40 % 01/03/15: Issue #20: warn users if using this function in HG2 (R2014b+)41 % 27/03/15: Fixed out of memory issue with enormous EPS files (generated by print() with OpenGL renderer), related to issue #3942 43 40 function fstrm = fix_lines(fstrm, fname2) 44 41 45 % Issue #20: warn users if using this function in HG2 (R2014b+)46 if using_hg247 warning('export_fig:hg2','The fix_lines function should not be used in this Matlab version.');48 end49 50 42 if nargout == 0 || nargin > 1 51 43 if nargin < 2 … … 122 114 end 123 115 116 % Isolate line style definition section 117 first_sec = strfind(fstrm, '% line types:'); 118 [second_sec, remaining] = strtok(fstrm(first_sec+1:end), '/'); 119 [remaining, remaining] = strtok(remaining, '%'); 120 124 121 % Define the new styles, including the new GR format 125 122 % Dot and dash lengths have two parts: a constant amount plus a line width … … 138 135 139 136 % Construct the output 140 % This is the original (memory-intensive) code: 141 %first_sec = strfind(fstrm, '% line types:'); % Isolate line style definition section 142 %[second_sec, remaining] = strtok(fstrm(first_sec+1:end), '/'); 143 %[remaining, remaining] = strtok(remaining, '%'); 144 %fstrm = [fstrm(1:first_sec) second_sec sprintf('%s\r', new_style{:}) remaining]; 145 fstrm = regexprep(fstrm,'(% line types:.+?)/.+?%',['$1',sprintf('%s\r',new_style{:}),'%']); 137 fstrm = [fstrm(1:first_sec) second_sec sprintf('%s\r', new_style{:}) remaining]; 146 138 147 139 % Write the output file -
issm/trunk-jpl/externalpackages/export_fig/ghostscript.m
r19571 r19993 1 function varargout = ghostscript(cmd)2 1 %GHOSTSCRIPT Calls a local GhostScript executable with the input command 3 2 % … … 21 20 % result - Output from ghostscript. 22 21 23 % Copyright: Oliver Woodford, 2009-2015, Yair Altman 2015- 24 %{ 25 % Thanks to Jonas Dorn for the fix for the title of the uigetdir window on Mac OS. 26 % Thanks to Nathan Childress for the fix to default location on 64-bit Windows systems. 27 % 27/04/11 - Find 64-bit Ghostscript on Windows. Thanks to Paul Durack and 28 % Shaun Kline for pointing out the issue 29 % 04/05/11 - Thanks to David Chorlian for pointing out an alternative 30 % location for gs on linux. 22 % Copyright: Oliver Woodford, 2009-2013 23 24 % Thanks to Jonas Dorn for the fix for the title of the uigetdir window on 25 % Mac OS. 26 % Thanks to Nathan Childress for the fix to the default location on 64-bit 27 % Windows systems. 28 % 27/4/11 - Find 64-bit Ghostscript on Windows. Thanks to Paul Durack and 29 % Shaun Kline for pointing out the issue 30 % 4/5/11 - Thanks to David Chorlian for pointing out an alternative 31 % location for gs on linux. 31 32 % 12/12/12 - Add extra executable name on Windows. Thanks to Ratish 32 % Punnoose for highlighting the issue. 33 % 28/06/13 - Fix error using GS 9.07 in Linux. Many thanks to Jannick 34 % Steinbring for proposing the fix. 35 % 24/10/13 - Fix error using GS 9.07 in Linux. Many thanks to Johannes 36 % for the fix. 37 % 23/01/14 - Add full path to ghostscript.txt in warning. Thanks to Koen 38 % Vermeer for raising the issue. 39 % 27/02/15 - If Ghostscript croaks, display suggested workarounds 40 % 30/03/15 - Improved performance by caching status of GS path check, if ok 41 % 14/05/15 - Clarified warning message in case GS path could not be saved 42 % 29/05/15 - Avoid cryptic error in case the ghostscipt path cannot be saved (issue #74) 43 %} 33 % Punnoose for highlighting the issue. 34 % 28/6/13 - Fix error using GS 9.07 in Linux. Many thanks to Jannick 35 % Steinbring for proposing the fix. 36 % 24/10/13 - Fix error using GS 9.07 in Linux. Many thanks to Johannes 37 % for the fix. 38 % 23/01/2014 - Add full path to ghostscript.txt in warning. Thanks to Koen 39 % Vermeer for raising the issue. 44 40 45 try 46 % Call ghostscript 47 [varargout{1:nargout}] = system([gs_command(gs_path()) cmd]); 48 catch err 49 % Display possible workarounds for Ghostscript croaks 50 url1 = 'https://github.com/altmany/export_fig/issues/12#issuecomment-61467998'; % issue #12 51 url2 = 'https://github.com/altmany/export_fig/issues/20#issuecomment-63826270'; % issue #20 52 hg2_str = ''; if using_hg2, hg2_str = ' or Matlab R2014a'; end 53 fprintf(2, 'Ghostscript error. Rolling back to GS 9.10%s may possibly solve this:\n * <a href="%s">%s</a> ',hg2_str,url1,url1); 54 if using_hg2 55 fprintf(2, '(GS 9.10)\n * <a href="%s">%s</a> (R2014a)',url2,url2); 56 end 57 fprintf('\n\n'); 58 if ismac || isunix 59 url3 = 'https://github.com/altmany/export_fig/issues/27'; % issue #27 60 fprintf(2, 'Alternatively, this may possibly be due to a font path issue:\n * <a href="%s">%s</a>\n\n',url3,url3); 61 % issue #20 62 fpath = which(mfilename); 63 if isempty(fpath), fpath = [mfilename('fullpath') '.m']; end 64 fprintf(2, 'Alternatively, if you are using csh, modify shell_cmd from "export..." to "setenv ..."\nat the bottom of <a href="matlab:opentoline(''%s'',174)">%s</a>\n\n',fpath,fpath); 65 end 66 rethrow(err); 67 end 41 function varargout = ghostscript(cmd) 42 % Initialize any required system calls before calling ghostscript 43 shell_cmd = ''; 44 if isunix 45 shell_cmd = 'export LD_LIBRARY_PATH=""; '; % Avoids an error on Linux with GS 9.07 46 end 47 if ismac 48 shell_cmd = 'export DYLD_LIBRARY_PATH=""; '; % Avoids an error on Mac with GS 9.07 49 end 50 % Call ghostscript 51 [varargout{1:nargout}] = system(sprintf('%s"%s" %s', shell_cmd, gs_path, cmd)); 68 52 end 69 53 70 54 function path_ = gs_path 71 % Return a valid path 72 % Start with the currently set path 73 path_ = user_string('ghostscript'); 74 % Check the path works 75 if check_gs_path(path_) 55 % Return a valid path 56 % Start with the currently set path 57 path_ = user_string('ghostscript'); 58 % Check the path works 59 if check_gs_path(path_) 60 return 61 end 62 % Check whether the binary is on the path 63 if ispc 64 bin = {'gswin32c.exe', 'gswin64c.exe', 'gs'}; 65 else 66 bin = {'gs'}; 67 end 68 for a = 1:numel(bin) 69 path_ = bin{a}; 70 if check_store_gs_path(path_) 76 71 return 77 72 end 78 % Check whether the binary is on the path 79 if ispc 80 bin = {'gswin32c.exe', 'gswin64c.exe', 'gs'}; 81 else 82 bin = {'gs'}; 73 end 74 % Search the obvious places 75 if ispc 76 default_location = 'C:\Program Files\gs\'; 77 dir_list = dir(default_location); 78 if isempty(dir_list) 79 default_location = 'C:\Program Files (x86)\gs\'; % Possible location on 64-bit systems 80 dir_list = dir(default_location); 83 81 end 84 for a = 1:numel(bin) 85 path_ = bin{a}; 82 executable = {'\bin\gswin32c.exe', '\bin\gswin64c.exe'}; 83 ver_num = 0; 84 % If there are multiple versions, use the newest 85 for a = 1:numel(dir_list) 86 ver_num2 = sscanf(dir_list(a).name, 'gs%g'); 87 if ~isempty(ver_num2) && ver_num2 > ver_num 88 for b = 1:numel(executable) 89 path2 = [default_location dir_list(a).name executable{b}]; 90 if exist(path2, 'file') == 2 91 path_ = path2; 92 ver_num = ver_num2; 93 end 94 end 95 end 96 end 97 if check_store_gs_path(path_) 98 return 99 end 100 else 101 executable = {'/usr/bin/gs', '/usr/local/bin/gs'}; 102 for a = 1:numel(executable) 103 path_ = executable{a}; 86 104 if check_store_gs_path(path_) 87 105 return 88 106 end 89 107 end 90 % Search the obvious places 91 if ispc 92 default_location = 'C:\Program Files\gs\'; 93 dir_list = dir(default_location); 94 if isempty(dir_list) 95 default_location = 'C:\Program Files (x86)\gs\'; % Possible location on 64-bit systems 96 dir_list = dir(default_location); 97 end 98 executable = {'\bin\gswin32c.exe', '\bin\gswin64c.exe'}; 99 ver_num = 0; 100 % If there are multiple versions, use the newest 101 for a = 1:numel(dir_list) 102 ver_num2 = sscanf(dir_list(a).name, 'gs%g'); 103 if ~isempty(ver_num2) && ver_num2 > ver_num 104 for b = 1:numel(executable) 105 path2 = [default_location dir_list(a).name executable{b}]; 106 if exist(path2, 'file') == 2 107 path_ = path2; 108 ver_num = ver_num2; 109 end 110 end 111 end 112 end 113 if check_store_gs_path(path_) 114 return 115 end 116 else 117 executable = {'/usr/bin/gs', '/usr/local/bin/gs'}; 118 for a = 1:numel(executable) 119 path_ = executable{a}; 120 if check_store_gs_path(path_) 121 return 122 end 123 end 108 end 109 % Ask the user to enter the path 110 while 1 111 if strncmp(computer, 'MAC', 3) % Is a Mac 112 % Give separate warning as the uigetdir dialogue box doesn't have a 113 % title 114 uiwait(warndlg('Ghostscript not found. Please locate the program.')) 124 115 end 125 % Ask the user to enter the path 126 while true 127 if strncmp(computer, 'MAC', 3) % Is a Mac 128 % Give separate warning as the uigetdir dialogue box doesn't have a 129 % title 130 uiwait(warndlg('Ghostscript not found. Please locate the program.')) 131 end 132 base = uigetdir('/', 'Ghostcript not found. Please locate the program.'); 133 if isequal(base, 0) 134 % User hit cancel or closed window 135 break; 136 end 137 base = [base filesep]; %#ok<AGROW> 138 bin_dir = {'', ['bin' filesep], ['lib' filesep]}; 139 for a = 1:numel(bin_dir) 140 for b = 1:numel(bin) 141 path_ = [base bin_dir{a} bin{b}]; 142 if exist(path_, 'file') == 2 143 if check_store_gs_path(path_) 144 return 145 end 116 base = uigetdir('/', 'Ghostcript not found. Please locate the program.'); 117 if isequal(base, 0) 118 % User hit cancel or closed window 119 break; 120 end 121 base = [base filesep]; 122 bin_dir = {'', ['bin' filesep], ['lib' filesep]}; 123 for a = 1:numel(bin_dir) 124 for b = 1:numel(bin) 125 path_ = [base bin_dir{a} bin{b}]; 126 if exist(path_, 'file') == 2 127 if check_store_gs_path(path_) 128 return 146 129 end 147 130 end 148 131 end 149 132 end 150 error('Ghostscript not found. Have you installed it from www.ghostscript.com?'); 133 end 134 error('Ghostscript not found. Have you installed it from www.ghostscript.com?'); 151 135 end 152 136 153 137 function good = check_store_gs_path(path_) 154 % Check the path is valid 155 good = check_gs_path(path_); 156 if ~good 157 return 158 end 159 % Update the current default path to the path found 160 if ~user_string('ghostscript', path_) 161 filename = fullfile(fileparts(which('user_string.m')), '.ignore', 'ghostscript.txt'); 162 warning('Path to ghostscript installation could not be saved in %s (perhaps a permissions issue). You can manually create this file and set its contents to %s, to improve performance in future invocations (this warning is safe to ignore).', filename, path_); 163 return 164 end 138 % Check the path is valid 139 good = check_gs_path(path_); 140 if ~good 141 return 142 end 143 % Update the current default path to the path found 144 if ~user_string('ghostscript', path_) 145 warning('Path to ghostscript installation could not be saved. Enter it manually in %s.', fullfile(fileparts(which('user_string.m')), '.ignore', 'ghostscript.txt')); 146 return 147 end 165 148 end 166 149 167 150 function good = check_gs_path(path_) 168 persistent isOk 169 if isempty(path_) 170 isOk = false; 171 elseif ~isequal(isOk,true) 172 % Check whether the path is valid 173 [status, message] = system([gs_command(path_) '-h']); %#ok<ASGLU> 174 isOk = status == 0; 175 end 176 good = isOk; 151 % Check the path is valid 152 shell_cmd = ''; 153 if ismac 154 shell_cmd = 'export DYLD_LIBRARY_PATH=""; '; % Avoids an error on Mac with GS 9.07 177 155 end 178 179 function cmd = gs_command(path_) 180 % Initialize any required system calls before calling ghostscript 181 % TODO: in Unix/Mac, find a way to determine whether to use "export" (bash) or "setenv" (csh/tcsh) 182 shell_cmd = ''; 183 if isunix 184 shell_cmd = 'export LD_LIBRARY_PATH=""; '; % Avoids an error on Linux with GS 9.07 185 end 186 if ismac 187 shell_cmd = 'export DYLD_LIBRARY_PATH=""; '; % Avoids an error on Mac with GS 9.07 188 end 189 % Construct the command string 190 cmd = sprintf('%s"%s" ', shell_cmd, path_); 156 [good, message] = system(sprintf('%s"%s" -h', shell_cmd, path_)); 157 good = good == 0; 191 158 end -
issm/trunk-jpl/externalpackages/export_fig/isolate_axes.m
r19571 r19993 1 function fh = isolate_axes(ah, vis)2 1 %ISOLATE_AXES Isolate the specified axes in a figure on their own 3 2 % … … 23 22 24 23 % Thank you to Rosella Blatt for reporting a bug to do with axes in GUIs 25 % 16/03/12: Moved copyfig to its own function. Thanks to Bob Fratantonio 26 % for pointing out that the function is also used in export_fig.m 27 % 12/12/12: Add support for isolating uipanels. Thanks to michael for suggesting it 28 % 08/10/13: Bug fix to allchildren suggested by Will Grant (many thanks!) 29 % 05/12/13: Bug fix to axes having different units. Thanks to Remington Reid for reporting 30 % 21/04/15: Bug fix for exporting uipanels with legend/colorbar on HG1 (reported by Alvaro 31 % on FEX page as a comment on 24-Apr-2014); standardized indentation & help section 32 % 22/04/15: Bug fix: legends and colorbars were not exported when exporting axes handle in HG2 24 % 16/3/2012 Moved copyfig to its own function. Thanks to Bob Fratantonio 25 % for pointing out that the function is also used in export_fig.m. 26 % 12/12/12 - Add support for isolating uipanels. Thanks to michael for 27 % suggesting it. 28 % 08/10/13 - Bug fix to allchildren suggested by Will Grant (many thanks!). 29 % 05/12/13 - Bug fix to axes having different units. Thanks to Remington 30 % Reid for reporting the issue. 33 31 34 % Make sure we have an array of handles 35 if ~all(ishandle(ah)) 36 error('ah must be an array of handles'); 32 function fh = isolate_axes(ah, vis) 33 % Make sure we have an array of handles 34 if ~all(ishandle(ah)) 35 error('ah must be an array of handles'); 36 end 37 % Check that the handles are all for axes or uipanels, and are all in the same figure 38 fh = ancestor(ah(1), 'figure'); 39 nAx = numel(ah); 40 for a = 1:nAx 41 if ~ismember(get(ah(a), 'Type'), {'axes', 'uipanel'}) 42 error('All handles must be axes or uipanel handles.'); 37 43 end 38 % Check that the handles are all for axes or uipanels, and are all in the same figure 39 fh = ancestor(ah(1), 'figure'); 40 nAx = numel(ah); 41 for a = 1:nAx 42 if ~ismember(get(ah(a), 'Type'), {'axes', 'uipanel'}) 43 error('All handles must be axes or uipanel handles.'); 44 end 45 if ~isequal(ancestor(ah(a), 'figure'), fh) 46 error('Axes must all come from the same figure.'); 47 end 44 if ~isequal(ancestor(ah(a), 'figure'), fh) 45 error('Axes must all come from the same figure.'); 48 46 end 49 % Tag the objects so we can find them in the copy 50 old_tag = get(ah, 'Tag'); 51 if nAx == 1 52 old_tag = {old_tag}; 47 end 48 % Tag the objects so we can find them in the copy 49 old_tag = get(ah, 'Tag'); 50 if nAx == 1 51 old_tag = {old_tag}; 52 end 53 set(ah, 'Tag', 'ObjectToCopy'); 54 % Create a new figure exactly the same as the old one 55 fh = copyfig(fh); %copyobj(fh, 0); 56 if nargin < 2 || ~vis 57 set(fh, 'Visible', 'off'); 58 end 59 % Reset the object tags 60 for a = 1:nAx 61 set(ah(a), 'Tag', old_tag{a}); 62 end 63 % Find the objects to save 64 ah = findall(fh, 'Tag', 'ObjectToCopy'); 65 if numel(ah) ~= nAx 66 close(fh); 67 error('Incorrect number of objects found.'); 68 end 69 % Set the axes tags to what they should be 70 for a = 1:nAx 71 set(ah(a), 'Tag', old_tag{a}); 72 end 73 % Keep any legends and colorbars which overlap the subplots 74 lh = findall(fh, 'Type', 'axes', '-and', {'Tag', 'legend', '-or', 'Tag', 'Colorbar'}); 75 nLeg = numel(lh); 76 if nLeg > 0 77 set([ah(:); lh(:)], 'Units', 'normalized'); 78 ax_pos = get(ah, 'OuterPosition'); 79 if nAx > 1 80 ax_pos = cell2mat(ax_pos(:)); 53 81 end 54 set(ah, 'Tag', 'ObjectToCopy'); 55 % Create a new figure exactly the same as the old one 56 fh = copyfig(fh); %copyobj(fh, 0); 57 if nargin < 2 || ~vis 58 set(fh, 'Visible', 'off'); 82 ax_pos(:,3:4) = ax_pos(:,3:4) + ax_pos(:,1:2); 83 leg_pos = get(lh, 'OuterPosition'); 84 if nLeg > 1; 85 leg_pos = cell2mat(leg_pos); 59 86 end 60 % Reset the object tags 61 for a = 1:nAx 62 set(ah(a), 'Tag', old_tag{a}); 63 end 64 % Find the objects to save 65 ah = findall(fh, 'Tag', 'ObjectToCopy'); 66 if numel(ah) ~= nAx 67 close(fh); 68 error('Incorrect number of objects found.'); 69 end 70 % Set the axes tags to what they should be 71 for a = 1:nAx 72 set(ah(a), 'Tag', old_tag{a}); 73 end 74 % Keep any legends and colorbars which overlap the subplots 75 % Note: in HG1 these are axes objects; in HG2 they are separate objects, therefore we 76 % don't test for the type, only the tag (hopefully nobody but Matlab uses them!) 77 lh = findall(fh, 'Tag', 'legend', '-or', 'Tag', 'Colorbar'); 78 nLeg = numel(lh); 79 if nLeg > 0 80 set([ah(:); lh(:)], 'Units', 'normalized'); 81 try 82 ax_pos = get(ah, 'OuterPosition'); % axes and figures have the OuterPosition property 83 catch 84 ax_pos = get(ah, 'Position'); % uipanels only have Position, not OuterPosition 85 end 86 if nAx > 1 87 ax_pos = cell2mat(ax_pos(:)); 88 end 89 ax_pos(:,3:4) = ax_pos(:,3:4) + ax_pos(:,1:2); 90 try 91 leg_pos = get(lh, 'OuterPosition'); 92 catch 93 leg_pos = get(lh, 'Position'); % No OuterPosition in HG2, only in HG1 94 end 95 if nLeg > 1; 96 leg_pos = cell2mat(leg_pos); 97 end 98 leg_pos(:,3:4) = leg_pos(:,3:4) + leg_pos(:,1:2); 99 ax_pos = shiftdim(ax_pos, -1); 100 % Overlap test 101 M = bsxfun(@lt, leg_pos(:,1), ax_pos(:,:,3)) & ... 102 bsxfun(@lt, leg_pos(:,2), ax_pos(:,:,4)) & ... 103 bsxfun(@gt, leg_pos(:,3), ax_pos(:,:,1)) & ... 104 bsxfun(@gt, leg_pos(:,4), ax_pos(:,:,2)); 105 ah = [ah; lh(any(M, 2))]; 106 end 107 % Get all the objects in the figure 108 axs = findall(fh); 109 % Delete everything except for the input objects and associated items 110 delete(axs(~ismember(axs, [ah; allchildren(ah); allancestors(ah)]))); 87 leg_pos(:,3:4) = leg_pos(:,3:4) + leg_pos(:,1:2); 88 ax_pos = shiftdim(ax_pos, -1); 89 % Overlap test 90 M = bsxfun(@lt, leg_pos(:,1), ax_pos(:,:,3)) & ... 91 bsxfun(@lt, leg_pos(:,2), ax_pos(:,:,4)) & ... 92 bsxfun(@gt, leg_pos(:,3), ax_pos(:,:,1)) & ... 93 bsxfun(@gt, leg_pos(:,4), ax_pos(:,:,2)); 94 ah = [ah; lh(any(M, 2))]; 95 end 96 % Get all the objects in the figure 97 axs = findall(fh); 98 % Delete everything except for the input objects and associated items 99 delete(axs(~ismember(axs, [ah; allchildren(ah); allancestors(ah)]))); 111 100 end 112 101 113 102 function ah = allchildren(ah) 114 115 116 117 118 103 ah = findall(ah); 104 if iscell(ah) 105 ah = cell2mat(ah); 106 end 107 ah = ah(:); 119 108 end 120 109 121 110 function ph = allancestors(ah) 122 ph = []; 123 for a = 1:numel(ah) 124 h = get(ah(a), 'parent'); 125 while h ~= 0 126 ph = [ph; h]; 127 h = get(h, 'parent'); 128 end 111 ph = []; 112 for a = 1:numel(ah) 113 h = get(ah(a), 'parent'); 114 while h ~= 0 115 ph = [ph; h]; 116 h = get(h, 'parent'); 129 117 end 130 118 end 119 end -
issm/trunk-jpl/externalpackages/export_fig/pdftops.m
r19571 r19993 29 29 % under linux. 30 30 % 23/01/2014 - Add full path to pdftops.txt in warning. 31 % 27/05/2015 - Fixed alert in case of missing pdftops; fixed code indentation32 31 33 34 32 % Call pdftops 33 [varargout{1:nargout}] = system(sprintf('"%s" %s', xpdf_path, cmd)); 35 34 end 36 35 37 36 function path_ = xpdf_path 38 % Return a valid path 39 % Start with the currently set path 40 path_ = user_string('pdftops'); 41 % Check the path works 42 if check_xpdf_path(path_) 43 return 37 % Return a valid path 38 % Start with the currently set path 39 path_ = user_string('pdftops'); 40 % Check the path works 41 if check_xpdf_path(path_) 42 return 43 end 44 % Check whether the binary is on the path 45 if ispc 46 bin = 'pdftops.exe'; 47 else 48 bin = 'pdftops'; 49 end 50 if check_store_xpdf_path(bin) 51 path_ = bin; 52 return 53 end 54 % Search the obvious places 55 if ispc 56 path_ = 'C:\Program Files\xpdf\pdftops.exe'; 57 else 58 path_ = '/usr/local/bin/pdftops'; 59 end 60 if check_store_xpdf_path(path_) 61 return 62 end 63 % Ask the user to enter the path 64 while 1 65 if strncmp(computer,'MAC',3) % Is a Mac 66 % Give separate warning as the uigetdir dialogue box doesn't have a 67 % title 68 uiwait(warndlg('Pdftops not found. Please locate the program, or install xpdf-tools from http://users.phg-online.de/tk/MOSXS/.')) 44 69 end 45 % Check whether the binary is on the path 46 if ispc 47 bin = 'pdftops.exe'; 48 else 49 bin = 'pdftops'; 70 base = uigetdir('/', 'Pdftops not found. Please locate the program.'); 71 if isequal(base, 0) 72 % User hit cancel or closed window 73 break; 50 74 end 51 if check_store_xpdf_path(bin) 52 path_ = bin; 53 return 54 end 55 % Search the obvious places 56 if ispc 57 path_ = 'C:\Program Files\xpdf\pdftops.exe'; 58 else 59 path_ = '/usr/local/bin/pdftops'; 75 base = [base filesep]; 76 bin_dir = {'', ['bin' filesep], ['lib' filesep]}; 77 for a = 1:numel(bin_dir) 78 path_ = [base bin_dir{a} bin]; 79 if exist(path_, 'file') == 2 80 break; 81 end 60 82 end 61 83 if check_store_xpdf_path(path_) 62 84 return 63 85 end 64 % Ask the user to enter the path 65 while 1 66 errMsg = 'Pdftops not found. Please locate the program, or install xpdf-tools from '; 67 url = 'http://foolabs.com/xpdf'; 68 fprintf(2, '%s\n', [errMsg '<a href="matlab:web(''-browser'',''' url ''');">' url '</a>']); 69 errMsg = [errMsg url]; %#ok<AGROW> 70 if strncmp(computer,'MAC',3) % Is a Mac 71 % Give separate warning as the MacOS uigetdir dialogue box doesn't have a title 72 uiwait(warndlg(errMsg)) 73 end 74 base = uigetdir('/', errMsg); 75 if isequal(base, 0) 76 % User hit cancel or closed window 77 break; 78 end 79 base = [base filesep]; %#ok<AGROW> 80 bin_dir = {'', ['bin' filesep], ['lib' filesep]}; 81 for a = 1:numel(bin_dir) 82 path_ = [base bin_dir{a} bin]; 83 if exist(path_, 'file') == 2 84 break; 85 end 86 end 87 if check_store_xpdf_path(path_) 88 return 89 end 90 end 91 error('pdftops executable not found.'); 86 end 87 error('pdftops executable not found.'); 92 88 end 93 89 94 90 function good = check_store_xpdf_path(path_) 95 96 97 98 99 100 101 102 103 104 91 % Check the path is valid 92 good = check_xpdf_path(path_); 93 if ~good 94 return 95 end 96 % Update the current default path to the path found 97 if ~user_string('pdftops', path_) 98 warning('Path to pdftops executable could not be saved. Enter it manually in %s.', fullfile(fileparts(which('user_string.m')), '.ignore', 'pdftops.txt')); 99 return 100 end 105 101 end 106 102 107 103 function good = check_xpdf_path(path_) 108 109 [good, message] = system(sprintf('"%s" -h', path_)); %#ok<ASGLU> 110 111 112 104 % Check the path is valid 105 [good, message] = system(sprintf('"%s" -h', path_)); 106 % system returns good = 1 even when the command runs 107 % Look for something distinct in the help text 108 good = ~isempty(strfind(message, 'PostScript')); 113 109 end -
issm/trunk-jpl/externalpackages/export_fig/print2array.m
r19571 r19993 1 function [A, bcol] = print2array(fig, res, renderer, gs_options)2 1 %PRINT2ARRAY Exports a figure to an image array 3 2 % … … 7 6 % A = print2array(figure_handle, resolution) 8 7 % A = print2array(figure_handle, resolution, renderer) 9 % A = print2array(figure_handle, resolution, renderer, gs_options)10 8 % [A bcol] = print2array(...) 11 9 % … … 22 20 % renderer - string containing the renderer paramater to be passed to 23 21 % print. Default: '-opengl'. 24 % gs_options - optional ghostscript options (e.g.: '-dNoOutputFonts'). If25 % multiple options are needed, enclose in call array: {'-a','-b'}26 22 % 27 23 % OUT: … … 29 25 % bcol - 1x3 uint8 vector of the background color 30 26 31 % Copyright (C) Oliver Woodford 2008-201 4, Yair Altman 2015-32 %{ 27 % Copyright (C) Oliver Woodford 2008-2012 28 33 29 % 05/09/11: Set EraseModes to normal when using opengl or zbuffer 34 % renderers. Thanks to Pawel Kocieniewski for reporting the issue. 35 % 21/09/11: Bug fix: unit8 -> uint8! Thanks to Tobias Lamour for reporting it. 36 % 14/11/11: Bug fix: stop using hardcopy(), as it interfered with figure size 37 % and erasemode settings. Makes it a bit slower, but more reliable. 38 % Thanks to Phil Trinh and Meelis Lootus for reporting the issues. 30 % renderers. Thanks to Pawel Kocieniewski for reporting the 31 % issue. 32 % 21/09/11: Bug fix: unit8 -> uint8! Thanks to Tobias Lamour for reporting 33 % the issue. 34 % 14/11/11: Bug fix: stop using hardcopy(), as it interfered with figure 35 % size and erasemode settings. Makes it a bit slower, but more 36 % reliable. Thanks to Phil Trinh and Meelis Lootus for reporting 37 % the issues. 39 38 % 09/12/11: Pass font path to ghostscript. 40 39 % 27/01/12: Bug fix affecting painters rendering tall figures. Thanks to 41 40 % Ken Campbell for reporting it. 42 % 03/04/12: Bug fix to median input. Thanks to Andy Matthews for reporting it. 41 % 03/04/12: Bug fix to median input. Thanks to Andy Matthews for reporting 42 % it. 43 43 % 26/10/12: Set PaperOrientation to portrait. Thanks to Michael Watts for 44 44 % reporting the issue. 45 % 26/02/15: If temp dir is not writable, use the current folder for temp46 % EPS/TIF files (Javier Paredes)47 % 27/02/15: Display suggested workarounds to internal print() error (issue #16)48 % 28/02/15: Enable users to specify optional ghostscript options (issue #36)49 % 10/03/15: Fixed minor warning reported by Paul Soderlind; fixed code indentation50 % 28/05/15: Fixed issue #69: patches with LineWidth==0.75 appear wide (internal bug in Matlab's print() func)51 % 07/07/15: Fixed issue #83: use numeric handles in HG152 %}53 45 54 % Generate default input arguments, if needed 55 if nargin < 2 56 res = 1; 57 if nargin < 1 58 fig = gcf; 46 function [A, bcol] = print2array(fig, res, renderer) 47 % Generate default input arguments, if needed 48 if nargin < 2 49 res = 1; 50 if nargin < 1 51 fig = gcf; 52 end 53 end 54 % Warn if output is large 55 old_mode = get(fig, 'Units'); 56 set(fig, 'Units', 'pixels'); 57 px = get(fig, 'Position'); 58 set(fig, 'Units', old_mode); 59 npx = prod(px(3:4)*res)/1e6; 60 if npx > 30 61 % 30M pixels or larger! 62 warning('MATLAB:LargeImage', 'print2array generating a %.1fM pixel image. This could be slow and might also cause memory problems.', npx); 63 end 64 % Retrieve the background colour 65 bcol = get(fig, 'Color'); 66 % Set the resolution parameter 67 res_str = ['-r' num2str(ceil(get(0, 'ScreenPixelsPerInch')*res))]; 68 % Generate temporary file name 69 tmp_nam = [tempname '.tif']; 70 if nargin > 2 && strcmp(renderer, '-painters') 71 % Print to eps file 72 tmp_eps = [tempname '.eps']; 73 print2eps(tmp_eps, fig, 0, renderer, '-loose'); 74 try 75 % Initialize the command to export to tiff using ghostscript 76 cmd_str = ['-dEPSCrop -q -dNOPAUSE -dBATCH ' res_str ' -sDEVICE=tiff24nc']; 77 % Set the font path 78 fp = font_path(); 79 if ~isempty(fp) 80 cmd_str = [cmd_str ' -sFONTPATH="' fp '"']; 81 end 82 % Add the filenames 83 cmd_str = [cmd_str ' -sOutputFile="' tmp_nam '" "' tmp_eps '"']; 84 % Execute the ghostscript command 85 ghostscript(cmd_str); 86 catch me 87 % Delete the intermediate file 88 delete(tmp_eps); 89 rethrow(me); 90 end 91 % Delete the intermediate file 92 delete(tmp_eps); 93 % Read in the generated bitmap 94 A = imread(tmp_nam); 95 % Delete the temporary bitmap file 96 delete(tmp_nam); 97 % Set border pixels to the correct colour 98 if isequal(bcol, 'none') 99 bcol = []; 100 elseif isequal(bcol, [1 1 1]) 101 bcol = uint8([255 255 255]); 102 else 103 for l = 1:size(A, 2) 104 if ~all(reshape(A(:,l,:) == 255, [], 1)) 105 break; 106 end 107 end 108 for r = size(A, 2):-1:l 109 if ~all(reshape(A(:,r,:) == 255, [], 1)) 110 break; 111 end 112 end 113 for t = 1:size(A, 1) 114 if ~all(reshape(A(t,:,:) == 255, [], 1)) 115 break; 116 end 117 end 118 for b = size(A, 1):-1:t 119 if ~all(reshape(A(b,:,:) == 255, [], 1)) 120 break; 121 end 122 end 123 bcol = uint8(median(single([reshape(A(:,[l r],:), [], size(A, 3)); reshape(A([t b],:,:), [], size(A, 3))]), 1)); 124 for c = 1:size(A, 3) 125 A(:,[1:l-1, r+1:end],c) = bcol(c); 126 A([1:t-1, b+1:end],:,c) = bcol(c); 59 127 end 60 128 end 61 % Warn if output is large 62 old_mode = get(fig, 'Units'); 63 set(fig, 'Units', 'pixels'); 64 px = get(fig, 'Position'); 65 set(fig, 'Units', old_mode); 66 npx = prod(px(3:4)*res)/1e6; 67 if npx > 30 68 % 30M pixels or larger! 69 warning('MATLAB:LargeImage', 'print2array generating a %.1fM pixel image. This could be slow and might also cause memory problems.', npx); 129 else 130 if nargin < 3 131 renderer = '-opengl'; 70 132 end 71 % Retrieve the background colour 72 bcol = get(fig, 'Color'); 73 % Set the resolution parameter 74 res_str = ['-r' num2str(ceil(get(0, 'ScreenPixelsPerInch')*res))]; 75 % Generate temporary file name 76 tmp_nam = [tempname '.tif']; 133 err = false; 134 % Set paper size 135 old_pos_mode = get(fig, 'PaperPositionMode'); 136 old_orientation = get(fig, 'PaperOrientation'); 137 set(fig, 'PaperPositionMode', 'auto', 'PaperOrientation', 'portrait'); 77 138 try 78 % Ensure that the temp dir is writable (Javier Paredes 26/2/15) 79 fid = fopen(tmp_nam,'w'); 80 fwrite(fid,1); 81 fclose(fid); 82 delete(tmp_nam); % cleanup 83 isTempDirOk = true; 84 catch 85 % Temp dir is not writable, so use the current folder 86 [dummy,fname,fext] = fileparts(tmp_nam); %#ok<ASGLU> 87 fpath = pwd; 88 tmp_nam = fullfile(fpath,[fname fext]); 89 isTempDirOk = false; 139 % Print to tiff file 140 print(fig, renderer, res_str, '-dtiff', tmp_nam); 141 % Read in the printed file 142 A = imread(tmp_nam); 143 % Delete the temporary file 144 delete(tmp_nam); 145 catch ex 146 err = true; 90 147 end 91 % Enable users to specify optional ghostscript options (issue #36) 92 if nargin > 3 && ~isempty(gs_options) 93 if iscell(gs_options) 94 gs_options = sprintf(' %s',gs_options{:}); 95 elseif ~ischar(gs_options) 96 error('gs_options input argument must be a string or cell-array of strings'); 148 % Reset paper size 149 set(fig, 'PaperPositionMode', old_pos_mode, 'PaperOrientation', old_orientation); 150 % Throw any error that occurred 151 if err 152 rethrow(ex); 153 end 154 % Set the background color 155 if isequal(bcol, 'none') 156 bcol = []; 157 else 158 bcol = bcol * 255; 159 if isequal(bcol, round(bcol)) 160 bcol = uint8(bcol); 97 161 else 98 gs_options = [' ' gs_options]; 99 end 100 else 101 gs_options = ''; 102 end 103 if nargin > 2 && strcmp(renderer, '-painters') 104 % Print to eps file 105 if isTempDirOk 106 tmp_eps = [tempname '.eps']; 107 else 108 tmp_eps = fullfile(fpath,[fname '.eps']); 109 end 110 print2eps(tmp_eps, fig, 0, renderer, '-loose'); 111 try 112 % Initialize the command to export to tiff using ghostscript 113 cmd_str = ['-dEPSCrop -q -dNOPAUSE -dBATCH ' res_str ' -sDEVICE=tiff24nc']; 114 % Set the font path 115 fp = font_path(); 116 if ~isempty(fp) 117 cmd_str = [cmd_str ' -sFONTPATH="' fp '"']; 118 end 119 % Add the filenames 120 cmd_str = [cmd_str ' -sOutputFile="' tmp_nam '" "' tmp_eps '"' gs_options]; 121 % Execute the ghostscript command 122 ghostscript(cmd_str); 123 catch me 124 % Delete the intermediate file 125 delete(tmp_eps); 126 rethrow(me); 127 end 128 % Delete the intermediate file 129 delete(tmp_eps); 130 % Read in the generated bitmap 131 A = imread(tmp_nam); 132 % Delete the temporary bitmap file 133 delete(tmp_nam); 134 % Set border pixels to the correct colour 135 if isequal(bcol, 'none') 136 bcol = []; 137 elseif isequal(bcol, [1 1 1]) 138 bcol = uint8([255 255 255]); 139 else 140 for l = 1:size(A, 2) 141 if ~all(reshape(A(:,l,:) == 255, [], 1)) 142 break; 143 end 144 end 145 for r = size(A, 2):-1:l 146 if ~all(reshape(A(:,r,:) == 255, [], 1)) 147 break; 148 end 149 end 150 for t = 1:size(A, 1) 151 if ~all(reshape(A(t,:,:) == 255, [], 1)) 152 break; 153 end 154 end 155 for b = size(A, 1):-1:t 156 if ~all(reshape(A(b,:,:) == 255, [], 1)) 157 break; 158 end 159 end 160 bcol = uint8(median(single([reshape(A(:,[l r],:), [], size(A, 3)); reshape(A([t b],:,:), [], size(A, 3))]), 1)); 161 for c = 1:size(A, 3) 162 A(:,[1:l-1, r+1:end],c) = bcol(c); 163 A([1:t-1, b+1:end],:,c) = bcol(c); 164 end 165 end 166 else 167 if nargin < 3 168 renderer = '-opengl'; 169 end 170 err = false; 171 % Set paper size 172 old_pos_mode = get(fig, 'PaperPositionMode'); 173 old_orientation = get(fig, 'PaperOrientation'); 174 set(fig, 'PaperPositionMode', 'auto', 'PaperOrientation', 'portrait'); 175 try 176 % Workaround for issue #69: patches with LineWidth==0.75 appear wide (internal bug in Matlab's print() function) 177 fp = []; % in case we get an error below 178 fp = findall(fig, 'Type','patch', 'LineWidth',0.75); 179 set(fp, 'LineWidth',0.5); 180 % Fix issue #83: use numeric handles in HG1 181 if ~using_hg2(fig), fig = double(fig); end 182 % Print to tiff file 183 print(fig, renderer, res_str, '-dtiff', tmp_nam); 184 % Read in the printed file 185 A = imread(tmp_nam); 186 % Delete the temporary file 187 delete(tmp_nam); 188 catch ex 189 err = true; 190 end 191 set(fp, 'LineWidth',0.75); % restore original figure appearance 192 % Reset paper size 193 set(fig, 'PaperPositionMode', old_pos_mode, 'PaperOrientation', old_orientation); 194 % Throw any error that occurred 195 if err 196 % Display suggested workarounds to internal print() error (issue #16) 197 fprintf(2, 'An error occured with Matlab''s builtin print function.\nTry setting the figure Renderer to ''painters'' or use opengl(''software'').\n\n'); 198 rethrow(ex); 199 end 200 % Set the background color 201 if isequal(bcol, 'none') 202 bcol = []; 203 else 204 bcol = bcol * 255; 205 if isequal(bcol, round(bcol)) 206 bcol = uint8(bcol); 207 else 208 bcol = squeeze(A(1,1,:)); 209 end 162 bcol = squeeze(A(1,1,:)); 210 163 end 211 164 end 212 % Check the output size is correct 213 if isequal(res, round(res)) 214 px = round([px([4 3])*res 3]); % round() to avoid an indexing warning below 215 if ~isequal(size(A), px)216 % Correct the output size217 A = A(1:min(end,px(1)),1:min(end,px(2)),:);218 end165 end 166 % Check the output size is correct 167 if isequal(res, round(res)) 168 px = [px([4 3])*res 3]; 169 if ~isequal(size(A), px) 170 % Correct the output size 171 A = A(1:min(end,px(1)),1:min(end,px(2)),:); 219 172 end 173 end 220 174 end 221 175 222 176 % Function to return (and create, where necessary) the font path 223 177 function fp = font_path() 224 fp = user_string('gs_font_path'); 178 fp = user_string('gs_font_path'); 179 if ~isempty(fp) 180 return 181 end 182 % Create the path 183 % Start with the default path 184 fp = getenv('GS_FONTPATH'); 185 % Add on the typical directories for a given OS 186 if ispc 225 187 if ~isempty(fp) 226 return188 fp = [fp ';']; 227 189 end 228 % Create the path 229 % Start with the default path 230 fp = getenv('GS_FONTPATH'); 231 % Add on the typical directories for a given OS 232 if ispc 233 if ~isempty(fp) 234 fp = [fp ';']; 235 end 236 fp = [fp getenv('WINDIR') filesep 'Fonts']; 237 else 238 if ~isempty(fp) 239 fp = [fp ':']; 240 end 241 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']; 190 fp = [fp getenv('WINDIR') filesep 'Fonts']; 191 else 192 if ~isempty(fp) 193 fp = [fp ':']; 242 194 end 243 user_string('gs_font_path', fp);195 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']; 244 196 end 197 user_string('gs_font_path', fp); 198 end -
issm/trunk-jpl/externalpackages/export_fig/print2eps.m
r19571 r19993 1 function print2eps(name, fig, export_options, varargin)2 1 %PRINT2EPS Prints figures to eps with improved line styles 3 2 % … … 5 4 % print2eps filename 6 5 % print2eps(filename, fig_handle) 7 % print2eps(filename, fig_handle, export_options)8 % print2eps(filename, fig_handle, export_options, print_options)6 % print2eps(filename, fig_handle, bb_padding) 7 % print2eps(filename, fig_handle, bb_padding, options) 9 8 % 10 9 % This function saves a figure as an eps file, with two improvements over 11 10 % MATLAB's print command. First, it improves the line style, making dashed 12 % lines more like those on screen and giving grid lines a dotted line style. 13 % Secondly, it substitutes original font names back into the eps file, 14 % where these have been changed by MATLAB, for up to 11 different fonts. 11 % lines more like those on screen and giving grid lines their own dotted 12 % style. Secondly, it substitutes original font names back into the eps 13 % file, where these have been changed by MATLAB, for up to 11 different 14 % fonts. 15 15 % 16 16 %IN: … … 20 20 % not specified, the figure is saved in the current directory. 21 21 % fig_handle - The handle of the figure to be saved. Default: gcf(). 22 % export_options - array of optional scalar values: 23 % bb_padding - Scalar value of amount of padding to add to border around 24 % the cropped image, in points (if >1) or percent (if <1). 25 % Can be negative as well as positive; Default: 0 26 % crop - Crop amount. Deafult: 0 27 % fontswap - Whether to swap non-default fonts in figure. Default: true 28 % print_options - Additional parameter strings to be passed to the print command 29 30 %{ 31 % Copyright (C) Oliver Woodford 2008-2014, Yair Altman 2015- 22 % bb_padding - Scalar value of amount of padding to add to border around 23 % the figure, in points. Can be negative as well as 24 % positive. Default: 0. 25 % options - Additional parameter strings to be passed to print. 26 27 % Copyright (C) Oliver Woodford 2008-2014 32 28 33 29 % The idea of editing the EPS file to change line styles comes from Jiro … … 35 31 % The idea of changing dash length with line width came from comments on 36 32 % fex id: 5743, but the implementation is mine :) 37 %} 38 %{ 39 % 14/11/11: Fix a MATLAB bug rendering black or white text incorrectly. 40 % Thanks to Mathieu Morlighem for reporting the issue and 41 % obtaining a fix from TMW. 33 34 % 14/11/2011: Fix a MATLAB bug rendering black or white text incorrectly. 35 % Thanks to Mathieu Morlighem for reporting the issue and 36 % obtaining a fix from TMW. 42 37 % 08/12/11: Added ability to correct fonts. Several people have requested 43 38 % this at one time or another, and also pointed me to printeps … … 63 58 % 13/08/13: Fix MATLAB feature of not exporting white lines correctly. 64 59 % Thanks to Sebastian Heßlinger for reporting it. 65 % 24/02/15: Fix for Matlab R2014b bug (issue #31): LineWidths<0.75 are not 66 % set in the EPS (default line width is used) 67 % 25/02/15: Fixed issue #32: BoundingBox problem caused uncropped EPS/PDF files 68 % 05/03/15: Fixed issue #43: Inability to perform EPS file post-processing 69 % 06/03/15: Improved image padding & cropping thanks to Oscar Hartogensis 70 % 21/03/15: Fixed edge-case of missing handles having a 'FontName' property 71 % 26/03/15: Attempt to fix issue #45: white lines in subplots do not print correctly 72 % 27/03/15: Attempt to fix issue #44: white artifact lines appearing in patch exports 73 % 30/03/15: Fixed issue #52: improved performance on HG2 (R2014b+) 74 % 09/04/15: Comment blocks consolidation and minor code cleanup (no real code change) 75 % 12/04/15: Fixed issue #56: bad cropping 76 % 14/04/15: Workaround for issue #45: lines in image subplots are exported in invalid color 77 % 07/07/15: Added option to avoid font-swapping in EPS/PDF 78 % 07/07/15: Fixed issue #83: use numeric handles in HG1 79 % 22/07/15: Fixed issue #91 (thanks to Carlos Moffat) 80 %} 81 82 options = {'-loose'}; 83 if nargin > 3 84 options = [options varargin]; 85 elseif nargin < 3 86 export_options = 0; 87 if nargin < 2 88 fig = gcf(); 89 end 90 end 91 92 % Retrieve padding, crop & font-swap values 93 if numel(export_options) > 2 % font-swapping 94 fontswap = export_options(3); 95 else 96 fontswap = true; 97 end 98 if numel(export_options) > 1 % cropping 99 bb_crop = export_options(2); 100 else 101 bb_crop = 0; % scalar value, so use default bb_crop value of 0 102 end 103 if numel(export_options) > 0 % padding 104 bb_padding = export_options(1); 105 else 106 bb_padding = 0; 107 end 108 109 % Construct the filename 110 if numel(name) < 5 || ~strcmpi(name(end-3:end), '.eps') 111 name = [name '.eps']; % Add the missing extension 112 end 113 114 % Set paper size 115 old_pos_mode = get(fig, 'PaperPositionMode'); 116 old_orientation = get(fig, 'PaperOrientation'); 117 set(fig, 'PaperPositionMode', 'auto', 'PaperOrientation', 'portrait'); 118 119 % Find all the used fonts in the figure 120 font_handles = findall(fig, '-property', 'FontName'); 121 fonts = get(font_handles, 'FontName'); 122 if isempty(fonts) 123 fonts = {}; 124 elseif ~iscell(fonts) 125 fonts = {fonts}; 126 end 127 128 % Map supported font aliases onto the correct name 129 fontsl = lower(fonts); 130 for a = 1:numel(fonts) 131 f = fontsl{a}; 132 f(f==' ') = []; 133 switch f 134 case {'times', 'timesnewroman', 'times-roman'} 135 fontsl{a} = 'times-roman'; 136 case {'arial', 'helvetica'} 137 fontsl{a} = 'helvetica'; 138 case {'newcenturyschoolbook', 'newcenturyschlbk'} 139 fontsl{a} = 'newcenturyschlbk'; 140 otherwise 141 end 142 end 143 fontslu = unique(fontsl); 144 145 % Determine the font swap table 146 if fontswap 147 matlab_fonts = {'Helvetica', 'Times-Roman', 'Palatino', 'Bookman', 'Helvetica-Narrow', 'Symbol', ... 148 'AvantGarde', 'NewCenturySchlbk', 'Courier', 'ZapfChancery', 'ZapfDingbats'}; 149 matlab_fontsl = lower(matlab_fonts); 150 require_swap = find(~ismember(fontslu, matlab_fontsl)); 151 unused_fonts = find(~ismember(matlab_fontsl, fontslu)); 152 font_swap = cell(3, min(numel(require_swap), numel(unused_fonts))); 153 fonts_new = fonts; 154 for a = 1:size(font_swap, 2) 155 font_swap{1,a} = find(strcmp(fontslu{require_swap(a)}, fontsl)); 156 font_swap{2,a} = matlab_fonts{unused_fonts(a)}; 157 font_swap{3,a} = fonts{font_swap{1,a}(1)}; 158 fonts_new(font_swap{1,a}) = font_swap(2,a); 159 end 160 else 161 font_swap = []; 162 end 163 164 % Swap the fonts 165 if ~isempty(font_swap) 166 fonts_size = get(font_handles, 'FontSize'); 167 if iscell(fonts_size) 168 fonts_size = cell2mat(fonts_size); 169 end 170 M = false(size(font_handles)); 171 172 % Loop because some changes may not stick first time, due to listeners 173 c = 0; 174 update = zeros(1000, 1); 175 for b = 1:10 % Limit number of loops to avoid infinite loop case 176 for a = 1:numel(M) 177 M(a) = ~isequal(get(font_handles(a), 'FontName'), fonts_new{a}) || ~isequal(get(font_handles(a), 'FontSize'), fonts_size(a)); 178 if M(a) 179 set(font_handles(a), 'FontName', fonts_new{a}, 'FontSize', fonts_size(a)); 180 c = c + 1; 181 update(c) = a; 182 end 183 end 184 if ~any(M) 185 break; 60 61 function print2eps(name, fig, bb_padding, varargin) 62 options = {'-depsc2'}; 63 if nargin > 3 64 options = [options varargin]; 65 elseif nargin < 3 66 bb_padding = 0; 67 if nargin < 2 68 fig = gcf(); 69 end 70 end 71 % Construct the filename 72 if numel(name) < 5 || ~strcmpi(name(end-3:end), '.eps') 73 name = [name '.eps']; % Add the missing extension 74 end 75 % Set paper size 76 old_pos_mode = get(fig, 'PaperPositionMode'); 77 old_orientation = get(fig, 'PaperOrientation'); 78 set(fig, 'PaperPositionMode', 'auto', 'PaperOrientation', 'portrait'); 79 % Find all the used fonts in the figure 80 font_handles = findall(fig, '-property', 'FontName'); 81 fonts = get(font_handles, 'FontName'); 82 if ~iscell(fonts) 83 fonts = {fonts}; 84 end 85 % Map supported font aliases onto the correct name 86 fontsl = lower(fonts); 87 for a = 1:numel(fonts) 88 f = fontsl{a}; 89 f(f==' ') = []; 90 switch f 91 case {'times', 'timesnewroman', 'times-roman'} 92 fontsl{a} = 'times-roman'; 93 case {'arial', 'helvetica'} 94 fontsl{a} = 'helvetica'; 95 case {'newcenturyschoolbook', 'newcenturyschlbk'} 96 fontsl{a} = 'newcenturyschlbk'; 97 otherwise 98 end 99 end 100 fontslu = unique(fontsl); 101 % Determine the font swap table 102 matlab_fonts = {'Helvetica', 'Times-Roman', 'Palatino', 'Bookman', 'Helvetica-Narrow', 'Symbol', ... 103 'AvantGarde', 'NewCenturySchlbk', 'Courier', 'ZapfChancery', 'ZapfDingbats'}; 104 matlab_fontsl = lower(matlab_fonts); 105 require_swap = find(~ismember(fontslu, matlab_fontsl)); 106 unused_fonts = find(~ismember(matlab_fontsl, fontslu)); 107 font_swap = cell(3, min(numel(require_swap), numel(unused_fonts))); 108 fonts_new = fonts; 109 for a = 1:size(font_swap, 2) 110 font_swap{1,a} = find(strcmp(fontslu{require_swap(a)}, fontsl)); 111 font_swap{2,a} = matlab_fonts{unused_fonts(a)}; 112 font_swap{3,a} = fonts{font_swap{1,a}(1)}; 113 fonts_new(font_swap{1,a}) = {font_swap{2,a}}; 114 end 115 % Swap the fonts 116 if ~isempty(font_swap) 117 fonts_size = get(font_handles, 'FontSize'); 118 if iscell(fonts_size) 119 fonts_size = cell2mat(fonts_size); 120 end 121 M = false(size(font_handles)); 122 % Loop because some changes may not stick first time, due to listeners 123 c = 0; 124 update = zeros(1000, 1); 125 for b = 1:10 % Limit number of loops to avoid infinite loop case 126 for a = 1:numel(M) 127 M(a) = ~isequal(get(font_handles(a), 'FontName'), fonts_new{a}) || ~isequal(get(font_handles(a), 'FontSize'), fonts_size(a)); 128 if M(a) 129 set(font_handles(a), 'FontName', fonts_new{a}, 'FontSize', fonts_size(a)); 130 c = c + 1; 131 update(c) = a; 186 132 end 187 133 end 188 189 % Compute the order to revert fonts later, without the need of a loop 190 [update, M] = unique(update(1:c)); 191 [M, M] = sort(M); 192 update = reshape(update(M), 1, []); 193 end 194 195 % MATLAB bug fix - black and white text can come out inverted sometimes 196 % Find the white and black text 197 black_text_handles = findall(fig, 'Type', 'text', 'Color', [0 0 0]); 198 white_text_handles = findall(fig, 'Type', 'text', 'Color', [1 1 1]); 199 % Set the font colors slightly off their correct values 200 set(black_text_handles, 'Color', [0 0 0] + eps); 201 set(white_text_handles, 'Color', [1 1 1] - eps); 202 203 % MATLAB bug fix - white lines can come out funny sometimes 204 % Find the white lines 205 white_line_handles = findall(fig, 'Type', 'line', 'Color', [1 1 1]); 206 % Set the line color slightly off white 207 set(white_line_handles, 'Color', [1 1 1] - 0.00001); 208 209 % Workaround for issue #45: lines in image subplots are exported in invalid color 210 % In this case the -depsc driver solves the problem, but then all the other workarounds 211 % below (for all the other issues) will fail, so it's better to let the user decide by 212 % just issuing a warning and accepting the '-depsc' input parameter 213 epsLevel2 = ~any(strcmpi(options,'-depsc')); 214 if epsLevel2 215 % Use -depsc2 (EPS color level-2) if -depsc (EPS color level-3) was not specifically requested 216 options{end+1} = '-depsc2'; 217 % Issue a warning if multiple images & lines were found in the figure, and HG1 with painters renderer is used 218 isPainters = any(strcmpi(options,'-painters')); 219 if isPainters && ~using_hg2 && numel(findall(fig,'Type','image'))>1 && ~isempty(findall(fig,'Type','line')) 220 warning('YMA:export_fig:issue45', ... 221 ['Multiple images & lines detected. In such cases, the lines might \n' ... 222 'appear with an invalid color due to an internal MATLAB bug (fixed in R2014b). \n' ... 223 'Possible workaround: add a ''-depsc'' or ''-opengl'' parameter to the export_fig command.']); 134 if ~any(M) 135 break; 224 136 end 225 137 end 226 227 % Fix issue #83: use numeric handles in HG1 228 if ~using_hg2(fig), fig = double(fig); end 229 230 % Print to eps file 231 print(fig, options{:}, name); 232 233 % Do post-processing on the eps file 234 try 235 % Read the EPS file into memory 236 fstrm = read_write_entire_textfile(name); 237 catch 238 fstrm = ''; 239 end 240 241 % Fix for Matlab R2014b bug (issue #31): LineWidths<0.75 are not set in the EPS (default line width is used) 242 try 243 if ~isempty(fstrm) && using_hg2(fig) 244 % Convert miter joins to line joins 245 %fstrm = regexprep(fstrm, '\n10.0 ML\n', '\n1 LJ\n'); 246 % This is faster (the original regexprep could take many seconds when the axes contains many lines): 247 fstrm = strrep(fstrm, sprintf('\n10.0 ML\n'), sprintf('\n1 LJ\n')); 248 249 % In HG2, grid lines and axes Ruler Axles have a default LineWidth of 0.5 => replace en-bulk (assume that 1.0 LineWidth = 1.333 LW) 250 % hAxes=gca; hAxes.YGridHandle.LineWidth, hAxes.YRuler.Axle.LineWidth 251 %fstrm = regexprep(fstrm, '(GC\n2 setlinecap\n1 LJ)\nN', '$1\n0.667 LW\nN'); 252 % This is faster: 253 fstrm = strrep(fstrm, sprintf('GC\n2 setlinecap\n1 LJ\nN'), sprintf('GC\n2 setlinecap\n1 LJ\n0.667 LW\nN')); 254 255 % This is more accurate but *MUCH* slower (issue #52) 256 %{ 257 % Modify all thin lines in the figure to have 10x LineWidths 258 hLines = findall(fig,'Type','line'); 259 hThinLines = []; 260 for lineIdx = 1 : numel(hLines) 261 thisLine = hLines(lineIdx); 262 if thisLine.LineWidth < 0.75 && strcmpi(thisLine.Visible,'on') 263 hThinLines(end+1) = thisLine; %#ok<AGROW> 264 thisLine.LineWidth = thisLine.LineWidth * 10; 265 end 266 end 267 268 % If any thin lines were found 269 if ~isempty(hThinLines) 270 % Prepare an EPS with large-enough line widths 271 print(fig, options{:}, name); 272 % Restore the original LineWidths in the figure 273 for lineIdx = 1 : numel(hThinLines) 274 thisLine = handle(hThinLines(lineIdx)); 275 thisLine.LineWidth = thisLine.LineWidth / 10; 276 end 277 278 % Compare the original and the new EPS files and correct the original stream's LineWidths 279 fstrm_new = read_write_entire_textfile(name); 280 idx = 500; % skip heading with its possibly-different timestamp 281 markerStr = sprintf('10.0 ML\nN'); 282 markerLen = length(markerStr); 283 while ~isempty(idx) && idx < length(fstrm) 284 lastIdx = min(length(fstrm), length(fstrm_new)); 285 delta = fstrm(idx+1:lastIdx) - fstrm_new(idx+1:lastIdx); 286 idx = idx + find(delta,1); 287 if ~isempty(idx) && ... 288 isequal(fstrm(idx-markerLen+1:idx), markerStr) && ... 289 ~isempty(regexp(fstrm_new(idx-markerLen+1:idx+12),'10.0 ML\n[\d\.]+ LW\nN')) %#ok<RGXP1> 290 value = str2double(regexprep(fstrm_new(idx:idx+12),' .*','')); 291 if isnan(value), break; end % something's wrong... - bail out 292 newStr = sprintf('%0.3f LW\n',value/10); 293 fstrm = [fstrm(1:idx-1) newStr fstrm(idx:end)]; 294 idx = idx + 12; 295 else 296 break; 297 end 298 end 299 end 300 %} 301 302 % This is much faster although less accurate: fix all non-gray lines to have a LineWidth of 0.75 (=1 LW) 303 % Note: This will give incorrect LineWidth of 075 for lines having LineWidth<0.75, as well as for non-gray grid-lines (if present) 304 % However, in practice these edge-cases are very rare indeed, and the difference in LineWidth should not be noticeable 305 %fstrm = regexprep(fstrm, '([CR]C\n2 setlinecap\n1 LJ)\nN', '$1\n1 LW\nN'); 306 % This is faster (the original regexprep could take many seconds when the axes contains many lines): 307 fstrm = strrep(fstrm, sprintf('\n2 setlinecap\n1 LJ\nN'), sprintf('\n2 setlinecap\n1 LJ\n1 LW\nN')); 308 end 309 catch err 310 fprintf(2, 'Error fixing LineWidths in EPS file: %s\n at %s:%d\n', err.message, err.stack(1).file, err.stack(1).line); 311 end 312 313 % Reset the font and line colors 314 set(black_text_handles, 'Color', [0 0 0]); 315 set(white_text_handles, 'Color', [1 1 1]); 316 set(white_line_handles, 'Color', [1 1 1]); 317 318 % Reset paper size 319 set(fig, 'PaperPositionMode', old_pos_mode, 'PaperOrientation', old_orientation); 320 321 % Reset the font names in the figure 322 if ~isempty(font_swap) 323 for a = update 324 set(font_handles(a), 'FontName', fonts{a}, 'FontSize', fonts_size(a)); 325 end 326 end 327 328 % Bail out if EPS post-processing is not possible 329 if isempty(fstrm) 330 warning('Loading EPS file failed, so unable to perform post-processing. This is usually because the figure contains a large number of patch objects. Consider exporting to a bitmap format in this case.'); 331 return 332 end 333 334 % Replace the font names 335 if ~isempty(font_swap) 336 for a = 1:size(font_swap, 2) 337 %fstrm = regexprep(fstrm, [font_swap{1,a} '-?[a-zA-Z]*\>'], font_swap{3,a}(~isspace(font_swap{3,a}))); 338 fstrm = regexprep(fstrm, font_swap{2,a}, font_swap{3,a}(~isspace(font_swap{3,a}))); 339 end 340 end 341 342 % Move the bounding box to the top of the file (HG2 only), or fix the line styles (HG1 only) 343 if using_hg2(fig) 344 % Move the bounding box to the top of the file (HG2 only) 345 [s, e] = regexp(fstrm, '%%BoundingBox: [^%]*%%'); 346 if numel(s) == 2 347 fstrm = fstrm([1:s(1)-1 s(2):e(2)-2 e(1)-1:s(2)-1 e(2)-1:end]); 348 end 349 else 350 % Fix the line styles (HG1 only) 351 fstrm = fix_lines(fstrm); 352 end 353 354 % Apply the bounding box padding & cropping, replacing Matlab's print()'s bounding box 355 if bb_crop 356 % Calculate a new bounding box based on a bitmap print using crop_border.m 357 % 1. Determine the Matlab BoundingBox and PageBoundingBox 358 [s,e] = regexp(fstrm, '%%BoundingBox: [^%]*%%'); % location BB in eps file 359 if numel(s)==2, s=s(2); e=e(2); end 360 aa = fstrm(s+15:e-3); % dimensions bb - STEP1 361 bb_matlab = cell2mat(textscan(aa,'%f32%f32%f32%f32')); % dimensions bb - STEP2 362 363 [s,e] = regexp(fstrm, '%%PageBoundingBox: [^%]*%%'); % location bb in eps file 364 if numel(s)==2, s=s(2); e=e(2); end 365 aa = fstrm(s+19:e-3); % dimensions bb - STEP1 366 pagebb_matlab = cell2mat(textscan(aa,'%f32%f32%f32%f32')); % dimensions bb - STEP2 367 368 % 2. Create a bitmap image and use crop_borders to create the relative 369 % bb with respect to the PageBoundingBox 370 [A, bcol] = print2array(fig, 1, '-opengl'); 371 [aa, aa, aa, bb_rel] = crop_borders(A, bcol, bb_padding); 372 373 % 3. Calculate the new Bounding Box 374 pagew = pagebb_matlab(3)-pagebb_matlab(1); 375 pageh = pagebb_matlab(4)-pagebb_matlab(2); 376 %bb_new = [pagebb_matlab(1)+pagew*bb_rel(1) pagebb_matlab(2)+pageh*bb_rel(2) ... 377 % pagebb_matlab(1)+pagew*bb_rel(3) pagebb_matlab(2)+pageh*bb_rel(4)]; 378 bb_new = pagebb_matlab([1,2,1,2]) + [pagew,pageh,pagew,pageh].*bb_rel; % clearer 379 bb_offset = (bb_new-bb_matlab) + [-1,-1,1,1]; % 1px margin so that cropping is not TOO tight 380 381 % Apply the bounding box padding 382 if bb_padding 383 if abs(bb_padding)<1 384 bb_padding = round((mean([bb_new(3)-bb_new(1) bb_new(4)-bb_new(2)])*bb_padding)/0.5)*0.5; % ADJUST BB_PADDING 385 end 386 add_padding = @(n1, n2, n3, n4) sprintf(' %d', str2double({n1, n2, n3, n4}) + [-bb_padding -bb_padding bb_padding bb_padding] + bb_offset); 387 else 388 add_padding = @(n1, n2, n3, n4) sprintf(' %d', str2double({n1, n2, n3, n4}) + bb_offset); % fix small but noticeable bounding box shift 389 end 390 fstrm = regexprep(fstrm, '%%BoundingBox:[ ]+([-]?\d+)[ ]+([-]?\d+)[ ]+([-]?\d+)[ ]+([-]?\d+)', '%%BoundingBox:${add_padding($1, $2, $3, $4)}'); 391 end 392 393 % Fix issue #44: white artifact lines appearing in patch exports 394 % Note: the problem is due to the fact that Matlab's print() function exports patches 395 % as a combination of filled triangles, and a white line appears where the triangles touch 396 % In the workaround below, we will modify such dual-triangles into a filled rectangle. 397 % We are careful to only modify regexps that exactly match specific patterns - it's better to not 398 % correct some white-line artifacts than to change the geometry of a patch, or to corrupt the EPS. 399 % e.g.: '0 -450 937 0 0 450 3 MP PP 937 0 0 -450 0 450 3 MP PP' => '0 -450 937 0 0 450 0 0 4 MP' 400 fstrm = regexprep(fstrm, '\n([-\d.]+ [-\d.]+) ([-\d.]+ [-\d.]+) ([-\d.]+ [-\d.]+) 3 MP\nPP\n\2 \1 \3 3 MP\nPP\n','\n$1 $2 $3 0 0 4 MP\nPP\n'); 401 fstrm = regexprep(fstrm, '\n([-\d.]+ [-\d.]+) ([-\d.]+ [-\d.]+) ([-\d.]+ [-\d.]+) 3 MP\nPP\n\2 \3 \1 3 MP\nPP\n','\n$1 $2 $3 0 0 4 MP\nPP\n'); 402 fstrm = regexprep(fstrm, '\n([-\d.]+ [-\d.]+) ([-\d.]+ [-\d.]+) ([-\d.]+ [-\d.]+) 3 MP\nPP\n\3 \1 \2 3 MP\nPP\n','\n$1 $2 $3 0 0 4 MP\nPP\n'); 403 fstrm = regexprep(fstrm, '\n([-\d.]+ [-\d.]+) ([-\d.]+ [-\d.]+) ([-\d.]+ [-\d.]+) 3 MP\nPP\n\3 \2 \1 3 MP\nPP\n','\n$1 $2 $3 0 0 4 MP\nPP\n'); 404 405 % Write out the fixed eps file 406 read_write_entire_textfile(name, fstrm); 407 end 138 % Compute the order to revert fonts later, without the need of a loop 139 [update, M] = unique(update(1:c)); 140 [M, M] = sort(M); 141 update = reshape(update(M), 1, []); 142 end 143 % MATLAB bug fix - black and white text can come out inverted sometimes 144 % Find the white and black text 145 white_text_handles = findobj(fig, 'Type', 'text'); 146 M = get(white_text_handles, 'Color'); 147 if iscell(M) 148 M = cell2mat(M); 149 end 150 M = sum(M, 2); 151 black_text_handles = white_text_handles(M == 0); 152 white_text_handles = white_text_handles(M == 3); 153 % Set the font colors slightly off their correct values 154 set(black_text_handles, 'Color', [0 0 0] + eps); 155 set(white_text_handles, 'Color', [1 1 1] - eps); 156 % MATLAB bug fix - white lines can come out funny sometimes 157 % Find the white lines 158 white_line_handles = findobj(fig, 'Type', 'line'); 159 M = get(white_line_handles, 'Color'); 160 if iscell(M) 161 M = cell2mat(M); 162 end 163 white_line_handles = white_line_handles(sum(M, 2) == 3); 164 % Set the line color slightly off white 165 set(white_line_handles, 'Color', [1 1 1] - 0.00001); 166 % Print to eps file 167 print(fig, options{:}, name); 168 % Reset the font and line colors 169 set(black_text_handles, 'Color', [0 0 0]); 170 set(white_text_handles, 'Color', [1 1 1]); 171 set(white_line_handles, 'Color', [1 1 1]); 172 % Reset paper size 173 set(fig, 'PaperPositionMode', old_pos_mode, 'PaperOrientation', old_orientation); 174 % Reset the font names in the figure 175 if ~isempty(font_swap) 176 for a = update 177 set(font_handles(a), 'FontName', fonts{a}, 'FontSize', fonts_size(a)); 178 end 179 end 180 % Do post-processing on the eps file 181 try 182 fstrm = read_write_entire_textfile(name); 183 catch 184 warning('Loading EPS file failed, so unable to perform post-processing. This is usually because the figure contains a large number of patch objects. Consider exporting to a bitmap format in this case.'); 185 return 186 end 187 % Replace the font names 188 if ~isempty(font_swap) 189 for a = 1:size(font_swap, 2) 190 %fstrm = regexprep(fstrm, [font_swap{1,a} '-?[a-zA-Z]*\>'], font_swap{3,a}(~isspace(font_swap{3,a}))); 191 fstrm = regexprep(fstrm, font_swap{2,a}, font_swap{3,a}(~isspace(font_swap{3,a}))); 192 end 193 end 194 if using_hg2(fig) 195 % Convert miter joins to line joins 196 fstrm = regexprep(fstrm, '10.0 ML\n', '1 LJ\n'); 197 % Move the bounding box to the top of the file 198 [s, e] = regexp(fstrm, '%%BoundingBox: [\w\s()]*%%'); 199 if numel(s) == 2 200 fstrm = fstrm([1:s(1)-1 s(2):e(2)-2 e(1)-1:s(2)-1 e(2)-1:end]); 201 end 202 else 203 % Fix the line styles 204 fstrm = fix_lines(fstrm); 205 end 206 % Apply the bounding box padding 207 if bb_padding 208 add_padding = @(n1, n2, n3, n4) sprintf(' %d', str2double({n1, n2, n3, n4}) + [-bb_padding -bb_padding bb_padding bb_padding]); 209 fstrm = regexprep(fstrm, '%%BoundingBox:[ ]+([-]?\d+)[ ]+([-]?\d+)[ ]+([-]?\d+)[ ]+([-]?\d+)', '%%BoundingBox:${add_padding($1, $2, $3, $4)}'); 210 end 211 % Write out the fixed eps file 212 read_write_entire_textfile(name, fstrm); 213 end -
issm/trunk-jpl/externalpackages/export_fig/user_string.m
r19571 r19993 1 function string = user_string(string_name, string)2 1 %USER_STRING Get/set a user specific string 3 2 % 4 3 % Examples: 5 % string 6 % isSaved = user_string(string_name, new_string)4 % string = user_string(string_name) 5 % saved = user_string(string_name, new_string) 7 6 % 8 7 % Function to get and set a string in a system or user specific file. This 9 8 % enables, for example, system specific paths to binaries to be saved. 10 9 % 11 % The specified string will be saved in a file named <string_name>.txt,12 % either in a subfolder named .ignore under this file's folder, or in the13 % user's prefdir folder (in case this file's folder is non-writable).14 %15 10 % IN: 16 % string_name - String containing the name of the string required, which 17 % sets the filename storing the string: <string_name>.txt 18 % new_string - The new string to be saved in the <string_name>.txt file 11 % string_name - String containing the name of the string required. The 12 % string is extracted from a file called (string_name).txt, 13 % stored in the same directory as user_string.m. 14 % new_string - The new string to be saved under the name given by 15 % string_name. 19 16 % 20 17 % OUT: 21 % string - The currently saved string. Default: ''22 % isSaved - Boolean indicating whether the save was succesful18 % string - The currently saved string. Default: ''. 19 % saved - Boolean indicating whether the save was succesful 23 20 24 % Copyright (C) Oliver Woodford 2011-201 4, Yair Altman 2015-21 % Copyright (C) Oliver Woodford 2011-2013 25 22 26 23 % This method of saving paths avoids changing .m files which might be in a … … 31 28 32 29 % 10/01/2013 - Access files in text, not binary mode, as latter can cause 33 % errors. Thanks to Christian for pointing this out. 34 % 29/05/2015 - Save file in prefdir if current folder is non-writable (issue #74) 30 % errors. Thanks to Christian for pointing this out. 35 31 36 if ~ischar(string_name) 37 error('string_name must be a string.'); 32 function string = user_string(string_name, string) 33 if ~ischar(string_name) 34 error('string_name must be a string.'); 35 end 36 % Create the full filename 37 string_name = fullfile(fileparts(mfilename('fullpath')), '.ignore', [string_name '.txt']); 38 if nargin > 1 39 % Set string 40 if ~ischar(string) 41 error('new_string must be a string.'); 38 42 end 39 % Create the full filename 40 fname = [string_name '.txt']; 41 dname = fullfile(fileparts(mfilename('fullpath')), '.ignore'); 42 file_name = fullfile(dname, fname); 43 if nargin > 1 44 % Set string 45 if ~ischar(string) 46 error('new_string must be a string.'); 47 end 48 % Make sure the save directory exists 49 %dname = fileparts(file_name); 50 if ~exist(dname, 'dir') 51 % Create the directory 52 try 53 if ~mkdir(dname) 54 string = false; 55 return 56 end 57 catch 43 % Make sure the save directory exists 44 dname = fileparts(string_name); 45 if ~exist(dname, 'dir') 46 % Create the directory 47 try 48 if ~mkdir(dname) 58 49 string = false; 59 50 return 60 51 end 61 % Make it hidden62 try63 fileattrib(dname, '+h');64 catch65 end66 end67 % Write the file68 fid = fopen(file_name, 'wt');69 if fid == -170 % file cannot be created/updated - use prefdir if file does not already exist71 % (if file exists but is simply not writable, don't create a duplicate in prefdir)72 if ~exist(file_name,'file')73 file_name = fullfile(prefdir, fname);74 fid = fopen(file_name, 'wt');75 end76 if fid == -177 string = false;78 return;79 end80 end81 try82 fprintf(fid, '%s', string);83 52 catch 84 fclose(fid);85 53 string = false; 86 54 return 87 55 end 56 % Make it hidden 57 try 58 fileattrib(dname, '+h'); 59 catch 60 end 61 end 62 % Write the file 63 fid = fopen(string_name, 'wt'); 64 if fid == -1 65 string = false; 66 return 67 end 68 try 69 fprintf(fid, '%s', string); 70 catch 88 71 fclose(fid); 89 string = true; 90 else 91 % Get string 92 fid = fopen(file_name, 'rt'); 93 if fid == -1 94 % file cannot be read, try to read the file in prefdir 95 file_name = fullfile(prefdir, fname); 96 fid = fopen(file_name, 'rt'); 97 if fid == -1 98 string = ''; 99 return 100 end 101 end 102 string = fgetl(fid); 103 fclose(fid); 72 string = false; 73 return 104 74 end 75 fclose(fid); 76 string = true; 77 else 78 % Get string 79 fid = fopen(string_name, 'rt'); 80 if fid == -1 81 string = ''; 82 return 83 end 84 string = fgetl(fid); 85 fclose(fid); 105 86 end 87 end -
issm/trunk-jpl/externalpackages/export_fig/using_hg2.m
r19571 r19993 1 %USING_HG2 Determine if the HG2 graphics engine is used1 %USING_HG2 Determine if the HG2 graphics pipeline is used 2 2 % 3 3 % tf = using_hg2(fig) … … 7 7 % 8 8 %OUT: 9 % tf - boolean indicating whether the HG2 graphics engine is being used9 % tf - boolean indicating whether the HG2 graphics pipeline is being used 10 10 % (true) or not (false). 11 11 12 % 19/06/2015 - Suppress warning in R2015b; cache result for improved performance13 14 12 function tf = using_hg2(fig) 15 persistent tf_cached 16 if isempty(tf_cached) 17 try 18 if nargin < 1, fig = figure('visible','off'); end 19 oldWarn = warning('off','MATLAB:graphicsversion:GraphicsVersionRemoval'); 20 try 21 % This generates a [supressed] warning in R2015b: 22 tf = ~graphicsversion(fig, 'handlegraphics'); 23 catch 24 tf = verLessThan('matlab','8.4'); % =R2014b 25 end 26 warning(oldWarn); 27 catch 28 tf = false; 29 end 30 if nargin < 1, delete(fig); end 31 tf_cached = tf; 32 else 33 tf = tf_cached; 34 end 13 try 14 tf = ~graphicsversion(fig, 'handlegraphics'); 15 catch 16 tf = false; 35 17 end 18 end
Note:
See TracChangeset
for help on using the changeset viewer.