1########################################################################
2##
3## Copyright (C) 2007-2021 The Octave Project Developers
4##
5## See the file COPYRIGHT.md in the top-level directory of this
6## distribution or <https://octave.org/copyright/>.
7##
8## This file is part of Octave.
9##
10## Octave is free software: you can redistribute it and/or modify it
11## under the terms of the GNU General Public License as published by
12## the Free Software Foundation, either version 3 of the License, or
13## (at your option) any later version.
14##
15## Octave is distributed in the hope that it will be useful, but
16## WITHOUT ANY WARRANTY; without even the implied warranty of
17## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18## GNU General Public License for more details.
19##
20## You should have received a copy of the GNU General Public License
21## along with Octave; see the file COPYING.  If not, see
22## <https://www.gnu.org/licenses/>.
23##
24########################################################################
25
26## -*- texinfo -*-
27## @deftypefn {} {[@var{h}, @var{fail}] =} __patch__ (@var{p}, @dots{})
28## Undocumented internal function.
29## @end deftypefn
30
31## __patch__ (p, x, y, c)
32## Create patch object from x and y with color c and parent p.
33## Return handle to patch object.
34
35function [h, failed] = __patch__ (p, varargin)
36
37  h = NaN;
38  failed = false;
39
40  is_numeric_arg = cellfun (@isnumeric, varargin);
41
42  if (isempty (varargin))
43    args = varargin;
44  elseif (is_numeric_arg(1))
45    if (nargin < 3 || ! is_numeric_arg(2))
46      failed = true;
47    else
48      if (nargin > 4 && all (is_numeric_arg(1:4)))
49        x = varargin{1};
50        y = varargin{2};
51        z = varargin{3};
52        c = varargin{4};
53        iarg = 5;
54      elseif (nargin > 3 && all (is_numeric_arg(1:3)))
55        x = varargin{1};
56        y = varargin{2};
57        if (nargin > 4 && iscolorspec (varargin{4}))
58          z = varargin{3};
59          c = varargin{4};
60          iarg = 5;
61        else
62          z = [];
63          c = varargin{3};
64          iarg = 4;
65        endif
66      elseif (nargin > 2 && all (is_numeric_arg(1:2)))
67        x = varargin{1};
68        y = varargin{2};
69        z = [];
70        if (iscolorspec (varargin{3}))
71          c = varargin{3};
72          iarg = 4;
73        else
74          c = [];
75          iarg = 3;
76        endif
77      endif
78
79      if (isvector (x))
80        x = x(:);
81        y = y(:);
82        z = z(:);
83        if (isnumeric (c))
84          if (isvector (c) && numel (c) == numel (x))
85            c = c(:);
86          elseif (rows (c) != numel (x) && columns (c) == numel (x))
87            c = c.';
88          endif
89        endif
90      endif
91      args{1} = "xdata";
92      args{2} = x;
93      args{3} = "ydata";
94      args{4} = y;
95      args{5} = "zdata";
96      args{6} = z;
97
98      if (isnumeric (c))
99
100        if (ndims (c) == 3 && columns (c) == 1)
101          c = permute (c, [1, 3, 2]);
102        endif
103
104        if (isvector (c) && numel (c) == columns (x))
105          if (isnan (c))
106            args{7} = "facecolor";
107            args{8} = [1, 1, 1];
108            args{9} = "cdata";
109            args{10} = c;
110          elseif (isnumeric (c))
111            args{7} = "facecolor";
112            args{8} = "flat";
113            args{9} = "cdata";
114            args{10} = c;
115          else
116            error ("patch: color data C must be numeric");
117          endif
118        elseif (isrow (c) && numel (c) == 3)
119          args{7} = "facecolor";
120          args{8} = c;
121          args{9} = "cdata";
122          args{10} = [];
123        elseif (ndims (c) == 3 && size (c, 3) == 3)
124          ## CDATA is specified as RGB data
125          if ((rows (c) == 1 && columns (c) == 1) ...
126              || (rows (c) == 1 && columns (c) == columns (x)))
127            ## Single patch color or per-face color
128            args{7} = "facecolor";
129            args{8} = "flat";
130            args{9} = "cdata";
131            args{10} = c;
132          elseif (rows (c) == rows (x) && columns (c) == columns (x))
133            ## Per-vertex color
134            args{7} = "facecolor";
135            args{8} = "interp";
136            args{9} = "cdata";
137            args{10} = c;
138          else
139            error ("patch: Invalid TrueColor data C");
140          endif
141        else
142          ## Color Vectors
143          if (isempty (c))
144            args{7} = "facecolor";
145            args{8} = "interp";
146            args{9} = "cdata";
147            args{10} = [];
148          elseif (size_equal (c, x) && size_equal (c, y))
149            args{7} = "facecolor";
150            args{8} = "interp";
151            args{9} = "cdata";
152            args{10} = c;
153          else
154            error ("patch: size of X, Y, and C must be equal");
155          endif
156        endif
157      elseif (iscolorspec (c))
158        args{7} = "facecolor";
159        args{8} = tolower (c);
160        args{9} = "cdata";
161        args{10} = [];
162      else
163        args{7} = "facecolor";
164        args{8} = [0, 0, 0];
165        args{9} = "cdata";
166        args{10} = [];
167      endif
168
169      args = [args, varargin(iarg:end)];
170    endif
171  else
172    args = varargin;
173  endif
174
175  if (! failed)
176    h = __go_patch__ (p, args{:});
177  endif
178
179endfunction
180
181function retval = iscolorspec (arg)
182  retval = false;
183  if (ischar (arg))
184    persistent colors = {"y", "yellow", "r", "red", "m", "magenta", ...
185                         "c", "cyan", "g", "green", "b", "blue", ...
186                         "w", "white", "k", "black"};
187    if (any (strcmpi (arg, colors)))
188      retval = true;
189    endif
190  endif
191endfunction
192