]> Creatis software - CreaPhase.git/blob - octave_packages/m/plot/private/__go_draw_axes__.m
update packages
[CreaPhase.git] / octave_packages / m / plot / private / __go_draw_axes__.m
1 ## Copyright (C) 2005-2012 John W. Eaton
2 ##
3 ## This file is part of Octave.
4 ##
5 ## Octave is free software; you can redistribute it and/or modify it
6 ## under the terms of the GNU General Public License as published by
7 ## the Free Software Foundation; either version 3 of the License, or (at
8 ## your option) any later version.
9 ##
10 ## Octave is distributed in the hope that it will be useful, but
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 ## General Public License for more details.
14 ##
15 ## You should have received a copy of the GNU General Public License
16 ## along with Octave; see the file COPYING.  If not, see
17 ## <http://www.gnu.org/licenses/>.
18
19 ## -*- texinfo -*-
20 ## @deftypefn {Function File} {} __go_draw_axes__ (@var{h}, @var{plot_stream}, @var{enhanced}, @var{mono})
21 ## Undocumented internal function.
22 ## @end deftypefn
23
24 ## Author: jwe
25
26 function __go_draw_axes__ (h, plot_stream, enhanced, mono,
27                            bg_is_set, fg_is_set, hlgnd)
28
29   if (nargin >= 4 && nargin <= 7)
30
31     showhiddenhandles = get (0, "showhiddenhandles");
32     unwind_protect
33       set (0, "showhiddenhandles", "on");
34       axis_obj = __get__ (h);
35     unwind_protect_cleanup
36       set (0, "showhiddenhandles", showhiddenhandles);
37     end_unwind_protect
38
39     parent_figure_obj = get (axis_obj.parent);
40     gnuplot_term = __gnuplot_get_var__ (axis_obj.parent, "GPVAL_TERM");
41
42     ## Set to false for plotyy axes.
43     ymirror = true;
44     if (isfield (axis_obj, "__plotyy_axes__"))
45       if (all (ishandle (axis_obj.__plotyy_axes__)))
46         ymirror = false;
47       else
48         h = axis_obj.__plotyy_axes__;
49         h = h(ishandle (h));
50         h = h(isprop (h, "__ploty_axes__"));
51         rmappdata (h, "__plotyy_axes__")
52       endif
53     endif
54
55     nd = __calc_dimensions__ (h);
56
57     if (strcmp (axis_obj.dataaspectratiomode, "manual")
58         && strcmp (axis_obj.xlimmode, "manual")
59         && strcmp (axis_obj.ylimmode, "manual"))
60       ## All can't be "manual"
61       axis_obj.plotboxaspectratiomode = "auto";
62     endif
63
64     if (strcmp (axis_obj.dataaspectratiomode, "manual")
65         && strcmp (axis_obj.xlimmode, "manual")
66         && strcmp (axis_obj.ylimmode, "manual")
67         && (nd == 2 || all (mod (axis_obj.view, 90) == 0)))
68       ## FIXME - adjust plotboxaspectratio to respect other
69       fpos = get (axis_obj.parent, "position");
70       apos = axis_obj.position;
71     endif
72
73     pos = __actual_axis_position__ (h);
74
75     if (strcmpi (axis_obj.dataaspectratiomode, "manual"))
76       dr = axis_obj.dataaspectratio;
77       if (nd == 2 || all (mod (axis_obj.view, 90) == 0))
78         dr = dr(1) / dr(2);
79       else
80         ## FIXME - need to properly implement 3D
81         dr = mean (dr(1:2)) / dr(3);
82       endif
83     else
84       dr = 1;
85     endif
86
87     if (strcmp (axis_obj.activepositionproperty, "position"))
88       if (__gnuplot_has_feature__ ("screen_coordinates_for_{lrtb}margin"))
89         if (nd == 2 || all (mod (axis_obj.view, 90) == 0))
90           x = [1, 1];
91         else
92           ## 3D plots need to be sized down to fit in the window.
93           x = 1.0 ./ sqrt([2, 2.5]);
94         endif
95         fprintf (plot_stream, "set tmargin screen %.15g;\n",
96                  pos(2)+pos(4)/2+x(2)*pos(4)/2);
97         fprintf (plot_stream, "set bmargin screen %.15g;\n",
98                  pos(2)+pos(4)/2-x(2)*pos(4)/2);
99         fprintf (plot_stream, "set lmargin screen %.15g;\n",
100                  pos(1)+pos(3)/2-x(1)*pos(3)/2);
101         fprintf (plot_stream, "set rmargin screen %.15g;\n",
102                  pos(1)+pos(3)/2+x(1)*pos(3)/2);
103         sz_str = "";
104       else
105         fprintf (plot_stream, "set tmargin 0;\n");
106         fprintf (plot_stream, "set bmargin 0;\n");
107         fprintf (plot_stream, "set lmargin 0;\n");
108         fprintf (plot_stream, "set rmargin 0;\n");
109
110         if (nd == 3 && all (axis_obj.view == [0, 90]))
111           ## FIXME -- Kludge to allow colorbar to be added to a pcolor() plot
112           pos(3:4) = pos(3:4) * 1.4;
113           pos(1:2) = pos(1:2) - pos(3:4) * 0.125;
114         endif
115
116         fprintf (plot_stream, "set origin %.15g, %.15g;\n", pos(1), pos(2));
117
118         if (strcmpi (axis_obj.dataaspectratiomode, "manual"))
119           sz_str = sprintf ("set size ratio %.15g", -dr);
120         else
121           sz_str = "set size noratio";
122         endif
123         sz_str = sprintf ("%s %.15g, %.15g;\n", sz_str, pos(3), pos(4));
124       endif
125     else ## activepositionproperty == outerposition
126       fprintf (plot_stream, "unset tmargin;\n");
127       fprintf (plot_stream, "unset bmargin;\n");
128       fprintf (plot_stream, "unset lmargin;\n");
129       fprintf (plot_stream, "unset rmargin;\n");
130       fprintf (plot_stream, "set origin %g, %g;\n", pos(1:2));
131       sz_str = "";
132       if (strcmpi (axis_obj.dataaspectratiomode, "manual"))
133         sz_str = sprintf ("ratio %g", -dr);
134       else
135         sz_str = "noratio";
136       endif
137       sz_str = sprintf ("set size %s %g, %g;\n", sz_str, pos(3:4));
138     endif
139     if (! isempty (sz_str))
140       fputs (plot_stream, sz_str);
141     endif
142
143     ## Reset all labels, axis-labels, tick-labels, and title
144     ## FIXME - We should have an function to initialize the axis.
145     ##         Presently, this is dispersed in this function.
146     fputs (plot_stream, "unset label;\n");
147     fputs (plot_stream, "unset xtics;\n");
148     fputs (plot_stream, "unset ytics;\n");
149     fputs (plot_stream, "unset ztics;\n");
150     fputs (plot_stream, "unset x2tics;\n");
151     fputs (plot_stream, "unset x2tics;\n");
152
153     if (! isempty (axis_obj.title))
154       t = get (axis_obj.title);
155       if (isempty (t.string))
156         fputs (plot_stream, "unset title;\n");
157       else
158         [tt, f, s] = __maybe_munge_text__ (enhanced, t, "string");
159         fontspec = create_fontspec (f, s, gnuplot_term);
160         fprintf (plot_stream, "set title \"%s\" %s %s;\n",
161                  undo_string_escapes (tt), fontspec,
162                  __do_enhanced_option__ (enhanced, t));
163       endif
164     endif
165
166     if (! isempty (axis_obj.xlabel))
167       t = get (axis_obj.xlabel);
168       angle = t.rotation;
169       colorspec = get_text_colorspec (axis_obj.xcolor, mono);
170       if (isempty (t.string))
171         fprintf (plot_stream, "unset xlabel;\n");
172         fprintf (plot_stream, "unset x2label;\n");
173       else
174         [tt, f, s] = __maybe_munge_text__ (enhanced, t, "string");
175         fontspec = create_fontspec (f, s, gnuplot_term);
176         if (strcmpi (axis_obj.xaxislocation, "top"))
177           fprintf (plot_stream, "set x2label \"%s\" %s %s %s",
178                    undo_string_escapes (tt), colorspec, fontspec,
179                    __do_enhanced_option__ (enhanced, t));
180         else
181           fprintf (plot_stream, "set xlabel \"%s\" %s %s %s",
182                    undo_string_escapes (tt), colorspec, fontspec,
183                    __do_enhanced_option__ (enhanced, t));
184         endif
185         fprintf (plot_stream, " rotate by %f;\n", angle);
186         if (strcmpi (axis_obj.xaxislocation, "top"))
187           fprintf (plot_stream, "unset xlabel;\n");
188         else
189           fprintf (plot_stream, "unset x2label;\n");
190         endif
191       endif
192     endif
193
194     if (! isempty (axis_obj.ylabel))
195       t = get (axis_obj.ylabel);
196       angle = t.rotation;
197       colorspec = get_text_colorspec (axis_obj.ycolor, mono);
198       if (isempty (t.string))
199         fprintf (plot_stream, "unset ylabel;\n");
200         fprintf (plot_stream, "unset y2label;\n");
201       else
202         [tt, f, s] = __maybe_munge_text__ (enhanced, t, "string");
203         fontspec = create_fontspec (f, s, gnuplot_term);
204         if (strcmpi (axis_obj.yaxislocation, "right"))
205           fprintf (plot_stream, "set y2label \"%s\" %s %s %s",
206                    undo_string_escapes (tt), colorspec, fontspec,
207                    __do_enhanced_option__ (enhanced, t));
208         else
209           fprintf (plot_stream, "set ylabel \"%s\" %s %s %s",
210                    undo_string_escapes (tt), colorspec, fontspec,
211                    __do_enhanced_option__ (enhanced, t));
212         endif
213         fprintf (plot_stream, " rotate by %f;\n", angle);
214         if (strcmpi (axis_obj.yaxislocation, "right"))
215           fprintf (plot_stream, "unset ylabel;\n");
216         else
217           fprintf (plot_stream, "unset y2label;\n");
218         endif
219       endif
220     endif
221
222     if (! isempty (axis_obj.zlabel))
223       t = get (axis_obj.zlabel);
224       angle = t.rotation;
225       colorspec = get_text_colorspec (axis_obj.zcolor, mono);
226       if (isempty (t.string))
227         fputs (plot_stream, "unset zlabel;\n");
228       else
229         [tt, f, s] = __maybe_munge_text__ (enhanced, t, "string");
230         fontspec = create_fontspec (f, s, gnuplot_term);
231         fprintf (plot_stream, "set zlabel \"%s\" %s %s %s",
232                  undo_string_escapes (tt), colorspec, fontspec,
233                  __do_enhanced_option__ (enhanced, t));
234         fprintf (plot_stream, " rotate by %f;\n", angle);
235       endif
236     endif
237
238     if (strcmpi (axis_obj.xaxislocation, "top"))
239       xaxisloc = "x2";
240       xaxisloc_using = "x2";
241     else
242       xaxisloc = "x";
243       xaxisloc_using = "x1";
244       if (strcmpi (axis_obj.xaxislocation, "zero"))
245         fputs (plot_stream, "set xzeroaxis;\n");
246       endif
247     endif
248     if (strcmpi (axis_obj.yaxislocation, "right"))
249       yaxisloc = "y2";
250       yaxisloc_using = "y2";
251     else
252       yaxisloc = "y";
253       yaxisloc_using = "y1";
254       if (strcmpi (axis_obj.yaxislocation, "zero"))
255         fputs (plot_stream, "set yzeroaxis;\n");
256       endif
257     endif
258
259     have_grid = false;
260
261     if (strcmpi (axis_obj.xgrid, "on"))
262       have_grid = true;
263       fprintf (plot_stream, "set grid %stics;\n", xaxisloc);
264     else
265       fprintf (plot_stream, "set grid no%stics;\n", xaxisloc);
266     endif
267
268     if (strcmpi (axis_obj.ygrid, "on"))
269       have_grid = true;
270       fprintf (plot_stream, "set grid %stics;\n", yaxisloc);
271     else
272       fprintf (plot_stream, "set grid no%stics;\n", yaxisloc);
273     endif
274
275     if (strcmpi (axis_obj.zgrid, "on"))
276       have_grid = true;
277       fputs (plot_stream, "set grid ztics;\n");
278     else
279       fputs (plot_stream, "set grid noztics;\n");
280     endif
281
282     if (strcmpi (axis_obj.xminorgrid, "on"))
283       have_grid = true;
284       if (strcmp (axis_obj.xscale, "log"))
285         m = 10;
286       else
287         m = 5;
288       endif
289       fprintf (plot_stream, "set m%stics %d;\n", xaxisloc, m);
290       fprintf (plot_stream, "set grid m%stics;\n", xaxisloc);
291     else
292       fprintf (plot_stream, "set grid nom%stics;\n", xaxisloc);
293     endif
294
295     if (strcmpi (axis_obj.yminorgrid, "on"))
296       have_grid = true;
297       if (strcmp (axis_obj.yscale, "log"))
298         m = 10;
299       else
300         m = 5;
301       endif
302       fprintf (plot_stream, "set m%stics %d;\n", yaxisloc, m);
303       fprintf (plot_stream, "set grid m%stics;\n", yaxisloc);
304     else
305       fprintf (plot_stream, "set grid nom%stics;\n", yaxisloc);
306     endif
307
308     if (strcmpi (axis_obj.zminorgrid, "on"))
309       have_grid = true;
310       if (strcmp (axis_obj.zscale, "log"))
311         m = 10;
312       else
313         m = 5;
314       endif
315       fprintf (plot_stream, "set mztics %d;\n", m);
316       fputs (plot_stream, "set grid mztics;\n");
317     else
318       fputs (plot_stream, "set grid nomztics;\n");
319     endif
320
321     ## The grid front/back/layerdefault option also controls the
322     ## appearance of tics, so it is used even if the grid is absent.
323     if (strcmpi (axis_obj.layer, "top"))
324       fputs (plot_stream, "set grid front;\n");
325       fputs (plot_stream, "set border front;\n");
326     else
327       fputs (plot_stream, "set grid layerdefault;\n");
328       ## FIXME -- the gnuplot help says that "layerdefault" should work
329       ## for set border too, but it fails for me with gnuplot 4.2.5.  So
330       ## use "back" instead.
331       fputs (plot_stream, "set border back;\n");
332     endif
333
334     fprintf (plot_stream, "set grid linewidth %f, linewidth %f;\n",
335              axis_obj.linewidth, axis_obj.linewidth);
336
337     if (! have_grid)
338       fputs (plot_stream, "unset grid;\n");
339     endif
340
341     xlogscale = strcmpi (axis_obj.xscale, "log");
342     ylogscale = strcmpi (axis_obj.yscale, "log");
343     zlogscale = strcmpi (axis_obj.zscale, "log");
344
345     ## Detect logscale and negative lims
346     if (xlogscale && all (axis_obj.xlim < 0))
347       axis_obj.xsgn = -1;
348       if (strcmp (axis_obj.xdir, "reverse"))
349         axis_obj.xdir = "normal";
350       elseif (strcmp (axis_obj.xdir, "normal"))
351         axis_obj.xdir = "reverse";
352       endif
353       axis_obj.xtick = -flip (axis_obj.xtick);
354       axis_obj.xticklabel = flip (axis_obj.xticklabel);
355       axis_obj.xlim = -flip (axis_obj.xlim);
356     else
357       axis_obj.xsgn = 1;
358     endif
359     if (ylogscale && all (axis_obj.ylim < 0))
360       axis_obj.ysgn = -1;
361       if (strcmp (axis_obj.ydir, "reverse"))
362         axis_obj.ydir = "normal";
363       elseif (strcmp (axis_obj.ydir, "normal"))
364         axis_obj.ydir = "reverse";
365       endif
366       axis_obj.ytick = -flip (axis_obj.ytick);
367       axis_obj.yticklabel = flip (axis_obj.yticklabel);
368       axis_obj.ylim = -flip (axis_obj.ylim);
369     else
370       axis_obj.ysgn = 1;
371     endif
372     if (zlogscale && all (axis_obj.zlim < 0))
373       axis_obj.zsgn = -1;
374       if (strcmp (axis_obj.zdir, "reverse"))
375         axis_obj.zdir = "normal";
376       elseif (strcmp (axis_obj.zdir, "normal"))
377         axis_obj.zdir = "reverse";
378       endif
379       axis_obj.ztick = -flip (axis_obj.ztick);
380       axis_obj.zticklabel = flip (axis_obj.zticklabel);
381       axis_obj.zlim = -flip (axis_obj.zlim);
382     else
383       axis_obj.zsgn = 1;
384     endif
385
386     xlim = axis_obj.xlim;
387     ylim = axis_obj.ylim;
388     zlim = axis_obj.zlim;
389     clim = axis_obj.clim;
390
391     do_tics (axis_obj, plot_stream, ymirror, mono, gnuplot_term);
392
393     fputs (plot_stream, "unset logscale;\n");
394     if (xlogscale)
395       fprintf (plot_stream, "set logscale %s;\n", xaxisloc);
396     endif
397     if (ylogscale)
398       fprintf (plot_stream, "set logscale %s;\n", yaxisloc);
399     endif
400     if (zlogscale)
401       fputs (plot_stream, "set logscale z;\n");
402     endif
403
404     xautoscale = strcmpi (axis_obj.xlimmode, "auto");
405     yautoscale = strcmpi (axis_obj.ylimmode, "auto");
406     zautoscale = strcmpi (axis_obj.zlimmode, "auto");
407     cautoscale = strcmpi (axis_obj.climmode, "auto");
408     cdatadirect = false;
409     truecolor = false;
410
411     fputs (plot_stream, "set clip two;\n");
412
413     kids = axis_obj.children;
414     ## Remove the axis labels and title from the children, and
415     ## preserved the original order.
416     [jnk, k] = setdiff (kids, [axis_obj.xlabel; axis_obj.ylabel; ...
417                                axis_obj.zlabel; axis_obj.title]);
418     kids = kids (sort (k));
419
420     if (nd == 3)
421       fputs (plot_stream, "set parametric;\n");
422       fputs (plot_stream, "set style data lines;\n");
423       fputs (plot_stream, "set surface;\n");
424       fputs (plot_stream, "unset contour;\n");
425     endif
426
427     data_idx = 0;
428     data = cell ();
429     is_image_data = [];
430     hidden_removal = NaN;
431     view_map = false;
432
433     if (! cautoscale && clim(1) == clim(2))
434       clim(2)++;
435     endif
436     addedcmap = [];
437
438     ximg_data = {};
439     ximg_data_idx = 0;
440
441     while (! isempty (kids))
442
443       obj = get (kids(end));
444
445       if (isfield (obj, "units"))
446         units = obj.units;
447         unwind_protect
448           set (kids(end), "units", "data");
449           obj = get (kids(end));
450         unwind_protect_cleanup
451           set (kids(end), "units", units);
452         end_unwind_protect
453       endif
454       kids = kids(1:(end-1));
455
456       if (strcmpi (obj.visible, "off"))
457         continue;
458       endif
459
460       if (xlogscale && isfield (obj, "xdata"))
461         obj.xdata = axis_obj.xsgn * obj.xdata;
462         obj.xdata(obj.xdata<=0) = NaN;
463       endif
464       if (ylogscale && isfield (obj, "ydata"))
465         obj.ydata = axis_obj.ysgn * obj.ydata;
466         obj.ydata(obj.ydata<=0) = NaN;
467       endif
468       if (zlogscale && isfield (obj, "zdata"))
469         obj.zdata = axis_obj.zsgn * obj.zdata;
470         obj.zdata(obj.zdata<=0) = NaN;
471       endif
472
473       ## Check for facecolor interpolation for surfaces.
474       doing_interp_color = ...
475          isfield (obj, "facecolor") && strncmp (obj.facecolor, "interp", 6);
476
477       switch (obj.type)
478         case "image"
479           img_data = obj.cdata;
480           img_xdata = obj.xdata;
481           img_ydata = obj.ydata;
482
483           if (ndims (img_data) == 3)
484             truecolor = true;
485           elseif (strcmpi (obj.cdatamapping, "direct"))
486             cdatadirect = true;
487           endif
488           data_idx++;
489           is_image_data(data_idx) = true;
490           parametric(data_idx) = false;
491           have_cdata(data_idx) = false;
492           have_3d_patch(data_idx) = false;
493
494           if (img_xdata(2) < img_xdata(1))
495             img_xdata = img_xdata(2:-1:1);
496             img_data = img_data(:,end:-1:1,:);
497           elseif (img_xdata(1) == img_xdata(2))
498             img_xdata = img_xdata(1) + [0, size(img_data,2)-1];
499           endif
500           if (img_ydata(2) < img_ydata(1))
501             img_ydata = img_ydata(2:-1:1);
502             img_data = img_data(end:-1:1,:,:);
503           elseif (img_ydata(1) == img_ydata(2))
504             img_ydata = img_ydata(1) + [0, size(img_data,1)-1];
505           endif
506
507           [y_dim, x_dim] = size (img_data(:,:,1));
508           if (x_dim > 1)
509             dx = abs (img_xdata(2)-img_xdata(1))/(x_dim-1);
510           else
511             x_dim = 2;
512             img_data = [img_data, img_data];
513             dx = abs (img_xdata(2)-img_xdata(1));
514           endif
515           if (y_dim > 1)
516             dy = abs (img_ydata(2)-img_ydata(1))/(y_dim-1);
517           else
518             y_dim = 2;
519             img_data = [img_data; img_data];
520             dy = abs (img_ydata(2)-img_ydata(1));
521           endif
522
523           x_origin = min (img_xdata);
524           y_origin = min (img_ydata);
525
526           if (ndims (img_data) == 3)
527             data{data_idx} = permute (img_data, [3, 1, 2])(:);
528             format = "1:2:3";
529             imagetype = "rgbimage";
530           else
531             data{data_idx} = img_data(:);
532             format = "1";
533             imagetype = "image";
534           endif
535
536           titlespec{data_idx} = "title \"\"";
537           usingclause{data_idx} = sprintf ("binary array=%dx%d scan=yx origin=(%.15g,%.15g) dx=%.15g dy=%.15g using %s",
538               x_dim, y_dim, x_origin, y_origin, dx, dy, format);
539           withclause{data_idx} = sprintf ("with %s;", imagetype);
540
541         case "line"
542           if (strncmp (obj.linestyle, "none", 4)
543               && (! isfield (obj, "marker")
544                   || (isfield (obj, "marker")
545                       && strncmp (obj.marker, "none", 4))))
546             continue;
547           endif
548           data_idx++;
549           is_image_data(data_idx) = false;
550           parametric(data_idx) = true;
551           have_cdata(data_idx) = false;
552           have_3d_patch(data_idx) = false;
553           if (isempty (obj.displayname))
554             titlespec{data_idx} = "title \"\"";
555           else
556             tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "displayname"));
557             titlespec{data_idx} = cstrcat ("title \"", tmp, "\"");
558           endif
559           usingclause{data_idx} = sprintf ("record=%d", numel (obj.xdata));
560           errbars = "";
561           if (nd == 3)
562             xdat = obj.xdata(:);
563             ydat = obj.ydata(:);
564             if (! isempty (obj.zdata))
565               zdat = obj.zdata(:);
566             else
567               zdat = zeros (size (xdat));
568             endif
569             data{data_idx} = [xdat, ydat, zdat]';
570             usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3)", numel (xdat));
571             ## fputs (plot_stream, "set parametric;\n");
572           else
573             xdat = obj.xdata(:);
574             ydat = obj.ydata(:);
575             data{data_idx} = [xdat, ydat]';
576             usingclause{data_idx} = sprintf ("record=%d using ($1):($2) axes %s%s",
577                                             rows(xdat), xaxisloc_using, yaxisloc_using);
578           endif
579
580           style = do_linestyle_command (obj, obj.color, data_idx, mono,
581                                         plot_stream, errbars);
582
583           withclause{data_idx} = sprintf ("with %s linestyle %d",
584                                           style{1}, data_idx);
585
586           if (length (style) > 1)
587             data_idx++;
588             is_image_data(data_idx) = is_image_data(data_idx - 1);
589             parametric(data_idx) = parametric(data_idx - 1);
590             have_cdata(data_idx) = have_cdata(data_idx - 1);
591             have_3d_patch(data_idx) = have_3d_patch(data_idx - 1);
592             titlespec{data_idx} = "title \"\"";
593             usingclause{data_idx} = usingclause{data_idx - 1};
594             data{data_idx} = data{data_idx - 1};
595             withclause{data_idx} = sprintf ("with %s linestyle %d",
596                                           style{2}, data_idx);
597           endif
598           if (length (style) > 2)
599             data_idx++;
600             is_image_data(data_idx) = is_image_data(data_idx - 1);
601             parametric(data_idx) = parametric(data_idx - 1);
602             have_cdata(data_idx) = have_cdata(data_idx - 1);
603             have_3d_patch(data_idx) = have_3d_patch(data_idx - 1);
604             titlespec{data_idx} = "title \"\"";
605             usingclause{data_idx} = usingclause{data_idx - 1};
606             data{data_idx} = data{data_idx - 1};
607             withclause{data_idx} = sprintf ("with %s linestyle %d",
608                                           style{3}, data_idx);
609           endif
610
611        case "patch"
612          cmap = parent_figure_obj.colormap;
613          [nr, nc] = size (obj.xdata);
614
615          if (! isempty (obj.cdata))
616            cdat = obj.cdata;
617            if (strcmpi (obj.cdatamapping, "direct"))
618              cdatadirect = true;
619            endif
620          else
621            cdat = [];
622          endif
623
624          data_3d_idx = NaN;
625          for i = 1:nc
626            xcol = obj.xdata(:,i);
627            ycol = obj.ydata(:,i);
628            if (nd == 3)
629              if (! isempty (obj.zdata))
630                zcol = obj.zdata(:,i);
631              else
632                zcol = zeros (size (xcol));
633              endif
634            endif
635
636            if (! isnan (xcol) && ! isnan (ycol))
637              ## Is the patch closed or not
638              if (strncmp (obj.facecolor, "none", 4))
639                hidden_removal = false;
640              else
641
642                if (isnan (hidden_removal))
643                  hidden_removal = true;
644                endif
645                if (nd == 3)
646                  if (numel (xcol) > 3)
647                    error ("__go_draw_axes__: gnuplot (as of v4.2) only supports 3D filled triangular patches");
648                  else
649                    if (isnan (data_3d_idx))
650                      data_idx++;
651                      data_3d_idx = data_idx;
652                      is_image_data(data_idx) = false;
653                      parametric(data_idx) = false;
654                      have_cdata(data_idx) = true;
655                      have_3d_patch(data_idx) = true;
656                      withclause{data_3d_idx} = sprintf ("with pm3d");
657                      usingclause{data_3d_idx} =  "using 1:2:3:4";
658                      data{data_3d_idx} = [];
659                    endif
660                    local_idx = data_3d_idx;
661                    ccdat = NaN;
662                  endif
663                else
664                  data_idx++;
665                  local_idx = data_idx;
666                  is_image_data(data_idx) = false;
667                  parametric(data_idx) = false;
668                  have_cdata(data_idx) = false;
669                  have_3d_patch(data_idx) = false;
670                endif
671
672                if (i > 1 || isempty (obj.displayname))
673                  titlespec{local_idx} = "title \"\"";
674                else
675                  tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "displayname"));
676                  titlespec{local_idx} = cstrcat ("title \"", tmp, "\"");
677                endif
678                if (isfield (obj, "facecolor"))
679                  if ((strncmp (obj.facecolor, "flat", 4)
680                      || strncmp (obj.facecolor, "interp", 6))
681                      && isfield (obj, "cdata"))
682                    if (ndims (obj.cdata) == 2
683                        && (size (obj.cdata, 2) == nc
684                            && (size (obj.cdata, 1) == 1
685                                || size (obj.cdata, 1) == 3)))
686                      ccol = cdat (:, i);
687                    elseif (ndims (obj.cdata) == 2
688                        && (size (obj.cdata, 1) == nc
689                            && (size (obj.cdata, 2) == 1
690                                || size (obj.cdata, 2) == 3)))
691                      ccol = cdat (i, :);
692                    elseif (ndims (obj.cdata) == 3)
693                      ccol = permute (cdat (:, i, :), [1, 3, 2]);
694                    else
695                      ccol = cdat;
696                    endif
697                    if (strncmp (obj.facecolor, "flat", 4))
698                      if (isequal (size (ccol), [1, 3]))
699                        ## RGB Triplet
700                        color = ccol;
701                      elseif (nd == 3 && numel (xcol) == 3)
702                        ccdat = ccol;
703                      else
704                        if (cdatadirect)
705                          r = round (ccol);
706                        else
707                          r = 1 + round ((size (cmap, 1) - 1)
708                                         * (ccol - clim(1))/(clim(2) - clim(1)));
709                        endif
710                        r = max (1, min (r, size (cmap, 1)));
711                        color = cmap(r, :);
712                      endif
713                    elseif (strncmp (obj.facecolor, "interp", 6))
714                      if (nd == 3 && numel (xcol) == 3)
715                        ccdat = ccol;
716                        if (! isvector (ccdat))
717                          tmp = rows(cmap) + rows(addedcmap) + ...
718                               [1 : rows(ccdat)];
719                          addedcmap = [addedcmap; ccdat];
720                          ccdat = tmp(:);
721                        else
722                          ccdat = ccdat(:);
723                        endif
724                      else
725                        if (sum (diff (ccol)))
726                          warning ("\"interp\" not supported, using 1st entry of cdata");
727                        endif
728                        if (cdatadirect)
729                          r = round (ccol);
730                        else
731                          r = 1 + round ((size (cmap, 1) - 1)
732                                         * (ccol - clim(1))/(clim(2) - clim(1)));
733                        endif
734                        r = max (1, min (r, size (cmap, 1)));
735                        color = cmap(r(1),:);
736                      endif
737                    endif
738                  elseif (isnumeric (obj.facecolor))
739                    color = obj.facecolor;
740                  else
741                    color = [0, 1, 0];
742                  endif
743                else
744                  color = [0, 1, 0];
745                endif
746
747                if (nd == 3 && numel (xcol) == 3)
748                  if (isnan (ccdat))
749                    ccdat = (rows (cmap) + rows(addedcmap) + 1) * ones(3, 1);
750                    addedcmap = [addedcmap; reshape(color, 1, 3)];
751                  endif
752                  data{data_3d_idx} = [data{data_3d_idx}, ...
753                                       [[xcol; xcol(end)], [ycol; ycol(end)], ...
754                                       [zcol; zcol(end)], [ccdat; ccdat(end)]]'];
755                else
756                  if (mono)
757                    colorspec = "";
758                  elseif (__gnuplot_has_feature__ ("transparent_patches")
759                          && isscalar (obj.facealpha))
760                    colorspec = sprintf ("lc rgb \"#%02x%02x%02x\" fillstyle transparent solid %f",
761                                       round (255*color), obj.facealpha);
762                  else
763                    colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"",
764                                         round (255*color));
765                  endif
766
767                  withclause{data_idx} = sprintf ("with filledcurve %s",
768                                                colorspec);
769                  data{data_idx} = [xcol, ycol]';
770                  usingclause{data_idx} = sprintf ("record=%d using ($1):($2)",
771                                                   numel (xcol));
772                endif
773              endif
774            endif
775
776            ## patch outline
777            if (!(strncmp (obj.edgecolor, "none", 4)
778                   && (strncmp (obj.marker, "none", 4)
779                       || (strncmp (obj.markeredgecolor, "none", 4)
780                           && strncmp (obj.markerfacecolor, "none", 4)))))
781
782              data_idx++;
783              is_image_data(data_idx) = false;
784              parametric(data_idx) = false;
785              have_cdata(data_idx) = false;
786              have_3d_patch(data_idx) = false;
787              titlespec{data_idx} = "title \"\"";
788              usingclause{data_idx} = sprintf ("record=%d", numel (obj.xdata));
789
790              if (isfield (obj, "markersize"))
791                mdat = obj.markersize / 3;
792              endif
793
794              if (isfield (obj, "edgecolor"))
795                ## FIXME
796                ## This is the wrong thing to do as edgecolor, markeredgecolor
797                ## and markerfacecolor can have different values and we should
798                ## treat them seperately. However, the below allow the scatter
799                ## functions to work as expected, where only one of these values
800                ## is set
801                if (strncmp (obj.edgecolor, "none", 4))
802                  if (strncmp (obj.markeredgecolor, "none", 4))
803                    ec = obj.markerfacecolor;
804                  else
805                    ec = obj.markeredgecolor;
806                  endif
807                else
808                  ec = obj.edgecolor;
809                endif
810
811                if ((strncmp (ec, "flat", 4)
812                     || strncmp (ec, "interp", 6))
813                    && isfield (obj, "cdata"))
814                  if (ndims (obj.cdata) == 2
815                      && (size (obj.cdata, 2) == nc
816                          && (size (obj.cdata, 1) == 1
817                              || size (obj.cdata, 1) == 3)))
818                    ccol = cdat (:, i);
819                  elseif (ndims (obj.cdata) == 2
820                          && (size (obj.cdata, 1) == nc
821                              && (size (obj.cdata, 2) == 1
822                                  || size (obj.cdata, 2) == 3)))
823                    ccol = cdat (i, :);
824                  elseif (ndims (obj.cdata) == 3)
825                    ccol = permute (cdat (:, i, :), [1, 3, 2]);
826                  else
827                    ccol = cdat;
828                  endif
829                  if (strncmp (ec, "flat", 4))
830                    if (numel(ccol) == 3)
831                      color = ccol;
832                    else
833                      if (isscalar (ccol))
834                        ccol = repmat(ccol, numel (xcol), 1);
835                      endif
836                      color = "flat";
837                      have_cdata(data_idx) = true;
838                    endif
839                  elseif (strncmp (ec, "interp", 6))
840                    if (numel(ccol) == 3)
841                      warning ("\"interp\" not supported, using 1st entry of cdata");
842                      color = ccol(1,:);
843                    else
844                      if (isscalar (ccol))
845                        ccol = repmat(ccol, numel (xcol), 1);
846                      endif
847                      color = "interp";
848                      have_cdata(data_idx) = true;
849                    endif
850                  endif
851                elseif (isnumeric (ec))
852                  color = ec;
853                else
854                  color = [0, 0, 0];
855                endif
856              else
857                color = [0, 0, 0];
858              endif
859
860              if (isfield (obj, "linestyle"))
861                switch (obj.linestyle)
862                  case "-"
863                    lt = "lt 1";
864                  case "--"
865                    lt = "lt 2";
866                  case ":"
867                    lt = "lt 3";
868                  case "-."
869                    lt = "lt 6";
870                  case "none"
871                    lt = "";
872                  otherwise
873                    lt = "";
874                endswitch
875              else
876                lt = "";
877              endif
878
879              if (isfield (obj, "linewidth"))
880                lw = sprintf("linewidth %f", obj.linewidth);
881              else
882                lw  = "";
883              endif
884
885              [pt, pt2, obj] = gnuplot_pointtype (obj);
886              if (! isempty (pt))
887                pt = sprintf ("pointtype %s", pt);
888              endif
889              if (! isempty (pt2))
890                pt2 = sprintf ("pointtype %s", pt2);
891              endif
892
893              if (mono)
894                colorspec = "";
895              else
896                if (ischar (color))
897                  colorspec = "palette";
898                else
899                  colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"",
900                                       round (255*color));
901                endif
902              endif
903
904              sidx = 1;
905              if (isempty (lt))
906                style = "";
907              else
908                style = "lines";
909              endif
910              tmpwith = {};
911
912              facesame = true;
913              if (! isequal (pt, pt2) && isfield (obj, "markerfacecolor")
914                  && !strncmp (obj.markerfacecolor, "none", 4))
915                if (strncmp (obj.markerfacecolor, "auto", 4)
916                    || ! isnumeric (obj.markerfacecolor)
917                    || (isnumeric (obj.markerfacecolor)
918                        && isequal (color, obj.markerfacecolor)))
919                  style = strcat (style, "points");
920                  if (isfield (obj, "markersize"))
921                    if (length (mdat) == nc)
922                      m = mdat(i);
923                    else
924                      m = mdat;
925                    endif
926                    ps = sprintf("pointsize %f", m / 3);
927                  else
928                    ps = "";
929                  endif
930
931                  tmpwith{sidx} = sprintf ("with %s %s %s %s %s %s",
932                                           style, lw, pt2, lt, ps,
933                                           colorspec);
934                else
935                  facesame = false;
936                  if (! isempty (style))
937                    tmpwith{sidx} = sprintf ("with %s %s %s %s",
938                                             style, lw, lt,
939                                             colorspec);
940                    sidx ++;
941                  endif
942                  if (isnumeric (obj.markerfacecolor) && ! mono)
943                    colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"",
944                                         round (255*obj.markerfacecolor));
945                  endif
946                  style = "points";
947                  if (isfield (obj, "markersize"))
948                    if (length (mdat) == nc)
949                      m = mdat(i);
950                    else
951                      m = mdat;
952                    endif
953                    ps = sprintf("pointsize %f", m / 3);
954                  else
955                    ps = "";
956                  endif
957                  tmpwith{sidx} = sprintf ("with %s %s %s %s %s %s",
958                                           style, lw, pt2, lt, ps,
959                                           colorspec);
960                endif
961              endif
962
963              if (isfield (obj, "markeredgecolor")
964                  && !strncmp (obj.markeredgecolor, "none", 4))
965                if (facesame && !isempty (pt)
966                    && (strncmp (obj.markeredgecolor, "auto", 4)
967                        || ! isnumeric (obj.markeredgecolor)
968                        || (isnumeric (obj.markeredgecolor)
969                            && isequal (color, obj.markeredgecolor))))
970                  if (sidx == 1 && ((length (style) == 5
971                           && strncmp (style, "lines", 5))
972                          || isempty (style)))
973                    style = strcat (style, "points");
974                    if (isfield (obj, "markersize"))
975                      if (length (mdat) == nc)
976                        m = mdat(i);
977                      else
978                        m = mdat;
979                      endif
980                      ps = sprintf("pointsize %f", m / 3);
981                    else
982                      ps = "";
983                    endif
984                    tmpwith{sidx} = sprintf ("with %s %s %s %s %s %s",
985                                             style, lw, pt, lt, ps,
986                                             colorspec);
987                  endif
988                else
989                  if (!isempty (style))
990                    if (length(tmpwith) < sidx || isempty (tmpwith{sidx}))
991                      tmpwith{sidx} = sprintf ("with %s %s %s %s",
992                                               style, lw, lt,
993                                               colorspec);
994                    endif
995                    sidx ++;
996                  endif
997
998                  if (!isempty (pt))
999                    if (! mono)
1000                      if (strncmp (obj.markeredgecolor, "auto", 4))
1001                        colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"",
1002                                             round (255*color));
1003                      elseif (isnumeric (obj.markeredgecolor) && ! mono)
1004                        colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"",
1005                                             round (255*obj.markeredgecolor));
1006                      endif
1007                    endif
1008                    style = "points";
1009                    if (isfield (obj, "markersize"))
1010                      if (length (mdat) == nc)
1011                        m = mdat(i);
1012                      else
1013                        m = mdat;
1014                      endif
1015                      ps = sprintf("pointsize %f", m / 3);
1016                    else
1017                      ps = "";
1018                    endif
1019                    tmpwith{sidx} = sprintf ("with %s %s %s %s %s %s",
1020                                             style, lw, pt, lt, ps,
1021                                             colorspec);
1022                  endif
1023                endif
1024              endif
1025
1026              if (isempty (tmpwith))
1027                withclause{data_idx} = sprintf ("with %s %s %s %s %s",
1028                                                style, lw, pt, lt,
1029                                                colorspec);
1030              else
1031                withclause{data_idx} = tmpwith{1};
1032              endif
1033              if (nd == 3)
1034                if (ischar (color))
1035                  if (! isnan (xcol) && ! isnan (ycol) && ! isnan (zcol))
1036                    data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)], ...
1037                                      [zcol; zcol(1)], [ccol; ccol(1)]]';
1038                  else
1039                    data{data_idx} = [xcol, ycol, zcol, ccol]';
1040                  endif
1041                  usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3):($4)", columns (data{data_idx}));
1042                else
1043                  if (! isnan (xcol) && ! isnan (ycol) && ! isnan (zcol))
1044                    data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)], ...
1045                                      [zcol; zcol(1)]]';
1046                  else
1047                    data{data_idx} = [xcol, ycol, zcol]';
1048                  endif
1049                  usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3)", columns (data{data_idx}));
1050                endif
1051              else
1052                if (ischar (color))
1053                  if (! isnan (xcol) && ! isnan (ycol))
1054                    data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)], ...
1055                                      [ccol; ccol(1)]]';
1056                  else
1057                    data{data_idx} = [xcol, ycol, ccol]';
1058                  endif
1059                  usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3)", columns (data{data_idx}));
1060                else
1061                  if (! isnan (xcol) && ! isnan (ycol))
1062                    data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)]]';
1063                  else
1064                    data{data_idx} = [xcol, ycol]';
1065                  endif
1066                  usingclause{data_idx} = sprintf ("record=%d using ($1):($2)", columns (data{data_idx}));
1067                endif
1068              endif
1069
1070              if (length (tmpwith) > 1)
1071                data_idx++;
1072                is_image_data(data_idx) = is_image_data(data_idx - 1);
1073                parametric(data_idx) = parametric(data_idx - 1);
1074                have_cdata(data_idx) = have_cdata(data_idx - 1);
1075                have_3d_patch(data_idx) = have_3d_patch(data_idx - 1);
1076                titlespec{data_idx} = "title \"\"";
1077                usingclause{data_idx} = usingclause{data_idx - 1};
1078                data{data_idx} = data{data_idx - 1};
1079                withclause{data_idx} = tmpwith{2};
1080              endif
1081              if (length (tmpwith) > 2)
1082                data_idx++;
1083                is_image_data(data_idx) = is_image_data(data_idx - 1);
1084                parametric(data_idx) = parametric(data_idx - 1);
1085                have_cdata(data_idx) = have_cdata(data_idx - 1);
1086                have_3d_patch(data_idx) = have_3d_patch(data_idx - 1);
1087                titlespec{data_idx} = "title \"\"";
1088                usingclause{data_idx} = usingclause{data_idx - 1};
1089                data{data_idx} = data{data_idx - 1};
1090                withclause{data_idx} = tmpwith{3};
1091              endif
1092            endif
1093          endfor
1094
1095         case "surface"
1096           view_map = true;
1097           if (! (strncmp (obj.edgecolor, "none", 4)
1098                  && strncmp (obj.facecolor, "none", 4)))
1099             data_idx++;
1100             is_image_data(data_idx) = false;
1101             parametric(data_idx) = false;
1102             have_cdata(data_idx) = true;
1103             have_3d_patch(data_idx) = false;
1104             style = do_linestyle_command (obj, obj.edgecolor,
1105                                           data_idx, mono,
1106                                           plot_stream);
1107
1108             if (isempty (obj.displayname))
1109               titlespec{data_idx} = "title \"\"";
1110             else
1111               tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "displayname"));
1112               titlespec{data_idx} = cstrcat ("title \"", tmp, "\"");
1113             endif
1114             withclause{data_idx} = sprintf ("with pm3d linestyle %d",
1115                                             data_idx);
1116             withpm3d = true;
1117             pm3didx = data_idx;
1118
1119             xdat = obj.xdata;
1120             ydat = obj.ydata;
1121             zdat = obj.zdata;
1122             cdat = obj.cdata;
1123
1124             err = false;
1125             if (! size_equal(zdat, cdat))
1126               err = true;
1127             endif
1128             if (isvector (xdat) && isvector (ydat) && ismatrix (zdat))
1129               if (rows (zdat) == length (ydat)
1130                   && columns (zdat) == length (xdat))
1131                 [xdat, ydat] = meshgrid (xdat, ydat);
1132               else
1133                 err = true;
1134               endif
1135             elseif (ismatrix (xdat) && ismatrix (ydat) && ismatrix (zdat))
1136               if (! size_equal (xdat, ydat, zdat))
1137                 err = true;
1138               endif
1139             else
1140               err = true;
1141             endif
1142             if (err)
1143               error ("__go_draw_axes__: invalid grid data");
1144             endif
1145             xlen = columns (zdat);
1146             ylen = rows (zdat);
1147             if (xlen == columns (xdat) && xlen == columns (ydat)
1148                 && ylen == rows (xdat) && ylen == rows (ydat))
1149               len = 4 * xlen;
1150               zz = zeros (ylen, len);
1151               k = 1;
1152               for kk = 1:4:len
1153                 zz(:,kk)   = xdat(:,k);
1154                 zz(:,kk+1) = ydat(:,k);
1155                 zz(:,kk+2) = zdat(:,k);
1156                 zz(:,kk+3) = cdat(:,k);
1157                 k++;
1158               endfor
1159               data{data_idx} = zz.';
1160             endif
1161
1162             if (doing_interp_color)
1163               interp_str = "interpolate 0, 0";
1164             else
1165               ## No interpolation of facecolors.
1166               interp_str = "";
1167             endif
1168             usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3):($4)", ylen, xlen);
1169
1170             flat_interp_face = (strncmp (obj.facecolor, "flat", 4)
1171                                 || strncmp (obj.facecolor, "interp", 6));
1172             flat_interp_edge = (strncmp (obj.edgecolor, "flat", 4)
1173                                 || strncmp (obj.edgecolor, "interp", 6));
1174
1175             facecolor_none_or_white = (strncmp (obj.facecolor, "none", 4)
1176                                        || (isnumeric (obj.facecolor)
1177                                            && all (obj.facecolor == 1)));
1178             hidden_removal = false;
1179             fputs (plot_stream, "set style increment default;\n");
1180             if (flat_interp_edge && facecolor_none_or_white)
1181               withpm3d = false;
1182               withclause{data_idx} = sprintf ("with %s palette", style {1});
1183               fputs (plot_stream, "unset pm3d\n");
1184               if (all (obj.facecolor == 1))
1185                 hidden_removal = true;
1186               endif
1187             elseif (facecolor_none_or_white)
1188               if (all (obj.facecolor == 1))
1189                 hidden_removal = true;
1190               endif
1191               fputs(plot_stream,"unset pm3d;\n");
1192               fputs(plot_stream,"set style increment user;\n");
1193               withpm3d = false;
1194               withclause{data_idx} = sprintf("with %s linestyle %d",
1195                                              style{1}, data_idx);
1196               fputs (plot_stream, "unset pm3d\n");
1197             endif
1198
1199             if (doing_interp_color)
1200               ## "depthorder" interferes with interpolation of colors.
1201               dord = "scansautomatic";
1202             else
1203               dord = "depthorder";
1204             endif
1205
1206             if (flat_interp_face && strncmp (obj.edgecolor, "flat", 4))
1207               fprintf (plot_stream, "set pm3d explicit at s %s %s corners2color c3;\n",
1208                        interp_str, dord);
1209             elseif (!facecolor_none_or_white)
1210               if (strncmp (obj.edgecolor, "none", 4))
1211                 if (__gnuplot_has_feature__ ("transparent_surface")
1212                     && isscalar (obj.facealpha))
1213                   fprintf (plot_stream,
1214                            "set style fill transparent solid %f;\n",
1215                            obj.facealpha);
1216                 endif
1217                 fprintf (plot_stream, "set pm3d explicit at s %s corners2color c3;\n",
1218                          interp_str, dord);
1219               else
1220                 fprintf (plot_stream, "set pm3d explicit at s hidden3d %d %s %s corners2color c3;\n",
1221                          data_idx, interp_str, dord);
1222
1223                 if (__gnuplot_has_feature__ ("transparent_surface")
1224                     && isscalar (obj.facealpha))
1225                   fprintf (plot_stream,
1226                            "set style fill transparent solid %f;\n",
1227                            obj.facealpha);
1228                 endif
1229               endif
1230             endif
1231
1232             zz = [];
1233             if (length (style) > 1)
1234               len = 3 * xlen;
1235               zz = zeros (ylen, len);
1236               k = 1;
1237               for kk = 1:3:len
1238                 zz(:,kk)   = xdat(:,k);
1239                 zz(:,kk+1) = ydat(:,k);
1240                 zz(:,kk+2) = zdat(:,k);
1241                 k++;
1242               endfor
1243               zz = zz.';
1244
1245               data_idx++;
1246               is_image_data(data_idx) = is_image_data(data_idx - 1);
1247               parametric(data_idx) = parametric(data_idx - 1);
1248               have_cdata(data_idx) = false;
1249               have_3d_patch(data_idx) = have_3d_patch(data_idx - 1);
1250               titlespec{data_idx} = "title \"\"";
1251               usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3)", ylen, xlen);
1252               data{data_idx} = zz;
1253               withclause{data_idx} = sprintf ("with %s linestyle %d",
1254                                               style{2}, data_idx);
1255
1256             endif
1257             if (length (style) > 2)
1258               data_idx++;
1259               is_image_data(data_idx) = is_image_data(data_idx - 1);
1260               parametric(data_idx) = parametric(data_idx - 1);
1261               have_cdata(data_idx) = false;
1262               have_3d_patch(data_idx) = have_3d_patch(data_idx - 1);
1263               titlespec{data_idx} = "title \"\"";
1264               usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3)", ylen, xlen);
1265               data{data_idx} = zz;
1266               withclause{data_idx} = sprintf ("with %s linestyle %d",
1267                                               style{3}, data_idx);
1268             endif
1269             if (withpm3d && strncmp (style {1}, "linespoints", 11))
1270               if (isempty(zz))
1271                 len = 3 * xlen;
1272                 zz = zeros (ylen, len);
1273                 k = 1;
1274                 for kk = 1:3:len
1275                   zz(:,kk)   = xdat(:,k);
1276                   zz(:,kk+1) = ydat(:,k);
1277                   zz(:,kk+2) = zdat(:,k);
1278                   k++;
1279                 endfor
1280                 zz = zz.';
1281               endif
1282               data_idx++;
1283               is_image_data(data_idx) = is_image_data(data_idx - 1);
1284               parametric(data_idx) = parametric(data_idx - 1);
1285               have_cdata(data_idx) = false;
1286               have_3d_patch(data_idx) = have_3d_patch(data_idx - 1);
1287               titlespec{data_idx} = "title \"\"";
1288               usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3)", ylen, xlen);
1289               data{data_idx} = zz;
1290               withclause{data_idx} = sprintf ("with points linestyle %d",
1291                                               pm3didx);
1292             endif
1293           endif
1294
1295         case "text"
1296           [label, f, s] = __maybe_munge_text__ (enhanced, obj, "string");
1297           fontspec = create_fontspec (f, s, gnuplot_term);
1298           lpos = obj.position;
1299           halign = obj.horizontalalignment;
1300           valign = obj.verticalalignment;
1301           angle = obj.rotation;
1302           units = obj.units;
1303           color = obj.color;
1304           if (strcmpi (units, "normalized"))
1305             units = "graph";
1306           elseif (strcmp (axis_obj.yaxislocation, "right")
1307                   && strcmp (units, "data"))
1308             units = "second";
1309           else
1310             units = "";
1311           endif
1312
1313           if (isnumeric (color))
1314             colorspec = get_text_colorspec (color, mono);
1315           endif
1316
1317           if (ischar (obj.string))
1318             num_lines = size (obj.string, 1);
1319           else
1320             num_lines = numel (obj.string);
1321           endif
1322           switch valign
1323             ## Text offset in characters. This relies on gnuplot for font metrics.
1324             case "top"
1325               dy = -0.5;
1326             case "cap"
1327               dy = -0.5;
1328             case "middle"
1329               dy = 0.5 * (num_lines - 1);
1330             case "baseline"
1331               dy = 0.5 + (num_lines - 1);
1332             case "bottom"
1333               dy = 0.5 + (num_lines - 1);
1334           endswitch
1335           ## Gnuplot's Character units are different for x/y and vary with fontsize. The aspect ratio
1336           ## of 1:1.7 was determined by experiment to work for eps/ps/etc. For the MacOS aqua terminal
1337           ## a value of 2.5 is needed. However, the difference is barely noticable.
1338           dx_and_dy = [(-dy * sind (angle)), (dy * cosd(angle))] .* [1.7 1];
1339
1340           ## FIXME - Multiline text produced the gnuplot "warning: ft_render: skipping glyph"
1341           if (nd == 3)
1342             ## This produces the desired vertical alignment in 3D.
1343             fprintf (plot_stream,
1344                      "set label \"%s\" at %s %.15e,%.15e,%.15e %s rotate by %f offset character %f,%f %s %s front %s;\n",
1345                      undo_string_escapes (label), units, lpos(1),
1346                      lpos(2), lpos(3), halign, angle, dx_and_dy, fontspec,
1347                      __do_enhanced_option__ (enhanced, obj), colorspec);
1348           else
1349             fprintf (plot_stream,
1350                      "set label \"%s\" at %s %.15e,%.15e %s rotate by %f offset character %f,%f %s %s front %s;\n",
1351                      undo_string_escapes (label), units,
1352                      lpos(1), lpos(2), halign, angle, dx_and_dy, fontspec,
1353                      __do_enhanced_option__ (enhanced, obj), colorspec);
1354           endif
1355
1356         case "hggroup"
1357           ## Push group children into the kid list.
1358           if (isempty (kids))
1359             kids = obj.children;
1360           elseif (! isempty (obj.children))
1361             kids = [kids; obj.children];
1362           endif
1363
1364         otherwise
1365           error ("__go_draw_axes__: unknown object class, %s",
1366                  obj.type);
1367       endswitch
1368
1369     endwhile
1370
1371     ## This is need to prevent warnings for rotations in 3D plots, while
1372     ## allowing colorbars with contours.
1373     if (nd == 2 || (data_idx > 1 && !view_map))
1374       fputs (plot_stream, "set pm3d implicit;\n");
1375     else
1376       fputs (plot_stream, "set pm3d explicit;\n");
1377     endif
1378
1379     if (isnan(hidden_removal) || hidden_removal)
1380       fputs (plot_stream, "set hidden3d;\n");
1381     else
1382       fputs (plot_stream, "unset hidden3d;\n");
1383     endif
1384
1385     have_data = (! (isempty (data) || all (cellfun ("isempty", data))));
1386
1387     ## Note we don't use the [xy]2range of gnuplot as we don't use the
1388     ## dual axis plotting features of gnuplot.
1389     if (isempty (xlim))
1390       return;
1391     endif
1392     if (strcmpi (axis_obj.xdir, "reverse"))
1393       xdir = "reverse";
1394     else
1395       xdir = "noreverse";
1396     endif
1397     fprintf (plot_stream, "set xrange [%.15e:%.15e] %s;\n", xlim, xdir);
1398     if (strcmpi (axis_obj.xaxislocation, "top"))
1399       fprintf (plot_stream, "set x2range [%.15e:%.15e] %s;\n", xlim, xdir);
1400     endif
1401
1402     if (isempty (ylim))
1403       return;
1404     endif
1405     if (strcmpi (axis_obj.ydir, "reverse"))
1406       ydir = "reverse";
1407     else
1408       ydir = "noreverse";
1409     endif
1410     fprintf (plot_stream, "set yrange [%.15e:%.15e] %s;\n", ylim, ydir);
1411     if (strcmpi (axis_obj.yaxislocation, "right"))
1412       fprintf (plot_stream, "set y2range [%.15e:%.15e] %s;\n", ylim, ydir);
1413     endif
1414
1415     if (nd == 3)
1416       if (isempty (zlim))
1417         return;
1418       endif
1419       if (strcmpi (axis_obj.zdir, "reverse"))
1420         zdir = "reverse";
1421       else
1422         zdir = "noreverse";
1423       endif
1424       fprintf (plot_stream, "set zrange [%.15e:%.15e] %s;\n", zlim, zdir);
1425     endif
1426
1427     cmap = parent_figure_obj.colormap;
1428     cmap_sz = rows(cmap);
1429     if (! any (isinf (clim)))
1430       if (truecolor || ! cdatadirect)
1431         if (rows(addedcmap) > 0)
1432           for i = 1:data_idx
1433             if (have_3d_patch(i))
1434               data{i}(end,:) = clim(2) * (data{i}(end, :) - 0.5) / cmap_sz;
1435              endif
1436           endfor
1437           fprintf (plot_stream, "set cbrange [%g:%g];\n", clim(1), clim(2) *
1438                    (cmap_sz + rows(addedcmap)) / cmap_sz);
1439         else
1440           fprintf (plot_stream, "set cbrange [%g:%g];\n", clim);
1441         endif
1442       else
1443         fprintf (plot_stream, "set cbrange [1:%d];\n", cmap_sz +
1444                  rows (addedcmap));
1445       endif
1446     endif
1447
1448     if (strcmpi (axis_obj.box, "on"))
1449       if (nd == 3)
1450         fputs (plot_stream, "set border 4095;\n");
1451       else
1452         fputs (plot_stream, "set border 431;\n");
1453       endif
1454     else
1455       if (nd == 3)
1456         fputs (plot_stream, "set border 895;\n");
1457       elseif (! isempty (axis_obj.ytick))
1458         if (strcmpi (axis_obj.yaxislocation, "right"))
1459           fprintf (plot_stream, "unset ytics; set y2tics %s nomirror\n",
1460                    axis_obj.tickdir);
1461           if (strcmpi (axis_obj.xaxislocation, "top"))
1462             fprintf (plot_stream, "unset xtics; set x2tics %s nomirror\n",
1463                      axis_obj.tickdir);
1464             fputs (plot_stream, "set border 12;\n");
1465           elseif (strcmpi (axis_obj.xaxislocation, "bottom"))
1466             fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
1467                      axis_obj.tickdir);
1468             fputs (plot_stream, "set border 9;\n");
1469           else # xaxislocation == zero
1470             fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
1471                      axis_obj.tickdir);
1472             fputs (plot_stream, "set border 8;\n");
1473             fprintf (plot_stream, "set xzeroaxis lt -1 lw %f;\n",
1474                      axis_obj.linewidth);
1475           endif
1476         elseif (strcmpi (axis_obj.yaxislocation, "left"))
1477           fprintf (plot_stream, "unset y2tics; set ytics %s nomirror\n",
1478                    axis_obj.tickdir);
1479           if (strcmpi (axis_obj.xaxislocation, "top"))
1480             fprintf (plot_stream, "unset xtics; set x2tics %s nomirror\n",
1481                      axis_obj.tickdir);
1482             fputs (plot_stream, "set border 6;\n");
1483           elseif (strcmpi (axis_obj.xaxislocation, "bottom"))
1484             fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
1485                      axis_obj.tickdir);
1486             fputs (plot_stream, "set border 3;\n");
1487           else # xaxislocation == zero
1488             fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
1489                      axis_obj.tickdir);
1490             fputs (plot_stream, "set border 2;\n");
1491             fprintf (plot_stream, "set xzeroaxis lt -1 lw %f;\n",
1492                      axis_obj.linewidth);
1493           endif
1494         else # yaxislocation == zero
1495           fprintf (plot_stream, "unset y2tics; set ytics %s nomirror\n",
1496                    axis_obj.tickdir);
1497           if (strcmpi (axis_obj.xaxislocation, "top"))
1498             fprintf (plot_stream, "unset xtics; set x2tics %s nomirror\n",
1499                      axis_obj.tickdir);
1500             fputs (plot_stream, "set border 4;\n");
1501           elseif (strcmpi (axis_obj.xaxislocation, "bottom"))
1502             fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
1503                      axis_obj.tickdir);
1504             fputs (plot_stream, "set border 1;\n");
1505           else # xaxislocation == zero
1506             fprintf (plot_stream, "unset y2tics; set ytics %s nomirror\n",
1507                      axis_obj.tickdir);
1508             fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
1509                      axis_obj.tickdir);
1510             fputs (plot_stream, "unset border;\n");
1511             fprintf (plot_stream, "set xzeroaxis lt -1 lw %f;\n",
1512                      axis_obj.linewidth);
1513           endif
1514           fprintf (plot_stream, "set yzeroaxis lt -1 lw %f;\n",
1515                    axis_obj.linewidth);
1516         endif
1517       endif
1518     endif
1519
1520     if (strcmpi (axis_obj.visible, "off"))
1521       fputs (plot_stream, "unset border; unset tics\n");
1522     else
1523       fprintf (plot_stream, "set border lw %f;\n", axis_obj.linewidth);
1524     endif
1525
1526     if (! isempty (hlgnd) && ! isempty (hlgnd.children)
1527         && any (strcmpi (get (hlgnd.children, "visible"), "on")))
1528       if (strcmpi (hlgnd.box, "on"))
1529         box = "box";
1530       else
1531         box = "nobox";
1532       endif
1533       if (strcmpi (hlgnd.orientation, "vertical"))
1534         horzvert = "vertical";
1535       else
1536         horzvert = "horizontal";
1537       endif
1538       if (strcmpi (hlgnd.textposition, "right"))
1539         reverse = "reverse";
1540       else
1541         reverse = "noreverse";
1542       endif
1543       inout = "inside";
1544       keypos = hlgnd.location;
1545       if (ischar (keypos))
1546         keypos = lower (keypos);
1547         keyout = findstr (keypos, "outside");
1548         if (! isempty (keyout))
1549           inout = "outside";
1550           keypos = keypos(1:keyout-1);
1551         endif
1552       endif
1553       switch (keypos)
1554         case "north"
1555           pos = "center top";
1556         case "south"
1557           pos = "center bottom";
1558         case "east"
1559           pos = "right center";
1560         case "west"
1561           pos = "left center";
1562         case "northeast"
1563           pos = "right top";
1564         case "northwest"
1565           pos = "left top";
1566         case "southeast"
1567           pos = "right bottom";
1568         case "southwest"
1569           pos = "left bottom";
1570         case "best"
1571           pos = "";
1572           warning ("legend: 'Best' not yet implemented for location specifier.\n");
1573           ## Least conflict with data in plot.
1574           ## Least unused space outside plot.
1575         otherwise
1576           pos = "";
1577       endswitch
1578       if (__gnuplot_has_feature__ ("key_has_font_properties"))
1579         [fontname, fontsize] = get_fontname_and_size (hlgnd);
1580         fontspec = create_fontspec (fontname, fontsize, gnuplot_term);
1581       else
1582         fontspec = "";
1583       endif
1584       fprintf (plot_stream, "set key %s %s;\nset key %s %s %s %s;\n",
1585                inout, pos, box, reverse, horzvert, fontspec);
1586     else
1587       fputs (plot_stream, "unset key;\n");
1588     endif
1589     fputs (plot_stream, "set style data lines;\n");
1590
1591     cmap = [cmap; addedcmap];
1592     cmap_sz = cmap_sz + rows(addedcmap);
1593     if (length(cmap) > 0)
1594       fprintf (plot_stream,
1595                "set palette positive color model RGB maxcolors %i;\n",
1596                cmap_sz);
1597       fprintf (plot_stream,
1598                "set palette file \"-\" binary record=%d using 1:2:3:4;\n",
1599                cmap_sz);
1600       fwrite (plot_stream, [1:cmap_sz; cmap.'], "float32");
1601       fwrite (plot_stream, "\n");
1602     endif
1603
1604     fputs (plot_stream, "unset colorbox;\n");
1605
1606     if (have_data)
1607       if (nd == 2)
1608         plot_cmd = "plot";
1609       else
1610         plot_cmd = "splot";
1611         rot_x = 90 - axis_obj.view(2);
1612         rot_z = axis_obj.view(1);
1613         while (rot_z < 0)
1614           rot_z += 360;
1615         endwhile
1616         fputs (plot_stream, "set ticslevel 0;\n");
1617         if (view_map && rot_x == 0 && rot_z == 0)
1618           fputs (plot_stream, "set view map;\n");
1619         else
1620           fprintf (plot_stream, "set view %.15g, %.15g;\n", rot_x, rot_z);
1621         endif
1622       endif
1623       if (have_3d_patch (1))
1624         fputs (plot_stream, "set pm3d depthorder\n");
1625         fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", plot_cmd,
1626                  usingclause{1}, titlespec{1}, withclause{1});
1627       elseif (is_image_data (1))
1628         if (numel (is_image_data) > 1 && is_image_data(2))
1629           ## Remove terminating semicolon
1630           n = max (strfind (withclause{1}, ";"));
1631           if (! isempty(n))
1632             withclause{1} = withclause{1}(1:n-1);
1633           endif
1634         endif
1635         fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", plot_cmd,
1636                  usingclause{1}, titlespec{1}, withclause{1});
1637       else
1638         fprintf (plot_stream, "%s \"-\" binary format='%%float64' %s %s %s \\\n", plot_cmd,
1639                  usingclause{1}, titlespec{1}, withclause{1});
1640       endif
1641       for i = 2:data_idx
1642         if (have_3d_patch (i))
1643           fprintf (plot_stream, ", \"-\" %s %s %s \\\n",
1644                    usingclause{i}, titlespec{i}, withclause{i});
1645         elseif (is_image_data (i))
1646           if (! is_image_data (i-1))
1647             fputs (plot_stream, "; ");
1648             if (bg_is_set)
1649               fputs (plot_stream, "unset obj 1; \\\n");
1650               bg_is_set = false;
1651             endif
1652             if (fg_is_set)
1653               fputs (plot_stream, "unset obj 2; \\\n");
1654               fg_is_set = false;
1655             endif
1656             if (numel (is_image_data) > i && is_image_data(i+1))
1657               ## Remove terminating semicolon
1658               n = max (strfind (withclause{i}, ";"));
1659               if (! isempty(n))
1660                 withclause{i} = withclause{i}(1:n-1);
1661               endif
1662             endif
1663             fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", plot_cmd,
1664                      usingclause{i}, titlespec{i}, withclause{i});
1665           else
1666             ## For consecutive images continue with the same plot command
1667             fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", ",",
1668                      usingclause{i}, titlespec{i}, withclause{i});
1669           endif
1670         elseif (is_image_data (i-1))
1671           if (bg_is_set)
1672             fputs (plot_stream, "unset obj 1; \\\n");
1673             bg_is_set = false;
1674           endif
1675           if (fg_is_set)
1676             fputs (plot_stream, "unset obj 2; \\\n");
1677             fg_is_set = false;
1678           endif
1679           fprintf (plot_stream, "%s \"-\" binary format='%%float64' %s %s %s \\\n", plot_cmd,
1680                    usingclause{i}, titlespec{i}, withclause{i});
1681         else
1682           fprintf (plot_stream, ", \"-\" binary format='%%float64' %s %s %s \\\n",
1683                    usingclause{i}, titlespec{i}, withclause{i});
1684         endif
1685       endfor
1686       fputs (plot_stream, ";\n");
1687       for i = 1:data_idx
1688         if (have_3d_patch (i))
1689           ## Can't write 3d patch data as binary as can't plot more than
1690           ## a single patch at a time and have to plot all patches together
1691           ## so that the gnuplot depth ordering is done correctly
1692           for j = 1 : 4 : columns(data{i})
1693             if (j != 1)
1694               fputs (plot_stream, "\n\n");
1695             endif
1696             fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data{i}(:,j).');
1697             fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n\n", data{i}(:,j+1).');
1698             fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data{i}(:,j+2).');
1699             fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data{i}(:,j+3).');
1700           endfor
1701           fputs (plot_stream, "e\n");
1702         elseif (is_image_data(i))
1703           fwrite (plot_stream, data{i}, "float32");
1704         else
1705           __gnuplot_write_data__ (plot_stream, data{i}, nd, parametric(i),
1706                                   have_cdata(i));
1707         endif
1708       endfor
1709     else
1710       fputs (plot_stream, "plot \"-\";\nInf Inf\ne\n");
1711     endif
1712
1713     ## Needed to allow mouse rotation with pcolor.
1714     if (view_map)
1715       fputs (plot_stream, "unset view;\n");
1716     endif
1717
1718     if (bg_is_set)
1719       fputs (plot_stream, "unset obj 1;\n");
1720       bg_is_set = false;
1721     endif
1722
1723     fflush (plot_stream);
1724
1725   else
1726     print_usage ();
1727   endif
1728
1729 endfunction
1730
1731 function x = flip (x)
1732   if (size (x, 1) == 1)
1733     x = fliplr (x);
1734   elseif (size (x, 2) == 1 || ischar (x))
1735     x = flipud (x);
1736   else
1737     x = flipud (fliplr (x));
1738   endif
1739 endfunction
1740
1741 function fontspec = create_fontspec (f, s, gp_term)
1742   if (strcmp (f, "*") || strcmp (gp_term, "tikz"))
1743     fontspec = sprintf ("font \",%d\"", s);
1744   else
1745     fontspec = sprintf ("font \"%s,%d\"", f, s);
1746   endif
1747 endfunction
1748
1749 function style = do_linestyle_command (obj, linecolor, idx, mono,
1750                                        plot_stream, errbars = "")
1751   style = {};
1752
1753   fprintf (plot_stream, "set style line %d default;\n", idx);
1754   fprintf (plot_stream, "set style line %d", idx);
1755
1756   found_style = false;
1757   if (isnumeric (linecolor))
1758     color = linecolor;
1759     if (! mono)
1760       fprintf (plot_stream, " linecolor rgb \"#%02x%02x%02x\"",
1761                round (255*color));
1762     endif
1763   else
1764     color = [0, 0, 0];
1765   endif
1766
1767   if (isfield (obj, "linestyle"))
1768     switch (obj.linestyle)
1769       case "-"
1770         lt = "1";
1771       case "--"
1772         lt = "2";
1773       case ":"
1774         lt = "3";
1775       case "-."
1776         lt = "6";
1777       case "none"
1778         lt = "";
1779       otherwise
1780         lt = "";
1781     endswitch
1782
1783     if (! isempty (lt))
1784       fprintf (plot_stream, " linetype %s", lt);
1785     endif
1786
1787   else
1788     lt = "";
1789   endif
1790   if (! isempty (errbars))
1791     found_style = true;
1792   endif
1793
1794   if (isfield (obj, "linewidth"))
1795     fprintf (plot_stream, " linewidth %f", obj.linewidth);
1796     found_style = true;
1797   endif
1798
1799   [pt, pt2, obj] = gnuplot_pointtype (obj);
1800
1801   if (! isempty (pt))
1802     found_style = true;
1803   endif
1804
1805   sidx = 1;
1806   if (isempty (errbars))
1807     if (isempty (lt))
1808       style {sidx} = "";
1809     else
1810       style {sidx} = "lines";
1811     endif
1812
1813     facesame = true;
1814     if (! isequal (pt, pt2) && isfield (obj, "markerfacecolor")
1815         && !strncmp (obj.markerfacecolor, "none", 4))
1816       if (strncmp (obj.markerfacecolor, "auto", 4)
1817           || ! isnumeric (obj.markerfacecolor)
1818           || (isnumeric (obj.markerfacecolor)
1819               && isequal (color, obj.markerfacecolor)))
1820         if (! isempty (pt2))
1821           fprintf (plot_stream, " pointtype %s", pt2);
1822           style {sidx} = strcat (style{sidx}, "points");
1823         endif
1824         if (isfield (obj, "markersize"))
1825           fprintf (plot_stream, " pointsize %f", obj.markersize / 3);
1826         endif
1827       else
1828         facesame = false;
1829         if (! found_style)
1830           fputs (plot_stream, " default");
1831         endif
1832         fputs (plot_stream, ";\n");
1833         if (! isempty (style {sidx}))
1834           sidx ++;
1835           idx ++;
1836         else
1837           fputs (plot_stream, ";\n");
1838         endif
1839         fprintf (plot_stream, "set style line %d default;\n", idx);
1840         fprintf (plot_stream, "set style line %d", idx);
1841         if (isnumeric (obj.markerfacecolor) && ! mono)
1842           fprintf (plot_stream, " linecolor rgb \"#%02x%02x%02x\"",
1843                    round (255*obj.markerfacecolor));
1844         endif
1845         if (! isempty (pt2))
1846           style {sidx} = "points";
1847           fprintf (plot_stream, " pointtype %s", pt2);
1848         endif
1849         if (isfield (obj, "markersize"))
1850           fprintf (plot_stream, " pointsize %f", obj.markersize / 3);
1851         endif
1852       endif
1853     endif
1854     if (isfield (obj, "markeredgecolor")
1855         && !strncmp (obj.markeredgecolor, "none", 4))
1856       if (facesame && !isempty (pt)
1857           && (strncmp (obj.markeredgecolor, "auto", 4)
1858               || ! isnumeric (obj.markeredgecolor)
1859               || (isnumeric (obj.markeredgecolor)
1860                   && isequal (color, obj.markeredgecolor))))
1861         if (sidx == 1 && ((length (style {sidx}) == 5
1862             && strncmp (style {sidx}, "lines", 5)) || isempty (style {sidx})))
1863           if (! isempty (pt))
1864             style {sidx} = strcat (style{sidx}, "points");
1865             fprintf (plot_stream, " pointtype %s", pt);
1866           endif
1867           if (isfield (obj, "markersize"))
1868             fprintf (plot_stream, " pointsize %f", obj.markersize / 3);
1869           endif
1870         endif
1871       else
1872         if (! found_style)
1873           fputs (plot_stream, " default");
1874         endif
1875         fputs (plot_stream, ";\n");
1876         if (!isempty (style {sidx}))
1877           sidx ++;
1878           idx ++;
1879         else
1880           fputs (plot_stream, ";\n");
1881         endif
1882         fprintf (plot_stream, "set style line %d default;\n", idx);
1883         fprintf (plot_stream, "set style line %d", idx);
1884         if (! mono)
1885           if (strncmp (obj.markeredgecolor, "auto", 4))
1886             fprintf (plot_stream, " linecolor rgb \"#%02x%02x%02x\"",
1887                      round (255*color));
1888           elseif (isnumeric (obj.markeredgecolor) && ! mono)
1889             fprintf (plot_stream, " linecolor rgb \"#%02x%02x%02x\"",
1890                      round (255*obj.markeredgecolor));
1891           endif
1892         endif
1893         if (! isempty (pt))
1894           style {sidx} = "points";
1895           fprintf (plot_stream, " pointtype %s", pt);
1896         endif
1897         if (isfield (obj, "markersize"))
1898           fprintf (plot_stream, " pointsize %f", obj.markersize / 3);
1899         endif
1900       endif
1901     endif
1902   else
1903     style{1} = errbars;
1904     fputs (plot_stream, " pointtype 0");
1905   endif
1906
1907   if (! found_style && isempty (style {1}))
1908     fputs (plot_stream, " default");
1909   endif
1910
1911   fputs (plot_stream, ";\n");
1912
1913 endfunction
1914
1915 function [pt, pt2, obj] = gnuplot_pointtype (obj)
1916   if (isfield (obj, "marker"))
1917     switch (obj.marker)
1918       case "+"
1919         pt = pt2 = "1";
1920       case "o"
1921         pt = "6";
1922         pt2 = "7";
1923       case "*"
1924         pt = pt2 = "3";
1925       case "."
1926         pt = "6";
1927         pt2 = "7";
1928         if (isfield (obj, "markerfacecolor")
1929             || strncmp (obj.markerfacecolor, "none", 4))
1930           obj.markerfacecolor = "auto";
1931         endif
1932         if (isfield (obj, "markersize"))
1933           obj.markersize /= 3;
1934         else
1935           obj.markersize = 5;
1936         endif
1937       case "x"
1938         pt = pt2 = "2";
1939       case {"square", "s"}
1940         pt = "4";
1941         pt2 = "5";
1942       case {"diamond", "d"}
1943         pt = "12";
1944         pt2 = "13";
1945       case "^"
1946         pt = "8";
1947         pt2 = "9";
1948       case "v"
1949         pt = "10";
1950         pt2 = "11";
1951       case ">"
1952         ## FIXME -- should be triangle pointing right, use triangle pointing up
1953         pt = "8";
1954         pt2 = "9";
1955       case "<"
1956         ## FIXME -- should be triangle pointing left, use triangle pointing down
1957         pt = "10";
1958         pt2 = "11";
1959       case {"pentagram", "p"}
1960         ## FIXME -- should be pentagram, using pentagon
1961         pt = "14";
1962         pt2 = "15";
1963       case {"hexagram", "h"}
1964         ## FIXME -- should be 6 pt start, using "*" instead
1965         pt = pt2 = "3";
1966       case "none"
1967         pt = pt2 = "";
1968       otherwise
1969         pt = pt2 = "";
1970     endswitch
1971   else
1972     pt = pt2 = "";
1973   endif
1974 endfunction
1975
1976 function __gnuplot_write_data__ (plot_stream, data, nd, parametric, cdata)
1977
1978   ## DATA is already transposed.
1979
1980   ## FIXME -- this may need to be converted to C++ for speed.
1981
1982   ## Convert NA elements to normal NaN values because fprintf writes
1983   ## "NA" and that confuses gnuplot.
1984   idx = find (isna (data));
1985   if (any (idx))
1986     data(idx) = NaN;
1987   endif
1988
1989   if (nd == 2)
1990     fwrite (plot_stream, data, "float64");
1991   elseif (nd == 3)
1992     if (parametric)
1993       fwrite (plot_stream, data, "float64");
1994     else
1995       nr = rows (data);
1996       if (cdata)
1997         for j = 1:4:nr
1998           fwrite (plot_stream, data(j:j+3,:), "float64");
1999         endfor
2000       else
2001         for j = 1:3:nr
2002           fwrite (plot_stream, data(j:j+2,:), "float64");
2003         endfor
2004       endif
2005     endif
2006   endif
2007
2008 endfunction
2009
2010 function do_tics (obj, plot_stream, ymirror, mono, gnuplot_term)
2011
2012   obj.xticklabel = ticklabel_to_cell (obj.xticklabel);
2013   obj.yticklabel = ticklabel_to_cell (obj.yticklabel);
2014   obj.zticklabel = ticklabel_to_cell (obj.zticklabel);
2015
2016   if (strcmp (obj.xminorgrid, "on"))
2017     obj.xminortick = "on";
2018   endif
2019   if (strcmp (obj.yminorgrid, "on"))
2020     obj.yminortick = "on";
2021   endif
2022   if (strcmp (obj.zminorgrid, "on"))
2023     obj.zminortick = "on";
2024   endif
2025
2026   [fontname, fontsize] = get_fontname_and_size (obj);
2027   fontspec = create_fontspec (fontname, fontsize, gnuplot_term);
2028
2029   ## A Gnuplot tic scale of 69 is equivalent to Octave's 0.5.
2030   ticklength = sprintf ("scale %4.1f", (69/0.5)*obj.ticklength(1));
2031
2032   if (strcmpi (obj.xaxislocation, "top"))
2033     do_tics_1 (obj.xtickmode, obj.xtick, obj.xminortick, obj.xticklabelmode,
2034                obj.xticklabel, obj.xcolor, "x2", plot_stream, true, mono,
2035                "border", obj.tickdir, ticklength, fontname, fontspec,
2036                obj.interpreter, obj.xscale, obj.xsgn, gnuplot_term);
2037     do_tics_1 ("manual", [], "off", obj.xticklabelmode, obj.xticklabel,
2038                obj.xcolor, "x", plot_stream, true, mono, "border",
2039                "", "", fontname, fontspec, obj.interpreter, obj.xscale,
2040                obj.xsgn, gnuplot_term);
2041   elseif (strcmpi (obj.xaxislocation, "zero"))
2042     do_tics_1 (obj.xtickmode, obj.xtick, obj.xminortick, obj.xticklabelmode,
2043                obj.xticklabel, obj.xcolor, "x", plot_stream, true, mono,
2044                "axis", obj.tickdir, ticklength, fontname, fontspec,
2045                obj.interpreter, obj.xscale, obj.xsgn, gnuplot_term);
2046     do_tics_1 ("manual", [], "off", obj.xticklabelmode, obj.xticklabel,
2047                obj.xcolor, "x2", plot_stream, true, mono, "axis",
2048                "", "", fontname, fontspec, obj.interpreter, obj.xscale,
2049                obj.xsgn, gnuplot_term);
2050   else
2051     do_tics_1 (obj.xtickmode, obj.xtick, obj.xminortick, obj.xticklabelmode,
2052                obj.xticklabel, obj.xcolor, "x", plot_stream, true, mono,
2053                "border", obj.tickdir, ticklength, fontname, fontspec,
2054                obj.interpreter, obj.xscale, obj.xsgn, gnuplot_term);
2055     do_tics_1 ("manual", [], "off", obj.xticklabelmode, obj.xticklabel,
2056                obj.xcolor, "x2", plot_stream, true, mono, "border",
2057                "", "", fontname, fontspec, obj.interpreter, obj.xscale,
2058                obj.xsgn, gnuplot_term);
2059   endif
2060   if (strcmpi (obj.yaxislocation, "right"))
2061     do_tics_1 (obj.ytickmode, obj.ytick, obj.yminortick, obj.yticklabelmode,
2062                obj.yticklabel, obj.ycolor, "y2", plot_stream, ymirror, mono,
2063                "border", obj.tickdir, ticklength, fontname, fontspec,
2064                obj.interpreter, obj.yscale, obj.ysgn, gnuplot_term);
2065     do_tics_1 ("manual", [], "off", obj.yticklabelmode, obj.yticklabel,
2066                obj.ycolor, "y", plot_stream, ymirror, mono, "border",
2067                "", "", fontname, fontspec, obj.interpreter, obj.yscale,
2068                obj.ysgn, gnuplot_term);
2069   elseif (strcmpi (obj.yaxislocation, "zero"))
2070     do_tics_1 (obj.ytickmode, obj.ytick, obj.yminortick, obj.yticklabelmode,
2071                obj.yticklabel, obj.ycolor, "y", plot_stream, ymirror, mono,
2072                "axis", obj.tickdir, ticklength, fontname, fontspec,
2073                obj.interpreter, obj.yscale, obj.ysgn, gnuplot_term);
2074     do_tics_1 ("manual", [], "off", obj.yticklabelmode, obj.yticklabel,
2075                obj.ycolor, "y2", plot_stream, ymirror, mono, "axis",
2076                "", "", fontname, fontspec, obj.interpreter, obj.yscale,
2077                obj.ysgn, gnuplot_term);
2078   else
2079     do_tics_1 (obj.ytickmode, obj.ytick, obj.yminortick, obj.yticklabelmode,
2080                obj.yticklabel, obj.ycolor, "y", plot_stream, ymirror, mono,
2081                "border", obj.tickdir, ticklength, fontname, fontspec,
2082                obj.interpreter, obj.yscale, obj.ysgn, gnuplot_term);
2083     do_tics_1 ("manual", [], "off", obj.yticklabelmode, obj.yticklabel,
2084                obj.ycolor, "y2", plot_stream, ymirror, mono, "border",
2085                "", "", fontname, fontspec, obj.interpreter, obj.yscale,
2086                obj.ysgn, gnuplot_term);
2087   endif
2088   do_tics_1 (obj.ztickmode, obj.ztick, obj.zminortick, obj.zticklabelmode,
2089              obj.zticklabel, obj.zcolor, "z", plot_stream, true, mono,
2090              "border", obj.tickdir, ticklength, fontname, fontspec,
2091              obj.interpreter, obj.zscale, obj.zsgn, gnuplot_term);
2092 endfunction
2093
2094 function do_tics_1 (ticmode, tics, mtics, labelmode, labels, color, ax,
2095                     plot_stream, mirror, mono, axispos, tickdir, ticklength,
2096                     fontname, fontspec, interpreter, scale, sgn, gnuplot_term)
2097   persistent warned_latex = false;
2098   if (strcmpi (interpreter, "tex"))
2099     for n = 1 : numel(labels)
2100       labels{n} = __tex2enhanced__ (labels{n}, fontname, false, false);
2101     endfor
2102   elseif (strcmpi (interpreter, "latex"))
2103     if (! warned_latex)
2104       warning ("latex markup not supported for tick marks");
2105       warned_latex = true;
2106     endif
2107   endif
2108   if (strcmp (scale, "log"))
2109     num_mtics = 10;
2110     if (any (strcmp (gnuplot_term, {"tikz", "pstex", "pslatex", "epslatex"})))
2111       fmt = "$10^{%T}$";
2112     else
2113       fmt = "10^{%T}";
2114     endif
2115     if (sgn < 0)
2116       fmt = strcat ("-", fmt);
2117     endif
2118   else
2119     fmt = "%g";
2120     num_mtics = 5;
2121   endif
2122   colorspec = get_text_colorspec (color, mono);
2123   if (strcmpi (ticmode, "manual") || strcmpi (labelmode, "manual"))
2124     if (isempty (tics))
2125       fprintf (plot_stream, "unset %stics;\nunset m%stics;\n", ax, ax);
2126     elseif (strcmpi (labelmode, "manual"))
2127       if (ischar (labels))
2128         labels = cellstr (labels);
2129       endif
2130       if (isnumeric (labels))
2131         labels = num2str (real (labels(:)));
2132       endif
2133       if (ischar (labels))
2134         labels = permute (cellstr (labels), [2, 1]);
2135       endif
2136       if (iscellstr (labels))
2137         k = 1;
2138         ntics = numel (tics);
2139         nlabels = numel (labels);
2140         fprintf (plot_stream, "set format %s \"%%s\";\n", ax);
2141         if (mirror)
2142           fprintf (plot_stream, "set %stics %s %s %s mirror (", ax,
2143                    tickdir, ticklength, axispos);
2144         else
2145           fprintf (plot_stream, "set %stics %s %s %s nomirror (", ax,
2146                    tickdir, ticklength, axispos);
2147         endif
2148
2149         labels = regexprep(labels, '%', "%%");
2150         for i = 1:ntics
2151           fprintf (plot_stream, " \"%s\" %.15g", labels{k++}, tics(i));
2152           if (i < ntics)
2153             fputs (plot_stream, ", ");
2154           endif
2155           if (k > nlabels)
2156             k = 1;
2157           endif
2158         endfor
2159         fprintf (plot_stream, ") %s %s;\n", colorspec, fontspec);
2160         if (strcmp (mtics, "on"))
2161           fprintf (plot_stream, "set m%stics %d;\n", ax, num_mtics);
2162         else
2163           fprintf (plot_stream, "unset m%stics;\n", ax);
2164         endif
2165      else
2166         error ("__go_draw_axes__: unsupported type of ticklabel");
2167       endif
2168     else
2169       fprintf (plot_stream, "set format %s \"%s\";\n", ax, fmt);
2170       if (mirror)
2171         fprintf (plot_stream, "set %stics %s %s %s mirror (", ax, tickdir,
2172                  ticklength, axispos);
2173       else
2174         fprintf (plot_stream, "set %stics %s %s %s nomirror (", ax, tickdir,
2175                  ticklength, axispos);
2176       endif
2177       fprintf (plot_stream, " %.15g,", tics(1:end-1));
2178       fprintf (plot_stream, " %.15g) %s;\n", tics(end), fontspec);
2179       if (strcmp (mtics, "on"))
2180         fprintf (plot_stream, "set m%stics %d;\n", ax, num_mtics);
2181       else
2182         fprintf (plot_stream, "unset m%stics;\n", ax);
2183       endif
2184     endif
2185   else
2186     fprintf (plot_stream, "set format %s \"%s\";\n", ax, fmt);
2187     if (mirror)
2188       fprintf (plot_stream, "set %stics %s %s %s mirror %s %s;\n", ax,
2189                axispos, tickdir, ticklength, colorspec, fontspec);
2190     else
2191       fprintf (plot_stream, "set %stics %s %s %s nomirror %s %s;\n", ax,
2192                tickdir, ticklength, axispos, colorspec, fontspec);
2193     endif
2194     if (strcmp (mtics, "on"))
2195       fprintf (plot_stream, "set m%stics %d;\n", ax, num_mtics);
2196     else
2197       fprintf (plot_stream, "unset m%stics;\n", ax);
2198     endif
2199   endif
2200 endfunction
2201
2202 function ticklabel = ticklabel_to_cell (ticklabel)
2203   if (isnumeric (ticklabel))
2204     ## Use upto 5 significant digits
2205     ticklabel = num2str (ticklabel(:), 5);
2206   endif
2207   if (ischar (ticklabel))
2208     if (size (ticklabel, 1) == 1 && any (ticklabel == "|"))
2209       n = setdiff (findstr (ticklabel, "|"), findstr (ticklabel, '\|'));
2210       ticklabel = strsplit (ticklabel, "|");
2211     else
2212       ticklabel = cellstr (ticklabel);
2213     endif
2214   elseif (isempty (ticklabel))
2215     ticklabel = {""};
2216   else
2217     ticklabel = ticklabel;
2218   endif
2219 endfunction
2220
2221 function colorspec = get_text_colorspec (color, mono)
2222   if (mono)
2223     colorspec = "";
2224   else
2225     colorspec = sprintf ("textcolor rgb \"#%02x%02x%02x\"",
2226                          round (255*color));
2227   endif
2228 endfunction
2229
2230 function [f, s, fnt, it, bld] = get_fontname_and_size (t)
2231   if (isempty (t.fontname) || strcmp (t.fontname, "*"))
2232     fnt = "{}";
2233   else
2234     fnt = t.fontname;
2235   endif
2236   f = fnt;
2237   it = false;
2238   bld = false;
2239   if (! isempty (t.fontweight) && strcmpi (t.fontweight, "bold"))
2240     if (! isempty(t.fontangle)
2241         && (strcmpi (t.fontangle, "italic")
2242             || strcmpi (t.fontangle, "oblique")))
2243       f = cstrcat (f, "-bolditalic");
2244       it = true;
2245       bld = true;
2246     else
2247       f = cstrcat (f, "-bold");
2248       bld = true;
2249     endif
2250   elseif (! isempty(t.fontangle)
2251           && (strcmpi (t.fontangle, "italic")
2252               || strcmpi (t.fontangle, "oblique")))
2253     f = cstrcat (f, "-italic");
2254     it = true;
2255   endif
2256   if (isempty (t.fontsize))
2257     s = 10;
2258   else
2259     s = t.fontsize;
2260   endif
2261 endfunction
2262
2263 function [str, f, s] = __maybe_munge_text__ (enhanced, obj, fld)
2264
2265   persistent warned_latex = false;
2266
2267   if (strcmp (fld, "string"))
2268     [f, s, fnt, it, bld] = get_fontname_and_size (obj);
2269   else
2270     f = "Helvetica";
2271     s = 10;
2272     fnt = f;
2273     it = false;
2274     bld = false;
2275   endif
2276
2277   ## The text object maybe multiline, and may be of any class
2278   str = getfield (obj, fld);
2279   if (ischar (str) && size (str, 1) > 1)
2280     str = cellstr (str);
2281   elseif (isnumeric (str))
2282     str = cellstr (num2str (str(:)));
2283   endif
2284   if (iscellstr (str))
2285     for n = 1:numel(str)
2286       if (isnumeric (str{n}))
2287         str{n} = num2str (str{n});
2288       endif
2289     endfor
2290     str = sprintf ("%s\n", str{:})(1:end-1);
2291   endif
2292
2293   if (enhanced)
2294     if (strcmpi (obj.interpreter, "tex"))
2295       if (iscellstr (str))
2296         for n = 1:numel(str)
2297           str{n} = __tex2enhanced__ (str{n}, fnt, it, bld);
2298         endfor
2299       else
2300         str = __tex2enhanced__ (str, fnt, it, bld);
2301       endif
2302     elseif (strcmpi (obj.interpreter, "latex"))
2303       if (! warned_latex)
2304         warning ("latex markup not supported for text objects");
2305         warned_latex = true;
2306       endif
2307     elseif (enhanced)
2308       str = no_super_sub_scripts (str);
2309     endif
2310   endif
2311 endfunction
2312
2313 function str = no_super_sub_scripts (str)
2314   if (iscellstr (str))
2315     labels = str;
2316   else
2317     labels = cellstr (str);
2318   endif
2319   for marker = "_^" 
2320     for m = 1 : numel(labels)
2321       n1 = strfind (labels{m}, sprintf ("\\%s", marker));
2322       n2 = strfind (labels{m}, marker);
2323       if (! isempty (n1))
2324         n1 = n1 + 1;
2325         n2 = setdiff (n2, n1);
2326       end
2327       for n = numel(n2):-1:1
2328         labels{m} = [labels{m}(1:n2(n)-1), "\\", labels{m}(n2(n):end)]
2329       endfor
2330     endfor
2331   endfor
2332   if (iscellstr (str))
2333     str = labels;
2334   else
2335     str = char (labels);
2336   endif
2337 endfunction
2338
2339 function str = __tex2enhanced__ (str, fnt, it, bld)
2340   persistent sym = __setup_sym_table__ ();
2341   persistent flds = fieldnames (sym);
2342
2343   [s, e, m] = regexp(str,'\\([a-zA-Z]+|0)','start','end','matches');
2344
2345   for i = length (s) : -1 : 1
2346     ## special case for "\0"  and replace with "{/Symbol \306}'
2347     if (strncmp (m{i}, '\0', 2))
2348       str = cstrcat (str(1:s(i) - 1), '{/Symbol \306}', str(s(i) + 2:end));
2349     else
2350       f = m{i}(2:end);
2351       if (isfield (sym, f))
2352         g = getfield(sym, f);
2353         ## FIXME The symbol font doesn't seem to support bold or italic
2354         ##if (bld)
2355         ##  if (it)
2356         ##    g = regexprep (g, '/Symbol', '/Symbol-bolditalic');
2357         ##  else
2358         ##    g = regexprep (g, '/Symbol', '/Symbol-bold');
2359         ##  endif
2360         ##elseif (it)
2361         ##  g = regexprep (g, '/Symbol', '/Symbol-italic');
2362         ##endif
2363         str = cstrcat (str(1:s(i) - 1), g, str(e(i) + 1:end));
2364       elseif (strncmp (f, "rm", 2))
2365         bld = false;
2366         it = false;
2367         str = cstrcat (str(1:s(i) - 1), '/', fnt, ' ', str(s(i) + 3:end));
2368       elseif (strncmp (f, "it", 2) || strncmp (f, "sl", 2))
2369         it = true;
2370         if (bld)
2371           str = cstrcat (str(1:s(i) - 1), '/', fnt, '-bolditalic ',
2372                         str(s(i) + 3:end));
2373         else
2374           str = cstrcat (str(1:s(i) - 1), '/', fnt, '-italic ',
2375                         str(s(i) + 3:end));
2376         endif
2377       elseif (strncmp (f, "bf", 2))
2378         bld = true;
2379         if (it)
2380           str = cstrcat (str(1:s(i) - 1), '/', fnt, '-bolditalic ',
2381                         str(2(i) + 3:end));
2382         else
2383           str = cstrcat (str(1:s(i) - 1), '/', fnt, '-bold ',
2384                         str(s(i) + 3:end));
2385         endif
2386       elseif (strcmpi (f, "color"))
2387         ## FIXME Ignore \color but remove trailing {} block as well
2388         d = strfind(str(e(i) + 1:end),'}');
2389         if (isempty (d))
2390           warning ('syntax error in \color argument');
2391         else
2392           str = cstrcat (str(1:s(i) - 1), str(e(i) + d + 1:end));
2393         endif
2394       elseif(strcmpi (f, "fontname"))
2395         b1 = strfind(str(e(i) + 1:end),'{');
2396         b2 = strfind(str(e(i) + 1:end),'}');
2397         if (isempty(b1) || isempty(b2))
2398           warning ('syntax error in \fontname argument');
2399         else
2400           str = cstrcat (str(1:s(i) - 1), '/',
2401                         str(e(i)+b1(1) + 1:e(i)+b2(1)-1), '{}',
2402                         str(e(i) + b2(1) + 1:end));
2403         endif
2404       elseif(strcmpi (f, "fontsize"))
2405         b1 = strfind(str(e(i) + 1:end),'{');
2406         b2 = strfind(str(e(i) + 1:end),'}');
2407         if (isempty(b1) || isempty(b2))
2408           warning ('syntax error in \fontname argument');
2409         else
2410           str = cstrcat (str(1:s(i) - 1), '/=',
2411                         str(e(i)+b1(1) + 1:e(i)+b2(1)-1), '{}',
2412                         str(e(i) + b2(1) + 1:end));
2413         endif
2414       else
2415         ## Last desperate attempt to treat the symbol. Look for things
2416         ## like \pix, that should be translated to the symbol Pi and x
2417         for j = 1 : length (flds)
2418           if (strncmp (flds{j}, f, length (flds{j})))
2419             g = getfield(sym, flds{j});
2420             ## FIXME The symbol font doesn't seem to support bold or italic
2421             ##if (bld)
2422             ##  if (it)
2423             ##    g = regexprep (g, '/Symbol', '/Symbol-bolditalic');
2424             ##  else
2425             ##    g = regexprep (g, '/Symbol', '/Symbol-bold');
2426             ##  endif
2427             ##elseif (it)
2428             ##  g = regexprep (g, '/Symbol', '/Symbol-italic');
2429             ##endif
2430             str = cstrcat (str(1:s(i) - 1), g,
2431                           str(s(i) + length (flds{j}) + 1:end));
2432             break;
2433           endif
2434         endfor
2435       endif
2436     endif
2437   endfor
2438
2439   ## Prepend @ to things  things like _0^x or _{-100}^{100} for
2440   ## alignment But need to put the shorter of the two arguments first.
2441   ## Carful of nested {} and unprinted characters when defining
2442   ## shortest.. Don't have to worry about things like ^\theta as they
2443   ## are already converted to ^{/Symbol q}.
2444
2445   ## FIXME -- This is a mess... Is it worth it just for a "@" character?
2446
2447   [s, m] = regexp(str,'[_\^]','start','matches');
2448   i = 1;
2449   p = 0;
2450   while (i < length (s))
2451     if (i < length(s))
2452       if (str(s(i) + p + 1) == "{")
2453         s1 = strfind(str(s(i) + p + 2:end),'{');
2454         si = 1;
2455         l1 = strfind(str(s(i) + p + 1:end),'}');
2456         li = 1;
2457         while (li <= length (l1) && si <= length (s1))
2458           if (l1(li) < s1(si))
2459             if (li == si)
2460               break;
2461             endif
2462             li++;
2463           else
2464             si++;
2465           endif
2466         endwhile
2467         l1 = l1 (min (length(l1), si));
2468         if (s(i) + l1 + 1 == s(i+1))
2469           if (str(s(i + 1) + p + 1) == "{")
2470             s2 = strfind(str(s(i + 1) + p + 2:end),'{');
2471             si = 1;
2472             l2 = strfind(str(s(i + 1) + p + 1:end),'}');
2473             li = 1;
2474             while (li <= length (l2) && si <= length (s2))
2475               if (l2(li) < s2(si))
2476                 if (li == si)
2477                   break;
2478                 endif
2479                 li++;
2480               else
2481                 si++;
2482               endif
2483             endwhile
2484             l2 = l2 (min (length(l2), si));
2485             if (length_string (str(s(i)+p+2:s(i)+p+l1-1)) <=
2486                 length_string(str(s(i+1)+p+2:s(i+1)+p+l2-1)))
2487               ## Shortest already first!
2488               str = cstrcat (str(1:s(i)+p-1), "@", str(s(i)+p:end));
2489             else
2490               ## Have to swap sub/super-script to get shortest first.
2491               str = cstrcat (str(1:s(i)+p-1), "@", str(s(i+1)+p:s(i+1)+p+l2),
2492                             str(s(i)+p:s(i)+p+l1), str(s(i+1)+p+l2+1:end));
2493             endif
2494           else
2495             ## Have to swap sub/super-script to get shortest first.
2496             str = cstrcat (str(1:s(i)+p-1), "@", str(s(i+1)+p:s(i+1)+p+1),
2497                           str(s(i)+p:s(i)+p+l1), str(s(i+1)+p+2:end));
2498           endif
2499           i += 2;
2500           p ++;
2501         else
2502           i++;
2503         endif
2504       else
2505         if (s(i+1) == s(i) + 2)
2506           ## Shortest already first!
2507           str = cstrcat (str(1:s(i)+p-1), "@", str(s(i)+p:end));
2508           p ++;
2509           i += 2;
2510         else
2511           i ++;
2512         endif
2513       endif
2514     else
2515       i ++;
2516     endif
2517   endwhile
2518
2519 endfunction
2520
2521 function l = length_string (s)
2522   l = length (s) - length (strfind(s,'{')) - length (strfind(s,'}'));
2523   m = regexp (s, '/([\w-]+|[\w-]+=\d+)', 'matches');
2524   if (!isempty (m))
2525     l = l - sum (cellfun ("length", m));
2526   endif
2527 endfunction
2528
2529 function sym = __setup_sym_table__ ()
2530   ## Setup the translation table for TeX to gnuplot enhanced mode.
2531   sym.forall = '{/Symbol \042}';
2532   sym.exists = '{/Symbol \044}';
2533   sym.ni = '{/Symbol \047}';
2534   sym.cong = '{/Symbol \100}';
2535   sym.Delta = '{/Symbol D}';
2536   sym.Phi = '{/Symbol F}';
2537   sym.Gamma = '{/Symbol G}';
2538   sym.vartheta = '{/Symbol J}';
2539   sym.Lambda = '{/Symbol L}';
2540   sym.Pi = '{/Symbol P}';
2541   sym.Theta = '{/Symbol Q}';
2542   sym.Sigma = '{/Symbol S}';
2543   sym.varsigma = '{/Symbol V}';
2544   sym.Omega = '{/Symbol W}';
2545   sym.Xi = '{/Symbol X}';
2546   sym.Psi = '{/Symbol Y}';
2547   sym.perp = '{/Symbol \136}';
2548   sym.alpha = '{/Symbol a}';
2549   sym.beta = '{/Symbol b}';
2550   sym.chi = '{/Symbol c}';
2551   sym.delta = '{/Symbol d}';
2552   sym.epsilon = '{/Symbol e}';
2553   sym.phi = '{/Symbol f}';
2554   sym.gamma = '{/Symbol g}';
2555   sym.eta = '{/Symbol h}';
2556   sym.iota = '{/Symbol i}';
2557   sym.varphi = '{/Symbol j}';
2558   sym.kappa = '{/Symbol k}';
2559   sym.lambda = '{/Symbol l}';
2560   sym.mu = '{/Symbol m}';
2561   sym.nu = '{/Symbol n}';
2562   sym.o =  '{/Symbol o}';
2563   sym.pi = '{/Symbol p}';
2564   sym.theta = '{/Symbol q}';
2565   sym.rho = '{/Symbol r}';
2566   sym.sigma = '{/Symbol s}';
2567   sym.tau = '{/Symbol t}';
2568   sym.upsilon = '{/Symbol u}';
2569   sym.varpi = '{/Symbol v}';
2570   sym.omega = '{/Symbol w}';
2571   sym.xi = '{/Symbol x}';
2572   sym.psi = '{/Symbol y}';
2573   sym.zeta = '{/Symbol z}';
2574   sym.sim = '{/Symbol \176}';
2575   sym.Upsilon = '{/Symbol \241}';
2576   sym.prime = '{/Symbol \242}';
2577   sym.leq = '{/Symbol \243}';
2578   sym.infty = '{/Symbol \245}';
2579   sym.clubsuit = '{/Symbol \247}';
2580   sym.diamondsuit = '{/Symbol \250}';
2581   sym.heartsuit = '{/Symbol \251}';
2582   sym.spadesuit = '{/Symbol \252}';
2583   sym.leftrightarrow = '{/Symbol \253}';
2584   sym.leftarrow = '{/Symbol \254}';
2585   sym.uparrow = '{/Symbol \255}';
2586   sym.rightarrow = '{/Symbol \256}';
2587   sym.downarrow = '{/Symbol \257}';
2588   sym.circ = '{/Symbol \260}';
2589   sym.pm = '{/Symbol \261}';
2590   sym.geq = '{/Symbol \263}';
2591   sym.times = '{/Symbol \264}';
2592   sym.propto = '{/Symbol \265}';
2593   sym.partial = '{/Symbol \266}';
2594   sym.bullet = '{/Symbol \267}';
2595   sym.div = '{/Symbol \270}';
2596   sym.neq = '{/Symbol \271}';
2597   sym.equiv = '{/Symbol \272}';
2598   sym.approx = '{/Symbol \273}';
2599   sym.ldots = '{/Symbol \274}';
2600   sym.mid = '{/Symbol \275}';
2601   sym.aleph = '{/Symbol \300}';
2602   sym.Im = '{/Symbol \301}';
2603   sym.Re = '{/Symbol \302}';
2604   sym.wp = '{/Symbol \303}';
2605   sym.otimes = '{/Symbol \304}';
2606   sym.oplus = '{/Symbol \305}';
2607   sym.oslash = '{/Symbol \306}';
2608   sym.cap = '{/Symbol \307}';
2609   sym.cup = '{/Symbol \310}';
2610   sym.supset = '{/Symbol \311}';
2611   sym.supseteq = '{/Symbol \312}';
2612   sym.subset = '{/Symbol \314}';
2613   sym.subseteq = '{/Symbol \315}';
2614   sym.in = '{/Symbol \316}';
2615   sym.notin = '{/Symbol \317}';
2616   sym.angle = '{/Symbol \320}';
2617   sym.bigtriangledown = '{/Symbol \321}';
2618   sym.langle = '{/Symbol \341}';
2619   sym.rangle = '{/Symbol \361}';
2620   sym.nabla = '{/Symbol \321}';
2621   sym.prod = '{/Symbol \325}';
2622   sym.surd = '{/Symbol \326}';
2623   sym.cdot = '{/Symbol \327}';
2624   sym.neg = '{/Symbol \330}';
2625   sym.wedge = '{/Symbol \331}';
2626   sym.vee = '{/Symbol \332}';
2627   sym.Leftrightarrow = '{/Symbol \333}';
2628   sym.Leftarrow = '{/Symbol \334}';
2629   sym.Uparrow = '{/Symbol \335}';
2630   sym.Rightarrow = '{/Symbol \336}';
2631   sym.Downarrow = '{/Symbol \337}';
2632   sym.diamond = '{/Symbol \340}';
2633   sym.copyright = '{/Symbol \343}';
2634   sym.lfloor = '{/Symbol \353}';
2635   sym.lceil  = '{/Symbol \351}';
2636   sym.rfloor = '{/Symbol \373}';
2637   sym.rceil  = '{/Symbol \371}';
2638   sym.int = '{/Symbol \362}';
2639 endfunction
2640
2641 function retval = __do_enhanced_option__ (enhanced, obj)
2642   retval = "";
2643   if (enhanced)
2644     if (strcmpi (obj.interpreter, "none"))
2645       retval = "noenhanced";
2646     else
2647       retval = "enhanced";
2648     endif
2649   endif
2650 endfunction