comparison toolboxes/FullBNT-1.0.7/KPMtools/exportfig.m @ 0:e9a9cd732c1e tip

first hg version after svn
author wolffd
date Tue, 10 Feb 2015 15:05:51 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:e9a9cd732c1e
1 function varargout = exportfig(varargin)
2 %EXPORTFIG Export a figure.
3 % EXPORTFIG(H, FILENAME) writes the figure H to FILENAME. H is
4 % a figure handle and FILENAME is a string that specifies the
5 % name of the output file.
6 %
7 % EXPORTFIG(H, FILENAME, OPTIONS) writes the figure H to FILENAME
8 % with options initially specified by the structure OPTIONS. The
9 % field names of OPTIONS must be legal parameters listed below
10 % and the field values must be legal values for the corresponding
11 % parameter. Default options can be set in releases prior to R12
12 % by storing the OPTIONS structure in the root object's appdata
13 % with the command
14 % setappdata(0,'exportfigdefaults', OPTIONS)
15 % and for releases after R12 by setting the preference with the
16 % command
17 % setpref('exportfig', 'defaults', OPTIONS)
18 %
19 % EXPORTFIG(...,PARAM1,VAL1,PARAM2,VAL2,...) specifies
20 % parameters that control various characteristics of the output
21 % file. Any parameter value can be the string 'auto' which means
22 % the parameter uses the default factory behavior, overriding
23 % any other default for the parameter.
24 %
25 % Format Paramter:
26 % 'Format' a string
27 % specifies the output format. Defaults to 'eps'. For a
28 % list of export formats type 'help print'.
29 % 'Preview' one of the strings 'none', 'tiff'
30 % specifies a preview for EPS files. Defaults to 'none'.
31 %
32 % Size Parameters:
33 % 'Width' a positive scalar
34 % specifies the width in the figure's PaperUnits
35 % 'Height' a positive scalar
36 % specifies the height in the figure's PaperUnits
37 % 'Bounds' one of the strings 'tight', 'loose'
38 % specifies a tight or loose bounding box. Defaults to 'tight'.
39 % 'Reference' an axes handle or a string
40 % specifies that the width and height parameters
41 % are relative to the given axes. If a string is
42 % specified then it must evaluate to an axes handle.
43 %
44 % Specifying only one dimension sets the other dimension
45 % so that the exported aspect ratio is the same as the
46 % figure's or reference axes' current aspect ratio.
47 % If neither dimension is specified the size defaults to
48 % the width and height from the figure's or reference
49 % axes' size. Tight bounding boxes are only computed for
50 % 2-D views and in that case the computed bounds enclose all
51 % text objects.
52 %
53 % Rendering Parameters:
54 % 'Color' one of the strings 'bw', 'gray', 'cmyk'
55 % 'bw' specifies that lines and text are exported in
56 % black and all other objects in grayscale
57 % 'gray' specifies that all objects are exported in grayscale
58 % 'rgb' specifies that all objects are exported in color
59 % using the RGB color space
60 % 'cmyk' specifies that all objects are exported in color
61 % using the CMYK color space
62 % 'Renderer' one of 'painters', 'zbuffer', 'opengl'
63 % specifies the renderer to use
64 % 'Resolution' a positive scalar
65 % specifies the resolution in dots-per-inch.
66 % 'LockAxes' one of 0 or 1
67 % specifies that all axes limits and ticks should be fixed
68 % while exporting.
69 %
70 % The default color setting is 'bw'.
71 %
72 % Font Parameters:
73 % 'FontMode' one of the strings 'scaled', 'fixed'
74 % 'FontSize' a positive scalar
75 % in 'scaled' mode multiplies with the font size of each
76 % text object to obtain the exported font size
77 % in 'fixed' mode specifies the font size of all text
78 % objects in points
79 % 'DefaultFixedFontSize' a positive scalar
80 % in 'fixed' mode specified the default font size in
81 % points
82 % 'FontSizeMin' a positive scalar
83 % specifies the minimum font size allowed after scaling
84 % 'FontSizeMax' a positive scalar
85 % specifies the maximum font size allowed after scaling
86 % 'FontEncoding' one of the strings 'latin1', 'adobe'
87 % specifies the character encoding of the font
88 % 'SeparateText' one of 0 or 1
89 % specifies that the text objects are stored in separate
90 % file as EPS with the base filename having '_t' appended.
91 %
92 % If FontMode is 'scaled' but FontSize is not specified then a
93 % scaling factor is computed from the ratio of the size of the
94 % exported figure to the size of the actual figure.
95 %
96 % The default 'FontMode' setting is 'scaled'.
97 %
98 % Line Width Parameters:
99 % 'LineMode' one of the strings 'scaled', 'fixed'
100 % 'LineWidth' a positive scalar
101 % 'DefaultFixedLineWidth' a positive scalar
102 % 'LineWidthMin' a positive scalar
103 % specifies the minimum line width allowed after scaling
104 % 'LineWidthMax' a positive scalar
105 % specifies the maximum line width allowed after scaling
106 % The semantics of 'Line' parameters are exactly the
107 % same as the corresponding 'Font' parameters, except that
108 % they apply to line widths instead of font sizes.
109 %
110 % Style Map Parameter:
111 % 'LineStyleMap' one of [], 'bw', or a function name or handle
112 % specifies how to map line colors to styles. An empty
113 % style map means styles are not changed. The style map
114 % 'bw' is a built-in mapping that maps lines with the same
115 % color to the same style and otherwise cycles through the
116 % available styles. A user-specified map is a function
117 % that takes as input a cell array of line objects and
118 % outputs a cell array of line style strings. The default
119 % map is [].
120 %
121 % Examples:
122 % exportfig(gcf,'fig1.eps','height',3);
123 % Exports the current figure to the file named 'fig1.eps' with
124 % a height of 3 inches (assuming the figure's PaperUnits is
125 % inches) and an aspect ratio the same as the figure's aspect
126 % ratio on screen.
127 %
128 % opts = struct('FontMode','fixed','FontSize',10,'height',3);
129 % exportfig(gcf, 'fig2.eps', opts, 'height', 5);
130 % Exports the current figure to 'fig2.eps' with all
131 % text in 10 point fonts and with height 5 inches.
132 %
133 % See also PREVIEWFIG, APPLYTOFIG, RESTOREFIG, PRINT.
134
135 % Copyright 2000 Ben Hinkle
136 % Email bug reports and comments to bhinkle@mathworks.com
137
138 if (nargin < 2)
139 error('Too few input arguments');
140 end
141
142 % exportfig(H, filename, [options,] ...)
143 H = varargin{1};
144 if ~LocalIsHG(H,'figure')
145 error('First argument must be a handle to a figure.');
146 end
147 filename = varargin{2};
148 if ~ischar(filename)
149 error('Second argument must be a string.');
150 end
151 paramPairs = {varargin{3:end}};
152 if nargin > 2
153 if isstruct(paramPairs{1})
154 pcell = LocalToCell(paramPairs{1});
155 paramPairs = {pcell{:}, paramPairs{2:end}};
156 end
157 end
158 verstr = version;
159 majorver = str2num(verstr(1));
160 defaults = [];
161 if majorver > 5
162 if ispref('exportfig','defaults')
163 defaults = getpref('exportfig','defaults');
164 end
165 elseif exist('getappdata')
166 defaults = getappdata(0,'exportfigdefaults');
167 end
168 if ~isempty(defaults)
169 dcell = LocalToCell(defaults);
170 paramPairs = {dcell{:}, paramPairs{:}};
171 end
172
173 % Do some validity checking on param-value pairs
174 if (rem(length(paramPairs),2) ~= 0)
175 error(['Invalid input syntax. Optional parameters and values' ...
176 ' must be in pairs.']);
177 end
178
179 auto.format = 'eps';
180 auto.preview = 'none';
181 auto.width = -1;
182 auto.height = -1;
183 auto.color = 'bw';
184 auto.defaultfontsize=10;
185 auto.fontsize = -1;
186 auto.fontmode='scaled';
187 auto.fontmin = 8;
188 auto.fontmax = 60;
189 auto.defaultlinewidth = 1.0;
190 auto.linewidth = -1;
191 auto.linemode=[];
192 auto.linemin = 0.5;
193 auto.linemax = 100;
194 auto.fontencoding = 'latin1';
195 auto.renderer = [];
196 auto.resolution = [];
197 auto.stylemap = [];
198 auto.applystyle = 0;
199 auto.refobj = -1;
200 auto.bounds = 'tight';
201 explicitbounds = 0;
202 auto.lockaxes = 1;
203 auto.separatetext = 0;
204 opts = auto;
205
206 % Process param-value pairs
207 args = {};
208 for k = 1:2:length(paramPairs)
209 param = lower(paramPairs{k});
210 if ~ischar(param)
211 error('Optional parameter names must be strings');
212 end
213 value = paramPairs{k+1};
214
215 switch (param)
216 case 'format'
217 opts.format = LocalCheckAuto(lower(value),auto.format);
218 if strcmp(opts.format,'preview')
219 error(['Format ''preview'' no longer supported. Use PREVIEWFIG' ...
220 ' instead.']);
221 end
222 case 'preview'
223 opts.preview = LocalCheckAuto(lower(value),auto.preview);
224 if ~strcmp(opts.preview,{'none','tiff'})
225 error('Preview must be ''none'' or ''tiff''.');
226 end
227 case 'width'
228 opts.width = LocalToNum(value, auto.width);
229 if ~ischar(value) | ~strcmp(value,'auto')
230 if ~LocalIsPositiveScalar(opts.width)
231 error('Width must be a numeric scalar > 0');
232 end
233 end
234 case 'height'
235 opts.height = LocalToNum(value, auto.height);
236 if ~ischar(value) | ~strcmp(value,'auto')
237 if(~LocalIsPositiveScalar(opts.height))
238 error('Height must be a numeric scalar > 0');
239 end
240 end
241 case 'color'
242 opts.color = LocalCheckAuto(lower(value),auto.color);
243 if ~strcmp(opts.color,{'bw','gray','rgb','cmyk'})
244 error('Color must be ''bw'', ''gray'',''rgb'' or ''cmyk''.');
245 end
246 case 'fontmode'
247 opts.fontmode = LocalCheckAuto(lower(value),auto.fontmode);
248 if ~strcmp(opts.fontmode,{'scaled','fixed'})
249 error('FontMode must be ''scaled'' or ''fixed''.');
250 end
251 case 'fontsize'
252 opts.fontsize = LocalToNum(value,auto.fontsize);
253 if ~ischar(value) | ~strcmp(value,'auto')
254 if ~LocalIsPositiveScalar(opts.fontsize)
255 error('FontSize must be a numeric scalar > 0');
256 end
257 end
258 case 'defaultfixedfontsize'
259 opts.defaultfontsize = LocalToNum(value,auto.defaultfontsize);
260 if ~ischar(value) | ~strcmp(value,'auto')
261 if ~LocalIsPositiveScalar(opts.defaultfontsize)
262 error('DefaultFixedFontSize must be a numeric scalar > 0');
263 end
264 end
265 case 'fontsizemin'
266 opts.fontmin = LocalToNum(value,auto.fontmin);
267 if ~ischar(value) | ~strcmp(value,'auto')
268 if ~LocalIsPositiveScalar(opts.fontmin)
269 error('FontSizeMin must be a numeric scalar > 0');
270 end
271 end
272 case 'fontsizemax'
273 opts.fontmax = LocalToNum(value,auto.fontmax);
274 if ~ischar(value) | ~strcmp(value,'auto')
275 if ~LocalIsPositiveScalar(opts.fontmax)
276 error('FontSizeMax must be a numeric scalar > 0');
277 end
278 end
279 case 'fontencoding'
280 opts.fontencoding = LocalCheckAuto(lower(value),auto.fontencoding);
281 if ~strcmp(opts.fontencoding,{'latin1','adobe'})
282 error('FontEncoding must be ''latin1'' or ''adobe''.');
283 end
284 case 'linemode'
285 opts.linemode = LocalCheckAuto(lower(value),auto.linemode);
286 if ~strcmp(opts.linemode,{'scaled','fixed'})
287 error('LineMode must be ''scaled'' or ''fixed''.');
288 end
289 case 'linewidth'
290 opts.linewidth = LocalToNum(value,auto.linewidth);
291 if ~ischar(value) | ~strcmp(value,'auto')
292 if ~LocalIsPositiveScalar(opts.linewidth)
293 error('LineWidth must be a numeric scalar > 0');
294 end
295 end
296 case 'defaultfixedlinewidth'
297 opts.defaultlinewidth = LocalToNum(value,auto.defaultlinewidth);
298 if ~ischar(value) | ~strcmp(value,'auto')
299 if ~LocalIsPositiveScalar(opts.defaultlinewidth)
300 error(['DefaultFixedLineWidth must be a numeric scalar >' ...
301 ' 0']);
302 end
303 end
304 case 'linewidthmin'
305 opts.linemin = LocalToNum(value,auto.linemin);
306 if ~ischar(value) | ~strcmp(value,'auto')
307 if ~LocalIsPositiveScalar(opts.linemin)
308 error('LineWidthMin must be a numeric scalar > 0');
309 end
310 end
311 case 'linewidthmax'
312 opts.linemax = LocalToNum(value,auto.linemax);
313 if ~ischar(value) | ~strcmp(value,'auto')
314 if ~LocalIsPositiveScalar(opts.linemax)
315 error('LineWidthMax must be a numeric scalar > 0');
316 end
317 end
318 case 'linestylemap'
319 opts.stylemap = LocalCheckAuto(value,auto.stylemap);
320 case 'renderer'
321 opts.renderer = LocalCheckAuto(lower(value),auto.renderer);
322 if ~ischar(value) | ~strcmp(value,'auto')
323 if ~strcmp(opts.renderer,{'painters','zbuffer','opengl'})
324 error(['Renderer must be ''painters'', ''zbuffer'' or' ...
325 ' ''opengl''.']);
326 end
327 end
328 case 'resolution'
329 opts.resolution = LocalToNum(value,auto.resolution);
330 if ~ischar(value) | ~strcmp(value,'auto')
331 if ~(isnumeric(value) & (prod(size(value)) == 1) & (value >= 0));
332 error('Resolution must be a numeric scalar >= 0');
333 end
334 end
335 case 'applystyle' % means to apply the options and not export
336 opts.applystyle = 1;
337 case 'reference'
338 if ischar(value)
339 if strcmp(value,'auto')
340 opts.refobj = auto.refobj;
341 else
342 opts.refobj = eval(value);
343 end
344 else
345 opts.refobj = value;
346 end
347 if ~LocalIsHG(opts.refobj,'axes')
348 error('Reference object must evaluate to an axes handle.');
349 end
350 case 'bounds'
351 opts.bounds = LocalCheckAuto(lower(value),auto.bounds);
352 explicitbounds = 1;
353 if ~strcmp(opts.bounds,{'tight','loose'})
354 error('Bounds must be ''tight'' or ''loose''.');
355 end
356 case 'lockaxes'
357 opts.lockaxes = LocalToNum(value,auto.lockaxes);
358 case 'separatetext'
359 opts.separatetext = LocalToNum(value,auto.separatetext);
360 otherwise
361 error(['Unrecognized option ' param '.']);
362 end
363 end
364
365 % make sure figure is up-to-date
366 drawnow;
367
368 allLines = findall(H, 'type', 'line');
369 allText = findall(H, 'type', 'text');
370 allAxes = findall(H, 'type', 'axes');
371 allImages = findall(H, 'type', 'image');
372 allLights = findall(H, 'type', 'light');
373 allPatch = findall(H, 'type', 'patch');
374 allSurf = findall(H, 'type', 'surface');
375 allRect = findall(H, 'type', 'rectangle');
376 allFont = [allText; allAxes];
377 allColor = [allLines; allText; allAxes; allLights];
378 allMarker = [allLines; allPatch; allSurf];
379 allEdge = [allPatch; allSurf];
380 allCData = [allImages; allPatch; allSurf];
381
382 old.objs = {};
383 old.prop = {};
384 old.values = {};
385
386 % Process format
387 if strncmp(opts.format,'eps',3) & ~strcmp(opts.preview,'none')
388 args = {args{:}, ['-' opts.preview]};
389 end
390
391 hadError = 0;
392 oldwarn = warning;
393 try
394
395 % lock axes limits, ticks and labels if requested
396 if opts.lockaxes
397 old = LocalManualAxesMode(old, allAxes, 'TickMode');
398 old = LocalManualAxesMode(old, allAxes, 'TickLabelMode');
399 old = LocalManualAxesMode(old, allAxes, 'LimMode');
400 end
401
402 % Process size parameters
403 figurePaperUnits = get(H, 'PaperUnits');
404 oldFigureUnits = get(H, 'Units');
405 oldFigPos = get(H,'Position');
406 set(H, 'Units', figurePaperUnits);
407 figPos = get(H,'Position');
408 refsize = figPos(3:4);
409 if opts.refobj ~= -1
410 oldUnits = get(opts.refobj, 'Units');
411 set(opts.refobj, 'Units', figurePaperUnits);
412 r = get(opts.refobj, 'Position');
413 refsize = r(3:4);
414 set(opts.refobj, 'Units', oldUnits);
415 end
416 aspectRatio = refsize(1)/refsize(2);
417 if (opts.width == -1) & (opts.height == -1)
418 opts.width = refsize(1);
419 opts.height = refsize(2);
420 elseif (opts.width == -1)
421 opts.width = opts.height * aspectRatio;
422 elseif (opts.height == -1)
423 opts.height = opts.width / aspectRatio;
424 end
425 wscale = opts.width/refsize(1);
426 hscale = opts.height/refsize(2);
427 sizescale = min(wscale,hscale);
428 old = LocalPushOldData(old,H,'PaperPositionMode', ...
429 get(H,'PaperPositionMode'));
430 set(H, 'PaperPositionMode', 'auto');
431 newPos = [figPos(1) figPos(2)+figPos(4)*(1-hscale) ...
432 wscale*figPos(3) hscale*figPos(4)];
433 set(H, 'Position', newPos);
434 set(H, 'Units', oldFigureUnits);
435
436 % process line-style map
437 if ~isempty(opts.stylemap) & ~isempty(allLines)
438 oldlstyle = LocalGetAsCell(allLines,'LineStyle');
439 old = LocalPushOldData(old, allLines, {'LineStyle'}, ...
440 oldlstyle);
441 newlstyle = oldlstyle;
442 if ischar(opts.stylemap) & strcmpi(opts.stylemap,'bw')
443 newlstyle = LocalMapColorToStyle(allLines);
444 else
445 try
446 newlstyle = feval(opts.stylemap,allLines);
447 catch
448 warning(['Skipping stylemap. ' lasterr]);
449 end
450 end
451 set(allLines,{'LineStyle'},newlstyle);
452 end
453
454 % Process rendering parameters
455 switch (opts.color)
456 case {'bw', 'gray'}
457 if ~strcmp(opts.color,'bw') & strncmp(opts.format,'eps',3)
458 opts.format = [opts.format 'c'];
459 end
460 args = {args{:}, ['-d' opts.format]};
461
462 %compute and set gray colormap
463 oldcmap = get(H,'Colormap');
464 newgrays = 0.30*oldcmap(:,1) + 0.59*oldcmap(:,2) + 0.11*oldcmap(:,3);
465 newcmap = [newgrays newgrays newgrays];
466 old = LocalPushOldData(old, H, 'Colormap', oldcmap);
467 set(H, 'Colormap', newcmap);
468
469 %compute and set ColorSpec and CData properties
470 old = LocalUpdateColors(allColor, 'color', old);
471 old = LocalUpdateColors(allAxes, 'xcolor', old);
472 old = LocalUpdateColors(allAxes, 'ycolor', old);
473 old = LocalUpdateColors(allAxes, 'zcolor', old);
474 old = LocalUpdateColors(allMarker, 'MarkerEdgeColor', old);
475 old = LocalUpdateColors(allMarker, 'MarkerFaceColor', old);
476 old = LocalUpdateColors(allEdge, 'EdgeColor', old);
477 old = LocalUpdateColors(allEdge, 'FaceColor', old);
478 old = LocalUpdateColors(allCData, 'CData', old);
479
480 case {'rgb','cmyk'}
481 if strncmp(opts.format,'eps',3)
482 opts.format = [opts.format 'c'];
483 args = {args{:}, ['-d' opts.format]};
484 if strcmp(opts.color,'cmyk')
485 args = {args{:}, '-cmyk'};
486 end
487 else
488 args = {args{:}, ['-d' opts.format]};
489 end
490 otherwise
491 error('Invalid Color parameter');
492 end
493 if (~isempty(opts.renderer))
494 args = {args{:}, ['-' opts.renderer]};
495 end
496 if (~isempty(opts.resolution)) | ~strncmp(opts.format,'eps',3)
497 if isempty(opts.resolution)
498 opts.resolution = 0;
499 end
500 args = {args{:}, ['-r' int2str(opts.resolution)]};
501 end
502
503 % Process font parameters
504 if ~isempty(opts.fontmode)
505 oldfonts = LocalGetAsCell(allFont,'FontSize');
506 oldfontunits = LocalGetAsCell(allFont,'FontUnits');
507 set(allFont,'FontUnits','points');
508 switch (opts.fontmode)
509 case 'fixed'
510 if (opts.fontsize == -1)
511 set(allFont,'FontSize',opts.defaultfontsize);
512 else
513 set(allFont,'FontSize',opts.fontsize);
514 end
515 case 'scaled'
516 if (opts.fontsize == -1)
517 scale = sizescale;
518 else
519 scale = opts.fontsize;
520 end
521 newfonts = LocalScale(oldfonts,scale,opts.fontmin,opts.fontmax);
522 set(allFont,{'FontSize'},newfonts);
523 otherwise
524 error('Invalid FontMode parameter');
525 end
526 old = LocalPushOldData(old, allFont, {'FontSize'}, oldfonts);
527 old = LocalPushOldData(old, allFont, {'FontUnits'}, oldfontunits);
528 end
529 if strcmp(opts.fontencoding,'adobe') & strncmp(opts.format,'eps',3)
530 args = {args{:}, '-adobecset'};
531 end
532
533 % Process line parameters
534 if ~isempty(opts.linemode)
535 oldlines = LocalGetAsCell(allMarker,'LineWidth');
536 old = LocalPushOldData(old, allMarker, {'LineWidth'}, oldlines);
537 switch (opts.linemode)
538 case 'fixed'
539 if (opts.linewidth == -1)
540 set(allMarker,'LineWidth',opts.defaultlinewidth);
541 else
542 set(allMarker,'LineWidth',opts.linewidth);
543 end
544 case 'scaled'
545 if (opts.linewidth == -1)
546 scale = sizescale;
547 else
548 scale = opts.linewidth;
549 end
550 newlines = LocalScale(oldlines, scale, opts.linemin, opts.linemax);
551 set(allMarker,{'LineWidth'},newlines);
552 end
553 end
554
555 % adjust figure bounds to surround axes
556 if strcmp(opts.bounds,'tight')
557 if (~strncmp(opts.format,'eps',3) & LocalHas3DPlot(allAxes)) | ...
558 (strncmp(opts.format,'eps',3) & opts.separatetext)
559 if (explicitbounds == 1)
560 warning(['Cannot compute ''tight'' bounds. Using ''loose''' ...
561 ' bounds.']);
562 end
563 opts.bounds = 'loose';
564 end
565 end
566 warning('off');
567 if ~isempty(allAxes)
568 if strncmp(opts.format,'eps',3)
569 if strcmp(opts.bounds,'loose')
570 args = {args{:}, '-loose'};
571 end
572 old = LocalPushOldData(old,H,'Position', oldFigPos);
573 elseif strcmp(opts.bounds,'tight')
574 oldaunits = LocalGetAsCell(allAxes,'Units');
575 oldapos = LocalGetAsCell(allAxes,'Position');
576 oldtunits = LocalGetAsCell(allText,'units');
577 oldtpos = LocalGetAsCell(allText,'Position');
578 set(allAxes,'units','points');
579 apos = LocalGetAsCell(allAxes,'Position');
580 oldunits = get(H,'Units');
581 set(H,'units','points');
582 origfr = get(H,'position');
583 fr = [];
584 for k=1:length(allAxes)
585 if ~strcmpi(get(allAxes(k),'Tag'),'legend')
586 axesR = apos{k};
587 r = LocalAxesTightBoundingBox(axesR, allAxes(k));
588 r(1:2) = r(1:2) + axesR(1:2);
589 fr = LocalUnionRect(fr,r);
590 end
591 end
592 if isempty(fr)
593 fr = [0 0 origfr(3:4)];
594 end
595 for k=1:length(allAxes)
596 ax = allAxes(k);
597 r = apos{k};
598 r(1:2) = r(1:2) - fr(1:2);
599 set(ax,'Position',r);
600 end
601 old = LocalPushOldData(old, allAxes, {'Position'}, oldapos);
602 old = LocalPushOldData(old, allText, {'Position'}, oldtpos);
603 old = LocalPushOldData(old, allText, {'Units'}, oldtunits);
604 old = LocalPushOldData(old, allAxes, {'Units'}, oldaunits);
605 old = LocalPushOldData(old, H, 'Position', oldFigPos);
606 old = LocalPushOldData(old, H, 'Units', oldFigureUnits);
607 r = [origfr(1) origfr(2)+origfr(4)-fr(4) fr(3:4)];
608 set(H,'Position',r);
609 else
610 args = {args{:}, '-loose'};
611 old = LocalPushOldData(old,H,'Position', oldFigPos);
612 end
613 end
614
615 % Process text in a separate file if needed
616 if opts.separatetext & ~opts.applystyle
617 % First hide all text and export
618 oldtvis = LocalGetAsCell(allText,'visible');
619 set(allText,'visible','off');
620 oldax = LocalGetAsCell(allAxes,'XTickLabel',1);
621 olday = LocalGetAsCell(allAxes,'YTickLabel',1);
622 oldaz = LocalGetAsCell(allAxes,'ZTickLabel',1);
623 null = cell(length(oldax),1);
624 [null{:}] = deal([]);
625 set(allAxes,{'XTickLabel'},null);
626 set(allAxes,{'YTickLabel'},null);
627 set(allAxes,{'ZTickLabel'},null);
628 print(H, filename, args{:});
629 set(allText,{'Visible'},oldtvis);
630 set(allAxes,{'XTickLabel'},oldax);
631 set(allAxes,{'YTickLabel'},olday);
632 set(allAxes,{'ZTickLabel'},oldaz);
633 % Now hide all non-text and export as eps in painters
634 [path, name, ext] = fileparts(filename);
635 tfile = fullfile(path,[name '_t.eps']);
636 tfile2 = fullfile(path,[name '_t2.eps']);
637 foundRenderer = 0;
638 for k=1:length(args)
639 if strncmp('-d',args{k},2)
640 args{k} = '-deps';
641 elseif strncmp('-zbuffer',args{k},8) | ...
642 strncmp('-opengl', args{k},6)
643 args{k} = '-painters';
644 foundRenderer = 1;
645 end
646 end
647 if ~foundRenderer
648 args = {args{:}, '-painters'};
649 end
650 allNonText = [allLines; allLights; allPatch; ...
651 allImages; allSurf; allRect];
652 oldvis = LocalGetAsCell(allNonText,'visible');
653 oldc = LocalGetAsCell(allAxes,'color');
654 oldaxg = LocalGetAsCell(allAxes,'XGrid');
655 oldayg = LocalGetAsCell(allAxes,'YGrid');
656 oldazg = LocalGetAsCell(allAxes,'ZGrid');
657 [null{:}] = deal('off');
658 set(allAxes,{'XGrid'},null);
659 set(allAxes,{'YGrid'},null);
660 set(allAxes,{'ZGrid'},null);
661 set(allNonText,'Visible','off');
662 set(allAxes,'Color','none');
663 print(H, tfile2, args{:});
664 set(allNonText,{'Visible'},oldvis);
665 set(allAxes,{'Color'},oldc);
666 set(allAxes,{'XGrid'},oldaxg);
667 set(allAxes,{'YGrid'},oldayg);
668 set(allAxes,{'ZGrid'},oldazg);
669 %hack up the postscript file
670 fid1 = fopen(tfile,'w');
671 fid2 = fopen(tfile2,'r');
672 line = fgetl(fid2);
673 while ischar(line)
674 if strncmp(line,'%%Title',7)
675 fprintf(fid1,'%s\n',['%%Title: ', tfile]);
676 elseif (length(line) < 3)
677 fprintf(fid1,'%s\n',line);
678 elseif ~strcmp(line(end-2:end),' PR') & ...
679 ~strcmp(line(end-1:end),' L')
680 fprintf(fid1,'%s\n',line);
681 end
682 line = fgetl(fid2);
683 end
684 fclose(fid1);
685 fclose(fid2);
686 delete(tfile2);
687
688 elseif ~opts.applystyle
689 drawnow;
690 print(H, filename, args{:});
691 end
692 warning(oldwarn);
693
694 catch
695 warning(oldwarn);
696 hadError = 1;
697 end
698
699 % Restore figure settings
700 if opts.applystyle
701 varargout{1} = old;
702 else
703 for n=1:length(old.objs)
704 if ~iscell(old.values{n}) & iscell(old.prop{n})
705 old.values{n} = {old.values{n}};
706 end
707 set(old.objs{n}, old.prop{n}, old.values{n});
708 end
709 end
710
711 if hadError
712 error(deblank(lasterr));
713 end
714
715 %
716 % Local Functions
717 %
718
719 function outData = LocalPushOldData(inData, objs, prop, values)
720 outData.objs = {objs, inData.objs{:}};
721 outData.prop = {prop, inData.prop{:}};
722 outData.values = {values, inData.values{:}};
723
724 function cellArray = LocalGetAsCell(fig,prop,allowemptycell);
725 cellArray = get(fig,prop);
726 if nargin < 3
727 allowemptycell = 0;
728 end
729 if ~iscell(cellArray) & (allowemptycell | ~isempty(cellArray))
730 cellArray = {cellArray};
731 end
732
733 function newArray = LocalScale(inArray, scale, minv, maxv)
734 n = length(inArray);
735 newArray = cell(n,1);
736 for k=1:n
737 newArray{k} = min(maxv,max(minv,scale*inArray{k}(1)));
738 end
739
740 function gray = LocalMapToGray1(color)
741 gray = color;
742 if ischar(color)
743 switch color(1)
744 case 'y'
745 color = [1 1 0];
746 case 'm'
747 color = [1 0 1];
748 case 'c'
749 color = [0 1 1];
750 case 'r'
751 color = [1 0 0];
752 case 'g'
753 color = [0 1 0];
754 case 'b'
755 color = [0 0 1];
756 case 'w'
757 color = [1 1 1];
758 case 'k'
759 color = [0 0 0];
760 end
761 end
762 if ~ischar(color)
763 gray = 0.30*color(1) + 0.59*color(2) + 0.11*color(3);
764 end
765
766 function newArray = LocalMapToGray(inArray);
767 n = length(inArray);
768 newArray = cell(n,1);
769 for k=1:n
770 color = inArray{k};
771 if ~isempty(color)
772 color = LocalMapToGray1(color);
773 end
774 if isempty(color) | ischar(color)
775 newArray{k} = color;
776 else
777 newArray{k} = [color color color];
778 end
779 end
780
781 function newArray = LocalMapColorToStyle(inArray);
782 inArray = LocalGetAsCell(inArray,'Color');
783 n = length(inArray);
784 newArray = cell(n,1);
785 styles = {'-','--',':','-.'};
786 uniques = [];
787 nstyles = length(styles);
788 for k=1:n
789 gray = LocalMapToGray1(inArray{k});
790 if isempty(gray) | ischar(gray) | gray < .05
791 newArray{k} = '-';
792 else
793 if ~isempty(uniques) & any(gray == uniques)
794 ind = find(gray==uniques);
795 else
796 uniques = [uniques gray];
797 ind = length(uniques);
798 end
799 newArray{k} = styles{mod(ind-1,nstyles)+1};
800 end
801 end
802
803 function newArray = LocalMapCData(inArray);
804 n = length(inArray);
805 newArray = cell(n,1);
806 for k=1:n
807 color = inArray{k};
808 if (ndims(color) == 3) & isa(color,'double')
809 gray = 0.30*color(:,:,1) + 0.59*color(:,:,2) + 0.11*color(:,:,3);
810 color(:,:,1) = gray;
811 color(:,:,2) = gray;
812 color(:,:,3) = gray;
813 end
814 newArray{k} = color;
815 end
816
817 function outData = LocalUpdateColors(inArray, prop, inData)
818 value = LocalGetAsCell(inArray,prop);
819 outData.objs = {inData.objs{:}, inArray};
820 outData.prop = {inData.prop{:}, {prop}};
821 outData.values = {inData.values{:}, value};
822 if (~isempty(value))
823 if strcmp(prop,'CData')
824 value = LocalMapCData(value);
825 else
826 value = LocalMapToGray(value);
827 end
828 set(inArray,{prop},value);
829 end
830
831 function bool = LocalIsPositiveScalar(value)
832 bool = isnumeric(value) & ...
833 prod(size(value)) == 1 & ...
834 value > 0;
835
836 function value = LocalToNum(value,auto)
837 if ischar(value)
838 if strcmp(value,'auto')
839 value = auto;
840 else
841 value = str2num(value);
842 end
843 end
844
845 %convert a struct to {field1,val1,field2,val2,...}
846 function c = LocalToCell(s)
847 f = fieldnames(s);
848 v = struct2cell(s);
849 opts = cell(2,length(f));
850 opts(1,:) = f;
851 opts(2,:) = v;
852 c = {opts{:}};
853
854 function c = LocalIsHG(obj,hgtype)
855 c = 0;
856 if (length(obj) == 1) & ishandle(obj)
857 c = strcmp(get(obj,'type'),hgtype);
858 end
859
860 function c = LocalHas3DPlot(a)
861 zticks = LocalGetAsCell(a,'ZTickLabel');
862 c = 0;
863 for k=1:length(zticks)
864 if ~isempty(zticks{k})
865 c = 1;
866 return;
867 end
868 end
869
870 function r = LocalUnionRect(r1,r2)
871 if isempty(r1)
872 r = r2;
873 elseif isempty(r2)
874 r = r1;
875 elseif max(r2(3:4)) > 0
876 left = min(r1(1),r2(1));
877 bot = min(r1(2),r2(2));
878 right = max(r1(1)+r1(3),r2(1)+r2(3));
879 top = max(r1(2)+r1(4),r2(2)+r2(4));
880 r = [left bot right-left top-bot];
881 else
882 r = r1;
883 end
884
885 function c = LocalLabelsMatchTicks(labs,ticks)
886 c = 0;
887 try
888 t1 = num2str(ticks(1));
889 n = length(ticks);
890 tend = num2str(ticks(n));
891 c = strncmp(labs(1),t1,length(labs(1))) & ...
892 strncmp(labs(n),tend,length(labs(n)));
893 end
894
895 function r = LocalAxesTightBoundingBox(axesR, a)
896 r = [];
897 atext = findall(a,'type','text','visible','on');
898 if ~isempty(atext)
899 set(atext,'units','points');
900 res=LocalGetAsCell(atext,'extent');
901 for n=1:length(atext)
902 r = LocalUnionRect(r,res{n});
903 end
904 end
905 if strcmp(get(a,'visible'),'on')
906 r = LocalUnionRect(r,[0 0 axesR(3:4)]);
907 oldunits = get(a,'fontunits');
908 set(a,'fontunits','points');
909 label = text(0,0,'','parent',a,...
910 'units','points',...
911 'fontsize',get(a,'fontsize'),...
912 'fontname',get(a,'fontname'),...
913 'fontweight',get(a,'fontweight'),...
914 'fontangle',get(a,'fontangle'),...
915 'visible','off');
916 fs = get(a,'fontsize');
917
918 % handle y axis tick labels
919 ry = [0 -fs/2 0 axesR(4)+fs];
920 ylabs = get(a,'yticklabels');
921 yticks = get(a,'ytick');
922 maxw = 0;
923 if ~isempty(ylabs)
924 for n=1:size(ylabs,1)
925 set(label,'string',ylabs(n,:));
926 ext = get(label,'extent');
927 maxw = max(maxw,ext(3));
928 end
929 if ~LocalLabelsMatchTicks(ylabs,yticks) & ...
930 strcmp(get(a,'xaxislocation'),'bottom')
931 ry(4) = ry(4) + 1.5*ext(4);
932 end
933 if strcmp(get(a,'yaxislocation'),'left')
934 ry(1) = -(maxw+5);
935 else
936 ry(1) = axesR(3);
937 end
938 ry(3) = maxw+5;
939 r = LocalUnionRect(r,ry);
940 end
941
942 % handle x axis tick labels
943 rx = [0 0 0 fs+5];
944 xlabs = get(a,'xticklabels');
945 xticks = get(a,'xtick');
946 if ~isempty(xlabs)
947 if strcmp(get(a,'xaxislocation'),'bottom')
948 rx(2) = -(fs+5);
949 if ~LocalLabelsMatchTicks(xlabs,xticks);
950 rx(4) = rx(4) + 2*fs;
951 rx(2) = rx(2) - 2*fs;
952 end
953 else
954 rx(2) = axesR(4);
955 % exponent is still below axes
956 if ~LocalLabelsMatchTicks(xlabs,xticks);
957 rx(4) = rx(4) + axesR(4) + 2*fs;
958 rx(2) = -2*fs;
959 end
960 end
961 set(label,'string',xlabs(1,:));
962 ext1 = get(label,'extent');
963 rx(1) = -ext1(3)/2;
964 set(label,'string',xlabs(size(xlabs,1),:));
965 ext2 = get(label,'extent');
966 rx(3) = axesR(3) + (ext2(3) + ext1(3))/2;
967 r = LocalUnionRect(r,rx);
968 end
969 set(a,'fontunits',oldunits);
970 delete(label);
971 end
972
973 function c = LocalManualAxesMode(old, allAxes, base)
974 xs = ['X' base];
975 ys = ['Y' base];
976 zs = ['Z' base];
977 oldXMode = LocalGetAsCell(allAxes,xs);
978 oldYMode = LocalGetAsCell(allAxes,ys);
979 oldZMode = LocalGetAsCell(allAxes,zs);
980 old = LocalPushOldData(old, allAxes, {xs}, oldXMode);
981 old = LocalPushOldData(old, allAxes, {ys}, oldYMode);
982 old = LocalPushOldData(old, allAxes, {zs}, oldZMode);
983 set(allAxes,xs,'manual');
984 set(allAxes,ys,'manual');
985 set(allAxes,zs,'manual');
986 c = old;
987
988 function val = LocalCheckAuto(val, auto)
989 if ischar(val) & strcmp(val,'auto')
990 val = auto;
991 end