changeset 33194:8725e0726cd0 bytecode-interpreter

maint: Merge default to bytecode-interpreter
author Arun Giridhar <arungiridhar@gmail.com>
date Tue, 12 Mar 2024 12:40:15 -0400
parents ed176bb5f7e6 (current diff) 16aa98e2c3e7 (diff)
children 1e2b93a4840d
files etc/NEWS.9.md
diffstat 5 files changed, 83 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/etc/NEWS.9.md	Thu Mar 07 21:19:52 2024 -0500
+++ b/etc/NEWS.9.md	Tue Mar 12 12:40:15 2024 -0400
@@ -70,9 +70,12 @@
   state, the resulting value is now displayed in the Command Window for
   informational purposes.
 
-- The axes graphics property "TickDir" now accepts the option "none", which
+- The axes graphics property `"TickDir"` now accepts the option `"none"`, which
   will not draw tick marks but will still draw tick labels.
 
+- Stricter checks are performed for valid dimensions of the color data
+  properties `"CData"` and `"FaceVertexCData"` when rendering `patch` objects.
+
 ### Matlab compatibility
 
 - The `inputParser` function now implements the `PartialMatching` property for
--- a/libinterp/corefcn/graphics.cc	Thu Mar 07 21:19:52 2024 -0500
+++ b/libinterp/corefcn/graphics.cc	Tue Mar 12 12:40:15 2024 -0400
@@ -9653,21 +9653,38 @@
       return;
     }
 
+  octave_idx_type nv = xd.rows ();
+  octave_idx_type nf = xd.columns ();
+  octave_idx_type ncv = cd.rows ();
+  octave_idx_type ncf = cd.columns ();
+  if ((ncf > 1 || ncv > 1) && ((ncf != nf) || (ncv != 1 && ncv != nv)))
+    {
+      m_bad_data_msg = "cdata does not match number of faces "
+                       "or number of vertices per face";
+      return;
+    }
+
+  bool pervertex = false;
+  if (ncv == nv)
+    pervertex = true;
+
+  bool isRGB = false;
+  if (cd.ndims () == 3)
+    isRGB = true;
+
   // Faces and Vertices
   dim_vector dv;
   bool is3D = false;
-  octave_idx_type nr = xd.rows ();
-  octave_idx_type nc = xd.columns ();
-  if (nr == 1 && nc > 1)
-    {
-      nr = nc;
-      nc = 1;
+  if (nv == 1 && nf > 1)
+    {
+      nv = nf;
+      nf = 1;
       xd = xd.as_column ();
       yd = yd.as_column ();
       zd = zd.as_column ();
     }
 
-  dv(0) = nr * nc;
+  dv(0) = nv * nf;
   if (zd.isempty ())
     dv(1) = 2;
   else
@@ -9677,35 +9694,50 @@
     }
 
   Matrix vert (dv);
-  Matrix idx (nc, nr);
-
+  Matrix idx (nf, nv);
+
+  Matrix fvc;
+  if (pervertex)
+    {
+      // "facevertexcdata" holds color data per vertex
+      fvc.resize (nv * nf, (isRGB ? 3 : 1));
+    }
+  else if (! cd.isempty ())
+    {
+      // "facevertexcdata" holds color data per face
+      dv(0) = ncf;
+      dv(1) = (isRGB ? 3 : 1);
+      fvc = cd.reshape (dv);
+    }
+
+  // create list of vertices from x/y/zdata
+  // FIXME: It might be possible to share vertices between adjacent faces.
   octave_idx_type kk = 0;
-  for (octave_idx_type jj = 0; jj < nc; jj++)
-    {
-      for (octave_idx_type ii = 0; ii < nr; ii++)
+  for (octave_idx_type jj = 0; jj < nf; jj++)
+    {
+      for (octave_idx_type ii = 0; ii < nv; ii++)
         {
           vert(kk, 0) = xd(ii, jj);
           vert(kk, 1) = yd(ii, jj);
           if (is3D)
             vert(kk, 2) = zd(ii, jj);
 
+          if (pervertex)
+            {
+              fvc(kk, 0) = cd(ii, jj, 0);
+              if (isRGB)
+                {
+                  fvc(kk, 1) = cd(ii, jj, 1);
+                  fvc(kk, 2) = cd(ii, jj, 2);
+                }
+            }
+
           idx(jj, ii) = static_cast<double> (kk+1);
 
           kk++;
         }
     }
 
-  // facevertexcdata
-  Matrix fvc;
-  if (cd.ndims () == 3)
-    {
-      dv(0) = cd.rows () * cd.columns ();
-      dv(1) = cd.dims ()(2);
-      fvc = cd.reshape (dv);
-    }
-  else
-    fvc = cd.as_column ();
-
   // FIXME: shouldn't we update facevertexalphadata here ?
 
   octave::unwind_protect_var<bool> restore_var (updating_patch_data, true);
@@ -9835,6 +9867,15 @@
       return;
     }
 
+  // Check if number of color values matches number of faces or vertices
+  octave_idx_type nfvc = fvc.rows ();
+  if (nfvc > 1 && nfvc != nfaces && nfvc != nvert)
+    {
+      m_bad_data_msg = "number of facevertexcdata values matches "
+                       "neither number of faces nor number of vertices";
+      return;
+    }
+
   // Replace NaNs
   if (idx.any_element_is_inf_or_nan ())
     {
@@ -9901,21 +9942,20 @@
 
   if (fvc.rows () == nfaces || fvc.rows () == 1)
     {
+      // "facevertexcdata" holds color data per face or same color for all
       dv(0) = 1;
       dv(1) = fvc.rows ();
       dv(2) = fvc.columns ();
       cd = fvc.reshape (dv);
     }
-  else
-    {
-      if (! fvc.isempty ())
-        {
-          dv(0) = idx.rows ();
-          dv(1) = nfaces;
-          dv(2) = fvc.columns ();
-          cd.resize (dv);
-          pervertex = true;
-        }
+  else if (! fvc.isempty ())
+    {
+      // "facevertexcdata" holds color data per vertex
+      dv(0) = idx.rows ();
+      dv(1) = nfaces;
+      dv(2) = fvc.columns ();
+      cd.resize (dv);
+      pervertex = true;
     }
 
   // Build x,y,zdata and eventually per vertex cdata
--- a/libinterp/corefcn/regexp.cc	Thu Mar 07 21:19:52 2024 -0500
+++ b/libinterp/corefcn/regexp.cc	Tue Mar 12 12:40:15 2024 -0400
@@ -880,9 +880,9 @@
 complement), and then further processing the return variables (now reduced in
 size) with successive @code{regexp} searches.
 
-Octave's @code{regexp} implementaion is based on the Perl Compatible
+Octave's @code{regexp} implementation is based on the Perl Compatible
 Regular Expressions library (@url{https://www.pcre.org/}).  For a more
-comprehensive list of rexexp operator syntax see the
+comprehensive list of @code{regexp} operator syntax see the
 @url{https://www.pcre.org/current/doc/html/pcre2syntax.html,,
 "PCRE Syntax quick-reference summary"}.
 
--- a/scripts/plot/draw/private/__bar__.m	Thu Mar 07 21:19:52 2024 -0500
+++ b/scripts/plot/draw/private/__bar__.m	Tue Mar 12 12:40:15 2024 -0400
@@ -283,10 +283,10 @@
 
       if (vertical)
         h = patch (hax, xb(:,:,i), yb(:,:,i),
-                   "cdata", i*ones (columns (xb),1), "FaceColor", "flat");
+                   "cdata", i, "FaceColor", "flat");
       else
         h = patch (hax, yb(:,:,i), xb(:,:,i),
-                   "cdata", i*ones (columns (yb),1), "FaceColor", "flat");
+                   "cdata", i, "FaceColor", "flat");
       endif
 
       if (! isempty (varargin))
--- a/scripts/plot/draw/private/__patch__.m	Thu Mar 07 21:19:52 2024 -0500
+++ b/scripts/plot/draw/private/__patch__.m	Tue Mar 12 12:40:15 2024 -0400
@@ -117,8 +117,8 @@
           args{7} = "facecolor";
           args{8} = "flat";
         endif
-        args{9} = "cdata";
-        args{10} = c;
+        args{9} = "facevertexcdata";
+        args{10} = c(:);
       elseif (isrow (c) && numel (c) == 3)
         ## One RGB color
         args{7} = "facecolor";