Changeset 19993


Ignore:
Timestamp:
01/25/16 19:42:49 (9 years ago)
Author:
seroussi
Message:

BUG: reverting back to old export_fig (too many problems)

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. Altman
     1Copyright (c) 2014, Oliver J. Woodford
    22All rights reserved.
    33
  • issm/trunk-jpl/externalpackages/export_fig/README.md

    r19571 r19993  
    2525|![](https://farm6.staticflickr.com/5616/15589249291_16e485c29a_o_d.png)|![](https://farm4.staticflickr.com/3944/15406302850_4d2e1c7afa_o_d.png)|![](https://farm6.staticflickr.com/5607/15568225476_8ce9bd5f6b_o_d.png)|
    2626
    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:
     27Note 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:
    2828```Matlab
    2929set(gcf, 'Color', 'w');
     
    171171**Specifying the figure/axes** - if you have mutiple figures open you can specify which figure to export using its handle: 
    172172```Matlab
    173 export_fig(figure_handle, filename);
     173export_fig(figure_handle, 'filename.fmt');
    174174```
    175175Equally, if your figure contains several subplots then you can export just one of them by giving export_fig the handle to the relevant axes:
    176176```Matlab
    177 export_fig(axes_handle, filename);
     177export_fig(axes_handle, 'filename.fmt');
    178178```
    179179
     
    195195**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)). 
    196196 
    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  
    199197**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. 
    200198 
    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`. 
    205200 
    206201**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: 
     
    220215
    221216**Undefined function errors** - If you download and run export_fig and get an error similar to this: 
    222 ```
     217```Matlab
    223218??? Undefined function or method 'print2array' for input arguments of type 'double'.
    224219```
     
    226221 
    227222### 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 (up to 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 that 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 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. 
     223There 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
     227Also, 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. 
    235230
    236231**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). 
     
    238233**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. 
    239234 
    240 **Lighting and transparency** - when using the painters renderer, transparency and lighting effects are not supported. Sorry, but this is an inherent feature of MATLAB's painters 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. 
    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
    243238 
    244239**Out of memory** - if you run into memory issues when using export_fig, some ways to get round this are: 
    245240 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. 
    249243 
    250244**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. 
     
    255249Secondly, 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.
    256250
    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.
     251If 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.
    260252
    261253### And finally...
     
    263255![](https://farm4.staticflickr.com/3956/15591911455_b9008bd77e_o_d.jpg)
    264256
    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 
     257If 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
     258figure 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  
    3333% setting
    3434
    35 % 26/02/15: If temp dir is not writable, use the output folder for temp
    36 %           files when appending (Javier Paredes); sanity check of inputs
    37 
    3835function append_pdfs(varargin)
    39 
    40 if nargin < 2,  return;  end  % sanity check
    41 
    4236% Are we appending or creating a new file
    4337append = 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
     38if append
     39    output = [tempname '.pdf'];
     40else
    6041    output = varargin{1};
    6142    varargin = varargin(2:end);
    6243end
    6344% Create the command file
    64 if isTempDirOk
    65     cmdfile = [tempname '.txt'];
    66 else
    67     cmdfile = fullfile(fpath,[fname '.txt']);
    68 end
     45cmdfile = [tempname '.txt'];
    6946fh = fopen(cmdfile, 'w');
    7047fprintf(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)
    21%COPYFIG Create a copy of a figure, without changing the figure
    32%
     
    1615% Copyright (C) Oliver Woodford 2012
    1716
    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
     17function fh = copyfig(fh)
     18% Set the default
     19if nargin == 0
     20    fh = gcf;
    5121end
     22% Is there a legend?
     23if isempty(findall(fh, 'Type', 'axes', 'Tag', 'legend'))
     24    % Safe to copy using copyobj
     25    fh = copyobj(fh, 0);
     26else
     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);
     32end
     33end
  • issm/trunk-jpl/externalpackages/export_fig/crop_borders.m

    r19571 r19993  
    1 function [A, vA, vB, bb_rel] = crop_borders(A, bcol, padding)
    21%CROP_BORDERS Crop the borders of an image or stack of images
    32%
    4 %   [B, vA, vB, bb_rel] = crop_borders(A, bcol, [padding])
     3%   [B, v] = crop_borders(A, bcol, [padding])
    54%
    65%IN:
    76%   A - HxWxCxN stack of images.
    87%   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.
    119%
    1210%OUT:
    1311%   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),:,:).
    1714
    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
     15function [A, v] = crop_borders(A, bcol, padding)
     16if nargin < 3
     17    padding = 0;
     18end
     19[h, w, c, n] = size(A);
     20if isscalar(bcol)
     21    bcol = bcol(ones(c, 1));
     22end
     23bail = false;
     24for l = 1:w
     25    for a = 1:c
     26        if ~all(col(A(:,l,a,:)) == bcol(a))
     27            bail = true;
    4228            break;
    4329        end
    4430    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
     34end
     35bcol = A(ceil(end/2),w,:,1);
     36bail = false;
     37for r = w:-1:l
     38    for a = 1:c
     39        if ~all(col(A(:,r,a,:)) == bcol(a))
     40            bail = true;
    5741            break;
    5842        end
    5943    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
     47end
     48bcol = A(1,ceil(end/2),:,1);
     49bail = false;
     50for t = 1:h
     51    for a = 1:c
     52        if ~all(col(A(t,:,a,:)) == bcol(a))
     53            bail = true;
    7254            break;
    7355        end
    7456    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
     60end
     61bcol = A(h,ceil(end/2),:,1);
     62bail = false;
     63for b = h:-1:t
     64    for a = 1:c
     65        if ~all(col(A(b,:,a,:)) == bcol(a))
     66            bail = true;
    8767            break;
    8868        end
    8969    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;
    10072    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];
     73end
     74% Crop the background, leaving one boundary pixel to avoid bleeding on resize
     75v = [max(t-padding, 1) min(b+padding, h) max(l-padding, 1) min(r+padding, w)];
     76A = A(v(1):v(2),v(3):v(4),:,:);
    12177end
    12278
    12379function A = col(A)
    124     A = A(:);
     80A = A(:);
    12581end
  • issm/trunk-jpl/externalpackages/export_fig/eps2pdf.m

    r19571 r19993  
    1 function eps2pdf(source, dest, crop, append, gray, quality, gs_options)
    21%EPS2PDF  Convert an eps file to pdf format using ghostscript
    32%
     
    87%   eps2pdf(source, dest, crop, append, gray)
    98%   eps2pdf(source, dest, crop, append, gray, quality)
    10 %   eps2pdf(source, dest, crop, append, gray, quality, gs_options)
    119%
    1210% This function converts an eps file to pdf format. The output can be
     
    1917% system. Ghostscript can be downloaded from: http://www.ghostscript.com
    2018%
    21 % Inputs:
    22 %   source  - filename of the source eps file to convert. The filename is
    23 %             assumed to already have the extension ".eps".
    24 %   dest    - filename of the destination pdf file. The filename is assumed
    25 %             to already have the extension ".pdf".
    26 %   crop    - boolean indicating whether to crop the borders off the pdf.
    27 %             Default: true.
    28 %   append  - boolean indicating whether the eps should be appended to the
    29 %             end of the pdf as a new page (if the pdf exists already).
    30 %             Default: false.
    31 %   gray    - boolean indicating whether the output pdf should be grayscale
    32 %             or not. Default: false.
     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.
    3331%   quality - scalar indicating the level of image bitmap quality to
    3432%             output. A larger value gives a higher quality. quality > 100
    3533%             gives lossless output. Default: ghostscript prepress default.
    36 %   gs_options - optional ghostscript options (e.g.: '-dNoOutputFonts'). If
    37 %                multiple options are needed, enclose in call array: {'-a','-b'}
    3834
    39 % Copyright (C) Oliver Woodford 2009-2014, Yair Altman 2015-
     35% Copyright (C) Oliver Woodford 2009-2011
    4036
    4137% Suggestion of appending pdf files provided by Matt C at:
     
    4844
    4945% 9/12/2011 Pass font path to ghostscript.
    50 % 26/02/15: If temp dir is not writable, use the dest folder for temp
    51 %           destination files (Javier Paredes)
    52 % 28/02/15: Enable users to specify optional ghostscript options (issue #36)
    53 % 01/03/15: Upon GS error, retry without the -sFONTPATH= option (this might solve
    54 %           some /findfont errors according to James Rankin, FEX Comment 23/01/15)
    55 % 23/06/15: Added extra debug info in case of ghostscript error; code indentation
    5646
    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'];
     47function eps2pdf(source, dest, crop, append, gray, quality)
     48% Intialise the options string for ghostscript
     49options = ['-q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sOutputFile="' dest '"'];
     50% Set crop option
     51if nargin < 3 || crop
     52    options = [options ' -dEPSCrop'];
     53end
     54% Set the font path
     55fp = font_path();
     56if ~isempty(fp)
     57    options = [options ' -sFONTPATH="' fp '"'];
     58end
     59% Set the grayscale option
     60if nargin > 4 && gray
     61    options = [options ' -sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray'];
     62end
     63% Set the bitmap quality
     64if 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);
    6274    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
     75end
     76% Check if the output file exists
     77if 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
    12488        % Delete the intermediate file
    12589        delete(tmp_nam);
     90        rethrow(me);
     91    end
     92    % Delete the intermediate file
     93    delete(tmp_nam);
     94else
     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);
     100end
     101% Check for error
     102if status
     103    % Report error
     104    if isempty(message)
     105        error('Unable to generate pdf. Check destination directory is writable.');
    126106    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);
    132108    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
     109end
    155110end
    156111
    157112% Function to return (and create, where necessary) the font path
    158113function fp = font_path()
    159     fp = user_string('gs_font_path');
     114fp = user_string('gs_font_path');
     115if ~isempty(fp)
     116    return
     117end
     118% Create the path
     119% Start with the default path
     120fp = getenv('GS_FONTPATH');
     121% Add on the typical directories for a given OS
     122if ispc
    160123    if ~isempty(fp)
    161         return
     124        fp = [fp ';'];
    162125    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'];
     127else
     128    if ~isempty(fp)
     129        fp = [fp ':'];
    177130    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'];
    179132end
     133user_string('gs_font_path', fp);
     134end
  • 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
    32%
    43% Examples:
    5 %   imageData = export_fig
    6 %   [imageData, alpha] = export_fig
     4%   im = export_fig
     5%   [im alpha] = export_fig
    76%   export_fig filename
    87%   export_fig filename -format1 -format2
     
    1514%   export_fig ... -q<val>
    1615%   export_fig ... -p<val>
    17 %   export_fig ... -d<gs_option>
    18 %   export_fig ... -depsc
    1916%   export_fig ... -<renderer>
    2017%   export_fig ... -<colorspace>
    2118%   export_fig ... -append
    2219%   export_fig ... -bookmark
    23 %   export_fig ... -clipboard
    24 %   export_fig ... -update
    25 %   export_fig ... -nofontswap
    2620%   export_fig(..., handle)
    2721%
    2822% 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 % with the following properties:
     23% bitmap file formats, and/or outputs a rasterized version to the
     24% workspace, with the following properties:
    3125%   - Figure/axes reproduced as it appears on screen
    3226%   - Cropped borders (optional)
     
    4135%   - Optionally append to file (pdf, tiff)
    4236%   - 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%   
    4539% This function is especially suited to exporting figures for use in
    4640% publications and presentations, because of the high quality and
     
    5246% objects), use the -transparent option or set the figure 'Color' property
    5347% 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.
    5651%
    5752% The choice of renderer (opengl, zbuffer or painters) has a large impact
    58 % on the quality of output. The default value (opengl for bitmaps, painters
    59 % for vector formats) generally gives good results, but if you aren't
    60 % satisfied then try another renderer.  Notes: 1) For vector formats (EPS,
    61 % PDF), only painters generates vector graphics. 2) For bitmaps, only
     53% 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
    6257% opengl can render transparent patch objects correctly. 3) For bitmaps,
    6358% only painters will correctly scale line dash and dot lengths when
     
    6560% using painters.
    6661%
    67 % When exporting to vector format (PDF & EPS) and bitmap format using the
     62% When exporting to vector format (pdf & eps) and bitmap format using the
    6863% painters renderer, this function requires that ghostscript is installed
    6964% on your system. You can download this from:
     
    7368%   http://www.foolabs.com/xpdf
    7469%
    75 % Inputs:
     70%IN:
    7671%   filename - string containing the name (optionally including full or
    7772%              relative path) of the file the figure is to be saved as. If
     
    9287%   -m<val> - option where val indicates the factor to magnify the
    9388%             on-screen figure pixel dimensions by when generating bitmap
    94 %             outputs (does not affect vector formats). Default: '-m1'.
     89%             outputs. Default: '-m1'.
    9590%   -r<val> - option val indicates the resolution (in pixels per inch) to
    9691%             export bitmap and vector outputs at, keeping the dimensions
     
    111106%                        use for bitmap outputs. '-a1' means no anti-
    112107%                        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.
    117111%   -<colorspace> - option indicating which colorspace color figures should
    118112%                   be saved in: RGB (default), CMYK or gray. CMYK is only
     
    125119%             sometimes give a smaller file size than the default lossy
    126120%             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).
    134124%   -append - option indicating that if the file (pdfs only) already
    135125%             exists, the figure is to be appended as a new page, instead
     
    137127%   -bookmark - option to indicate that a bookmark with the name of the
    138128%               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.
    158137%
    159138%   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
    166144
    167145% The idea of using ghostscript is inspired by Peder Axensten's SAVEFIG
     
    184162% Thanks to Tammy Threadgill for reporting a bug where an axes is not
    185163% isolated from gui objects.
    186 %}
    187 %{
     164
    188165% 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
     179function [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.
     182drawnow;
     183% Parse the input arguments
     184[fig, options] = parse_args(nargout, varargin{:});
     185% Isolate the subplot, if it is one
     186cls = all(ismember(get(fig, 'Type'), {'axes', 'uipanel'}));
     187if cls
     188    % Given handles of one or more axes, so isolate them from the rest
     189    fig = isolate_axes(fig);
     190else
     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');
     197end
     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.
     201magnify = options.magnify * options.aa_factor;
     202if 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
     214end
     215% MATLAB "feature": axes limits and tick marks can change when printing
     216Hlims = findall(fig, 'Type', 'axes');
     217if ~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'));
     225end
     226% Set all axes limit and tick modes to manual, so the limits and ticks can't change
     227set(Hlims, 'XLimMode', 'manual', 'YLimMode', 'manual', 'ZLimMode', 'manual');
     228set_tick_mode(Hlims, 'X');
     229set_tick_mode(Hlims, 'Y');
     230set_tick_mode(Hlims, 'Z');
     231% Set to print exactly what is there
     232set(fig, 'InvertHardcopy', 'off');
     233% Set the renderer
     234switch 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
     243end
     244% Do the bitmap formats first
     245if 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
    257333    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
     404end
     405% Now do the vector formats
     406if 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.');
    279438            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);
    362458            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
     466end
     467if cls
     468    % Close the created figure
     469    close(fig);
     470else
     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
     477end
     478end
     479
     480function [fig, options] = parse_args(nout, varargin)
     481% Parse the input arguments
     482% Set the defaults
     483fig = get(0, 'CurrentFigure');
     484options = 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', []);
     504native = false; % Set resolution to native of an image
     505
     506% Go through the other arguments
     507for 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});
    377553                    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;
    444563                    end
    445                 end
    446                 if options.png
    447                     % Compute the resolution
    448                     res = options.magnify * get(0, 'ScreenPixelsPerInch') / 25.4e-3;
    449                     % Save the png
    450                     imwrite(A, [options.name '.png'], 'Alpha', double(alpha), 'ResolutionUnit', 'meter', 'XResolution', res, 'YResolution', res);
    451                     % Clear the png bit
    452                     options.png = false;
    453                 end
    454                 % Return only one channel for greyscale
    455                 if isbitmap(options)
    456                     A = check_greyscale(A);
    457                 end
    458                 if options.alpha
    459                     % Store the image
    460                     imageData = A;
    461                     % Clear the alpha bit
    462                     options.alpha = false;
    463                 end
    464                 % Get the non-alpha image
    465                 if isbitmap(options)
    466                     alph = alpha(:,:,ones(1, size(A, 3)));
    467                     A = uint8(single(A) .* alph + 255 * (1 - alph));
    468                     clear alph
    469                 end
    470                 if options.im
    471                     % Store the new image
    472                     imageData = A;
    473                 end
    474             else
    475                 % Print large version to array
    476                 if options.transparent
    477                     % MATLAB "feature": apparently figure size can change when changing
    478                     % colour in -nodisplay mode
    479                     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                 else
    486                     [A, tcol] = print2array(fig, magnify, renderer);
    487                 end
    488                 % Crop the background
    489                 if options.crop
    490                     A = crop_borders(A, tcol, options.bb_padding);
    491                 end
    492                 % Downscale the image
    493                 A = downsize(A, options.aa_factor);
    494                 if options.colourspace == 2
    495                     % Convert to greyscale
    496                     A = rgb2grey(A);
    497                 else
    498                     % Return only one channel for greyscale
    499                     A = check_greyscale(A);
    500                 end
    501                 % Outputs
    502                 if options.im
    503                     imageData = A;
    504                 end
    505                 if options.alpha
    506                     imageData = A;
    507                     alpha = zeros(size(A, 1), size(A, 2), 'single');
    508                 end
    509564            end
    510             % Save the images
    511             if options.png
    512                 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];
    514569            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};
    517585            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
     588end
     589
     590% Set default anti-aliasing now we know the renderer
     591if options.aa_factor == 0
     592    options.aa_factor = 1 + 2 * (~(using_hg2(fig) && strcmp(get(ancestor(fig, 'figure'), 'GraphicsSmoothing'), 'on')) | (options.renderer == 3));
     593end
     594
     595% Convert user dir '~' to full path
     596if 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));
     598end
     599
     600% Compute the magnification and resolution
     601if 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
     608elseif isempty(options.resolution)
     609    options.resolution = 864;
     610end 
     611
     612% Check we have a figure handle
     613if isempty(fig)
     614    error('No figure found');
     615end
     616
     617% Set the default format
     618if ~isvector(options) && ~isbitmap(options)
     619    options.png = true;
     620end
     621
     622% Check whether transparent background is wanted (old way)
     623if isequal(get(ancestor(fig(1), 'figure'), 'Color'), 'none')
     624    options.transparent = true;
     625end
     626
     627% If requested, set the resolution to the native vertical resolution of the
     628% first suitable image found
     629if 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];
    659646        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)
    1034648                continue
    1035649            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
     670end
    1066671end
    1067672
    1068673function A = downsize(A, factor)
    1069     % Downsample an image
    1070     if factor == 1
    1071         % Nothing to do
    1072         return
    1073     end
    1074     try
    1075         % Faster, but requires image processing toolbox
    1076         A = imresize(A, 1/factor, 'bilinear');
    1077     catch
    1078         % No image processing toolbox - resize manually
    1079         % Lowpass filter - use Gaussian as is separable, so faster
    1080         % Compute the 1d Gaussian filter
    1081         filt = (-factor-1:factor+1) / (factor * 0.6);
    1082         filt = exp(-filt .* filt);
    1083         % Normalize the filter
    1084         filt = single(filt / sum(filt));
    1085         % Filter the image
    1086         padding = floor(numel(filt) / 2);
    1087         for a = 1:size(A, 3)
    1088             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');
    1089         end
    1090         % Subsample
    1091         A = A(1+floor(mod(end-1, factor)/2):factor:end,1+floor(mod(end-1, factor)/2):factor:end,:);
    1092     end
     674% Downsample an image
     675if factor == 1
     676    % Nothing to do
     677    return
     678end
     679try
     680    % Faster, but requires image processing toolbox
     681    A = imresize(A, 1/factor, 'bilinear');
     682catch
     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,:);
     697end
    1093698end
    1094699
    1095700function 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>
     701A = cast(reshape(reshape(single(A), [], 3) * single([0.299; 0.587; 0.114]), size(A, 1), size(A, 2)), class(A));
    1097702end
    1098703
    1099704function A = check_greyscale(A)
    1100     % Check if the image is greyscale
    1101     if size(A, 3) == 3 && ...
    1102             all(reshape(A(:,:,1) == A(:,:,2), [], 1)) && ...
    1103             all(reshape(A(:,:,2) == A(:,:,3), [], 1))
    1104         A = A(:,:,1); % Save only one channel for 8-bit output
    1105     end
     705% Check if the image is greyscale
     706if 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
     710end
    1106711end
    1107712
    1108713function eps_remove_background(fname, count)
    1109     % Remove the background of an eps file
    1110     % Open the file
    1111     fh = fopen(fname, 'r+');
    1112     if fh == -1
    1113         error('Not able to open file %s.', fname);
    1114     end
    1115     % Read the file line by line
    1116     while count
    1117         % Get the next line
    1118         l = fgets(fh);
    1119         if isequal(l, -1)
    1120             break; % Quit, no rectangle found
    1121         end
    1122         % Check if the line contains the background rectangle
    1123         if isequal(regexp(l, ' *0 +0 +\d+ +\d+ +r[fe] *[\n\r]+', 'start'), 1)
    1124             % Set the line to whitespace and quit
    1125             l(1:regexp(l, '[\n\r]', 'start', 'once')-1) = ' ';
    1126             fseek(fh, -numel(l), 0);
    1127             fprintf(fh, l);
    1128             % Reduce the count
    1129             count = count - 1;
    1130         end
    1131     end
    1132     % Close the file
    1133     fclose(fh);
     714% Remove the background of an eps file
     715% Open the file
     716fh = fopen(fname, 'r+');
     717if fh == -1
     718    error('Not able to open file %s.', fname);
     719end
     720% Read the file line by line
     721while 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
     736end
     737% Close the file
     738fclose(fh);
    1134739end
    1135740
    1136741function b = isvector(options)
    1137     b = options.pdf || options.eps;
     742b = options.pdf || options.eps;
    1138743end
    1139744
    1140745function b = isbitmap(options)
    1141     b = options.png || options.tif || options.jpg || options.bmp || options.im || options.alpha;
     746b = options.png || options.tif || options.jpg || options.bmp || options.im || options.alpha;
    1142747end
    1143748
    1144749% Helper function
    1145750function A = make_cell(A)
    1146     if ~iscell(A)
    1147         A = {A};
    1148     end
     751if ~iscell(A)
     752    A = {A};
     753end
    1149754end
    1150755
    1151756function 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
     759fh = fopen(fname, 'r');
     760if fh == -1
     761    error('File %s not found.', fname);
     762end
     763try
     764    fstrm = fread(fh, '*char')';
     765catch ex
    1164766    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);
     768end
     769fclose(fh);
     770
     771% Include standard pdfmark prolog to maximize compatibility
     772fstrm = strrep(fstrm, '%%BeginProlog', sprintf('%%%%BeginProlog\n/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse'));
     773% Add page bookmark
     774fstrm = strrep(fstrm, '%%EndPageSetup', sprintf('%%%%EndPageSetup\n[ /Title (%s) /OUT pdfmark',bookmark_text));
     775
     776% Write out the updated file
     777fh = fopen(fname, 'w');
     778if fh == -1
     779    error('Unable to open %s for writing.', fname);
     780end
     781try
     782    fwrite(fh, fstrm, 'char*1');
     783catch ex
    1182784    fclose(fh);
     785    rethrow(ex);
     786end
     787fclose(fh);
    1183788end
    1184789
    1185790function 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
     793M = get(Hlims, [ax 'Scale']);
     794if ~iscell(M)
     795    M = {M};
     796end
     797M = cellfun(@(c) strcmp(c, 'linear'), M);
     798set(Hlims(M), [ax 'TickMode'], 'manual');
     799end
  • issm/trunk-jpl/externalpackages/export_fig/fix_lines.m

    r19571 r19993  
    3838% opened.
    3939
    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 #39
    42 
    4340function fstrm = fix_lines(fstrm, fname2)
    4441
    45 % Issue #20: warn users if using this function in HG2 (R2014b+)
    46 if using_hg2
    47     warning('export_fig:hg2','The fix_lines function should not be used in this Matlab version.');
    48 end
    49    
    5042if nargout == 0 || nargin > 1
    5143    if nargin < 2
     
    122114end
    123115
     116% Isolate line style definition section
     117first_sec = strfind(fstrm, '% line types:');
     118[second_sec, remaining] = strtok(fstrm(first_sec+1:end), '/');
     119[remaining, remaining] = strtok(remaining, '%');
     120
    124121% Define the new styles, including the new GR format
    125122% Dot and dash lengths have two parts: a constant amount plus a line width
     
    138135
    139136% 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{:}),'%']);
     137fstrm = [fstrm(1:first_sec) second_sec sprintf('%s\r', new_style{:}) remaining];
    146138
    147139% Write the output file
  • issm/trunk-jpl/externalpackages/export_fig/ghostscript.m

    r19571 r19993  
    1 function varargout = ghostscript(cmd)
    21%GHOSTSCRIPT  Calls a local GhostScript executable with the input command
    32%
     
    2120%   result - Output from ghostscript.
    2221
    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.
    3132% 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.
    4440
    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
     41function varargout = ghostscript(cmd)
     42% Initialize any required system calls before calling ghostscript
     43shell_cmd = '';
     44if isunix
     45    shell_cmd = 'export LD_LIBRARY_PATH=""; '; % Avoids an error on Linux with GS 9.07
     46end
     47if ismac
     48    shell_cmd = 'export DYLD_LIBRARY_PATH=""; ';  % Avoids an error on Mac with GS 9.07
     49end
     50% Call ghostscript
     51[varargout{1:nargout}] = system(sprintf('%s"%s" %s', shell_cmd, gs_path, cmd));
    6852end
    6953
    7054function 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
     57path_ = user_string('ghostscript');
     58% Check the path works
     59if check_gs_path(path_)
     60    return
     61end
     62% Check whether the binary is on the path
     63if ispc
     64    bin = {'gswin32c.exe', 'gswin64c.exe', 'gs'};
     65else
     66    bin = {'gs'};
     67end
     68for a = 1:numel(bin)
     69    path_ = bin{a};
     70    if check_store_gs_path(path_)
    7671        return
    7772    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'};
     73end
     74% Search the obvious places
     75if 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);
    8381    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
     100else
     101    executable = {'/usr/bin/gs', '/usr/local/bin/gs'};
     102    for a = 1:numel(executable)
     103        path_ = executable{a};
    86104        if check_store_gs_path(path_)
    87105            return
    88106        end
    89107    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
     108end
     109% Ask the user to enter the path
     110while 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.'))
    124115    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
    146129                end
    147130            end
    148131        end
    149132    end
    150     error('Ghostscript not found. Have you installed it from www.ghostscript.com?');
     133end
     134error('Ghostscript not found. Have you installed it from www.ghostscript.com?');
    151135end
    152136
    153137function 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
     139good = check_gs_path(path_);
     140if ~good
     141    return
     142end
     143% Update the current default path to the path found
     144if ~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
     147end
    165148end
    166149
    167150function 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
     152shell_cmd = '';
     153if ismac
     154    shell_cmd = 'export DYLD_LIBRARY_PATH=""; ';  % Avoids an error on Mac with GS 9.07
    177155end
    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_));
     157good = good == 0;
    191158end
  • issm/trunk-jpl/externalpackages/export_fig/isolate_axes.m

    r19571 r19993  
    1 function fh = isolate_axes(ah, vis)
    21%ISOLATE_AXES Isolate the specified axes in a figure on their own
    32%
     
    2322
    2423% 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.
    3331
    34     % Make sure we have an array of handles
    35     if ~all(ishandle(ah))
    36         error('ah must be an array of handles');
     32function fh = isolate_axes(ah, vis)
     33% Make sure we have an array of handles
     34if ~all(ishandle(ah))
     35    error('ah must be an array of handles');
     36end
     37% Check that the handles are all for axes or uipanels, and are all in the same figure
     38fh = ancestor(ah(1), 'figure');
     39nAx = numel(ah);
     40for a = 1:nAx
     41    if ~ismember(get(ah(a), 'Type'), {'axes', 'uipanel'})
     42        error('All handles must be axes or uipanel handles.');
    3743    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.');
    4846    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};
     47end
     48% Tag the objects so we can find them in the copy
     49old_tag = get(ah, 'Tag');
     50if nAx == 1
     51    old_tag = {old_tag};
     52end
     53set(ah, 'Tag', 'ObjectToCopy');
     54% Create a new figure exactly the same as the old one
     55fh = copyfig(fh); %copyobj(fh, 0);
     56if nargin < 2 || ~vis
     57    set(fh, 'Visible', 'off');
     58end
     59% Reset the object tags
     60for a = 1:nAx
     61    set(ah(a), 'Tag', old_tag{a});
     62end
     63% Find the objects to save
     64ah = findall(fh, 'Tag', 'ObjectToCopy');
     65if numel(ah) ~= nAx
     66    close(fh);
     67    error('Incorrect number of objects found.');
     68end
     69% Set the axes tags to what they should be
     70for a = 1:nAx
     71    set(ah(a), 'Tag', old_tag{a});
     72end
     73% Keep any legends and colorbars which overlap the subplots
     74lh = findall(fh, 'Type', 'axes', '-and', {'Tag', 'legend', '-or', 'Tag', 'Colorbar'});
     75nLeg = numel(lh);
     76if nLeg > 0
     77    set([ah(:); lh(:)], 'Units', 'normalized');
     78    ax_pos = get(ah, 'OuterPosition');
     79    if nAx > 1
     80        ax_pos = cell2mat(ax_pos(:));
    5381    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);
    5986    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))];
     95end
     96% Get all the objects in the figure
     97axs = findall(fh);
     98% Delete everything except for the input objects and associated items
     99delete(axs(~ismember(axs, [ah; allchildren(ah); allancestors(ah)])));
    111100end
    112101
    113102function ah = allchildren(ah)
    114     ah = findall(ah);
    115     if iscell(ah)
    116         ah = cell2mat(ah);
    117     end
    118     ah = ah(:);
     103ah = findall(ah);
     104if iscell(ah)
     105    ah = cell2mat(ah);
     106end
     107ah = ah(:);
    119108end
    120109
    121110function 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
     111ph = [];
     112for a = 1:numel(ah)
     113    h = get(ah(a), 'parent');
     114    while h ~= 0
     115        ph = [ph; h];
     116        h = get(h, 'parent');
    129117    end
    130118end
     119end
  • issm/trunk-jpl/externalpackages/export_fig/pdftops.m

    r19571 r19993  
    2929% under linux.
    3030% 23/01/2014 - Add full path to pdftops.txt in warning.
    31 % 27/05/2015 - Fixed alert in case of missing pdftops; fixed code indentation
    3231
    33     % Call pdftops
    34     [varargout{1:nargout}] = system(sprintf('"%s" %s', xpdf_path, cmd));
     32% Call pdftops
     33[varargout{1:nargout}] = system(sprintf('"%s" %s', xpdf_path, cmd));
    3534end
    3635
    3736function 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
     39path_ = user_string('pdftops');
     40% Check the path works
     41if check_xpdf_path(path_)
     42    return
     43end
     44% Check whether the binary is on the path
     45if ispc
     46    bin = 'pdftops.exe';
     47else
     48    bin = 'pdftops';
     49end
     50if check_store_xpdf_path(bin)
     51    path_ = bin;
     52    return
     53end
     54% Search the obvious places
     55if ispc
     56    path_ = 'C:\Program Files\xpdf\pdftops.exe';
     57else
     58    path_ = '/usr/local/bin/pdftops';
     59end
     60if check_store_xpdf_path(path_)
     61    return
     62end
     63% Ask the user to enter the path
     64while 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/.'))
    4469    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;
    5074    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
    6082    end
    6183    if check_store_xpdf_path(path_)
    6284        return
    6385    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.');
     86end
     87error('pdftops executable not found.');
    9288end
    9389
    9490function good = check_store_xpdf_path(path_)
    95     % Check the path is valid
    96     good = check_xpdf_path(path_);
    97     if ~good
    98         return
    99     end
    100     % Update the current default path to the path found
    101     if ~user_string('pdftops', path_)
    102         warning('Path to pdftops executable could not be saved. Enter it manually in %s.', fullfile(fileparts(which('user_string.m')), '.ignore', 'pdftops.txt'));
    103         return
    104     end
     91% Check the path is valid
     92good = check_xpdf_path(path_);
     93if ~good
     94    return
     95end
     96% Update the current default path to the path found
     97if ~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
     100end
    105101end
    106102
    107103function good = check_xpdf_path(path_)
    108     % Check the path is valid
    109     [good, message] = system(sprintf('"%s" -h', path_)); %#ok<ASGLU>
    110     % system returns good = 1 even when the command runs
    111     % Look for something distinct in the help text
    112     good = ~isempty(strfind(message, 'PostScript'));
     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
     108good = ~isempty(strfind(message, 'PostScript'));
    113109end
  • issm/trunk-jpl/externalpackages/export_fig/print2array.m

    r19571 r19993  
    1 function [A, bcol] = print2array(fig, res, renderer, gs_options)
    21%PRINT2ARRAY  Exports a figure to an image array
    32%
     
    76%   A = print2array(figure_handle, resolution)
    87%   A = print2array(figure_handle, resolution, renderer)
    9 %   A = print2array(figure_handle, resolution, renderer, gs_options)
    108%   [A bcol] = print2array(...)
    119%
     
    2220%   renderer - string containing the renderer paramater to be passed to
    2321%              print. Default: '-opengl'.
    24 %   gs_options - optional ghostscript options (e.g.: '-dNoOutputFonts'). If
    25 %                multiple options are needed, enclose in call array: {'-a','-b'}
    2622%
    2723% OUT:
     
    2925%   bcol - 1x3 uint8 vector of the background color
    3026
    31 % Copyright (C) Oliver Woodford 2008-2014, Yair Altman 2015-
    32 %{
     27% Copyright (C) Oliver Woodford 2008-2012
     28
    3329% 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.
    3938% 09/12/11: Pass font path to ghostscript.
    4039% 27/01/12: Bug fix affecting painters rendering tall figures. Thanks to
    4140%           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.
    4343% 26/10/12: Set PaperOrientation to portrait. Thanks to Michael Watts for
    4444%           reporting the issue.
    45 % 26/02/15: If temp dir is not writable, use the current folder for temp
    46 %           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 indentation
    50 % 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 HG1
    52 %}
    5345
    54     % Generate default input arguments, if needed
    55     if nargin < 2
    56         res = 1;
    57         if nargin < 1
    58             fig = gcf;
     46function [A, bcol] = print2array(fig, res, renderer)
     47% Generate default input arguments, if needed
     48if nargin < 2
     49    res = 1;
     50    if nargin < 1
     51        fig = gcf;
     52    end
     53end
     54% Warn if output is large
     55old_mode = get(fig, 'Units');
     56set(fig, 'Units', 'pixels');
     57px = get(fig, 'Position');
     58set(fig, 'Units', old_mode);
     59npx = prod(px(3:4)*res)/1e6;
     60if 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);
     63end
     64% Retrieve the background colour
     65bcol = get(fig, 'Color');
     66% Set the resolution parameter
     67res_str = ['-r' num2str(ceil(get(0, 'ScreenPixelsPerInch')*res))];
     68% Generate temporary file name
     69tmp_nam = [tempname '.tif'];
     70if 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);
    59127        end
    60128    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);
     129else
     130    if nargin < 3
     131        renderer = '-opengl';
    70132    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');
    77138    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;
    90147    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);
    97161        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,:));
    210163        end
    211164    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 size
    217             A = A(1:min(end,px(1)),1:min(end,px(2)),:);
    218         end
     165end
     166% Check the output size is correct
     167if 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)),:);
    219172    end
     173end
    220174end
    221175
    222176% Function to return (and create, where necessary) the font path
    223177function fp = font_path()
    224     fp = user_string('gs_font_path');
     178fp = user_string('gs_font_path');
     179if ~isempty(fp)
     180    return
     181end
     182% Create the path
     183% Start with the default path
     184fp = getenv('GS_FONTPATH');
     185% Add on the typical directories for a given OS
     186if ispc
    225187    if ~isempty(fp)
    226         return
     188        fp = [fp ';'];
    227189    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'];
     191else
     192    if ~isempty(fp)
     193        fp = [fp ':'];
    242194    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'];
    244196end
     197user_string('gs_font_path', fp);
     198end
  • issm/trunk-jpl/externalpackages/export_fig/print2eps.m

    r19571 r19993  
    1 function print2eps(name, fig, export_options, varargin)
    21%PRINT2EPS  Prints figures to eps with improved line styles
    32%
     
    54%   print2eps filename
    65%   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)
    98%
    109% This function saves a figure as an eps file, with two improvements over
    1110% 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.
    1515%
    1616%IN:
     
    2020%              not specified, the figure is saved in the current directory.
    2121%   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
    3228
    3329% The idea of editing the EPS file to change line styles comes from Jiro
     
    3531% The idea of changing dash length with line width came from comments on
    3632% 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.
    4237% 08/12/11: Added ability to correct fonts. Several people have requested
    4338%           this at one time or another, and also pointed me to printeps
     
    6358% 13/08/13: Fix MATLAB feature of not exporting white lines correctly.
    6459%           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
     61function print2eps(name, fig, bb_padding, varargin)
     62options = {'-depsc2'};
     63if nargin > 3
     64    options = [options varargin];
     65elseif nargin < 3
     66    bb_padding = 0;
     67    if nargin < 2
     68        fig = gcf();
     69    end
     70end
     71% Construct the filename
     72if numel(name) < 5 || ~strcmpi(name(end-3:end), '.eps')
     73    name = [name '.eps']; % Add the missing extension
     74end
     75% Set paper size
     76old_pos_mode = get(fig, 'PaperPositionMode');
     77old_orientation = get(fig, 'PaperOrientation');
     78set(fig, 'PaperPositionMode', 'auto', 'PaperOrientation', 'portrait');
     79% Find all the used fonts in the figure
     80font_handles = findall(fig, '-property', 'FontName');
     81fonts = get(font_handles, 'FontName');
     82if ~iscell(fonts)
     83    fonts = {fonts};
     84end
     85% Map supported font aliases onto the correct name
     86fontsl = lower(fonts);
     87for 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
     99end
     100fontslu = unique(fontsl);
     101% Determine the font swap table
     102matlab_fonts = {'Helvetica', 'Times-Roman', 'Palatino', 'Bookman', 'Helvetica-Narrow', 'Symbol', ...
     103                'AvantGarde', 'NewCenturySchlbk', 'Courier', 'ZapfChancery', 'ZapfDingbats'};
     104matlab_fontsl = lower(matlab_fonts);
     105require_swap = find(~ismember(fontslu, matlab_fontsl));
     106unused_fonts = find(~ismember(matlab_fontsl, fontslu));
     107font_swap = cell(3, min(numel(require_swap), numel(unused_fonts)));
     108fonts_new = fonts;
     109for 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}};
     114end
     115% Swap the fonts
     116if ~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;
    186132            end
    187133        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;
    224136        end
    225137    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, []);
     142end
     143% MATLAB bug fix - black and white text can come out inverted sometimes
     144% Find the white and black text
     145white_text_handles = findobj(fig, 'Type', 'text');
     146M = get(white_text_handles, 'Color');
     147if iscell(M)
     148    M = cell2mat(M);
     149end
     150M = sum(M, 2);
     151black_text_handles = white_text_handles(M == 0);
     152white_text_handles = white_text_handles(M == 3);
     153% Set the font colors slightly off their correct values
     154set(black_text_handles, 'Color', [0 0 0] + eps);
     155set(white_text_handles, 'Color', [1 1 1] - eps);
     156% MATLAB bug fix - white lines can come out funny sometimes
     157% Find the white lines
     158white_line_handles = findobj(fig, 'Type', 'line');
     159M = get(white_line_handles, 'Color');
     160if iscell(M)
     161    M = cell2mat(M);
     162end
     163white_line_handles = white_line_handles(sum(M, 2) == 3);
     164% Set the line color slightly off white
     165set(white_line_handles, 'Color', [1 1 1] - 0.00001);
     166% Print to eps file
     167print(fig, options{:}, name);
     168% Reset the font and line colors
     169set(black_text_handles, 'Color', [0 0 0]);
     170set(white_text_handles, 'Color', [1 1 1]);
     171set(white_line_handles, 'Color', [1 1 1]);
     172% Reset paper size
     173set(fig, 'PaperPositionMode', old_pos_mode, 'PaperOrientation', old_orientation);
     174% Reset the font names in the figure
     175if ~isempty(font_swap)
     176    for a = update
     177        set(font_handles(a), 'FontName', fonts{a}, 'FontSize', fonts_size(a));
     178    end
     179end
     180% Do post-processing on the eps file
     181try
     182    fstrm = read_write_entire_textfile(name);
     183catch
     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
     186end
     187% Replace the font names
     188if ~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
     193end
     194if 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
     202else
     203    % Fix the line styles
     204    fstrm = fix_lines(fstrm);
     205end
     206% Apply the bounding box padding
     207if 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)}');
     210end
     211% Write out the fixed eps file
     212read_write_entire_textfile(name, fstrm);
     213end
  • issm/trunk-jpl/externalpackages/export_fig/user_string.m

    r19571 r19993  
    1 function string = user_string(string_name, string)
    21%USER_STRING  Get/set a user specific string
    32%
    43% Examples:
    5 %   string  = user_string(string_name)
    6 %   isSaved = user_string(string_name, new_string)
     4%   string = user_string(string_name)
     5%   saved = user_string(string_name, new_string)
    76%
    87% Function to get and set a string in a system or user specific file. This
    98% enables, for example, system specific paths to binaries to be saved.
    109%
    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 the
    13 % user's prefdir folder (in case this file's folder is non-writable).
    14 %
    1510% 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.
    1916%
    2017% OUT:
    21 %   string  - The currently saved string. Default: ''
    22 %   isSaved - Boolean indicating whether the save was succesful
     18%   string - The currently saved string. Default: ''.
     19%   saved - Boolean indicating whether the save was succesful
    2320
    24 % Copyright (C) Oliver Woodford 2011-2014, Yair Altman 2015-
     21% Copyright (C) Oliver Woodford 2011-2013
    2522
    2623% This method of saving paths avoids changing .m files which might be in a
     
    3128
    3229% 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.
    3531
    36     if ~ischar(string_name)
    37         error('string_name must be a string.');
     32function string = user_string(string_name, string)
     33if ~ischar(string_name)
     34    error('string_name must be a string.');
     35end
     36% Create the full filename
     37string_name = fullfile(fileparts(mfilename('fullpath')), '.ignore', [string_name '.txt']);
     38if nargin > 1
     39    % Set string
     40    if ~ischar(string)
     41        error('new_string must be a string.');
    3842    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)               
    5849                string = false;
    5950                return
    6051            end
    61             % Make it hidden
    62             try
    63                 fileattrib(dname, '+h');
    64             catch
    65             end
    66         end
    67         % Write the file
    68         fid = fopen(file_name, 'wt');
    69         if fid == -1
    70             % file cannot be created/updated - use prefdir if file does not already exist
    71             % (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             end
    76             if fid == -1
    77                 string = false;
    78                 return;
    79             end
    80         end
    81         try
    82             fprintf(fid, '%s', string);
    8352        catch
    84             fclose(fid);
    8553            string = false;
    8654            return
    8755        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
    8871        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
    10474    end
     75    fclose(fid);
     76    string = true;
     77else
     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);
    10586end
     87end
  • issm/trunk-jpl/externalpackages/export_fig/using_hg2.m

    r19571 r19993  
    1 %USING_HG2 Determine if the HG2 graphics engine is used
     1%USING_HG2 Determine if the HG2 graphics pipeline is used
    22%
    33%   tf = using_hg2(fig)
     
    77%
    88%OUT:
    9 %   tf - boolean indicating whether the HG2 graphics engine is being used
     9%   tf - boolean indicating whether the HG2 graphics pipeline is being used
    1010%        (true) or not (false).
    1111
    12 % 19/06/2015 - Suppress warning in R2015b; cache result for improved performance
    13 
    1412function 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
     13try
     14    tf = ~graphicsversion(fig, 'handlegraphics');
     15catch
     16    tf = false;
    3517end
     18end
Note: See TracChangeset for help on using the changeset viewer.