Revision: 3865
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3865&view=rev
Author:   mdboom
Date:     2007-09-20 06:57:59 -0700 (Thu, 20 Sep 2007)

Log Message:
-----------
Go all out with iterator (rather than copy) approach, as it is much faster.

Modified Paths:
--------------
    branches/transforms/lib/matplotlib/backend_bases.py
    branches/transforms/lib/matplotlib/backends/backend_agg.py
    branches/transforms/lib/matplotlib/transforms.py
    branches/transforms/src/_backend_agg.cpp
    branches/transforms/src/_backend_agg.h

Modified: branches/transforms/lib/matplotlib/backend_bases.py
===================================================================
--- branches/transforms/lib/matplotlib/backend_bases.py 2007-09-20 13:57:32 UTC 
(rev 3864)
+++ branches/transforms/lib/matplotlib/backend_bases.py 2007-09-20 13:57:59 UTC 
(rev 3865)
@@ -17,11 +17,6 @@
 class RendererBase:
     """An abstract base class to handle drawing/rendering operations
     """
-    # This will cache paths across rendering instances
-    # Each subclass of RenderBase should define this a weak-keyed
-    # dictionary to hold native paths
-    # _native_paths = weakref.WeakKeyDictionary()
-    
     def __init__(self):
         self._texmanager = None
 
@@ -37,43 +32,16 @@
         """
         pass
 
-    def _get_cached_native_path(self, path):
-       native_path = self._native_paths.get(path)
-       if native_path is None:
-           print "CACHE MISS", path
-           native_path = self.convert_to_native_path(path)
-           self._native_paths[path] = native_path
-       return native_path
-    
     def draw_path(self, gc, path, transform, rgbFace=None):
        """
        Handles the caching of the native path associated with the
        given path and calls the underlying backend's _draw_path to
        actually do the drawing.
        """
-       native_path = self._get_cached_native_path(path)
-       self._draw_native_path(gc, native_path, transform, rgbFace)
+        # MGDTODO: Update docstring
+        raise NotImplementedError
 
-    def _draw_native_path(self, gc, native_path, transform, rgbFace):
-       """
-       Draw the native path object with the given GraphicsContext and
-       transform.  The transform passed in will always be affine.
-       """
-       raise NotImplementedError
-       
-    def convert_to_native_path(self, path):
-       """
-       Backends will normally will override this, but if they don't need any
-       special optimizations, they can just have the generic path data
-       passed to them in draw_path.
-       """
-       return path
-
     def draw_markers(self, gc, marker_path, marker_trans, path, trans, 
rgbFace=None):
-       native_marker_path = self._get_cached_native_path(marker_path)
-       self._draw_native_markers(gc, native_marker_path, marker_trans, path, 
trans, rgbFace)
-       
-    def _draw_native_markers(self, gc, native_marker_path, marker_trans, path, 
trans, rgbFace=None):
         """
         This method is currently underscore hidden because the
         draw_markers method is being used as a sentinel for newstyle
@@ -94,7 +62,11 @@
         vec6 = transform.as_vec6_val()
         ...backend dependent affine...
         """
+        # MGDTODO: Update docstring
         raise NotImplementedError
+       
+    def _draw_native_markers(self, gc, native_marker_path, marker_trans, path, 
trans, rgbFace=None):
+        raise NotImplementedError
 
     def get_image_magnification(self):
         """

Modified: branches/transforms/lib/matplotlib/backends/backend_agg.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_agg.py  2007-09-20 
13:57:32 UTC (rev 3864)
+++ branches/transforms/lib/matplotlib/backends/backend_agg.py  2007-09-20 
13:57:59 UTC (rev 3865)
@@ -117,8 +117,8 @@
                                      debug=False)
         if __debug__: verbose.report('RendererAgg.__init__ _RendererAgg done',
                                      'debug-annoying')
-
-       self.convert_to_native_path = self._renderer.convert_to_native_path
+        self.draw_path = self._renderer.draw_path
+        self.draw_markers = self._renderer.draw_markers
         self.draw_image = self._renderer.draw_image
         self.copy_from_bbox = self._renderer.copy_from_bbox
         self.restore_region = self._renderer.restore_region
@@ -129,16 +129,6 @@
         if __debug__: verbose.report('RendererAgg.__init__ done',
                                      'debug-annoying')
 
-    def _draw_native_path(self, gc, path, transform, rgbFace):
-       return self._renderer.draw_path(gc, path, transform.get_matrix(), 
rgbFace)
-    
-    def _draw_native_markers(self, gc, native_marker_path, marker_trans, path, 
trans, rgbFace=None):
-       return self._renderer.draw_markers(
-           gc,
-           native_marker_path, marker_trans.get_matrix(),
-           path.vertices, path.codes, trans.get_matrix(),
-           rgbFace)
-
     def draw_mathtext(self, gc, x, y, s, prop, angle):
         """
         Draw the math text using matplotlib.mathtext

Modified: branches/transforms/lib/matplotlib/transforms.py
===================================================================
--- branches/transforms/lib/matplotlib/transforms.py    2007-09-20 13:57:32 UTC 
(rev 3864)
+++ branches/transforms/lib/matplotlib/transforms.py    2007-09-20 13:57:59 UTC 
(rev 3865)
@@ -365,7 +365,7 @@
         Transform.__init__(self)
         self._inverted = None
 
-    def __array__(self):
+    def __array__(self, *args, **kwargs):
        return self.get_matrix()
        
     def _do_invalidation(self):

Modified: branches/transforms/src/_backend_agg.cpp
===================================================================
--- branches/transforms/src/_backend_agg.cpp    2007-09-20 13:57:32 UTC (rev 
3864)
+++ branches/transforms/src/_backend_agg.cpp    2007-09-20 13:57:59 UTC (rev 
3865)
@@ -48,59 +48,42 @@
 agg::trans_affine py_to_agg_transformation_matrix(const Py::Object& obj) {
   PyArrayObject* matrix = NULL;
   
-  double a = 1.0, b = 0.0, c = 0.0, d = 1.0, e = 0.0, f = 0.0;
-
   try {
-    matrix = (PyArrayObject*) PyArray_ContiguousFromObject(obj.ptr(), 
PyArray_DOUBLE, 2, 2);
-    if (!matrix || matrix->nd != 2 || matrix->dimensions[0] != 3 || 
matrix->dimensions[1] != 3) {
-      throw Py::ValueError("Invalid affine transformation matrix.");
+    matrix = (PyArrayObject*) PyArray_FromObject(obj.ptr(), PyArray_DOUBLE, 2, 
2);
+    if (!matrix) {
+      throw Py::Exception();
     }
-
-    size_t stride0 = matrix->strides[0];
-    size_t stride1 = matrix->strides[1];
-    char* row0 = matrix->data;
-    char* row1 = row0 + stride0;
-
-    a = *(double*)(row0);
-    row0 += stride1;
-    c = *(double*)(row0);
-    row0 += stride1;
-    e = *(double*)(row0);
-    
-    b = *(double*)(row1);
-    row1 += stride1;
-    d = *(double*)(row1);
-    row1 += stride1;
-    f = *(double*)(row1);
+    if (matrix->nd == 2 || matrix->dimensions[0] == 3 || matrix->dimensions[1] 
== 3) {
+      size_t stride0 = matrix->strides[0];
+      size_t stride1 = matrix->strides[1];
+      char* row0 = matrix->data;
+      char* row1 = row0 + stride0;
+      
+      double a = *(double*)(row0);
+      row0 += stride1;
+      double c = *(double*)(row0);
+      row0 += stride1;
+      double e = *(double*)(row0);
+      
+      double b = *(double*)(row1);
+      row1 += stride1;
+      double d = *(double*)(row1);
+      row1 += stride1;
+      double f = *(double*)(row1);
+      
+      Py_XDECREF(matrix);
+      
+      return agg::trans_affine(a, b, c, d, e, f);
+    }
   } catch (...) {
-    Py_XDECREF(matrix);
+    
   }
 
   Py_XDECREF(matrix);
-
-  return agg::trans_affine(a, b, c, d, e, f);
+  throw Py::TypeError("Invalid affine transformation matrix");
 }
 
-/** Helper function to get the next vertex in a Numpy array of vertices.
- *  Will generally be used through the GET_NEXT_VERTEX macro.
- */
-inline void get_next_vertex(const char* & vertex_i, const char* vertex_end, 
-                           double& x, double& y,
-                           size_t next_vertex_stride, 
-                           size_t next_axis_stride,
-                           const char* & code_i, size_t code_stride) {
-  if (vertex_i + next_axis_stride >= vertex_end)
-    throw Py::ValueError("Error parsing path.  Read past end of vertices");
-  x = *(double*)vertex_i;
-  y = *(double*)(vertex_i + next_axis_stride);
-  vertex_i += next_vertex_stride;
-  code_i += code_stride;
-}
-
-#define GET_NEXT_VERTEX(x, y) get_next_vertex(vertex_i, vertex_end, x, y, 
next_vertex_stride, next_axis_stride, code_i, code_stride)
-
 Py::Object BufferRegion::to_string(const Py::Tuple &args) {
-  
   // owned=true to prevent memory leak
   return Py::String(PyString_FromStringAndSize((const 
char*)aggbuf.data,aggbuf.height*aggbuf.stride), true);
 }
@@ -145,7 +128,6 @@
     double* pv = (double*)(vertices->data + (idx * vertices->strides[0]));
     *x = *pv++;
     *y = *pv;
-    // MGDTODO: Range check
     return code_map[(unsigned int)*(codes->data + (idx * codes->strides[0]))];
   }
 
@@ -170,9 +152,43 @@
                                       agg::path_cmd_curve4,
                                       agg::path_cmd_end_poly | 
agg::path_flags_close};
 
+template<class VertexSource> class conv_quantize
+{
+public:
+  conv_quantize(VertexSource& source, bool quantize) :
+    m_source(&source), m_quantize(quantize) {}
+  
+  void set_source(VertexSource& source) { m_source = &source; }
+
+  void rewind(unsigned path_id) 
+  { 
+    m_source->rewind(path_id); 
+  }
+
+  unsigned vertex(double* x, double* y)
+  {
+    unsigned cmd = m_source->vertex(x, y);
+    if(m_quantize && agg::is_vertex(cmd))
+      {
+       *x = (int)(*x);
+       *y = (int)(*y);
+      }
+    return cmd;
+  }
+
+  void activate(bool quantize) {
+    m_quantize = quantize;
+  }
+
+private:
+  VertexSource*      m_source;
+  bool m_quantize;
+};
+
+
 GCAgg::GCAgg(const Py::Object &gc, double dpi, bool snapto) :
   dpi(dpi), snapto(snapto), isaa(true), linewidth(1.0), alpha(1.0),
-  cliprect(NULL), clippath(NULL), 
+  cliprect(NULL), 
   Ndash(0), dashOffset(0.0), dasha(NULL)
 {
   _VERBOSE("GCAgg::GCAgg");
@@ -316,15 +332,7 @@
   
   _VERBOSE("GCAgg::_set_clip_path");
   
-  Py_XINCREF(clippath);
-  clippath = NULL;
-  
-  Py::Object o = gc.getAttr("_clippath");
-  if (o.ptr()==Py_None) {
-    return;
-  }
-  
-  clippath = new PathAgg(o);
+  clippath = gc.getAttr("_clippath");
 }
 
 
@@ -337,8 +345,7 @@
   height(height),
   dpi(dpi),
   NUMBYTES(width*height*4),
-  debug(debug),
-  lastclippath(NULL)
+  debug(debug)
 {
   _VERBOSE("RendererAgg::RendererAgg");
   unsigned stride(width*4);
@@ -599,7 +606,7 @@
 
 Py::Object
 RendererAgg::draw_markers(const Py::Tuple& args) {
-  typedef agg::conv_transform<agg::path_storage> transformed_path_t;
+  typedef agg::conv_transform<PathIterator> transformed_path_t;
   typedef agg::conv_curve<transformed_path_t> curve_t;
   typedef agg::conv_stroke<curve_t> stroke_t;
   typedef agg::conv_dash<curve_t> dash_t;
@@ -607,27 +614,29 @@
 
   theRasterizer->reset_clipping();
   
-  args.verify_length(7);
+  args.verify_length(5, 6);
   
   GCAgg gc = GCAgg(args[0], dpi);
   Py::Object marker_path_obj = args[1];
-  if (!PathAgg::check(marker_path_obj))
-    throw Py::TypeError("Native path object is not of correct type");
-  PathAgg* marker_path = static_cast<PathAgg*>(marker_path_obj.ptr());
   agg::trans_affine marker_trans = py_to_agg_transformation_matrix(args[2]);
-  Py::Object vertices_obj = args[3];
-  Py::Object codes_obj = args[4];
-  agg::trans_affine trans = py_to_agg_transformation_matrix(args[5]);
-  facepair_t face = _get_rgba_face(args[6], gc.alpha);
+  Py::Object path_obj = args[3];
+  agg::trans_affine trans = py_to_agg_transformation_matrix(args[4]);
+  Py::Object face_obj;
+  if (args.size() == 6)
+    face_obj = args[5];
+  facepair_t face = _get_rgba_face(face_obj, gc.alpha);
 
   // Deal with the difference in y-axis direction
   marker_trans *= agg::trans_affine_scaling(1.0, -1.0);
   trans *= agg::trans_affine_scaling(1.0, -1.0);
   trans *= agg::trans_affine_translation(0.0, (double)height);
   
-  marker_path->rewind(0);
-  transformed_path_t marker_path_transformed(*marker_path, marker_trans);
+  PathIterator marker_path(marker_path_obj);
+  transformed_path_t marker_path_transformed(marker_path, marker_trans);
   curve_t marker_path_curve(marker_path_transformed);
+
+  PathIterator path(path_obj);
+  transformed_path_t path_transformed(path, trans);
   
   //maxim's suggestions for cached scanlines
   agg::scanline_storage_aa8 scanlines;
@@ -635,19 +644,8 @@
   
   agg::int8u* fillCache = NULL;
   agg::int8u* strokeCache = NULL;
-  PyArrayObject* vertices = NULL;
-  PyArrayObject* codes = NULL;
 
   try {
-    vertices = (PyArrayObject*)PyArray_ContiguousFromObject
-      (vertices_obj.ptr(), PyArray_DOUBLE, 2, 2);
-    if (!vertices || vertices->nd != 2 || vertices->dimensions[1] != 2)
-      throw Py::ValueError("Invalid vertices array.");
-    codes = (PyArrayObject*)PyArray_ContiguousFromObject
-      (codes_obj.ptr(), PyArray_UINT8, 1, 1);
-    if (!codes) 
-      throw Py::ValueError("Invalid codes array.");
-
     unsigned fillSize = 0;
     if (face.first) {
       theRasterizer->add_path(marker_path_curve);
@@ -681,53 +679,29 @@
       rendererBase->clip_box(l, height-(b+h),l+w, height-b);
     }
     
-    size_t next_vertex_stride = vertices->strides[0];
-    size_t next_axis_stride = vertices->strides[1];
-    size_t code_stride = codes->strides[0];
-
-    const char* vertex_i = vertices->data;
-    const char* code_i = codes->data;
-    const char* vertex_end = vertex_i + (vertices->dimensions[0] * 
vertices->strides[0]);
-
-    size_t N = codes->dimensions[0];
     double x, y;
 
     agg::serialized_scanlines_adaptor_aa8 sa;
     agg::serialized_scanlines_adaptor_aa8::embedded_scanline sl;
 
-    for (size_t i=0; i < N; i++) {
-      size_t num_vertices = NUM_VERTICES[(int)(*code_i)];
-      if (num_vertices) {
-       for (size_t j=0; j<num_vertices; ++j)
-         GET_NEXT_VERTEX(x, y);
-       if (*code_i == STOP || *code_i == CLOSEPOLY)
-         continue;
-
-       trans.transform(&x, &y);
-       
-       if (face.first) {
-         //render the fill
-         sa.init(fillCache, fillSize, x, y);
-         rendererAA->color(face.second);
-         agg::render_scanlines(sa, sl, *rendererAA);
-       }
-
-       //render the stroke
-       sa.init(strokeCache, strokeSize, x, y);
-       rendererAA->color(gc.color);
+    while (path_transformed.vertex(&x, &y) != agg::path_cmd_stop) {
+      if (face.first) {
+       //render the fill
+       sa.init(fillCache, fillSize, x, y);
+       rendererAA->color(face.second);
        agg::render_scanlines(sa, sl, *rendererAA);
       }
-      code_i += code_stride;
+      
+      //render the stroke
+      sa.init(strokeCache, strokeSize, x, y);
+      rendererAA->color(gc.color);
+      agg::render_scanlines(sa, sl, *rendererAA);
     }
   } catch(...) {
-    Py_XDECREF(vertices);
-    Py_XDECREF(codes);
     delete[] fillCache;
     delete[] strokeCache;
   }
   
-  Py_XDECREF(vertices);
-  Py_XDECREF(codes);
   delete [] fillCache;
   delete [] strokeCache;
 
@@ -888,98 +862,12 @@
   
 }
 
-Py::Object
-RendererAgg::convert_to_native_path(const Py::Tuple& args) {
-  _VERBOSE("RendererAgg::draw_image");
-  args.verify_length(1);
-  
-  Py::Object path = args[0];
 
-  return Py::asObject(new PathAgg(path));
-}
-
-  
-PathAgg::PathAgg(const Py::Object& path_obj) : curvy(false) {
-  Py::Object vertices_obj = path_obj.getAttr("vertices");
-  Py::Object codes_obj = path_obj.getAttr("codes");
-  
-  PyArrayObject* vertices = NULL;
-  PyArrayObject* codes = NULL;
-
-  try {
-    vertices = (PyArrayObject*)PyArray_ContiguousFromObject
-      (vertices_obj.ptr(), PyArray_DOUBLE, 2, 2);
-    if (!vertices || vertices->nd != 2 || vertices->dimensions[1] != 2)
-      throw Py::ValueError("Invalid vertices array.");
-    codes = (PyArrayObject*)PyArray_ContiguousFromObject
-      (codes_obj.ptr(), PyArray_UINT8, 1, 1);
-    if (!codes) 
-      throw Py::ValueError("Invalid codes array.");
-
-    size_t next_vertex_stride = vertices->strides[0];
-    size_t next_axis_stride = vertices->strides[1];
-    size_t code_stride = codes->strides[0];
-
-    const char* vertex_i = vertices->data;
-    const char* code_i = codes->data;
-    const char* vertex_end = vertex_i + (vertices->dimensions[0] * 
vertices->strides[0]);
-
-    size_t N = codes->dimensions[0];
-    double x0, y0, x1, y1, x2, y2;
-
-    for (size_t i = 0; i < N; ++i) {
-      switch (*(unsigned char*)(code_i)) {
-      case STOP:
-       GET_NEXT_VERTEX(x0, y0);
-       _VERBOSE("STOP");
-       // MGDTODO: If this isn't the end, we should raise an error
-       break;
-      case MOVETO:
-       GET_NEXT_VERTEX(x0, y0);
-       move_to(x0, y0);
-       _VERBOSE("MOVETO");
-       break;
-      case LINETO:
-       GET_NEXT_VERTEX(x0, y0);
-       line_to(x0, y0);
-       _VERBOSE("LINETO");
-       break;
-      case CURVE3:
-       GET_NEXT_VERTEX(x0, y0);
-       GET_NEXT_VERTEX(x1, y1);
-       curve3(x0, y0, x1, y1);
-       curvy = true;
-       _VERBOSE("CURVE3");
-       break;
-      case CURVE4:
-       GET_NEXT_VERTEX(x0, y0);
-       GET_NEXT_VERTEX(x1, y1);
-       GET_NEXT_VERTEX(x2, y2);
-       curve4(x0, y0, x1, y1, x2, y2);
-       curvy = true;
-       _VERBOSE("CURVE4");
-       break;
-      case CLOSEPOLY:
-       close_polygon();
-       GET_NEXT_VERTEX(x0, y0);
-       _VERBOSE("CLOSEPOLY");
-       break;
-      }
-    }
-  } catch(...) {
-    Py_XDECREF(vertices);
-    Py_XDECREF(codes);
-    throw;
-  }
-
-  Py_XDECREF(vertices);
-  Py_XDECREF(codes);
-}
-
 Py::Object
 RendererAgg::draw_path(const Py::Tuple& args) {
   typedef agg::conv_transform<PathIterator> transformed_path_t;
-  typedef agg::conv_curve<transformed_path_t> curve_t;
+  typedef conv_quantize<transformed_path_t> quantize_t;
+  typedef agg::conv_curve<quantize_t> curve_t;
   typedef agg::conv_stroke<curve_t> stroke_t;
   typedef agg::conv_dash<curve_t> dash_t;
   typedef agg::conv_stroke<dash_t> stroke_dash_t;
@@ -991,61 +879,59 @@
   theRasterizer->reset_clipping();
   
   _VERBOSE("RendererAgg::draw_path");
-  args.verify_length(4);
+  args.verify_length(3, 4);
 
-  GCAgg gc = GCAgg(args[0], dpi);
+  Py::Object gc_obj = args[0];
   Py::Object path_obj = args[1];
-//   if (!PathAgg::check(path_obj))
-//     throw Py::TypeError("Native path object is not of correct type");
-  // PathAgg* path = static_cast<PathAgg*>(path_obj.ptr());
   PathIterator path(path_obj);
 
   agg::trans_affine trans = py_to_agg_transformation_matrix(args[2]);
-  facepair_t face = _get_rgba_face(args[3], gc.alpha);
 
   trans *= agg::trans_affine_scaling(1.0, -1.0);
   trans *= agg::trans_affine_translation(0.0, (double)height);
 
-  transformed_path_t* tpath = NULL;
-  agg::path_storage new_path;
+  bool snap = false;
+  if (path.total_vertices() == 2) {
+    double x0, y0, x1, y1;
+    path.vertex(0, &x0, &y0);
+    trans.transform(&x0, &y0);
+    path.vertex(1, &x1, &y1);
+    trans.transform(&x1, &y1);
+    snap = ((int)x0 == (int)x1) || ((int)y0 == (int)y1);
+  }
 
-  bool has_clippath = (gc.clippath != NULL);
+  GCAgg gc = GCAgg(gc_obj, dpi, snap);
+  Py::Object face_obj;
+  if (args.size() == 4)
+    face_obj = args[3];
+  facepair_t face = _get_rgba_face(face_obj, gc.alpha);
 
-  if (has_clippath && (gc.clippath != lastclippath || trans != 
lastclippath_transform)) {
-//     rendererBaseAlphaMask->clear(agg::gray8(0, 0));
-//     gc.clippath->rewind(0);
-//     transformed_path_t transformed_clippath(*(gc.clippath), trans);
-//     theRasterizer->add_path(transformed_clippath);
-//     rendererAlphaMask->color(agg::gray8(255, 255));
-//     agg::render_scanlines(*theRasterizer, *scanlineAlphaMask, 
*rendererAlphaMask);
-//     lastclippath = gc.clippath;
-//     lastclippath_transform = trans;
+  bool has_clippath = (gc.clippath.ptr() != Py_None);
+
+  if (has_clippath && 
+      (gc.clippath.ptr() != lastclippath.ptr() || trans != 
lastclippath_transform)) {
+    PathIterator clippath(gc.clippath);
+    rendererBaseAlphaMask->clear(agg::gray8(0, 0));
+    transformed_path_t transformed_clippath(clippath, trans);
+    agg::conv_curve<transformed_path_t> curved_clippath(transformed_clippath);
+    theRasterizer->add_path(curved_clippath);
+    rendererAlphaMask->color(agg::gray8(255, 255));
+    agg::render_scanlines(*theRasterizer, *scanlineAlphaMask, 
*rendererAlphaMask);
+    lastclippath = gc.clippath;
+    lastclippath_transform = trans;
   }
 
   try {
     // If this is a straight horizontal or vertical line, quantize to nearest 
     // pixels
-//     if (path.total_vertices() == 2) {
-//       double x0, y0, x1, y1;
-//       path.vertex(0, &x0, &y0);
-//       trans.transform(&x0, &y0);
-//       path.vertex(1, &x1, &y1);
-//       trans.transform(&x1, &y1);
-//       if (((int)x0 == (int)x1) || ((int)y0 == (int)y1)) {
-//     new_path.move_to((int)x0 + 0.5, (int)y0 + 0.5);
-//     new_path.line_to((int)x1 + 0.5, (int)y1 + 0.5);
-//     tpath = new transformed_path_t(new_path, agg::trans_affine());
-//       }
-//     }
 
-    if (!tpath) {
-      tpath = new transformed_path_t(path, trans);
-    }
+    transformed_path_t tpath(path, trans);
+    quantize_t quantized(tpath, snap);
 
     // Benchmarking shows that there is no noticable slowdown to always
     // treating paths as having curved segments.  Doing so greatly 
     // simplifies the code
-    curve_t curve(*tpath);
+    curve_t curve(quantized);
     
     set_clipbox_rasterizer(gc.cliprect);
     
@@ -1106,12 +992,11 @@
       }
     }
   } catch (...) {
-    delete tpath;
+    // MGDTODO: We don't have anything on the heap, so this catch
+    // clause isn't really necessary, but we might again soon...
     throw;
   }
   
-  delete tpath;
-
   return Py::Object();
 }
 
@@ -1446,11 +1331,9 @@
   behaviors().doc("The agg backend extension module");
   
   add_varargs_method("draw_path", &RendererAgg::draw_path,
-                    "draw_path(gc, rgbFace, native_path, transform)\n");
-  add_varargs_method("convert_to_native_path", 
&RendererAgg::convert_to_native_path,
-                    "convert_to_native_path(vertices, codes)\n");
+                    "draw_path(gc, path, transform, rgbFace)\n");
   add_varargs_method("draw_markers", &RendererAgg::draw_markers,
-                    "draw_markers(gc, marker_path, marker_trans, vertices, 
codes, rgbFace)\n");
+                    "draw_markers(gc, marker_path, marker_trans, path, 
rgbFace)\n");
   add_varargs_method("draw_text_image", &RendererAgg::draw_text_image,
                     "draw_text_image(font_image, x, y, r, g, b, a)\n");
   add_varargs_method("draw_image", &RendererAgg::draw_image,
@@ -1476,12 +1359,6 @@
                     "restore_region(region)");
 }
 
-void PathAgg::init_type()
-{
-  behaviors().name("PathAgg");
-  behaviors().doc("A native Agg path object");
-}
-
 extern "C"
 DL_EXPORT(void)
   init_backend_agg(void)

Modified: branches/transforms/src/_backend_agg.h
===================================================================
--- branches/transforms/src/_backend_agg.h      2007-09-20 13:57:32 UTC (rev 
3864)
+++ branches/transforms/src/_backend_agg.h      2007-09-20 13:57:59 UTC (rev 
3865)
@@ -105,20 +105,6 @@
   };
 };
 
-// A completely opaque data type used only to pass native path
-// data to/from Python.  Python can't do anything with the data
-// other than create and then use it.
-class PathAgg : 
-  public agg::path_storage, 
-  public Py::PythonExtension<PathAgg> {
-public:
-  static void init_type(void);
-
-  PathAgg(const Py::Object& path_obj);
-
-  bool curvy;
-};
-
 class GCAgg {
 public:
   GCAgg(const Py::Object& gc, double dpi, bool snapto=false);
@@ -126,7 +112,6 @@
   ~GCAgg() {
     delete [] dasha;
     delete [] cliprect;
-    Py_XINCREF(clippath);
   }
 
   double dpi;
@@ -142,7 +127,7 @@
   agg::rgba color;
 
   double *cliprect;
-  PathAgg *clippath;
+  Py::Object clippath;
   //dashes
   size_t Ndash;
   double dashOffset;
@@ -183,7 +168,6 @@
   Py::Object draw_text_image(const Py::Tuple & args);
   Py::Object draw_image(const Py::Tuple & args);
   Py::Object draw_path(const Py::Tuple & args);
-  Py::Object convert_to_native_path(const Py::Tuple & args);
 
   Py::Object write_rgba(const Py::Tuple & args);
   Py::Object write_png(const Py::Tuple & args);
@@ -240,7 +224,7 @@
   void set_clipbox_rasterizer( double *cliprect);
 
 private:
-  PathAgg *lastclippath;
+  Py::Object lastclippath;
   agg::trans_affine lastclippath_transform;
 };
 
@@ -253,7 +237,6 @@
     : Py::ExtensionModule<_backend_agg_module>( "_backend_agg" )
   {
     RendererAgg::init_type();
-    PathAgg::init_type();
 
     add_keyword_method("RendererAgg", &_backend_agg_module::new_renderer,
                       "RendererAgg(width, height, dpi)");


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Matplotlib-checkins mailing list
Matplotlib-checkins@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to