changeset 7862:8f3459a90bf3

Redesign axis limit computation handling (using hidden limit properties in child objects)
author Michael Goffioul <michael.goffioul@gmail.com>
date Sun, 23 Mar 2008 16:45:45 +0100
parents 7397a0026ca8
children 2a62d45fa21d
files src/ChangeLog src/genprops.awk src/graphics.cc src/graphics.h.in
diffstat 4 files changed, 597 insertions(+), 205 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Mon Mar 17 18:51:36 2008 +0200
+++ b/src/ChangeLog	Sun Mar 23 16:45:45 2008 +0100
@@ -47,6 +47,144 @@
 
 2008-06-04  Michael Goffioul <michael.goffioul@gmail.com>
 
+	* genprops.awk (emit_get_array): Don't produce get_xxx_property
+	accessors.
+	* graphics.h.in (array_property::get_limits): New method to return the
+	array limits.
+	(base_properties::get_xdata_property,
+	base_properties::get_ydata_property,
+	base_properties::get_zdata_property,
+	base_properties::get_ldata_property,
+	base_properties::get_udata_property,
+	base_properties::get_xldata_property,
+	base_properties::get_xudata_property,
+	base_properties::get_cdata_property): Remove methods, replaced with
+	limit-based equivalent.
+	(base_graphics_object::get_xdata_property,
+	base_graphics_object::get_ydata_property,
+	base_graphics_object::get_zdata_property,
+	base_graphics_object::get_ldata_property,
+	base_graphics_object::get_udata_property,
+	base_graphics_object::get_xldata_property,
+	base_graphics_object::get_xudata_property,
+	base_graphics_object::get_cdata_property): Likewise.
+	(graphics_object::get_xdata_property,
+	graphics_object::get_ydata_property,
+	graphics_object::get_zdata_property,
+	graphics_object::get_ldata_property,
+	graphics_object::get_udata_property,
+	graphics_object::get_xldata_property,
+	graphics_object::get_xudata_property,
+	graphics_object::get_cdata_property): Likewise.
+	(base_properties::get_xlim, base_properties::get_ylim,
+	base_properties::get_zlim, base_properties::get_clim,
+	base_properties::get_alim, base_properties::is_xliminclude,
+	base_properties::is_yliminclude, base_properties::is_zliminclude,
+	base_properties::is_climinclude, base_properties::is_aliminclude):
+	New methods.
+	(base_graphics_object::get_xlim, base_graphics_object::get_ylim,
+	base_graphics_object::get_zlim, base_graphics_object::get_clim,
+	base_graphics_object::get_alim, base_graphics_object::is_xliminclude,
+	base_graphics_object::is_yliminclude,
+	base_graphics_object::is_zliminclude,
+	base_graphics_object::is_climinclude,
+	base_graphics_object::is_aliminclude): Likewise.
+	(graphics_object::get_xlim, graphics_object::get_ylim,
+	graphics_object::get_zlim, graphics_object::get_clim,
+	graphics_object::get_alim, graphics_object::is_xliminclude,
+	graphics_object::is_yliminclude, graphics_object::is_zliminclude,
+	graphics_object::is_climinclude, graphics_object::is_aliminclude):
+	Likewise.
+	(base_graphics_object::update_axis_limits): Provide default behavior
+	by passing the call to the parent object.
+	(line::properties::xdata, line::properties::ydata,
+	line::properties::zdata, line::properties::ldata,
+	line::properties::udata, line::properties::xldata,
+	line::properties::xudata): Replace 'l' modifier with 'u'.
+	(line::properties::xlim, line::properties::ylim,
+	line::properties::zlim, line::properties::xliminclude,
+	line::properties::yliminclude, line::properties::zliminclude): New
+	hidden properties.
+	(line::properties::update_xdata, line::properties::update_ydata,
+	line::properties::update_zdata, line::properties::update_xldata,
+	line::properties::update_xudata, line::properties::update_ldata,
+	line::properties::update_udata): New updaters that update limit
+	properties.
+	(line::properties::compute_xlim, line::properties::compute_ylim): New
+	method to compute actual limits taking into account x/y data and
+	upper/lower bounds.
+	(text::properties::position): Add 'u' modifier.
+	(text::properties::xlim, text::properties::ylim,
+	text::properties::zlim, text::properties::xliminclude,
+	text::properties::yliminclude, text::properties::zliminclude): New
+	hidden properties.
+	(text::properties::update_position): New updater that updates limit
+	properties.
+	(image::properties::xdata, image::properties::ydata,
+	image::properties::cdata): Replace 'l' modifier with 'u'.
+	(image::properties::cdatamapping): Add 'l' modifier.
+	(image::properties::xlim, image::properties::ylim,
+	image::properties::clim, image::properties::xliminclude,
+	image::properties::yliminclude, image::properties::climinclude): New
+	hidden properties.
+	(image::properties::get_climinclude,
+	image::properties::is_climinclude): Provide specialized inline
+	accessors.
+	(image::properties::update_xdata, image::properties::update_ydata,
+	image::properties::update_cdata): New updaters that update limit
+	properties.
+	(patch::properties::xdata, patch::properties::ydata,
+	patch::properties::zdata, patch::properties::cdata): Replace 'l'
+	modifier with 'u'.
+	(patch::properties::cdatamapping): Add 'l' modifier.
+	(patch::properties::alphadatamapping): New property.
+	(patch::properties::xlim, patch::properties::ylim,
+	patch::properties::zlim, patch::properties::clim,
+	patch::properties::alim, patch::properties::xliminclude,
+	patch::properties::yliminclude, patch::properties::zliminclude,
+	patch::properties::climinclude, patch::properties::aliminclude: New
+	hidden properties.
+	(patch::properties::get_climinclude,
+	patch::properties::is_climinclude, patch::properties::get_aliminclude,
+	patch::properties::is_aliminclude): Provide specialized inline
+	accessors.
+	(patch::properties::update_xdata, patch::properties::update_ydata,
+	patch::properties::update_zdata, patch::properties::update_cdata): New
+	updaters that update limit properties.
+	(surface::properties::xdata, surface::properties::ydata,
+	surface::properties::zdata, surface::properties::cdata,
+	surface::properties::alphadata): Replace 'l' modifier with 'u'.
+	(surface::properties::cdatamapping,
+	surface::properties::alphadatamapping): Add 'l' modifier.
+	(surface::properties::xlim, surface::properties::ylim,
+	surface::properties::zlim, surface::properties::clim,
+	surface::properties::alim, surface::properties::xliminclude,
+	surface::properties::yliminclude, surface::properties::zliminclude,
+	surface::properties::climinclude, surface::properties::aliminclude: New
+	hidden properties.
+	(surface::properties::get_climinclude,
+	surface::properties::is_climinclude,
+	surface::properties::get_aliminclude,
+	surface::properties::is_aliminclude): Provide specialized inline
+	accessors.
+	(surface::properties::update_xdata, surface::properties::update_ydata,
+	surface::properties::update_zdata): Update limit properties.
+	(surface::properties::update_cdata,
+	surface::properties::update_alphadata): New updaters that update limit
+	properties.
+	* graphics.cc (base_properties::update_axis_limits): Simply call
+	update_axis_limits in owning graphics_object.
+	(base_graphics_object::update_axis_limits): Provide default behavior
+	by passing the call to the parent object.
+	(check_limits_vals(double&,double&,double&,const octave_value&)): New
+	static method to work with new limit properties in graphics objects.
+	(get_children_limits): New static method to compute the raw limits of
+	a set of children, based on the new limit properties.
+	(axes::update_axis_limits): Simplify and call get_children_limits. Add
+	handling of alpha limits.
+	(line::properties::compute_xlim, line::properties::compute_ylim): New
+	methods to compute line limits taking into account upper/lower bounds.
+
 	* graphics.cc (axes::properties::sync_positions): Update
 	transformation data.
 
--- a/src/genprops.awk	Mon Mar 17 18:51:36 2008 +0200
+++ b/src/genprops.awk	Sun Mar 23 16:45:45 2008 +0100
@@ -229,9 +229,6 @@
 function emit_get_array (i)
 {
   emit_get_accessor(i, "octave_value", "get");
-
-  printf ("  array_property get_%s_property (void) const { return %s; }\n",
-          name[i], name[i]);
 }
 
 ## common section
--- a/src/graphics.cc	Mon Mar 17 18:51:36 2008 +0200
+++ b/src/graphics.cc	Sun Mar 23 16:45:45 2008 +0100
@@ -1508,11 +1508,9 @@
 void
 base_properties::update_axis_limits (const std::string& axis_type) const
 {
-  graphics_handle h = (get_type () == "axes") ? __myhandle__ : get_parent ();
-
-  graphics_object obj = gh_manager::get_object (h);
-
-  if (obj.isa ("axes"))
+  graphics_object obj = gh_manager::get_object (__myhandle__);
+
+  if (obj)
     obj.update_axis_limits (axis_type);
 }
 
@@ -1643,6 +1641,22 @@
 
 // ---------------------------------------------------------------------
 
+void
+base_graphics_object::update_axis_limits (const std::string& axis_type)
+{
+  if (valid_object ())
+    {
+      graphics_object parent_obj = gh_manager::get_object (get_parent ());
+
+      if (parent_obj)
+	parent_obj.update_axis_limits (axis_type);
+    }
+  else
+    error ("base_graphics_object::update_axis_limits: invalid graphics object");
+}
+
+// ---------------------------------------------------------------------
+
 #include "graphics-props.cc"
 
 // ---------------------------------------------------------------------
@@ -2558,7 +2572,9 @@
   return retval;
 }
 
+// FIXME: Remove
 // FIXME: Maybe this should go into array_property class?
+/*
 static void
 check_limit_vals (double& min_val, double& max_val, double& min_pos,
 		  const array_property& data)
@@ -2573,6 +2589,34 @@
   if (! (xisinf (val) || xisnan (val)) && val > 0 && val < min_pos)
     min_pos = val;
 }
+*/
+
+static void
+check_limit_vals (double& min_val, double& max_val, double& min_pos,
+		  const octave_value& data)
+{
+  if (data.is_matrix_type ())
+    {
+      Matrix m = data.matrix_value ();
+
+      if (! error_state && m.numel () == 3)
+	{
+	  double val;
+
+	  val = m(0);
+	  if (! (xisinf (val) || xisnan (val)) && val < min_val)
+	    min_val = val;
+
+	  val = m(1);
+	  if (! (xisinf (val) || xisnan (val)) && val > max_val)
+	    max_val = val;
+
+	  val = m(2);
+	  if (! (xisinf (val) || xisnan (val)) && val > 0 && val < min_pos)
+	    min_pos = val;
+	}
+    }
+}
 
 // magform(x) Returns (a, b), where x = a * 10^b, a >= 1., and b is
 // integral.
@@ -2766,6 +2810,89 @@
   ticks = tmp_ticks;
 }
 
+static void
+get_children_limits (double& min_val, double& max_val, double& min_pos,
+		     const Matrix& kids, char limit_type)
+{
+  octave_idx_type n = kids.numel ();
+
+  switch (limit_type)
+    {
+    case 'x':
+      for (octave_idx_type i = 0; i < n; i++)
+	{
+	  graphics_object obj = gh_manager::get_object (kids(i));
+
+	  if (obj.is_xliminclude ())
+	    {
+	      octave_value lim = obj.get_xlim ();
+
+	      check_limit_vals (min_val, max_val, min_pos, lim);
+	    }
+	}
+      break;
+
+    case 'y':
+      for (octave_idx_type i = 0; i < n; i++)
+	{
+	  graphics_object obj = gh_manager::get_object (kids(i));
+
+	  if (obj.is_yliminclude ())
+	    {
+	      octave_value lim = obj.get_ylim ();
+
+	      check_limit_vals (min_val, max_val, min_pos, lim);
+	    }
+	}
+      break;
+    
+    case 'z':
+      for (octave_idx_type i = 0; i < n; i++)
+	{
+	  graphics_object obj = gh_manager::get_object (kids(i));
+
+	  if (obj.is_zliminclude ())
+	    {
+	      octave_value lim = obj.get_zlim ();
+
+	      check_limit_vals (min_val, max_val, min_pos, lim);
+	    }
+	}
+      break;
+    
+    case 'c':
+      for (octave_idx_type i = 0; i < n; i++)
+	{
+	  graphics_object obj = gh_manager::get_object (kids(i));
+
+	  if (obj.is_climinclude ())
+	    {
+	      octave_value lim = obj.get_clim ();
+
+	      check_limit_vals (min_val, max_val, min_pos, lim);
+	    }
+	}
+      break;
+    
+    case 'a':
+      for (octave_idx_type i = 0; i < n; i++)
+	{
+	  graphics_object obj = gh_manager::get_object (kids(i));
+
+	  if (obj.is_aliminclude ())
+	    {
+	      octave_value lim = obj.get_alim ();
+
+	      check_limit_vals (min_val, max_val, min_pos, lim);
+	    }
+	}
+      break;
+
+    default:
+      break;
+    }
+}
+
 static bool updating_axis_limits = false;
 
 void
@@ -2788,32 +2915,13 @@
 
   if (axis_type == "xdata" || axis_type == "xscale"
       || axis_type == "xldata" || axis_type == "xudata"
-      || axis_type == "xlimmode")
+      || axis_type == "xlimmode" || axis_type == "xliminclude"
+      || axis_type == "xlim")
     {
       if (xproperties.xlimmode_is ("auto"))
 	{
-	  for (octave_idx_type i = 0; i < n; i++)
-	    {
-	      graphics_object obj = gh_manager::get_object (kids(i));
-
-	      if (obj.isa ("line") || obj.isa ("image")
-		  || obj.isa ("patch") || obj.isa ("surface"))
-		{
-		  array_property xdata = obj.get_xdata_property ();
-
-		  check_limit_vals (min_val, max_val, min_pos, xdata);
-
-		  if (obj.isa ("line"))
-		    {
-		      array_property xldata = obj.get_xldata_property ();
-		      array_property xudata = obj.get_xudata_property ();
-
-		      check_limit_vals (min_val, max_val, min_pos, xldata);
-		      check_limit_vals (min_val, max_val, min_pos, xudata);
-		    }
-		}
-	    }
-
+	  get_children_limits (min_val, max_val, min_pos, kids, 'x');
+	  
 	  limits = xproperties.get_axis_limits (min_val, max_val, min_pos,
 						xproperties.xscale_is ("log"));
 
@@ -2822,31 +2930,12 @@
     }
   else if (axis_type == "ydata" || axis_type == "yscale"
 	   || axis_type == "ldata" || axis_type == "udata"
-	   || axis_type == "ylimmode")
+	   || axis_type == "ylimmode" || axis_type == "yliminclude"
+	   || axis_type == "ylim")
     {
       if (xproperties.ylimmode_is ("auto"))
 	{
-	    for (octave_idx_type i = 0; i < n; i++)
-	    {
-	      graphics_object obj = gh_manager::get_object (kids(i));
-
-	      if (obj.isa ("line") || obj.isa ("image")
-		|| obj.isa ("patch") || obj.isa ("surface"))
-		{
-		  array_property ydata = obj.get_ydata_property ();
-
-		  check_limit_vals (min_val, max_val, min_pos, ydata);
-
-		  if (obj.isa ("line"))
-		    {
-		      array_property ldata = obj.get_ldata_property ();
-		      array_property udata = obj.get_udata_property ();
-
-		      check_limit_vals (min_val, max_val, min_pos, ldata);
-		      check_limit_vals (min_val, max_val, min_pos, udata);
-		    }
-		}
-	    }
+	  get_children_limits (min_val, max_val, min_pos, kids, 'y');
 
 	  limits = xproperties.get_axis_limits (min_val, max_val, min_pos,
 						xproperties.yscale_is ("log"));
@@ -2855,21 +2944,12 @@
 	}
     }
   else if (axis_type == "zdata" || axis_type == "zscale"
-	   || axis_type == "zlimmode")
+	   || axis_type == "zlimmode" || axis_type == "zliminclude"
+	   || axis_type == "zlim")
     {
       if (xproperties.zlimmode_is ("auto"))
 	{
-	  for (octave_idx_type i = 0; i < n; i++)
-	    {
-	      graphics_object obj = gh_manager::get_object (kids(i));
-
-	      if (obj.isa ("line") || obj.isa ("patch") || obj.isa ("surface"))
-		{
-		  array_property zdata = obj.get_zdata_property ();
-
-		  check_limit_vals (min_val, max_val, min_pos, zdata);
-		}
-	    }
+	  get_children_limits (min_val, max_val, min_pos, kids, 'z');
 
 	  limits = xproperties.get_axis_limits (min_val, max_val, min_pos,
 						xproperties.zscale_is ("log"));
@@ -2877,23 +2957,20 @@
 	  update_type = 'z';
 	}
     }
-  else if (axis_type == "cdata" || axis_type == "climmode")
+  else if (axis_type == "cdata" || axis_type == "climmode"
+	   || axis_type == "cdatamapping" || axis_type == "climinclude"
+	   || axis_type == "clim")
     {
       if (xproperties.climmode_is ("auto"))
 	{
-	  for (octave_idx_type i = 0; i < n; i++)
+	  get_children_limits (min_val, max_val, min_pos, kids, 'c');
+
+	  if (min_val > max_val)
 	    {
-	      graphics_object obj = gh_manager::get_object (kids(i));
-
-	      if (obj.isa ("image") || obj.isa ("patch") || obj.isa ("surface"))
-		{
-		  array_property cdata = obj.get_cdata_property ();
-
-		  check_limit_vals (min_val, max_val, min_pos, cdata);
-		}
+	      min_val = min_pos = 0;
+	      max_val = 1;
 	    }
-
-	  if (min_val == max_val)
+	  else if (min_val == max_val)
 	    max_val = min_val + 1;
 
 	  limits.resize (1, 2);
@@ -2905,6 +2982,31 @@
 	}
 
     }
+  else if (axis_type == "alphadata" || axis_type == "alimmode"
+	   || axis_type == "alphadatamapping" || axis_type == "aliminclude"
+	   || axis_type == "alim")
+    {
+      if (xproperties.alimmode_is ("auto"))
+	{
+	  get_children_limits (min_val, max_val, min_pos, kids, 'a');
+
+	  if (min_val > max_val)
+	    {
+	      min_val = min_pos = 0;
+	      max_val = 1;
+	    }
+	  else if (min_val == max_val)
+	    max_val = min_val + 1;
+
+	  limits.resize (1, 2);
+
+	  limits(0) = min_val;
+	  limits(1) = max_val;
+
+	  update_type = 'a';
+	}
+
+    }
 
   unwind_protect_bool (updating_axis_limits);
   updating_axis_limits = true;
@@ -2934,6 +3036,11 @@
       xproperties.set_climmode ("auto");
       break;
 
+    case 'a':
+      xproperties.set_alim (limits);
+      xproperties.set_alimmode ("auto");
+      break;
+
     default:
       break;
     }
@@ -2992,7 +3099,29 @@
 
 // ---------------------------------------------------------------------
 
-// Note: "line" code is entirely auto-generated
+Matrix
+line::properties::compute_xlim (void) const
+{
+  Matrix m (1, 3);
+
+  m(0) = xmin (xdata.min_val (), xmin (xldata.min_val (), xudata.min_val ()));
+  m(1) = xmax (xdata.max_val (), xmax (xldata.max_val (), xudata.max_val ()));
+  m(2) = xmin (xdata.min_pos (), xmin (xldata.min_pos (), xudata.min_pos ()));
+
+  return m;
+}
+
+Matrix
+line::properties::compute_ylim (void) const
+{
+  Matrix m (1, 3);
+
+  m(0) = xmin (ydata.min_val (), xmin (ldata.min_val (), udata.min_val ()));
+  m(1) = xmax (ydata.max_val (), xmax (ldata.max_val (), udata.max_val ()));
+  m(2) = xmin (ydata.min_pos (), xmin (ldata.min_pos (), udata.min_pos ()));
+
+  return m;
+}
 
 // ---------------------------------------------------------------------
 
--- a/src/graphics.h.in	Mon Mar 17 18:51:36 2008 +0200
+++ b/src/graphics.h.in	Sun Mar 23 16:45:45 2008 +0100
@@ -852,6 +852,17 @@
   double max_val (void) const { return xmax; }
   double min_pos (void) const { return xminp; }
 
+  Matrix get_limits (void) const
+    {
+      Matrix m (1, 3);
+      
+      m(0) = min_val ();
+      m(1) = max_val ();
+      m(2) = min_pos ();
+
+      return m;
+    }
+
   array_property& operator = (const octave_value& val)
     {
       set (val);
@@ -1671,54 +1682,19 @@
   // genprops.awk script.
   //
   // EMIT_BASE_PROPERTIES_GET_FUNCTIONS
-  virtual array_property get_xdata_property (void) const
-  {
-    error ("get: invalid property \"xdata\"");
-    return array_property ();
-  }
-
-  virtual array_property get_ydata_property (void) const
-  {
-    error ("get: invalid property \"ydata\"");
-    return array_property ();
-  }
-
-  virtual array_property get_zdata_property (void) const
-  {
-    error ("get: invalid property \"zdata\"");
-    return array_property ();
-  }
-
-  virtual array_property get_ldata_property (void) const
-  {
-    error ("get: invalid property \"ldata\"");
-    return array_property ();
-  }
-
-  virtual array_property get_udata_property (void) const
-  {
-    error ("get: invalid property \"udata\"");
-    return array_property ();
-  }
-
-  virtual array_property get_xldata_property (void) const
-  {
-    error ("get: invalid property \"xldata\"");
-    return array_property ();
-  }
-
-  virtual array_property get_xudata_property (void) const
-  {
-    error ("get: invalid property \"xudata\"");
-    return array_property ();
-  }
-
-  virtual array_property get_cdata_property (void) const
-  {
-    error ("get: invalid property \"cdata\"");
-    return array_property ();
-  }
-
+
+  virtual octave_value get_xlim (void) const { return octave_value (); }
+  virtual octave_value get_ylim (void) const { return octave_value (); }
+  virtual octave_value get_zlim (void) const { return octave_value (); }
+  virtual octave_value get_clim (void) const { return octave_value (); }
+  virtual octave_value get_alim (void) const { return octave_value (); }
+
+  virtual bool is_xliminclude (void) const { return false; }
+  virtual bool is_yliminclude (void) const { return false; }
+  virtual bool is_zliminclude (void) const { return false; }
+  virtual bool is_climinclude (void) const { return false; }
+  virtual bool is_aliminclude (void) const { return false; }
+  
 protected:
   // properties common to all objects
   bool_property beingdeleted;
@@ -1901,10 +1877,7 @@
     return properties;
   }
 
-  virtual void update_axis_limits (const std::string&)
-  {
-    error ("base_graphics_object::update_axis_limits: invalid graphics object");
-  }
+  virtual void update_axis_limits (const std::string& axis_type);
 
   virtual bool valid_object (void) const { return false; }
 
@@ -2054,54 +2027,37 @@
   // genprops.awk script.
   //
   // EMIT_GRAPHICS_OBJECT_GET_FUNCTIONS
-  array_property get_xdata_property (void) const
-  {
-    const base_properties& props = get_properties ();
-    return props.get_xdata_property ();
-  }
-
-  array_property get_ydata_property (void) const
-  {
-    const base_properties& props = get_properties ();
-    return props.get_ydata_property ();
-  }
-
-  array_property get_zdata_property (void) const
-  {
-    const base_properties& props = get_properties ();
-    return props.get_zdata_property ();
-  }
-
-  array_property get_ldata_property (void) const
-  {
-    const base_properties& props = get_properties ();
-    return props.get_ldata_property ();
-  }
-
-  array_property get_udata_property (void) const
-  {
-    const base_properties& props = get_properties ();
-    return props.get_udata_property ();
-  }
-
-  array_property get_xldata_property (void) const
-  {
-    const base_properties& props = get_properties ();
-    return props.get_xldata_property ();
-  }
-
-  array_property get_xudata_property (void) const
-  {
-    const base_properties& props = get_properties ();
-    return props.get_xudata_property ();
-  }
-
-  array_property get_cdata_property (void) const
-  {
-    const base_properties& props = get_properties ();
-    return props.get_cdata_property ();
-  }
-
+
+  octave_value get_xlim (void) const
+  { return get_properties ().get_xlim (); }
+
+  octave_value get_ylim (void) const
+  { return get_properties ().get_ylim (); }
+  
+  octave_value get_zlim (void) const
+  { return get_properties ().get_zlim (); }
+  
+  octave_value get_clim (void) const
+  { return get_properties ().get_clim (); }
+  
+  octave_value get_alim (void) const
+  { return get_properties ().get_alim (); }
+
+  bool is_xliminclude (void) const
+  { return get_properties ().is_xliminclude (); }
+  
+  bool is_yliminclude (void) const
+  { return get_properties ().is_yliminclude (); }
+  
+  bool is_zliminclude (void) const
+  { return get_properties ().is_zliminclude (); }
+  
+  bool is_climinclude (void) const
+  { return get_properties ().is_climinclude (); }
+  
+  bool is_aliminclude (void) const
+  { return get_properties ().is_aliminclude (); }
+  
   graphics_backend get_backend (void) const { return rep->get_backend (); }
 
   void add_property_listener (const std::string& nm, const octave_value& v,
@@ -2866,13 +2822,13 @@
     // ldata, udata, xldata, xudata, keylabel, interpreter
 
     BEGIN_PROPERTIES(line)
-      row_vector_property xdata l , default_data ()
-      row_vector_property ydata l , default_data ()
-      row_vector_property zdata l , Matrix ()
-      row_vector_property ldata l , Matrix ()
-      row_vector_property udata l , Matrix ()
-      row_vector_property xldata l , Matrix ()
-      row_vector_property xudata l , Matrix ()
+      row_vector_property xdata u , default_data ()
+      row_vector_property ydata u , default_data ()
+      row_vector_property zdata u , Matrix ()
+      row_vector_property ldata u , Matrix ()
+      row_vector_property udata u , Matrix ()
+      row_vector_property xldata u , Matrix ()
+      row_vector_property xudata u , Matrix ()
       color_property color , color_values (0, 0, 0)
       radio_property linestyle , "{-}|--|:|-.|none"
       double_property linewidth , 0.5
@@ -2884,7 +2840,32 @@
       radio_property interpreter , "{tex}|none|latex"
       string_property displayname , ""
       radio_property erasemode , "{normal}|none|xor|background"
+      // hidden properties for limit computation
+      row_vector_property xlim hlr , Matrix ()
+      row_vector_property ylim hlr , Matrix ()
+      row_vector_property zlim hlr , Matrix ()
+      bool_property xliminclude hl , "on"
+      bool_property yliminclude hl , "on"
+      bool_property zliminclude hl , "off"
     END_PROPERTIES
+
+  private:
+    Matrix compute_xlim (void) const;
+    Matrix compute_ylim (void) const;
+
+    void update_xdata (void) { set_xlim (compute_xlim ()); }
+    void update_xldata (void) { set_xlim (compute_xlim ()); }
+    void update_xudata (void) { set_xlim (compute_xlim ()); }
+    
+    void update_ydata (void) { set_ylim (compute_ylim ()); }
+    void update_ldata (void) { set_ylim (compute_ylim ()); }
+    void update_udata (void) { set_ylim (compute_ylim ()); }
+
+    void update_zdata (void)
+      {
+	set_zlim (zdata.get_limits ());
+	set_zliminclude (get_zdata ().numel () > 0);
+      }
   };
 
 private:
@@ -2920,7 +2901,7 @@
     BEGIN_PROPERTIES(text)
       string_property string , ""
       radio_property units , "{data}|pixels|normalized|inches|centimeters|points"
-      array_property position , Matrix (1, 3, 0.0)
+      array_property position u , Matrix (1, 3, 0.0)
       double_property rotation , 0
       radio_property horizontalalignment , "{left}|center|right"
       color_property color , color_values (0, 0, 0)
@@ -2939,6 +2920,13 @@
       double_property linewidth , 0.5
       double_property margin , 1
       radio_property verticalalignment , "top|cap|{middle}|baseline|bottom"
+      // hidden properties for limit computation
+      row_vector_property xlim hlr , Matrix ()
+      row_vector_property ylim hlr , Matrix ()
+      row_vector_property zlim hlr , Matrix ()
+      bool_property xliminclude hl , "on"
+      bool_property yliminclude hl , "on"
+      bool_property zliminclude hl , "off"
     END_PROPERTIES
 
   protected:
@@ -2946,6 +2934,31 @@
       {
         position.add_constraint (dim_vector (1, 3));
       }
+
+  private:
+    void update_position (void)
+      {
+	Matrix pos = get_position ().matrix_value ();
+	Matrix lim;
+
+	lim = Matrix (1, 3, pos(0));
+	lim(2) = (lim(2) <= 0 ? octave_Inf : lim(2));
+	set_xlim (lim);
+
+	lim = Matrix (1, 3, pos(1));
+	lim(2) = (lim(2) <= 0 ? octave_Inf : lim(2));
+	set_ylim (lim);
+
+	if (pos.numel () == 3)
+	  {
+	    lim = Matrix (1, 3, pos(2));
+	    lim(2) = (lim(2) <= 0 ? octave_Inf : lim(2));
+	    set_zliminclude ("on");
+	    set_zlim (lim);
+	  }
+	else
+	  set_zliminclude ("off");
+      }
   };
 
 private:
@@ -2975,14 +2988,26 @@
   class OCTINTERP_API properties : public base_properties
   {
   public:
+    bool is_climinclude (void) const
+      { return (climinclude.is_on () && cdatamapping.is ("scaled")); }
+    std::string get_climinclude (void) const
+      { return climinclude.current_value (); }
+
     // See the genprops.awk script for an explanation of the
     // properties declarations.
 
     BEGIN_PROPERTIES(image)
-      row_vector_property xdata l , Matrix ()
-      row_vector_property ydata l , Matrix ()
-      array_property cdata l , Matrix ()
-      radio_property cdatamapping a , "{scaled}|direct"
+      row_vector_property xdata u , Matrix ()
+      row_vector_property ydata u , Matrix ()
+      array_property cdata u , Matrix ()
+      radio_property cdatamapping al , "{scaled}|direct"
+      // hidden properties for limit computation
+      row_vector_property xlim hlr , Matrix()
+      row_vector_property ylim hlr , Matrix()
+      row_vector_property clim hlr , Matrix()
+      bool_property xliminclude hl , "on"
+      bool_property yliminclude hl , "on"
+      bool_property climinclude hlg , "on"
     END_PROPERTIES
 
   protected:
@@ -2995,6 +3020,23 @@
 	cdata.add_constraint (dim_vector (-1, -1));
 	cdata.add_constraint (dim_vector (-1, -1, 3));
       }
+
+  private:
+    // FIXME: limits should take pixel width into account
+    void update_xdata (void)
+      { set_xlim (xdata.get_limits ()); }
+
+    // FIXME: idem
+    void update_ydata (void)
+      { set_ylim (ydata.get_limits ()); }
+
+    void update_cdata (void)
+      {
+	if (cdatamapping_is ("scaled"))
+	  set_clim (cdata.get_limits ());
+	else
+	  clim = cdata.get_limits ();
+      }
   };
 
 private:
@@ -3026,15 +3068,25 @@
   public:
     octave_value get_color_data (void) const;
     
+    bool is_climinclude (void) const
+      { return (climinclude.is_on () && cdatamapping.is ("scaled")); }
+    std::string get_climinclude (void) const
+      { return climinclude.current_value (); }
+
+    bool is_aliminclude (void) const
+      { return (aliminclude.is_on () && alphadatamapping.is ("scaled")); }
+    std::string get_aliminclude (void) const
+      { return aliminclude.current_value (); }
+
     // See the genprops.awk script for an explanation of the
     // properties declarations.
 
     BEGIN_PROPERTIES(patch)
-      array_property xdata l , Matrix ()
-      array_property ydata l , Matrix ()
-      array_property zdata l , Matrix ()
-      array_property cdata l , Matrix ()
-      radio_property cdatamapping , "{scaled}|direct"
+      array_property xdata u , Matrix ()
+      array_property ydata u , Matrix ()
+      array_property zdata u , Matrix ()
+      array_property cdata u , Matrix ()
+      radio_property cdatamapping l , "{scaled}|direct"
       array_property faces , Matrix ()
       array_property facevertexalphadata , Matrix ()
       array_property facevertexcdata , Matrix ()
@@ -3062,6 +3114,18 @@
       double_property markersize , 6
       string_property keylabel , ""
       radio_property interpreter , "{tex}|none|latex"
+      radio_property alphadatamapping l , "none|{scaled}|direct"
+      // hidden properties for limit computation
+      row_vector_property xlim hlr , Matrix ()
+      row_vector_property ylim hlr , Matrix ()
+      row_vector_property zlim hlr , Matrix ()
+      row_vector_property clim hlr , Matrix ()
+      row_vector_property alim hlr , Matrix ()
+      bool_property xliminclude hl , "on"
+      bool_property yliminclude hl , "on"
+      bool_property zliminclude hl , "on"
+      bool_property climinclude hlg , "on"
+      bool_property aliminclude hlg , "on"
     END_PROPERTIES
 
   protected:
@@ -3078,6 +3142,19 @@
 	facevertexcdata.add_constraint (dim_vector (-1, 3));
 	facevertexalphadata.add_constraint (dim_vector (-1, 1));
       }
+
+  private:
+    void update_xdata (void) { set_xlim (xdata.get_limits ()); }
+    void update_ydata (void) { set_ylim (ydata.get_limits ()); }
+    void update_zdata (void) { set_zlim (zdata.get_limits ()); }
+    
+    void update_cdata (void)
+      {
+	if (cdatamapping_is ("scaled"))
+	  set_clim (cdata.get_limits ());
+	else
+	  clim = cdata.get_limits ();
+      }
   };
 
 private:
@@ -3109,15 +3186,25 @@
   public:
     octave_value get_color_data (void) const;
 
+    bool is_climinclude (void) const
+      { return (climinclude.is_on () && cdatamapping.is ("scaled")); }
+    std::string get_climinclude (void) const
+      { return climinclude.current_value (); }
+
+    bool is_aliminclude (void) const
+      { return (aliminclude.is_on () && alphadatamapping.is ("scaled")); }
+    std::string get_aliminclude (void) const
+      { return aliminclude.current_value (); }
+
     // See the genprops.awk script for an explanation of the
     // properties declarations.
 
     BEGIN_PROPERTIES(surface)
-      array_property xdata lu , Matrix ()
-      array_property ydata lu , Matrix ()
-      array_property zdata lu , Matrix ()
-      array_property cdata l , Matrix ()
-      radio_property cdatamapping a , "{scaled}|direct"
+      array_property xdata u , Matrix ()
+      array_property ydata u , Matrix ()
+      array_property zdata u , Matrix ()
+      array_property cdata u , Matrix ()
+      radio_property cdatamapping al , "{scaled}|direct"
       color_property facecolor , "{flat}|none|interp|texturemap"
       double_radio_property facealpha , double_radio_property (1.0, radio_values ("flat|interp"))
       color_property edgecolor , color_property (color_values (0, 0, 0), radio_values ("flat|none|interp"))
@@ -3129,8 +3216,8 @@
       double_property markersize , 6
       string_property keylabel , ""
       radio_property interpreter , "{tex}|none|latex"
-      array_property alphadata , Matrix ()
-      radio_property alphadatamapping , "none|direct|{scaled}"
+      array_property alphadata u , Matrix ()
+      radio_property alphadatamapping l , "none|direct|{scaled}"
       double_property ambientstrength , 0.3
       radio_property backfacelighting , "unlit|lit|{reverselit}"
       double_property diffusestrength , 0.6
@@ -3144,6 +3231,17 @@
       double_property specularexponent , 10
       double_property specularstrength , 0.9
       array_property vertexnormals u , Matrix ()
+      // hidden properties for limit computation
+      row_vector_property xlim hlr , Matrix ()
+      row_vector_property ylim hlr , Matrix ()
+      row_vector_property zlim hlr , Matrix ()
+      row_vector_property clim hlr , Matrix ()
+      row_vector_property alim hlr , Matrix ()
+      bool_property xliminclude hl , "on"
+      bool_property yliminclude hl , "on"
+      bool_property zliminclude hl , "on"
+      bool_property climinclude hlg , "on"
+      bool_property aliminclude hlg , "on"
     END_PROPERTIES
 
   protected:
@@ -3165,9 +3263,39 @@
   private:
     void update_normals (void);
 
-    void update_xdata (void) { update_normals (); }
-    void update_ydata (void) { update_normals (); }
-    void update_zdata (void) { update_normals (); }
+    void update_xdata (void)
+      {
+	update_normals ();
+	set_xlim (xdata.get_limits ());
+      }
+ 
+    void update_ydata (void)
+      {
+	update_normals ();
+	set_ylim (ydata.get_limits ());
+      }
+
+    void update_zdata (void)
+      {
+	update_normals ();
+	set_zlim (zdata.get_limits ());
+      }
+
+    void update_cdata (void)
+      {
+	if (cdatamapping_is ("scaled"))
+	  set_clim (cdata.get_limits ());
+	else
+	  clim = cdata.get_limits ();
+      }
+
+    void update_alphadata (void)
+      {
+	if (alphadatamapping_is ("scaled"))
+	  set_alim (alphadata.get_limits ());
+	else
+	  alim = alphadata.get_limits ();
+      }
 
     void update_normalmode (void)
       { update_normals (); }