[21337] | 1 | Index: ../trunk-jpl/externalpackages/export_fig/append_pdfs.m
|
---|
| 2 | ===================================================================
|
---|
| 3 | --- ../trunk-jpl/externalpackages/export_fig/append_pdfs.m (revision 21314)
|
---|
| 4 | +++ ../trunk-jpl/externalpackages/export_fig/append_pdfs.m (revision 21315)
|
---|
| 5 | @@ -32,17 +32,40 @@
|
---|
| 6 | % Issue resolved (to best of my ability) 1/6/2011, using the prepress
|
---|
| 7 | % setting
|
---|
| 8 |
|
---|
| 9 | +% 26/02/15: If temp dir is not writable, use the output folder for temp
|
---|
| 10 | +% files when appending (Javier Paredes); sanity check of inputs
|
---|
| 11 | +
|
---|
| 12 | function append_pdfs(varargin)
|
---|
| 13 | +
|
---|
| 14 | +if nargin < 2, return; end % sanity check
|
---|
| 15 | +
|
---|
| 16 | % Are we appending or creating a new file
|
---|
| 17 | append = exist(varargin{1}, 'file') == 2;
|
---|
| 18 | -if append
|
---|
| 19 | - output = [tempname '.pdf'];
|
---|
| 20 | -else
|
---|
| 21 | +output = [tempname '.pdf'];
|
---|
| 22 | +try
|
---|
| 23 | + % Ensure that the temp dir is writable (Javier Paredes 26/2/15)
|
---|
| 24 | + fid = fopen(output,'w');
|
---|
| 25 | + fwrite(fid,1);
|
---|
| 26 | + fclose(fid);
|
---|
| 27 | + delete(output);
|
---|
| 28 | + isTempDirOk = true;
|
---|
| 29 | +catch
|
---|
| 30 | + % Temp dir is not writable, so use the output folder
|
---|
| 31 | + [dummy,fname,fext] = fileparts(output); %#ok<ASGLU>
|
---|
| 32 | + fpath = fileparts(varargin{1});
|
---|
| 33 | + output = fullfile(fpath,[fname fext]);
|
---|
| 34 | + isTempDirOk = false;
|
---|
| 35 | +end
|
---|
| 36 | +if ~append
|
---|
| 37 | output = varargin{1};
|
---|
| 38 | varargin = varargin(2:end);
|
---|
| 39 | end
|
---|
| 40 | % Create the command file
|
---|
| 41 | -cmdfile = [tempname '.txt'];
|
---|
| 42 | +if isTempDirOk
|
---|
| 43 | + cmdfile = [tempname '.txt'];
|
---|
| 44 | +else
|
---|
| 45 | + cmdfile = fullfile(fpath,[fname '.txt']);
|
---|
| 46 | +end
|
---|
| 47 | fh = fopen(cmdfile, 'w');
|
---|
| 48 | fprintf(fh, '-q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sOutputFile="%s" -f', output);
|
---|
| 49 | fprintf(fh, ' "%s"', varargin{:});
|
---|
| 50 | Index: ../trunk-jpl/externalpackages/export_fig/crop_borders.m
|
---|
| 51 | ===================================================================
|
---|
| 52 | --- ../trunk-jpl/externalpackages/export_fig/crop_borders.m (revision 21314)
|
---|
| 53 | +++ ../trunk-jpl/externalpackages/export_fig/crop_borders.m (revision 21315)
|
---|
| 54 | @@ -1,81 +1,157 @@
|
---|
| 55 | +function [A, vA, vB, bb_rel] = crop_borders(A, bcol, padding, crop_amounts)
|
---|
| 56 | %CROP_BORDERS Crop the borders of an image or stack of images
|
---|
| 57 | %
|
---|
| 58 | -% [B, v] = crop_borders(A, bcol, [padding])
|
---|
| 59 | +% [B, vA, vB, bb_rel] = crop_borders(A, bcol, [padding])
|
---|
| 60 | %
|
---|
| 61 | %IN:
|
---|
| 62 | % A - HxWxCxN stack of images.
|
---|
| 63 | % bcol - Cx1 background colour vector.
|
---|
| 64 | -% padding - scalar indicating how many pixels padding to have. Default: 0.
|
---|
| 65 | +% padding - scalar indicating how much padding to have in relation to
|
---|
| 66 | +% the cropped-image-size (0<=padding<=1). Default: 0
|
---|
| 67 | +% crop_amounts - 4-element vector of crop amounts: [top,right,bottom,left]
|
---|
| 68 | +% where NaN/Inf indicate auto-cropping, 0 means no cropping,
|
---|
| 69 | +% and any other value mean cropping in pixel amounts.
|
---|
| 70 | %
|
---|
| 71 | %OUT:
|
---|
| 72 | % B - JxKxCxN cropped stack of images.
|
---|
| 73 | -% v - 1x4 vector of start and end indices for first two dimensions, s.t.
|
---|
| 74 | -% B = A(v(1):v(2),v(3):v(4),:,:).
|
---|
| 75 | +% vA - coordinates in A that contain the cropped image
|
---|
| 76 | +% vB - coordinates in B where the cropped version of A is placed
|
---|
| 77 | +% bb_rel - relative bounding box (used for eps-cropping)
|
---|
| 78 |
|
---|
| 79 | -function [A, v] = crop_borders(A, bcol, padding)
|
---|
| 80 | -if nargin < 3
|
---|
| 81 | - padding = 0;
|
---|
| 82 | -end
|
---|
| 83 | -[h, w, c, n] = size(A);
|
---|
| 84 | -if isscalar(bcol)
|
---|
| 85 | - bcol = bcol(ones(c, 1));
|
---|
| 86 | -end
|
---|
| 87 | -bail = false;
|
---|
| 88 | -for l = 1:w
|
---|
| 89 | - for a = 1:c
|
---|
| 90 | - if ~all(col(A(:,l,a,:)) == bcol(a))
|
---|
| 91 | - bail = true;
|
---|
| 92 | - break;
|
---|
| 93 | - end
|
---|
| 94 | +%{
|
---|
| 95 | +% 06/03/15: Improved image cropping thanks to Oscar Hartogensis
|
---|
| 96 | +% 08/06/15: Fixed issue #76: case of transparent figure bgcolor
|
---|
| 97 | +% 21/02/16: Enabled specifying non-automated crop amounts
|
---|
| 98 | +% 04/04/16: Fix per Luiz Carvalho for old Matlab releases
|
---|
| 99 | +% 23/10/16: Fixed issue #175: there used to be a 1px minimal padding in case of crop, now removed
|
---|
| 100 | +%}
|
---|
| 101 | +
|
---|
| 102 | + if nargin < 3
|
---|
| 103 | + padding = 0;
|
---|
| 104 | end
|
---|
| 105 | - if bail
|
---|
| 106 | - break;
|
---|
| 107 | + if nargin < 4
|
---|
| 108 | + crop_amounts = nan(1,4); % =auto-cropping
|
---|
| 109 | end
|
---|
| 110 | -end
|
---|
| 111 | -bcol = A(ceil(end/2),w,:,1);
|
---|
| 112 | -bail = false;
|
---|
| 113 | -for r = w:-1:l
|
---|
| 114 | - for a = 1:c
|
---|
| 115 | - if ~all(col(A(:,r,a,:)) == bcol(a))
|
---|
| 116 | - bail = true;
|
---|
| 117 | - break;
|
---|
| 118 | + crop_amounts(end+1:4) = NaN; % fill missing values with NaN
|
---|
| 119 | +
|
---|
| 120 | + [h, w, c, n] = size(A);
|
---|
| 121 | + if isempty(bcol) % case of transparent bgcolor
|
---|
| 122 | + bcol = A(ceil(end/2),1,:,1);
|
---|
| 123 | + end
|
---|
| 124 | + if isscalar(bcol)
|
---|
| 125 | + bcol = bcol(ones(c, 1));
|
---|
| 126 | + end
|
---|
| 127 | +
|
---|
| 128 | + % Crop margin from left
|
---|
| 129 | + if ~isfinite(crop_amounts(4))
|
---|
| 130 | + bail = false;
|
---|
| 131 | + for l = 1:w
|
---|
| 132 | + for a = 1:c
|
---|
| 133 | + if ~all(col(A(:,l,a,:)) == bcol(a))
|
---|
| 134 | + bail = true;
|
---|
| 135 | + break;
|
---|
| 136 | + end
|
---|
| 137 | + end
|
---|
| 138 | + if bail
|
---|
| 139 | + break;
|
---|
| 140 | + end
|
---|
| 141 | end
|
---|
| 142 | + else
|
---|
| 143 | + l = 1 + abs(crop_amounts(4));
|
---|
| 144 | end
|
---|
| 145 | - if bail
|
---|
| 146 | - break;
|
---|
| 147 | +
|
---|
| 148 | + % Crop margin from right
|
---|
| 149 | + if ~isfinite(crop_amounts(2))
|
---|
| 150 | + bcol = A(ceil(end/2),w,:,1);
|
---|
| 151 | + bail = false;
|
---|
| 152 | + for r = w:-1:l
|
---|
| 153 | + for a = 1:c
|
---|
| 154 | + if ~all(col(A(:,r,a,:)) == bcol(a))
|
---|
| 155 | + bail = true;
|
---|
| 156 | + break;
|
---|
| 157 | + end
|
---|
| 158 | + end
|
---|
| 159 | + if bail
|
---|
| 160 | + break;
|
---|
| 161 | + end
|
---|
| 162 | + end
|
---|
| 163 | + else
|
---|
| 164 | + r = w - abs(crop_amounts(2));
|
---|
| 165 | end
|
---|
| 166 | -end
|
---|
| 167 | -bcol = A(1,ceil(end/2),:,1);
|
---|
| 168 | -bail = false;
|
---|
| 169 | -for t = 1:h
|
---|
| 170 | - for a = 1:c
|
---|
| 171 | - if ~all(col(A(t,:,a,:)) == bcol(a))
|
---|
| 172 | - bail = true;
|
---|
| 173 | - break;
|
---|
| 174 | +
|
---|
| 175 | + % Crop margin from top
|
---|
| 176 | + if ~isfinite(crop_amounts(1))
|
---|
| 177 | + bcol = A(1,ceil(end/2),:,1);
|
---|
| 178 | + bail = false;
|
---|
| 179 | + for t = 1:h
|
---|
| 180 | + for a = 1:c
|
---|
| 181 | + if ~all(col(A(t,:,a,:)) == bcol(a))
|
---|
| 182 | + bail = true;
|
---|
| 183 | + break;
|
---|
| 184 | + end
|
---|
| 185 | + end
|
---|
| 186 | + if bail
|
---|
| 187 | + break;
|
---|
| 188 | + end
|
---|
| 189 | end
|
---|
| 190 | + else
|
---|
| 191 | + t = 1 + abs(crop_amounts(1));
|
---|
| 192 | end
|
---|
| 193 | - if bail
|
---|
| 194 | - break;
|
---|
| 195 | +
|
---|
| 196 | + % Crop margin from bottom
|
---|
| 197 | + bcol = A(h,ceil(end/2),:,1);
|
---|
| 198 | + if ~isfinite(crop_amounts(3))
|
---|
| 199 | + bail = false;
|
---|
| 200 | + for b = h:-1:t
|
---|
| 201 | + for a = 1:c
|
---|
| 202 | + if ~all(col(A(b,:,a,:)) == bcol(a))
|
---|
| 203 | + bail = true;
|
---|
| 204 | + break;
|
---|
| 205 | + end
|
---|
| 206 | + end
|
---|
| 207 | + if bail
|
---|
| 208 | + break;
|
---|
| 209 | + end
|
---|
| 210 | + end
|
---|
| 211 | + else
|
---|
| 212 | + b = h - abs(crop_amounts(3));
|
---|
| 213 | end
|
---|
| 214 | -end
|
---|
| 215 | -bcol = A(h,ceil(end/2),:,1);
|
---|
| 216 | -bail = false;
|
---|
| 217 | -for b = h:-1:t
|
---|
| 218 | - for a = 1:c
|
---|
| 219 | - if ~all(col(A(b,:,a,:)) == bcol(a))
|
---|
| 220 | - bail = true;
|
---|
| 221 | - break;
|
---|
| 222 | +
|
---|
| 223 | + if padding == 0 % no padding
|
---|
| 224 | + % Issue #175: there used to be a 1px minimal padding in case of crop, now removed
|
---|
| 225 | + %{
|
---|
| 226 | + if ~isequal([t b l r], [1 h 1 w]) % Check if we're actually croppping
|
---|
| 227 | + padding = 1; % Leave one boundary pixel to avoid bleeding on resize
|
---|
| 228 | + bcol(:) = nan; % make the 1px padding transparent
|
---|
| 229 | end
|
---|
| 230 | + %}
|
---|
| 231 | + elseif abs(padding) < 1 % pad value is a relative fraction of image size
|
---|
| 232 | + padding = sign(padding)*round(mean([b-t r-l])*abs(padding)); % ADJUST PADDING
|
---|
| 233 | + else % pad value is in units of 1/72" points
|
---|
| 234 | + padding = round(padding); % fix cases of non-integer pad value
|
---|
| 235 | end
|
---|
| 236 | - if bail
|
---|
| 237 | - break;
|
---|
| 238 | +
|
---|
| 239 | + if padding > 0 % extra padding
|
---|
| 240 | + % Create an empty image, containing the background color, that has the
|
---|
| 241 | + % cropped image size plus the padded border
|
---|
| 242 | + B = repmat(bcol,[(b-t)+1+padding*2,(r-l)+1+padding*2,1,n]); % Fix per Luiz Carvalho
|
---|
| 243 | + % vA - coordinates in A that contain the cropped image
|
---|
| 244 | + vA = [t b l r];
|
---|
| 245 | + % vB - coordinates in B where the cropped version of A will be placed
|
---|
| 246 | + vB = [padding+1, (b-t)+1+padding, padding+1, (r-l)+1+padding];
|
---|
| 247 | + % Place the original image in the empty image
|
---|
| 248 | + B(vB(1):vB(2), vB(3):vB(4), :, :) = A(vA(1):vA(2), vA(3):vA(4), :, :);
|
---|
| 249 | + A = B;
|
---|
| 250 | + else % extra cropping
|
---|
| 251 | + vA = [t-padding b+padding l-padding r+padding];
|
---|
| 252 | + A = A(vA(1):vA(2), vA(3):vA(4), :, :);
|
---|
| 253 | + vB = [NaN NaN NaN NaN];
|
---|
| 254 | end
|
---|
| 255 | +
|
---|
| 256 | + % For EPS cropping, determine the relative BoundingBox - bb_rel
|
---|
| 257 | + bb_rel = [l-1 h-b-1 r+1 h-t+1]./[w h w h];
|
---|
| 258 | end
|
---|
| 259 | -% Crop the background, leaving one boundary pixel to avoid bleeding on resize
|
---|
| 260 | -v = [max(t-padding, 1) min(b+padding, h) max(l-padding, 1) min(r+padding, w)];
|
---|
| 261 | -A = A(v(1):v(2),v(3):v(4),:,:);
|
---|
| 262 | -end
|
---|
| 263 |
|
---|
| 264 | function A = col(A)
|
---|
| 265 | -A = A(:);
|
---|
| 266 | + A = A(:);
|
---|
| 267 | end
|
---|
| 268 | Index: ../trunk-jpl/externalpackages/export_fig/using_hg2.m
|
---|
| 269 | ===================================================================
|
---|
| 270 | --- ../trunk-jpl/externalpackages/export_fig/using_hg2.m (revision 21314)
|
---|
| 271 | +++ ../trunk-jpl/externalpackages/export_fig/using_hg2.m (revision 21315)
|
---|
| 272 | @@ -1,4 +1,4 @@
|
---|
| 273 | -%USING_HG2 Determine if the HG2 graphics pipeline is used
|
---|
| 274 | +%USING_HG2 Determine if the HG2 graphics engine is used
|
---|
| 275 | %
|
---|
| 276 | % tf = using_hg2(fig)
|
---|
| 277 | %
|
---|
| 278 | @@ -6,13 +6,31 @@
|
---|
| 279 | % fig - handle to the figure in question.
|
---|
| 280 | %
|
---|
| 281 | %OUT:
|
---|
| 282 | -% tf - boolean indicating whether the HG2 graphics pipeline is being used
|
---|
| 283 | +% tf - boolean indicating whether the HG2 graphics engine is being used
|
---|
| 284 | % (true) or not (false).
|
---|
| 285 |
|
---|
| 286 | +% 19/06/2015 - Suppress warning in R2015b; cache result for improved performance
|
---|
| 287 | +% 06/06/2016 - Fixed issue #156 (bad return value in R2016b)
|
---|
| 288 | +
|
---|
| 289 | function tf = using_hg2(fig)
|
---|
| 290 | -try
|
---|
| 291 | - tf = ~graphicsversion(fig, 'handlegraphics');
|
---|
| 292 | -catch
|
---|
| 293 | - tf = false;
|
---|
| 294 | + persistent tf_cached
|
---|
| 295 | + if isempty(tf_cached)
|
---|
| 296 | + try
|
---|
| 297 | + if nargin < 1, fig = figure('visible','off'); end
|
---|
| 298 | + oldWarn = warning('off','MATLAB:graphicsversion:GraphicsVersionRemoval');
|
---|
| 299 | + try
|
---|
| 300 | + % This generates a [supressed] warning in R2015b:
|
---|
| 301 | + tf = ~graphicsversion(fig, 'handlegraphics');
|
---|
| 302 | + catch
|
---|
| 303 | + tf = ~verLessThan('matlab','8.4'); % =R2014b
|
---|
| 304 | + end
|
---|
| 305 | + warning(oldWarn);
|
---|
| 306 | + catch
|
---|
| 307 | + tf = false;
|
---|
| 308 | + end
|
---|
| 309 | + if nargin < 1, delete(fig); end
|
---|
| 310 | + tf_cached = tf;
|
---|
| 311 | + else
|
---|
| 312 | + tf = tf_cached;
|
---|
| 313 | + end
|
---|
| 314 | end
|
---|
| 315 | -end
|
---|
| 316 | Index: ../trunk-jpl/externalpackages/export_fig/print2eps.m
|
---|
| 317 | ===================================================================
|
---|
| 318 | --- ../trunk-jpl/externalpackages/export_fig/print2eps.m (revision 21314)
|
---|
| 319 | +++ ../trunk-jpl/externalpackages/export_fig/print2eps.m (revision 21315)
|
---|
| 320 | @@ -1,3 +1,4 @@
|
---|
| 321 | +function print2eps(name, fig, export_options, varargin)
|
---|
| 322 | %PRINT2EPS Prints figures to eps with improved line styles
|
---|
| 323 | %
|
---|
| 324 | % Examples:
|
---|
| 325 | @@ -3,13 +4,12 @@
|
---|
| 326 | % print2eps filename
|
---|
| 327 | % print2eps(filename, fig_handle)
|
---|
| 328 | -% print2eps(filename, fig_handle, bb_padding)
|
---|
| 329 | -% print2eps(filename, fig_handle, bb_padding, options)
|
---|
| 330 | +% print2eps(filename, fig_handle, export_options)
|
---|
| 331 | +% print2eps(filename, fig_handle, export_options, print_options)
|
---|
| 332 | %
|
---|
| 333 | % This function saves a figure as an eps file, with two improvements over
|
---|
| 334 | % MATLAB's print command. First, it improves the line style, making dashed
|
---|
| 335 | -% lines more like those on screen and giving grid lines their own dotted
|
---|
| 336 | -% style. Secondly, it substitutes original font names back into the eps
|
---|
| 337 | -% file, where these have been changed by MATLAB, for up to 11 different
|
---|
| 338 | -% fonts.
|
---|
| 339 | +% lines more like those on screen and giving grid lines a dotted line style.
|
---|
| 340 | +% Secondly, it substitutes original font names back into the eps file,
|
---|
| 341 | +% where these have been changed by MATLAB, for up to 11 different fonts.
|
---|
| 342 | %
|
---|
| 343 | %IN:
|
---|
| 344 | @@ -19,21 +19,29 @@
|
---|
| 345 | % ".eps" extension is added if not there already. If a path is
|
---|
| 346 | % not specified, the figure is saved in the current directory.
|
---|
| 347 | % fig_handle - The handle of the figure to be saved. Default: gcf().
|
---|
| 348 | -% bb_padding - Scalar value of amount of padding to add to border around
|
---|
| 349 | -% the figure, in points. Can be negative as well as
|
---|
| 350 | -% positive. Default: 0.
|
---|
| 351 | -% options - Additional parameter strings to be passed to print.
|
---|
| 352 | +% export_options - array or struct of optional scalar values:
|
---|
| 353 | +% bb_padding - Scalar value of amount of padding to add to border around
|
---|
| 354 | +% the cropped image, in points (if >1) or percent (if <1).
|
---|
| 355 | +% Can be negative as well as positive; Default: 0
|
---|
| 356 | +% crop - Cropping flag. Deafult: 0
|
---|
| 357 | +% fontswap - Whether to swap non-default fonts in figure. Default: true
|
---|
| 358 | +% renderer - Renderer used to generate bounding-box. Default: 'opengl'
|
---|
| 359 | +% crop_amounts - 4-element vector of crop amounts: [top,right,bottom,left]
|
---|
| 360 | +% (available only via the struct alternative)
|
---|
| 361 | +% print_options - Additional parameter strings to be passed to the print command
|
---|
| 362 |
|
---|
| 363 | -% Copyright (C) Oliver Woodford 2008-2014
|
---|
| 364 | +%{
|
---|
| 365 | +% Copyright (C) Oliver Woodford 2008-2014, Yair Altman 2015-
|
---|
| 366 |
|
---|
| 367 | % The idea of editing the EPS file to change line styles comes from Jiro
|
---|
| 368 | % Doke's FIXPSLINESTYLE (fex id: 17928)
|
---|
| 369 | % The idea of changing dash length with line width came from comments on
|
---|
| 370 | % fex id: 5743, but the implementation is mine :)
|
---|
| 371 | -
|
---|
| 372 | -% 14/11/2011: Fix a MATLAB bug rendering black or white text incorrectly.
|
---|
| 373 | -% Thanks to Mathieu Morlighem for reporting the issue and
|
---|
| 374 | -% obtaining a fix from TMW.
|
---|
| 375 | +%}
|
---|
| 376 | +%{
|
---|
| 377 | +% 14/11/11: Fix a MATLAB bug rendering black or white text incorrectly.
|
---|
| 378 | +% Thanks to Mathieu Morlighem for reporting the issue and
|
---|
| 379 | +% obtaining a fix from TMW.
|
---|
| 380 | % 08/12/11: Added ability to correct fonts. Several people have requested
|
---|
| 381 | % this at one time or another, and also pointed me to printeps
|
---|
| 382 | % (fex id: 7501), so thank you to them. My implementation (which
|
---|
| 383 | @@ -56,158 +64,466 @@
|
---|
| 384 | % 23/07/13: Bug fix to font swapping. Thanks to George for reporting the
|
---|
| 385 | % issue.
|
---|
| 386 | % 13/08/13: Fix MATLAB feature of not exporting white lines correctly.
|
---|
| 387 | -% Thanks to Sebastian Heßlinger for reporting it.
|
---|
| 388 | +% Thanks to Sebastian Hesslinger for reporting it.
|
---|
| 389 | +% 24/02/15: Fix for Matlab R2014b bug (issue #31): LineWidths<0.75 are not
|
---|
| 390 | +% set in the EPS (default line width is used)
|
---|
| 391 | +% 25/02/15: Fixed issue #32: BoundingBox problem caused uncropped EPS/PDF files
|
---|
| 392 | +% 05/03/15: Fixed issue #43: Inability to perform EPS file post-processing
|
---|
| 393 | +% 06/03/15: Improved image padding & cropping thanks to Oscar Hartogensis
|
---|
| 394 | +% 21/03/15: Fixed edge-case of missing handles having a 'FontName' property
|
---|
| 395 | +% 26/03/15: Attempt to fix issue #45: white lines in subplots do not print correctly
|
---|
| 396 | +% 27/03/15: Attempt to fix issue #44: white artifact lines appearing in patch exports
|
---|
| 397 | +% 30/03/15: Fixed issue #52: improved performance on HG2 (R2014b+)
|
---|
| 398 | +% 09/04/15: Comment blocks consolidation and minor code cleanup (no real code change)
|
---|
| 399 | +% 12/04/15: Fixed issue #56: bad cropping
|
---|
| 400 | +% 14/04/15: Workaround for issue #45: lines in image subplots are exported in invalid color
|
---|
| 401 | +% 07/07/15: Added option to avoid font-swapping in EPS/PDF
|
---|
| 402 | +% 07/07/15: Fixed issue #83: use numeric handles in HG1
|
---|
| 403 | +% 22/07/15: Fixed issue #91 (thanks to Carlos Moffat)
|
---|
| 404 | +% 28/09/15: Fixed issue #108 (thanks to JacobD10)
|
---|
| 405 | +% 01/11/15: Fixed issue #112: optional renderer for bounding-box computation (thanks to Jesús Pestana Puerta)
|
---|
| 406 | +% 21/02/16: Enabled specifying non-automated crop amounts
|
---|
| 407 | +% 22/02/16: Better support + backward compatibility for transparency (issue #108)
|
---|
| 408 | +% 10/06/16: Fixed issue #159: text handles get cleared by Matlab in the print() command
|
---|
| 409 | +% 12/06/16: Improved the fix for issue #159 (in the previous commit)
|
---|
| 410 | +% 12/06/16: Fixed issue #158: transparent patch color in PDF/EPS
|
---|
| 411 | +%}
|
---|
| 412 |
|
---|
| 413 | -function print2eps(name, fig, bb_padding, varargin)
|
---|
| 414 | -options = {'-depsc2'};
|
---|
| 415 | -if nargin > 3
|
---|
| 416 | - options = [options varargin];
|
---|
| 417 | -elseif nargin < 3
|
---|
| 418 | - bb_padding = 0;
|
---|
| 419 | - if nargin < 2
|
---|
| 420 | - fig = gcf();
|
---|
| 421 | + options = {'-loose'};
|
---|
| 422 | + if nargin > 3
|
---|
| 423 | + options = [options varargin];
|
---|
| 424 | + elseif nargin < 3
|
---|
| 425 | + export_options = 0;
|
---|
| 426 | + if nargin < 2
|
---|
| 427 | + fig = gcf();
|
---|
| 428 | + end
|
---|
| 429 | end
|
---|
| 430 | -end
|
---|
| 431 | -% Construct the filename
|
---|
| 432 | -if numel(name) < 5 || ~strcmpi(name(end-3:end), '.eps')
|
---|
| 433 | - name = [name '.eps']; % Add the missing extension
|
---|
| 434 | -end
|
---|
| 435 | -% Set paper size
|
---|
| 436 | -old_pos_mode = get(fig, 'PaperPositionMode');
|
---|
| 437 | -old_orientation = get(fig, 'PaperOrientation');
|
---|
| 438 | -set(fig, 'PaperPositionMode', 'auto', 'PaperOrientation', 'portrait');
|
---|
| 439 | -% Find all the used fonts in the figure
|
---|
| 440 | -font_handles = findall(fig, '-property', 'FontName');
|
---|
| 441 | -fonts = get(font_handles, 'FontName');
|
---|
| 442 | -if ~iscell(fonts)
|
---|
| 443 | - fonts = {fonts};
|
---|
| 444 | -end
|
---|
| 445 | -% Map supported font aliases onto the correct name
|
---|
| 446 | -fontsl = lower(fonts);
|
---|
| 447 | -for a = 1:numel(fonts)
|
---|
| 448 | - f = fontsl{a};
|
---|
| 449 | - f(f==' ') = [];
|
---|
| 450 | - switch f
|
---|
| 451 | - case {'times', 'timesnewroman', 'times-roman'}
|
---|
| 452 | - fontsl{a} = 'times-roman';
|
---|
| 453 | - case {'arial', 'helvetica'}
|
---|
| 454 | - fontsl{a} = 'helvetica';
|
---|
| 455 | - case {'newcenturyschoolbook', 'newcenturyschlbk'}
|
---|
| 456 | - fontsl{a} = 'newcenturyschlbk';
|
---|
| 457 | - otherwise
|
---|
| 458 | +
|
---|
| 459 | + % Retrieve padding, crop & font-swap values
|
---|
| 460 | + crop_amounts = nan(1,4); % auto-crop all 4 sides by default
|
---|
| 461 | + if isstruct(export_options)
|
---|
| 462 | + try fontswap = export_options.fontswap; catch, fontswap = true; end
|
---|
| 463 | + try bb_crop = export_options.crop; catch, bb_crop = 0; end
|
---|
| 464 | + try crop_amounts = export_options.crop_amounts; catch, end
|
---|
| 465 | + try bb_padding = export_options.bb_padding; catch, bb_padding = 0; end
|
---|
| 466 | + try renderer = export_options.rendererStr; catch, renderer = 'opengl'; end % fix for issue #110
|
---|
| 467 | + if renderer(1)~='-', renderer = ['-' renderer]; end
|
---|
| 468 | + else
|
---|
| 469 | + if numel(export_options) > 2 % font-swapping
|
---|
| 470 | + fontswap = export_options(3);
|
---|
| 471 | + else
|
---|
| 472 | + fontswap = true;
|
---|
| 473 | + end
|
---|
| 474 | + if numel(export_options) > 1 % cropping
|
---|
| 475 | + bb_crop = export_options(2);
|
---|
| 476 | + else
|
---|
| 477 | + bb_crop = 0; % scalar value, so use default bb_crop value of 0
|
---|
| 478 | + end
|
---|
| 479 | + if numel(export_options) > 0 % padding
|
---|
| 480 | + bb_padding = export_options(1);
|
---|
| 481 | + else
|
---|
| 482 | + bb_padding = 0;
|
---|
| 483 | + end
|
---|
| 484 | + renderer = '-opengl';
|
---|
| 485 | end
|
---|
| 486 | -end
|
---|
| 487 | -fontslu = unique(fontsl);
|
---|
| 488 | -% Determine the font swap table
|
---|
| 489 | -matlab_fonts = {'Helvetica', 'Times-Roman', 'Palatino', 'Bookman', 'Helvetica-Narrow', 'Symbol', ...
|
---|
| 490 | - 'AvantGarde', 'NewCenturySchlbk', 'Courier', 'ZapfChancery', 'ZapfDingbats'};
|
---|
| 491 | -matlab_fontsl = lower(matlab_fonts);
|
---|
| 492 | -require_swap = find(~ismember(fontslu, matlab_fontsl));
|
---|
| 493 | -unused_fonts = find(~ismember(matlab_fontsl, fontslu));
|
---|
| 494 | -font_swap = cell(3, min(numel(require_swap), numel(unused_fonts)));
|
---|
| 495 | -fonts_new = fonts;
|
---|
| 496 | -for a = 1:size(font_swap, 2)
|
---|
| 497 | - font_swap{1,a} = find(strcmp(fontslu{require_swap(a)}, fontsl));
|
---|
| 498 | - font_swap{2,a} = matlab_fonts{unused_fonts(a)};
|
---|
| 499 | - font_swap{3,a} = fonts{font_swap{1,a}(1)};
|
---|
| 500 | - fonts_new(font_swap{1,a}) = {font_swap{2,a}};
|
---|
| 501 | -end
|
---|
| 502 | -% Swap the fonts
|
---|
| 503 | -if ~isempty(font_swap)
|
---|
| 504 | - fonts_size = get(font_handles, 'FontSize');
|
---|
| 505 | - if iscell(fonts_size)
|
---|
| 506 | - fonts_size = cell2mat(fonts_size);
|
---|
| 507 | +
|
---|
| 508 | + % Construct the filename
|
---|
| 509 | + if numel(name) < 5 || ~strcmpi(name(end-3:end), '.eps')
|
---|
| 510 | + name = [name '.eps']; % Add the missing extension
|
---|
| 511 | end
|
---|
| 512 | - M = false(size(font_handles));
|
---|
| 513 | - % Loop because some changes may not stick first time, due to listeners
|
---|
| 514 | - c = 0;
|
---|
| 515 | - update = zeros(1000, 1);
|
---|
| 516 | - for b = 1:10 % Limit number of loops to avoid infinite loop case
|
---|
| 517 | - for a = 1:numel(M)
|
---|
| 518 | - M(a) = ~isequal(get(font_handles(a), 'FontName'), fonts_new{a}) || ~isequal(get(font_handles(a), 'FontSize'), fonts_size(a));
|
---|
| 519 | - if M(a)
|
---|
| 520 | - set(font_handles(a), 'FontName', fonts_new{a}, 'FontSize', fonts_size(a));
|
---|
| 521 | - c = c + 1;
|
---|
| 522 | - update(c) = a;
|
---|
| 523 | +
|
---|
| 524 | + % Set paper size
|
---|
| 525 | + old_pos_mode = get(fig, 'PaperPositionMode');
|
---|
| 526 | + old_orientation = get(fig, 'PaperOrientation');
|
---|
| 527 | + set(fig, 'PaperPositionMode', 'auto', 'PaperOrientation', 'portrait');
|
---|
| 528 | +
|
---|
| 529 | + % Find all the used fonts in the figure
|
---|
| 530 | + font_handles = findall(fig, '-property', 'FontName');
|
---|
| 531 | + fonts = get(font_handles, 'FontName');
|
---|
| 532 | + if isempty(fonts)
|
---|
| 533 | + fonts = {};
|
---|
| 534 | + elseif ~iscell(fonts)
|
---|
| 535 | + fonts = {fonts};
|
---|
| 536 | + end
|
---|
| 537 | +
|
---|
| 538 | + % Map supported font aliases onto the correct name
|
---|
| 539 | + fontsl = lower(fonts);
|
---|
| 540 | + for a = 1:numel(fonts)
|
---|
| 541 | + f = fontsl{a};
|
---|
| 542 | + f(f==' ') = [];
|
---|
| 543 | + switch f
|
---|
| 544 | + case {'times', 'timesnewroman', 'times-roman'}
|
---|
| 545 | + fontsl{a} = 'times-roman';
|
---|
| 546 | + case {'arial', 'helvetica'}
|
---|
| 547 | + fontsl{a} = 'helvetica';
|
---|
| 548 | + case {'newcenturyschoolbook', 'newcenturyschlbk'}
|
---|
| 549 | + fontsl{a} = 'newcenturyschlbk';
|
---|
| 550 | + otherwise
|
---|
| 551 | + end
|
---|
| 552 | + end
|
---|
| 553 | + fontslu = unique(fontsl);
|
---|
| 554 | +
|
---|
| 555 | + % Determine the font swap table
|
---|
| 556 | + if fontswap
|
---|
| 557 | + matlab_fonts = {'Helvetica', 'Times-Roman', 'Palatino', 'Bookman', 'Helvetica-Narrow', 'Symbol', ...
|
---|
| 558 | + 'AvantGarde', 'NewCenturySchlbk', 'Courier', 'ZapfChancery', 'ZapfDingbats'};
|
---|
| 559 | + matlab_fontsl = lower(matlab_fonts);
|
---|
| 560 | + require_swap = find(~ismember(fontslu, matlab_fontsl));
|
---|
| 561 | + unused_fonts = find(~ismember(matlab_fontsl, fontslu));
|
---|
| 562 | + font_swap = cell(3, min(numel(require_swap), numel(unused_fonts)));
|
---|
| 563 | + fonts_new = fonts;
|
---|
| 564 | + for a = 1:size(font_swap, 2)
|
---|
| 565 | + font_swap{1,a} = find(strcmp(fontslu{require_swap(a)}, fontsl));
|
---|
| 566 | + font_swap{2,a} = matlab_fonts{unused_fonts(a)};
|
---|
| 567 | + font_swap{3,a} = fonts{font_swap{1,a}(1)};
|
---|
| 568 | + fonts_new(font_swap{1,a}) = font_swap(2,a);
|
---|
| 569 | + end
|
---|
| 570 | + else
|
---|
| 571 | + font_swap = [];
|
---|
| 572 | + end
|
---|
| 573 | +
|
---|
| 574 | + % Swap the fonts
|
---|
| 575 | + if ~isempty(font_swap)
|
---|
| 576 | + fonts_size = get(font_handles, 'FontSize');
|
---|
| 577 | + if iscell(fonts_size)
|
---|
| 578 | + fonts_size = cell2mat(fonts_size);
|
---|
| 579 | + end
|
---|
| 580 | + M = false(size(font_handles));
|
---|
| 581 | +
|
---|
| 582 | + % Loop because some changes may not stick first time, due to listeners
|
---|
| 583 | + c = 0;
|
---|
| 584 | + update = zeros(1000, 1);
|
---|
| 585 | + for b = 1:10 % Limit number of loops to avoid infinite loop case
|
---|
| 586 | + for a = 1:numel(M)
|
---|
| 587 | + M(a) = ~isequal(get(font_handles(a), 'FontName'), fonts_new{a}) || ~isequal(get(font_handles(a), 'FontSize'), fonts_size(a));
|
---|
| 588 | + if M(a)
|
---|
| 589 | + set(font_handles(a), 'FontName', fonts_new{a}, 'FontSize', fonts_size(a));
|
---|
| 590 | + c = c + 1;
|
---|
| 591 | + update(c) = a;
|
---|
| 592 | + end
|
---|
| 593 | end
|
---|
| 594 | + if ~any(M)
|
---|
| 595 | + break;
|
---|
| 596 | + end
|
---|
| 597 | end
|
---|
| 598 | - if ~any(M)
|
---|
| 599 | - break;
|
---|
| 600 | +
|
---|
| 601 | + % Compute the order to revert fonts later, without the need of a loop
|
---|
| 602 | + [update, M] = unique(update(1:c));
|
---|
| 603 | + [M, M] = sort(M);
|
---|
| 604 | + update = reshape(update(M), 1, []);
|
---|
| 605 | + end
|
---|
| 606 | +
|
---|
| 607 | + % MATLAB bug fix - black and white text can come out inverted sometimes
|
---|
| 608 | + % Find the white and black text
|
---|
| 609 | + black_text_handles = findall(fig, 'Type', 'text', 'Color', [0 0 0]);
|
---|
| 610 | + white_text_handles = findall(fig, 'Type', 'text', 'Color', [1 1 1]);
|
---|
| 611 | + % Set the font colors slightly off their correct values
|
---|
| 612 | + set(black_text_handles, 'Color', [0 0 0] + eps);
|
---|
| 613 | + set(white_text_handles, 'Color', [1 1 1] - eps);
|
---|
| 614 | +
|
---|
| 615 | + % MATLAB bug fix - white lines can come out funny sometimes
|
---|
| 616 | + % Find the white lines
|
---|
| 617 | + white_line_handles = findall(fig, 'Type', 'line', 'Color', [1 1 1]);
|
---|
| 618 | + % Set the line color slightly off white
|
---|
| 619 | + set(white_line_handles, 'Color', [1 1 1] - 0.00001);
|
---|
| 620 | +
|
---|
| 621 | + % Workaround for issue #45: lines in image subplots are exported in invalid color
|
---|
| 622 | + % In this case the -depsc driver solves the problem, but then all the other workarounds
|
---|
| 623 | + % below (for all the other issues) will fail, so it's better to let the user decide by
|
---|
| 624 | + % just issuing a warning and accepting the '-depsc' input parameter
|
---|
| 625 | + epsLevel2 = ~any(strcmpi(options,'-depsc'));
|
---|
| 626 | + if epsLevel2
|
---|
| 627 | + % Use -depsc2 (EPS color level-2) if -depsc (EPS color level-3) was not specifically requested
|
---|
| 628 | + options{end+1} = '-depsc2';
|
---|
| 629 | + % Issue a warning if multiple images & lines were found in the figure, and HG1 with painters renderer is used
|
---|
| 630 | + isPainters = any(strcmpi(options,'-painters'));
|
---|
| 631 | + if isPainters && ~using_hg2 && numel(findall(fig,'Type','image'))>1 && ~isempty(findall(fig,'Type','line'))
|
---|
| 632 | + warning('YMA:export_fig:issue45', ...
|
---|
| 633 | + ['Multiple images & lines detected. In such cases, the lines might \n' ...
|
---|
| 634 | + 'appear with an invalid color due to an internal MATLAB bug (fixed in R2014b). \n' ...
|
---|
| 635 | + 'Possible workaround: add a ''-depsc'' or ''-opengl'' parameter to the export_fig command.']);
|
---|
| 636 | end
|
---|
| 637 | end
|
---|
| 638 | - % Compute the order to revert fonts later, without the need of a loop
|
---|
| 639 | - [update, M] = unique(update(1:c));
|
---|
| 640 | - [M, M] = sort(M);
|
---|
| 641 | - update = reshape(update(M), 1, []);
|
---|
| 642 | -end
|
---|
| 643 | -% MATLAB bug fix - black and white text can come out inverted sometimes
|
---|
| 644 | -% Find the white and black text
|
---|
| 645 | -white_text_handles = findobj(fig, 'Type', 'text');
|
---|
| 646 | -M = get(white_text_handles, 'Color');
|
---|
| 647 | -if iscell(M)
|
---|
| 648 | - M = cell2mat(M);
|
---|
| 649 | -end
|
---|
| 650 | -M = sum(M, 2);
|
---|
| 651 | -black_text_handles = white_text_handles(M == 0);
|
---|
| 652 | -white_text_handles = white_text_handles(M == 3);
|
---|
| 653 | -% Set the font colors slightly off their correct values
|
---|
| 654 | -set(black_text_handles, 'Color', [0 0 0] + eps);
|
---|
| 655 | -set(white_text_handles, 'Color', [1 1 1] - eps);
|
---|
| 656 | -% MATLAB bug fix - white lines can come out funny sometimes
|
---|
| 657 | -% Find the white lines
|
---|
| 658 | -white_line_handles = findobj(fig, 'Type', 'line');
|
---|
| 659 | -M = get(white_line_handles, 'Color');
|
---|
| 660 | -if iscell(M)
|
---|
| 661 | - M = cell2mat(M);
|
---|
| 662 | -end
|
---|
| 663 | -white_line_handles = white_line_handles(sum(M, 2) == 3);
|
---|
| 664 | -% Set the line color slightly off white
|
---|
| 665 | -set(white_line_handles, 'Color', [1 1 1] - 0.00001);
|
---|
| 666 | -% Print to eps file
|
---|
| 667 | -print(fig, options{:}, name);
|
---|
| 668 | -% Reset the font and line colors
|
---|
| 669 | -set(black_text_handles, 'Color', [0 0 0]);
|
---|
| 670 | -set(white_text_handles, 'Color', [1 1 1]);
|
---|
| 671 | -set(white_line_handles, 'Color', [1 1 1]);
|
---|
| 672 | -% Reset paper size
|
---|
| 673 | -set(fig, 'PaperPositionMode', old_pos_mode, 'PaperOrientation', old_orientation);
|
---|
| 674 | -% Reset the font names in the figure
|
---|
| 675 | -if ~isempty(font_swap)
|
---|
| 676 | - for a = update
|
---|
| 677 | - set(font_handles(a), 'FontName', fonts{a}, 'FontSize', fonts_size(a));
|
---|
| 678 | +
|
---|
| 679 | + % Fix issue #83: use numeric handles in HG1
|
---|
| 680 | + if ~using_hg2(fig), fig = double(fig); end
|
---|
| 681 | +
|
---|
| 682 | + % Workaround for when transparency is lost through conversion fig>EPS>PDF (issue #108)
|
---|
| 683 | + % Replace transparent patch RGB values with an ID value (rare chance that ID color is being used already)
|
---|
| 684 | + if using_hg2
|
---|
| 685 | + origAlphaColors = eps_maintainAlpha(fig);
|
---|
| 686 | end
|
---|
| 687 | -end
|
---|
| 688 | -% Do post-processing on the eps file
|
---|
| 689 | -try
|
---|
| 690 | - fstrm = read_write_entire_textfile(name);
|
---|
| 691 | -catch
|
---|
| 692 | - 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.');
|
---|
| 693 | - return
|
---|
| 694 | -end
|
---|
| 695 | -% Replace the font names
|
---|
| 696 | -if ~isempty(font_swap)
|
---|
| 697 | - for a = 1:size(font_swap, 2)
|
---|
| 698 | - %fstrm = regexprep(fstrm, [font_swap{1,a} '-?[a-zA-Z]*\>'], font_swap{3,a}(~isspace(font_swap{3,a})));
|
---|
| 699 | - fstrm = regexprep(fstrm, font_swap{2,a}, font_swap{3,a}(~isspace(font_swap{3,a})));
|
---|
| 700 | +
|
---|
| 701 | + % Print to eps file
|
---|
| 702 | + print(fig, options{:}, name);
|
---|
| 703 | +
|
---|
| 704 | + % Do post-processing on the eps file
|
---|
| 705 | + try
|
---|
| 706 | + % Read the EPS file into memory
|
---|
| 707 | + fstrm = read_write_entire_textfile(name);
|
---|
| 708 | + catch
|
---|
| 709 | + fstrm = '';
|
---|
| 710 | end
|
---|
| 711 | +
|
---|
| 712 | + % Restore colors for transparent patches/lines and apply the
|
---|
| 713 | + % setopacityalpha setting in the EPS file (issue #108)
|
---|
| 714 | + if using_hg2
|
---|
| 715 | + [~,fstrm,foundFlags] = eps_maintainAlpha(fig, fstrm, origAlphaColors);
|
---|
| 716 | +
|
---|
| 717 | + % If some of the transparencies were not found in the EPS file, then rerun the
|
---|
| 718 | + % export with only the found transparencies modified (backward compatibility)
|
---|
| 719 | + if ~isempty(fstrm) && ~all(foundFlags)
|
---|
| 720 | + foundIdx = find(foundFlags);
|
---|
| 721 | + for objIdx = 1 : sum(foundFlags)
|
---|
| 722 | + colorsIdx = foundIdx(objIdx);
|
---|
| 723 | + colorsData = origAlphaColors{colorsIdx};
|
---|
| 724 | + hObj = colorsData{1};
|
---|
| 725 | + propName = colorsData{2};
|
---|
| 726 | + newColor = colorsData{4};
|
---|
| 727 | + hObj.(propName).ColorData = newColor;
|
---|
| 728 | + end
|
---|
| 729 | + delete(name);
|
---|
| 730 | + print(fig, options{:}, name);
|
---|
| 731 | + fstrm = read_write_entire_textfile(name);
|
---|
| 732 | + [~,fstrm] = eps_maintainAlpha(fig, fstrm, origAlphaColors(foundFlags));
|
---|
| 733 | + end
|
---|
| 734 | + end
|
---|
| 735 | +
|
---|
| 736 | + % Fix for Matlab R2014b bug (issue #31): LineWidths<0.75 are not set in the EPS (default line width is used)
|
---|
| 737 | + try
|
---|
| 738 | + if ~isempty(fstrm) && using_hg2(fig)
|
---|
| 739 | + % Convert miter joins to line joins
|
---|
| 740 | + %fstrm = regexprep(fstrm, '\n10.0 ML\n', '\n1 LJ\n');
|
---|
| 741 | + % This is faster (the original regexprep could take many seconds when the axes contains many lines):
|
---|
| 742 | + fstrm = strrep(fstrm, sprintf('\n10.0 ML\n'), sprintf('\n1 LJ\n'));
|
---|
| 743 | +
|
---|
| 744 | + % 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)
|
---|
| 745 | + % hAxes=gca; hAxes.YGridHandle.LineWidth, hAxes.YRuler.Axle.LineWidth
|
---|
| 746 | + %fstrm = regexprep(fstrm, '(GC\n2 setlinecap\n1 LJ)\nN', '$1\n0.667 LW\nN');
|
---|
| 747 | + % This is faster:
|
---|
| 748 | + fstrm = strrep(fstrm, sprintf('GC\n2 setlinecap\n1 LJ\nN'), sprintf('GC\n2 setlinecap\n1 LJ\n0.667 LW\nN'));
|
---|
| 749 | +
|
---|
| 750 | + % This is more accurate but *MUCH* slower (issue #52)
|
---|
| 751 | + %{
|
---|
| 752 | + % Modify all thin lines in the figure to have 10x LineWidths
|
---|
| 753 | + hLines = findall(fig,'Type','line');
|
---|
| 754 | + hThinLines = [];
|
---|
| 755 | + for lineIdx = 1 : numel(hLines)
|
---|
| 756 | + thisLine = hLines(lineIdx);
|
---|
| 757 | + if thisLine.LineWidth < 0.75 && strcmpi(thisLine.Visible,'on')
|
---|
| 758 | + hThinLines(end+1) = thisLine; %#ok<AGROW>
|
---|
| 759 | + thisLine.LineWidth = thisLine.LineWidth * 10;
|
---|
| 760 | + end
|
---|
| 761 | + end
|
---|
| 762 | +
|
---|
| 763 | + % If any thin lines were found
|
---|
| 764 | + if ~isempty(hThinLines)
|
---|
| 765 | + % Prepare an EPS with large-enough line widths
|
---|
| 766 | + print(fig, options{:}, name);
|
---|
| 767 | + % Restore the original LineWidths in the figure
|
---|
| 768 | + for lineIdx = 1 : numel(hThinLines)
|
---|
| 769 | + thisLine = handle(hThinLines(lineIdx));
|
---|
| 770 | + thisLine.LineWidth = thisLine.LineWidth / 10;
|
---|
| 771 | + end
|
---|
| 772 | +
|
---|
| 773 | + % Compare the original and the new EPS files and correct the original stream's LineWidths
|
---|
| 774 | + fstrm_new = read_write_entire_textfile(name);
|
---|
| 775 | + idx = 500; % skip heading with its possibly-different timestamp
|
---|
| 776 | + markerStr = sprintf('10.0 ML\nN');
|
---|
| 777 | + markerLen = length(markerStr);
|
---|
| 778 | + while ~isempty(idx) && idx < length(fstrm)
|
---|
| 779 | + lastIdx = min(length(fstrm), length(fstrm_new));
|
---|
| 780 | + delta = fstrm(idx+1:lastIdx) - fstrm_new(idx+1:lastIdx);
|
---|
| 781 | + idx = idx + find(delta,1);
|
---|
| 782 | + if ~isempty(idx) && ...
|
---|
| 783 | + isequal(fstrm(idx-markerLen+1:idx), markerStr) && ...
|
---|
| 784 | + ~isempty(regexp(fstrm_new(idx-markerLen+1:idx+12),'10.0 ML\n[\d\.]+ LW\nN')) %#ok<RGXP1>
|
---|
| 785 | + value = str2double(regexprep(fstrm_new(idx:idx+12),' .*',''));
|
---|
| 786 | + if isnan(value), break; end % something's wrong... - bail out
|
---|
| 787 | + newStr = sprintf('%0.3f LW\n',value/10);
|
---|
| 788 | + fstrm = [fstrm(1:idx-1) newStr fstrm(idx:end)];
|
---|
| 789 | + idx = idx + 12;
|
---|
| 790 | + else
|
---|
| 791 | + break;
|
---|
| 792 | + end
|
---|
| 793 | + end
|
---|
| 794 | + end
|
---|
| 795 | + %}
|
---|
| 796 | +
|
---|
| 797 | + % This is much faster although less accurate: fix all non-gray lines to have a LineWidth of 0.75 (=1 LW)
|
---|
| 798 | + % Note: This will give incorrect LineWidth of 075 for lines having LineWidth<0.75, as well as for non-gray grid-lines (if present)
|
---|
| 799 | + % However, in practice these edge-cases are very rare indeed, and the difference in LineWidth should not be noticeable
|
---|
| 800 | + %fstrm = regexprep(fstrm, '([CR]C\n2 setlinecap\n1 LJ)\nN', '$1\n1 LW\nN');
|
---|
| 801 | + % This is faster (the original regexprep could take many seconds when the axes contains many lines):
|
---|
| 802 | + fstrm = strrep(fstrm, sprintf('\n2 setlinecap\n1 LJ\nN'), sprintf('\n2 setlinecap\n1 LJ\n1 LW\nN'));
|
---|
| 803 | + end
|
---|
| 804 | + catch err
|
---|
| 805 | + fprintf(2, 'Error fixing LineWidths in EPS file: %s\n at %s:%d\n', err.message, err.stack(1).file, err.stack(1).line);
|
---|
| 806 | + end
|
---|
| 807 | +
|
---|
| 808 | + % Reset the font and line colors
|
---|
| 809 | + try
|
---|
| 810 | + set(black_text_handles, 'Color', [0 0 0]);
|
---|
| 811 | + set(white_text_handles, 'Color', [1 1 1]);
|
---|
| 812 | + catch
|
---|
| 813 | + % Fix issue #159: redo findall() '*text_handles'
|
---|
| 814 | + black_text_handles = findall(fig, 'Type', 'text', 'Color', [0 0 0]+eps);
|
---|
| 815 | + white_text_handles = findall(fig, 'Type', 'text', 'Color', [1 1 1]-eps);
|
---|
| 816 | + set(black_text_handles, 'Color', [0 0 0]);
|
---|
| 817 | + set(white_text_handles, 'Color', [1 1 1]);
|
---|
| 818 | + end
|
---|
| 819 | + set(white_line_handles, 'Color', [1 1 1]);
|
---|
| 820 | +
|
---|
| 821 | + % Reset paper size
|
---|
| 822 | + set(fig, 'PaperPositionMode', old_pos_mode, 'PaperOrientation', old_orientation);
|
---|
| 823 | +
|
---|
| 824 | + % Reset the font names in the figure
|
---|
| 825 | + if ~isempty(font_swap)
|
---|
| 826 | + for a = update
|
---|
| 827 | + set(font_handles(a), 'FontName', fonts{a}, 'FontSize', fonts_size(a));
|
---|
| 828 | + end
|
---|
| 829 | + end
|
---|
| 830 | +
|
---|
| 831 | + % Bail out if EPS post-processing is not possible
|
---|
| 832 | + if isempty(fstrm)
|
---|
| 833 | + 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.');
|
---|
| 834 | + return
|
---|
| 835 | + end
|
---|
| 836 | +
|
---|
| 837 | + % Replace the font names
|
---|
| 838 | + if ~isempty(font_swap)
|
---|
| 839 | + for a = 1:size(font_swap, 2)
|
---|
| 840 | + %fstrm = regexprep(fstrm, [font_swap{1,a} '-?[a-zA-Z]*\>'], font_swap{3,a}(~isspace(font_swap{3,a})));
|
---|
| 841 | + fstrm = regexprep(fstrm, font_swap{2,a}, font_swap{3,a}(~isspace(font_swap{3,a})));
|
---|
| 842 | + end
|
---|
| 843 | + end
|
---|
| 844 | +
|
---|
| 845 | + % Move the bounding box to the top of the file (HG2 only), or fix the line styles (HG1 only)
|
---|
| 846 | + if using_hg2(fig)
|
---|
| 847 | + % Move the bounding box to the top of the file (HG2 only)
|
---|
| 848 | + [s, e] = regexp(fstrm, '%%BoundingBox: [^%]*%%');
|
---|
| 849 | + if numel(s) == 2
|
---|
| 850 | + fstrm = fstrm([1:s(1)-1 s(2):e(2)-2 e(1)-1:s(2)-1 e(2)-1:end]);
|
---|
| 851 | + end
|
---|
| 852 | + else
|
---|
| 853 | + % Fix the line styles (HG1 only)
|
---|
| 854 | + fstrm = fix_lines(fstrm);
|
---|
| 855 | + end
|
---|
| 856 | +
|
---|
| 857 | + % Apply the bounding box padding & cropping, replacing Matlab's print()'s bounding box
|
---|
| 858 | + if bb_crop
|
---|
| 859 | + % Calculate a new bounding box based on a bitmap print using crop_border.m
|
---|
| 860 | + % 1. Determine the Matlab BoundingBox and PageBoundingBox
|
---|
| 861 | + [s,e] = regexp(fstrm, '%%BoundingBox: [^%]*%%'); % location BB in eps file
|
---|
| 862 | + if numel(s)==2, s=s(2); e=e(2); end
|
---|
| 863 | + aa = fstrm(s+15:e-3); % dimensions bb - STEP1
|
---|
| 864 | + bb_matlab = cell2mat(textscan(aa,'%f32%f32%f32%f32')); % dimensions bb - STEP2
|
---|
| 865 | +
|
---|
| 866 | + [s,e] = regexp(fstrm, '%%PageBoundingBox: [^%]*%%'); % location bb in eps file
|
---|
| 867 | + if numel(s)==2, s=s(2); e=e(2); end
|
---|
| 868 | + aa = fstrm(s+19:e-3); % dimensions bb - STEP1
|
---|
| 869 | + pagebb_matlab = cell2mat(textscan(aa,'%f32%f32%f32%f32')); % dimensions bb - STEP2
|
---|
| 870 | +
|
---|
| 871 | + % 2. Create a bitmap image and use crop_borders to create the relative
|
---|
| 872 | + % bb with respect to the PageBoundingBox
|
---|
| 873 | + [A, bcol] = print2array(fig, 1, renderer);
|
---|
| 874 | + [aa, aa, aa, bb_rel] = crop_borders(A, bcol, bb_padding, crop_amounts);
|
---|
| 875 | +
|
---|
| 876 | + % 3. Calculate the new Bounding Box
|
---|
| 877 | + pagew = pagebb_matlab(3)-pagebb_matlab(1);
|
---|
| 878 | + pageh = pagebb_matlab(4)-pagebb_matlab(2);
|
---|
| 879 | + %bb_new = [pagebb_matlab(1)+pagew*bb_rel(1) pagebb_matlab(2)+pageh*bb_rel(2) ...
|
---|
| 880 | + % pagebb_matlab(1)+pagew*bb_rel(3) pagebb_matlab(2)+pageh*bb_rel(4)];
|
---|
| 881 | + bb_new = pagebb_matlab([1,2,1,2]) + [pagew,pageh,pagew,pageh].*bb_rel; % clearer
|
---|
| 882 | + bb_offset = (bb_new-bb_matlab) + [-1,-1,1,1]; % 1px margin so that cropping is not TOO tight
|
---|
| 883 | +
|
---|
| 884 | + % Apply the bounding box padding
|
---|
| 885 | + if bb_padding
|
---|
| 886 | + if abs(bb_padding)<1
|
---|
| 887 | + 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
|
---|
| 888 | + end
|
---|
| 889 | + add_padding = @(n1, n2, n3, n4) sprintf(' %d', str2double({n1, n2, n3, n4}) + [-bb_padding -bb_padding bb_padding bb_padding] + bb_offset);
|
---|
| 890 | + else
|
---|
| 891 | + add_padding = @(n1, n2, n3, n4) sprintf(' %d', str2double({n1, n2, n3, n4}) + bb_offset); % fix small but noticeable bounding box shift
|
---|
| 892 | + end
|
---|
| 893 | + fstrm = regexprep(fstrm, '%%BoundingBox:[ ]+([-]?\d+)[ ]+([-]?\d+)[ ]+([-]?\d+)[ ]+([-]?\d+)', '%%BoundingBox:${add_padding($1, $2, $3, $4)}');
|
---|
| 894 | + end
|
---|
| 895 | +
|
---|
| 896 | + % Fix issue #44: white artifact lines appearing in patch exports
|
---|
| 897 | + % Note: the problem is due to the fact that Matlab's print() function exports patches
|
---|
| 898 | + % as a combination of filled triangles, and a white line appears where the triangles touch
|
---|
| 899 | + % In the workaround below, we will modify such dual-triangles into a filled rectangle.
|
---|
| 900 | + % We are careful to only modify regexps that exactly match specific patterns - it's better to not
|
---|
| 901 | + % correct some white-line artifacts than to change the geometry of a patch, or to corrupt the EPS.
|
---|
| 902 | + % 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'
|
---|
| 903 | + 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');
|
---|
| 904 | + 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');
|
---|
| 905 | + 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');
|
---|
| 906 | + 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');
|
---|
| 907 | +
|
---|
| 908 | + % Write out the fixed eps file
|
---|
| 909 | + read_write_entire_textfile(name, fstrm);
|
---|
| 910 | end
|
---|
| 911 | -if using_hg2(fig)
|
---|
| 912 | - % Convert miter joins to line joins
|
---|
| 913 | - fstrm = regexprep(fstrm, '10.0 ML\n', '1 LJ\n');
|
---|
| 914 | - % Move the bounding box to the top of the file
|
---|
| 915 | - [s, e] = regexp(fstrm, '%%BoundingBox: [\w\s()]*%%');
|
---|
| 916 | - if numel(s) == 2
|
---|
| 917 | - fstrm = fstrm([1:s(1)-1 s(2):e(2)-2 e(1)-1:s(2)-1 e(2)-1:end]);
|
---|
| 918 | +
|
---|
| 919 | +function [StoredColors, fstrm, foundFlags] = eps_maintainAlpha(fig, fstrm, StoredColors)
|
---|
| 920 | + if nargin == 1 % in: convert transparency in Matlab figure into unique RGB colors
|
---|
| 921 | + hObjs = findall(fig); %findobj(fig,'Type','Area');
|
---|
| 922 | + StoredColors = {};
|
---|
| 923 | + propNames = {'Face','Edge'};
|
---|
| 924 | + for objIdx = 1:length(hObjs)
|
---|
| 925 | + hObj = hObjs(objIdx);
|
---|
| 926 | + for propIdx = 1 : numel(propNames)
|
---|
| 927 | + try
|
---|
| 928 | + propName = propNames{propIdx};
|
---|
| 929 | + if strcmp(hObj.(propName).ColorType, 'truecoloralpha')
|
---|
| 930 | + nColors = length(StoredColors);
|
---|
| 931 | + oldColor = hObj.(propName).ColorData;
|
---|
| 932 | + newColor = uint8([101; 102+floor(nColors/255); mod(nColors,255); 255]);
|
---|
| 933 | + StoredColors{end+1} = {hObj, propName, oldColor, newColor};
|
---|
| 934 | + hObj.(propName).ColorData = newColor;
|
---|
| 935 | + end
|
---|
| 936 | + catch
|
---|
| 937 | + % Never mind - ignore (either doesn't have the property or cannot change it)
|
---|
| 938 | + end
|
---|
| 939 | + end
|
---|
| 940 | + end
|
---|
| 941 | + else % restore transparency in Matlab figure by converting back from the unique RGBs
|
---|
| 942 | + %Find the transparent patches
|
---|
| 943 | + wasError = false;
|
---|
| 944 | + nColors = length(StoredColors);
|
---|
| 945 | + foundFlags = false(1,nColors);
|
---|
| 946 | + for objIdx = 1 : nColors
|
---|
| 947 | + colorsData = StoredColors{objIdx};
|
---|
| 948 | + hObj = colorsData{1};
|
---|
| 949 | + propName = colorsData{2};
|
---|
| 950 | + origColor = colorsData{3};
|
---|
| 951 | + newColor = colorsData{4};
|
---|
| 952 | + try
|
---|
| 953 | + %Restore the EPS files patch color
|
---|
| 954 | + colorID = num2str(round(double(newColor(1:3)') /255,3),'%.3g %.3g %.3g'); %ID for searching
|
---|
| 955 | + origRGB = num2str(round(double(origColor(1:3)')/255,3),'%.3g %.3g %.3g'); %Replace with original color
|
---|
| 956 | + origAlpha = num2str(round(double(origColor(end)) /255,3),'%.3g'); %Convert alpha value for EPS
|
---|
| 957 | +
|
---|
| 958 | + %Find and replace the RGBA values within the EPS text fstrm
|
---|
| 959 | + if strcmpi(propName,'Face')
|
---|
| 960 | + oldStr = sprintf(['\n' colorID ' RC\nN\n']);
|
---|
| 961 | + newStr = sprintf(['\n' origRGB ' RC\n' origAlpha ' .setopacityalpha true\nN\n']);
|
---|
| 962 | + else %'Edge'
|
---|
| 963 | + oldStr = sprintf(['\n' colorID ' RC\n1 LJ\n']);
|
---|
| 964 | + newStr = sprintf(['\n' origRGB ' RC\n' origAlpha ' .setopacityalpha true\n']);
|
---|
| 965 | + end
|
---|
| 966 | + foundFlags(objIdx) = ~isempty(strfind(fstrm, oldStr));
|
---|
| 967 | + fstrm = strrep(fstrm, oldStr, newStr);
|
---|
| 968 | +
|
---|
| 969 | + %Restore the figure object's original color
|
---|
| 970 | + hObj.(propName).ColorData = origColor;
|
---|
| 971 | + catch err
|
---|
| 972 | + % something is wrong - cannot restore transparent color...
|
---|
| 973 | + if ~wasError
|
---|
| 974 | + fprintf(2, 'Error maintaining transparency in EPS file: %s\n at %s:%d\n', err.message, err.stack(1).file, err.stack(1).line);
|
---|
| 975 | + wasError = true;
|
---|
| 976 | + end
|
---|
| 977 | + end
|
---|
| 978 | + end
|
---|
| 979 | end
|
---|
| 980 | -else
|
---|
| 981 | - % Fix the line styles
|
---|
| 982 | - fstrm = fix_lines(fstrm);
|
---|
| 983 | end
|
---|
| 984 | -% Apply the bounding box padding
|
---|
| 985 | -if bb_padding
|
---|
| 986 | - add_padding = @(n1, n2, n3, n4) sprintf(' %d', str2double({n1, n2, n3, n4}) + [-bb_padding -bb_padding bb_padding bb_padding]);
|
---|
| 987 | - fstrm = regexprep(fstrm, '%%BoundingBox:[ ]+([-]?\d+)[ ]+([-]?\d+)[ ]+([-]?\d+)[ ]+([-]?\d+)', '%%BoundingBox:${add_padding($1, $2, $3, $4)}');
|
---|
| 988 | -end
|
---|
| 989 | -% Write out the fixed eps file
|
---|
| 990 | -read_write_entire_textfile(name, fstrm);
|
---|
| 991 | -end
|
---|
| 992 | Index: ../trunk-jpl/externalpackages/export_fig/LICENSE
|
---|
| 993 | ===================================================================
|
---|
| 994 | --- ../trunk-jpl/externalpackages/export_fig/LICENSE (revision 21314)
|
---|
| 995 | +++ ../trunk-jpl/externalpackages/export_fig/LICENSE (revision 21315)
|
---|
| 996 | @@ -1,4 +1,4 @@
|
---|
| 997 | -Copyright (c) 2014, Oliver J. Woodford
|
---|
| 998 | +Copyright (c) 2014, Oliver J. Woodford, Yair M. Altman
|
---|
| 999 | All rights reserved.
|
---|
| 1000 |
|
---|
| 1001 | Redistribution and use in source and binary forms, with or without
|
---|
| 1002 | Index: ../trunk-jpl/externalpackages/export_fig/copyfig.m
|
---|
| 1003 | ===================================================================
|
---|
| 1004 | --- ../trunk-jpl/externalpackages/export_fig/copyfig.m (revision 21314)
|
---|
| 1005 | +++ ../trunk-jpl/externalpackages/export_fig/copyfig.m (revision 21315)
|
---|
| 1006 | @@ -1,3 +1,4 @@
|
---|
| 1007 | +function fh = copyfig(fh)
|
---|
| 1008 | %COPYFIG Create a copy of a figure, without changing the figure
|
---|
| 1009 | %
|
---|
| 1010 | % Examples:
|
---|
| 1011 | @@ -14,20 +15,37 @@
|
---|
| 1012 |
|
---|
| 1013 | % Copyright (C) Oliver Woodford 2012
|
---|
| 1014 |
|
---|
| 1015 | -function fh = copyfig(fh)
|
---|
| 1016 | -% Set the default
|
---|
| 1017 | -if nargin == 0
|
---|
| 1018 | - fh = gcf;
|
---|
| 1019 | +% 26/02/15: If temp dir is not writable, use the dest folder for temp
|
---|
| 1020 | +% destination files (Javier Paredes)
|
---|
| 1021 | +% 15/04/15: Suppress warnings during copyobj (Dun Kirk comment on FEX page 2013-10-02)
|
---|
| 1022 | +
|
---|
| 1023 | + % Set the default
|
---|
| 1024 | + if nargin == 0
|
---|
| 1025 | + fh = gcf;
|
---|
| 1026 | + end
|
---|
| 1027 | + % Is there a legend?
|
---|
| 1028 | + if isempty(findall(fh, 'Type', 'axes', 'Tag', 'legend'))
|
---|
| 1029 | + % Safe to copy using copyobj
|
---|
| 1030 | + oldWarn = warning('off'); %#ok<WNOFF> %Suppress warnings during copyobj (Dun Kirk comment on FEX page 2013-10-02)
|
---|
| 1031 | + fh = copyobj(fh, 0);
|
---|
| 1032 | + warning(oldWarn);
|
---|
| 1033 | + else
|
---|
| 1034 | + % copyobj will change the figure, so save and then load it instead
|
---|
| 1035 | + tmp_nam = [tempname '.fig'];
|
---|
| 1036 | + try
|
---|
| 1037 | + % Ensure that the temp dir is writable (Javier Paredes 26/2/15)
|
---|
| 1038 | + fid = fopen(tmp_nam,'w');
|
---|
| 1039 | + fwrite(fid,1);
|
---|
| 1040 | + fclose(fid);
|
---|
| 1041 | + delete(tmp_nam); % cleanup
|
---|
| 1042 | + catch
|
---|
| 1043 | + % Temp dir is not writable, so use the current folder
|
---|
| 1044 | + [dummy,fname,fext] = fileparts(tmp_nam); %#ok<ASGLU>
|
---|
| 1045 | + fpath = pwd;
|
---|
| 1046 | + tmp_nam = fullfile(fpath,[fname fext]);
|
---|
| 1047 | + end
|
---|
| 1048 | + hgsave(fh, tmp_nam);
|
---|
| 1049 | + fh = hgload(tmp_nam);
|
---|
| 1050 | + delete(tmp_nam);
|
---|
| 1051 | + end
|
---|
| 1052 | end
|
---|
| 1053 | -% Is there a legend?
|
---|
| 1054 | -if isempty(findall(fh, 'Type', 'axes', 'Tag', 'legend'))
|
---|
| 1055 | - % Safe to copy using copyobj
|
---|
| 1056 | - fh = copyobj(fh, 0);
|
---|
| 1057 | -else
|
---|
| 1058 | - % copyobj will change the figure, so save and then load it instead
|
---|
| 1059 | - tmp_nam = [tempname '.fig'];
|
---|
| 1060 | - hgsave(fh, tmp_nam);
|
---|
| 1061 | - fh = hgload(tmp_nam);
|
---|
| 1062 | - delete(tmp_nam);
|
---|
| 1063 | -end
|
---|
| 1064 | -end
|
---|
| 1065 | Index: ../trunk-jpl/externalpackages/export_fig/ImageSelection.class
|
---|
| 1066 | ===================================================================
|
---|
| 1067 | Cannot display: file marked as a binary type.
|
---|
| 1068 | svn:mime-type = application/octet-stream
|
---|
| 1069 |
|
---|
| 1070 | Property changes on: ../trunk-jpl/externalpackages/export_fig/ImageSelection.class
|
---|
| 1071 | ___________________________________________________________________
|
---|
| 1072 | Added: svn:executable
|
---|
| 1073 | + *
|
---|
| 1074 | Added: svn:mime-type
|
---|
| 1075 | + application/octet-stream
|
---|
| 1076 |
|
---|
| 1077 | Index: ../trunk-jpl/externalpackages/export_fig/README.md
|
---|
| 1078 | ===================================================================
|
---|
| 1079 | --- ../trunk-jpl/externalpackages/export_fig/README.md (revision 21314)
|
---|
| 1080 | +++ ../trunk-jpl/externalpackages/export_fig/README.md (revision 21315)
|
---|
| 1081 | @@ -24,7 +24,7 @@
|
---|
| 1082 | |:-------:|:---------:|:----------:|
|
---|
| 1083 | ||||
|
---|
| 1084 |
|
---|
| 1085 | -Note that the size and background colour of test2.png (the output of export_fig) are the same as those of the on screen figure, in contrast to test.png. Of course, if you want want the figure background to be white (or any other colour) in the exported file then you can set this prior to exporting using:
|
---|
| 1086 | +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:
|
---|
| 1087 | ```Matlab
|
---|
| 1088 | set(gcf, 'Color', 'w');
|
---|
| 1089 | ```
|
---|
| 1090 | @@ -148,7 +148,7 @@
|
---|
| 1091 |
|
---|
| 1092 | **Cropping** - by default, export_fig crops its output to minimize the amount of empty space around the figure. If you'd prefer the figure to be uncropped, and instead have the same appearance (in terms of border width) as the on screen figure, then use the `-nocrop` option.
|
---|
| 1093 |
|
---|
| 1094 | -**Colourspace** - by default, export_fig generates files in the RGB [colourspace](http://en.wikipedia.org/wiki/Color_space). However, you can also export in greyscale or the CMYK colourspace, using the `-grey` (or `-gray`) and `-cmyk` options respectively. The CMYK option is useful for publishers who require documents in this colourspace, but the option is only supported for PDF, EPS and TIFF files.
|
---|
| 1095 | +**Colourspace** - by default, export_fig generates files in the RGB [colourspace](https://en.wikipedia.org/wiki/Color_space). However, you can also export in greyscale or the CMYK colourspace, using the `-grey` (or `-gray`) and `-cmyk` options respectively. The CMYK option is useful for publishers who require documents in this colourspace, but the option is only supported for PDF, EPS and TIFF files.
|
---|
| 1096 |
|
---|
| 1097 | **Specifying a target directory** - you can get export_fig to save output files to any directory (for which you have write permission), simply by specifying the full or relative path in the filename. For example:
|
---|
| 1098 | ```Matlab
|
---|
| 1099 | @@ -170,11 +170,11 @@
|
---|
| 1100 |
|
---|
| 1101 | **Specifying the figure/axes** - if you have mutiple figures open you can specify which figure to export using its handle:
|
---|
| 1102 | ```Matlab
|
---|
| 1103 | -export_fig(figure_handle, 'filename.fmt');
|
---|
| 1104 | +export_fig(figure_handle, filename);
|
---|
| 1105 | ```
|
---|
| 1106 | Equally, if your figure contains several subplots then you can export just one of them by giving export_fig the handle to the relevant axes:
|
---|
| 1107 | ```Matlab
|
---|
| 1108 | -export_fig(axes_handle, 'filename.fmt');
|
---|
| 1109 | +export_fig(axes_handle, filename);
|
---|
| 1110 | ```
|
---|
| 1111 |
|
---|
| 1112 | **Multiple formats** - save time by exporting to multiple formats simultaneously. E.g.:
|
---|
| 1113 | @@ -194,9 +194,14 @@
|
---|
| 1114 |
|
---|
| 1115 | **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)).
|
---|
| 1116 |
|
---|
| 1117 | +**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.
|
---|
| 1118 | +
|
---|
| 1119 | **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.
|
---|
| 1120 |
|
---|
| 1121 | -**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`.
|
---|
| 1122 | +**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`:
|
---|
| 1123 | +```Matlab
|
---|
| 1124 | +export_fig test.png -painters
|
---|
| 1125 | +```
|
---|
| 1126 |
|
---|
| 1127 | **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:
|
---|
| 1128 | ```Matlab
|
---|
| 1129 | @@ -214,32 +219,33 @@
|
---|
| 1130 | to this location using the dialogue box.
|
---|
| 1131 |
|
---|
| 1132 | **Undefined function errors** - If you download and run export_fig and get an error similar to this:
|
---|
| 1133 | -```Matlab
|
---|
| 1134 | +```
|
---|
| 1135 | ??? Undefined function or method 'print2array' for input arguments of type 'double'.
|
---|
| 1136 | ```
|
---|
| 1137 | then you are missing one or more of the files that come in the export_fig package. Make sure that you click the "Get from GitHub" button at the top-right of the download [page](http://www.mathworks.co.uk/matlabcentral/fileexchange/23629-exportfig), then extract all the files in the zip file to the same directory. You should then have all the necessary files.
|
---|
| 1138 |
|
---|
| 1139 | ### Known issues
|
---|
| 1140 | -There are lots of problems with MATLAB's exporting functions, and unfortunately export_fig, which is simply a glorified wrapper for MATLAB's print function, doesn't solve all of them (yet?). Some of the problems I know about are:
|
---|
| 1141 | +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:
|
---|
| 1142 |
|
---|
| 1143 | -**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'.
|
---|
| 1144 | +**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'.
|
---|
| 1145 |
|
---|
| 1146 | -Also, when using the painters renderer, ghostscript will sometimes throw an error such as `Error: /undefined in /findfont`. This suggests that ghostscript could not find a definition file for one of your fonts. One possible fix for this is to make sure the file `EXPORT_FIG_PATH/.ignore/gs_font_path.txt` exists and contains a list of paths to the folder(s) containing the necessary font definitions (make sure they're TrueType definitions), separated by a semicolon.
|
---|
| 1147 | +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.
|
---|
| 1148 |
|
---|
| 1149 | -**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.
|
---|
| 1150 | +**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.
|
---|
| 1151 |
|
---|
| 1152 | **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).
|
---|
| 1153 |
|
---|
| 1154 | **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.
|
---|
| 1155 |
|
---|
| 1156 | -**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.
|
---|
| 1157 | +**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.
|
---|
| 1158 |
|
---|
| 1159 | -**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.
|
---|
| 1160 | +**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 appears to be due to bugs in MATLAB's internal vector rendering code. These lines can often be removed from the PDF using software such as [InkScape](https://inkscape.org). Sometimes disabling anti-aliasing in the PDF-reader software can get rid of the lines ([discussion](https://github.com/altmany/export_fig/issues/44)).
|
---|
| 1161 |
|
---|
| 1162 | **Out of memory** - if you run into memory issues when using export_fig, some ways to get round this are:
|
---|
| 1163 | 1. Reduce the level of anti-aliasing.
|
---|
| 1164 | - 2. Reduce the size of the on screen figure.
|
---|
| 1165 | - 3. Reduce the resolution (dpi) the figure is exported at.
|
---|
| 1166 | + 2. Reduce the size of the figure.
|
---|
| 1167 | + 3. Reduce the export resolution (dpi).
|
---|
| 1168 | + 4. Change the renderer to painters or ZBuffer.
|
---|
| 1169 |
|
---|
| 1170 | **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.
|
---|
| 1171 |
|
---|
| 1172 | @@ -248,12 +254,17 @@
|
---|
| 1173 |
|
---|
| 1174 | Secondly, if exporting to bitmap, do try all the renderers (i.e. try the options `-opengl`, `-zbuffer` and `-painters` separately), to see if one of them does produce an acceptable output, and if so, use that.
|
---|
| 1175 |
|
---|
| 1176 | -If the figure looks correct on screen, but an error exists in the exported output (which cannot be solved using a different renderer) then please feel free to raise an [issue](https://github.com/ojwoodford/export_fig/issues). Please be sure to include the .fig file, the export_fig command you use, the output you get, and a description of what you expected. I can't promise anything, but if it's easy to fix I probably will do it. Often I will find that the error is due to a bug in MATLAB's print function, in which case I will suggest you submit it as a bug to TheMathWorks, and inform me of any fix they suggest. Also, if there's a feature you'd like that isn't supported please tell me what it is and I'll consider implementing it.
|
---|
| 1177 | +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).
|
---|
| 1178 | +
|
---|
| 1179 | +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/altmany/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.
|
---|
| 1180 |
|
---|
| 1181 | ### And finally...
|
---|
| 1182 |
|
---|
| 1183 | 
|
---|
| 1184 |
|
---|
| 1185 | -If you've ever wondered what's going on in the icon on the export_fig download page (reproduced on the left), then this explanantion is for you. The icon is designed to demonstrate as many of export_fig's features as possible. Given a
|
---|
| 1186 | -figure containing a translucent mesh (top right), export_fig can export to pdf (bottom centre), which allows the figure to be zoomed in without losing quality (because it's a vector graphic), but isn't able to reproduce the translucency, and also, depending on the viewer, creates small gaps between the patches, which are seen here as thin white lines. By contrast, when exporting to png (top left), translucency is preserved (see how the graphic below shows through), the figure is anti-aliased, but zooming in does not reveal more detail.
|
---|
| 1187 | +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:
|
---|
| 1188 | +
|
---|
| 1189 | +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.
|
---|
| 1190 | +
|
---|
| 1191 | +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.
|
---|
| 1192 |
|
---|
| 1193 | Index: ../trunk-jpl/externalpackages/export_fig/README
|
---|
| 1194 | ===================================================================
|
---|
| 1195 | --- ../trunk-jpl/externalpackages/export_fig/README (revision 0)
|
---|
| 1196 | +++ ../trunk-jpl/externalpackages/export_fig/README (revision 21315)
|
---|
| 1197 | @@ -0,0 +1,17 @@
|
---|
| 1198 | +Downloaded from https://www.mathworks.com/matlabcentral/fileexchange/23629-export-fig
|
---|
| 1199 | +
|
---|
| 1200 | +We had to patch export_fig.m to force export_fig to use the renderers painter, otherwise it is just way to slow (opengl is the default if we have patches)
|
---|
| 1201 | +
|
---|
| 1202 | +Line 585:
|
---|
| 1203 | +
|
---|
| 1204 | +
|
---|
| 1205 | +if ~options.renderer
|
---|
| 1206 | + if hasTransparency || hasPatches
|
---|
| 1207 | + % This is *MUCH* slower, but more accurate for patches and transparent annotations (issue #39)
|
---|
| 1208 | + renderer = '-opengl';
|
---|
| 1209 | + else
|
---|
| 1210 | + renderer = '-painters';
|
---|
| 1211 | + end
|
---|
| 1212 | +end
|
---|
| 1213 | +
|
---|
| 1214 | +change to painters all the time
|
---|
| 1215 | Index: ../trunk-jpl/externalpackages/export_fig/eps2pdf.m
|
---|
| 1216 | ===================================================================
|
---|
| 1217 | --- ../trunk-jpl/externalpackages/export_fig/eps2pdf.m (revision 21314)
|
---|
| 1218 | +++ ../trunk-jpl/externalpackages/export_fig/eps2pdf.m (revision 21315)
|
---|
| 1219 | @@ -1,3 +1,4 @@
|
---|
| 1220 | +function eps2pdf(source, dest, crop, append, gray, quality, gs_options)
|
---|
| 1221 | %EPS2PDF Convert an eps file to pdf format using ghostscript
|
---|
| 1222 | %
|
---|
| 1223 | % Examples:
|
---|
| 1224 | @@ -6,6 +7,7 @@
|
---|
| 1225 | % eps2pdf(source, dest, crop, append)
|
---|
| 1226 | % eps2pdf(source, dest, crop, append, gray)
|
---|
| 1227 | % eps2pdf(source, dest, crop, append, gray, quality)
|
---|
| 1228 | +% eps2pdf(source, dest, crop, append, gray, quality, gs_options)
|
---|
| 1229 | %
|
---|
| 1230 | % This function converts an eps file to pdf format. The output can be
|
---|
| 1231 | % optionally cropped and also converted to grayscale. If the output pdf
|
---|
| 1232 | @@ -16,23 +18,25 @@
|
---|
| 1233 | % This function requires that you have ghostscript installed on your
|
---|
| 1234 | % system. Ghostscript can be downloaded from: http://www.ghostscript.com
|
---|
| 1235 | %
|
---|
| 1236 | -%IN:
|
---|
| 1237 | -% source - filename of the source eps file to convert. The filename is
|
---|
| 1238 | -% assumed to already have the extension ".eps".
|
---|
| 1239 | -% dest - filename of the destination pdf file. The filename is assumed to
|
---|
| 1240 | -% already have the extension ".pdf".
|
---|
| 1241 | -% crop - boolean indicating whether to crop the borders off the pdf.
|
---|
| 1242 | -% Default: true.
|
---|
| 1243 | -% append - boolean indicating whether the eps should be appended to the
|
---|
| 1244 | -% end of the pdf as a new page (if the pdf exists already).
|
---|
| 1245 | -% Default: false.
|
---|
| 1246 | -% gray - boolean indicating whether the output pdf should be grayscale or
|
---|
| 1247 | -% not. Default: false.
|
---|
| 1248 | +% Inputs:
|
---|
| 1249 | +% source - filename of the source eps file to convert. The filename is
|
---|
| 1250 | +% assumed to already have the extension ".eps".
|
---|
| 1251 | +% dest - filename of the destination pdf file. The filename is assumed
|
---|
| 1252 | +% to already have the extension ".pdf".
|
---|
| 1253 | +% crop - boolean indicating whether to crop the borders off the pdf.
|
---|
| 1254 | +% Default: true.
|
---|
| 1255 | +% append - boolean indicating whether the eps should be appended to the
|
---|
| 1256 | +% end of the pdf as a new page (if the pdf exists already).
|
---|
| 1257 | +% Default: false.
|
---|
| 1258 | +% gray - boolean indicating whether the output pdf should be grayscale
|
---|
| 1259 | +% or not. Default: false.
|
---|
| 1260 | % quality - scalar indicating the level of image bitmap quality to
|
---|
| 1261 | % output. A larger value gives a higher quality. quality > 100
|
---|
| 1262 | % gives lossless output. Default: ghostscript prepress default.
|
---|
| 1263 | +% gs_options - optional ghostscript options (e.g.: '-dNoOutputFonts'). If
|
---|
| 1264 | +% multiple options are needed, enclose in call array: {'-a','-b'}
|
---|
| 1265 |
|
---|
| 1266 | -% Copyright (C) Oliver Woodford 2009-2011
|
---|
| 1267 | +% Copyright (C) Oliver Woodford 2009-2014, Yair Altman 2015-
|
---|
| 1268 |
|
---|
| 1269 | % Suggestion of appending pdf files provided by Matt C at:
|
---|
| 1270 | % http://www.mathworks.com/matlabcentral/fileexchange/23629
|
---|
| 1271 | @@ -43,92 +47,143 @@
|
---|
| 1272 | % which was fixed for lossless compression settings.
|
---|
| 1273 |
|
---|
| 1274 | % 9/12/2011 Pass font path to ghostscript.
|
---|
| 1275 | +% 26/02/15: If temp dir is not writable, use the dest folder for temp
|
---|
| 1276 | +% destination files (Javier Paredes)
|
---|
| 1277 | +% 28/02/15: Enable users to specify optional ghostscript options (issue #36)
|
---|
| 1278 | +% 01/03/15: Upon GS error, retry without the -sFONTPATH= option (this might solve
|
---|
| 1279 | +% some /findfont errors according to James Rankin, FEX Comment 23/01/15)
|
---|
| 1280 | +% 23/06/15: Added extra debug info in case of ghostscript error; code indentation
|
---|
| 1281 | +% 04/10/15: Suggest a workaround for issue #41 (missing font path; thanks Mariia Fedotenkova)
|
---|
| 1282 | +% 22/02/16: Bug fix from latest release of this file (workaround for issue #41)
|
---|
| 1283 |
|
---|
| 1284 | -function eps2pdf(source, dest, crop, append, gray, quality)
|
---|
| 1285 | -% Intialise the options string for ghostscript
|
---|
| 1286 | -options = ['-q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sOutputFile="' dest '"'];
|
---|
| 1287 | -% Set crop option
|
---|
| 1288 | -if nargin < 3 || crop
|
---|
| 1289 | - options = [options ' -dEPSCrop'];
|
---|
| 1290 | -end
|
---|
| 1291 | -% Set the font path
|
---|
| 1292 | -fp = font_path();
|
---|
| 1293 | -if ~isempty(fp)
|
---|
| 1294 | - options = [options ' -sFONTPATH="' fp '"'];
|
---|
| 1295 | -end
|
---|
| 1296 | -% Set the grayscale option
|
---|
| 1297 | -if nargin > 4 && gray
|
---|
| 1298 | - options = [options ' -sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray'];
|
---|
| 1299 | -end
|
---|
| 1300 | -% Set the bitmap quality
|
---|
| 1301 | -if nargin > 5 && ~isempty(quality)
|
---|
| 1302 | - options = [options ' -dAutoFilterColorImages=false -dAutoFilterGrayImages=false'];
|
---|
| 1303 | - if quality > 100
|
---|
| 1304 | - options = [options ' -dColorImageFilter=/FlateEncode -dGrayImageFilter=/FlateEncode -c ".setpdfwrite << /ColorImageDownsampleThreshold 10 /GrayImageDownsampleThreshold 10 >> setdistillerparams"'];
|
---|
| 1305 | - else
|
---|
| 1306 | - options = [options ' -dColorImageFilter=/DCTEncode -dGrayImageFilter=/DCTEncode'];
|
---|
| 1307 | - v = 1 + (quality < 80);
|
---|
| 1308 | - quality = 1 - quality / 100;
|
---|
| 1309 | - s = sprintf('<< /QFactor %.2f /Blend 1 /HSample [%d 1 1 %d] /VSample [%d 1 1 %d] >>', quality, v, v, v, v);
|
---|
| 1310 | - options = sprintf('%s -c ".setpdfwrite << /ColorImageDict %s /GrayImageDict %s >> setdistillerparams"', options, s, s);
|
---|
| 1311 | + % Intialise the options string for ghostscript
|
---|
| 1312 | + options = ['-q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sOutputFile="' dest '"'];
|
---|
| 1313 | + % Set crop option
|
---|
| 1314 | + if nargin < 3 || crop
|
---|
| 1315 | + options = [options ' -dEPSCrop'];
|
---|
| 1316 | end
|
---|
| 1317 | -end
|
---|
| 1318 | -% Check if the output file exists
|
---|
| 1319 | -if nargin > 3 && append && exist(dest, 'file') == 2
|
---|
| 1320 | - % File exists - append current figure to the end
|
---|
| 1321 | - tmp_nam = tempname;
|
---|
| 1322 | - % Copy the file
|
---|
| 1323 | - copyfile(dest, tmp_nam);
|
---|
| 1324 | - % Add the output file names
|
---|
| 1325 | - options = [options ' -f "' tmp_nam '" "' source '"'];
|
---|
| 1326 | - try
|
---|
| 1327 | - % Convert to pdf using ghostscript
|
---|
| 1328 | - [status, message] = ghostscript(options);
|
---|
| 1329 | - catch me
|
---|
| 1330 | + % Set the font path
|
---|
| 1331 | + fp = font_path();
|
---|
| 1332 | + if ~isempty(fp)
|
---|
| 1333 | + options = [options ' -sFONTPATH="' fp '"'];
|
---|
| 1334 | + end
|
---|
| 1335 | + % Set the grayscale option
|
---|
| 1336 | + if nargin > 4 && gray
|
---|
| 1337 | + options = [options ' -sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray'];
|
---|
| 1338 | + end
|
---|
| 1339 | + % Set the bitmap quality
|
---|
| 1340 | + if nargin > 5 && ~isempty(quality)
|
---|
| 1341 | + options = [options ' -dAutoFilterColorImages=false -dAutoFilterGrayImages=false'];
|
---|
| 1342 | + if quality > 100
|
---|
| 1343 | + options = [options ' -dColorImageFilter=/FlateEncode -dGrayImageFilter=/FlateEncode -c ".setpdfwrite << /ColorImageDownsampleThreshold 10 /GrayImageDownsampleThreshold 10 >> setdistillerparams"'];
|
---|
| 1344 | + else
|
---|
| 1345 | + options = [options ' -dColorImageFilter=/DCTEncode -dGrayImageFilter=/DCTEncode'];
|
---|
| 1346 | + v = 1 + (quality < 80);
|
---|
| 1347 | + quality = 1 - quality / 100;
|
---|
| 1348 | + s = sprintf('<< /QFactor %.2f /Blend 1 /HSample [%d 1 1 %d] /VSample [%d 1 1 %d] >>', quality, v, v, v, v);
|
---|
| 1349 | + options = sprintf('%s -c ".setpdfwrite << /ColorImageDict %s /GrayImageDict %s >> setdistillerparams"', options, s, s);
|
---|
| 1350 | + end
|
---|
| 1351 | + end
|
---|
| 1352 | + % Enable users to specify optional ghostscript options (issue #36)
|
---|
| 1353 | + if nargin > 6 && ~isempty(gs_options)
|
---|
| 1354 | + if iscell(gs_options)
|
---|
| 1355 | + gs_options = sprintf(' %s',gs_options{:});
|
---|
| 1356 | + elseif ~ischar(gs_options)
|
---|
| 1357 | + error('gs_options input argument must be a string or cell-array of strings');
|
---|
| 1358 | + else
|
---|
| 1359 | + gs_options = [' ' gs_options];
|
---|
| 1360 | + end
|
---|
| 1361 | + options = [options gs_options];
|
---|
| 1362 | + end
|
---|
| 1363 | + % Check if the output file exists
|
---|
| 1364 | + if nargin > 3 && append && exist(dest, 'file') == 2
|
---|
| 1365 | + % File exists - append current figure to the end
|
---|
| 1366 | + tmp_nam = tempname;
|
---|
| 1367 | + try
|
---|
| 1368 | + % Ensure that the temp dir is writable (Javier Paredes 26/2/15)
|
---|
| 1369 | + fid = fopen(tmp_nam,'w');
|
---|
| 1370 | + fwrite(fid,1);
|
---|
| 1371 | + fclose(fid);
|
---|
| 1372 | + delete(tmp_nam);
|
---|
| 1373 | + catch
|
---|
| 1374 | + % Temp dir is not writable, so use the dest folder
|
---|
| 1375 | + [dummy,fname,fext] = fileparts(tmp_nam); %#ok<ASGLU>
|
---|
| 1376 | + fpath = fileparts(dest);
|
---|
| 1377 | + tmp_nam = fullfile(fpath,[fname fext]);
|
---|
| 1378 | + end
|
---|
| 1379 | + % Copy the file
|
---|
| 1380 | + copyfile(dest, tmp_nam);
|
---|
| 1381 | + % Add the output file names
|
---|
| 1382 | + options = [options ' -f "' tmp_nam '" "' source '"'];
|
---|
| 1383 | + try
|
---|
| 1384 | + % Convert to pdf using ghostscript
|
---|
| 1385 | + [status, message] = ghostscript(options);
|
---|
| 1386 | + catch me
|
---|
| 1387 | + % Delete the intermediate file
|
---|
| 1388 | + delete(tmp_nam);
|
---|
| 1389 | + rethrow(me);
|
---|
| 1390 | + end
|
---|
| 1391 | % Delete the intermediate file
|
---|
| 1392 | delete(tmp_nam);
|
---|
| 1393 | - rethrow(me);
|
---|
| 1394 | - end
|
---|
| 1395 | - % Delete the intermediate file
|
---|
| 1396 | - delete(tmp_nam);
|
---|
| 1397 | -else
|
---|
| 1398 | - % File doesn't exist or should be over-written
|
---|
| 1399 | - % Add the output file names
|
---|
| 1400 | - options = [options ' -f "' source '"'];
|
---|
| 1401 | - % Convert to pdf using ghostscript
|
---|
| 1402 | - [status, message] = ghostscript(options);
|
---|
| 1403 | -end
|
---|
| 1404 | -% Check for error
|
---|
| 1405 | -if status
|
---|
| 1406 | - % Report error
|
---|
| 1407 | - if isempty(message)
|
---|
| 1408 | - error('Unable to generate pdf. Check destination directory is writable.');
|
---|
| 1409 | else
|
---|
| 1410 | - error(message);
|
---|
| 1411 | + % File doesn't exist or should be over-written
|
---|
| 1412 | + % Add the output file names
|
---|
| 1413 | + options = [options ' -f "' source '"'];
|
---|
| 1414 | + % Convert to pdf using ghostscript
|
---|
| 1415 | + [status, message] = ghostscript(options);
|
---|
| 1416 | end
|
---|
| 1417 | + % Check for error
|
---|
| 1418 | + if status
|
---|
| 1419 | + % Retry without the -sFONTPATH= option (this might solve some GS
|
---|
| 1420 | + % /findfont errors according to James Rankin, FEX Comment 23/01/15)
|
---|
| 1421 | + orig_options = options;
|
---|
| 1422 | + if ~isempty(fp)
|
---|
| 1423 | + options = regexprep(options, ' -sFONTPATH=[^ ]+ ',' ');
|
---|
| 1424 | + status = ghostscript(options);
|
---|
| 1425 | + if ~status, return; end % hurray! (no error)
|
---|
| 1426 | + end
|
---|
| 1427 | + % Report error
|
---|
| 1428 | + if isempty(message)
|
---|
| 1429 | + error('Unable to generate pdf. Check destination directory is writable.');
|
---|
| 1430 | + elseif ~isempty(strfind(message,'/typecheck in /findfont'))
|
---|
| 1431 | + % Suggest a workaround for issue #41 (missing font path)
|
---|
| 1432 | + font_name = strtrim(regexprep(message,'.*Operand stack:\s*(.*)\s*Execution.*','$1'));
|
---|
| 1433 | + fprintf(2, 'Ghostscript error: could not find the following font(s): %s\n', font_name);
|
---|
| 1434 | + fpath = fileparts(mfilename('fullpath'));
|
---|
| 1435 | + gs_fonts_file = fullfile(fpath, '.ignore', 'gs_font_path.txt');
|
---|
| 1436 | + fprintf(2, ' try to add the font''s folder to your %s file\n\n', gs_fonts_file);
|
---|
| 1437 | + error('export_fig error');
|
---|
| 1438 | + else
|
---|
| 1439 | + fprintf(2, '\nGhostscript error: perhaps %s is open by another application\n', dest);
|
---|
| 1440 | + if ~isempty(gs_options)
|
---|
| 1441 | + fprintf(2, ' or maybe the%s option(s) are not accepted by your GS version\n', gs_options);
|
---|
| 1442 | + end
|
---|
| 1443 | + fprintf(2, 'Ghostscript options: %s\n\n', orig_options);
|
---|
| 1444 | + error(message);
|
---|
| 1445 | + end
|
---|
| 1446 | + end
|
---|
| 1447 | end
|
---|
| 1448 | -end
|
---|
| 1449 |
|
---|
| 1450 | % Function to return (and create, where necessary) the font path
|
---|
| 1451 | function fp = font_path()
|
---|
| 1452 | -fp = user_string('gs_font_path');
|
---|
| 1453 | -if ~isempty(fp)
|
---|
| 1454 | - return
|
---|
| 1455 | -end
|
---|
| 1456 | -% Create the path
|
---|
| 1457 | -% Start with the default path
|
---|
| 1458 | -fp = getenv('GS_FONTPATH');
|
---|
| 1459 | -% Add on the typical directories for a given OS
|
---|
| 1460 | -if ispc
|
---|
| 1461 | + fp = user_string('gs_font_path');
|
---|
| 1462 | if ~isempty(fp)
|
---|
| 1463 | - fp = [fp ';'];
|
---|
| 1464 | + return
|
---|
| 1465 | end
|
---|
| 1466 | - fp = [fp getenv('WINDIR') filesep 'Fonts'];
|
---|
| 1467 | -else
|
---|
| 1468 | - if ~isempty(fp)
|
---|
| 1469 | - fp = [fp ':'];
|
---|
| 1470 | + % Create the path
|
---|
| 1471 | + % Start with the default path
|
---|
| 1472 | + fp = getenv('GS_FONTPATH');
|
---|
| 1473 | + % Add on the typical directories for a given OS
|
---|
| 1474 | + if ispc
|
---|
| 1475 | + if ~isempty(fp)
|
---|
| 1476 | + fp = [fp ';'];
|
---|
| 1477 | + end
|
---|
| 1478 | + fp = [fp getenv('WINDIR') filesep 'Fonts'];
|
---|
| 1479 | + else
|
---|
| 1480 | + if ~isempty(fp)
|
---|
| 1481 | + fp = [fp ':'];
|
---|
| 1482 | + end
|
---|
| 1483 | + 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'];
|
---|
| 1484 | end
|
---|
| 1485 | - 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'];
|
---|
| 1486 | + user_string('gs_font_path', fp);
|
---|
| 1487 | end
|
---|
| 1488 | -user_string('gs_font_path', fp);
|
---|
| 1489 | -end
|
---|
| 1490 | Index: ../trunk-jpl/externalpackages/export_fig/user_string.m
|
---|
| 1491 | ===================================================================
|
---|
| 1492 | --- ../trunk-jpl/externalpackages/export_fig/user_string.m (revision 21314)
|
---|
| 1493 | +++ ../trunk-jpl/externalpackages/export_fig/user_string.m (revision 21315)
|
---|
| 1494 | @@ -1,24 +1,27 @@
|
---|
| 1495 | +function string = user_string(string_name, string)
|
---|
| 1496 | %USER_STRING Get/set a user specific string
|
---|
| 1497 | %
|
---|
| 1498 | % Examples:
|
---|
| 1499 | -% string = user_string(string_name)
|
---|
| 1500 | -% saved = user_string(string_name, new_string)
|
---|
| 1501 | +% string = user_string(string_name)
|
---|
| 1502 | +% isSaved = user_string(string_name, new_string)
|
---|
| 1503 | %
|
---|
| 1504 | % Function to get and set a string in a system or user specific file. This
|
---|
| 1505 | % enables, for example, system specific paths to binaries to be saved.
|
---|
| 1506 | %
|
---|
| 1507 | +% The specified string will be saved in a file named <string_name>.txt,
|
---|
| 1508 | +% either in a subfolder named .ignore under this file's folder, or in the
|
---|
| 1509 | +% user's prefdir folder (in case this file's folder is non-writable).
|
---|
| 1510 | +%
|
---|
| 1511 | % IN:
|
---|
| 1512 | -% string_name - String containing the name of the string required. The
|
---|
| 1513 | -% string is extracted from a file called (string_name).txt,
|
---|
| 1514 | -% stored in the same directory as user_string.m.
|
---|
| 1515 | -% new_string - The new string to be saved under the name given by
|
---|
| 1516 | -% string_name.
|
---|
| 1517 | +% string_name - String containing the name of the string required, which
|
---|
| 1518 | +% sets the filename storing the string: <string_name>.txt
|
---|
| 1519 | +% new_string - The new string to be saved in the <string_name>.txt file
|
---|
| 1520 | %
|
---|
| 1521 | % OUT:
|
---|
| 1522 | -% string - The currently saved string. Default: ''.
|
---|
| 1523 | -% saved - Boolean indicating whether the save was succesful
|
---|
| 1524 | +% string - The currently saved string. Default: ''
|
---|
| 1525 | +% isSaved - Boolean indicating whether the save was succesful
|
---|
| 1526 |
|
---|
| 1527 | -% Copyright (C) Oliver Woodford 2011-2013
|
---|
| 1528 | +% Copyright (C) Oliver Woodford 2011-2014, Yair Altman 2015-
|
---|
| 1529 |
|
---|
| 1530 | % This method of saving paths avoids changing .m files which might be in a
|
---|
| 1531 | % version control system. Instead it saves the user dependent paths in
|
---|
| 1532 | @@ -27,61 +30,76 @@
|
---|
| 1533 | % approach.
|
---|
| 1534 |
|
---|
| 1535 | % 10/01/2013 - Access files in text, not binary mode, as latter can cause
|
---|
| 1536 | -% errors. Thanks to Christian for pointing this out.
|
---|
| 1537 | +% errors. Thanks to Christian for pointing this out.
|
---|
| 1538 | +% 29/05/2015 - Save file in prefdir if current folder is non-writable (issue #74)
|
---|
| 1539 |
|
---|
| 1540 | -function string = user_string(string_name, string)
|
---|
| 1541 | -if ~ischar(string_name)
|
---|
| 1542 | - error('string_name must be a string.');
|
---|
| 1543 | -end
|
---|
| 1544 | -% Create the full filename
|
---|
| 1545 | -string_name = fullfile(fileparts(mfilename('fullpath')), '.ignore', [string_name '.txt']);
|
---|
| 1546 | -if nargin > 1
|
---|
| 1547 | - % Set string
|
---|
| 1548 | - if ~ischar(string)
|
---|
| 1549 | - error('new_string must be a string.');
|
---|
| 1550 | + if ~ischar(string_name)
|
---|
| 1551 | + error('string_name must be a string.');
|
---|
| 1552 | end
|
---|
| 1553 | - % Make sure the save directory exists
|
---|
| 1554 | - dname = fileparts(string_name);
|
---|
| 1555 | - if ~exist(dname, 'dir')
|
---|
| 1556 | - % Create the directory
|
---|
| 1557 | - try
|
---|
| 1558 | - if ~mkdir(dname)
|
---|
| 1559 | + % Create the full filename
|
---|
| 1560 | + fname = [string_name '.txt'];
|
---|
| 1561 | + dname = fullfile(fileparts(mfilename('fullpath')), '.ignore');
|
---|
| 1562 | + file_name = fullfile(dname, fname);
|
---|
| 1563 | + if nargin > 1
|
---|
| 1564 | + % Set string
|
---|
| 1565 | + if ~ischar(string)
|
---|
| 1566 | + error('new_string must be a string.');
|
---|
| 1567 | + end
|
---|
| 1568 | + % Make sure the save directory exists
|
---|
| 1569 | + %dname = fileparts(file_name);
|
---|
| 1570 | + if ~exist(dname, 'dir')
|
---|
| 1571 | + % Create the directory
|
---|
| 1572 | + try
|
---|
| 1573 | + if ~mkdir(dname)
|
---|
| 1574 | + string = false;
|
---|
| 1575 | + return
|
---|
| 1576 | + end
|
---|
| 1577 | + catch
|
---|
| 1578 | string = false;
|
---|
| 1579 | return
|
---|
| 1580 | end
|
---|
| 1581 | + % Make it hidden
|
---|
| 1582 | + try
|
---|
| 1583 | + fileattrib(dname, '+h');
|
---|
| 1584 | + catch
|
---|
| 1585 | + end
|
---|
| 1586 | + end
|
---|
| 1587 | + % Write the file
|
---|
| 1588 | + fid = fopen(file_name, 'wt');
|
---|
| 1589 | + if fid == -1
|
---|
| 1590 | + % file cannot be created/updated - use prefdir if file does not already exist
|
---|
| 1591 | + % (if file exists but is simply not writable, don't create a duplicate in prefdir)
|
---|
| 1592 | + if ~exist(file_name,'file')
|
---|
| 1593 | + file_name = fullfile(prefdir, fname);
|
---|
| 1594 | + fid = fopen(file_name, 'wt');
|
---|
| 1595 | + end
|
---|
| 1596 | + if fid == -1
|
---|
| 1597 | + string = false;
|
---|
| 1598 | + return;
|
---|
| 1599 | + end
|
---|
| 1600 | + end
|
---|
| 1601 | + try
|
---|
| 1602 | + fprintf(fid, '%s', string);
|
---|
| 1603 | catch
|
---|
| 1604 | + fclose(fid);
|
---|
| 1605 | string = false;
|
---|
| 1606 | return
|
---|
| 1607 | end
|
---|
| 1608 | - % Make it hidden
|
---|
| 1609 | - try
|
---|
| 1610 | - fileattrib(dname, '+h');
|
---|
| 1611 | - catch
|
---|
| 1612 | + fclose(fid);
|
---|
| 1613 | + string = true;
|
---|
| 1614 | + else
|
---|
| 1615 | + % Get string
|
---|
| 1616 | + fid = fopen(file_name, 'rt');
|
---|
| 1617 | + if fid == -1
|
---|
| 1618 | + % file cannot be read, try to read the file in prefdir
|
---|
| 1619 | + file_name = fullfile(prefdir, fname);
|
---|
| 1620 | + fid = fopen(file_name, 'rt');
|
---|
| 1621 | + if fid == -1
|
---|
| 1622 | + string = '';
|
---|
| 1623 | + return
|
---|
| 1624 | + end
|
---|
| 1625 | end
|
---|
| 1626 | - end
|
---|
| 1627 | - % Write the file
|
---|
| 1628 | - fid = fopen(string_name, 'wt');
|
---|
| 1629 | - if fid == -1
|
---|
| 1630 | - string = false;
|
---|
| 1631 | - return
|
---|
| 1632 | - end
|
---|
| 1633 | - try
|
---|
| 1634 | - fprintf(fid, '%s', string);
|
---|
| 1635 | - catch
|
---|
| 1636 | + string = fgetl(fid);
|
---|
| 1637 | fclose(fid);
|
---|
| 1638 | - string = false;
|
---|
| 1639 | - return
|
---|
| 1640 | end
|
---|
| 1641 | - fclose(fid);
|
---|
| 1642 | - string = true;
|
---|
| 1643 | -else
|
---|
| 1644 | - % Get string
|
---|
| 1645 | - fid = fopen(string_name, 'rt');
|
---|
| 1646 | - if fid == -1
|
---|
| 1647 | - string = '';
|
---|
| 1648 | - return
|
---|
| 1649 | - end
|
---|
| 1650 | - string = fgetl(fid);
|
---|
| 1651 | - fclose(fid);
|
---|
| 1652 | end
|
---|
| 1653 | -end
|
---|
| 1654 | Index: ../trunk-jpl/externalpackages/export_fig/export_fig.m
|
---|
| 1655 | ===================================================================
|
---|
| 1656 | --- ../trunk-jpl/externalpackages/export_fig/export_fig.m (revision 21314)
|
---|
| 1657 | +++ ../trunk-jpl/externalpackages/export_fig/export_fig.m (revision 21315)
|
---|
| 1658 | @@ -1,11 +1,13 @@
|
---|
| 1659 | -%EXPORT_FIG Exports figures suitable for publication
|
---|
| 1660 | +function [imageData, alpha] = export_fig(varargin)
|
---|
| 1661 | +%EXPORT_FIG Exports figures in a publication-quality format
|
---|
| 1662 | %
|
---|
| 1663 | % Examples:
|
---|
| 1664 | -% im = export_fig
|
---|
| 1665 | -% [im alpha] = export_fig
|
---|
| 1666 | +% imageData = export_fig
|
---|
| 1667 | +% [imageData, alpha] = export_fig
|
---|
| 1668 | % export_fig filename
|
---|
| 1669 | % export_fig filename -format1 -format2
|
---|
| 1670 | % export_fig ... -nocrop
|
---|
| 1671 | +% export_fig ... -c[<val>,<val>,<val>,<val>]
|
---|
| 1672 | % export_fig ... -transparent
|
---|
| 1673 | % export_fig ... -native
|
---|
| 1674 | % export_fig ... -m<val>
|
---|
| 1675 | @@ -13,29 +15,34 @@
|
---|
| 1676 | % export_fig ... -a<val>
|
---|
| 1677 | % export_fig ... -q<val>
|
---|
| 1678 | % export_fig ... -p<val>
|
---|
| 1679 | +% export_fig ... -d<gs_option>
|
---|
| 1680 | +% export_fig ... -depsc
|
---|
| 1681 | % export_fig ... -<renderer>
|
---|
| 1682 | % export_fig ... -<colorspace>
|
---|
| 1683 | % export_fig ... -append
|
---|
| 1684 | % export_fig ... -bookmark
|
---|
| 1685 | +% export_fig ... -clipboard
|
---|
| 1686 | +% export_fig ... -update
|
---|
| 1687 | +% export_fig ... -nofontswap
|
---|
| 1688 | % export_fig(..., handle)
|
---|
| 1689 | %
|
---|
| 1690 | % This function saves a figure or single axes to one or more vector and/or
|
---|
| 1691 | -% bitmap file formats, and/or outputs a rasterized version to the
|
---|
| 1692 | -% workspace, with the following properties:
|
---|
| 1693 | +% bitmap file formats, and/or outputs a rasterized version to the workspace,
|
---|
| 1694 | +% with the following properties:
|
---|
| 1695 | % - Figure/axes reproduced as it appears on screen
|
---|
| 1696 | % - Cropped borders (optional)
|
---|
| 1697 | % - Embedded fonts (vector formats)
|
---|
| 1698 | % - Improved line and grid line styles
|
---|
| 1699 | % - Anti-aliased graphics (bitmap formats)
|
---|
| 1700 | % - Render images at native resolution (optional for bitmap formats)
|
---|
| 1701 | -% - Transparent background supported (pdf, eps, png)
|
---|
| 1702 | -% - Semi-transparent patch objects supported (png only)
|
---|
| 1703 | +% - Transparent background supported (pdf, eps, png, tif)
|
---|
| 1704 | +% - Semi-transparent patch objects supported (png & tif only)
|
---|
| 1705 | % - RGB, CMYK or grayscale output (CMYK only with pdf, eps, tiff)
|
---|
| 1706 | % - Variable image compression, including lossless (pdf, eps, jpg)
|
---|
| 1707 | % - Optionally append to file (pdf, tiff)
|
---|
| 1708 | % - Vector formats: pdf, eps
|
---|
| 1709 | -% - Bitmap formats: png, tiff, jpg, bmp, export to workspace
|
---|
| 1710 | -%
|
---|
| 1711 | +% - Bitmap formats: png, tiff, jpg, bmp, export to workspace
|
---|
| 1712 | +%
|
---|
| 1713 | % This function is especially suited to exporting figures for use in
|
---|
| 1714 | % publications and presentations, because of the high quality and
|
---|
| 1715 | % portability of media produced.
|
---|
| 1716 | @@ -45,21 +52,20 @@
|
---|
| 1717 | % output file. For transparent background (and semi-transparent patch
|
---|
| 1718 | % objects), use the -transparent option or set the figure 'Color' property
|
---|
| 1719 | % to 'none'. To make axes transparent set the axes 'Color' property to
|
---|
| 1720 | -% 'none'. Pdf, eps and png are the only file formats to support a
|
---|
| 1721 | -% transparent background, whilst the png format alone supports transparency
|
---|
| 1722 | -% of patch objects.
|
---|
| 1723 | +% 'none'. PDF, EPS, TIF & PNG are the only formats that support a transparent
|
---|
| 1724 | +% background; only TIF & PNG formats support transparency of patch objects.
|
---|
| 1725 | %
|
---|
| 1726 | % The choice of renderer (opengl, zbuffer or painters) has a large impact
|
---|
| 1727 | -% on the quality of output. Whilst the default value (opengl for bitmaps,
|
---|
| 1728 | -% painters for vector formats) generally gives good results, if you aren't
|
---|
| 1729 | -% satisfied then try another renderer. Notes: 1) For vector formats (eps,
|
---|
| 1730 | -% pdf), only painters generates vector graphics. 2) For bitmaps, only
|
---|
| 1731 | +% on the quality of output. The default value (opengl for bitmaps, painters
|
---|
| 1732 | +% for vector formats) generally gives good results, but if you aren't
|
---|
| 1733 | +% satisfied then try another renderer. Notes: 1) For vector formats (EPS,
|
---|
| 1734 | +% PDF), only painters generates vector graphics. 2) For bitmaps, only
|
---|
| 1735 | % opengl can render transparent patch objects correctly. 3) For bitmaps,
|
---|
| 1736 | % only painters will correctly scale line dash and dot lengths when
|
---|
| 1737 | % magnifying or anti-aliasing. 4) Fonts may be substitued with Courier when
|
---|
| 1738 | % using painters.
|
---|
| 1739 | %
|
---|
| 1740 | -% When exporting to vector format (pdf & eps) and bitmap format using the
|
---|
| 1741 | +% When exporting to vector format (PDF & EPS) and bitmap format using the
|
---|
| 1742 | % painters renderer, this function requires that ghostscript is installed
|
---|
| 1743 | % on your system. You can download this from:
|
---|
| 1744 | % http://www.ghostscript.com
|
---|
| 1745 | @@ -67,7 +73,7 @@
|
---|
| 1746 | % suite of functions. You can download this from:
|
---|
| 1747 | % http://www.foolabs.com/xpdf
|
---|
| 1748 | %
|
---|
| 1749 | -%IN:
|
---|
| 1750 | +% Inputs:
|
---|
| 1751 | % filename - string containing the name (optionally including full or
|
---|
| 1752 | % relative path) of the file the figure is to be saved as. If
|
---|
| 1753 | % a path is not specified, the figure is saved in the current
|
---|
| 1754 | @@ -82,11 +88,15 @@
|
---|
| 1755 | % of formats are valid.
|
---|
| 1756 | % -nocrop - option indicating that the borders of the output are not to
|
---|
| 1757 | % be cropped.
|
---|
| 1758 | +% -c[<val>,<val>,<val>,<val>] - option indicating crop amounts. Must be
|
---|
| 1759 | +% a 4-element vector of numeric values: [top,right,bottom,left]
|
---|
| 1760 | +% where NaN/Inf indicate auto-cropping, 0 means no cropping,
|
---|
| 1761 | +% and any other value mean cropping in pixel amounts.
|
---|
| 1762 | % -transparent - option indicating that the figure background is to be
|
---|
| 1763 | -% made transparent (png, pdf and eps output only).
|
---|
| 1764 | +% made transparent (png, pdf, tif and eps output only).
|
---|
| 1765 | % -m<val> - option where val indicates the factor to magnify the
|
---|
| 1766 | % on-screen figure pixel dimensions by when generating bitmap
|
---|
| 1767 | -% outputs. Default: '-m1'.
|
---|
| 1768 | +% outputs (does not affect vector formats). Default: '-m1'.
|
---|
| 1769 | % -r<val> - option val indicates the resolution (in pixels per inch) to
|
---|
| 1770 | % export bitmap and vector outputs at, keeping the dimensions
|
---|
| 1771 | % of the on-screen figure. Default: '-r864' (for vector output
|
---|
| 1772 | @@ -105,9 +115,10 @@
|
---|
| 1773 | % -a1, -a2, -a3, -a4 - option indicating the amount of anti-aliasing to
|
---|
| 1774 | % use for bitmap outputs. '-a1' means no anti-
|
---|
| 1775 | % aliasing; '-a4' is the maximum amount (default).
|
---|
| 1776 | -% -<renderer> - option to force a particular renderer (painters, opengl
|
---|
| 1777 | -% or zbuffer) to be used over the default: opengl for
|
---|
| 1778 | -% bitmaps; painters for vector formats.
|
---|
| 1779 | +% -<renderer> - option to force a particular renderer (painters, opengl or
|
---|
| 1780 | +% zbuffer). Default value: opengl for bitmap formats or
|
---|
| 1781 | +% figures with patches and/or transparent annotations;
|
---|
| 1782 | +% painters for vector formats without patches/transparencies.
|
---|
| 1783 | % -<colorspace> - option indicating which colorspace color figures should
|
---|
| 1784 | % be saved in: RGB (default), CMYK or gray. CMYK is only
|
---|
| 1785 | % supported in pdf, eps and tiff output.
|
---|
| 1786 | @@ -118,29 +129,45 @@
|
---|
| 1787 | % default for pdf & eps. Note: lossless compression can
|
---|
| 1788 | % sometimes give a smaller file size than the default lossy
|
---|
| 1789 | % compression, depending on the type of images.
|
---|
| 1790 | -% -p<val> - option to add a border of width val to eps and pdf files,
|
---|
| 1791 | -% where val is in units of the intermediate eps file. Default:
|
---|
| 1792 | -% 0 (i.e. no padding).
|
---|
| 1793 | +% -p<val> - option to pad a border of width val to exported files, where
|
---|
| 1794 | +% val is either a relative size with respect to cropped image
|
---|
| 1795 | +% size (i.e. p=0.01 adds a 1% border). For EPS & PDF formats,
|
---|
| 1796 | +% val can also be integer in units of 1/72" points (abs(val)>1).
|
---|
| 1797 | +% val can be positive (padding) or negative (extra cropping).
|
---|
| 1798 | +% If used, the -nocrop flag will be ignored, i.e. the image will
|
---|
| 1799 | +% always be cropped and then padded. Default: 0 (i.e. no padding).
|
---|
| 1800 | % -append - option indicating that if the file (pdfs only) already
|
---|
| 1801 | % exists, the figure is to be appended as a new page, instead
|
---|
| 1802 | % of being overwritten (default).
|
---|
| 1803 | % -bookmark - option to indicate that a bookmark with the name of the
|
---|
| 1804 | % figure is to be created in the output file (pdf only).
|
---|
| 1805 | -% handle - The handle of the figure, axes or uipanels (can be an array of
|
---|
| 1806 | -% handles, but the objects must be in the same figure) to be
|
---|
| 1807 | -% saved. Default: gcf.
|
---|
| 1808 | +% -clipboard - option to save output as an image on the system clipboard.
|
---|
| 1809 | +% Note: background transparency is not preserved in clipboard
|
---|
| 1810 | +% -d<gs_option> - option to indicate a ghostscript setting. For example,
|
---|
| 1811 | +% -dMaxBitmap=0 or -dNoOutputFonts (Ghostscript 9.15+).
|
---|
| 1812 | +% -depsc - option to use EPS level-3 rather than the default level-2 print
|
---|
| 1813 | +% device. This solves some bugs with Matlab's default -depsc2 device
|
---|
| 1814 | +% such as discolored subplot lines on images (vector formats only).
|
---|
| 1815 | +% -update - option to download and install the latest version of export_fig
|
---|
| 1816 | +% -nofontswap - option to avoid font swapping. Font swapping is automatically
|
---|
| 1817 | +% done in vector formats (only): 11 standard Matlab fonts are
|
---|
| 1818 | +% replaced by the original figure fonts. This option prevents this.
|
---|
| 1819 | +% handle - The handle of the figure, axes or uipanels (can be an array of
|
---|
| 1820 | +% handles, but the objects must be in the same figure) to be
|
---|
| 1821 | +% saved. Default: gcf.
|
---|
| 1822 | %
|
---|
| 1823 | -%OUT:
|
---|
| 1824 | -% im - MxNxC uint8 image array of the figure.
|
---|
| 1825 | -% alpha - MxN single array of alphamatte values in range [0,1], for the
|
---|
| 1826 | -% case when the background is transparent.
|
---|
| 1827 | +% Outputs:
|
---|
| 1828 | +% imageData - MxNxC uint8 image array of the exported image.
|
---|
| 1829 | +% alpha - MxN single array of alphamatte values in the range [0,1],
|
---|
| 1830 | +% for the case when the background is transparent.
|
---|
| 1831 | %
|
---|
| 1832 | % Some helpful examples and tips can be found at:
|
---|
| 1833 | -% https://github.com/ojwoodford/export_fig
|
---|
| 1834 | +% https://github.com/altmany/export_fig
|
---|
| 1835 | %
|
---|
| 1836 | -% See also PRINT, SAVEAS.
|
---|
| 1837 | +% See also PRINT, SAVEAS, ScreenCapture (on the Matlab File Exchange)
|
---|
| 1838 |
|
---|
| 1839 | -% Copyright (C) Oliver Woodford 2008-2014
|
---|
| 1840 | +%{
|
---|
| 1841 | +% Copyright (C) Oliver Woodford 2008-2014, Yair Altman 2015-
|
---|
| 1842 |
|
---|
| 1843 | % The idea of using ghostscript is inspired by Peder Axensten's SAVEFIG
|
---|
| 1844 | % (fex id: 10889) which is itself inspired by EPS2PDF (fex id: 5782).
|
---|
| 1845 | @@ -161,639 +188,1095 @@
|
---|
| 1846 | % fix anyway.
|
---|
| 1847 | % Thanks to Tammy Threadgill for reporting a bug where an axes is not
|
---|
| 1848 | % isolated from gui objects.
|
---|
| 1849 | -
|
---|
| 1850 | +%}
|
---|
| 1851 | +%{
|
---|
| 1852 | % 23/02/12: Ensure that axes limits don't change during printing
|
---|
| 1853 | -% 14/03/12: Fix bug in fixing the axes limits (thanks to Tobias Lamour for
|
---|
| 1854 | -% reporting it).
|
---|
| 1855 | -% 02/05/12: Incorporate patch of Petr Nechaev (many thanks), enabling
|
---|
| 1856 | -% bookmarking of figures in pdf files.
|
---|
| 1857 | -% 09/05/12: Incorporate patch of Arcelia Arrieta (many thanks), to keep
|
---|
| 1858 | -% tick marks fixed.
|
---|
| 1859 | -% 12/12/12: Add support for isolating uipanels. Thanks to michael for
|
---|
| 1860 | -% suggesting it.
|
---|
| 1861 | -% 25/09/13: Add support for changing resolution in vector formats. Thanks
|
---|
| 1862 | -% to Jan Jaap Meijer for suggesting it.
|
---|
| 1863 | -% 07/05/14: Add support for '~' at start of path. Thanks to Sally Warner
|
---|
| 1864 | -% for suggesting it.
|
---|
| 1865 | +% 14/03/12: Fix bug in fixing the axes limits (thanks to Tobias Lamour for reporting it).
|
---|
| 1866 | +% 02/05/12: Incorporate patch of Petr Nechaev (many thanks), enabling bookmarking of figures in pdf files.
|
---|
| 1867 | +% 09/05/12: Incorporate patch of Arcelia Arrieta (many thanks), to keep tick marks fixed.
|
---|
| 1868 | +% 12/12/12: Add support for isolating uipanels. Thanks to michael for suggesting it.
|
---|
| 1869 | +% 25/09/13: Add support for changing resolution in vector formats. Thanks to Jan Jaap Meijer for suggesting it.
|
---|
| 1870 | +% 07/05/14: Add support for '~' at start of path. Thanks to Sally Warner for suggesting it.
|
---|
| 1871 | +% 24/02/15: Fix Matlab R2014b bug (issue #34): plot markers are not displayed when ZLimMode='manual'
|
---|
| 1872 | +% 25/02/15: Fix issue #4 (using HG2 on R2014a and earlier)
|
---|
| 1873 | +% 25/02/15: Fix issue #21 (bold TeX axes labels/titles in R2014b)
|
---|
| 1874 | +% 26/02/15: If temp dir is not writable, use the user-specified folder for temporary EPS/PDF files (Javier Paredes)
|
---|
| 1875 | +% 27/02/15: Modified repository URL from github.com/ojwoodford to /altmany
|
---|
| 1876 | +% Indented main function
|
---|
| 1877 | +% Added top-level try-catch block to display useful workarounds
|
---|
| 1878 | +% 28/02/15: Enable users to specify optional ghostscript options (issue #36)
|
---|
| 1879 | +% 06/03/15: Improved image padding & cropping thanks to Oscar Hartogensis
|
---|
| 1880 | +% 26/03/15: Fixed issue #49 (bug with transparent grayscale images); fixed out-of-memory issue
|
---|
| 1881 | +% 26/03/15: Fixed issue #42: non-normalized annotations on HG1
|
---|
| 1882 | +% 26/03/15: Fixed issue #46: Ghostscript crash if figure units <> pixels
|
---|
| 1883 | +% 27/03/15: Fixed issue #39: bad export of transparent annotations/patches
|
---|
| 1884 | +% 28/03/15: Fixed issue #50: error on some Matlab versions with the fix for issue #42
|
---|
| 1885 | +% 29/03/15: Fixed issue #33: bugs in Matlab's print() function with -cmyk
|
---|
| 1886 | +% 29/03/15: Improved processing of input args (accept space between param name & value, related to issue #51)
|
---|
| 1887 | +% 30/03/15: When exporting *.fig files, then saveas *.fig if figure is open, otherwise export the specified fig file
|
---|
| 1888 | +% 30/03/15: Fixed edge case bug introduced yesterday (commit #ae1755bd2e11dc4e99b95a7681f6e211b3fa9358)
|
---|
| 1889 | +% 09/04/15: Consolidated header comment sections; initialize output vars only if requested (nargout>0)
|
---|
| 1890 | +% 14/04/15: Workaround for issue #45: lines in image subplots are exported in invalid color
|
---|
| 1891 | +% 15/04/15: Fixed edge-case in parsing input parameters; fixed help section to show the -depsc option (issue #45)
|
---|
| 1892 | +% 21/04/15: Bug fix: Ghostscript croaks on % chars in output PDF file (reported by Sven on FEX page, 15-Jul-2014)
|
---|
| 1893 | +% 22/04/15: Bug fix: Pdftops croaks on relative paths (reported by Tintin Milou on FEX page, 19-Jan-2015)
|
---|
| 1894 | +% 04/05/15: Merged fix #63 (Kevin Mattheus Moerman): prevent tick-label changes during export
|
---|
| 1895 | +% 07/05/15: Partial fix for issue #65: PDF export used painters rather than opengl renderer (thanks Nguyenr)
|
---|
| 1896 | +% 08/05/15: Fixed issue #65: bad PDF append since commit #e9f3cdf 21/04/15 (thanks Robert Nguyen)
|
---|
| 1897 | +% 12/05/15: Fixed issue #67: exponent labels cropped in export, since fix #63 (04/05/15)
|
---|
| 1898 | +% 28/05/15: Fixed issue #69: set non-bold label font only if the string contains symbols (\beta etc.), followup to issue #21
|
---|
| 1899 | +% 29/05/15: Added informative error message in case user requested SVG output (issue #72)
|
---|
| 1900 | +% 09/06/15: Fixed issue #58: -transparent removed anti-aliasing when exporting to PNG
|
---|
| 1901 | +% 19/06/15: Added -update option to download and install the latest version of export_fig
|
---|
| 1902 | +% 07/07/15: Added -nofontswap option to avoid font-swapping in EPS/PDF
|
---|
| 1903 | +% 16/07/15: Fixed problem with anti-aliasing on old Matlab releases
|
---|
| 1904 | +% 11/09/15: Fixed issue #103: magnification must never become negative; also fixed reported error msg in parsing input params
|
---|
| 1905 | +% 26/09/15: Alert if trying to export transparent patches/areas to non-PNG outputs (issue #108)
|
---|
| 1906 | +% 04/10/15: Do not suggest workarounds for certain errors that have already been handled previously
|
---|
| 1907 | +% 01/11/15: Fixed issue #112: use same renderer in print2eps as export_fig (thanks to Jesús Pestana Puerta)
|
---|
| 1908 | +% 10/11/15: Custom GS installation webpage for MacOS. Thanks to Andy Hueni via FEX
|
---|
| 1909 | +% 19/11/15: Fixed clipboard export in R2015b (thanks to Dan K via FEX)
|
---|
| 1910 | +% 21/02/16: Added -c option for indicating specific crop amounts (idea by Cedric Noordam on FEX)
|
---|
| 1911 | +% 08/05/16: Added message about possible error reason when groot.Units~=pixels (issue #149)
|
---|
| 1912 | +% 17/05/16: Fixed case of image YData containing more than 2 elements (issue #151)
|
---|
| 1913 | +% 08/08/16: Enabled exporting transparency to TIF, in addition to PNG/PDF (issue #168)
|
---|
| 1914 | +%}
|
---|
| 1915 |
|
---|
| 1916 | -function [im, alpha] = export_fig(varargin)
|
---|
| 1917 | -% Make sure the figure is rendered correctly _now_ so that properties like
|
---|
| 1918 | -% axes limits are up-to-date.
|
---|
| 1919 | -drawnow;
|
---|
| 1920 | -% Parse the input arguments
|
---|
| 1921 | -[fig, options] = parse_args(nargout, varargin{:});
|
---|
| 1922 | -% Isolate the subplot, if it is one
|
---|
| 1923 | -cls = all(ismember(get(fig, 'Type'), {'axes', 'uipanel'}));
|
---|
| 1924 | -if cls
|
---|
| 1925 | - % Given handles of one or more axes, so isolate them from the rest
|
---|
| 1926 | - fig = isolate_axes(fig);
|
---|
| 1927 | -else
|
---|
| 1928 | - % Check we have a figure
|
---|
| 1929 | - if ~isequal(get(fig, 'Type'), 'figure');
|
---|
| 1930 | - error('Handle must be that of a figure, axes or uipanel');
|
---|
| 1931 | + if nargout
|
---|
| 1932 | + [imageData, alpha] = deal([]);
|
---|
| 1933 | end
|
---|
| 1934 | - % Get the old InvertHardcopy mode
|
---|
| 1935 | - old_mode = get(fig, 'InvertHardcopy');
|
---|
| 1936 | -end
|
---|
| 1937 | -% Hack the font units where necessary (due to a font rendering bug in
|
---|
| 1938 | -% print?). This may not work perfectly in all cases. Also it can change the
|
---|
| 1939 | -% figure layout if reverted, so use a copy.
|
---|
| 1940 | -magnify = options.magnify * options.aa_factor;
|
---|
| 1941 | -if isbitmap(options) && magnify ~= 1
|
---|
| 1942 | - fontu = findobj(fig, 'FontUnits', 'normalized');
|
---|
| 1943 | - if ~isempty(fontu)
|
---|
| 1944 | - % Some normalized font units found
|
---|
| 1945 | - if ~cls
|
---|
| 1946 | - fig = copyfig(fig);
|
---|
| 1947 | - set(fig, 'Visible', 'off');
|
---|
| 1948 | - fontu = findobj(fig, 'FontUnits', 'normalized');
|
---|
| 1949 | - cls = true;
|
---|
| 1950 | + hadError = false;
|
---|
| 1951 | + displaySuggestedWorkarounds = true;
|
---|
| 1952 | +
|
---|
| 1953 | + % Ensure the figure is rendered correctly _now_ so that properties like axes limits are up-to-date
|
---|
| 1954 | + drawnow;
|
---|
| 1955 | + pause(0.05); % this solves timing issues with Java Swing's EDT (http://undocumentedmatlab.com/blog/solving-a-matlab-hang-problem)
|
---|
| 1956 | +
|
---|
| 1957 | + % Parse the input arguments
|
---|
| 1958 | + fig = get(0, 'CurrentFigure');
|
---|
| 1959 | + [fig, options] = parse_args(nargout, fig, varargin{:});
|
---|
| 1960 | +
|
---|
| 1961 | + % Ensure that we have a figure handle
|
---|
| 1962 | + if isequal(fig,-1)
|
---|
| 1963 | + return; % silent bail-out
|
---|
| 1964 | + elseif isempty(fig)
|
---|
| 1965 | + error('No figure found');
|
---|
| 1966 | + end
|
---|
| 1967 | +
|
---|
| 1968 | + % Isolate the subplot, if it is one
|
---|
| 1969 | + cls = all(ismember(get(fig, 'Type'), {'axes', 'uipanel'}));
|
---|
| 1970 | + if cls
|
---|
| 1971 | + % Given handles of one or more axes, so isolate them from the rest
|
---|
| 1972 | + fig = isolate_axes(fig);
|
---|
| 1973 | + else
|
---|
| 1974 | + % Check we have a figure
|
---|
| 1975 | + if ~isequal(get(fig, 'Type'), 'figure');
|
---|
| 1976 | + error('Handle must be that of a figure, axes or uipanel');
|
---|
| 1977 | end
|
---|
| 1978 | - set(fontu, 'FontUnits', 'points');
|
---|
| 1979 | + % Get the old InvertHardcopy mode
|
---|
| 1980 | + old_mode = get(fig, 'InvertHardcopy');
|
---|
| 1981 | end
|
---|
| 1982 | -end
|
---|
| 1983 | -% MATLAB "feature": axes limits and tick marks can change when printing
|
---|
| 1984 | -Hlims = findall(fig, 'Type', 'axes');
|
---|
| 1985 | -if ~cls
|
---|
| 1986 | - % Record the old axes limit and tick modes
|
---|
| 1987 | - Xlims = make_cell(get(Hlims, 'XLimMode'));
|
---|
| 1988 | - Ylims = make_cell(get(Hlims, 'YLimMode'));
|
---|
| 1989 | - Zlims = make_cell(get(Hlims, 'ZLimMode'));
|
---|
| 1990 | - Xtick = make_cell(get(Hlims, 'XTickMode'));
|
---|
| 1991 | - Ytick = make_cell(get(Hlims, 'YTickMode'));
|
---|
| 1992 | - Ztick = make_cell(get(Hlims, 'ZTickMode'));
|
---|
| 1993 | -end
|
---|
| 1994 | -% Set all axes limit and tick modes to manual, so the limits and ticks can't change
|
---|
| 1995 | -set(Hlims, 'XLimMode', 'manual', 'YLimMode', 'manual', 'ZLimMode', 'manual');
|
---|
| 1996 | -set_tick_mode(Hlims, 'X');
|
---|
| 1997 | -set_tick_mode(Hlims, 'Y');
|
---|
| 1998 | -set_tick_mode(Hlims, 'Z');
|
---|
| 1999 | -% Set to print exactly what is there
|
---|
| 2000 | -set(fig, 'InvertHardcopy', 'off');
|
---|
| 2001 | -% Set the renderer
|
---|
| 2002 | -switch options.renderer
|
---|
| 2003 | - case 1
|
---|
| 2004 | - renderer = '-opengl';
|
---|
| 2005 | - case 2
|
---|
| 2006 | - renderer = '-zbuffer';
|
---|
| 2007 | - case 3
|
---|
| 2008 | - renderer = '-painters';
|
---|
| 2009 | - otherwise
|
---|
| 2010 | - renderer = '-opengl'; % Default for bitmaps
|
---|
| 2011 | -end
|
---|
| 2012 | -% Do the bitmap formats first
|
---|
| 2013 | -if isbitmap(options)
|
---|
| 2014 | - % Get the background colour
|
---|
| 2015 | - if options.transparent && (options.png || options.alpha)
|
---|
| 2016 | - % Get out an alpha channel
|
---|
| 2017 | - % MATLAB "feature": black colorbar axes can change to white and vice versa!
|
---|
| 2018 | - hCB = findobj(fig, 'Type', 'axes', 'Tag', 'Colorbar');
|
---|
| 2019 | - if isempty(hCB)
|
---|
| 2020 | - yCol = [];
|
---|
| 2021 | - xCol = [];
|
---|
| 2022 | - else
|
---|
| 2023 | - yCol = get(hCB, 'YColor');
|
---|
| 2024 | - xCol = get(hCB, 'XColor');
|
---|
| 2025 | - if iscell(yCol)
|
---|
| 2026 | - yCol = cell2mat(yCol);
|
---|
| 2027 | - xCol = cell2mat(xCol);
|
---|
| 2028 | +
|
---|
| 2029 | + % Hack the font units where necessary (due to a font rendering bug in print?).
|
---|
| 2030 | + % This may not work perfectly in all cases.
|
---|
| 2031 | + % Also it can change the figure layout if reverted, so use a copy.
|
---|
| 2032 | + magnify = options.magnify * options.aa_factor;
|
---|
| 2033 | + if isbitmap(options) && magnify ~= 1
|
---|
| 2034 | + fontu = findall(fig, 'FontUnits', 'normalized');
|
---|
| 2035 | + if ~isempty(fontu)
|
---|
| 2036 | + % Some normalized font units found
|
---|
| 2037 | + if ~cls
|
---|
| 2038 | + fig = copyfig(fig);
|
---|
| 2039 | + set(fig, 'Visible', 'off');
|
---|
| 2040 | + fontu = findall(fig, 'FontUnits', 'normalized');
|
---|
| 2041 | + cls = true;
|
---|
| 2042 | end
|
---|
| 2043 | - yCol = sum(yCol, 2);
|
---|
| 2044 | - xCol = sum(xCol, 2);
|
---|
| 2045 | + set(fontu, 'FontUnits', 'points');
|
---|
| 2046 | end
|
---|
| 2047 | - % MATLAB "feature": apparently figure size can change when changing
|
---|
| 2048 | - % colour in -nodisplay mode
|
---|
| 2049 | - pos = get(fig, 'Position');
|
---|
| 2050 | - % Set the background colour to black, and set size in case it was
|
---|
| 2051 | - % changed internally
|
---|
| 2052 | - tcol = get(fig, 'Color');
|
---|
| 2053 | - set(fig, 'Color', 'k', 'Position', pos);
|
---|
| 2054 | - % Correct the colorbar axes colours
|
---|
| 2055 | - set(hCB(yCol==0), 'YColor', [0 0 0]);
|
---|
| 2056 | - set(hCB(xCol==0), 'XColor', [0 0 0]);
|
---|
| 2057 | - % Print large version to array
|
---|
| 2058 | - B = print2array(fig, magnify, renderer);
|
---|
| 2059 | - % Downscale the image
|
---|
| 2060 | - B = downsize(single(B), options.aa_factor);
|
---|
| 2061 | - % Set background to white (and set size)
|
---|
| 2062 | - set(fig, 'Color', 'w', 'Position', pos);
|
---|
| 2063 | - % Correct the colorbar axes colours
|
---|
| 2064 | - set(hCB(yCol==3), 'YColor', [1 1 1]);
|
---|
| 2065 | - set(hCB(xCol==3), 'XColor', [1 1 1]);
|
---|
| 2066 | - % Print large version to array
|
---|
| 2067 | - A = print2array(fig, magnify, renderer);
|
---|
| 2068 | - % Downscale the image
|
---|
| 2069 | - A = downsize(single(A), options.aa_factor);
|
---|
| 2070 | - % Set the background colour (and size) back to normal
|
---|
| 2071 | - set(fig, 'Color', tcol, 'Position', pos);
|
---|
| 2072 | - % Compute the alpha map
|
---|
| 2073 | - alpha = round(sum(B - A, 3)) / (255 * 3) + 1;
|
---|
| 2074 | - A = alpha;
|
---|
| 2075 | - A(A==0) = 1;
|
---|
| 2076 | - A = B ./ A(:,:,[1 1 1]);
|
---|
| 2077 | - clear B
|
---|
| 2078 | - % Convert to greyscale
|
---|
| 2079 | - if options.colourspace == 2
|
---|
| 2080 | - A = rgb2grey(A);
|
---|
| 2081 | - end
|
---|
| 2082 | - A = uint8(A);
|
---|
| 2083 | - % Crop the background
|
---|
| 2084 | - if options.crop
|
---|
| 2085 | - [alpha, v] = crop_borders(alpha, 0, 1);
|
---|
| 2086 | - A = A(v(1):v(2),v(3):v(4),:);
|
---|
| 2087 | - end
|
---|
| 2088 | - if options.png
|
---|
| 2089 | - % Compute the resolution
|
---|
| 2090 | - res = options.magnify * get(0, 'ScreenPixelsPerInch') / 25.4e-3;
|
---|
| 2091 | - % Save the png
|
---|
| 2092 | - imwrite(A, [options.name '.png'], 'Alpha', double(alpha), 'ResolutionUnit', 'meter', 'XResolution', res, 'YResolution', res);
|
---|
| 2093 | - % Clear the png bit
|
---|
| 2094 | - options.png = false;
|
---|
| 2095 | - end
|
---|
| 2096 | - % Return only one channel for greyscale
|
---|
| 2097 | - if isbitmap(options)
|
---|
| 2098 | - A = check_greyscale(A);
|
---|
| 2099 | - end
|
---|
| 2100 | - if options.alpha
|
---|
| 2101 | - % Store the image
|
---|
| 2102 | - im = A;
|
---|
| 2103 | - % Clear the alpha bit
|
---|
| 2104 | - options.alpha = false;
|
---|
| 2105 | - end
|
---|
| 2106 | - % Get the non-alpha image
|
---|
| 2107 | - if isbitmap(options)
|
---|
| 2108 | - alph = alpha(:,:,ones(1, size(A, 3)));
|
---|
| 2109 | - A = uint8(single(A) .* alph + 255 * (1 - alph));
|
---|
| 2110 | - clear alph
|
---|
| 2111 | - end
|
---|
| 2112 | - if options.im
|
---|
| 2113 | - % Store the new image
|
---|
| 2114 | - im = A;
|
---|
| 2115 | - end
|
---|
| 2116 | - else
|
---|
| 2117 | - % Print large version to array
|
---|
| 2118 | - if options.transparent
|
---|
| 2119 | - % MATLAB "feature": apparently figure size can change when changing
|
---|
| 2120 | - % colour in -nodisplay mode
|
---|
| 2121 | - pos = get(fig, 'Position');
|
---|
| 2122 | - tcol = get(fig, 'Color');
|
---|
| 2123 | - set(fig, 'Color', 'w', 'Position', pos);
|
---|
| 2124 | - A = print2array(fig, magnify, renderer);
|
---|
| 2125 | - set(fig, 'Color', tcol, 'Position', pos);
|
---|
| 2126 | - tcol = 255;
|
---|
| 2127 | - else
|
---|
| 2128 | - [A, tcol] = print2array(fig, magnify, renderer);
|
---|
| 2129 | - end
|
---|
| 2130 | - % Crop the background
|
---|
| 2131 | - if options.crop
|
---|
| 2132 | - A = crop_borders(A, tcol, 1);
|
---|
| 2133 | - end
|
---|
| 2134 | - % Downscale the image
|
---|
| 2135 | - A = downsize(A, options.aa_factor);
|
---|
| 2136 | - if options.colourspace == 2
|
---|
| 2137 | - % Convert to greyscale
|
---|
| 2138 | - A = rgb2grey(A);
|
---|
| 2139 | - else
|
---|
| 2140 | - % Return only one channel for greyscale
|
---|
| 2141 | - A = check_greyscale(A);
|
---|
| 2142 | - end
|
---|
| 2143 | - % Outputs
|
---|
| 2144 | - if options.im
|
---|
| 2145 | - im = A;
|
---|
| 2146 | - end
|
---|
| 2147 | - if options.alpha
|
---|
| 2148 | - im = A;
|
---|
| 2149 | - alpha = zeros(size(A, 1), size(A, 2), 'single');
|
---|
| 2150 | - end
|
---|
| 2151 | end
|
---|
| 2152 | - % Save the images
|
---|
| 2153 | - if options.png
|
---|
| 2154 | - res = options.magnify * get(0, 'ScreenPixelsPerInch') / 25.4e-3;
|
---|
| 2155 | - imwrite(A, [options.name '.png'], 'ResolutionUnit', 'meter', 'XResolution', res, 'YResolution', res);
|
---|
| 2156 | - end
|
---|
| 2157 | - if options.bmp
|
---|
| 2158 | - imwrite(A, [options.name '.bmp']);
|
---|
| 2159 | - end
|
---|
| 2160 | - % Save jpeg with given quality
|
---|
| 2161 | - if options.jpg
|
---|
| 2162 | - quality = options.quality;
|
---|
| 2163 | - if isempty(quality)
|
---|
| 2164 | - quality = 95;
|
---|
| 2165 | +
|
---|
| 2166 | + try
|
---|
| 2167 | + % MATLAB "feature": axes limits and tick marks can change when printing
|
---|
| 2168 | + Hlims = findall(fig, 'Type', 'axes');
|
---|
| 2169 | + if ~cls
|
---|
| 2170 | + % Record the old axes limit and tick modes
|
---|
| 2171 | + Xlims = make_cell(get(Hlims, 'XLimMode'));
|
---|
| 2172 | + Ylims = make_cell(get(Hlims, 'YLimMode'));
|
---|
| 2173 | + Zlims = make_cell(get(Hlims, 'ZLimMode'));
|
---|
| 2174 | + Xtick = make_cell(get(Hlims, 'XTickMode'));
|
---|
| 2175 | + Ytick = make_cell(get(Hlims, 'YTickMode'));
|
---|
| 2176 | + Ztick = make_cell(get(Hlims, 'ZTickMode'));
|
---|
| 2177 | + Xlabel = make_cell(get(Hlims, 'XTickLabelMode'));
|
---|
| 2178 | + Ylabel = make_cell(get(Hlims, 'YTickLabelMode'));
|
---|
| 2179 | + Zlabel = make_cell(get(Hlims, 'ZTickLabelMode'));
|
---|
| 2180 | end
|
---|
| 2181 | - if quality > 100
|
---|
| 2182 | - imwrite(A, [options.name '.jpg'], 'Mode', 'lossless');
|
---|
| 2183 | - else
|
---|
| 2184 | - imwrite(A, [options.name '.jpg'], 'Quality', quality);
|
---|
| 2185 | +
|
---|
| 2186 | + % Set all axes limit and tick modes to manual, so the limits and ticks can't change
|
---|
| 2187 | + % Fix Matlab R2014b bug (issue #34): plot markers are not displayed when ZLimMode='manual'
|
---|
| 2188 | + set(Hlims, 'XLimMode', 'manual', 'YLimMode', 'manual');
|
---|
| 2189 | + set_tick_mode(Hlims, 'X');
|
---|
| 2190 | + set_tick_mode(Hlims, 'Y');
|
---|
| 2191 | + if ~using_hg2(fig)
|
---|
| 2192 | + set(Hlims,'ZLimMode', 'manual');
|
---|
| 2193 | + set_tick_mode(Hlims, 'Z');
|
---|
| 2194 | end
|
---|
| 2195 | + catch
|
---|
| 2196 | + % ignore - fix issue #4 (using HG2 on R2014a and earlier)
|
---|
| 2197 | end
|
---|
| 2198 | - % Save tif images in cmyk if wanted (and possible)
|
---|
| 2199 | - if options.tif
|
---|
| 2200 | - if options.colourspace == 1 && size(A, 3) == 3
|
---|
| 2201 | - A = double(255 - A);
|
---|
| 2202 | - K = min(A, [], 3);
|
---|
| 2203 | - K_ = 255 ./ max(255 - K, 1);
|
---|
| 2204 | - C = (A(:,:,1) - K) .* K_;
|
---|
| 2205 | - M = (A(:,:,2) - K) .* K_;
|
---|
| 2206 | - Y = (A(:,:,3) - K) .* K_;
|
---|
| 2207 | - A = uint8(cat(3, C, M, Y, K));
|
---|
| 2208 | - clear C M Y K K_
|
---|
| 2209 | +
|
---|
| 2210 | + % Fix issue #21 (bold TeX axes labels/titles in R2014b when exporting to EPS/PDF)
|
---|
| 2211 | + try
|
---|
| 2212 | + if using_hg2(fig) && isvector(options)
|
---|
| 2213 | + % Set the FontWeight of axes labels/titles to 'normal'
|
---|
| 2214 | + % Fix issue #69: set non-bold font only if the string contains symbols (\beta etc.)
|
---|
| 2215 | + texLabels = findall(fig, 'type','text', 'FontWeight','bold');
|
---|
| 2216 | + symbolIdx = ~cellfun('isempty',strfind({texLabels.String},'\'));
|
---|
| 2217 | + set(texLabels(symbolIdx), 'FontWeight','normal');
|
---|
| 2218 | end
|
---|
| 2219 | - append_mode = {'overwrite', 'append'};
|
---|
| 2220 | - imwrite(A, [options.name '.tif'], 'Resolution', options.magnify*get(0, 'ScreenPixelsPerInch'), 'WriteMode', append_mode{options.append+1});
|
---|
| 2221 | + catch
|
---|
| 2222 | + % ignore
|
---|
| 2223 | end
|
---|
| 2224 | -end
|
---|
| 2225 | -% Now do the vector formats
|
---|
| 2226 | -if isvector(options)
|
---|
| 2227 | - % Set the default renderer to painters
|
---|
| 2228 | - if ~options.renderer
|
---|
| 2229 | - renderer = '-painters';
|
---|
| 2230 | - end
|
---|
| 2231 | - % Generate some filenames
|
---|
| 2232 | - tmp_nam = [tempname '.eps'];
|
---|
| 2233 | - if options.pdf
|
---|
| 2234 | - pdf_nam = [options.name '.pdf'];
|
---|
| 2235 | - else
|
---|
| 2236 | - pdf_nam = [tempname '.pdf'];
|
---|
| 2237 | - end
|
---|
| 2238 | - % Generate the options for print
|
---|
| 2239 | - p2eArgs = {renderer, sprintf('-r%d', options.resolution)};
|
---|
| 2240 | - if options.colourspace == 1
|
---|
| 2241 | - p2eArgs = [p2eArgs {'-cmyk'}];
|
---|
| 2242 | - end
|
---|
| 2243 | - if ~options.crop
|
---|
| 2244 | - p2eArgs = [p2eArgs {'-loose'}];
|
---|
| 2245 | - end
|
---|
| 2246 | +
|
---|
| 2247 | + % Fix issue #42: non-normalized annotations on HG1 (internal Matlab bug)
|
---|
| 2248 | + annotationHandles = [];
|
---|
| 2249 | try
|
---|
| 2250 | - % Generate an eps
|
---|
| 2251 | - print2eps(tmp_nam, fig, options.bb_padding, p2eArgs{:});
|
---|
| 2252 | - % Remove the background, if desired
|
---|
| 2253 | - if options.transparent && ~isequal(get(fig, 'Color'), 'none')
|
---|
| 2254 | - eps_remove_background(tmp_nam, 1 + using_hg2(fig));
|
---|
| 2255 | - end
|
---|
| 2256 | - % Add a bookmark to the PDF if desired
|
---|
| 2257 | - if options.bookmark
|
---|
| 2258 | - fig_nam = get(fig, 'Name');
|
---|
| 2259 | - if isempty(fig_nam)
|
---|
| 2260 | - warning('export_fig:EmptyBookmark', 'Bookmark requested for figure with no name. Bookmark will be empty.');
|
---|
| 2261 | + if ~using_hg2(fig)
|
---|
| 2262 | + annotationHandles = findall(fig,'Type','hggroup','-and','-property','Units','-and','-not','Units','norm');
|
---|
| 2263 | + try % suggested by Jesús Pestana Puerta (jespestana) 30/9/2015
|
---|
| 2264 | + originalUnits = get(annotationHandles,'Units');
|
---|
| 2265 | + set(annotationHandles,'Units','norm');
|
---|
| 2266 | + catch
|
---|
| 2267 | end
|
---|
| 2268 | - add_bookmark(tmp_nam, fig_nam);
|
---|
| 2269 | end
|
---|
| 2270 | - % Generate a pdf
|
---|
| 2271 | - eps2pdf(tmp_nam, pdf_nam, 1, options.append, options.colourspace==2, options.quality);
|
---|
| 2272 | - catch ex
|
---|
| 2273 | - % Delete the eps
|
---|
| 2274 | - delete(tmp_nam);
|
---|
| 2275 | - rethrow(ex);
|
---|
| 2276 | + catch
|
---|
| 2277 | + % should never happen, but ignore in any case - issue #50
|
---|
| 2278 | end
|
---|
| 2279 | - % Delete the eps
|
---|
| 2280 | - delete(tmp_nam);
|
---|
| 2281 | - if options.eps
|
---|
| 2282 | - try
|
---|
| 2283 | - % Generate an eps from the pdf
|
---|
| 2284 | - pdf2eps(pdf_nam, [options.name '.eps']);
|
---|
| 2285 | - catch ex
|
---|
| 2286 | - if ~options.pdf
|
---|
| 2287 | - % Delete the pdf
|
---|
| 2288 | - delete(pdf_nam);
|
---|
| 2289 | - end
|
---|
| 2290 | - rethrow(ex);
|
---|
| 2291 | +
|
---|
| 2292 | + % Fix issue #46: Ghostscript crash if figure units <> pixels
|
---|
| 2293 | + oldFigUnits = get(fig,'Units');
|
---|
| 2294 | + set(fig,'Units','pixels');
|
---|
| 2295 | +
|
---|
| 2296 | + % Set to print exactly what is there
|
---|
| 2297 | + set(fig, 'InvertHardcopy', 'off');
|
---|
| 2298 | + % Set the renderer
|
---|
| 2299 | + switch options.renderer
|
---|
| 2300 | + case 1
|
---|
| 2301 | + renderer = '-opengl';
|
---|
| 2302 | + case 2
|
---|
| 2303 | + renderer = '-zbuffer';
|
---|
| 2304 | + case 3
|
---|
| 2305 | + renderer = '-painters';
|
---|
| 2306 | + otherwise
|
---|
| 2307 | + renderer = '-opengl'; % Default for bitmaps
|
---|
| 2308 | + end
|
---|
| 2309 | +
|
---|
| 2310 | + % Handle transparent patches
|
---|
| 2311 | + hasTransparency = ~isempty(findall(fig,'-property','FaceAlpha','-and','-not','FaceAlpha',1));
|
---|
| 2312 | + hasPatches = ~isempty(findall(fig,'type','patch'));
|
---|
| 2313 | + if hasTransparency
|
---|
| 2314 | + % Alert if trying to export transparent patches/areas to non-supported outputs (issue #108)
|
---|
| 2315 | + % http://www.mathworks.com/matlabcentral/answers/265265-can-export_fig-or-else-draw-vector-graphics-with-transparent-surfaces
|
---|
| 2316 | + % TODO - use transparency when exporting to PDF by not passing via print2eps
|
---|
| 2317 | + msg = 'export_fig currently supports transparent patches/areas only in PNG output. ';
|
---|
| 2318 | + if options.pdf
|
---|
| 2319 | + warning('export_fig:transparency', '%s\nTo export transparent patches/areas to PDF, use the print command:\n print(gcf, ''-dpdf'', ''%s.pdf'');', msg, options.name);
|
---|
| 2320 | + elseif ~options.png && ~options.tif % issue #168
|
---|
| 2321 | + warning('export_fig:transparency', '%s\nTo export the transparency correctly, try using the ScreenCapture utility on the Matlab File Exchange: http://bit.ly/1QFrBip', msg);
|
---|
| 2322 | end
|
---|
| 2323 | - if ~options.pdf
|
---|
| 2324 | - % Delete the pdf
|
---|
| 2325 | - delete(pdf_nam);
|
---|
| 2326 | - end
|
---|
| 2327 | end
|
---|
| 2328 | -end
|
---|
| 2329 | -if cls
|
---|
| 2330 | - % Close the created figure
|
---|
| 2331 | - close(fig);
|
---|
| 2332 | -else
|
---|
| 2333 | - % Reset the hardcopy mode
|
---|
| 2334 | - set(fig, 'InvertHardcopy', old_mode);
|
---|
| 2335 | - % Reset the axes limit and tick modes
|
---|
| 2336 | - for a = 1:numel(Hlims)
|
---|
| 2337 | - set(Hlims(a), 'XLimMode', Xlims{a}, 'YLimMode', Ylims{a}, 'ZLimMode', Zlims{a}, 'XTickMode', Xtick{a}, 'YTickMode', Ytick{a}, 'ZTickMode', Ztick{a});
|
---|
| 2338 | - end
|
---|
| 2339 | -end
|
---|
| 2340 | -end
|
---|
| 2341 |
|
---|
| 2342 | -function [fig, options] = parse_args(nout, varargin)
|
---|
| 2343 | -% Parse the input arguments
|
---|
| 2344 | -% Set the defaults
|
---|
| 2345 | -fig = get(0, 'CurrentFigure');
|
---|
| 2346 | -options = struct('name', 'export_fig_out', ...
|
---|
| 2347 | - 'crop', true, ...
|
---|
| 2348 | - 'transparent', false, ...
|
---|
| 2349 | - 'renderer', 0, ... % 0: default, 1: OpenGL, 2: ZBuffer, 3: Painters
|
---|
| 2350 | - 'pdf', false, ...
|
---|
| 2351 | - 'eps', false, ...
|
---|
| 2352 | - 'png', false, ...
|
---|
| 2353 | - 'tif', false, ...
|
---|
| 2354 | - 'jpg', false, ...
|
---|
| 2355 | - 'bmp', false, ...
|
---|
| 2356 | - 'colourspace', 0, ... % 0: RGB/gray, 1: CMYK, 2: gray
|
---|
| 2357 | - 'append', false, ...
|
---|
| 2358 | - 'im', nout == 1, ...
|
---|
| 2359 | - 'alpha', nout == 2, ...
|
---|
| 2360 | - 'aa_factor', 0, ...
|
---|
| 2361 | - 'bb_padding', 0, ...
|
---|
| 2362 | - 'magnify', [], ...
|
---|
| 2363 | - 'resolution', [], ...
|
---|
| 2364 | - 'bookmark', false, ...
|
---|
| 2365 | - 'quality', []);
|
---|
| 2366 | -native = false; % Set resolution to native of an image
|
---|
| 2367 | + try
|
---|
| 2368 | + % Do the bitmap formats first
|
---|
| 2369 | + if isbitmap(options)
|
---|
| 2370 | + if abs(options.bb_padding) > 1
|
---|
| 2371 | + displaySuggestedWorkarounds = false;
|
---|
| 2372 | + error('For bitmap output (png,jpg,tif,bmp) the padding value (-p) must be between -1<p<1')
|
---|
| 2373 | + end
|
---|
| 2374 | + % Get the background colour
|
---|
| 2375 | + if options.transparent && (options.png || options.alpha)
|
---|
| 2376 | + % Get out an alpha channel
|
---|
| 2377 | + % MATLAB "feature": black colorbar axes can change to white and vice versa!
|
---|
| 2378 | + hCB = findall(fig, 'Type','axes', 'Tag','Colorbar');
|
---|
| 2379 | + if isempty(hCB)
|
---|
| 2380 | + yCol = [];
|
---|
| 2381 | + xCol = [];
|
---|
| 2382 | + else
|
---|
| 2383 | + yCol = get(hCB, 'YColor');
|
---|
| 2384 | + xCol = get(hCB, 'XColor');
|
---|
| 2385 | + if iscell(yCol)
|
---|
| 2386 | + yCol = cell2mat(yCol);
|
---|
| 2387 | + xCol = cell2mat(xCol);
|
---|
| 2388 | + end
|
---|
| 2389 | + yCol = sum(yCol, 2);
|
---|
| 2390 | + xCol = sum(xCol, 2);
|
---|
| 2391 | + end
|
---|
| 2392 | + % MATLAB "feature": apparently figure size can change when changing
|
---|
| 2393 | + % colour in -nodisplay mode
|
---|
| 2394 | + pos = get(fig, 'Position');
|
---|
| 2395 | + % Set the background colour to black, and set size in case it was
|
---|
| 2396 | + % changed internally
|
---|
| 2397 | + tcol = get(fig, 'Color');
|
---|
| 2398 | + set(fig, 'Color', 'k', 'Position', pos);
|
---|
| 2399 | + % Correct the colorbar axes colours
|
---|
| 2400 | + set(hCB(yCol==0), 'YColor', [0 0 0]);
|
---|
| 2401 | + set(hCB(xCol==0), 'XColor', [0 0 0]);
|
---|
| 2402 |
|
---|
| 2403 | -% Go through the other arguments
|
---|
| 2404 | -for a = 1:nargin-1
|
---|
| 2405 | - if all(ishandle(varargin{a}))
|
---|
| 2406 | - fig = varargin{a};
|
---|
| 2407 | - elseif ischar(varargin{a}) && ~isempty(varargin{a})
|
---|
| 2408 | - if varargin{a}(1) == '-'
|
---|
| 2409 | - switch lower(varargin{a}(2:end))
|
---|
| 2410 | - case 'nocrop'
|
---|
| 2411 | - options.crop = false;
|
---|
| 2412 | - case {'trans', 'transparent'}
|
---|
| 2413 | - options.transparent = true;
|
---|
| 2414 | - case 'opengl'
|
---|
| 2415 | - options.renderer = 1;
|
---|
| 2416 | - case 'zbuffer'
|
---|
| 2417 | - options.renderer = 2;
|
---|
| 2418 | - case 'painters'
|
---|
| 2419 | - options.renderer = 3;
|
---|
| 2420 | - case 'pdf'
|
---|
| 2421 | - options.pdf = true;
|
---|
| 2422 | - case 'eps'
|
---|
| 2423 | - options.eps = true;
|
---|
| 2424 | - case 'png'
|
---|
| 2425 | - options.png = true;
|
---|
| 2426 | - case {'tif', 'tiff'}
|
---|
| 2427 | - options.tif = true;
|
---|
| 2428 | - case {'jpg', 'jpeg'}
|
---|
| 2429 | - options.jpg = true;
|
---|
| 2430 | - case 'bmp'
|
---|
| 2431 | - options.bmp = true;
|
---|
| 2432 | - case 'rgb'
|
---|
| 2433 | - options.colourspace = 0;
|
---|
| 2434 | - case 'cmyk'
|
---|
| 2435 | - options.colourspace = 1;
|
---|
| 2436 | - case {'gray', 'grey'}
|
---|
| 2437 | - options.colourspace = 2;
|
---|
| 2438 | - case {'a1', 'a2', 'a3', 'a4'}
|
---|
| 2439 | - options.aa_factor = str2double(varargin{a}(3));
|
---|
| 2440 | - case 'append'
|
---|
| 2441 | - options.append = true;
|
---|
| 2442 | - case 'bookmark'
|
---|
| 2443 | - options.bookmark = true;
|
---|
| 2444 | - case 'native'
|
---|
| 2445 | - native = true;
|
---|
| 2446 | - otherwise
|
---|
| 2447 | - val = str2double(regexp(varargin{a}, '(?<=-(m|M|r|R|q|Q|p|P))-?\d*.?\d+', 'match'));
|
---|
| 2448 | - if ~isscalar(val)
|
---|
| 2449 | - error('option %s not recognised', varargin{a});
|
---|
| 2450 | + % The following code might cause out-of-memory errors
|
---|
| 2451 | + try
|
---|
| 2452 | + % Print large version to array
|
---|
| 2453 | + B = print2array(fig, magnify, renderer);
|
---|
| 2454 | + % Downscale the image
|
---|
| 2455 | + B = downsize(single(B), options.aa_factor);
|
---|
| 2456 | + catch
|
---|
| 2457 | + % This is more conservative in memory, but kills transparency (issue #58)
|
---|
| 2458 | + B = single(print2array(fig, magnify/options.aa_factor, renderer));
|
---|
| 2459 | + end
|
---|
| 2460 | +
|
---|
| 2461 | + % Set background to white (and set size)
|
---|
| 2462 | + set(fig, 'Color', 'w', 'Position', pos);
|
---|
| 2463 | + % Correct the colorbar axes colours
|
---|
| 2464 | + set(hCB(yCol==3), 'YColor', [1 1 1]);
|
---|
| 2465 | + set(hCB(xCol==3), 'XColor', [1 1 1]);
|
---|
| 2466 | +
|
---|
| 2467 | + % The following code might cause out-of-memory errors
|
---|
| 2468 | + try
|
---|
| 2469 | + % Print large version to array
|
---|
| 2470 | + A = print2array(fig, magnify, renderer);
|
---|
| 2471 | + % Downscale the image
|
---|
| 2472 | + A = downsize(single(A), options.aa_factor);
|
---|
| 2473 | + catch
|
---|
| 2474 | + % This is more conservative in memory, but kills transparency (issue #58)
|
---|
| 2475 | + A = single(print2array(fig, magnify/options.aa_factor, renderer));
|
---|
| 2476 | + end
|
---|
| 2477 | +
|
---|
| 2478 | + % Set the background colour (and size) back to normal
|
---|
| 2479 | + set(fig, 'Color', tcol, 'Position', pos);
|
---|
| 2480 | + % Compute the alpha map
|
---|
| 2481 | + alpha = round(sum(B - A, 3)) / (255 * 3) + 1;
|
---|
| 2482 | + A = alpha;
|
---|
| 2483 | + A(A==0) = 1;
|
---|
| 2484 | + A = B ./ A(:,:,[1 1 1]);
|
---|
| 2485 | + clear B
|
---|
| 2486 | + % Convert to greyscale
|
---|
| 2487 | + if options.colourspace == 2
|
---|
| 2488 | + A = rgb2grey(A);
|
---|
| 2489 | + end
|
---|
| 2490 | + A = uint8(A);
|
---|
| 2491 | + % Crop the background
|
---|
| 2492 | + if options.crop
|
---|
| 2493 | + %[alpha, v] = crop_borders(alpha, 0, 1, options.crop_amounts);
|
---|
| 2494 | + %A = A(v(1):v(2),v(3):v(4),:);
|
---|
| 2495 | + [alpha, vA, vB] = crop_borders(alpha, 0, options.bb_padding, options.crop_amounts);
|
---|
| 2496 | + if ~any(isnan(vB)) % positive padding
|
---|
| 2497 | + B = repmat(uint8(zeros(1,1,size(A,3))),size(alpha));
|
---|
| 2498 | + B(vB(1):vB(2), vB(3):vB(4), :) = A(vA(1):vA(2), vA(3):vA(4), :); % ADDED BY OH
|
---|
| 2499 | + A = B;
|
---|
| 2500 | + else % negative padding
|
---|
| 2501 | + A = A(vA(1):vA(2), vA(3):vA(4), :);
|
---|
| 2502 | end
|
---|
| 2503 | - switch lower(varargin{a}(2))
|
---|
| 2504 | - case 'm'
|
---|
| 2505 | - options.magnify = val;
|
---|
| 2506 | - case 'r'
|
---|
| 2507 | - options.resolution = val;
|
---|
| 2508 | - case 'q'
|
---|
| 2509 | - options.quality = max(val, 0);
|
---|
| 2510 | - case 'p'
|
---|
| 2511 | - options.bb_padding = val;
|
---|
| 2512 | + end
|
---|
| 2513 | + if options.png
|
---|
| 2514 | + % Compute the resolution
|
---|
| 2515 | + res = options.magnify * get(0, 'ScreenPixelsPerInch') / 25.4e-3;
|
---|
| 2516 | + % Save the png
|
---|
| 2517 | + imwrite(A, [options.name '.png'], 'Alpha', double(alpha), 'ResolutionUnit', 'meter', 'XResolution', res, 'YResolution', res);
|
---|
| 2518 | + % Clear the png bit
|
---|
| 2519 | + options.png = false;
|
---|
| 2520 | + end
|
---|
| 2521 | + % Return only one channel for greyscale
|
---|
| 2522 | + if isbitmap(options)
|
---|
| 2523 | + A = check_greyscale(A);
|
---|
| 2524 | + end
|
---|
| 2525 | + if options.alpha
|
---|
| 2526 | + % Store the image
|
---|
| 2527 | + imageData = A;
|
---|
| 2528 | + % Clear the alpha bit
|
---|
| 2529 | + options.alpha = false;
|
---|
| 2530 | + end
|
---|
| 2531 | + % Get the non-alpha image
|
---|
| 2532 | + if isbitmap(options)
|
---|
| 2533 | + alph = alpha(:,:,ones(1, size(A, 3)));
|
---|
| 2534 | + A = uint8(single(A) .* alph + 255 * (1 - alph));
|
---|
| 2535 | + clear alph
|
---|
| 2536 | + end
|
---|
| 2537 | + if options.im
|
---|
| 2538 | + % Store the new image
|
---|
| 2539 | + imageData = A;
|
---|
| 2540 | + end
|
---|
| 2541 | + else
|
---|
| 2542 | + % Print large version to array
|
---|
| 2543 | + if options.transparent
|
---|
| 2544 | + % MATLAB "feature": apparently figure size can change when changing
|
---|
| 2545 | + % colour in -nodisplay mode
|
---|
| 2546 | + pos = get(fig, 'Position');
|
---|
| 2547 | + tcol = get(fig, 'Color');
|
---|
| 2548 | + set(fig, 'Color', 'w', 'Position', pos);
|
---|
| 2549 | + A = print2array(fig, magnify, renderer);
|
---|
| 2550 | + set(fig, 'Color', tcol, 'Position', pos);
|
---|
| 2551 | + tcol = 255;
|
---|
| 2552 | + else
|
---|
| 2553 | + [A, tcol] = print2array(fig, magnify, renderer);
|
---|
| 2554 | + end
|
---|
| 2555 | + % Crop the background
|
---|
| 2556 | + if options.crop
|
---|
| 2557 | + A = crop_borders(A, tcol, options.bb_padding, options.crop_amounts);
|
---|
| 2558 | + end
|
---|
| 2559 | + % Downscale the image
|
---|
| 2560 | + A = downsize(A, options.aa_factor);
|
---|
| 2561 | + if options.colourspace == 2
|
---|
| 2562 | + % Convert to greyscale
|
---|
| 2563 | + A = rgb2grey(A);
|
---|
| 2564 | + else
|
---|
| 2565 | + % Return only one channel for greyscale
|
---|
| 2566 | + A = check_greyscale(A);
|
---|
| 2567 | + end
|
---|
| 2568 | + % Outputs
|
---|
| 2569 | + if options.im
|
---|
| 2570 | + imageData = A;
|
---|
| 2571 | + end
|
---|
| 2572 | + if options.alpha
|
---|
| 2573 | + imageData = A;
|
---|
| 2574 | + alpha = zeros(size(A, 1), size(A, 2), 'single');
|
---|
| 2575 | + end
|
---|
| 2576 | + end
|
---|
| 2577 | + % Save the images
|
---|
| 2578 | + if options.png
|
---|
| 2579 | + res = options.magnify * get(0, 'ScreenPixelsPerInch') / 25.4e-3;
|
---|
| 2580 | + imwrite(A, [options.name '.png'], 'ResolutionUnit', 'meter', 'XResolution', res, 'YResolution', res);
|
---|
| 2581 | + end
|
---|
| 2582 | + if options.bmp
|
---|
| 2583 | + imwrite(A, [options.name '.bmp']);
|
---|
| 2584 | + end
|
---|
| 2585 | + % Save jpeg with given quality
|
---|
| 2586 | + if options.jpg
|
---|
| 2587 | + quality = options.quality;
|
---|
| 2588 | + if isempty(quality)
|
---|
| 2589 | + quality = 95;
|
---|
| 2590 | + end
|
---|
| 2591 | + if quality > 100
|
---|
| 2592 | + imwrite(A, [options.name '.jpg'], 'Mode', 'lossless');
|
---|
| 2593 | + else
|
---|
| 2594 | + imwrite(A, [options.name '.jpg'], 'Quality', quality);
|
---|
| 2595 | + end
|
---|
| 2596 | + end
|
---|
| 2597 | + % Save tif images in cmyk if wanted (and possible)
|
---|
| 2598 | + if options.tif
|
---|
| 2599 | + if options.colourspace == 1 && size(A, 3) == 3
|
---|
| 2600 | + A = double(255 - A);
|
---|
| 2601 | + K = min(A, [], 3);
|
---|
| 2602 | + K_ = 255 ./ max(255 - K, 1);
|
---|
| 2603 | + C = (A(:,:,1) - K) .* K_;
|
---|
| 2604 | + M = (A(:,:,2) - K) .* K_;
|
---|
| 2605 | + Y = (A(:,:,3) - K) .* K_;
|
---|
| 2606 | + A = uint8(cat(3, C, M, Y, K));
|
---|
| 2607 | + clear C M Y K K_
|
---|
| 2608 | + end
|
---|
| 2609 | + append_mode = {'overwrite', 'append'};
|
---|
| 2610 | + imwrite(A, [options.name '.tif'], 'Resolution', options.magnify*get(0, 'ScreenPixelsPerInch'), 'WriteMode', append_mode{options.append+1});
|
---|
| 2611 | + end
|
---|
| 2612 | + end
|
---|
| 2613 | +
|
---|
| 2614 | + % Now do the vector formats
|
---|
| 2615 | + if isvector(options)
|
---|
| 2616 | + % Set the default renderer to painters
|
---|
| 2617 | + if ~options.renderer
|
---|
| 2618 | + if hasTransparency || hasPatches
|
---|
| 2619 | + % This is *MUCH* slower, but more accurate for patches and transparent annotations (issue #39)
|
---|
| 2620 | + renderer = '-painters';
|
---|
| 2621 | + else
|
---|
| 2622 | + renderer = '-painters';
|
---|
| 2623 | + end
|
---|
| 2624 | + end
|
---|
| 2625 | + options.rendererStr = renderer; % fix for issue #112
|
---|
| 2626 | + % Generate some filenames
|
---|
| 2627 | + tmp_nam = [tempname '.eps'];
|
---|
| 2628 | + try
|
---|
| 2629 | + % Ensure that the temp dir is writable (Javier Paredes 30/1/15)
|
---|
| 2630 | + fid = fopen(tmp_nam,'w');
|
---|
| 2631 | + fwrite(fid,1);
|
---|
| 2632 | + fclose(fid);
|
---|
| 2633 | + delete(tmp_nam);
|
---|
| 2634 | + isTempDirOk = true;
|
---|
| 2635 | + catch
|
---|
| 2636 | + % Temp dir is not writable, so use the user-specified folder
|
---|
| 2637 | + [dummy,fname,fext] = fileparts(tmp_nam); %#ok<ASGLU>
|
---|
| 2638 | + fpath = fileparts(options.name);
|
---|
| 2639 | + tmp_nam = fullfile(fpath,[fname fext]);
|
---|
| 2640 | + isTempDirOk = false;
|
---|
| 2641 | + end
|
---|
| 2642 | + if isTempDirOk
|
---|
| 2643 | + pdf_nam_tmp = [tempname '.pdf'];
|
---|
| 2644 | + else
|
---|
| 2645 | + pdf_nam_tmp = fullfile(fpath,[fname '.pdf']);
|
---|
| 2646 | + end
|
---|
| 2647 | + if options.pdf
|
---|
| 2648 | + pdf_nam = [options.name '.pdf'];
|
---|
| 2649 | + try copyfile(pdf_nam, pdf_nam_tmp, 'f'); catch, end % fix for issue #65
|
---|
| 2650 | + else
|
---|
| 2651 | + pdf_nam = pdf_nam_tmp;
|
---|
| 2652 | + end
|
---|
| 2653 | + % Generate the options for print
|
---|
| 2654 | + p2eArgs = {renderer, sprintf('-r%d', options.resolution)};
|
---|
| 2655 | + if options.colourspace == 1 % CMYK
|
---|
| 2656 | + % Issue #33: due to internal bugs in Matlab's print() function, we can't use its -cmyk option
|
---|
| 2657 | + %p2eArgs{end+1} = '-cmyk';
|
---|
| 2658 | + end
|
---|
| 2659 | + if ~options.crop
|
---|
| 2660 | + % Issue #56: due to internal bugs in Matlab's print() function, we can't use its internal cropping mechanism,
|
---|
| 2661 | + % therefore we always use '-loose' (in print2eps.m) and do our own cropping (in crop_borders)
|
---|
| 2662 | + %p2eArgs{end+1} = '-loose';
|
---|
| 2663 | + end
|
---|
| 2664 | + if any(strcmpi(varargin,'-depsc'))
|
---|
| 2665 | + % Issue #45: lines in image subplots are exported in invalid color.
|
---|
| 2666 | + % The workaround is to use the -depsc parameter instead of the default -depsc2
|
---|
| 2667 | + p2eArgs{end+1} = '-depsc';
|
---|
| 2668 | + end
|
---|
| 2669 | + try
|
---|
| 2670 | + % Generate an eps
|
---|
| 2671 | + print2eps(tmp_nam, fig, options, p2eArgs{:});
|
---|
| 2672 | + % Remove the background, if desired
|
---|
| 2673 | + if options.transparent && ~isequal(get(fig, 'Color'), 'none')
|
---|
| 2674 | + eps_remove_background(tmp_nam, 1 + using_hg2(fig));
|
---|
| 2675 | + end
|
---|
| 2676 | + % Fix colorspace to CMYK, if requested (workaround for issue #33)
|
---|
| 2677 | + if options.colourspace == 1 % CMYK
|
---|
| 2678 | + % Issue #33: due to internal bugs in Matlab's print() function, we can't use its -cmyk option
|
---|
| 2679 | + change_rgb_to_cmyk(tmp_nam);
|
---|
| 2680 | + end
|
---|
| 2681 | + % Add a bookmark to the PDF if desired
|
---|
| 2682 | + if options.bookmark
|
---|
| 2683 | + fig_nam = get(fig, 'Name');
|
---|
| 2684 | + if isempty(fig_nam)
|
---|
| 2685 | + warning('export_fig:EmptyBookmark', 'Bookmark requested for figure with no name. Bookmark will be empty.');
|
---|
| 2686 | end
|
---|
| 2687 | + add_bookmark(tmp_nam, fig_nam);
|
---|
| 2688 | + end
|
---|
| 2689 | + % Generate a pdf
|
---|
| 2690 | + eps2pdf(tmp_nam, pdf_nam_tmp, 1, options.append, options.colourspace==2, options.quality, options.gs_options);
|
---|
| 2691 | + % Ghostscript croaks on % chars in the output PDF file, so use tempname and then rename the file
|
---|
| 2692 | + try movefile(pdf_nam_tmp, pdf_nam, 'f'); catch, end
|
---|
| 2693 | + catch ex
|
---|
| 2694 | + % Delete the eps
|
---|
| 2695 | + delete(tmp_nam);
|
---|
| 2696 | + rethrow(ex);
|
---|
| 2697 | end
|
---|
| 2698 | + % Delete the eps
|
---|
| 2699 | + delete(tmp_nam);
|
---|
| 2700 | + if options.eps
|
---|
| 2701 | + try
|
---|
| 2702 | + % Generate an eps from the pdf
|
---|
| 2703 | + % since pdftops can't handle relative paths (e.g., '..\'), use a temp file
|
---|
| 2704 | + eps_nam_tmp = strrep(pdf_nam_tmp,'.pdf','.eps');
|
---|
| 2705 | + pdf2eps(pdf_nam, eps_nam_tmp);
|
---|
| 2706 | + movefile(eps_nam_tmp, [options.name '.eps'], 'f');
|
---|
| 2707 | + catch ex
|
---|
| 2708 | + if ~options.pdf
|
---|
| 2709 | + % Delete the pdf
|
---|
| 2710 | + delete(pdf_nam);
|
---|
| 2711 | + end
|
---|
| 2712 | + try delete(eps_nam_tmp); catch, end
|
---|
| 2713 | + rethrow(ex);
|
---|
| 2714 | + end
|
---|
| 2715 | + if ~options.pdf
|
---|
| 2716 | + % Delete the pdf
|
---|
| 2717 | + delete(pdf_nam);
|
---|
| 2718 | + end
|
---|
| 2719 | + end
|
---|
| 2720 | + end
|
---|
| 2721 | +
|
---|
| 2722 | + % Revert the figure or close it (if requested)
|
---|
| 2723 | + if cls || options.closeFig
|
---|
| 2724 | + % Close the created figure
|
---|
| 2725 | + close(fig);
|
---|
| 2726 | else
|
---|
| 2727 | - [p, options.name, ext] = fileparts(varargin{a});
|
---|
| 2728 | - if ~isempty(p)
|
---|
| 2729 | - options.name = [p filesep options.name];
|
---|
| 2730 | + % Reset the hardcopy mode
|
---|
| 2731 | + set(fig, 'InvertHardcopy', old_mode);
|
---|
| 2732 | + % Reset the axes limit and tick modes
|
---|
| 2733 | + for a = 1:numel(Hlims)
|
---|
| 2734 | + try
|
---|
| 2735 | + set(Hlims(a), 'XLimMode', Xlims{a}, 'YLimMode', Ylims{a}, 'ZLimMode', Zlims{a},...
|
---|
| 2736 | + 'XTickMode', Xtick{a}, 'YTickMode', Ytick{a}, 'ZTickMode', Ztick{a},...
|
---|
| 2737 | + 'XTickLabelMode', Xlabel{a}, 'YTickLabelMode', Ylabel{a}, 'ZTickLabelMode', Zlabel{a});
|
---|
| 2738 | + catch
|
---|
| 2739 | + % ignore - fix issue #4 (using HG2 on R2014a and earlier)
|
---|
| 2740 | + end
|
---|
| 2741 | end
|
---|
| 2742 | - switch lower(ext)
|
---|
| 2743 | - case {'.tif', '.tiff'}
|
---|
| 2744 | - options.tif = true;
|
---|
| 2745 | - case {'.jpg', '.jpeg'}
|
---|
| 2746 | - options.jpg = true;
|
---|
| 2747 | - case '.png'
|
---|
| 2748 | - options.png = true;
|
---|
| 2749 | - case '.bmp'
|
---|
| 2750 | - options.bmp = true;
|
---|
| 2751 | - case '.eps'
|
---|
| 2752 | - options.eps = true;
|
---|
| 2753 | - case '.pdf'
|
---|
| 2754 | - options.pdf = true;
|
---|
| 2755 | - otherwise
|
---|
| 2756 | - options.name = varargin{a};
|
---|
| 2757 | + % Revert the tex-labels font weights
|
---|
| 2758 | + try set(texLabels, 'FontWeight','bold'); catch, end
|
---|
| 2759 | + % Revert annotation units
|
---|
| 2760 | + for handleIdx = 1 : numel(annotationHandles)
|
---|
| 2761 | + try
|
---|
| 2762 | + oldUnits = originalUnits{handleIdx};
|
---|
| 2763 | + catch
|
---|
| 2764 | + oldUnits = originalUnits;
|
---|
| 2765 | + end
|
---|
| 2766 | + try set(annotationHandles(handleIdx),'Units',oldUnits); catch, end
|
---|
| 2767 | end
|
---|
| 2768 | + % Revert figure units
|
---|
| 2769 | + set(fig,'Units',oldFigUnits);
|
---|
| 2770 | end
|
---|
| 2771 | +
|
---|
| 2772 | + % Output to clipboard (if requested)
|
---|
| 2773 | + if options.clipboard
|
---|
| 2774 | + % Delete the output file if unchanged from the default name ('export_fig_out.png')
|
---|
| 2775 | + if strcmpi(options.name,'export_fig_out')
|
---|
| 2776 | + try
|
---|
| 2777 | + fileInfo = dir('export_fig_out.png');
|
---|
| 2778 | + if ~isempty(fileInfo)
|
---|
| 2779 | + timediff = now - fileInfo.datenum;
|
---|
| 2780 | + ONE_SEC = 1/24/60/60;
|
---|
| 2781 | + if timediff < ONE_SEC
|
---|
| 2782 | + delete('export_fig_out.png');
|
---|
| 2783 | + end
|
---|
| 2784 | + end
|
---|
| 2785 | + catch
|
---|
| 2786 | + % never mind...
|
---|
| 2787 | + end
|
---|
| 2788 | + end
|
---|
| 2789 | +
|
---|
| 2790 | + % Save the image in the system clipboard
|
---|
| 2791 | + % credit: Jiro Doke's IMCLIPBOARD: http://www.mathworks.com/matlabcentral/fileexchange/28708-imclipboard
|
---|
| 2792 | + try
|
---|
| 2793 | + error(javachk('awt', 'export_fig -clipboard output'));
|
---|
| 2794 | + catch
|
---|
| 2795 | + warning('export_fig -clipboard output failed: requires Java to work');
|
---|
| 2796 | + return;
|
---|
| 2797 | + end
|
---|
| 2798 | + try
|
---|
| 2799 | + % Import necessary Java classes
|
---|
| 2800 | + import java.awt.Toolkit
|
---|
| 2801 | + import java.awt.image.BufferedImage
|
---|
| 2802 | + import java.awt.datatransfer.DataFlavor
|
---|
| 2803 | +
|
---|
| 2804 | + % Get System Clipboard object (java.awt.Toolkit)
|
---|
| 2805 | + cb = Toolkit.getDefaultToolkit.getSystemClipboard();
|
---|
| 2806 | +
|
---|
| 2807 | + % Add java class (ImageSelection) to the path
|
---|
| 2808 | + if ~exist('ImageSelection', 'class')
|
---|
| 2809 | + javaaddpath(fileparts(which(mfilename)), '-end');
|
---|
| 2810 | + end
|
---|
| 2811 | +
|
---|
| 2812 | + % Get image size
|
---|
| 2813 | + ht = size(imageData, 1);
|
---|
| 2814 | + wd = size(imageData, 2);
|
---|
| 2815 | +
|
---|
| 2816 | + % Convert to Blue-Green-Red format
|
---|
| 2817 | + try
|
---|
| 2818 | + imageData2 = imageData(:, :, [3 2 1]);
|
---|
| 2819 | + catch
|
---|
| 2820 | + % Probably gray-scaled image (2D, without the 3rd [RGB] dimension)
|
---|
| 2821 | + imageData2 = imageData(:, :, [1 1 1]);
|
---|
| 2822 | + end
|
---|
| 2823 | +
|
---|
| 2824 | + % Convert to 3xWxH format
|
---|
| 2825 | + imageData2 = permute(imageData2, [3, 2, 1]);
|
---|
| 2826 | +
|
---|
| 2827 | + % Append Alpha data (unused - transparency is not supported in clipboard copy)
|
---|
| 2828 | + alphaData2 = uint8(permute(255*alpha,[3,2,1])); %=255*ones(1,wd,ht,'uint8')
|
---|
| 2829 | + imageData2 = cat(1, imageData2, alphaData2);
|
---|
| 2830 | +
|
---|
| 2831 | + % Create image buffer
|
---|
| 2832 | + imBuffer = BufferedImage(wd, ht, BufferedImage.TYPE_INT_RGB);
|
---|
| 2833 | + imBuffer.setRGB(0, 0, wd, ht, typecast(imageData2(:), 'int32'), 0, wd);
|
---|
| 2834 | +
|
---|
| 2835 | + % Create ImageSelection object from the image buffer
|
---|
| 2836 | + imSelection = ImageSelection(imBuffer);
|
---|
| 2837 | +
|
---|
| 2838 | + % Set clipboard content to the image
|
---|
| 2839 | + cb.setContents(imSelection, []);
|
---|
| 2840 | + catch
|
---|
| 2841 | + warning('export_fig -clipboard output failed: %s', lasterr); %#ok<LERR>
|
---|
| 2842 | + end
|
---|
| 2843 | + end
|
---|
| 2844 | +
|
---|
| 2845 | + % Don't output the data to console unless requested
|
---|
| 2846 | + if ~nargout
|
---|
| 2847 | + clear imageData alpha
|
---|
| 2848 | + end
|
---|
| 2849 | + catch err
|
---|
| 2850 | + % Display possible workarounds before the error message
|
---|
| 2851 | + if displaySuggestedWorkarounds && ~strcmpi(err.message,'export_fig error')
|
---|
| 2852 | + if ~hadError, fprintf(2, 'export_fig error. '); end
|
---|
| 2853 | + fprintf(2, 'Please ensure:\n');
|
---|
| 2854 | + 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');
|
---|
| 2855 | + if ismac
|
---|
| 2856 | + fprintf(2, ' and that you have <a href="http://pages.uoregon.edu/koch">Ghostscript</a> installed\n');
|
---|
| 2857 | + else
|
---|
| 2858 | + fprintf(2, ' and that you have <a href="http://www.ghostscript.com">Ghostscript</a> installed\n');
|
---|
| 2859 | + end
|
---|
| 2860 | + try
|
---|
| 2861 | + if options.eps
|
---|
| 2862 | + fprintf(2, ' and that you have <a href="http://www.foolabs.com/xpdf">pdftops</a> installed\n');
|
---|
| 2863 | + end
|
---|
| 2864 | + catch
|
---|
| 2865 | + % ignore - probably an error in parse_args
|
---|
| 2866 | + end
|
---|
| 2867 | + 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');
|
---|
| 2868 | + fprintf(2, ' and that you did not made a mistake in the <a href="matlab:help export_fig">expected input arguments</a>\n');
|
---|
| 2869 | + try
|
---|
| 2870 | + % Alert per issue #149
|
---|
| 2871 | + if ~strncmpi(get(0,'Units'),'pixel',5)
|
---|
| 2872 | + fprintf(2, ' or try to set groot''s Units property back to its default value of ''pixels'' (<a href="matlab:web(''https://github.com/altmany/export_fig/issues/149'',''-browser'');">details</a>)\n');
|
---|
| 2873 | + end
|
---|
| 2874 | + catch
|
---|
| 2875 | + % ignore - maybe an old MAtlab release
|
---|
| 2876 | + end
|
---|
| 2877 | + fprintf(2, '\nIf the problem persists, then please <a href="https://github.com/altmany/export_fig/issues">report a new issue</a>.\n\n');
|
---|
| 2878 | + end
|
---|
| 2879 | + rethrow(err)
|
---|
| 2880 | end
|
---|
| 2881 | end
|
---|
| 2882 |
|
---|
| 2883 | -% Set default anti-aliasing now we know the renderer
|
---|
| 2884 | -if options.aa_factor == 0
|
---|
| 2885 | - options.aa_factor = 1 + 2 * (~(using_hg2(fig) && strcmp(get(ancestor(fig, 'figure'), 'GraphicsSmoothing'), 'on')) | (options.renderer == 3));
|
---|
| 2886 | +function options = default_options()
|
---|
| 2887 | + % Default options used by export_fig
|
---|
| 2888 | + options = struct(...
|
---|
| 2889 | + 'name', 'export_fig_out', ...
|
---|
| 2890 | + 'crop', true, ...
|
---|
| 2891 | + 'crop_amounts', nan(1,4), ... % auto-crop all 4 image sides
|
---|
| 2892 | + 'transparent', false, ...
|
---|
| 2893 | + 'renderer', 0, ... % 0: default, 1: OpenGL, 2: ZBuffer, 3: Painters
|
---|
| 2894 | + 'pdf', false, ...
|
---|
| 2895 | + 'eps', false, ...
|
---|
| 2896 | + 'png', false, ...
|
---|
| 2897 | + 'tif', false, ...
|
---|
| 2898 | + 'jpg', false, ...
|
---|
| 2899 | + 'bmp', false, ...
|
---|
| 2900 | + 'clipboard', false, ...
|
---|
| 2901 | + 'colourspace', 0, ... % 0: RGB/gray, 1: CMYK, 2: gray
|
---|
| 2902 | + 'append', false, ...
|
---|
| 2903 | + 'im', false, ...
|
---|
| 2904 | + 'alpha', false, ...
|
---|
| 2905 | + 'aa_factor', 0, ...
|
---|
| 2906 | + 'bb_padding', 0, ...
|
---|
| 2907 | + 'magnify', [], ...
|
---|
| 2908 | + 'resolution', [], ...
|
---|
| 2909 | + 'bookmark', false, ...
|
---|
| 2910 | + 'closeFig', false, ...
|
---|
| 2911 | + 'quality', [], ...
|
---|
| 2912 | + 'update', false, ...
|
---|
| 2913 | + 'fontswap', true, ...
|
---|
| 2914 | + 'gs_options', {{}});
|
---|
| 2915 | end
|
---|
| 2916 |
|
---|
| 2917 | -% Convert user dir '~' to full path
|
---|
| 2918 | -if numel(options.name) > 2 && options.name(1) == '~' && (options.name(2) == '/' || options.name(2) == '\')
|
---|
| 2919 | - options.name = fullfile(char(java.lang.System.getProperty('user.home')), options.name(2:end));
|
---|
| 2920 | -end
|
---|
| 2921 | +function [fig, options] = parse_args(nout, fig, varargin)
|
---|
| 2922 | + % Parse the input arguments
|
---|
| 2923 |
|
---|
| 2924 | -% Compute the magnification and resolution
|
---|
| 2925 | -if isempty(options.magnify)
|
---|
| 2926 | - if isempty(options.resolution)
|
---|
| 2927 | - options.magnify = 1;
|
---|
| 2928 | - options.resolution = 864;
|
---|
| 2929 | - else
|
---|
| 2930 | - options.magnify = options.resolution ./ get(0, 'ScreenPixelsPerInch');
|
---|
| 2931 | + % Set the defaults
|
---|
| 2932 | + native = false; % Set resolution to native of an image
|
---|
| 2933 | + options = default_options();
|
---|
| 2934 | + options.im = (nout == 1); % user requested imageData output
|
---|
| 2935 | + options.alpha = (nout == 2); % user requested alpha output
|
---|
| 2936 | +
|
---|
| 2937 | + % Go through the other arguments
|
---|
| 2938 | + skipNext = false;
|
---|
| 2939 | + for a = 1:nargin-2
|
---|
| 2940 | + if skipNext
|
---|
| 2941 | + skipNext = false;
|
---|
| 2942 | + continue;
|
---|
| 2943 | + end
|
---|
| 2944 | + if all(ishandle(varargin{a}))
|
---|
| 2945 | + fig = varargin{a};
|
---|
| 2946 | + elseif ischar(varargin{a}) && ~isempty(varargin{a})
|
---|
| 2947 | + if varargin{a}(1) == '-'
|
---|
| 2948 | + switch lower(varargin{a}(2:end))
|
---|
| 2949 | + case 'nocrop'
|
---|
| 2950 | + options.crop = false;
|
---|
| 2951 | + options.crop_amounts = [0,0,0,0];
|
---|
| 2952 | + case {'trans', 'transparent'}
|
---|
| 2953 | + options.transparent = true;
|
---|
| 2954 | + case 'opengl'
|
---|
| 2955 | + options.renderer = 1;
|
---|
| 2956 | + case 'zbuffer'
|
---|
| 2957 | + options.renderer = 2;
|
---|
| 2958 | + case 'painters'
|
---|
| 2959 | + options.renderer = 3;
|
---|
| 2960 | + case 'pdf'
|
---|
| 2961 | + options.pdf = true;
|
---|
| 2962 | + case 'eps'
|
---|
| 2963 | + options.eps = true;
|
---|
| 2964 | + case 'png'
|
---|
| 2965 | + options.png = true;
|
---|
| 2966 | + case {'tif', 'tiff'}
|
---|
| 2967 | + options.tif = true;
|
---|
| 2968 | + case {'jpg', 'jpeg'}
|
---|
| 2969 | + options.jpg = true;
|
---|
| 2970 | + case 'bmp'
|
---|
| 2971 | + options.bmp = true;
|
---|
| 2972 | + case 'rgb'
|
---|
| 2973 | + options.colourspace = 0;
|
---|
| 2974 | + case 'cmyk'
|
---|
| 2975 | + options.colourspace = 1;
|
---|
| 2976 | + case {'gray', 'grey'}
|
---|
| 2977 | + options.colourspace = 2;
|
---|
| 2978 | + case {'a1', 'a2', 'a3', 'a4'}
|
---|
| 2979 | + options.aa_factor = str2double(varargin{a}(3));
|
---|
| 2980 | + case 'append'
|
---|
| 2981 | + options.append = true;
|
---|
| 2982 | + case 'bookmark'
|
---|
| 2983 | + options.bookmark = true;
|
---|
| 2984 | + case 'native'
|
---|
| 2985 | + native = true;
|
---|
| 2986 | + case 'clipboard'
|
---|
| 2987 | + options.clipboard = true;
|
---|
| 2988 | + options.im = true;
|
---|
| 2989 | + options.alpha = true;
|
---|
| 2990 | + case 'svg'
|
---|
| 2991 | + msg = ['SVG output is not supported by export_fig. Use one of the following alternatives:\n' ...
|
---|
| 2992 | + ' 1. saveas(gcf,''filename.svg'')\n' ...
|
---|
| 2993 | + ' 2. plot2svg utility: http://github.com/jschwizer99/plot2svg\n' ...
|
---|
| 2994 | + ' 3. export_fig to EPS/PDF, then convert to SVG using generic (non-Matlab) tools\n'];
|
---|
| 2995 | + error(sprintf(msg)); %#ok<SPERR>
|
---|
| 2996 | + case 'update'
|
---|
| 2997 | + % Download the latest version of export_fig into the export_fig folder
|
---|
| 2998 | + try
|
---|
| 2999 | + zipFileName = 'https://github.com/altmany/export_fig/archive/master.zip';
|
---|
| 3000 | + folderName = fileparts(which(mfilename('fullpath')));
|
---|
| 3001 | + targetFileName = fullfile(folderName, datestr(now,'yyyy-mm-dd.zip'));
|
---|
| 3002 | + urlwrite(zipFileName,targetFileName);
|
---|
| 3003 | + catch
|
---|
| 3004 | + error('Could not download %s into %s\n',zipFileName,targetFileName);
|
---|
| 3005 | + end
|
---|
| 3006 | +
|
---|
| 3007 | + % Unzip the downloaded zip file in the export_fig folder
|
---|
| 3008 | + try
|
---|
| 3009 | + unzip(targetFileName,folderName);
|
---|
| 3010 | + catch
|
---|
| 3011 | + error('Could not unzip %s\n',targetFileName);
|
---|
| 3012 | + end
|
---|
| 3013 | + case 'nofontswap'
|
---|
| 3014 | + options.fontswap = false;
|
---|
| 3015 | + otherwise
|
---|
| 3016 | + try
|
---|
| 3017 | + wasError = false;
|
---|
| 3018 | + if strcmpi(varargin{a}(1:2),'-d')
|
---|
| 3019 | + varargin{a}(2) = 'd'; % ensure lowercase 'd'
|
---|
| 3020 | + options.gs_options{end+1} = varargin{a};
|
---|
| 3021 | + elseif strcmpi(varargin{a}(1:2),'-c')
|
---|
| 3022 | + if numel(varargin{a})==2
|
---|
| 3023 | + skipNext = true;
|
---|
| 3024 | + vals = str2num(varargin{a+1}); %#ok<ST2NM>
|
---|
| 3025 | + else
|
---|
| 3026 | + vals = str2num(varargin{a}(3:end)); %#ok<ST2NM>
|
---|
| 3027 | + end
|
---|
| 3028 | + if numel(vals)~=4
|
---|
| 3029 | + wasError = true;
|
---|
| 3030 | + error('option -c cannot be parsed: must be a 4-element numeric vector');
|
---|
| 3031 | + end
|
---|
| 3032 | + options.crop_amounts = vals;
|
---|
| 3033 | + options.crop = true;
|
---|
| 3034 | + else % scalar parameter value
|
---|
| 3035 | + val = str2double(regexp(varargin{a}, '(?<=-(m|M|r|R|q|Q|p|P))-?\d*.?\d+', 'match'));
|
---|
| 3036 | + if isempty(val) || isnan(val)
|
---|
| 3037 | + % Issue #51: improved processing of input args (accept space between param name & value)
|
---|
| 3038 | + val = str2double(varargin{a+1});
|
---|
| 3039 | + if isscalar(val) && ~isnan(val)
|
---|
| 3040 | + skipNext = true;
|
---|
| 3041 | + end
|
---|
| 3042 | + end
|
---|
| 3043 | + if ~isscalar(val) || isnan(val)
|
---|
| 3044 | + wasError = true;
|
---|
| 3045 | + error('option %s is not recognised or cannot be parsed', varargin{a});
|
---|
| 3046 | + end
|
---|
| 3047 | + switch lower(varargin{a}(2))
|
---|
| 3048 | + case 'm'
|
---|
| 3049 | + % Magnification may never be negative
|
---|
| 3050 | + if val <= 0
|
---|
| 3051 | + wasError = true;
|
---|
| 3052 | + error('Bad magnification value: %g (must be positive)', val);
|
---|
| 3053 | + end
|
---|
| 3054 | + options.magnify = val;
|
---|
| 3055 | + case 'r'
|
---|
| 3056 | + options.resolution = val;
|
---|
| 3057 | + case 'q'
|
---|
| 3058 | + options.quality = max(val, 0);
|
---|
| 3059 | + case 'p'
|
---|
| 3060 | + options.bb_padding = val;
|
---|
| 3061 | + end
|
---|
| 3062 | + end
|
---|
| 3063 | + catch err
|
---|
| 3064 | + % We might have reached here by raising an intentional error
|
---|
| 3065 | + if wasError % intentional raise
|
---|
| 3066 | + rethrow(err)
|
---|
| 3067 | + else % unintentional
|
---|
| 3068 | + error(['Unrecognized export_fig input option: ''' varargin{a} '''']);
|
---|
| 3069 | + end
|
---|
| 3070 | + end
|
---|
| 3071 | + end
|
---|
| 3072 | + else
|
---|
| 3073 | + [p, options.name, ext] = fileparts(varargin{a});
|
---|
| 3074 | + if ~isempty(p)
|
---|
| 3075 | + options.name = [p filesep options.name];
|
---|
| 3076 | + end
|
---|
| 3077 | + switch lower(ext)
|
---|
| 3078 | + case {'.tif', '.tiff'}
|
---|
| 3079 | + options.tif = true;
|
---|
| 3080 | + case {'.jpg', '.jpeg'}
|
---|
| 3081 | + options.jpg = true;
|
---|
| 3082 | + case '.png'
|
---|
| 3083 | + options.png = true;
|
---|
| 3084 | + case '.bmp'
|
---|
| 3085 | + options.bmp = true;
|
---|
| 3086 | + case '.eps'
|
---|
| 3087 | + options.eps = true;
|
---|
| 3088 | + case '.pdf'
|
---|
| 3089 | + options.pdf = true;
|
---|
| 3090 | + case '.fig'
|
---|
| 3091 | + % If no open figure, then load the specified .fig file and continue
|
---|
| 3092 | + if isempty(fig)
|
---|
| 3093 | + fig = openfig(varargin{a},'invisible');
|
---|
| 3094 | + varargin{a} = fig;
|
---|
| 3095 | + options.closeFig = true;
|
---|
| 3096 | + else
|
---|
| 3097 | + % save the current figure as the specified .fig file and exit
|
---|
| 3098 | + saveas(fig(1),varargin{a});
|
---|
| 3099 | + fig = -1;
|
---|
| 3100 | + return
|
---|
| 3101 | + end
|
---|
| 3102 | + case '.svg'
|
---|
| 3103 | + msg = ['SVG output is not supported by export_fig. Use one of the following alternatives:\n' ...
|
---|
| 3104 | + ' 1. saveas(gcf,''filename.svg'')\n' ...
|
---|
| 3105 | + ' 2. plot2svg utility: http://github.com/jschwizer99/plot2svg\n' ...
|
---|
| 3106 | + ' 3. export_fig to EPS/PDF, then convert to SVG using generic (non-Matlab) tools\n'];
|
---|
| 3107 | + error(sprintf(msg)); %#ok<SPERR>
|
---|
| 3108 | + otherwise
|
---|
| 3109 | + options.name = varargin{a};
|
---|
| 3110 | + end
|
---|
| 3111 | + end
|
---|
| 3112 | + end
|
---|
| 3113 | end
|
---|
| 3114 | -elseif isempty(options.resolution)
|
---|
| 3115 | - options.resolution = 864;
|
---|
| 3116 | -end
|
---|
| 3117 |
|
---|
| 3118 | -% Check we have a figure handle
|
---|
| 3119 | -if isempty(fig)
|
---|
| 3120 | - error('No figure found');
|
---|
| 3121 | -end
|
---|
| 3122 | + % Quick bail-out if no figure found
|
---|
| 3123 | + if isempty(fig), return; end
|
---|
| 3124 |
|
---|
| 3125 | -% Set the default format
|
---|
| 3126 | -if ~isvector(options) && ~isbitmap(options)
|
---|
| 3127 | - options.png = true;
|
---|
| 3128 | -end
|
---|
| 3129 | + % Do border padding with repsect to a cropped image
|
---|
| 3130 | + if options.bb_padding
|
---|
| 3131 | + options.crop = true;
|
---|
| 3132 | + end
|
---|
| 3133 |
|
---|
| 3134 | -% Check whether transparent background is wanted (old way)
|
---|
| 3135 | -if isequal(get(ancestor(fig(1), 'figure'), 'Color'), 'none')
|
---|
| 3136 | - options.transparent = true;
|
---|
| 3137 | -end
|
---|
| 3138 | + % Set default anti-aliasing now we know the renderer
|
---|
| 3139 | + if options.aa_factor == 0
|
---|
| 3140 | + try isAA = strcmp(get(ancestor(fig, 'figure'), 'GraphicsSmoothing'), 'on'); catch, isAA = false; end
|
---|
| 3141 | + options.aa_factor = 1 + 2 * (~(using_hg2(fig) && isAA) | (options.renderer == 3));
|
---|
| 3142 | + end
|
---|
| 3143 |
|
---|
| 3144 | -% If requested, set the resolution to the native vertical resolution of the
|
---|
| 3145 | -% first suitable image found
|
---|
| 3146 | -if native && isbitmap(options)
|
---|
| 3147 | - % Find a suitable image
|
---|
| 3148 | - list = findobj(fig, 'Type', 'image', 'Tag', 'export_fig_native');
|
---|
| 3149 | - if isempty(list)
|
---|
| 3150 | - list = findobj(fig, 'Type', 'image', 'Visible', 'on');
|
---|
| 3151 | + % Convert user dir '~' to full path
|
---|
| 3152 | + if numel(options.name) > 2 && options.name(1) == '~' && (options.name(2) == '/' || options.name(2) == '\')
|
---|
| 3153 | + options.name = fullfile(char(java.lang.System.getProperty('user.home')), options.name(2:end));
|
---|
| 3154 | end
|
---|
| 3155 | - for hIm = list(:)'
|
---|
| 3156 | - % Check height is >= 2
|
---|
| 3157 | - height = size(get(hIm, 'CData'), 1);
|
---|
| 3158 | - if height < 2
|
---|
| 3159 | - continue
|
---|
| 3160 | +
|
---|
| 3161 | + % Compute the magnification and resolution
|
---|
| 3162 | + if isempty(options.magnify)
|
---|
| 3163 | + if isempty(options.resolution)
|
---|
| 3164 | + options.magnify = 1;
|
---|
| 3165 | + options.resolution = 864;
|
---|
| 3166 | + else
|
---|
| 3167 | + options.magnify = options.resolution ./ get(0, 'ScreenPixelsPerInch');
|
---|
| 3168 | end
|
---|
| 3169 | - % Account for the image filling only part of the axes, or vice
|
---|
| 3170 | - % versa
|
---|
| 3171 | - yl = get(hIm, 'YData');
|
---|
| 3172 | - if isscalar(yl)
|
---|
| 3173 | - yl = [yl(1)-0.5 yl(1)+height+0.5];
|
---|
| 3174 | - else
|
---|
| 3175 | - if ~diff(yl)
|
---|
| 3176 | + elseif isempty(options.resolution)
|
---|
| 3177 | + options.resolution = 864;
|
---|
| 3178 | + end
|
---|
| 3179 | +
|
---|
| 3180 | + % Set the default format
|
---|
| 3181 | + if ~isvector(options) && ~isbitmap(options)
|
---|
| 3182 | + options.png = true;
|
---|
| 3183 | + end
|
---|
| 3184 | +
|
---|
| 3185 | + % Check whether transparent background is wanted (old way)
|
---|
| 3186 | + if isequal(get(ancestor(fig(1), 'figure'), 'Color'), 'none')
|
---|
| 3187 | + options.transparent = true;
|
---|
| 3188 | + end
|
---|
| 3189 | +
|
---|
| 3190 | + % If requested, set the resolution to the native vertical resolution of the
|
---|
| 3191 | + % first suitable image found
|
---|
| 3192 | + if native && isbitmap(options)
|
---|
| 3193 | + % Find a suitable image
|
---|
| 3194 | + list = findall(fig, 'Type','image', 'Tag','export_fig_native');
|
---|
| 3195 | + if isempty(list)
|
---|
| 3196 | + list = findall(fig, 'Type','image', 'Visible','on');
|
---|
| 3197 | + end
|
---|
| 3198 | + for hIm = list(:)'
|
---|
| 3199 | + % Check height is >= 2
|
---|
| 3200 | + height = size(get(hIm, 'CData'), 1);
|
---|
| 3201 | + if height < 2
|
---|
| 3202 | continue
|
---|
| 3203 | end
|
---|
| 3204 | - yl = yl + [-0.5 0.5] * (diff(yl) / (height - 1));
|
---|
| 3205 | + % Account for the image filling only part of the axes, or vice versa
|
---|
| 3206 | + yl = get(hIm, 'YData');
|
---|
| 3207 | + if isscalar(yl)
|
---|
| 3208 | + yl = [yl(1)-0.5 yl(1)+height+0.5];
|
---|
| 3209 | + else
|
---|
| 3210 | + yl = [min(yl), max(yl)]; % fix issue #151 (case of yl containing more than 2 elements)
|
---|
| 3211 | + if ~diff(yl)
|
---|
| 3212 | + continue
|
---|
| 3213 | + end
|
---|
| 3214 | + yl = yl + [-0.5 0.5] * (diff(yl) / (height - 1));
|
---|
| 3215 | + end
|
---|
| 3216 | + hAx = get(hIm, 'Parent');
|
---|
| 3217 | + yl2 = get(hAx, 'YLim');
|
---|
| 3218 | + % Find the pixel height of the axes
|
---|
| 3219 | + oldUnits = get(hAx, 'Units');
|
---|
| 3220 | + set(hAx, 'Units', 'pixels');
|
---|
| 3221 | + pos = get(hAx, 'Position');
|
---|
| 3222 | + set(hAx, 'Units', oldUnits);
|
---|
| 3223 | + if ~pos(4)
|
---|
| 3224 | + continue
|
---|
| 3225 | + end
|
---|
| 3226 | + % Found a suitable image
|
---|
| 3227 | + % Account for stretch-to-fill being disabled
|
---|
| 3228 | + pbar = get(hAx, 'PlotBoxAspectRatio');
|
---|
| 3229 | + pos = min(pos(4), pbar(2)*pos(3)/pbar(1));
|
---|
| 3230 | + % Set the magnification to give native resolution
|
---|
| 3231 | + options.magnify = abs((height * diff(yl2)) / (pos * diff(yl))); % magnification must never be negative: issue #103
|
---|
| 3232 | + break
|
---|
| 3233 | end
|
---|
| 3234 | - hAx = get(hIm, 'Parent');
|
---|
| 3235 | - yl2 = get(hAx, 'YLim');
|
---|
| 3236 | - % Find the pixel height of the axes
|
---|
| 3237 | - oldUnits = get(hAx, 'Units');
|
---|
| 3238 | - set(hAx, 'Units', 'pixels');
|
---|
| 3239 | - pos = get(hAx, 'Position');
|
---|
| 3240 | - set(hAx, 'Units', oldUnits);
|
---|
| 3241 | - if ~pos(4)
|
---|
| 3242 | - continue
|
---|
| 3243 | - end
|
---|
| 3244 | - % Found a suitable image
|
---|
| 3245 | - % Account for stretch-to-fill being disabled
|
---|
| 3246 | - pbar = get(hAx, 'PlotBoxAspectRatio');
|
---|
| 3247 | - pos = min(pos(4), pbar(2)*pos(3)/pbar(1));
|
---|
| 3248 | - % Set the magnification to give native resolution
|
---|
| 3249 | - options.magnify = (height * diff(yl2)) / (pos * diff(yl));
|
---|
| 3250 | - break
|
---|
| 3251 | end
|
---|
| 3252 | end
|
---|
| 3253 | -end
|
---|
| 3254 |
|
---|
| 3255 | function A = downsize(A, factor)
|
---|
| 3256 | -% Downsample an image
|
---|
| 3257 | -if factor == 1
|
---|
| 3258 | - % Nothing to do
|
---|
| 3259 | - return
|
---|
| 3260 | -end
|
---|
| 3261 | -try
|
---|
| 3262 | - % Faster, but requires image processing toolbox
|
---|
| 3263 | - A = imresize(A, 1/factor, 'bilinear');
|
---|
| 3264 | -catch
|
---|
| 3265 | - % No image processing toolbox - resize manually
|
---|
| 3266 | - % Lowpass filter - use Gaussian as is separable, so faster
|
---|
| 3267 | - % Compute the 1d Gaussian filter
|
---|
| 3268 | - filt = (-factor-1:factor+1) / (factor * 0.6);
|
---|
| 3269 | - filt = exp(-filt .* filt);
|
---|
| 3270 | - % Normalize the filter
|
---|
| 3271 | - filt = single(filt / sum(filt));
|
---|
| 3272 | - % Filter the image
|
---|
| 3273 | - padding = floor(numel(filt) / 2);
|
---|
| 3274 | - for a = 1:size(A, 3)
|
---|
| 3275 | - 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');
|
---|
| 3276 | + % Downsample an image
|
---|
| 3277 | + if factor == 1
|
---|
| 3278 | + % Nothing to do
|
---|
| 3279 | + return
|
---|
| 3280 | end
|
---|
| 3281 | - % Subsample
|
---|
| 3282 | - A = A(1+floor(mod(end-1, factor)/2):factor:end,1+floor(mod(end-1, factor)/2):factor:end,:);
|
---|
| 3283 | + try
|
---|
| 3284 | + % Faster, but requires image processing toolbox
|
---|
| 3285 | + A = imresize(A, 1/factor, 'bilinear');
|
---|
| 3286 | + catch
|
---|
| 3287 | + % No image processing toolbox - resize manually
|
---|
| 3288 | + % Lowpass filter - use Gaussian as is separable, so faster
|
---|
| 3289 | + % Compute the 1d Gaussian filter
|
---|
| 3290 | + filt = (-factor-1:factor+1) / (factor * 0.6);
|
---|
| 3291 | + filt = exp(-filt .* filt);
|
---|
| 3292 | + % Normalize the filter
|
---|
| 3293 | + filt = single(filt / sum(filt));
|
---|
| 3294 | + % Filter the image
|
---|
| 3295 | + padding = floor(numel(filt) / 2);
|
---|
| 3296 | + for a = 1:size(A, 3)
|
---|
| 3297 | + 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');
|
---|
| 3298 | + end
|
---|
| 3299 | + % Subsample
|
---|
| 3300 | + A = A(1+floor(mod(end-1, factor)/2):factor:end,1+floor(mod(end-1, factor)/2):factor:end,:);
|
---|
| 3301 | + end
|
---|
| 3302 | end
|
---|
| 3303 | -end
|
---|
| 3304 |
|
---|
| 3305 | function A = rgb2grey(A)
|
---|
| 3306 | -A = cast(reshape(reshape(single(A), [], 3) * single([0.299; 0.587; 0.114]), size(A, 1), size(A, 2)), class(A));
|
---|
| 3307 | + A = cast(reshape(reshape(single(A), [], 3) * single([0.299; 0.587; 0.114]), size(A, 1), size(A, 2)), class(A)); %#ok<ZEROLIKE>
|
---|
| 3308 | end
|
---|
| 3309 |
|
---|
| 3310 | function A = check_greyscale(A)
|
---|
| 3311 | -% Check if the image is greyscale
|
---|
| 3312 | -if size(A, 3) == 3 && ...
|
---|
| 3313 | - all(reshape(A(:,:,1) == A(:,:,2), [], 1)) && ...
|
---|
| 3314 | - all(reshape(A(:,:,2) == A(:,:,3), [], 1))
|
---|
| 3315 | - A = A(:,:,1); % Save only one channel for 8-bit output
|
---|
| 3316 | + % Check if the image is greyscale
|
---|
| 3317 | + if size(A, 3) == 3 && ...
|
---|
| 3318 | + all(reshape(A(:,:,1) == A(:,:,2), [], 1)) && ...
|
---|
| 3319 | + all(reshape(A(:,:,2) == A(:,:,3), [], 1))
|
---|
| 3320 | + A = A(:,:,1); % Save only one channel for 8-bit output
|
---|
| 3321 | + end
|
---|
| 3322 | end
|
---|
| 3323 | -end
|
---|
| 3324 |
|
---|
| 3325 | function eps_remove_background(fname, count)
|
---|
| 3326 | -% Remove the background of an eps file
|
---|
| 3327 | -% Open the file
|
---|
| 3328 | -fh = fopen(fname, 'r+');
|
---|
| 3329 | -if fh == -1
|
---|
| 3330 | - error('Not able to open file %s.', fname);
|
---|
| 3331 | -end
|
---|
| 3332 | -% Read the file line by line
|
---|
| 3333 | -while count
|
---|
| 3334 | - % Get the next line
|
---|
| 3335 | - l = fgets(fh);
|
---|
| 3336 | - if isequal(l, -1)
|
---|
| 3337 | - break; % Quit, no rectangle found
|
---|
| 3338 | + % Remove the background of an eps file
|
---|
| 3339 | + % Open the file
|
---|
| 3340 | + fh = fopen(fname, 'r+');
|
---|
| 3341 | + if fh == -1
|
---|
| 3342 | + error('Not able to open file %s.', fname);
|
---|
| 3343 | end
|
---|
| 3344 | - % Check if the line contains the background rectangle
|
---|
| 3345 | - if isequal(regexp(l, ' *0 +0 +\d+ +\d+ +r[fe] *[\n\r]+', 'start'), 1)
|
---|
| 3346 | - % Set the line to whitespace and quit
|
---|
| 3347 | - l(1:regexp(l, '[\n\r]', 'start', 'once')-1) = ' ';
|
---|
| 3348 | - fseek(fh, -numel(l), 0);
|
---|
| 3349 | - fprintf(fh, l);
|
---|
| 3350 | - % Reduce the count
|
---|
| 3351 | - count = count - 1;
|
---|
| 3352 | + % Read the file line by line
|
---|
| 3353 | + while count
|
---|
| 3354 | + % Get the next line
|
---|
| 3355 | + l = fgets(fh);
|
---|
| 3356 | + if isequal(l, -1)
|
---|
| 3357 | + break; % Quit, no rectangle found
|
---|
| 3358 | + end
|
---|
| 3359 | + % Check if the line contains the background rectangle
|
---|
| 3360 | + if isequal(regexp(l, ' *0 +0 +\d+ +\d+ +r[fe] *[\n\r]+', 'start'), 1)
|
---|
| 3361 | + % Set the line to whitespace and quit
|
---|
| 3362 | + l(1:regexp(l, '[\n\r]', 'start', 'once')-1) = ' ';
|
---|
| 3363 | + fseek(fh, -numel(l), 0);
|
---|
| 3364 | + fprintf(fh, l);
|
---|
| 3365 | + % Reduce the count
|
---|
| 3366 | + count = count - 1;
|
---|
| 3367 | + end
|
---|
| 3368 | end
|
---|
| 3369 | + % Close the file
|
---|
| 3370 | + fclose(fh);
|
---|
| 3371 | end
|
---|
| 3372 | -% Close the file
|
---|
| 3373 | -fclose(fh);
|
---|
| 3374 | -end
|
---|
| 3375 |
|
---|
| 3376 | function b = isvector(options)
|
---|
| 3377 | -b = options.pdf || options.eps;
|
---|
| 3378 | + b = options.pdf || options.eps;
|
---|
| 3379 | end
|
---|
| 3380 |
|
---|
| 3381 | function b = isbitmap(options)
|
---|
| 3382 | -b = options.png || options.tif || options.jpg || options.bmp || options.im || options.alpha;
|
---|
| 3383 | + b = options.png || options.tif || options.jpg || options.bmp || options.im || options.alpha;
|
---|
| 3384 | end
|
---|
| 3385 |
|
---|
| 3386 | % Helper function
|
---|
| 3387 | function A = make_cell(A)
|
---|
| 3388 | -if ~iscell(A)
|
---|
| 3389 | - A = {A};
|
---|
| 3390 | + if ~iscell(A)
|
---|
| 3391 | + A = {A};
|
---|
| 3392 | + end
|
---|
| 3393 | end
|
---|
| 3394 | -end
|
---|
| 3395 |
|
---|
| 3396 | function add_bookmark(fname, bookmark_text)
|
---|
| 3397 | -% Adds a bookmark to the temporary EPS file after %%EndPageSetup
|
---|
| 3398 | -% Read in the file
|
---|
| 3399 | -fh = fopen(fname, 'r');
|
---|
| 3400 | -if fh == -1
|
---|
| 3401 | - error('File %s not found.', fname);
|
---|
| 3402 | -end
|
---|
| 3403 | -try
|
---|
| 3404 | - fstrm = fread(fh, '*char')';
|
---|
| 3405 | -catch ex
|
---|
| 3406 | + % Adds a bookmark to the temporary EPS file after %%EndPageSetup
|
---|
| 3407 | + % Read in the file
|
---|
| 3408 | + fh = fopen(fname, 'r');
|
---|
| 3409 | + if fh == -1
|
---|
| 3410 | + error('File %s not found.', fname);
|
---|
| 3411 | + end
|
---|
| 3412 | + try
|
---|
| 3413 | + fstrm = fread(fh, '*char')';
|
---|
| 3414 | + catch ex
|
---|
| 3415 | + fclose(fh);
|
---|
| 3416 | + rethrow(ex);
|
---|
| 3417 | + end
|
---|
| 3418 | fclose(fh);
|
---|
| 3419 | - rethrow(ex);
|
---|
| 3420 | -end
|
---|
| 3421 | -fclose(fh);
|
---|
| 3422 |
|
---|
| 3423 | -% Include standard pdfmark prolog to maximize compatibility
|
---|
| 3424 | -fstrm = strrep(fstrm, '%%BeginProlog', sprintf('%%%%BeginProlog\n/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse'));
|
---|
| 3425 | -% Add page bookmark
|
---|
| 3426 | -fstrm = strrep(fstrm, '%%EndPageSetup', sprintf('%%%%EndPageSetup\n[ /Title (%s) /OUT pdfmark',bookmark_text));
|
---|
| 3427 | + % Include standard pdfmark prolog to maximize compatibility
|
---|
| 3428 | + fstrm = strrep(fstrm, '%%BeginProlog', sprintf('%%%%BeginProlog\n/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse'));
|
---|
| 3429 | + % Add page bookmark
|
---|
| 3430 | + fstrm = strrep(fstrm, '%%EndPageSetup', sprintf('%%%%EndPageSetup\n[ /Title (%s) /OUT pdfmark',bookmark_text));
|
---|
| 3431 |
|
---|
| 3432 | -% Write out the updated file
|
---|
| 3433 | -fh = fopen(fname, 'w');
|
---|
| 3434 | -if fh == -1
|
---|
| 3435 | - error('Unable to open %s for writing.', fname);
|
---|
| 3436 | -end
|
---|
| 3437 | -try
|
---|
| 3438 | - fwrite(fh, fstrm, 'char*1');
|
---|
| 3439 | -catch ex
|
---|
| 3440 | + % Write out the updated file
|
---|
| 3441 | + fh = fopen(fname, 'w');
|
---|
| 3442 | + if fh == -1
|
---|
| 3443 | + error('Unable to open %s for writing.', fname);
|
---|
| 3444 | + end
|
---|
| 3445 | + try
|
---|
| 3446 | + fwrite(fh, fstrm, 'char*1');
|
---|
| 3447 | + catch ex
|
---|
| 3448 | + fclose(fh);
|
---|
| 3449 | + rethrow(ex);
|
---|
| 3450 | + end
|
---|
| 3451 | fclose(fh);
|
---|
| 3452 | - rethrow(ex);
|
---|
| 3453 | end
|
---|
| 3454 | -fclose(fh);
|
---|
| 3455 | -end
|
---|
| 3456 |
|
---|
| 3457 | function set_tick_mode(Hlims, ax)
|
---|
| 3458 | -% Set the tick mode of linear axes to manual
|
---|
| 3459 | -% Leave log axes alone as these are tricky
|
---|
| 3460 | -M = get(Hlims, [ax 'Scale']);
|
---|
| 3461 | -if ~iscell(M)
|
---|
| 3462 | - M = {M};
|
---|
| 3463 | + % Set the tick mode of linear axes to manual
|
---|
| 3464 | + % Leave log axes alone as these are tricky
|
---|
| 3465 | + M = get(Hlims, [ax 'Scale']);
|
---|
| 3466 | + if ~iscell(M)
|
---|
| 3467 | + M = {M};
|
---|
| 3468 | + end
|
---|
| 3469 | + M = cellfun(@(c) strcmp(c, 'linear'), M);
|
---|
| 3470 | + set(Hlims(M), [ax 'TickMode'], 'manual');
|
---|
| 3471 | + %set(Hlims(M), [ax 'TickLabelMode'], 'manual'); % this hides exponent label in HG2!
|
---|
| 3472 | end
|
---|
| 3473 | -M = cellfun(@(c) strcmp(c, 'linear'), M);
|
---|
| 3474 | -set(Hlims(M), [ax 'TickMode'], 'manual');
|
---|
| 3475 | +
|
---|
| 3476 | +function change_rgb_to_cmyk(fname) % convert RGB => CMYK within an EPS file
|
---|
| 3477 | + % Do post-processing on the eps file
|
---|
| 3478 | + try
|
---|
| 3479 | + % Read the EPS file into memory
|
---|
| 3480 | + fstrm = read_write_entire_textfile(fname);
|
---|
| 3481 | +
|
---|
| 3482 | + % Replace all gray-scale colors
|
---|
| 3483 | + fstrm = regexprep(fstrm, '\n([\d.]+) +GC\n', '\n0 0 0 ${num2str(1-str2num($1))} CC\n');
|
---|
| 3484 | +
|
---|
| 3485 | + % Replace all RGB colors
|
---|
| 3486 | + fstrm = regexprep(fstrm, '\n[0.]+ +[0.]+ +[0.]+ +RC\n', '\n0 0 0 1 CC\n'); % pure black
|
---|
| 3487 | + 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');
|
---|
| 3488 | +
|
---|
| 3489 | + % Overwrite the file with the modified contents
|
---|
| 3490 | + read_write_entire_textfile(fname, fstrm);
|
---|
| 3491 | + catch
|
---|
| 3492 | + % never mind - leave as is...
|
---|
| 3493 | + end
|
---|
| 3494 | end
|
---|
| 3495 | Index: ../trunk-jpl/externalpackages/export_fig/ghostscript.m
|
---|
| 3496 | ===================================================================
|
---|
| 3497 | --- ../trunk-jpl/externalpackages/export_fig/ghostscript.m (revision 21314)
|
---|
| 3498 | +++ ../trunk-jpl/externalpackages/export_fig/ghostscript.m (revision 21315)
|
---|
| 3499 | @@ -1,3 +1,4 @@
|
---|
| 3500 | +function varargout = ghostscript(cmd)
|
---|
| 3501 | %GHOSTSCRIPT Calls a local GhostScript executable with the input command
|
---|
| 3502 | %
|
---|
| 3503 | % Example:
|
---|
| 3504 | @@ -19,140 +20,177 @@
|
---|
| 3505 | % status - 0 iff command ran without problem.
|
---|
| 3506 | % result - Output from ghostscript.
|
---|
| 3507 |
|
---|
| 3508 | -% Copyright: Oliver Woodford, 2009-2013
|
---|
| 3509 | -
|
---|
| 3510 | -% Thanks to Jonas Dorn for the fix for the title of the uigetdir window on
|
---|
| 3511 | -% Mac OS.
|
---|
| 3512 | -% Thanks to Nathan Childress for the fix to the default location on 64-bit
|
---|
| 3513 | -% Windows systems.
|
---|
| 3514 | -% 27/4/11 - Find 64-bit Ghostscript on Windows. Thanks to Paul Durack and
|
---|
| 3515 | -% Shaun Kline for pointing out the issue
|
---|
| 3516 | -% 4/5/11 - Thanks to David Chorlian for pointing out an alternative
|
---|
| 3517 | -% location for gs on linux.
|
---|
| 3518 | +% Copyright: Oliver Woodford, 2009-2015, Yair Altman 2015-
|
---|
| 3519 | +%{
|
---|
| 3520 | +% Thanks to Jonas Dorn for the fix for the title of the uigetdir window on Mac OS.
|
---|
| 3521 | +% Thanks to Nathan Childress for the fix to default location on 64-bit Windows systems.
|
---|
| 3522 | +% 27/04/11 - Find 64-bit Ghostscript on Windows. Thanks to Paul Durack and
|
---|
| 3523 | +% Shaun Kline for pointing out the issue
|
---|
| 3524 | +% 04/05/11 - Thanks to David Chorlian for pointing out an alternative
|
---|
| 3525 | +% location for gs on linux.
|
---|
| 3526 | % 12/12/12 - Add extra executable name on Windows. Thanks to Ratish
|
---|
| 3527 | -% Punnoose for highlighting the issue.
|
---|
| 3528 | -% 28/6/13 - Fix error using GS 9.07 in Linux. Many thanks to Jannick
|
---|
| 3529 | -% Steinbring for proposing the fix.
|
---|
| 3530 | -% 24/10/13 - Fix error using GS 9.07 in Linux. Many thanks to Johannes
|
---|
| 3531 | -% for the fix.
|
---|
| 3532 | -% 23/01/2014 - Add full path to ghostscript.txt in warning. Thanks to Koen
|
---|
| 3533 | -% Vermeer for raising the issue.
|
---|
| 3534 | +% Punnoose for highlighting the issue.
|
---|
| 3535 | +% 28/06/13 - Fix error using GS 9.07 in Linux. Many thanks to Jannick
|
---|
| 3536 | +% Steinbring for proposing the fix.
|
---|
| 3537 | +% 24/10/13 - Fix error using GS 9.07 in Linux. Many thanks to Johannes
|
---|
| 3538 | +% for the fix.
|
---|
| 3539 | +% 23/01/14 - Add full path to ghostscript.txt in warning. Thanks to Koen
|
---|
| 3540 | +% Vermeer for raising the issue.
|
---|
| 3541 | +% 27/02/15 - If Ghostscript croaks, display suggested workarounds
|
---|
| 3542 | +% 30/03/15 - Improved performance by caching status of GS path check, if ok
|
---|
| 3543 | +% 14/05/15 - Clarified warning message in case GS path could not be saved
|
---|
| 3544 | +% 29/05/15 - Avoid cryptic error in case the ghostscipt path cannot be saved (issue #74)
|
---|
| 3545 | +% 10/11/15 - Custom GS installation webpage for MacOS. Thanks to Andy Hueni via FEX
|
---|
| 3546 | +%}
|
---|
| 3547 |
|
---|
| 3548 | -function varargout = ghostscript(cmd)
|
---|
| 3549 | -% Initialize any required system calls before calling ghostscript
|
---|
| 3550 | -shell_cmd = '';
|
---|
| 3551 | -if isunix
|
---|
| 3552 | - shell_cmd = 'export LD_LIBRARY_PATH=""; '; % Avoids an error on Linux with GS 9.07
|
---|
| 3553 | + try
|
---|
| 3554 | + % Call ghostscript
|
---|
| 3555 | + [varargout{1:nargout}] = system([gs_command(gs_path()) cmd]);
|
---|
| 3556 | + catch err
|
---|
| 3557 | + % Display possible workarounds for Ghostscript croaks
|
---|
| 3558 | + url1 = 'https://github.com/altmany/export_fig/issues/12#issuecomment-61467998'; % issue #12
|
---|
| 3559 | + url2 = 'https://github.com/altmany/export_fig/issues/20#issuecomment-63826270'; % issue #20
|
---|
| 3560 | + hg2_str = ''; if using_hg2, hg2_str = ' or Matlab R2014a'; end
|
---|
| 3561 | + 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);
|
---|
| 3562 | + if using_hg2
|
---|
| 3563 | + fprintf(2, '(GS 9.10)\n * <a href="%s">%s</a> (R2014a)',url2,url2);
|
---|
| 3564 | + end
|
---|
| 3565 | + fprintf('\n\n');
|
---|
| 3566 | + if ismac || isunix
|
---|
| 3567 | + url3 = 'https://github.com/altmany/export_fig/issues/27'; % issue #27
|
---|
| 3568 | + fprintf(2, 'Alternatively, this may possibly be due to a font path issue:\n * <a href="%s">%s</a>\n\n',url3,url3);
|
---|
| 3569 | + % issue #20
|
---|
| 3570 | + fpath = which(mfilename);
|
---|
| 3571 | + if isempty(fpath), fpath = [mfilename('fullpath') '.m']; end
|
---|
| 3572 | + 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);
|
---|
| 3573 | + end
|
---|
| 3574 | + rethrow(err);
|
---|
| 3575 | + end
|
---|
| 3576 | end
|
---|
| 3577 | -if ismac
|
---|
| 3578 | - shell_cmd = 'export DYLD_LIBRARY_PATH=""; '; % Avoids an error on Mac with GS 9.07
|
---|
| 3579 | -end
|
---|
| 3580 | -% Call ghostscript
|
---|
| 3581 | -[varargout{1:nargout}] = system(sprintf('%s"%s" %s', shell_cmd, gs_path, cmd));
|
---|
| 3582 | -end
|
---|
| 3583 |
|
---|
| 3584 | function path_ = gs_path
|
---|
| 3585 | -% Return a valid path
|
---|
| 3586 | -% Start with the currently set path
|
---|
| 3587 | -path_ = user_string('ghostscript');
|
---|
| 3588 | -% Check the path works
|
---|
| 3589 | -if check_gs_path(path_)
|
---|
| 3590 | - return
|
---|
| 3591 | -end
|
---|
| 3592 | -% Check whether the binary is on the path
|
---|
| 3593 | -if ispc
|
---|
| 3594 | - bin = {'gswin32c.exe', 'gswin64c.exe', 'gs'};
|
---|
| 3595 | -else
|
---|
| 3596 | - bin = {'gs'};
|
---|
| 3597 | -end
|
---|
| 3598 | -for a = 1:numel(bin)
|
---|
| 3599 | - path_ = bin{a};
|
---|
| 3600 | - if check_store_gs_path(path_)
|
---|
| 3601 | + % Return a valid path
|
---|
| 3602 | + % Start with the currently set path
|
---|
| 3603 | + path_ = user_string('ghostscript');
|
---|
| 3604 | + % Check the path works
|
---|
| 3605 | + if check_gs_path(path_)
|
---|
| 3606 | return
|
---|
| 3607 | end
|
---|
| 3608 | -end
|
---|
| 3609 | -% Search the obvious places
|
---|
| 3610 | -if ispc
|
---|
| 3611 | - default_location = 'C:\Program Files\gs\';
|
---|
| 3612 | - dir_list = dir(default_location);
|
---|
| 3613 | - if isempty(dir_list)
|
---|
| 3614 | - default_location = 'C:\Program Files (x86)\gs\'; % Possible location on 64-bit systems
|
---|
| 3615 | + % Check whether the binary is on the path
|
---|
| 3616 | + if ispc
|
---|
| 3617 | + bin = {'gswin32c.exe', 'gswin64c.exe', 'gs'};
|
---|
| 3618 | + else
|
---|
| 3619 | + bin = {'gs'};
|
---|
| 3620 | + end
|
---|
| 3621 | + for a = 1:numel(bin)
|
---|
| 3622 | + path_ = bin{a};
|
---|
| 3623 | + if check_store_gs_path(path_)
|
---|
| 3624 | + return
|
---|
| 3625 | + end
|
---|
| 3626 | + end
|
---|
| 3627 | + % Search the obvious places
|
---|
| 3628 | + if ispc
|
---|
| 3629 | + default_location = 'C:\Program Files\gs\';
|
---|
| 3630 | dir_list = dir(default_location);
|
---|
| 3631 | - end
|
---|
| 3632 | - executable = {'\bin\gswin32c.exe', '\bin\gswin64c.exe'};
|
---|
| 3633 | - ver_num = 0;
|
---|
| 3634 | - % If there are multiple versions, use the newest
|
---|
| 3635 | - for a = 1:numel(dir_list)
|
---|
| 3636 | - ver_num2 = sscanf(dir_list(a).name, 'gs%g');
|
---|
| 3637 | - if ~isempty(ver_num2) && ver_num2 > ver_num
|
---|
| 3638 | - for b = 1:numel(executable)
|
---|
| 3639 | - path2 = [default_location dir_list(a).name executable{b}];
|
---|
| 3640 | - if exist(path2, 'file') == 2
|
---|
| 3641 | - path_ = path2;
|
---|
| 3642 | - ver_num = ver_num2;
|
---|
| 3643 | + if isempty(dir_list)
|
---|
| 3644 | + default_location = 'C:\Program Files (x86)\gs\'; % Possible location on 64-bit systems
|
---|
| 3645 | + dir_list = dir(default_location);
|
---|
| 3646 | + end
|
---|
| 3647 | + executable = {'\bin\gswin32c.exe', '\bin\gswin64c.exe'};
|
---|
| 3648 | + ver_num = 0;
|
---|
| 3649 | + % If there are multiple versions, use the newest
|
---|
| 3650 | + for a = 1:numel(dir_list)
|
---|
| 3651 | + ver_num2 = sscanf(dir_list(a).name, 'gs%g');
|
---|
| 3652 | + if ~isempty(ver_num2) && ver_num2 > ver_num
|
---|
| 3653 | + for b = 1:numel(executable)
|
---|
| 3654 | + path2 = [default_location dir_list(a).name executable{b}];
|
---|
| 3655 | + if exist(path2, 'file') == 2
|
---|
| 3656 | + path_ = path2;
|
---|
| 3657 | + ver_num = ver_num2;
|
---|
| 3658 | + end
|
---|
| 3659 | end
|
---|
| 3660 | end
|
---|
| 3661 | end
|
---|
| 3662 | - end
|
---|
| 3663 | - if check_store_gs_path(path_)
|
---|
| 3664 | - return
|
---|
| 3665 | - end
|
---|
| 3666 | -else
|
---|
| 3667 | - executable = {'/usr/bin/gs', '/usr/local/bin/gs'};
|
---|
| 3668 | - for a = 1:numel(executable)
|
---|
| 3669 | - path_ = executable{a};
|
---|
| 3670 | if check_store_gs_path(path_)
|
---|
| 3671 | return
|
---|
| 3672 | end
|
---|
| 3673 | + else
|
---|
| 3674 | + executable = {'/usr/bin/gs', '/usr/local/bin/gs'};
|
---|
| 3675 | + for a = 1:numel(executable)
|
---|
| 3676 | + path_ = executable{a};
|
---|
| 3677 | + if check_store_gs_path(path_)
|
---|
| 3678 | + return
|
---|
| 3679 | + end
|
---|
| 3680 | + end
|
---|
| 3681 | end
|
---|
| 3682 | -end
|
---|
| 3683 | -% Ask the user to enter the path
|
---|
| 3684 | -while 1
|
---|
| 3685 | - if strncmp(computer, 'MAC', 3) % Is a Mac
|
---|
| 3686 | - % Give separate warning as the uigetdir dialogue box doesn't have a
|
---|
| 3687 | - % title
|
---|
| 3688 | - uiwait(warndlg('Ghostscript not found. Please locate the program.'))
|
---|
| 3689 | - end
|
---|
| 3690 | - base = uigetdir('/', 'Ghostcript not found. Please locate the program.');
|
---|
| 3691 | - if isequal(base, 0)
|
---|
| 3692 | - % User hit cancel or closed window
|
---|
| 3693 | - break;
|
---|
| 3694 | - end
|
---|
| 3695 | - base = [base filesep];
|
---|
| 3696 | - bin_dir = {'', ['bin' filesep], ['lib' filesep]};
|
---|
| 3697 | - for a = 1:numel(bin_dir)
|
---|
| 3698 | - for b = 1:numel(bin)
|
---|
| 3699 | - path_ = [base bin_dir{a} bin{b}];
|
---|
| 3700 | - if exist(path_, 'file') == 2
|
---|
| 3701 | - if check_store_gs_path(path_)
|
---|
| 3702 | - return
|
---|
| 3703 | + % Ask the user to enter the path
|
---|
| 3704 | + while true
|
---|
| 3705 | + if strncmp(computer, 'MAC', 3) % Is a Mac
|
---|
| 3706 | + % Give separate warning as the uigetdir dialogue box doesn't have a
|
---|
| 3707 | + % title
|
---|
| 3708 | + uiwait(warndlg('Ghostscript not found. Please locate the program.'))
|
---|
| 3709 | + end
|
---|
| 3710 | + base = uigetdir('/', 'Ghostcript not found. Please locate the program.');
|
---|
| 3711 | + if isequal(base, 0)
|
---|
| 3712 | + % User hit cancel or closed window
|
---|
| 3713 | + break;
|
---|
| 3714 | + end
|
---|
| 3715 | + base = [base filesep]; %#ok<AGROW>
|
---|
| 3716 | + bin_dir = {'', ['bin' filesep], ['lib' filesep]};
|
---|
| 3717 | + for a = 1:numel(bin_dir)
|
---|
| 3718 | + for b = 1:numel(bin)
|
---|
| 3719 | + path_ = [base bin_dir{a} bin{b}];
|
---|
| 3720 | + if exist(path_, 'file') == 2
|
---|
| 3721 | + if check_store_gs_path(path_)
|
---|
| 3722 | + return
|
---|
| 3723 | + end
|
---|
| 3724 | end
|
---|
| 3725 | end
|
---|
| 3726 | end
|
---|
| 3727 | end
|
---|
| 3728 | + if ismac
|
---|
| 3729 | + error('Ghostscript not found. Have you installed it (http://pages.uoregon.edu/koch)?');
|
---|
| 3730 | + else
|
---|
| 3731 | + error('Ghostscript not found. Have you installed it from www.ghostscript.com?');
|
---|
| 3732 | + end
|
---|
| 3733 | end
|
---|
| 3734 | -error('Ghostscript not found. Have you installed it from www.ghostscript.com?');
|
---|
| 3735 | -end
|
---|
| 3736 |
|
---|
| 3737 | function good = check_store_gs_path(path_)
|
---|
| 3738 | -% Check the path is valid
|
---|
| 3739 | -good = check_gs_path(path_);
|
---|
| 3740 | -if ~good
|
---|
| 3741 | - return
|
---|
| 3742 | + % Check the path is valid
|
---|
| 3743 | + good = check_gs_path(path_);
|
---|
| 3744 | + if ~good
|
---|
| 3745 | + return
|
---|
| 3746 | + end
|
---|
| 3747 | + % Update the current default path to the path found
|
---|
| 3748 | + if ~user_string('ghostscript', path_)
|
---|
| 3749 | + filename = fullfile(fileparts(which('user_string.m')), '.ignore', 'ghostscript.txt');
|
---|
| 3750 | + 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_);
|
---|
| 3751 | + return
|
---|
| 3752 | + end
|
---|
| 3753 | end
|
---|
| 3754 | -% Update the current default path to the path found
|
---|
| 3755 | -if ~user_string('ghostscript', path_)
|
---|
| 3756 | - warning('Path to ghostscript installation could not be saved. Enter it manually in %s.', fullfile(fileparts(which('user_string.m')), '.ignore', 'ghostscript.txt'));
|
---|
| 3757 | - return
|
---|
| 3758 | -end
|
---|
| 3759 | -end
|
---|
| 3760 |
|
---|
| 3761 | function good = check_gs_path(path_)
|
---|
| 3762 | -% Check the path is valid
|
---|
| 3763 | -shell_cmd = '';
|
---|
| 3764 | -if ismac
|
---|
| 3765 | - shell_cmd = 'export DYLD_LIBRARY_PATH=""; '; % Avoids an error on Mac with GS 9.07
|
---|
| 3766 | + persistent isOk
|
---|
| 3767 | + if isempty(path_)
|
---|
| 3768 | + isOk = false;
|
---|
| 3769 | + elseif ~isequal(isOk,true)
|
---|
| 3770 | + % Check whether the path is valid
|
---|
| 3771 | + [status, message] = system([gs_command(path_) '-h']); %#ok<ASGLU>
|
---|
| 3772 | + isOk = status == 0;
|
---|
| 3773 | + end
|
---|
| 3774 | + good = isOk;
|
---|
| 3775 | end
|
---|
| 3776 | -[good, message] = system(sprintf('%s"%s" -h', shell_cmd, path_));
|
---|
| 3777 | -good = good == 0;
|
---|
| 3778 | +
|
---|
| 3779 | +function cmd = gs_command(path_)
|
---|
| 3780 | + % Initialize any required system calls before calling ghostscript
|
---|
| 3781 | + % TODO: in Unix/Mac, find a way to determine whether to use "export" (bash) or "setenv" (csh/tcsh)
|
---|
| 3782 | + shell_cmd = '';
|
---|
| 3783 | + if isunix
|
---|
| 3784 | + shell_cmd = 'export LD_LIBRARY_PATH=""; '; % Avoids an error on Linux with GS 9.07
|
---|
| 3785 | + end
|
---|
| 3786 | + if ismac
|
---|
| 3787 | + shell_cmd = 'export DYLD_LIBRARY_PATH=""; '; % Avoids an error on Mac with GS 9.07
|
---|
| 3788 | + end
|
---|
| 3789 | + % Construct the command string
|
---|
| 3790 | + cmd = sprintf('%s"%s" ', shell_cmd, path_);
|
---|
| 3791 | end
|
---|
| 3792 | Index: ../trunk-jpl/externalpackages/export_fig/print2array.m
|
---|
| 3793 | ===================================================================
|
---|
| 3794 | --- ../trunk-jpl/externalpackages/export_fig/print2array.m (revision 21314)
|
---|
| 3795 | +++ ../trunk-jpl/externalpackages/export_fig/print2array.m (revision 21315)
|
---|
| 3796 | @@ -1,3 +1,4 @@
|
---|
| 3797 | +function [A, bcol] = print2array(fig, res, renderer, gs_options)
|
---|
| 3798 | %PRINT2ARRAY Exports a figure to an image array
|
---|
| 3799 | %
|
---|
| 3800 | % Examples:
|
---|
| 3801 | @@ -5,6 +6,7 @@
|
---|
| 3802 | % A = print2array(figure_handle)
|
---|
| 3803 | % A = print2array(figure_handle, resolution)
|
---|
| 3804 | % A = print2array(figure_handle, resolution, renderer)
|
---|
| 3805 | +% A = print2array(figure_handle, resolution, renderer, gs_options)
|
---|
| 3806 | % [A bcol] = print2array(...)
|
---|
| 3807 | %
|
---|
| 3808 | % This function outputs a bitmap image of the given figure, at the desired
|
---|
| 3809 | @@ -19,180 +21,224 @@
|
---|
| 3810 | % resolution. Default: 1.
|
---|
| 3811 | % renderer - string containing the renderer paramater to be passed to
|
---|
| 3812 | % print. Default: '-opengl'.
|
---|
| 3813 | +% gs_options - optional ghostscript options (e.g.: '-dNoOutputFonts'). If
|
---|
| 3814 | +% multiple options are needed, enclose in call array: {'-a','-b'}
|
---|
| 3815 | %
|
---|
| 3816 | % OUT:
|
---|
| 3817 | % A - MxNx3 uint8 image of the figure.
|
---|
| 3818 | % bcol - 1x3 uint8 vector of the background color
|
---|
| 3819 |
|
---|
| 3820 | -% Copyright (C) Oliver Woodford 2008-2012
|
---|
| 3821 | -
|
---|
| 3822 | +% Copyright (C) Oliver Woodford 2008-2014, Yair Altman 2015-
|
---|
| 3823 | +%{
|
---|
| 3824 | % 05/09/11: Set EraseModes to normal when using opengl or zbuffer
|
---|
| 3825 | -% renderers. Thanks to Pawel Kocieniewski for reporting the
|
---|
| 3826 | -% issue.
|
---|
| 3827 | -% 21/09/11: Bug fix: unit8 -> uint8! Thanks to Tobias Lamour for reporting
|
---|
| 3828 | -% the issue.
|
---|
| 3829 | -% 14/11/11: Bug fix: stop using hardcopy(), as it interfered with figure
|
---|
| 3830 | -% size and erasemode settings. Makes it a bit slower, but more
|
---|
| 3831 | -% reliable. Thanks to Phil Trinh and Meelis Lootus for reporting
|
---|
| 3832 | -% the issues.
|
---|
| 3833 | +% renderers. Thanks to Pawel Kocieniewski for reporting the issue.
|
---|
| 3834 | +% 21/09/11: Bug fix: unit8 -> uint8! Thanks to Tobias Lamour for reporting it.
|
---|
| 3835 | +% 14/11/11: Bug fix: stop using hardcopy(), as it interfered with figure size
|
---|
| 3836 | +% and erasemode settings. Makes it a bit slower, but more reliable.
|
---|
| 3837 | +% Thanks to Phil Trinh and Meelis Lootus for reporting the issues.
|
---|
| 3838 | % 09/12/11: Pass font path to ghostscript.
|
---|
| 3839 | % 27/01/12: Bug fix affecting painters rendering tall figures. Thanks to
|
---|
| 3840 | % Ken Campbell for reporting it.
|
---|
| 3841 | -% 03/04/12: Bug fix to median input. Thanks to Andy Matthews for reporting
|
---|
| 3842 | -% it.
|
---|
| 3843 | +% 03/04/12: Bug fix to median input. Thanks to Andy Matthews for reporting it.
|
---|
| 3844 | % 26/10/12: Set PaperOrientation to portrait. Thanks to Michael Watts for
|
---|
| 3845 | % reporting the issue.
|
---|
| 3846 | +% 26/02/15: If temp dir is not writable, use the current folder for temp
|
---|
| 3847 | +% EPS/TIF files (Javier Paredes)
|
---|
| 3848 | +% 27/02/15: Display suggested workarounds to internal print() error (issue #16)
|
---|
| 3849 | +% 28/02/15: Enable users to specify optional ghostscript options (issue #36)
|
---|
| 3850 | +% 10/03/15: Fixed minor warning reported by Paul Soderlind; fixed code indentation
|
---|
| 3851 | +% 28/05/15: Fixed issue #69: patches with LineWidth==0.75 appear wide (internal bug in Matlab's print() func)
|
---|
| 3852 | +% 07/07/15: Fixed issue #83: use numeric handles in HG1
|
---|
| 3853 | +%}
|
---|
| 3854 |
|
---|
| 3855 | -function [A, bcol] = print2array(fig, res, renderer)
|
---|
| 3856 | -% Generate default input arguments, if needed
|
---|
| 3857 | -if nargin < 2
|
---|
| 3858 | - res = 1;
|
---|
| 3859 | - if nargin < 1
|
---|
| 3860 | - fig = gcf;
|
---|
| 3861 | + % Generate default input arguments, if needed
|
---|
| 3862 | + if nargin < 2
|
---|
| 3863 | + res = 1;
|
---|
| 3864 | + if nargin < 1
|
---|
| 3865 | + fig = gcf;
|
---|
| 3866 | + end
|
---|
| 3867 | end
|
---|
| 3868 | -end
|
---|
| 3869 | -% Warn if output is large
|
---|
| 3870 | -old_mode = get(fig, 'Units');
|
---|
| 3871 | -set(fig, 'Units', 'pixels');
|
---|
| 3872 | -px = get(fig, 'Position');
|
---|
| 3873 | -set(fig, 'Units', old_mode);
|
---|
| 3874 | -npx = prod(px(3:4)*res)/1e6;
|
---|
| 3875 | -if npx > 30
|
---|
| 3876 | - % 30M pixels or larger!
|
---|
| 3877 | - warning('MATLAB:LargeImage', 'print2array generating a %.1fM pixel image. This could be slow and might also cause memory problems.', npx);
|
---|
| 3878 | -end
|
---|
| 3879 | -% Retrieve the background colour
|
---|
| 3880 | -bcol = get(fig, 'Color');
|
---|
| 3881 | -% Set the resolution parameter
|
---|
| 3882 | -res_str = ['-r' num2str(ceil(get(0, 'ScreenPixelsPerInch')*res))];
|
---|
| 3883 | -% Generate temporary file name
|
---|
| 3884 | -tmp_nam = [tempname '.tif'];
|
---|
| 3885 | -if nargin > 2 && strcmp(renderer, '-painters')
|
---|
| 3886 | - % Print to eps file
|
---|
| 3887 | - tmp_eps = [tempname '.eps'];
|
---|
| 3888 | - print2eps(tmp_eps, fig, 0, renderer, '-loose');
|
---|
| 3889 | + % Warn if output is large
|
---|
| 3890 | + old_mode = get(fig, 'Units');
|
---|
| 3891 | + set(fig, 'Units', 'pixels');
|
---|
| 3892 | + px = get(fig, 'Position');
|
---|
| 3893 | + set(fig, 'Units', old_mode);
|
---|
| 3894 | + npx = prod(px(3:4)*res)/1e6;
|
---|
| 3895 | + if npx > 30
|
---|
| 3896 | + % 30M pixels or larger!
|
---|
| 3897 | + warning('MATLAB:LargeImage', 'print2array generating a %.1fM pixel image. This could be slow and might also cause memory problems.', npx);
|
---|
| 3898 | + end
|
---|
| 3899 | + % Retrieve the background colour
|
---|
| 3900 | + bcol = get(fig, 'Color');
|
---|
| 3901 | + % Set the resolution parameter
|
---|
| 3902 | + res_str = ['-r' num2str(ceil(get(0, 'ScreenPixelsPerInch')*res))];
|
---|
| 3903 | + % Generate temporary file name
|
---|
| 3904 | + tmp_nam = [tempname '.tif'];
|
---|
| 3905 | try
|
---|
| 3906 | - % Initialize the command to export to tiff using ghostscript
|
---|
| 3907 | - cmd_str = ['-dEPSCrop -q -dNOPAUSE -dBATCH ' res_str ' -sDEVICE=tiff24nc'];
|
---|
| 3908 | - % Set the font path
|
---|
| 3909 | - fp = font_path();
|
---|
| 3910 | - if ~isempty(fp)
|
---|
| 3911 | - cmd_str = [cmd_str ' -sFONTPATH="' fp '"'];
|
---|
| 3912 | + % Ensure that the temp dir is writable (Javier Paredes 26/2/15)
|
---|
| 3913 | + fid = fopen(tmp_nam,'w');
|
---|
| 3914 | + fwrite(fid,1);
|
---|
| 3915 | + fclose(fid);
|
---|
| 3916 | + delete(tmp_nam); % cleanup
|
---|
| 3917 | + isTempDirOk = true;
|
---|
| 3918 | + catch
|
---|
| 3919 | + % Temp dir is not writable, so use the current folder
|
---|
| 3920 | + [dummy,fname,fext] = fileparts(tmp_nam); %#ok<ASGLU>
|
---|
| 3921 | + fpath = pwd;
|
---|
| 3922 | + tmp_nam = fullfile(fpath,[fname fext]);
|
---|
| 3923 | + isTempDirOk = false;
|
---|
| 3924 | + end
|
---|
| 3925 | + % Enable users to specify optional ghostscript options (issue #36)
|
---|
| 3926 | + if nargin > 3 && ~isempty(gs_options)
|
---|
| 3927 | + if iscell(gs_options)
|
---|
| 3928 | + gs_options = sprintf(' %s',gs_options{:});
|
---|
| 3929 | + elseif ~ischar(gs_options)
|
---|
| 3930 | + error('gs_options input argument must be a string or cell-array of strings');
|
---|
| 3931 | + else
|
---|
| 3932 | + gs_options = [' ' gs_options];
|
---|
| 3933 | end
|
---|
| 3934 | - % Add the filenames
|
---|
| 3935 | - cmd_str = [cmd_str ' -sOutputFile="' tmp_nam '" "' tmp_eps '"'];
|
---|
| 3936 | - % Execute the ghostscript command
|
---|
| 3937 | - ghostscript(cmd_str);
|
---|
| 3938 | - catch me
|
---|
| 3939 | - % Delete the intermediate file
|
---|
| 3940 | - delete(tmp_eps);
|
---|
| 3941 | - rethrow(me);
|
---|
| 3942 | + else
|
---|
| 3943 | + gs_options = '';
|
---|
| 3944 | end
|
---|
| 3945 | - % Delete the intermediate file
|
---|
| 3946 | - delete(tmp_eps);
|
---|
| 3947 | - % Read in the generated bitmap
|
---|
| 3948 | - A = imread(tmp_nam);
|
---|
| 3949 | - % Delete the temporary bitmap file
|
---|
| 3950 | - delete(tmp_nam);
|
---|
| 3951 | - % Set border pixels to the correct colour
|
---|
| 3952 | - if isequal(bcol, 'none')
|
---|
| 3953 | - bcol = [];
|
---|
| 3954 | - elseif isequal(bcol, [1 1 1])
|
---|
| 3955 | - bcol = uint8([255 255 255]);
|
---|
| 3956 | - else
|
---|
| 3957 | - for l = 1:size(A, 2)
|
---|
| 3958 | - if ~all(reshape(A(:,l,:) == 255, [], 1))
|
---|
| 3959 | - break;
|
---|
| 3960 | - end
|
---|
| 3961 | + if nargin > 2 && strcmp(renderer, '-painters')
|
---|
| 3962 | + % Print to eps file
|
---|
| 3963 | + if isTempDirOk
|
---|
| 3964 | + tmp_eps = [tempname '.eps'];
|
---|
| 3965 | + else
|
---|
| 3966 | + tmp_eps = fullfile(fpath,[fname '.eps']);
|
---|
| 3967 | end
|
---|
| 3968 | - for r = size(A, 2):-1:l
|
---|
| 3969 | - if ~all(reshape(A(:,r,:) == 255, [], 1))
|
---|
| 3970 | - break;
|
---|
| 3971 | + print2eps(tmp_eps, fig, 0, renderer, '-loose');
|
---|
| 3972 | + try
|
---|
| 3973 | + % Initialize the command to export to tiff using ghostscript
|
---|
| 3974 | + cmd_str = ['-dEPSCrop -q -dNOPAUSE -dBATCH ' res_str ' -sDEVICE=tiff24nc'];
|
---|
| 3975 | + % Set the font path
|
---|
| 3976 | + fp = font_path();
|
---|
| 3977 | + if ~isempty(fp)
|
---|
| 3978 | + cmd_str = [cmd_str ' -sFONTPATH="' fp '"'];
|
---|
| 3979 | end
|
---|
| 3980 | + % Add the filenames
|
---|
| 3981 | + cmd_str = [cmd_str ' -sOutputFile="' tmp_nam '" "' tmp_eps '"' gs_options];
|
---|
| 3982 | + % Execute the ghostscript command
|
---|
| 3983 | + ghostscript(cmd_str);
|
---|
| 3984 | + catch me
|
---|
| 3985 | + % Delete the intermediate file
|
---|
| 3986 | + delete(tmp_eps);
|
---|
| 3987 | + rethrow(me);
|
---|
| 3988 | end
|
---|
| 3989 | - for t = 1:size(A, 1)
|
---|
| 3990 | - if ~all(reshape(A(t,:,:) == 255, [], 1))
|
---|
| 3991 | - break;
|
---|
| 3992 | + % Delete the intermediate file
|
---|
| 3993 | + delete(tmp_eps);
|
---|
| 3994 | + % Read in the generated bitmap
|
---|
| 3995 | + A = imread(tmp_nam);
|
---|
| 3996 | + % Delete the temporary bitmap file
|
---|
| 3997 | + delete(tmp_nam);
|
---|
| 3998 | + % Set border pixels to the correct colour
|
---|
| 3999 | + if isequal(bcol, 'none')
|
---|
| 4000 | + bcol = [];
|
---|
| 4001 | + elseif isequal(bcol, [1 1 1])
|
---|
| 4002 | + bcol = uint8([255 255 255]);
|
---|
| 4003 | + else
|
---|
| 4004 | + for l = 1:size(A, 2)
|
---|
| 4005 | + if ~all(reshape(A(:,l,:) == 255, [], 1))
|
---|
| 4006 | + break;
|
---|
| 4007 | + end
|
---|
| 4008 | end
|
---|
| 4009 | - end
|
---|
| 4010 | - for b = size(A, 1):-1:t
|
---|
| 4011 | - if ~all(reshape(A(b,:,:) == 255, [], 1))
|
---|
| 4012 | - break;
|
---|
| 4013 | + for r = size(A, 2):-1:l
|
---|
| 4014 | + if ~all(reshape(A(:,r,:) == 255, [], 1))
|
---|
| 4015 | + break;
|
---|
| 4016 | + end
|
---|
| 4017 | end
|
---|
| 4018 | + for t = 1:size(A, 1)
|
---|
| 4019 | + if ~all(reshape(A(t,:,:) == 255, [], 1))
|
---|
| 4020 | + break;
|
---|
| 4021 | + end
|
---|
| 4022 | + end
|
---|
| 4023 | + for b = size(A, 1):-1:t
|
---|
| 4024 | + if ~all(reshape(A(b,:,:) == 255, [], 1))
|
---|
| 4025 | + break;
|
---|
| 4026 | + end
|
---|
| 4027 | + end
|
---|
| 4028 | + bcol = uint8(median(single([reshape(A(:,[l r],:), [], size(A, 3)); reshape(A([t b],:,:), [], size(A, 3))]), 1));
|
---|
| 4029 | + for c = 1:size(A, 3)
|
---|
| 4030 | + A(:,[1:l-1, r+1:end],c) = bcol(c);
|
---|
| 4031 | + A([1:t-1, b+1:end],:,c) = bcol(c);
|
---|
| 4032 | + end
|
---|
| 4033 | end
|
---|
| 4034 | - bcol = uint8(median(single([reshape(A(:,[l r],:), [], size(A, 3)); reshape(A([t b],:,:), [], size(A, 3))]), 1));
|
---|
| 4035 | - for c = 1:size(A, 3)
|
---|
| 4036 | - A(:,[1:l-1, r+1:end],c) = bcol(c);
|
---|
| 4037 | - A([1:t-1, b+1:end],:,c) = bcol(c);
|
---|
| 4038 | + else
|
---|
| 4039 | + if nargin < 3
|
---|
| 4040 | + renderer = '-opengl';
|
---|
| 4041 | end
|
---|
| 4042 | - end
|
---|
| 4043 | -else
|
---|
| 4044 | - if nargin < 3
|
---|
| 4045 | - renderer = '-opengl';
|
---|
| 4046 | - end
|
---|
| 4047 | - err = false;
|
---|
| 4048 | - % Set paper size
|
---|
| 4049 | - old_pos_mode = get(fig, 'PaperPositionMode');
|
---|
| 4050 | - old_orientation = get(fig, 'PaperOrientation');
|
---|
| 4051 | - set(fig, 'PaperPositionMode', 'auto', 'PaperOrientation', 'portrait');
|
---|
| 4052 | - try
|
---|
| 4053 | - % Print to tiff file
|
---|
| 4054 | - print(fig, renderer, res_str, '-dtiff', tmp_nam);
|
---|
| 4055 | - % Read in the printed file
|
---|
| 4056 | - A = imread(tmp_nam);
|
---|
| 4057 | - % Delete the temporary file
|
---|
| 4058 | - delete(tmp_nam);
|
---|
| 4059 | - catch ex
|
---|
| 4060 | - err = true;
|
---|
| 4061 | - end
|
---|
| 4062 | - % Reset paper size
|
---|
| 4063 | - set(fig, 'PaperPositionMode', old_pos_mode, 'PaperOrientation', old_orientation);
|
---|
| 4064 | - % Throw any error that occurred
|
---|
| 4065 | - if err
|
---|
| 4066 | - rethrow(ex);
|
---|
| 4067 | - end
|
---|
| 4068 | - % Set the background color
|
---|
| 4069 | - if isequal(bcol, 'none')
|
---|
| 4070 | - bcol = [];
|
---|
| 4071 | - else
|
---|
| 4072 | - bcol = bcol * 255;
|
---|
| 4073 | - if isequal(bcol, round(bcol))
|
---|
| 4074 | - bcol = uint8(bcol);
|
---|
| 4075 | + err = false;
|
---|
| 4076 | + % Set paper size
|
---|
| 4077 | + old_pos_mode = get(fig, 'PaperPositionMode');
|
---|
| 4078 | + old_orientation = get(fig, 'PaperOrientation');
|
---|
| 4079 | + set(fig, 'PaperPositionMode', 'auto', 'PaperOrientation', 'portrait');
|
---|
| 4080 | + try
|
---|
| 4081 | + % Workaround for issue #69: patches with LineWidth==0.75 appear wide (internal bug in Matlab's print() function)
|
---|
| 4082 | + fp = []; % in case we get an error below
|
---|
| 4083 | + fp = findall(fig, 'Type','patch', 'LineWidth',0.75);
|
---|
| 4084 | + set(fp, 'LineWidth',0.5);
|
---|
| 4085 | + % Fix issue #83: use numeric handles in HG1
|
---|
| 4086 | + if ~using_hg2(fig), fig = double(fig); end
|
---|
| 4087 | + % Print to tiff file
|
---|
| 4088 | + print(fig, renderer, res_str, '-dtiff', tmp_nam);
|
---|
| 4089 | + % Read in the printed file
|
---|
| 4090 | + A = imread(tmp_nam);
|
---|
| 4091 | + % Delete the temporary file
|
---|
| 4092 | + delete(tmp_nam);
|
---|
| 4093 | + catch ex
|
---|
| 4094 | + err = true;
|
---|
| 4095 | + end
|
---|
| 4096 | + set(fp, 'LineWidth',0.75); % restore original figure appearance
|
---|
| 4097 | + % Reset paper size
|
---|
| 4098 | + set(fig, 'PaperPositionMode', old_pos_mode, 'PaperOrientation', old_orientation);
|
---|
| 4099 | + % Throw any error that occurred
|
---|
| 4100 | + if err
|
---|
| 4101 | + % Display suggested workarounds to internal print() error (issue #16)
|
---|
| 4102 | + fprintf(2, 'An error occured with Matlab''s builtin print function.\nTry setting the figure Renderer to ''painters'' or use opengl(''software'').\n\n');
|
---|
| 4103 | + rethrow(ex);
|
---|
| 4104 | + end
|
---|
| 4105 | + % Set the background color
|
---|
| 4106 | + if isequal(bcol, 'none')
|
---|
| 4107 | + bcol = [];
|
---|
| 4108 | else
|
---|
| 4109 | - bcol = squeeze(A(1,1,:));
|
---|
| 4110 | + bcol = bcol * 255;
|
---|
| 4111 | + if isequal(bcol, round(bcol))
|
---|
| 4112 | + bcol = uint8(bcol);
|
---|
| 4113 | + else
|
---|
| 4114 | + bcol = squeeze(A(1,1,:));
|
---|
| 4115 | + end
|
---|
| 4116 | end
|
---|
| 4117 | end
|
---|
| 4118 | -end
|
---|
| 4119 | -% Check the output size is correct
|
---|
| 4120 | -if isequal(res, round(res))
|
---|
| 4121 | - px = [px([4 3])*res 3];
|
---|
| 4122 | - if ~isequal(size(A), px)
|
---|
| 4123 | - % Correct the output size
|
---|
| 4124 | - A = A(1:min(end,px(1)),1:min(end,px(2)),:);
|
---|
| 4125 | + % Check the output size is correct
|
---|
| 4126 | + if isequal(res, round(res))
|
---|
| 4127 | + px = round([px([4 3])*res 3]); % round() to avoid an indexing warning below
|
---|
| 4128 | + if ~isequal(size(A), px)
|
---|
| 4129 | + % Correct the output size
|
---|
| 4130 | + A = A(1:min(end,px(1)),1:min(end,px(2)),:);
|
---|
| 4131 | + end
|
---|
| 4132 | end
|
---|
| 4133 | end
|
---|
| 4134 | -end
|
---|
| 4135 |
|
---|
| 4136 | % Function to return (and create, where necessary) the font path
|
---|
| 4137 | function fp = font_path()
|
---|
| 4138 | -fp = user_string('gs_font_path');
|
---|
| 4139 | -if ~isempty(fp)
|
---|
| 4140 | - return
|
---|
| 4141 | -end
|
---|
| 4142 | -% Create the path
|
---|
| 4143 | -% Start with the default path
|
---|
| 4144 | -fp = getenv('GS_FONTPATH');
|
---|
| 4145 | -% Add on the typical directories for a given OS
|
---|
| 4146 | -if ispc
|
---|
| 4147 | + fp = user_string('gs_font_path');
|
---|
| 4148 | if ~isempty(fp)
|
---|
| 4149 | - fp = [fp ';'];
|
---|
| 4150 | + return
|
---|
| 4151 | end
|
---|
| 4152 | - fp = [fp getenv('WINDIR') filesep 'Fonts'];
|
---|
| 4153 | -else
|
---|
| 4154 | - if ~isempty(fp)
|
---|
| 4155 | - fp = [fp ':'];
|
---|
| 4156 | + % Create the path
|
---|
| 4157 | + % Start with the default path
|
---|
| 4158 | + fp = getenv('GS_FONTPATH');
|
---|
| 4159 | + % Add on the typical directories for a given OS
|
---|
| 4160 | + if ispc
|
---|
| 4161 | + if ~isempty(fp)
|
---|
| 4162 | + fp = [fp ';'];
|
---|
| 4163 | + end
|
---|
| 4164 | + fp = [fp getenv('WINDIR') filesep 'Fonts'];
|
---|
| 4165 | + else
|
---|
| 4166 | + if ~isempty(fp)
|
---|
| 4167 | + fp = [fp ':'];
|
---|
| 4168 | + end
|
---|
| 4169 | + 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'];
|
---|
| 4170 | end
|
---|
| 4171 | - 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'];
|
---|
| 4172 | + user_string('gs_font_path', fp);
|
---|
| 4173 | end
|
---|
| 4174 | -user_string('gs_font_path', fp);
|
---|
| 4175 | -end
|
---|
| 4176 | Index: ../trunk-jpl/externalpackages/export_fig/ImageSelection.java
|
---|
| 4177 | ===================================================================
|
---|
| 4178 | --- ../trunk-jpl/externalpackages/export_fig/ImageSelection.java (revision 0)
|
---|
| 4179 | +++ ../trunk-jpl/externalpackages/export_fig/ImageSelection.java (revision 21315)
|
---|
| 4180 | @@ -0,0 +1,38 @@
|
---|
| 4181 | +/*
|
---|
| 4182 | + * Based on code snippet from
|
---|
| 4183 | + * http://java.sun.com/developer/technicalArticles/releases/data/
|
---|
| 4184 | + *
|
---|
| 4185 | + * Copyright © 2008, 2010 Oracle and/or its affiliates. All rights reserved. Use is subject to license terms.
|
---|
| 4186 | + */
|
---|
| 4187 | +
|
---|
| 4188 | +import java.awt.image.BufferedImage;
|
---|
| 4189 | +import java.awt.datatransfer.*;
|
---|
| 4190 | +
|
---|
| 4191 | +public class ImageSelection implements Transferable {
|
---|
| 4192 | +
|
---|
| 4193 | + private static final DataFlavor flavors[] =
|
---|
| 4194 | + {DataFlavor.imageFlavor};
|
---|
| 4195 | +
|
---|
| 4196 | + private BufferedImage image;
|
---|
| 4197 | +
|
---|
| 4198 | + public ImageSelection(BufferedImage image) {
|
---|
| 4199 | + this.image = image;
|
---|
| 4200 | + }
|
---|
| 4201 | +
|
---|
| 4202 | + // Transferable
|
---|
| 4203 | + public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
|
---|
| 4204 | + if (flavor.equals(flavors[0]) == false) {
|
---|
| 4205 | + throw new UnsupportedFlavorException(flavor);
|
---|
| 4206 | + }
|
---|
| 4207 | + return image;
|
---|
| 4208 | + }
|
---|
| 4209 | +
|
---|
| 4210 | + public DataFlavor[] getTransferDataFlavors() {
|
---|
| 4211 | + return flavors;
|
---|
| 4212 | + }
|
---|
| 4213 | +
|
---|
| 4214 | + public boolean isDataFlavorSupported(DataFlavor
|
---|
| 4215 | + flavor) {
|
---|
| 4216 | + return flavor.equals(flavors[0]);
|
---|
| 4217 | + }
|
---|
| 4218 | +}
|
---|
| 4219 | \ No newline at end of file
|
---|
| 4220 |
|
---|
| 4221 | Property changes on: ../trunk-jpl/externalpackages/export_fig/ImageSelection.java
|
---|
| 4222 | ___________________________________________________________________
|
---|
| 4223 | Added: svn:executable
|
---|
| 4224 | + *
|
---|
| 4225 |
|
---|
| 4226 | Index: ../trunk-jpl/externalpackages/export_fig/pdftops.m
|
---|
| 4227 | ===================================================================
|
---|
| 4228 | --- ../trunk-jpl/externalpackages/export_fig/pdftops.m (revision 21314)
|
---|
| 4229 | +++ ../trunk-jpl/externalpackages/export_fig/pdftops.m (revision 21315)
|
---|
| 4230 | @@ -15,7 +15,7 @@
|
---|
| 4231 | % http://www.foolabs.com/xpdf
|
---|
| 4232 | %
|
---|
| 4233 | % IN:
|
---|
| 4234 | -% cmd - Command string to be passed into pdftops.
|
---|
| 4235 | +% cmd - Command string to be passed into pdftops (e.g. '-help').
|
---|
| 4236 | %
|
---|
| 4237 | % OUT:
|
---|
| 4238 | % status - 0 iff command ran without problem.
|
---|
| 4239 | @@ -23,87 +23,128 @@
|
---|
| 4240 |
|
---|
| 4241 | % Copyright: Oliver Woodford, 2009-2010
|
---|
| 4242 |
|
---|
| 4243 | -% Thanks to Jonas Dorn for the fix for the title of the uigetdir window on
|
---|
| 4244 | -% Mac OS.
|
---|
| 4245 | -% Thanks to Christoph Hertel for pointing out a bug in check_xpdf_path
|
---|
| 4246 | -% under linux.
|
---|
| 4247 | +% Thanks to Jonas Dorn for the fix for the title of the uigetdir window on Mac OS.
|
---|
| 4248 | +% Thanks to Christoph Hertel for pointing out a bug in check_xpdf_path under linux.
|
---|
| 4249 | % 23/01/2014 - Add full path to pdftops.txt in warning.
|
---|
| 4250 | +% 27/05/2015 - Fixed alert in case of missing pdftops; fixed code indentation
|
---|
| 4251 | +% 02/05/2016 - Added possible error explanation suggested by Michael Pacer (issue #137)
|
---|
| 4252 | +% 02/05/2016 - Search additional possible paths suggested by Jonas Stein (issue #147)
|
---|
| 4253 | +% 03/05/2016 - Display the specific error message if pdftops fails for some reason (issue #148)
|
---|
| 4254 |
|
---|
| 4255 | -% Call pdftops
|
---|
| 4256 | -[varargout{1:nargout}] = system(sprintf('"%s" %s', xpdf_path, cmd));
|
---|
| 4257 | + % Call pdftops
|
---|
| 4258 | + [varargout{1:nargout}] = system(sprintf('"%s" %s', xpdf_path, cmd));
|
---|
| 4259 | end
|
---|
| 4260 |
|
---|
| 4261 | function path_ = xpdf_path
|
---|
| 4262 | -% Return a valid path
|
---|
| 4263 | -% Start with the currently set path
|
---|
| 4264 | -path_ = user_string('pdftops');
|
---|
| 4265 | -% Check the path works
|
---|
| 4266 | -if check_xpdf_path(path_)
|
---|
| 4267 | - return
|
---|
| 4268 | -end
|
---|
| 4269 | -% Check whether the binary is on the path
|
---|
| 4270 | -if ispc
|
---|
| 4271 | - bin = 'pdftops.exe';
|
---|
| 4272 | -else
|
---|
| 4273 | - bin = 'pdftops';
|
---|
| 4274 | -end
|
---|
| 4275 | -if check_store_xpdf_path(bin)
|
---|
| 4276 | - path_ = bin;
|
---|
| 4277 | - return
|
---|
| 4278 | -end
|
---|
| 4279 | -% Search the obvious places
|
---|
| 4280 | -if ispc
|
---|
| 4281 | - path_ = 'C:\Program Files\xpdf\pdftops.exe';
|
---|
| 4282 | -else
|
---|
| 4283 | - path_ = '/usr/local/bin/pdftops';
|
---|
| 4284 | -end
|
---|
| 4285 | -if check_store_xpdf_path(path_)
|
---|
| 4286 | - return
|
---|
| 4287 | -end
|
---|
| 4288 | -% Ask the user to enter the path
|
---|
| 4289 | -while 1
|
---|
| 4290 | - if strncmp(computer,'MAC',3) % Is a Mac
|
---|
| 4291 | - % Give separate warning as the uigetdir dialogue box doesn't have a
|
---|
| 4292 | - % title
|
---|
| 4293 | - uiwait(warndlg('Pdftops not found. Please locate the program, or install xpdf-tools from http://users.phg-online.de/tk/MOSXS/.'))
|
---|
| 4294 | + % Return a valid path
|
---|
| 4295 | + % Start with the currently set path
|
---|
| 4296 | + path_ = user_string('pdftops');
|
---|
| 4297 | + % Check the path works
|
---|
| 4298 | + if check_xpdf_path(path_)
|
---|
| 4299 | + return
|
---|
| 4300 | end
|
---|
| 4301 | - base = uigetdir('/', 'Pdftops not found. Please locate the program.');
|
---|
| 4302 | - if isequal(base, 0)
|
---|
| 4303 | - % User hit cancel or closed window
|
---|
| 4304 | - break;
|
---|
| 4305 | + % Check whether the binary is on the path
|
---|
| 4306 | + if ispc
|
---|
| 4307 | + bin = 'pdftops.exe';
|
---|
| 4308 | + else
|
---|
| 4309 | + bin = 'pdftops';
|
---|
| 4310 | end
|
---|
| 4311 | - base = [base filesep];
|
---|
| 4312 | - bin_dir = {'', ['bin' filesep], ['lib' filesep]};
|
---|
| 4313 | - for a = 1:numel(bin_dir)
|
---|
| 4314 | - path_ = [base bin_dir{a} bin];
|
---|
| 4315 | - if exist(path_, 'file') == 2
|
---|
| 4316 | - break;
|
---|
| 4317 | + if check_store_xpdf_path(bin)
|
---|
| 4318 | + path_ = bin;
|
---|
| 4319 | + return
|
---|
| 4320 | + end
|
---|
| 4321 | + % Search the obvious places
|
---|
| 4322 | + if ispc
|
---|
| 4323 | + paths = {'C:\Program Files\xpdf\pdftops.exe', 'C:\Program Files (x86)\xpdf\pdftops.exe'};
|
---|
| 4324 | + else
|
---|
| 4325 | + paths = {'/usr/bin/pdftops', '/usr/local/bin/pdftops'};
|
---|
| 4326 | + end
|
---|
| 4327 | + for a = 1:numel(paths)
|
---|
| 4328 | + path_ = paths{a};
|
---|
| 4329 | + if check_store_xpdf_path(path_)
|
---|
| 4330 | + return
|
---|
| 4331 | end
|
---|
| 4332 | end
|
---|
| 4333 | - if check_store_xpdf_path(path_)
|
---|
| 4334 | - return
|
---|
| 4335 | +
|
---|
| 4336 | + % Ask the user to enter the path
|
---|
| 4337 | + errMsg1 = 'Pdftops not found. Please locate the program, or install xpdf-tools from ';
|
---|
| 4338 | + url1 = 'http://foolabs.com/xpdf';
|
---|
| 4339 | + fprintf(2, '%s\n', [errMsg1 '<a href="matlab:web(''-browser'',''' url1 ''');">' url1 '</a>']);
|
---|
| 4340 | + errMsg1 = [errMsg1 url1];
|
---|
| 4341 | + %if strncmp(computer,'MAC',3) % Is a Mac
|
---|
| 4342 | + % % Give separate warning as the MacOS uigetdir dialogue box doesn't have a title
|
---|
| 4343 | + % uiwait(warndlg(errMsg1))
|
---|
| 4344 | + %end
|
---|
| 4345 | +
|
---|
| 4346 | + % Provide an alternative possible explanation as per issue #137
|
---|
| 4347 | + errMsg2 = 'If you have pdftops installed, perhaps Matlab is shaddowing it as described in ';
|
---|
| 4348 | + url2 = 'https://github.com/altmany/export_fig/issues/137';
|
---|
| 4349 | + fprintf(2, '%s\n', [errMsg2 '<a href="matlab:web(''-browser'',''' url2 ''');">issue #137</a>']);
|
---|
| 4350 | + errMsg2 = [errMsg2 url1];
|
---|
| 4351 | +
|
---|
| 4352 | + state = 0;
|
---|
| 4353 | + while 1
|
---|
| 4354 | + if state
|
---|
| 4355 | + option1 = 'Install pdftops';
|
---|
| 4356 | + else
|
---|
| 4357 | + option1 = 'Issue #137';
|
---|
| 4358 | + end
|
---|
| 4359 | + answer = questdlg({errMsg1,'',errMsg2},'Pdftops error',option1,'Locate pdftops','Cancel','Cancel');
|
---|
| 4360 | + drawnow; % prevent a Matlab hang: http://undocumentedmatlab.com/blog/solving-a-matlab-hang-problem
|
---|
| 4361 | + switch answer
|
---|
| 4362 | + case 'Install pdftops'
|
---|
| 4363 | + web('-browser',url1);
|
---|
| 4364 | + case 'Issue #137'
|
---|
| 4365 | + web('-browser',url2);
|
---|
| 4366 | + state = 1;
|
---|
| 4367 | + case 'Locate pdftops'
|
---|
| 4368 | + base = uigetdir('/', errMsg1);
|
---|
| 4369 | + if isequal(base, 0)
|
---|
| 4370 | + % User hit cancel or closed window
|
---|
| 4371 | + break
|
---|
| 4372 | + end
|
---|
| 4373 | + base = [base filesep]; %#ok<AGROW>
|
---|
| 4374 | + bin_dir = {'', ['bin' filesep], ['lib' filesep]};
|
---|
| 4375 | + for a = 1:numel(bin_dir)
|
---|
| 4376 | + path_ = [base bin_dir{a} bin];
|
---|
| 4377 | + if exist(path_, 'file') == 2
|
---|
| 4378 | + break
|
---|
| 4379 | + end
|
---|
| 4380 | + end
|
---|
| 4381 | + if check_store_xpdf_path(path_)
|
---|
| 4382 | + return
|
---|
| 4383 | + end
|
---|
| 4384 | +
|
---|
| 4385 | + otherwise % User hit Cancel or closed window
|
---|
| 4386 | + break
|
---|
| 4387 | + end
|
---|
| 4388 | end
|
---|
| 4389 | + error('pdftops executable not found.');
|
---|
| 4390 | end
|
---|
| 4391 | -error('pdftops executable not found.');
|
---|
| 4392 | -end
|
---|
| 4393 |
|
---|
| 4394 | function good = check_store_xpdf_path(path_)
|
---|
| 4395 | -% Check the path is valid
|
---|
| 4396 | -good = check_xpdf_path(path_);
|
---|
| 4397 | -if ~good
|
---|
| 4398 | - return
|
---|
| 4399 | + % Check the path is valid
|
---|
| 4400 | + good = check_xpdf_path(path_);
|
---|
| 4401 | + if ~good
|
---|
| 4402 | + return
|
---|
| 4403 | + end
|
---|
| 4404 | + % Update the current default path to the path found
|
---|
| 4405 | + if ~user_string('pdftops', path_)
|
---|
| 4406 | + warning('Path to pdftops executable could not be saved. Enter it manually in %s.', fullfile(fileparts(which('user_string.m')), '.ignore', 'pdftops.txt'));
|
---|
| 4407 | + return
|
---|
| 4408 | + end
|
---|
| 4409 | end
|
---|
| 4410 | -% Update the current default path to the path found
|
---|
| 4411 | -if ~user_string('pdftops', path_)
|
---|
| 4412 | - warning('Path to pdftops executable could not be saved. Enter it manually in %s.', fullfile(fileparts(which('user_string.m')), '.ignore', 'pdftops.txt'));
|
---|
| 4413 | - return
|
---|
| 4414 | -end
|
---|
| 4415 | -end
|
---|
| 4416 |
|
---|
| 4417 | function good = check_xpdf_path(path_)
|
---|
| 4418 | -% Check the path is valid
|
---|
| 4419 | -[good, message] = system(sprintf('"%s" -h', path_));
|
---|
| 4420 | -% system returns good = 1 even when the command runs
|
---|
| 4421 | -% Look for something distinct in the help text
|
---|
| 4422 | -good = ~isempty(strfind(message, 'PostScript'));
|
---|
| 4423 | + % Check the path is valid
|
---|
| 4424 | + [good, message] = system(sprintf('"%s" -h', path_)); %#ok<ASGLU>
|
---|
| 4425 | + % system returns good = 1 even when the command runs
|
---|
| 4426 | + % Look for something distinct in the help text
|
---|
| 4427 | + good = ~isempty(strfind(message, 'PostScript'));
|
---|
| 4428 | +
|
---|
| 4429 | + % Display the error message if the pdftops executable exists but fails for some reason
|
---|
| 4430 | + if ~good && exist(path_,'file') % file exists but generates an error
|
---|
| 4431 | + fprintf('Error running %s:\n', path_);
|
---|
| 4432 | + fprintf(2,'%s\n\n',message);
|
---|
| 4433 | + end
|
---|
| 4434 | end
|
---|
| 4435 | Index: ../trunk-jpl/externalpackages/export_fig/fix_lines.m
|
---|
| 4436 | ===================================================================
|
---|
| 4437 | --- ../trunk-jpl/externalpackages/export_fig/fix_lines.m (revision 21314)
|
---|
| 4438 | +++ ../trunk-jpl/externalpackages/export_fig/fix_lines.m (revision 21315)
|
---|
| 4439 | @@ -37,8 +37,16 @@
|
---|
| 4440 | % Thank you to Laurence K for suggesting the check to see if the file was
|
---|
| 4441 | % opened.
|
---|
| 4442 |
|
---|
| 4443 | +% 01/03/15: Issue #20: warn users if using this function in HG2 (R2014b+)
|
---|
| 4444 | +% 27/03/15: Fixed out of memory issue with enormous EPS files (generated by print() with OpenGL renderer), related to issue #39
|
---|
| 4445 | +
|
---|
| 4446 | function fstrm = fix_lines(fstrm, fname2)
|
---|
| 4447 |
|
---|
| 4448 | +% Issue #20: warn users if using this function in HG2 (R2014b+)
|
---|
| 4449 | +if using_hg2
|
---|
| 4450 | + warning('export_fig:hg2','The fix_lines function should not be used in this Matlab version.');
|
---|
| 4451 | +end
|
---|
| 4452 | +
|
---|
| 4453 | if nargout == 0 || nargin > 1
|
---|
| 4454 | if nargin < 2
|
---|
| 4455 | % Overwrite the input file
|
---|
| 4456 | @@ -113,11 +121,6 @@
|
---|
| 4457 | end
|
---|
| 4458 | end
|
---|
| 4459 |
|
---|
| 4460 | -% Isolate line style definition section
|
---|
| 4461 | -first_sec = strfind(fstrm, '% line types:');
|
---|
| 4462 | -[second_sec, remaining] = strtok(fstrm(first_sec+1:end), '/');
|
---|
| 4463 | -[remaining, remaining] = strtok(remaining, '%');
|
---|
| 4464 | -
|
---|
| 4465 | % Define the new styles, including the new GR format
|
---|
| 4466 | % Dot and dash lengths have two parts: a constant amount plus a line width
|
---|
| 4467 | % variable amount. The constant amount comes after dpi2point, and the
|
---|
| 4468 | @@ -134,7 +137,12 @@
|
---|
| 4469 | '/GR { [0 dpi2point mul 4 dpi2point mul] 0 setdash 1 setlinecap } bdef'}; % Grid lines - dot spacing remains constant
|
---|
| 4470 |
|
---|
| 4471 | % Construct the output
|
---|
| 4472 | -fstrm = [fstrm(1:first_sec) second_sec sprintf('%s\r', new_style{:}) remaining];
|
---|
| 4473 | +% This is the original (memory-intensive) code:
|
---|
| 4474 | +%first_sec = strfind(fstrm, '% line types:'); % Isolate line style definition section
|
---|
| 4475 | +%[second_sec, remaining] = strtok(fstrm(first_sec+1:end), '/');
|
---|
| 4476 | +%[remaining, remaining] = strtok(remaining, '%');
|
---|
| 4477 | +%fstrm = [fstrm(1:first_sec) second_sec sprintf('%s\r', new_style{:}) remaining];
|
---|
| 4478 | +fstrm = regexprep(fstrm,'(% line types:.+?)/.+?%',['$1',sprintf('%s\r',new_style{:}),'%']);
|
---|
| 4479 |
|
---|
| 4480 | % Write the output file
|
---|
| 4481 | if nargout == 0 || nargin > 1
|
---|
| 4482 | Index: ../trunk-jpl/externalpackages/export_fig/isolate_axes.m
|
---|
| 4483 | ===================================================================
|
---|
| 4484 | --- ../trunk-jpl/externalpackages/export_fig/isolate_axes.m (revision 21314)
|
---|
| 4485 | +++ ../trunk-jpl/externalpackages/export_fig/isolate_axes.m (revision 21315)
|
---|
| 4486 | @@ -1,3 +1,4 @@
|
---|
| 4487 | +function fh = isolate_axes(ah, vis)
|
---|
| 4488 | %ISOLATE_AXES Isolate the specified axes in a figure on their own
|
---|
| 4489 | %
|
---|
| 4490 | % Examples:
|
---|
| 4491 | @@ -21,99 +22,109 @@
|
---|
| 4492 | % Copyright (C) Oliver Woodford 2011-2013
|
---|
| 4493 |
|
---|
| 4494 | % Thank you to Rosella Blatt for reporting a bug to do with axes in GUIs
|
---|
| 4495 | -% 16/3/2012 Moved copyfig to its own function. Thanks to Bob Fratantonio
|
---|
| 4496 | -% for pointing out that the function is also used in export_fig.m.
|
---|
| 4497 | -% 12/12/12 - Add support for isolating uipanels. Thanks to michael for
|
---|
| 4498 | -% suggesting it.
|
---|
| 4499 | -% 08/10/13 - Bug fix to allchildren suggested by Will Grant (many thanks!).
|
---|
| 4500 | -% 05/12/13 - Bug fix to axes having different units. Thanks to Remington
|
---|
| 4501 | -% Reid for reporting the issue.
|
---|
| 4502 | +% 16/03/12: Moved copyfig to its own function. Thanks to Bob Fratantonio
|
---|
| 4503 | +% for pointing out that the function is also used in export_fig.m
|
---|
| 4504 | +% 12/12/12: Add support for isolating uipanels. Thanks to michael for suggesting it
|
---|
| 4505 | +% 08/10/13: Bug fix to allchildren suggested by Will Grant (many thanks!)
|
---|
| 4506 | +% 05/12/13: Bug fix to axes having different units. Thanks to Remington Reid for reporting
|
---|
| 4507 | +% 21/04/15: Bug fix for exporting uipanels with legend/colorbar on HG1 (reported by Alvaro
|
---|
| 4508 | +% on FEX page as a comment on 24-Apr-2014); standardized indentation & help section
|
---|
| 4509 | +% 22/04/15: Bug fix: legends and colorbars were not exported when exporting axes handle in HG2
|
---|
| 4510 |
|
---|
| 4511 | -function fh = isolate_axes(ah, vis)
|
---|
| 4512 | -% Make sure we have an array of handles
|
---|
| 4513 | -if ~all(ishandle(ah))
|
---|
| 4514 | - error('ah must be an array of handles');
|
---|
| 4515 | -end
|
---|
| 4516 | -% Check that the handles are all for axes or uipanels, and are all in the same figure
|
---|
| 4517 | -fh = ancestor(ah(1), 'figure');
|
---|
| 4518 | -nAx = numel(ah);
|
---|
| 4519 | -for a = 1:nAx
|
---|
| 4520 | - if ~ismember(get(ah(a), 'Type'), {'axes', 'uipanel'})
|
---|
| 4521 | - error('All handles must be axes or uipanel handles.');
|
---|
| 4522 | + % Make sure we have an array of handles
|
---|
| 4523 | + if ~all(ishandle(ah))
|
---|
| 4524 | + error('ah must be an array of handles');
|
---|
| 4525 | end
|
---|
| 4526 | - if ~isequal(ancestor(ah(a), 'figure'), fh)
|
---|
| 4527 | - error('Axes must all come from the same figure.');
|
---|
| 4528 | + % Check that the handles are all for axes or uipanels, and are all in the same figure
|
---|
| 4529 | + fh = ancestor(ah(1), 'figure');
|
---|
| 4530 | + nAx = numel(ah);
|
---|
| 4531 | + for a = 1:nAx
|
---|
| 4532 | + if ~ismember(get(ah(a), 'Type'), {'axes', 'uipanel'})
|
---|
| 4533 | + error('All handles must be axes or uipanel handles.');
|
---|
| 4534 | + end
|
---|
| 4535 | + if ~isequal(ancestor(ah(a), 'figure'), fh)
|
---|
| 4536 | + error('Axes must all come from the same figure.');
|
---|
| 4537 | + end
|
---|
| 4538 | end
|
---|
| 4539 | -end
|
---|
| 4540 | -% Tag the objects so we can find them in the copy
|
---|
| 4541 | -old_tag = get(ah, 'Tag');
|
---|
| 4542 | -if nAx == 1
|
---|
| 4543 | - old_tag = {old_tag};
|
---|
| 4544 | -end
|
---|
| 4545 | -set(ah, 'Tag', 'ObjectToCopy');
|
---|
| 4546 | -% Create a new figure exactly the same as the old one
|
---|
| 4547 | -fh = copyfig(fh); %copyobj(fh, 0);
|
---|
| 4548 | -if nargin < 2 || ~vis
|
---|
| 4549 | - set(fh, 'Visible', 'off');
|
---|
| 4550 | -end
|
---|
| 4551 | -% Reset the object tags
|
---|
| 4552 | -for a = 1:nAx
|
---|
| 4553 | - set(ah(a), 'Tag', old_tag{a});
|
---|
| 4554 | -end
|
---|
| 4555 | -% Find the objects to save
|
---|
| 4556 | -ah = findall(fh, 'Tag', 'ObjectToCopy');
|
---|
| 4557 | -if numel(ah) ~= nAx
|
---|
| 4558 | - close(fh);
|
---|
| 4559 | - error('Incorrect number of objects found.');
|
---|
| 4560 | -end
|
---|
| 4561 | -% Set the axes tags to what they should be
|
---|
| 4562 | -for a = 1:nAx
|
---|
| 4563 | - set(ah(a), 'Tag', old_tag{a});
|
---|
| 4564 | -end
|
---|
| 4565 | -% Keep any legends and colorbars which overlap the subplots
|
---|
| 4566 | -lh = findall(fh, 'Type', 'axes', '-and', {'Tag', 'legend', '-or', 'Tag', 'Colorbar'});
|
---|
| 4567 | -nLeg = numel(lh);
|
---|
| 4568 | -if nLeg > 0
|
---|
| 4569 | - set([ah(:); lh(:)], 'Units', 'normalized');
|
---|
| 4570 | - ax_pos = get(ah, 'OuterPosition');
|
---|
| 4571 | - if nAx > 1
|
---|
| 4572 | - ax_pos = cell2mat(ax_pos(:));
|
---|
| 4573 | + % Tag the objects so we can find them in the copy
|
---|
| 4574 | + old_tag = get(ah, 'Tag');
|
---|
| 4575 | + if nAx == 1
|
---|
| 4576 | + old_tag = {old_tag};
|
---|
| 4577 | end
|
---|
| 4578 | - ax_pos(:,3:4) = ax_pos(:,3:4) + ax_pos(:,1:2);
|
---|
| 4579 | - leg_pos = get(lh, 'OuterPosition');
|
---|
| 4580 | - if nLeg > 1;
|
---|
| 4581 | - leg_pos = cell2mat(leg_pos);
|
---|
| 4582 | + set(ah, 'Tag', 'ObjectToCopy');
|
---|
| 4583 | + % Create a new figure exactly the same as the old one
|
---|
| 4584 | + fh = copyfig(fh); %copyobj(fh, 0);
|
---|
| 4585 | + if nargin < 2 || ~vis
|
---|
| 4586 | + set(fh, 'Visible', 'off');
|
---|
| 4587 | end
|
---|
| 4588 | - leg_pos(:,3:4) = leg_pos(:,3:4) + leg_pos(:,1:2);
|
---|
| 4589 | - ax_pos = shiftdim(ax_pos, -1);
|
---|
| 4590 | - % Overlap test
|
---|
| 4591 | - M = bsxfun(@lt, leg_pos(:,1), ax_pos(:,:,3)) & ...
|
---|
| 4592 | - bsxfun(@lt, leg_pos(:,2), ax_pos(:,:,4)) & ...
|
---|
| 4593 | - bsxfun(@gt, leg_pos(:,3), ax_pos(:,:,1)) & ...
|
---|
| 4594 | - bsxfun(@gt, leg_pos(:,4), ax_pos(:,:,2));
|
---|
| 4595 | - ah = [ah; lh(any(M, 2))];
|
---|
| 4596 | + % Reset the object tags
|
---|
| 4597 | + for a = 1:nAx
|
---|
| 4598 | + set(ah(a), 'Tag', old_tag{a});
|
---|
| 4599 | + end
|
---|
| 4600 | + % Find the objects to save
|
---|
| 4601 | + ah = findall(fh, 'Tag', 'ObjectToCopy');
|
---|
| 4602 | + if numel(ah) ~= nAx
|
---|
| 4603 | + close(fh);
|
---|
| 4604 | + error('Incorrect number of objects found.');
|
---|
| 4605 | + end
|
---|
| 4606 | + % Set the axes tags to what they should be
|
---|
| 4607 | + for a = 1:nAx
|
---|
| 4608 | + set(ah(a), 'Tag', old_tag{a});
|
---|
| 4609 | + end
|
---|
| 4610 | + % Keep any legends and colorbars which overlap the subplots
|
---|
| 4611 | + % Note: in HG1 these are axes objects; in HG2 they are separate objects, therefore we
|
---|
| 4612 | + % don't test for the type, only the tag (hopefully nobody but Matlab uses them!)
|
---|
| 4613 | + lh = findall(fh, 'Tag', 'legend', '-or', 'Tag', 'Colorbar');
|
---|
| 4614 | + nLeg = numel(lh);
|
---|
| 4615 | + if nLeg > 0
|
---|
| 4616 | + set([ah(:); lh(:)], 'Units', 'normalized');
|
---|
| 4617 | + try
|
---|
| 4618 | + ax_pos = get(ah, 'OuterPosition'); % axes and figures have the OuterPosition property
|
---|
| 4619 | + catch
|
---|
| 4620 | + ax_pos = get(ah, 'Position'); % uipanels only have Position, not OuterPosition
|
---|
| 4621 | + end
|
---|
| 4622 | + if nAx > 1
|
---|
| 4623 | + ax_pos = cell2mat(ax_pos(:));
|
---|
| 4624 | + end
|
---|
| 4625 | + ax_pos(:,3:4) = ax_pos(:,3:4) + ax_pos(:,1:2);
|
---|
| 4626 | + try
|
---|
| 4627 | + leg_pos = get(lh, 'OuterPosition');
|
---|
| 4628 | + catch
|
---|
| 4629 | + leg_pos = get(lh, 'Position'); % No OuterPosition in HG2, only in HG1
|
---|
| 4630 | + end
|
---|
| 4631 | + if nLeg > 1;
|
---|
| 4632 | + leg_pos = cell2mat(leg_pos);
|
---|
| 4633 | + end
|
---|
| 4634 | + leg_pos(:,3:4) = leg_pos(:,3:4) + leg_pos(:,1:2);
|
---|
| 4635 | + ax_pos = shiftdim(ax_pos, -1);
|
---|
| 4636 | + % Overlap test
|
---|
| 4637 | + M = bsxfun(@lt, leg_pos(:,1), ax_pos(:,:,3)) & ...
|
---|
| 4638 | + bsxfun(@lt, leg_pos(:,2), ax_pos(:,:,4)) & ...
|
---|
| 4639 | + bsxfun(@gt, leg_pos(:,3), ax_pos(:,:,1)) & ...
|
---|
| 4640 | + bsxfun(@gt, leg_pos(:,4), ax_pos(:,:,2));
|
---|
| 4641 | + ah = [ah; lh(any(M, 2))];
|
---|
| 4642 | + end
|
---|
| 4643 | + % Get all the objects in the figure
|
---|
| 4644 | + axs = findall(fh);
|
---|
| 4645 | + % Delete everything except for the input objects and associated items
|
---|
| 4646 | + delete(axs(~ismember(axs, [ah; allchildren(ah); allancestors(ah)])));
|
---|
| 4647 | end
|
---|
| 4648 | -% Get all the objects in the figure
|
---|
| 4649 | -axs = findall(fh);
|
---|
| 4650 | -% Delete everything except for the input objects and associated items
|
---|
| 4651 | -delete(axs(~ismember(axs, [ah; allchildren(ah); allancestors(ah)])));
|
---|
| 4652 | -end
|
---|
| 4653 |
|
---|
| 4654 | function ah = allchildren(ah)
|
---|
| 4655 | -ah = findall(ah);
|
---|
| 4656 | -if iscell(ah)
|
---|
| 4657 | - ah = cell2mat(ah);
|
---|
| 4658 | + ah = findall(ah);
|
---|
| 4659 | + if iscell(ah)
|
---|
| 4660 | + ah = cell2mat(ah);
|
---|
| 4661 | + end
|
---|
| 4662 | + ah = ah(:);
|
---|
| 4663 | end
|
---|
| 4664 | -ah = ah(:);
|
---|
| 4665 | -end
|
---|
| 4666 |
|
---|
| 4667 | function ph = allancestors(ah)
|
---|
| 4668 | -ph = [];
|
---|
| 4669 | -for a = 1:numel(ah)
|
---|
| 4670 | - h = get(ah(a), 'parent');
|
---|
| 4671 | - while h ~= 0
|
---|
| 4672 | - ph = [ph; h];
|
---|
| 4673 | - h = get(h, 'parent');
|
---|
| 4674 | + ph = [];
|
---|
| 4675 | + for a = 1:numel(ah)
|
---|
| 4676 | + h = get(ah(a), 'parent');
|
---|
| 4677 | + while h ~= 0
|
---|
| 4678 | + ph = [ph; h];
|
---|
| 4679 | + h = get(h, 'parent');
|
---|
| 4680 | + end
|
---|
| 4681 | end
|
---|
| 4682 | end
|
---|
| 4683 | -end
|
---|