SourceForge logo
SourceForge logo
Menu

matplotlib-checkins

From: <md...@us...> - 2007年10月24日 17:11:12
Revision: 3993
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3993&view=rev
Author: mdboom
Date: 2007年10月24日 10:11:00 -0700 (2007年10月24日)
Log Message:
-----------
Forgot to svn add these files in last commit.
Added Paths:
-----------
 branches/transforms/src/_path.cpp
 branches/transforms/src/agg_py_transforms.h
Added: branches/transforms/src/_path.cpp
===================================================================
--- branches/transforms/src/_path.cpp	 (rev 0)
+++ branches/transforms/src/_path.cpp	2007年10月24日 17:11:00 UTC (rev 3993)
@@ -0,0 +1,384 @@
+#include "agg_py_path_iterator.h"
+#include "agg_py_transforms.h"
+
+#include "CXX/Extensions.hxx"
+
+#include "agg_conv_curve.h"
+#include "agg_conv_stroke.h"
+#include "agg_conv_transform.h"
+#include "agg_path_storage.h"
+#include "agg_trans_affine.h"
+
+// the extension module
+class _path_module : public Py::ExtensionModule<_path_module>
+{
+public:
+ _path_module()
+ : Py::ExtensionModule<_path_module>( "_path" )
+ {
+ add_varargs_method("point_in_path", &_path_module::point_in_path,
+		 "point_in_path(x, y, path, trans)");
+ add_varargs_method("point_on_path", &_path_module::point_on_path,
+		 "point_on_path(x, y, r, path, trans)");
+ add_varargs_method("get_path_extents", &_path_module::get_path_extents,
+		 "get_path_extents(path, trans)");
+ add_varargs_method("get_path_collection_extents", &_path_module::get_path_collection_extents,
+		 "get_path_collection_extents(trans, paths, transforms, offsets, offsetTrans)");
+ add_varargs_method("point_in_path_collection", &_path_module::point_in_path_collection,
+		 "point_in_path_collection(x, y, r, trans, paths, transforms, offsets, offsetTrans, filled)");
+
+ initialize("Helper functions for paths");
+ }
+
+ virtual ~_path_module() {}
+
+private:
+
+ Py::Object point_in_path(const Py::Tuple& args);
+ Py::Object point_on_path(const Py::Tuple& args);
+ Py::Object get_path_extents(const Py::Tuple& args);
+ Py::Object get_path_collection_extents(const Py::Tuple& args);
+ Py::Object point_in_path_collection(const Py::Tuple& args);
+};
+
+//
+// The following function was found in the Agg 2.3 examples (interactive_polygon.cpp).
+// It has been generalized to work on (possibly curved) polylines, rather than
+// just polygons. The original comments have been kept intact.
+// -- Michael Droettboom 2007年10月02日
+//
+//======= Crossings Multiply algorithm of InsideTest ======================== 
+//
+// By Eric Haines, 3D/Eye Inc, er...@ey...
+//
+// This version is usually somewhat faster than the original published in
+// Graphics Gems IV; by turning the division for testing the X axis crossing
+// into a tricky multiplication test this part of the test became faster,
+// which had the additional effect of making the test for "both to left or
+// both to right" a bit slower for triangles than simply computing the
+// intersection each time. The main increase is in triangle testing speed,
+// which was about 15% faster; all other polygon complexities were pretty much
+// the same as before. On machines where division is very expensive (not the
+// case on the HP 9000 series on which I tested) this test should be much
+// faster overall than the old code. Your mileage may (in fact, will) vary,
+// depending on the machine and the test data, but in general I believe this
+// code is both shorter and faster. This test was inspired by unpublished
+// Graphics Gems submitted by Joseph Samosky and Mark Haigh-Hutchinson.
+// Related work by Samosky is in:
+//
+// Samosky, Joseph, "SectionView: A system for interactively specifying and
+// visualizing sections through three-dimensional medical image data",
+// M.S. Thesis, Department of Electrical Engineering and Computer Science,
+// Massachusetts Institute of Technology, 1993.
+//
+// Shoot a test ray along +X axis. The strategy is to compare vertex Y values
+// to the testing point's Y and quickly discard edges which are entirely to one
+// side of the test ray. Note that CONVEX and WINDING code can be added as
+// for the CrossingsTest() code; it is left out here for clarity.
+//
+// Input 2D polygon _pgon_ with _numverts_ number of vertices and test point
+// _point_, returns 1 if inside, 0 if outside.
+template<class T>
+bool point_in_path_impl(double tx, double ty, T& path) {
+ int yflag0, yflag1, inside_flag;
+ double vtx0, vty0, vtx1, vty1, sx, sy;
+ double x, y;
+
+ path.rewind(0);
+ unsigned code = path.vertex(&x, &y);
+ if (code == agg::path_cmd_stop)
+ return false;
+
+ while (true) {
+ sx = vtx0 = x;
+ sy = vty0 = y;
+
+ // get test bit for above/below X axis
+ yflag0 = (vty0 >= ty);
+
+ vtx1 = x;
+ vty1 = x;
+
+ inside_flag = 0;
+ while (true) {
+ code = path.vertex(&x, &y);
+
+ // The following cases denote the beginning on a new subpath
+ if ((code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly) {
+	x = sx; y = sy;
+ } else if (code == agg::path_cmd_move_to)
+	break;
+ 
+ yflag1 = (vty1 >= ty);
+ // Check if endpoints straddle (are on opposite sides) of X axis
+ // (i.e. the Y's differ); if so, +X ray could intersect this edge.
+ // The old test also checked whether the endpoints are both to the
+ // right or to the left of the test point. However, given the faster
+ // intersection point computation used below, this test was found to
+ // be a break-even proposition for most polygons and a loser for
+ // triangles (where 50% or more of the edges which survive this test
+ // will cross quadrants and so have to have the X intersection computed
+ // anyway). I credit Joseph Samosky with inspiring me to try dropping
+ // the "both left or both right" part of my code.
+ if (yflag0 != yflag1) {
+	// Check intersection of pgon segment with +X ray.
+	// Note if >= point's X; if so, the ray hits it.
+	// The division operation is avoided for the ">=" test by checking
+	// the sign of the first vertex wrto the test point; idea inspired
+	// by Joseph Samosky's and Mark Haigh-Hutchinson's different
+	// polygon inclusion tests.
+	if ( ((vty1-ty) * (vtx0-vtx1) >=
+	 (vtx1-tx) * (vty0-vty1)) == yflag1 ) {
+	 inside_flag ^= 1;
+	}
+ }
+
+ // Move to the next pair of vertices, retaining info as possible.
+ yflag0 = yflag1;
+ vtx0 = vtx1;
+ vty0 = vty1;
+	
+ vtx1 = x;
+ vty1 = y;
+
+ if (code == agg::path_cmd_stop || 
+	 (code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly)
+	break;
+ }
+
+ if (inside_flag != 0)
+ return true;
+
+ if (code == agg::path_cmd_stop)
+ return false;
+ }
+
+ return false;
+}
+
+bool point_in_path(double x, double y, PathIterator& path, agg::trans_affine& trans) {
+ typedef agg::conv_transform<PathIterator> transformed_path_t;
+ typedef agg::conv_curve<transformed_path_t> curve_t;
+ 
+ transformed_path_t trans_path(path, trans);
+ curve_t curved_path(trans_path);
+ return point_in_path_impl(x, y, curved_path);
+}
+
+bool point_on_path(double x, double y, double r, PathIterator& path, agg::trans_affine& trans) {
+ 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;
+
+ transformed_path_t trans_path(path, trans);
+ curve_t curved_path(trans_path);
+ stroke_t stroked_path(curved_path);
+ stroked_path.width(r * 2.0);
+ return point_in_path_impl(x, y, stroked_path);
+}
+
+Py::Object _path_module::point_in_path(const Py::Tuple& args) {
+ args.verify_length(4);
+ 
+ double x = Py::Float(args[0]);
+ double y = Py::Float(args[1]);
+ PathIterator path(args[2]);
+ agg::trans_affine trans = py_to_agg_transformation_matrix(args[3]);
+
+ if (::point_in_path(x, y, path, trans))
+ return Py::Int(1);
+ return Py::Int(0);
+}
+
+Py::Object _path_module::point_on_path(const Py::Tuple& args) {
+ args.verify_length(5);
+ 
+ double x = Py::Float(args[0]);
+ double y = Py::Float(args[1]);
+ double r = Py::Float(args[2]);
+ PathIterator path(args[3]);
+ agg::trans_affine trans = py_to_agg_transformation_matrix(args[4]);
+
+ if (::point_on_path(x, y, r, path, trans))
+ return Py::Int(1);
+ return Py::Int(0);
+}
+
+void get_path_extents(PathIterator& path, agg::trans_affine& trans, 
+		 double* x0, double* y0, double* x1, double* y1) {
+ typedef agg::conv_transform<PathIterator> transformed_path_t;
+ typedef agg::conv_curve<transformed_path_t> curve_t;
+ double x, y;
+ unsigned code;
+
+ transformed_path_t tpath(path, trans);
+ curve_t curved_path(tpath);
+
+ curved_path.rewind(0);
+
+ while ((code = curved_path.vertex(&x, &y)) != agg::path_cmd_stop) {
+ if ((code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly)
+ continue;
+ if (x < *x0) *x0 = x;
+ if (y < *y0) *y0 = y;
+ if (x > *x1) *x1 = x;
+ if (y > *y1) *y1 = y;
+ }
+}
+
+Py::Object _path_module::get_path_extents(const Py::Tuple& args) {
+ args.verify_length(2);
+ 
+ PathIterator path(args[0]);
+ agg::trans_affine trans = py_to_agg_transformation_matrix(args[1]);
+
+ double x0 = std::numeric_limits<double>::infinity();
+ double y0 = std::numeric_limits<double>::infinity();
+ double x1 = -std::numeric_limits<double>::infinity();
+ double y1 = -std::numeric_limits<double>::infinity();
+
+ ::get_path_extents(path, trans, &x0, &y0, &x1, &y1);
+
+ Py::Tuple result(4);
+ result[0] = Py::Float(x0);
+ result[1] = Py::Float(y0);
+ result[2] = Py::Float(x1);
+ result[3] = Py::Float(y1);
+ return result;
+}
+
+Py::Object _path_module::get_path_collection_extents(const Py::Tuple& args) {
+ args.verify_length(5);
+
+ //segments, trans, clipbox, colors, linewidths, antialiaseds
+ agg::trans_affine	 master_transform = py_to_agg_transformation_matrix(args[0]);
+ Py::SeqBase<Py::Object> paths		 = args[1];
+ Py::SeqBase<Py::Object> transforms_obj = args[2];
+ Py::Object offsets_obj = args[3];
+ agg::trans_affine offset_trans = py_to_agg_transformation_matrix(args[4], false);
+
+ PyArrayObject* offsets = NULL;
+ double x0, y0, x1, y1;
+
+ try {
+ offsets = (PyArrayObject*)PyArray_FromObject(offsets_obj.ptr(), PyArray_DOUBLE, 2, 2);
+ if (!offsets || offsets->dimensions[1] != 2)
+ throw Py::ValueError("Offsets array must be Nx2");
+
+ size_t Npaths = paths.length();
+ size_t Noffsets = offsets->dimensions[0];
+ size_t N	 = std::max(Npaths, Noffsets);
+ size_t Ntransforms = std::min(transforms_obj.length(), N);
+ size_t i;
+
+ // Convert all of the transforms up front
+ typedef std::vector<agg::trans_affine> transforms_t;
+ transforms_t transforms;
+ transforms.reserve(Ntransforms);
+ for (i = 0; i < Ntransforms; ++i) {
+ agg::trans_affine trans = py_to_agg_transformation_matrix
+	(transforms_obj[i], false);
+ trans *= master_transform;
+ transforms.push_back(trans);
+ }
+ 
+ // The offset each of those and collect the mins/maxs
+ x0 = std::numeric_limits<double>::infinity();
+ y0 = std::numeric_limits<double>::infinity();
+ x1 = -std::numeric_limits<double>::infinity();
+ y1 = -std::numeric_limits<double>::infinity();
+ for (i = 0; i < N; ++i) {
+ PathIterator path(paths[i % Npaths]);
+ 
+ double xo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 0);
+ double yo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 1);
+ offset_trans.transform(&xo, &yo);
+ agg::trans_affine_translation transOffset(xo, yo);
+ agg::trans_affine trans = transforms[i % Ntransforms];
+ trans *= transOffset;
+
+ ::get_path_extents(path, trans, &x0, &y0, &x1, &y1);
+ }
+ } catch (...) {
+ Py_XDECREF(offsets);
+ throw;
+ }
+
+ Py_XDECREF(offsets);
+
+ Py::Tuple result(4);
+ result[0] = Py::Float(x0);
+ result[1] = Py::Float(y0);
+ result[2] = Py::Float(x1);
+ result[3] = Py::Float(y1);
+ return result;
+}
+
+Py::Object _path_module::point_in_path_collection(const Py::Tuple& args) {
+ args.verify_length(9);
+
+ //segments, trans, clipbox, colors, linewidths, antialiaseds
+ double		 x		 = Py::Float(args[0]);
+ double		 y		 = Py::Float(args[1]);
+ double radius = Py::Float(args[2]);
+ agg::trans_affine	 master_transform = py_to_agg_transformation_matrix(args[3]);
+ Py::SeqBase<Py::Object> paths		 = args[4];
+ Py::SeqBase<Py::Object> transforms_obj = args[5];
+ Py::SeqBase<Py::Object> offsets_obj = args[6];
+ agg::trans_affine offset_trans = py_to_agg_transformation_matrix(args[7]);
+ bool filled = Py::Int(args[8]);
+ 
+ PyArrayObject* offsets = (PyArrayObject*)PyArray_FromObject(offsets_obj.ptr(), PyArray_DOUBLE, 2, 2);
+ if (!offsets || offsets->dimensions[1] != 2)
+ throw Py::ValueError("Offsets array must be Nx2");
+
+ size_t Npaths	 = paths.length();
+ size_t Noffsets = offsets->dimensions[0];
+ size_t N	 = std::max(Npaths, Noffsets);
+ size_t Ntransforms = std::min(transforms_obj.length(), N);
+ size_t i;
+
+ // Convert all of the transforms up front
+ typedef std::vector<agg::trans_affine> transforms_t;
+ transforms_t transforms;
+ transforms.reserve(Ntransforms);
+ for (i = 0; i < Ntransforms; ++i) {
+ agg::trans_affine trans = py_to_agg_transformation_matrix
+ (transforms_obj[i], false);
+ trans *= master_transform;
+ transforms.push_back(trans);
+ }
+
+ Py::List result;
+
+ for (i = 0; i < N; ++i) {
+ PathIterator path(paths[i % Npaths]);
+ 
+ double xo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 0);
+ double yo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 1);
+ offset_trans.transform(&xo, &yo);
+ agg::trans_affine_translation transOffset(xo, yo);
+ agg::trans_affine trans = transforms[i % Ntransforms];
+ trans *= transOffset;
+
+ if (filled) {
+ if (::point_in_path(x, y, path, trans))
+	result.append(Py::Int((int)i));
+ } else {
+ if (::point_on_path(x, y, radius, path, trans))
+	result.append(Py::Int((int)i));
+ }
+ }
+
+ return result;
+}
+
+extern "C"
+DL_EXPORT(void)
+ init_path(void)
+{
+ import_array();
+ 
+ static _path_module* _path = NULL;
+ _path = new _path_module;
+};
Added: branches/transforms/src/agg_py_transforms.h
===================================================================
--- branches/transforms/src/agg_py_transforms.h	 (rev 0)
+++ branches/transforms/src/agg_py_transforms.h	2007年10月24日 17:11:00 UTC (rev 3993)
@@ -0,0 +1,58 @@
+#ifndef __AGG_PY_TRANSFORMS_H__
+#define __AGG_PY_TRANSFORMS_H__
+
+#define PY_ARRAY_TYPES_PREFIX NumPy
+#include "numpy/arrayobject.h"
+
+#include "CXX/Objects.hxx"
+#include "agg_trans_affine.h"
+
+
+/** A helper function to convert from a Numpy affine transformation matrix
+ * to an agg::trans_affine.
+ */
+agg::trans_affine py_to_agg_transformation_matrix(const Py::Object& obj, bool errors = true) {
+ PyArrayObject* matrix = NULL;
+ 
+ try {
+ if (obj.ptr() == Py_None)
+ throw std::exception();
+ matrix = (PyArrayObject*) PyArray_FromObject(obj.ptr(), PyArray_DOUBLE, 2, 2);
+ if (!matrix)
+ throw std::exception();
+ 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);
+ }
+
+ throw std::exception();
+ } catch (...) {
+ if (errors) {
+ Py_XDECREF(matrix);
+ throw Py::TypeError("Invalid affine transformation matrix");
+ }
+ }
+
+ Py_XDECREF(matrix);
+ return agg::trans_affine();
+}
+
+#endif // __AGG_PY_TRANSFORMS_H__
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年11月07日 20:38:49
Revision: 4153
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4153&view=rev
Author: mdboom
Date: 2007年11月07日 12:38:46 -0800 (2007年11月07日)
Log Message:
-----------
Update to use modern Numpy C API
Modified Paths:
--------------
 branches/transforms/src/_backend_agg.cpp
 branches/transforms/src/_path.cpp
Modified: branches/transforms/src/_backend_agg.cpp
===================================================================
--- branches/transforms/src/_backend_agg.cpp	2007年11月07日 20:13:35 UTC (rev 4152)
+++ branches/transforms/src/_backend_agg.cpp	2007年11月07日 20:38:46 UTC (rev 4153)
@@ -280,7 +280,7 @@
 if (bbox_obj.ptr() != Py_None) {
 bbox = (PyArrayObject*) PyArray_FromObject(bbox_obj.ptr(), PyArray_DOUBLE, 2, 2); 
 
- if (!bbox || bbox->nd != 2 || bbox->dimensions[0] != 2 || bbox->dimensions[1] != 2) {
+ if (!bbox || PyArray_NDIM(bbox) != 2 || PyArray_DIM(bbox, 0) != 2 || PyArray_DIM(bbox, 1) != 2) {
 Py_XDECREF(bbox);
 throw Py::TypeError
 	("Expected a Bbox object.");
@@ -942,23 +942,23 @@
 try {
 offsets = (PyArrayObject*)PyArray_FromObject(offsets_obj.ptr(), PyArray_DOUBLE, 0, 2);
 if (!offsets || 
-	(offsets->nd == 2 && offsets->dimensions[1] != 2) || 
-	(offsets->nd == 1 && offsets->dimensions[0])) {
+	(PyArray_NDIM(offsets) == 2 && PyArray_DIM(offsets, 1) != 2) || 
+	(PyArray_NDIM(offsets) == 1 && PyArray_DIM(offsets, 0) != 0)) {
 throw Py::ValueError("Offsets array must be Nx2");
 }
 
 PyArrayObject* facecolors = (PyArrayObject*)PyArray_FromObject
 (facecolors_obj.ptr(), PyArray_DOUBLE, 1, 2);
 if (!facecolors || 
-	(facecolors->nd == 1 && facecolors->dimensions[0] != 0) || 
-	(facecolors->nd == 2 && facecolors->dimensions[1] != 4))
+	(PyArray_NDIM(facecolors) == 1 && PyArray_DIM(facecolors, 0) != 0) || 
+	(PyArray_NDIM(facecolors) == 2 && PyArray_DIM(facecolors, 1) != 4))
 throw Py::ValueError("Facecolors must be a Nx4 numpy array or empty");
 
 PyArrayObject* edgecolors = (PyArrayObject*)PyArray_FromObject
 (edgecolors_obj.ptr(), PyArray_DOUBLE, 1, 2);
 if (!edgecolors || 
-	(edgecolors->nd == 1 && edgecolors->dimensions[0] != 0) || 
-	(edgecolors->nd == 2 && edgecolors->dimensions[1] != 4))
+	(PyArray_NDIM(edgecolors) == 1 && PyArray_DIM(edgecolors, 0) != 0) || 
+	(PyArray_NDIM(edgecolors) == 2 && PyArray_DIM(edgecolors, 1) != 4))
 throw Py::ValueError("Edgecolors must be a Nx4 numpy array");
 
 size_t Npaths = path_generator.num_paths();
@@ -1178,11 +1178,11 @@
 throw Py::ValueError("Invalid coordinates array.");
 }
 
- Py::Tuple shape(3);
- shape[0] = Py::Int((int)meshHeight + 1);
- shape[1] = Py::Int((int)meshWidth + 1);
- shape[2] = Py::Int(2);
- m_coordinates = (PyArrayObject*)PyArray_Reshape(coordinates_array, shape.ptr());
+ PyArray_Dims shape;
+ npy_intp dims[] = { meshHeight + 1, meshWidth + 1, 2 };
+ shape.ptr = dims;
+ shape.len = 3;
+ m_coordinates = (PyArrayObject*)PyArray_Newshape(coordinates_array, &shape, PyArray_CORDER);
 }
 
 inline ~QuadMeshGenerator() {
@@ -1237,13 +1237,13 @@
 if (showedges) {
 int dims[] = { 1, 4, 0 };
 double data[] = { 0, 0, 0, 1 };
- edgecolors_obj = PyArray_FromDimsAndData(2, dims, PyArray_DOUBLE, (char*)data);
+ edgecolors_obj = PyArray_SimpleNewFromData(2, dims, PyArray_DOUBLE, (char*)data);
 } else {
 if (antialiased) {
 edgecolors_obj = facecolors_obj;
 } else {
 int dims[] = { 0, 0 };
- edgecolors_obj = PyArray_FromDims(1, dims, PyArray_DOUBLE);
+ edgecolors_obj = PyArray_SimpleNew(1, dims, PyArray_DOUBLE);
 }
 }
 
Modified: branches/transforms/src/_path.cpp
===================================================================
--- branches/transforms/src/_path.cpp	2007年11月07日 20:13:35 UTC (rev 4152)
+++ branches/transforms/src/_path.cpp	2007年11月07日 20:38:46 UTC (rev 4153)
@@ -263,8 +263,8 @@
 try {
 offsets = (PyArrayObject*)PyArray_FromObject(offsets_obj.ptr(), PyArray_DOUBLE, 0, 2);
 if (!offsets || 
-	(offsets->nd == 2 && offsets->dimensions[1] != 2) || 
-	(offsets->nd == 1 && offsets->dimensions[0])) {
+	(PyArray_NDIM(offsets) == 2 && PyArray_DIM(offsets, 1) != 2) || 
+	(PyArray_NDIM(offsets) == 1 && PyArray_DIM(offsets, 0) != 0)) {
 throw Py::ValueError("Offsets array must be Nx2");
 }
 
@@ -338,9 +338,12 @@
 agg::trans_affine offset_trans = py_to_agg_transformation_matrix(args[7]);
 bool filled = Py::Int(args[8]);
 
- PyArrayObject* offsets = (PyArrayObject*)PyArray_FromObject(offsets_obj.ptr(), PyArray_DOUBLE, 2, 2);
- if (!offsets || offsets->dimensions[1] != 2)
+ PyArrayObject* offsets = (PyArrayObject*)PyArray_FromObject(offsets_obj.ptr(), PyArray_DOUBLE, 0, 2);
+ if (!offsets || 
+ (PyArray_NDIM(offsets) == 2 && PyArray_DIM(offsets, 1) != 2) || 
+ (PyArray_NDIM(offsets) == 1 && PyArray_DIM(offsets, 0) != 0)) {
 throw Py::ValueError("Offsets array must be Nx2");
+ }
 
 size_t Npaths	 = paths.length();
 size_t Noffsets = offsets->dimensions[0];
@@ -360,17 +363,24 @@
 }
 
 Py::List result;
+ agg::trans_affine trans;
 
 for (i = 0; i < N; ++i) {
 PathIterator path(paths[i % Npaths]);
- 
- double xo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 0);
- double yo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 1);
- offset_trans.transform(&xo, &yo);
- agg::trans_affine_translation transOffset(xo, yo);
- agg::trans_affine trans = transforms[i % Ntransforms];
- trans *= transOffset;
 
+ if (Ntransforms) {
+ trans = transforms[i % Ntransforms];
+ } else {
+ trans = master_transform;
+ }
+
+ if (Noffsets) {
+ double xo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 0);
+ double yo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 1);
+ offset_trans.transform(&xo, &yo);
+ trans *= agg::trans_affine_translation(xo, yo);
+ }
+
 if (filled) {
 if (::point_in_path(x, y, path, trans))
 	result.append(Py::Int((int)i));
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年11月08日 14:06:27
Revision: 4159
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4159&view=rev
Author: mdboom
Date: 2007年11月08日 06:06:25 -0800 (2007年11月08日)
Log Message:
-----------
Get wxagg extension working again. Factor out the new Bbox conversion
code into agg_py_transforms.h
Modified Paths:
--------------
 branches/transforms/src/_backend_agg.cpp
 branches/transforms/src/_backend_agg.h
 branches/transforms/src/_gtkagg.cpp
 branches/transforms/src/_tkagg.cpp
 branches/transforms/src/_wxagg.cpp
 branches/transforms/src/agg_py_transforms.h
Modified: branches/transforms/src/_backend_agg.cpp
===================================================================
--- branches/transforms/src/_backend_agg.cpp	2007年11月08日 14:05:18 UTC (rev 4158)
+++ branches/transforms/src/_backend_agg.cpp	2007年11月08日 14:06:25 UTC (rev 4159)
@@ -273,33 +273,6 @@
 
 };
 
-bool
-RendererAgg::bbox_to_rect(const Py::Object& bbox_obj, double* l, double* b, double* r, double* t) {
- PyArrayObject* bbox = NULL;
-
- if (bbox_obj.ptr() != Py_None) {
- bbox = (PyArrayObject*) PyArray_FromObject(bbox_obj.ptr(), PyArray_DOUBLE, 2, 2); 
-
- if (!bbox || PyArray_NDIM(bbox) != 2 || PyArray_DIM(bbox, 0) != 2 || PyArray_DIM(bbox, 1) != 2) {
- Py_XDECREF(bbox);
- throw Py::TypeError
-	("Expected a Bbox object.");
- }
- 
- *l	 = *(double*)PyArray_GETPTR2(bbox, 0, 0);
- double _b = *(double*)PyArray_GETPTR2(bbox, 0, 1);
- *r	 = *(double*)PyArray_GETPTR2(bbox, 1, 0);
- double _t = *(double*)PyArray_GETPTR2(bbox, 1, 1);
- *b	 = height - _t;
- *t	 = height - _b;
-
- Py_XDECREF(bbox);
- return true;
- }
-
- return false;
-}
-
 template<class R>
 void
 RendererAgg::set_clipbox(const Py::Object& cliprect, R rasterizer) {
@@ -308,7 +281,7 @@
 _VERBOSE("RendererAgg::set_clipbox");
 
 double l, b, r, t;
- if (bbox_to_rect(cliprect, &l, &b, &r, &t)) {
+ if (py_convert_bbox(cliprect.ptr(), l, b, r, t)) {
 rasterizer->clip_box((int)l, (int)b, (int)r, (int)t);
 }
 
@@ -408,7 +381,7 @@
 
 Py::Object box_obj = args[0];
 double l, b, r, t;
- if (!bbox_to_rect(box_obj, &l, &b, &r, &t)) 
+ if (!py_convert_bbox(box_obj.ptr(), l, b, r, t)) 
 throw Py::TypeError("Invalid bbox provided to copy_from_bbox");
 
 agg::rect rect((int)l, (int)b, (int)r, (int)t);
Modified: branches/transforms/src/_backend_agg.h
===================================================================
--- branches/transforms/src/_backend_agg.h	2007年11月08日 14:05:18 UTC (rev 4158)
+++ branches/transforms/src/_backend_agg.h	2007年11月08日 14:06:25 UTC (rev 4159)
@@ -215,7 +215,6 @@
 double points_to_pixels_snapto( const Py::Object& points);
 agg::rgba rgb_to_color(const Py::SeqBase<Py::Object>& rgb, double alpha);
 facepair_t _get_rgba_face(const Py::Object& rgbFace, double alpha);
- bool bbox_to_rect(const Py::Object& bbox, double* l, double* b, double* r, double* t);
 template<class R>
 void set_clipbox(const Py::Object& cliprect, R rasterizer);
 bool render_clippath(const Py::Object& clippath, const agg::trans_affine& clippath_trans);
Modified: branches/transforms/src/_gtkagg.cpp
===================================================================
--- branches/transforms/src/_gtkagg.cpp	2007年11月08日 14:05:18 UTC (rev 4158)
+++ branches/transforms/src/_gtkagg.cpp	2007年11月08日 14:06:25 UTC (rev 4159)
@@ -14,6 +14,7 @@
 #include "_backend_agg.h"
 #define PY_ARRAY_TYPES_PREFIX NumPy
 #include "numpy/arrayobject.h"
+#include "agg_py_transforms.h"
 
 // the extension module
 class _gtkagg_module : public Py::ExtensionModule<_gtkagg_module>
@@ -71,31 +72,12 @@
 else {
 //bbox is not None; copy the image in the bbox
 PyObject* clipbox = args[2].ptr();
- PyArrayObject* bbox = NULL;
 double l, b, r, t;
 
- try {
-	bbox = (PyArrayObject*) PyArray_FromObject(clipbox, PyArray_DOUBLE, 2, 2); 
-	
-	if (!bbox || bbox->nd != 2 || bbox->dimensions[0] != 2 || bbox->dimensions[1] != 2) {
-	 throw Py::TypeError
-	 ("Argument 3 to agg_to_gtk_drawable must be a Bbox object.");
-	}
-	
-	l = *(double*)PyArray_GETPTR2(bbox, 0, 0);
-	b = *(double*)PyArray_GETPTR2(bbox, 0, 1);
-	r = *(double*)PyArray_GETPTR2(bbox, 1, 0);
-	t = *(double*)PyArray_GETPTR2(bbox, 1, 1);
-
-	Py_XDECREF(bbox);
-	bbox = NULL;
- } catch (...) {
-	Py_XDECREF(bbox);
-	bbox = NULL;
-	throw;
+ if (!py_convert_bbox(clipbox, l, b, r, t)) {
+	throw Py::TypeError
+	 ("Argument 3 to agg_to_gtk_drawable must be a Bbox object.");
 }
- //std::cout << b << " "
- //		<< t << " ";
 
 destx = (int)l;
 desty = srcheight-(int)t;
@@ -118,11 +100,8 @@
 agg::rect_base<int> region(destx, desty, (int)r, srcheight-(int)b);
 destrb.copy_from(*aggRenderer->renderingBuffer, &region,
 		 -destx, -desty);
-
-
 }
 
-
 /*std::cout << desty << " "
 	 << destheight << " "
 	 << srcheight << std::endl;*/
Modified: branches/transforms/src/_tkagg.cpp
===================================================================
--- branches/transforms/src/_tkagg.cpp	2007年11月08日 14:05:18 UTC (rev 4158)
+++ branches/transforms/src/_tkagg.cpp	2007年11月08日 14:06:25 UTC (rev 4159)
@@ -14,6 +14,7 @@
 
 #include "agg_basics.h"
 #include "_backend_agg.h"
+#include "agg_py_transforms.h"
 
 extern "C" {
 #ifdef __APPLE__
@@ -85,30 +86,9 @@
 
 /* check for bbox/blitting */
 bboxo = (PyObject*)atol(argv[4]);
- if (bboxo != Py_None) {
+ if (py_convert_bbox(bboxo, l, b, r, t)) {
 has_bbox = true;
- PyArrayObject* bbox = NULL;
- try {
-	bbox = (PyArrayObject*) PyArray_FromObject(bboxo, PyArray_DOUBLE, 2, 2); 
-	
-	if (!bbox || bbox->nd != 2 || bbox->dimensions[0] != 2 || bbox->dimensions[1] != 2) {
-	 throw Py::TypeError
-	 ("Argument 3 to agg_to_gtk_drawable must be a Bbox object.");
-	}
-	
-	l = *(double*)PyArray_GETPTR2(bbox, 0, 0);
-	b = *(double*)PyArray_GETPTR2(bbox, 0, 1);
-	r = *(double*)PyArray_GETPTR2(bbox, 1, 0);
-	t = *(double*)PyArray_GETPTR2(bbox, 1, 1);
 
-	Py_XDECREF(bbox);
-	bbox = NULL;
- } catch (...) {
-	Py_XDECREF(bbox);
-	bbox = NULL;
-	throw;
- }
-
 destx = (int)l;
 desty = srcheight-(int)t;
 destwidth = (int)(r-l);
Modified: branches/transforms/src/_wxagg.cpp
===================================================================
--- branches/transforms/src/_wxagg.cpp	2007年11月08日 14:05:18 UTC (rev 4158)
+++ branches/transforms/src/_wxagg.cpp	2007年11月08日 14:06:25 UTC (rev 4159)
@@ -46,9 +46,9 @@
 
 #include "agg_basics.h"
 #include "_backend_agg.h"
-#include "_transforms.h"
 #include "agg_pixfmt_rgba.h"
 #include "util/agg_color_conv_rgb8.h"
+#include "agg_py_transforms.h"
 
 #include <wx/image.h>
 #include <wx/bitmap.h>
@@ -56,8 +56,8 @@
 
 
 // forward declarations
-static wxImage *convert_agg2image(RendererAgg *aggRenderer, Bbox *clipbox);
-static wxBitmap *convert_agg2bitmap(RendererAgg *aggRenderer, Bbox *clipbox);
+static wxImage *convert_agg2image(RendererAgg *aggRenderer, Py::Object clipbox);
+static wxBitmap *convert_agg2bitmap(RendererAgg *aggRenderer, Py::Object clipbox);
 
 
 // the extension module
@@ -94,9 +94,7 @@
 RendererAgg* aggRenderer = static_cast<RendererAgg*>(
 args[0].getAttr("_renderer").ptr());
 
- Bbox *clipbox = NULL;
- if (args[1].ptr() != Py_None)
- clipbox = static_cast<Bbox*>(args[1].ptr());
+ Py::Object clipbox = args[1];
 
 // convert the buffer
 wxImage *image = convert_agg2image(aggRenderer, clipbox);
@@ -118,9 +116,7 @@
 RendererAgg* aggRenderer = static_cast<RendererAgg*>(
 args[0].getAttr("_renderer").ptr());
 
- Bbox *clipbox = NULL;
- if (args[1].ptr() != Py_None)
- clipbox = static_cast<Bbox*>(args[1].ptr());
+ Py::Object clipbox = args[1];
 
 // convert the buffer
 wxBitmap *bitmap = convert_agg2bitmap(aggRenderer, clipbox);
@@ -141,7 +137,7 @@
 // Implementation Functions
 //
 
-static wxImage *convert_agg2image(RendererAgg *aggRenderer, Bbox *clipbox)
+static wxImage *convert_agg2image(RendererAgg *aggRenderer, Py::Object clipbox)
 {
 int srcWidth = 1;
 int srcHeight = 1;
@@ -150,7 +146,9 @@
 bool deleteSrcBuffer = false;
 agg::int8u *srcBuffer = NULL;
 
- if (clipbox == NULL) {
+ double l, b, r, t;
+
+ if (!py_convert_bbox(clipbox.ptr(), l, b, r, t)) {
 // Convert everything: rgba => rgb -> image
 srcBuffer = aggRenderer->pixBuffer;
 srcWidth = (int) aggRenderer->get_width();
@@ -158,11 +156,6 @@
 srcStride = (int) aggRenderer->get_width()*4;
 } else {
 // Convert a region: rgba => clipped rgba => rgb -> image
- double l = clipbox->ll_api()->x_api()->val() ;
- double b = clipbox->ll_api()->y_api()->val();
- double r = clipbox->ur_api()->x_api()->val() ;
- double t = clipbox->ur_api()->y_api()->val() ;
-
 srcWidth = (int) (r-l);
 srcHeight = (int) (t-b);
 srcStride = srcWidth*4;
@@ -230,7 +223,7 @@
 }
 
 
-static wxBitmap *convert_agg2bitmap(RendererAgg *aggRenderer, Bbox *clipbox)
+static wxBitmap *convert_agg2bitmap(RendererAgg *aggRenderer, Py::Object clipbox)
 {
 // Convert everything: rgba => rgb -> image => bitmap
 // Convert a region: rgba => clipped rgba => rgb -> image => bitmap
Modified: branches/transforms/src/agg_py_transforms.h
===================================================================
--- branches/transforms/src/agg_py_transforms.h	2007年11月08日 14:05:18 UTC (rev 4158)
+++ branches/transforms/src/agg_py_transforms.h	2007年11月08日 14:06:25 UTC (rev 4159)
@@ -7,7 +7,6 @@
 #include "CXX/Objects.hxx"
 #include "agg_trans_affine.h"
 
-
 /** A helper function to convert from a Numpy affine transformation matrix
 * to an agg::trans_affine.
 */
@@ -20,10 +19,10 @@
 matrix = (PyArrayObject*) PyArray_FromObject(obj.ptr(), PyArray_DOUBLE, 2, 2);
 if (!matrix)
 throw std::exception();
- 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;
+ if (PyArray_NDIM(matrix) == 2 || PyArray_DIM(matrix, 0) == 3 || PyArray_DIM(matrix, 1) == 3) {
+ size_t stride0 = PyArray_STRIDE(matrix, 0);
+ size_t stride1 = PyArray_STRIDE(matrix, 1);
+ char* row0 = PyArray_BYTES(matrix);
 char* row1 = row0 + stride0;
 
 double a = *(double*)(row0);
@@ -55,4 +54,35 @@
 return agg::trans_affine();
 }
 
+bool py_convert_bbox(PyObject* bbox_obj, double& l, double& b, double& r, double& t) {
+ PyArrayObject* bbox = NULL;
+
+ if (bbox_obj == Py_None)
+ return false;
+
+ try {
+ bbox = (PyArrayObject*) PyArray_FromObject(bbox_obj, PyArray_DOUBLE, 2, 2); 
+	
+ if (!bbox || bbox->nd != 2 || bbox->dimensions[0] != 2 || bbox->dimensions[1] != 2) {
+ throw Py::TypeError
+	("Argument 3 to agg_to_gtk_drawable must be a Bbox object.");
+ }
+	
+ l = *(double*)PyArray_GETPTR2(bbox, 0, 0);
+ b = *(double*)PyArray_GETPTR2(bbox, 0, 1);
+ r = *(double*)PyArray_GETPTR2(bbox, 1, 0);
+ t = *(double*)PyArray_GETPTR2(bbox, 1, 1);
+
+ Py_XDECREF(bbox);
+ bbox = NULL;
+ return true;
+ } catch (...) {
+ Py_XDECREF(bbox);
+ bbox = NULL;
+ throw;
+ }
+
+ return false;
+}
+
 #endif // __AGG_PY_TRANSFORMS_H__
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年11月14日 18:43:41
Revision: 4284
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4284&view=rev
Author: mdboom
Date: 2007年11月14日 10:42:52 -0800 (2007年11月14日)
Log Message:
-----------
Update to use new numpy macros.
Modified Paths:
--------------
 branches/transforms/src/agg_py_path_iterator.h
 branches/transforms/src/agg_py_transforms.h
Modified: branches/transforms/src/agg_py_path_iterator.h
===================================================================
--- branches/transforms/src/agg_py_path_iterator.h	2007年11月14日 18:38:05 UTC (rev 4283)
+++ branches/transforms/src/agg_py_path_iterator.h	2007年11月14日 18:42:52 UTC (rev 4284)
@@ -20,7 +20,7 @@
 
 m_vertices = (PyArrayObject*)PyArray_FromObject
 (vertices_obj.ptr(), PyArray_DOUBLE, 2, 2);
- if (!m_vertices || m_vertices->nd != 2 || m_vertices->dimensions[1] != 2)
+ if (!m_vertices || PyArray_NDIM(m_vertices) != 2 || PyArray_DIM(m_vertices, 1) != 2)
 throw Py::ValueError("Invalid vertices array.");
 
 if (codes_obj.ptr() != Py_None) {
Modified: branches/transforms/src/agg_py_transforms.h
===================================================================
--- branches/transforms/src/agg_py_transforms.h	2007年11月14日 18:38:05 UTC (rev 4283)
+++ branches/transforms/src/agg_py_transforms.h	2007年11月14日 18:42:52 UTC (rev 4284)
@@ -63,7 +63,7 @@
 try {
 bbox = (PyArrayObject*) PyArray_FromObject(bbox_obj, PyArray_DOUBLE, 2, 2); 
 	
- if (!bbox || bbox->nd != 2 || bbox->dimensions[0] != 2 || bbox->dimensions[1] != 2) {
+ if (!bbox || PyArray_NDIM(bbox) != 2 || PyArray_DIM(bbox, 0) != 2 || PyArray_DIM(bbox, 1) != 2) {
 throw Py::TypeError
 	("Argument 3 to agg_to_gtk_drawable must be a Bbox object.");
 }
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年11月26日 17:23:26
Revision: 4448
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4448&view=rev
Author: mdboom
Date: 2007年11月26日 09:23:18 -0800 (2007年11月26日)
Log Message:
-----------
Still trying to fix compile error on 64-bit platforms...
Modified Paths:
--------------
 branches/transforms/src/_backend_agg.cpp
 branches/transforms/src/_path.cpp
Modified: branches/transforms/src/_backend_agg.cpp
===================================================================
--- branches/transforms/src/_backend_agg.cpp	2007年11月26日 16:59:29 UTC (rev 4447)
+++ branches/transforms/src/_backend_agg.cpp	2007年11月26日 17:23:18 UTC (rev 4448)
@@ -1203,14 +1203,14 @@
 antialiaseds[0] = Py::Int(antialiased ? 1 : 0);
 
 if (showedges) {
- int dims[] = { 1, 4, 0 };
+ npy_intp dims[] = { 1, 4, 0 };
 double data[] = { 0, 0, 0, 1 };
 edgecolors_obj = PyArray_SimpleNewFromData(2, dims, PyArray_DOUBLE, (char*)data);
 } else {
 if (antialiased) {
 edgecolors_obj = facecolors_obj;
 } else {
- int dims[] = { 0, 0 };
+ npy_intp dims[] = { 0, 0 };
 edgecolors_obj = PyArray_SimpleNew(1, dims, PyArray_DOUBLE);
 }
 }
Modified: branches/transforms/src/_path.cpp
===================================================================
--- branches/transforms/src/_path.cpp	2007年11月26日 16:59:29 UTC (rev 4447)
+++ branches/transforms/src/_path.cpp	2007年11月26日 17:23:18 UTC (rev 4448)
@@ -696,10 +696,12 @@
 f = *(double*)(row1);
 }
 
- result = (PyArrayObject*)PyArray_NewFromDescr
- (&PyArray_Type, PyArray_DescrFromType(PyArray_DOUBLE), 
- PyArray_NDIM(vertices), PyArray_DIMS(vertices), 
- NULL, NULL, 0, NULL);
+ // I would have preferred to use PyArray_FromDims here, but on
+ // 64-bit platforms, PyArray_DIMS() does not return the same thing
+ // that PyArray_FromDims wants, requiring a copy, which I would
+ // like to avoid in this critical section.
+ result = (PyArrayObject*)PyArray_SimpleNew
+ (PyArray_NDIM(vertices), PyArray_DIMS(vertices), PyArray_DOUBLE);
 if (PyArray_NDIM(vertices) == 2) {
 size_t n = PyArray_DIM(vertices, 0);
 char* vertex_in = PyArray_BYTES(vertices);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年11月27日 20:03:50
Revision: 4473
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4473&view=rev
Author: mdboom
Date: 2007年11月27日 12:03:48 -0800 (2007年11月27日)
Log Message:
-----------
Improve speed of quad mesh drawing (by about 25%)
Modified Paths:
--------------
 branches/transforms/src/_backend_agg.cpp
 branches/transforms/src/_backend_agg.h
Modified: branches/transforms/src/_backend_agg.cpp
===================================================================
--- branches/transforms/src/_backend_agg.cpp	2007年11月27日 18:34:38 UTC (rev 4472)
+++ branches/transforms/src/_backend_agg.cpp	2007年11月27日 20:03:48 UTC (rev 4473)
@@ -348,10 +348,13 @@
 
 template<class Path>
 bool should_snap(Path& path, const agg::trans_affine& trans) {
- // If this is a straight horizontal or vertical line, quantize to nearest
+ // If this contains only straight horizontal or vertical lines, quantize to nearest
 // pixels
 double x0, y0, x1, y1;
 unsigned code;
+ if (path.total_vertices() > 5)
+ return false;
+
 code = path.vertex(&x0, &y0);
 trans.transform(&x0, &y0);
 
@@ -742,38 +745,20 @@
 return Py::Object();
 }
 
-template<class PathIteratorType>
-void RendererAgg::_draw_path(PathIteratorType& path, agg::trans_affine trans,
-			 bool has_clippath, const facepair_t& face,
-			 const GCAgg& gc, bool check_snap) {
- typedef agg::conv_transform<PathIteratorType>		 transformed_path_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;
+template<class path_t>
+void RendererAgg::_draw_path(path_t& path, bool has_clippath,
+			 const facepair_t& face, const GCAgg& gc) {
+ typedef agg::conv_stroke<path_t>			 stroke_t;
+ typedef agg::conv_dash<path_t>			 dash_t;
 typedef agg::conv_stroke<dash_t>			 stroke_dash_t;
 typedef agg::pixfmt_amask_adaptor<pixfmt, alpha_mask_type> pixfmt_amask_type;
 typedef agg::renderer_base<pixfmt_amask_type>		 amask_ren_type;
 typedef agg::renderer_scanline_aa_solid<amask_ren_type> amask_aa_renderer_type;
 typedef agg::renderer_scanline_bin_solid<amask_ren_type> amask_bin_renderer_type;
 
- trans *= agg::trans_affine_scaling(1.0, -1.0);
- trans *= agg::trans_affine_translation(0.0, (double)height);
-
- // Build the transform stack
- bool snap = false;
- if (check_snap)
- snap = should_snap(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(quantized);
-
 // Render face
 if (face.first) {
- theRasterizer->add_path(curve);
+ theRasterizer->add_path(path);
 
 if (gc.isaa) {
 if (has_clippath) {
@@ -803,22 +788,21 @@
 // Render stroke
 if (gc.linewidth != 0.0) {
 double linewidth = gc.linewidth;
- if (snap)
+ if (!gc.isaa)
 linewidth = round(linewidth);
-
 if (gc.dashes.size() == 0) {
- stroke_t stroke(curve);
+ stroke_t stroke(path);
 stroke.width(linewidth);
 stroke.line_cap(gc.cap);
 stroke.line_join(gc.join);
 theRasterizer->add_path(stroke);
 } else {
- dash_t dash(curve);
+ dash_t dash(path);
 for (GCAgg::dash_t::const_iterator i = gc.dashes.begin();
 	 i != gc.dashes.end(); ++i) {
 	double val0 = i->first;
 	double val1 = i->second;
-	if (snap) {
+	if (!gc.isaa) {
 	 val0 = (int)val0 + 0.5;
 	 val1 = (int)val1 + 0.5;
 	}
@@ -831,7 +815,7 @@
 theRasterizer->add_path(stroke);
 }
 
- if (gc.isaa && !(snap)) {
+ if (gc.isaa) {
 if (has_clippath) {
 	pixfmt_amask_type pfa(*pixFmt, *alphaMask);
 	amask_ren_type r(pfa);
@@ -859,6 +843,10 @@
 
 Py::Object
 RendererAgg::draw_path(const Py::Tuple& args) {
+ typedef agg::conv_transform<PathIterator>	transformed_path_t;
+ typedef conv_quantize<transformed_path_t>	quantize_t;
+ typedef agg::conv_curve<quantize_t>		curve_t;
+
 _VERBOSE("RendererAgg::draw_path");
 args.verify_length(3, 4);
 
@@ -878,15 +866,24 @@
 set_clipbox(gc.cliprect, theRasterizer);
 bool has_clippath = render_clippath(gc.clippath, gc.clippath_trans);
 
- _draw_path(path, trans, has_clippath, face, gc, true);
+ trans *= agg::trans_affine_scaling(1.0, -1.0);
+ trans *= agg::trans_affine_translation(0.0, (double)height);
+ bool snap = should_snap(path, trans);
+ transformed_path_t tpath(path, trans);
+ quantize_t quantized(tpath, snap);
+ curve_t curve(quantized);
+ if (snap)
+ gc.isaa = false;
 
+ _draw_path(curve, has_clippath, face, gc);
+
 return Py::Object();
 }
 
-template<class PathGenerator>
+template<class PathGenerator, int check_snap, int has_curves>
 Py::Object
 RendererAgg::_draw_path_collection_generic
- (const agg::trans_affine&	 master_transform,
+ (agg::trans_affine	 master_transform,
 const Py::Object&		 cliprect,
 const Py::Object&		 clippath,
 const agg::trans_affine& clippath_trans,
@@ -898,8 +895,12 @@
 const Py::Object& edgecolors_obj,
 const Py::SeqBase<Py::Float>& linewidths,
 const Py::SeqBase<Py::Object>& linestyles_obj,
- const Py::SeqBase<Py::Int>& antialiaseds,
- bool check_snap) {
+ const Py::SeqBase<Py::Int>& antialiaseds) {
+ typedef agg::conv_transform<typename PathGenerator::path_iterator> transformed_path_t;
+ typedef conv_quantize<transformed_path_t>			 quantize_t;
+ typedef agg::conv_curve<quantize_t>				 quantized_curve_t;
+ typedef agg::conv_curve<transformed_path_t>			 curve_t;
+
 GCAgg gc(dpi);
 
 PyArrayObject* offsets = NULL;
@@ -944,6 +945,9 @@
 size_t i = 0;
 
 // Convert all of the transforms up front
+ master_transform *= agg::trans_affine_scaling(1.0, -1.0);
+ master_transform *= agg::trans_affine_translation(0.0, (double)height);
+
 typedef std::vector<agg::trans_affine> transforms_t;
 transforms_t transforms;
 transforms.reserve(Ntransforms);
@@ -975,6 +979,7 @@
 facepair_t face;
 face.first = Nfacecolors != 0;
 agg::trans_affine trans;
+ bool snap = false;
 
 for (i = 0; i < N; ++i) {
 typename PathGenerator::path_iterator path = path_generator(i);
@@ -1016,9 +1021,32 @@
 	}
 }
 
- gc.isaa = bool(Py::Int(antialiaseds[i % Naa]));
+ if (check_snap) {
+	snap = should_snap(path, trans);
+	if (snap)
+	 gc.isaa = false;
+	else
+	 gc.isaa = bool(Py::Int(antialiaseds[i % Naa]));
 
- _draw_path(path, trans, has_clippath, face, gc, check_snap);
+	transformed_path_t tpath(path, trans);
+	quantize_t quantized(tpath, snap);
+	if (has_curves) {
+	 quantized_curve_t curve(quantized);
+	 _draw_path(curve, has_clippath, face, gc);
+	} else {
+	 _draw_path(quantized, has_clippath, face, gc);
+	}
+ } else {
+	gc.isaa = bool(Py::Int(antialiaseds[i % Naa]));
+
+	transformed_path_t tpath(path, trans);
+	if (has_curves) {
+	 curve_t curve(tpath);
+	 _draw_path(curve, has_clippath, face, gc);
+	} else {
+	 _draw_path(tpath, has_clippath, face, gc);
+	}
+ }
 }
 } catch (...) {
 Py_XDECREF(offsets);
@@ -1075,7 +1103,7 @@
 
 PathListGenerator path_generator(paths);
 
- _draw_path_collection_generic
+ _draw_path_collection_generic<PathListGenerator, 1, 1>
 (master_transform,
 cliprect,
 clippath,
@@ -1088,8 +1116,7 @@
 edgecolors_obj,
 linewidths,
 linestyles_obj,
- antialiaseds,
- true);
+ antialiaseds);
 
 return Py::Object();
 }
@@ -1108,19 +1135,18 @@
 m_iterator(0), m_m(m), m_n(n), m_coordinates(coordinates) {
 }
 
- static const size_t offsets[5][2];
-
 inline unsigned vertex(unsigned idx, double* x, double* y) {
- size_t m = m_m + offsets[idx][0];
- size_t n = m_n + offsets[idx][1];
+ size_t m = (idx & 0x2) ? (m_m + 1) : m_m;
+ size_t n = (idx+1 & 0x2) ? (m_n + 1) : m_n;
 double* pair = (double*)PyArray_GETPTR2(m_coordinates, m, n);
 *x = *pair++;
 *y = *pair;
- return (idx == 0) ? agg::path_cmd_move_to : agg::path_cmd_line_to;
+ return (idx) ? agg::path_cmd_line_to : agg::path_cmd_move_to;
 }
 
 inline unsigned vertex(double* x, double* y) {
- if (m_iterator >= total_vertices()) return agg::path_cmd_stop;
+ if (m_iterator >= total_vertices()) 
+	return agg::path_cmd_stop;
 return vertex(m_iterator++, x, y);
 }
 
@@ -1159,13 +1185,6 @@
 }
 };
 
-const size_t QuadMeshGenerator::QuadMeshPathIterator::offsets[5][2] = {
- { 0, 0 },
- { 0, 1 },
- { 1, 1 },
- { 1, 0 },
- { 0, 0 } };
-
 Py::Object
 RendererAgg::draw_quad_mesh(const Py::Tuple& args) {
 _VERBOSE("RendererAgg::draw_quad_mesh");
@@ -1208,7 +1227,7 @@
 }
 }
 
- _draw_path_collection_generic
+ _draw_path_collection_generic<QuadMeshGenerator, 0, 0>
 (master_transform,
 cliprect,
 clippath,
@@ -1221,8 +1240,7 @@
 edgecolors_obj,
 linewidths,
 linestyles_obj,
- antialiaseds,
- false);
+ antialiaseds);
 
 return Py::Object();
 }
Modified: branches/transforms/src/_backend_agg.h
===================================================================
--- branches/transforms/src/_backend_agg.h	2007年11月27日 18:34:38 UTC (rev 4472)
+++ branches/transforms/src/_backend_agg.h	2007年11月27日 20:03:48 UTC (rev 4473)
@@ -226,16 +226,16 @@
 void set_clipbox(const Py::Object& cliprect, R rasterizer);
 bool render_clippath(const Py::Object& clippath, const agg::trans_affine& clippath_trans);
 template<class PathIteratorType>
- void _draw_path(PathIteratorType& path, agg::trans_affine trans, 
-		 bool has_clippath, const facepair_t& face, const GCAgg& gc, bool check_snap);
- template<class PathGenerator>
+ void _draw_path(PathIteratorType& path, bool has_clippath,
+		 const facepair_t& face, const GCAgg& gc);
+ template<class PathGenerator, int check_snap, int has_curves>
 Py::Object
 _draw_path_collection_generic
- (const agg::trans_affine&	 master_transform,
+ (agg::trans_affine 	 master_transform,
 const Py::Object&		 cliprect,
 const Py::Object&		 clippath,
 const agg::trans_affine& clippath_trans,
- const PathGenerator&	 path_finder,
+ const PathGenerator&	 path_generator,
 const Py::SeqBase<Py::Object>& transforms_obj,
 const Py::Object& offsets_obj,
 const agg::trans_affine& offset_trans,
@@ -243,8 +243,7 @@
 const Py::Object& edgecolors_obj,
 const Py::SeqBase<Py::Float>& linewidths,
 const Py::SeqBase<Py::Object>& linestyles_obj,
- const Py::SeqBase<Py::Int>& antialiaseds,
- bool check_snap);
+ const Py::SeqBase<Py::Int>& antialiaseds);
 
 private:
 Py::Object lastclippath;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年11月28日 18:26:45
Revision: 4488
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4488&view=rev
Author: mdboom
Date: 2007年11月28日 10:26:40 -0800 (2007年11月28日)
Log Message:
-----------
Increase performance of draw_markers in Agg backend
Modified Paths:
--------------
 branches/transforms/src/_backend_agg.cpp
 branches/transforms/src/agg_py_path_iterator.h
Modified: branches/transforms/src/_backend_agg.cpp
===================================================================
--- branches/transforms/src/_backend_agg.cpp	2007年11月28日 18:18:11 UTC (rev 4487)
+++ branches/transforms/src/_backend_agg.cpp	2007年11月28日 18:26:40 UTC (rev 4488)
@@ -549,8 +549,8 @@
 agg::serialized_scanlines_adaptor_aa8 sa;
 agg::serialized_scanlines_adaptor_aa8::embedded_scanline sl;
 
- while (path_quantized.vertex(&x, &y) != agg::path_cmd_stop) {
- if (has_clippath) {
+ if (has_clippath) {
+ while (path_quantized.vertex(&x, &y) != agg::path_cmd_stop) {
 	pixfmt_amask_type pfa(*pixFmt, *alphaMask);
 	amask_ren_type r(pfa);
 	amask_aa_renderer_type ren(r);
@@ -563,7 +563,9 @@
 	ren.color(gc.color);
 	sa.init(strokeCache, strokeSize, x, y);
 	agg::render_scanlines(sa, sl, ren);
- } else {
+ }
+ } else {
+ while (path_quantized.vertex(&x, &y) != agg::path_cmd_stop) {
 	if (face.first) {
 	 rendererAA->color(face.second);
 	 sa.init(fillCache, fillSize, x, y);
@@ -1139,6 +1141,7 @@
 m_iterator(0), m_m(m), m_n(n), m_coordinates(coordinates) {
 }
 
+ private:
 inline unsigned vertex(unsigned idx, double* x, double* y) {
 size_t m = (idx & 0x2) ? (m_m + 1) : m_m;
 size_t n = (idx+1 & 0x2) ? (m_n + 1) : m_n;
@@ -1148,8 +1151,9 @@
 return (idx) ? agg::path_cmd_line_to : agg::path_cmd_move_to;
 }
 
+ public:
 inline unsigned vertex(double* x, double* y) {
- if (m_iterator >= total_vertices()) 
+ if (m_iterator >= total_vertices())
 	return agg::path_cmd_stop;
 return vertex(m_iterator++, x, y);
 }
@@ -1496,7 +1500,7 @@
 int ymin = height;
 int xmax = 0;
 int ymax = 0;
- 
+
 // Looks at the alpha channel to find the minimum extents of the image
 unsigned char* pixel = pixBuffer + 3;
 for (int y = 0; y < (int)height; ++y) {
@@ -1520,11 +1524,11 @@
 ymin = std::max(0, ymin - 1);
 xmax = std::min(xmax, (int)width);
 ymax = std::min(ymax, (int)height);
- 
+
 newwidth	= xmax - xmin;
 newheight	= ymax - ymin;
 int newsize	= newwidth * newheight * 4;
- 
+
 unsigned char* buf = new unsigned char[newsize];
 unsigned int* dst = (unsigned int*)buf;
 unsigned int* src = (unsigned int*)pixBuffer;
@@ -1540,7 +1544,7 @@
 bounds[1] = Py::Int(ymin);
 bounds[2] = Py::Int(newwidth);
 bounds[3] = Py::Int(newheight);
- 
+
 Py::Tuple result(2);
 result[0] = data;
 result[1] = bounds;
Modified: branches/transforms/src/agg_py_path_iterator.h
===================================================================
--- branches/transforms/src/agg_py_path_iterator.h	2007年11月28日 18:18:11 UTC (rev 4487)
+++ branches/transforms/src/agg_py_path_iterator.h	2007年11月28日 18:26:40 UTC (rev 4488)
@@ -17,7 +17,7 @@
 m_vertices(NULL), m_codes(NULL), m_iterator(0) {
 Py::Object vertices_obj = path_obj.getAttr("vertices");
 Py::Object codes_obj = path_obj.getAttr("codes");
- 
+
 m_vertices = (PyArrayObject*)PyArray_FromObject
 (vertices_obj.ptr(), PyArray_DOUBLE, 2, 2);
 if (!m_vertices || PyArray_NDIM(m_vertices) != 2 || PyArray_DIM(m_vertices, 1) != 2)
@@ -26,7 +26,7 @@
 if (codes_obj.ptr() != Py_None) {
 m_codes = (PyArrayObject*)PyArray_FromObject
 	(codes_obj.ptr(), PyArray_UINT8, 1, 1);
- if (!m_codes) 
+ if (!m_codes)
 	throw Py::ValueError("Invalid codes array.");
 }
 
@@ -40,11 +40,11 @@
 
 static const char code_map[];
 
+ private:
 inline unsigned vertex(unsigned idx, double* x, double* y) {
- if (idx > m_total_vertices)
- throw Py::RuntimeError("Requested vertex past end");
- *x = *(double*)PyArray_GETPTR2(m_vertices, idx, 0);
- *y = *(double*)PyArray_GETPTR2(m_vertices, idx, 1);
+ char* pair = (char*)PyArray_GETPTR2(m_vertices, idx, 0);
+ *x = *(double*)pair;
+ *y = *(double*)(pair + PyArray_STRIDE(m_vertices, 1));
 if (m_codes) {
 return code_map[(int)*(char *)PyArray_GETPTR1(m_codes, idx)];
 } else {
@@ -52,6 +52,7 @@
 }
 }
 
+ public:
 inline unsigned vertex(double* x, double* y) {
 if (m_iterator >= m_total_vertices) return agg::path_cmd_stop;
 return vertex(m_iterator++, x, y);
@@ -71,10 +72,10 @@
 };
 
 // Maps path codes on the Python side to agg path commands
-const char PathIterator::code_map[] = 
- {0, 
- agg::path_cmd_move_to, 
- agg::path_cmd_line_to, 
+const char PathIterator::code_map[] =
+ {0,
+ agg::path_cmd_move_to,
+ agg::path_cmd_line_to,
 agg::path_cmd_curve3,
 agg::path_cmd_curve4,
 agg::path_cmd_end_poly | agg::path_flags_close};
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <md...@us...> - 2007年11月29日 15:40:44
Revision: 4501
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4501&view=rev
Author: mdboom
Date: 2007年11月29日 07:40:42 -0800 (2007年11月29日)
Log Message:
-----------
Ran "astyle --style=ansi" to convert to ANSI style.
Modified Paths:
--------------
 branches/transforms/src/_path.cpp
 branches/transforms/src/agg_py_path_iterator.h
 branches/transforms/src/agg_py_transforms.h
Modified: branches/transforms/src/_path.cpp
===================================================================
--- branches/transforms/src/_path.cpp	2007年11月29日 13:50:25 UTC (rev 4500)
+++ branches/transforms/src/_path.cpp	2007年11月29日 15:40:42 UTC (rev 4501)
@@ -11,61 +11,61 @@
 
 // MGDTODO: Un-CXX-ify this module
 
-struct XY {
- double x;
- double y;
+struct XY
+{
+ double x;
+ double y;
 
- XY(double x_, double y_) : x(x_), y(y_) {}
+ XY(double x_, double y_) : x(x_), y(y_) {}
 };
 
 // the extension module
 class _path_module : public Py::ExtensionModule<_path_module>
 {
 public:
- _path_module()
- : Py::ExtensionModule<_path_module>( "_path" )
- {
- add_varargs_method("point_in_path", &_path_module::point_in_path,
-		 "point_in_path(x, y, path, trans)");
- add_varargs_method("point_on_path", &_path_module::point_on_path,
-		 "point_on_path(x, y, r, path, trans)");
- add_varargs_method("get_path_extents", &_path_module::get_path_extents,
-		 "get_path_extents(path, trans)");
- add_varargs_method("update_path_extents", &_path_module::update_path_extents,
-		 "update_path_extents(path, trans, bbox, minpos)");
- add_varargs_method("get_path_collection_extents", &_path_module::get_path_collection_extents,
-		 "get_path_collection_extents(trans, paths, transforms, offsets, offsetTrans)");
- add_varargs_method("point_in_path_collection", &_path_module::point_in_path_collection,
-		 "point_in_path_collection(x, y, r, trans, paths, transforms, offsets, offsetTrans, filled)");
- add_varargs_method("path_in_path", &_path_module::path_in_path,
-		 "path_in_path(a, atrans, b, btrans)");
- add_varargs_method("clip_path_to_rect", &_path_module::clip_path_to_rect,
-		 "clip_path_to_rect(path, bbox, inside)");
- add_varargs_method("affine_transform", &_path_module::affine_transform,
-		 "affine_transform(vertices, transform)");
- add_varargs_method("count_bboxes_overlapping_bbox", &_path_module::count_bboxes_overlapping_bbox,
-		 "count_bboxes_overlapping_bbox(bbox, bboxes)");
- add_varargs_method("path_intersects_path", &_path_module::path_intersects_path,
-		 "path_intersects_path(p1, p2)");
+ _path_module()
+ : Py::ExtensionModule<_path_module>( "_path" )
+ {
+ add_varargs_method("point_in_path", &_path_module::point_in_path,
+ "point_in_path(x, y, path, trans)");
+ add_varargs_method("point_on_path", &_path_module::point_on_path,
+ "point_on_path(x, y, r, path, trans)");
+ add_varargs_method("get_path_extents", &_path_module::get_path_extents,
+ "get_path_extents(path, trans)");
+ add_varargs_method("update_path_extents", &_path_module::update_path_extents,
+ "update_path_extents(path, trans, bbox, minpos)");
+ add_varargs_method("get_path_collection_extents", &_path_module::get_path_collection_extents,
+ "get_path_collection_extents(trans, paths, transforms, offsets, offsetTrans)");
+ add_varargs_method("point_in_path_collection", &_path_module::point_in_path_collection,
+ "point_in_path_collection(x, y, r, trans, paths, transforms, offsets, offsetTrans, filled)");
+ add_varargs_method("path_in_path", &_path_module::path_in_path,
+ "path_in_path(a, atrans, b, btrans)");
+ add_varargs_method("clip_path_to_rect", &_path_module::clip_path_to_rect,
+ "clip_path_to_rect(path, bbox, inside)");
+ add_varargs_method("affine_transform", &_path_module::affine_transform,
+ "affine_transform(vertices, transform)");
+ add_varargs_method("count_bboxes_overlapping_bbox", &_path_module::count_bboxes_overlapping_bbox,
+ "count_bboxes_overlapping_bbox(bbox, bboxes)");
+ add_varargs_method("path_intersects_path", &_path_module::path_intersects_path,
+ "path_intersects_path(p1, p2)");
 
- initialize("Helper functions for paths");
- }
+ initialize("Helper functions for paths");
+ }
 
- virtual ~_path_module() {}
+ virtual ~_path_module() {}
 
 private:
-
- Py::Object point_in_path(const Py::Tuple& args);
- Py::Object point_on_path(const Py::Tuple& args);
- Py::Object get_path_extents(const Py::Tuple& args);
- Py::Object update_path_extents(const Py::Tuple& args);
- Py::Object get_path_collection_extents(const Py::Tuple& args);
- Py::Object point_in_path_collection(const Py::Tuple& args);
- Py::Object path_in_path(const Py::Tuple& args);
- Py::Object clip_path_to_rect(const Py::Tuple& args);
- Py::Object affine_transform(const Py::Tuple& args);
- Py::Object count_bboxes_overlapping_bbox(const Py::Tuple& args);
- Py::Object path_intersects_path(const Py::Tuple& args);
+ Py::Object point_in_path(const Py::Tuple& args);
+ Py::Object point_on_path(const Py::Tuple& args);
+ Py::Object get_path_extents(const Py::Tuple& args);
+ Py::Object update_path_extents(const Py::Tuple& args);
+ Py::Object get_path_collection_extents(const Py::Tuple& args);
+ Py::Object point_in_path_collection(const Py::Tuple& args);
+ Py::Object path_in_path(const Py::Tuple& args);
+ Py::Object clip_path_to_rect(const Py::Tuple& args);
+ Py::Object affine_transform(const Py::Tuple& args);
+ Py::Object count_bboxes_overlapping_bbox(const Py::Tuple& args);
+ Py::Object path_intersects_path(const Py::Tuple& args);
 };
 
 //
@@ -106,466 +106,528 @@
 // Input 2D polygon _pgon_ with _numverts_ number of vertices and test point
 // _point_, returns 1 if inside, 0 if outside.
 template<class T>
-bool point_in_path_impl(double tx, double ty, T& path) {
- int yflag0, yflag1, inside_flag;
- double vtx0, vty0, vtx1, vty1, sx, sy;
- double x, y;
+bool point_in_path_impl(double tx, double ty, T& path)
+{
+ int yflag0, yflag1, inside_flag;
+ double vtx0, vty0, vtx1, vty1, sx, sy;
+ double x, y;
 
- path.rewind(0);
+ path.rewind(0);
 
- inside_flag = 0;
+ inside_flag = 0;
 
- unsigned code = 0;
- do {
- if (code != agg::path_cmd_move_to)
- code = path.vertex(&x, &y);
+ unsigned code = 0;
+ do
+ {
+ if (code != agg::path_cmd_move_to)
+ code = path.vertex(&x, &y);
 
- sx = vtx0 = x;
- sy = vty0 = y;
+ sx = vtx0 = x;
+ sy = vty0 = y;
 
- // get test bit for above/below X axis
- yflag0 = (vty0 >= ty);
+ // get test bit for above/below X axis
+ yflag0 = (vty0 >= ty);
 
- vtx1 = x;
- vty1 = x;
+ vtx1 = x;
+ vty1 = x;
 
- inside_flag = 0;
- do {
- code = path.vertex(&x, &y);
+ inside_flag = 0;
+ do
+ {
+ code = path.vertex(&x, &y);
 
- // The following cases denote the beginning on a new subpath
- if (code == agg::path_cmd_stop || (code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly) {
-	x = sx; y = sy;
- } else if (code == agg::path_cmd_move_to)
-	break;
+ // The following cases denote the beginning on a new subpath
+ if (code == agg::path_cmd_stop || 
+		(code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly)
+ {
+ x = sx;
+ y = sy;
+ }
+ else if (code == agg::path_cmd_move_to)
+ break;
 
- yflag1 = (vty1 >= ty);
- // Check if endpoints straddle (are on opposite sides) of X axis
- // (i.e. the Y's differ); if so, +X ray could intersect this edge.
- // The old test also checked whether the endpoints are both to the
- // right or to the left of the test point. However, given the faster
- // intersection point computation used below, this test was found to
- // be a break-even proposition for most polygons and a loser for
- // triangles (where 50% or more of the edges which survive this test
- // will cross quadrants and so have to have the X intersection computed
- // anyway). I credit Joseph Samosky with inspiring me to try dropping
- // the "both left or both right" part of my code.
- if (yflag0 != yflag1) {
-	// Check intersection of pgon segment with +X ray.
-	// Note if >= point's X; if so, the ray hits it.
-	// The division operation is avoided for the ">=" test by checking
-	// the sign of the first vertex wrto the test point; idea inspired
-	// by Joseph Samosky's and Mark Haigh-Hutchinson's different
-	// polygon inclusion tests.
-	if ( ((vty1-ty) * (vtx0-vtx1) >=
-	 (vtx1-tx) * (vty0-vty1)) == yflag1 ) {
-	 inside_flag ^= 1;
-	}
- }
+ yflag1 = (vty1 >= ty);
+ // Check if endpoints straddle (are on opposite sides) of X axis
+ // (i.e. the Y's differ); if so, +X ray could intersect this edge.
+ // The old test also checked whether the endpoints are both to the
+ // right or to the left of the test point. However, given the faster
+ // intersection point computation used below, this test was found to
+ // be a break-even proposition for most polygons and a loser for
+ // triangles (where 50% or more of the edges which survive this test
+ // will cross quadrants and so have to have the X intersection computed
+ // anyway). I credit Joseph Samosky with inspiring me to try dropping
+ // the "both left or both right" part of my code.
+ if (yflag0 != yflag1)
+ {
+ // Check intersection of pgon segment with +X ray.
+ // Note if >= point's X; if so, the ray hits it.
+ // The division operation is avoided for the ">=" test by checking
+ // the sign of the first vertex wrto the test point; idea inspired
+ // by Joseph Samosky's and Mark Haigh-Hutchinson's different
+ // polygon inclusion tests.
+ if ( ((vty1-ty) * (vtx0-vtx1) >=
+ (vtx1-tx) * (vty0-vty1)) == yflag1 )
+ {
+ inside_flag ^= 1;
+ }
+ }
 
- // Move to the next pair of vertices, retaining info as possible.
- yflag0 = yflag1;
- vtx0 = vtx1;
- vty0 = vty1;
+ // Move to the next pair of vertices, retaining info as possible.
+ yflag0 = yflag1;
+ vtx0 = vtx1;
+ vty0 = vty1;
 
- vtx1 = x;
- vty1 = y;
- } while (code != agg::path_cmd_stop &&
-	 (code & agg::path_cmd_end_poly) != agg::path_cmd_end_poly);
+ vtx1 = x;
+ vty1 = y;
+ }
+ while (code != agg::path_cmd_stop &&
+	 (code & agg::path_cmd_end_poly) != agg::path_cmd_end_poly);
 
- yflag1 = (vty1 >= ty);
- if (yflag0 != yflag1) {
- if ( ((vty1-ty) * (vtx0-vtx1) >=
-	 (vtx1-tx) * (vty0-vty1)) == yflag1 ) {
-	inside_flag ^= 1;
- }
+ yflag1 = (vty1 >= ty);
+ if (yflag0 != yflag1)
+ {
+ if ( ((vty1-ty) * (vtx0-vtx1) >=
+		 (vtx1-tx) * (vty0-vty1)) == yflag1 )
+ {
+ inside_flag ^= 1;
+ }
+ }
+
+ if (inside_flag != 0)
+ return true;
 }
+ while (code != agg::path_cmd_stop);
 
- if (inside_flag != 0)
- return true;
- } while (code != agg::path_cmd_stop);
-
- return (inside_flag != 0);
+ return (inside_flag != 0);
 }
 
-inline bool point_in_path(double x, double y, PathIterator& path, const agg::trans_affine& trans) {
- typedef agg::conv_transform<PathIterator> transformed_path_t;
- typedef agg::conv_curve<transformed_path_t> curve_t;
+inline bool point_in_path(double x, double y, PathIterator& path, const agg::trans_affine& trans)
+{
+ typedef agg::conv_transform<PathIterator> transformed_path_t;
+ typedef agg::conv_curve<transformed_path_t> curve_t;
 
- if (path.total_vertices() < 3)
- return false;
+ if (path.total_vertices() < 3)
+ return false;
 
- transformed_path_t trans_path(path, trans);
- curve_t curved_path(trans_path);
- return point_in_path_impl(x, y, curved_path);
+ transformed_path_t trans_path(path, trans);
+ curve_t curved_path(trans_path);
+ return point_in_path_impl(x, y, curved_path);
 }
 
-inline bool point_on_path(double x, double y, double r, PathIterator& path, const agg::trans_affine& trans) {
- 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;
+inline bool point_on_path(double x, double y, double r, PathIterator& path, const agg::trans_affine& trans)
+{
+ 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;
 
- transformed_path_t trans_path(path, trans);
- curve_t curved_path(trans_path);
- stroke_t stroked_path(curved_path);
- stroked_path.width(r * 2.0);
- return point_in_path_impl(x, y, stroked_path);
+ transformed_path_t trans_path(path, trans);
+ curve_t curved_path(trans_path);
+ stroke_t stroked_path(curved_path);
+ stroked_path.width(r * 2.0);
+ return point_in_path_impl(x, y, stroked_path);
 }
 
-Py::Object _path_module::point_in_path(const Py::Tuple& args) {
- args.verify_length(4);
+Py::Object _path_module::point_in_path(const Py::Tuple& args)
+{
+ args.verify_length(4);
 
- double x = Py::Float(args[0]);
- double y = Py::Float(args[1]);
- PathIterator path(args[2]);
- agg::trans_affine trans = py_to_agg_transformation_matrix(args[3]);
+ double x = Py::Float(args[0]);
+ double y = Py::Float(args[1]);
+ PathIterator path(args[2]);
+ agg::trans_affine trans = py_to_agg_transformation_matrix(args[3]);
 
- if (::point_in_path(x, y, path, trans))
- return Py::Int(1);
- return Py::Int(0);
+ if (::point_in_path(x, y, path, trans))
+ return Py::Int(1);
+ return Py::Int(0);
 }
 
-Py::Object _path_module::point_on_path(const Py::Tuple& args) {
- args.verify_length(5);
+Py::Object _path_module::point_on_path(const Py::Tuple& args)
+{
+ args.verify_length(5);
 
- double x = Py::Float(args[0]);
- double y = Py::Float(args[1]);
- double r = Py::Float(args[2]);
- PathIterator path(args[3]);
- agg::trans_affine trans = py_to_agg_transformation_matrix(args[4]);
+ double x = Py::Float(args[0]);
+ double y = Py::Float(args[1]);
+ double r = Py::Float(args[2]);
+ PathIterator path(args[3]);
+ agg::trans_affine trans = py_to_agg_transformation_matrix(args[4]);
 
- if (::point_on_path(x, y, r, path, trans))
- return Py::Int(1);
- return Py::Int(0);
+ if (::point_on_path(x, y, r, path, trans))
+ return Py::Int(1);
+ return Py::Int(0);
 }
 
 void get_path_extents(PathIterator& path, const agg::trans_affine& trans,
-		 double* x0, double* y0, double* x1, double* y1,
-		 double* xm, double* ym) {
- typedef agg::conv_transform<PathIterator> transformed_path_t;
- typedef agg::conv_curve<transformed_path_t> curve_t;
- double x, y;
- unsigned code;
+ double* x0, double* y0, double* x1, double* y1,
+ double* xm, double* ym)
+{
+ typedef agg::conv_transform<PathIterator> transformed_path_t;
+ typedef agg::conv_curve<transformed_path_t> curve_t;
+ double x, y;
+ unsigned code;
 
- transformed_path_t tpath(path, trans);
- curve_t curved_path(tpath);
+ transformed_path_t tpath(path, trans);
+ curve_t curved_path(tpath);
 
- curved_path.rewind(0);
+ curved_path.rewind(0);
 
- while ((code = curved_path.vertex(&x, &y)) != agg::path_cmd_stop) {
- if ((code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly)
- continue;
- if (x < *x0) {
- *x0 = x;
- if (x > 0.0)
-	*xm = x;
+ while ((code = curved_path.vertex(&x, &y)) != agg::path_cmd_stop)
+ {
+ if ((code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly)
+ continue;
+ if (x < *x0)
+ {
+ *x0 = x;
+ if (x > 0.0)
+ *xm = x;
+ }
+ if (y < *y0)
+ {
+ *y0 = y;
+ if (y > 0.0)
+ *ym = y;
+ }
+ if (x > *x1) *x1 = x;
+ if (y > *y1) *y1 = y;
 }
- if (y < *y0) {
- *y0 = y;
- if (y > 0.0)
-	*ym = y;
- }
- if (x > *x1) *x1 = x;
- if (y > *y1) *y1 = y;
- }
 }
 
-Py::Object _path_module::get_path_extents(const Py::Tuple& args) {
- args.verify_length(2);
+Py::Object _path_module::get_path_extents(const Py::Tuple& args)
+{
+ args.verify_length(2);
 
- PathIterator path(args[0]);
- agg::trans_affine trans = py_to_agg_transformation_matrix(args[1], false);
+ PathIterator path(args[0]);
+ agg::trans_affine trans = py_to_agg_transformation_matrix(args[1], false);
 
- npy_intp extent_dims[] = { 2, 2, 0 };
- double* extents_data = new double[4];
- double xm, ym;
- PyArrayObject* extents = NULL;
- try {
- extents_data[0] = std::numeric_limits<double>::infinity();
- extents_data[1] = std::numeric_limits<double>::infinity();
- extents_data[2] = -std::numeric_limits<double>::infinity();
- extents_data[3] = -std::numeric_limits<double>::infinity();
+ npy_intp extent_dims[] = { 2, 2, 0 };
+ double* extents_data = new double[4];
+ double xm, ym;
+ PyArrayObject* extents = NULL;
+ try
+ {
+ extents_data[0] = std::numeric_limits<double>::infinity();
+ extents_data[1] = std::numeric_limits<double>::infinity();
+ extents_data[2] = -std::numeric_limits<double>::infinity();
+ extents_data[3] = -std::numeric_limits<double>::infinity();
 
- ::get_path_extents(path, trans,
-		 &extents_data[0], &extents_data[1], &extents_data[2], &extents_data[3],
-		 &xm, &ym);
+ ::get_path_extents(path, trans,
+ &extents_data[0], &extents_data[1], &extents_data[2], &extents_data[3],
+ &xm, &ym);
 
- extents = (PyArrayObject*)PyArray_SimpleNewFromData
- (2, extent_dims, PyArray_DOUBLE, extents_data);
- } catch (...) {
- if (extents)
- Py_XDECREF(extents);
- else
- delete[] extents_data;
- throw;
- }
+ extents = (PyArrayObject*)PyArray_SimpleNewFromData
+ (2, extent_dims, PyArray_DOUBLE, extents_data);
+ }
+ catch (...)
+ {
+ if (extents)
+ Py_XDECREF(extents);
+ else
+ delete[] extents_data;
+ throw;
+ }
 
- return Py::Object((PyObject*)extents);
+ return Py::Object((PyObject*)extents);
 }
 
-Py::Object _path_module::update_path_extents(const Py::Tuple& args) {
- args.verify_length(5);
+Py::Object _path_module::update_path_extents(const Py::Tuple& args)
+{
+ args.verify_length(5);
 
- double x0, y0, x1, y1;
- PathIterator path(args[0]);
- agg::trans_affine trans = py_to_agg_transformation_matrix(args[1], false);
- if (!py_convert_bbox(args[2].ptr(), x0, y0, x1, y1)) {
- throw Py::ValueError("Must pass Bbox object as arg 3 of update_path_extents");
- }
- Py::Object minpos_obj = args[3];
- bool ignore = bool(Py::Int(args[4]));
+ double x0, y0, x1, y1;
+ PathIterator path(args[0]);
+ agg::trans_affine trans = py_to_agg_transformation_matrix(args[1], false);
+ if (!py_convert_bbox(args[2].ptr(), x0, y0, x1, y1))
+ {
+ throw Py::ValueError("Must pass Bbox object as arg 3 of update_path_extents");
+ }
+ Py::Object minpos_obj = args[3];
+ bool ignore = bool(Py::Int(args[4]));
 
- double xm, ym;
- PyArrayObject* input_minpos = NULL;
- try {
- input_minpos = (PyArrayObject*)PyArray_FromObject(minpos_obj.ptr(), PyArray_DOUBLE, 1, 1);
- if (!input_minpos || PyArray_DIM(input_minpos, 0) != 2) {
- throw Py::TypeError("Argument 4 to update_path_extents must be a length-2 numpy array.");
+ double xm, ym;
+ PyArrayObject* input_minpos = NULL;
+ try
+ {
+ input_minpos = (PyArrayObject*)PyArray_FromObject(minpos_obj.ptr(), PyArray_DOUBLE, 1, 1);
+ if (!input_minpos || PyArray_DIM(input_minpos, 0) != 2)
+ {
+ throw Py::TypeError("Argument 4 to update_path_extents must be a length-2 numpy array.");
+ }
+ xm = *(double*)PyArray_GETPTR1(input_minpos, 0);
+ ym = *(double*)PyArray_GETPTR1(input_minpos, 1);
 }
- xm = *(double*)PyArray_GETPTR1(input_minpos, 0);
- ym = *(double*)PyArray_GETPTR1(input_minpos, 1);
- } catch (...) {
+ catch (...)
+ {
+ Py_XDECREF(input_minpos);
+ throw;
+ }
 Py_XDECREF(input_minpos);
- throw;
- }
- Py_XDECREF(input_minpos);
 
- npy_intp extent_dims[] = { 2, 2, 0 };
- double* extents_data = new double[4];
- npy_intp minpos_dims[] = { 2, 0 };
- double* minpos_data = new double[2];
- PyArrayObject* extents = NULL;
- PyArrayObject* minpos = NULL;
- bool changed = false;
+ npy_intp extent_dims[] = { 2, 2, 0 };
+ double* extents_data = new double[4];
+ npy_intp minpos_dims[] = { 2, 0 };
+ double* minpos_data = new double[2];
+ PyArrayObject* extents = NULL;
+ PyArrayObject* minpos = NULL;
+ bool changed = false;
 
- try {
- if (ignore) {
- extents_data[0] = std::numeric_limits<double>::infinity();
- extents_data[1] = std::numeric_limits<double>::infinity();
- extents_data[2] = -std::numeric_limits<double>::infinity();
- extents_data[3] = -std::numeric_limits<double>::infinity();
- minpos_data[0] = std::numeric_limits<double>::infinity();
- minpos_data[1] = std::numeric_limits<double>::infinity();
- } else {
- extents_data[0] = std::min(x0, x1);
- extents_data[1] = std::min(y0, y1);
- extents_data[2] = std::max(x0, x1);
- extents_data[3] = std::max(y0, y1);
- minpos_data[0] = xm;
- minpos_data[1] = ym;
- }
+ try
+ {
+ if (ignore)
+ {
+ extents_data[0] = std::numeric_limits<double>::infinity();
+ extents_data[1] = std::numeric_limits<double>::infinity();
+ extents_data[2] = -std::numeric_limits<double>::infinity();
+ extents_data[3] = -std::numeric_limits<double>::infinity();
+ minpos_data[0] = std::numeric_limits<double>::infinity();
+ minpos_data[1] = std::numeric_limits<double>::infinity();
+ }
+ else
+ {
+ extents_data[0] = std::min(x0, x1);
+ extents_data[1] = std::min(y0, y1);
+ extents_data[2] = std::max(x0, x1);
+ extents_data[3] = std::max(y0, y1);
+ minpos_data[0] = xm;
+ minpos_data[1] = ym;
+ }
 
- ::get_path_extents(path, trans,
-		 &extents_data[0], &extents_data[1], &extents_data[2], &extents_data[3],
-		 &minpos_data[0], &minpos_data[1]);
+ ::get_path_extents(path, trans,
+ &extents_data[0], &extents_data[1], &extents_data[2], &extents_data[3],
+ &minpos_data[0], &minpos_data[1]);
 
- changed = (extents_data[0] != x0 ||
-	 extents_data[1] != y0 ||
-	 extents_data[2] != x1 ||
-	 extents_data[3] != y1 ||
-	 minpos_data[0] != xm ||
-	 minpos_data[1] != ym);
+ changed = (extents_data[0] != x0 ||
+ extents_data[1] != y0 ||
+ extents_data[2] != x1 ||
+ extents_data[3] != y1 ||
+ minpos_data[0] != xm ||
+ minpos_data[1] != ym);
 
- extents = (PyArrayObject*)PyArray_SimpleNewFromData
- (2, extent_dims, PyArray_DOUBLE, extents_data);
- minpos = (PyArrayObject*)PyArray_SimpleNewFromData
- (1, minpos_dims, PyArray_DOUBLE, minpos_data);
- } catch(...) {
- if (extents)
- Py_XDECREF(extents);
- else
- delete[] extents_data;
- if (minpos)
- Py_XDECREF(minpos);
- else
- delete[] minpos_data;
- throw;
- }
+ extents = (PyArrayObject*)PyArray_SimpleNewFromData
+ (2, extent_dims, PyArray_DOUBLE, extents_data);
+ minpos = (PyArrayObject*)PyArray_SimpleNewFromData
+ (1, minpos_dims, PyArray_DOUBLE, minpos_data);
+ }
+ catch (...)
+ {
+ if (extents)
+ Py_XDECREF(extents);
+ else
+ delete[] extents_data;
+ if (minpos)
+ Py_XDECREF(minpos);
+ else
+ delete[] minpos_data;
+ throw;
+ }
 
- Py::Tuple result(3);
- result[0] = Py::Object((PyObject*) extents);
- result[1] = Py::Object((PyObject*) minpos);
- result[2] = Py::Int(changed ? 1 : 0);
+ Py::Tuple result(3);
+ result[0] = Py::Object((PyObject*) extents);
+ result[1] = Py::Object((PyObject*) minpos);
+ result[2] = Py::Int(changed ? 1 : 0);
 
- return result;
+ return result;
 }
 
-Py::Object _path_module::get_path_collection_extents(const Py::Tuple& args) {
- args.verify_length(5);
+Py::Object _path_module::get_path_collection_extents(const Py::Tuple& args)
+{
+ args.verify_length(5);
 
- //segments, trans, clipbox, colors, linewidths, antialiaseds
- agg::trans_affine	 master_transform = py_to_agg_transformation_matrix(args[0]);
- Py::SeqBase<Py::Object> paths		 = args[1];
- Py::SeqBase<Py::Object> transforms_obj = args[2];
- Py::Object offsets_obj = args[3];
- agg::trans_affine offset_trans = py_to_agg_transformation_matrix(args[4], false);
+ //segments, trans, clipbox, colors, linewidths, antialiaseds
+ agg::trans_affine	 master_transform = py_to_agg_transformation_matrix(args[0]);
+ Py::SeqBase<Py::Object> paths		 = args[1];
+ Py::SeqBase<Py::Object> transforms_obj = args[2];
+ Py::Object offsets_obj = args[3];
+ agg::trans_affine offset_trans = py_to_agg_transformation_matrix(args[4], false);
 
- PyArrayObject* offsets = NULL;
- double x0, y0, x1, y1, xm, ym;
+ PyArrayObject* offsets = NULL;
+ double x0, y0, x1, y1, xm, ym;
 
- try {
- offsets = (PyArrayObject*)PyArray_FromObject(offsets_obj.ptr(), PyArray_DOUBLE, 0, 2);
- if (!offsets ||
-	(PyArray_NDIM(offsets) == 2 && PyArray_DIM(offsets, 1) != 2) ||
-	(PyArray_NDIM(offsets) == 1 && PyArray_DIM(offsets, 0) != 0)) {
- throw Py::ValueError("Offsets array must be Nx2");
- }
+ try
+ {
+ offsets = (PyArrayObject*)PyArray_FromObject(offsets_obj.ptr(), PyArray_DOUBLE, 0, 2);
+ if (!offsets ||
+	 (PyArray_NDIM(offsets) == 2 && PyArray_DIM(offsets, 1) != 2) ||
+	 (PyArray_NDIM(offsets) == 1 && PyArray_DIM(offsets, 0) != 0))
+ {
+ throw Py::ValueError("Offsets array must be Nx2");
+ }
 
- size_t Npaths = paths.length();
- size_t Noffsets = offsets->dimensions[0];
- size_t N	 = std::max(Npaths, Noffsets);
- size_t Ntransforms = std::min(transforms_obj.length(), N);
- size_t i;
+ size_t Npaths = paths.length();
+ size_t Noffsets = offsets->dimensions[0];
+ size_t N	 = std::max(Npaths, Noffsets);
+ size_t Ntransforms = std::min(transforms_obj.length(), N);
+ size_t i;
 
- // Convert all of the transforms up front
- typedef std::vector<agg::trans_affine> transforms_t;
- transforms_t transforms;
- transforms.reserve(Ntransforms);
- for (i = 0; i < Ntransforms; ++i) {
- agg::trans_affine trans = py_to_agg_transformation_matrix
-	(transforms_obj[i], false);
- trans *= master_transform;
- transforms.push_back(trans);
- }
+ // Convert all of the transforms up front
+ typedef std::vector<agg::trans_affine> transforms_t;
+ transforms_t transforms;
+ transforms.reserve(Ntransforms);
+ for (i = 0; i < Ntransforms; ++i)
+ {
+ agg::trans_affine trans = py_to_agg_transformation_matrix
+ (transforms_obj[i], false);
+ trans *= master_transform;
+ transforms.push_back(trans);
+ }
 
- // The offset each of those and collect the mins/maxs
- x0 = std::numeric_limits<double>::infinity();
- y0 = std::numeric_limits<double>::infinity();
- x1 = -std::numeric_limits<double>::infinity();
- y1 = -std::numeric_limits<double>::infinity();
- agg::trans_affine trans;
+ // The offset each of those and collect the mins/maxs
+ x0 = std::numeric_limits<double>::infinity();
+ y0 = std::numeric_limits<double>::infinity();
+ x1 = -std::numeric_limits<double>::infinity();
+ y1 = -std::numeric_limits<double>::infinity();
+ agg::trans_affine trans;
 
- for (i = 0; i < N; ++i) {
- PathIterator path(paths[i % Npaths]);
- if (Ntransforms) {
-	trans = transforms[i % Ntransforms];
- } else {
-	trans = master_transform;
- }
+ for (i = 0; i < N; ++i)
+ {
+ PathIterator path(paths[i % Npaths]);
+ if (Ntransforms)
+ {
+ trans = transforms[i % Ntransforms];
+ }
+ else
+ {
+ trans = master_transform;
+ }
 
- if (Noffsets) {
-	double xo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 0);
-	double yo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 1);
-	offset_trans.transform(&xo, &yo);
-	trans *= agg::trans_affine_translation(xo, yo);
- }
+ if (Noffsets)
+ {
+ double xo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 0);
+ double yo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 1);
+ offset_trans.transform(&xo, &yo);
+ trans *= agg::trans_affine_translation(xo, yo);
+ }
 
- ::get_path_extents(path, trans, &x0, &y0, &x1, &y1, &xm, &ym);
+ ::get_path_extents(path, trans, &x0, &y0, &x1, &y1, &xm, &ym);
+ }
 }
- } catch (...) {
+ catch (...)
+ {
+ Py_XDECREF(offsets);
+ throw;
+ }
+
 Py_XDECREF(offsets);
- throw;
- }
 
- Py_XDECREF(offsets);
-
- Py::Tuple result(4);
- result[0] = Py::Float(x0);
- result[1] = Py::Float(y0);
- result[2] = Py::Float(x1);
- result[3] = Py::Float(y1);
- return result;
+ Py::Tuple result(4);
+ result[0] = Py::Float(x0);
+ result[1] = Py::Float(y0);
+ result[2] = Py::Float(x1);
+ result[3] = Py::Float(y1);
+ return result;
 }
 
-Py::Object _path_module::point_in_path_collection(const Py::Tuple& args) {
- args.verify_length(9);
+Py::Object _path_module::point_in_path_collection(const Py::Tuple& args)
+{
+ args.verify_length(9);
 
- //segments, trans, clipbox, colors, linewidths, antialiaseds
- double		 x		 = Py::Float(args[0]);
- double		 y		 = Py::Float(args[1]);
- double radius = Py::Float(args[2]);
- agg::trans_affine	 master_transform = py_to_agg_transformation_matrix(args[3]);
- Py::SeqBase<Py::Object> paths		 = args[4];
- Py::SeqBase<Py::Object> transforms_obj = args[5];
- Py::SeqBase<Py::Object> offsets_obj = args[6];
- agg::trans_affine offset_trans = py_to_agg_transformation_matrix(args[7]);
- bool filled = Py::Int(args[8]);
+ //segments, trans, clipbox, colors, linewidths, antialiaseds
+ double		 x		 = Py::Float(args[0]);
+ double		 y		 = Py::Float(args[1]);
+ double radius = Py::Float(args[2]);
+ agg::trans_affine	 master_transform = py_to_agg_transformation_matrix(args[3]);
+ Py::SeqBase<Py::Object> paths		 = args[4];
+ Py::SeqBase<Py::Object> transforms_obj = args[5];
+ Py::SeqBase<Py::Object> offsets_obj = args[6];
+ agg::trans_affine offset_trans = py_to_agg_transformation_matrix(args[7]);
+ bool filled = Py::Int(args[8]);
 
- PyArrayObject* offsets = (PyArrayObject*)PyArray_FromObject(offsets_obj.ptr(), PyArray_DOUBLE, 0, 2);
- if (!offsets ||
- (PyArray_NDIM(offsets) == 2 && PyArray_DIM(offsets, 1) != 2) ||
- (PyArray_NDIM(offsets) == 1 && PyArray_DIM(offsets, 0) != 0)) {
- throw Py::ValueError("Offsets array must be Nx2");
- }
+ PyArrayObject* offsets = (PyArrayObject*)PyArray_FromObject(offsets_obj.ptr(), PyArray_DOUBLE, 0, 2);
+ if (!offsets ||
+	(PyArray_NDIM(offsets) == 2 && PyArray_DIM(offsets, 1) != 2) ||
+	(PyArray_NDIM(offsets) == 1 && PyArray_DIM(offsets, 0) != 0))
+ {
+ throw Py::ValueError("Offsets array must be Nx2");
+ }
 
- size_t Npaths	 = paths.length();
- size_t Noffsets = offsets->dimensions[0];
- size_t N	 = std::max(Npaths, Noffsets);
- size_t Ntransforms = std::min(transforms_obj.length(), N);
- size_t i;
+ size_t Npaths	 = paths.length();
+ size_t Noffsets = offsets->dimensions[0];
+ size_t N	 = std::max(Npaths, Noffsets);
+ size_t Ntransforms = std::min(transforms_obj.length(), N);
+ size_t i;
 
- // Convert all of the transforms up front
- typedef std::vector<agg::trans_affine> transforms_t;
- transforms_t transforms;
- transforms.reserve(Ntransforms);
- for (i = 0; i < Ntransforms; ++i) {
- agg::trans_affine trans = py_to_agg_transformation_matrix
- (transforms_obj[i], false);
- trans *= master_transform;
- transforms.push_back(trans);
- }
+ // Convert all of the transforms up front
+ typedef std::vector<agg::trans_affine> transforms_t;
+ transforms_t transforms;
+ transforms.reserve(Ntransforms);
+ for (i = 0; i < Ntransforms; ++i)
+ {
+ agg::trans_affine trans = py_to_agg_transformation_matrix
+ (transforms_obj[i], false);
+ trans *= master_transform;
+ transforms.push_back(trans);
+ }
 
- Py::List result;
- agg::trans_affine trans;
+ Py::List result;
+ agg::trans_affine trans;
 
- for (i = 0; i < N; ++i) {
- PathIterator path(paths[i % Npaths]);
+ for (i = 0; i < N; ++i)
+ {
+ PathIterator path(paths[i % Npaths]);
 
- if (Ntransforms) {
- trans = transforms[i % Ntransforms];
- } else {
- trans = master_transform;
- }
+ if (Ntransforms)
+ {
+ trans = transforms[i % Ntransforms];
+ }
+ else
+ {
+ trans = master_transform;
+ }
 
- if (Noffsets) {
- double xo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 0);
- double yo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 1);
- offset_trans.transform(&xo, &yo);
- trans *= agg::trans_affine_translation(xo, yo);
- }
+ if (Noffsets)
+ {
+ double xo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 0);
+ double yo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 1);
+ offset_trans.transform(&xo, &yo);
+ trans *= agg::trans_affine_translation(xo, yo);
+ }
 
- if (filled) {
- if (::point_in_path(x, y, path, trans))
-	result.append(Py::Int((int)i));
- } else {
- if (::point_on_path(x, y, radius, path, trans))
-	result.append(Py::Int((int)i));
+ if (filled)
+ {
+ if (::point_in_path(x, y, path, trans))
+ result.append(Py::Int((int)i));
+ }
+ else
+ {
+ if (::point_on_path(x, y, radius, path, trans))
+ result.append(Py::Int((int)i));
+ }
 }
- }
 
- return result;
+ return result;
 }
 
 bool path_in_path(PathIterator& a, const agg::trans_affine& atrans,
-		 PathIterator& b, const agg::trans_affine& btrans) {
- typedef agg::conv_transform<PathIterator> transformed_path_t;
- typedef agg::conv_curve<transformed_path_t> curve_t;
+ PathIterator& b, const agg::trans_affine& btrans)
+{
+ typedef agg::conv_transform<PathIterator> transformed_path_t;
+ typedef agg::conv_curve<transformed_path_t> curve_t;
 
- if (a.total_vertices() < 3)
- return false;
+ if (a.total_vertices() < 3)
+ return false;
 
- transformed_path_t b_path_trans(b, btrans);
- curve_t b_curved(b_path_trans);
+ transformed_path_t b_path_trans(b, btrans);
+ curve_t b_curved(b_path_trans);
 
- double x, y;
- b_curved.rewind(0);
- while (b_curved.vertex(&x, &y) != agg::path_cmd_stop) {
- if (!::point_in_path(x, y, a, atrans))
- return false;
- }
+ double x, y;
+ b_curved.rewind(0);
+ while (b_curved.vertex(&x, &y) != agg::path_cmd_stop)
+ {
+ if (!::point_in_path(x, y, a, atrans))
+ return false;
+ }
 
- return true;
+ return true;
 }
 
-Py::Object _path_module::path_in_path(const Py::Tuple& args) {
- args.verify_length(4);
+Py::Object _path_module::path_in_path(const Py::Tuple& args)
+{
+ args.verify_length(4);
 
- PathIterator a(args[0]);
- agg::trans_affine atrans = py_to_agg_transformation_matrix(args[1]);
- PathIterator b(args[2]);
- agg::trans_affine btrans = py_to_agg_transformation_matrix(args[3]);
+ PathIterator a(args[0]);
+ agg::trans_affine atrans = py_to_agg_transformation_matrix(args[1]);
+ PathIterator b(args[2]);
+ agg::trans_affine btrans = py_to_agg_transformation_matrix(args[3]);
 
- return Py::Int(::path_in_path(a, atrans, b, btrans));
+ return Py::Int(::path_in_path(a, atrans, b, btrans));
 }
 
 /** The clip_path_to_rect code here is a clean-room implementation of the
@@ -576,398 +638,465 @@
 
 typedef std::vector<XY> Polygon;
 
-namespace clip_to_rect_filters {
- /* There are four different passes needed to create/remove vertices
- (one for each side of the rectangle). The differences between those
- passes are encapsulated in these functor classes.
- */
- struct bisectx {
+namespace clip_to_rect_filters
+{
+/* There are four different passes needed to create/remove vertices
+ (one for each side of the rectangle). The differences between those
+ passes are encapsulated in these functor classes.
+*/
+struct bisectx
+{
 double m_x;
 
 bisectx(double x) : m_x(x) {}
 
- void bisect(double sx, double sy, double px, double py, double* bx, double* by) const {
- *bx = m_x;
- double dx = px - sx;
- double dy = py - sy;
- *by = sy + dy * ((m_x - sx) / dx);
+ void bisect(double sx, double sy, double px, double py, double* bx, double* by) const
+ {
+ *bx = m_x;
+ double dx = px - sx;
+ double dy = py - sy;
+ *by = sy + dy * ((m_x - sx) / dx);
 }
- };
+};
 
- struct xlt : public bisectx {
+struct xlt : public bisectx
+{
 xlt(double x) : bisectx(x) {}
 
- bool is_inside(double x, double y) const {
- return x <= m_x;
+ bool is_inside(double x, double y) const
+ {
+ return x <= m_x;
 }
- };
+};
 
- struct xgt : public bisectx {
+struct xgt : public bisectx
+{
 xgt(double x) : bisectx(x) {}
 
- bool is_inside(double x, double y) const {
- return x >= m_x;
+ bool is_inside(double x, double y) const
+ {
+ return x >= m_x;
 }
- };
+};
 
- struct bisecty {
+struct bisecty
+{
 double m_y;
 
 bisecty(double y) : m_y(y) {}
 
- void bisect(double sx, double sy, double px, double py, double* bx, double* by) const {
- *by = m_y;
- double dx = px - sx;
- double dy = py - sy;
- *bx = sx + dx * ((m_y - sy) / dy);
+ void bisect(double sx, double sy, double px, double py, double* bx, double* by) const
+ {
+ *by = m_y;
+ double dx = px - sx;
+ double dy = py - sy;
+ *bx = sx + dx * ((m_y - sy) / dy);
 }
- };
+};
 
- struct ylt : public bisecty {
+struct ylt : public bisecty
+{
 ylt(double y) : bisecty(y) {}
 
- bool is_inside(double x, double y) const {
- return y <= m_y;
+ bool is_inside(double x, double y) const
+ {
+ return y <= m_y;
 }
- };
+};
 
- struct ygt : public bisecty {
+struct ygt : public bisecty
+{
 ygt(double y) : bisecty(y) {}
 
- bool is_inside(double x, double y) const {
- return y >= m_y;
+ bool is_inside(double x, double y) const
+ {
+ return y >= m_y;
 }
- };
+};
 }
 
 template<class Filter>
-void clip_to_rect_one_step(const Polygon& polygon, Polygon& result, const Filter& filter) {
- double sx, sy, px, py, bx, by;
- bool sinside, pinside;
- result.clear();
+void clip_to_rect_one_step(const Polygon& polygon, Polygon& result, const Filter& filter)
+{
+ double sx, sy, px, py, bx, by;
+ bool sinside, pinside;
+ result.clear();
 
- if (polygon.size() == 0)
- return;
+ if (polygon.size() == 0)
+ return;
 
- sx = polygon.back().x;
- sy = polygon.back().y;
- for (Polygon::const_iterator i = polygon.begin(); i != polygon.end(); ++i) {
- px = i->x;
- py = i->y;
+ sx = polygon.back().x;
+ sy = polygon.back().y;
+ for (Polygon::const_iterator i = polygon.begin(); i != polygon.end(); ++i)
+ {
+ px = i->x;
+ py = i->y;
 
- sinside = filter.is_inside(sx, sy);
- pinside = filter.is_inside(px, py);
+ sinside = filter.is_inside(sx, sy);
+ pinside = filter.is_inside(px, py);
 
- if (sinside ^ pinside) {
- filter.bisect(sx, sy, px, py, &bx, &by);
- result.push_back(XY(bx, by));
- }
+ if (sinside ^ pinside)
+ {
+ filter.bisect(sx, sy, px, py, &bx, &by);
+ result.push_back(XY(bx, by));
+ }
 
- if (pinside) {
- result.push_back(XY(px, py));
+ if (pinside)
+ {
+ result.push_back(XY(px, py));
+ }
+
+ sx = px;
+ sy = py;
 }
-
- sx = px; sy = py;
- }
 }
 
 void clip_to_rect(PathIterator& path,
-		 double x0, double y0, double x1, double y1,
-		 bool inside, std::vector<Polygon>& results) {
- double xmin, ymin, xmax, ymax;
- if (x0 < x1) {
- xmin = x0; xmax = x1;
- } else {
- xmin = x1; xmax = x0;
- }
+ double x0, double y0, double x1, double y1,
+ bool inside, std::vector<Polygon>& results)
+{
+ double xmin, ymin, xmax, ymax;
+ if (x0 < x1)
+ {
+ xmin = x0;
+ xmax = x1;
+ }
+ else
+ {
+ xmin = x1;
+ xmax = x0;
+ }
 
- if (y0 < y1) {
- ymin = y0; ymax = y1;
- } else {
- ymin = y1; ymax = y0;
- }
+ if (y0 < y1)
+ {
+ ymin = y0;
+ ymax = y1;
+ }
+ else
+ {
+ ymin = y1;
+ ymax = y0;
+ }
 
- if (!inside) {
- std::swap(xmin, xmax);
- std::swap(ymin, ymax);
- }
+ if (!inside)
+ {
+ std::swap(xmin, xmax);
+ std::swap(ymin, ymax);
+ }
 
- Polygon polygon1, polygon2;
- double x, y;
- unsigned code = 0;
- path.rewind(0);
+ Polygon polygon1, polygon2;
+ double x, y;
+ unsigned code = 0;
+ path.rewind(0);
 
- do {
- // Grab the next subpath and store it in polygon1
- polygon1.clear();
- do {
- if (code == agg::path_cmd_move_to)
-	polygon1.push_back(XY(x, y));
+ do
+ {
+ // Grab the next subpath and store it in polygon1
+ polygon1.clear();
+ do
+ {
+ if (code == agg::path_cmd_move_to)
+ polygon1.push_back(XY(x, y));
 
- code = path.vertex(&x, &y);
+ code = path.vertex(&x, &y);
 
- if (code == agg::path_cmd_stop)
-	break;
+ if (code == agg::path_cmd_stop)
+ break;
 
- if (code != agg::path_cmd_move_to)
-	polygon1.push_back(XY(x, y));
- } while ((code & agg::path_cmd_end_poly) != agg::path_cmd_end_poly);
+ if (code != agg::path_cmd_move_to)
+ polygon1.push_back(XY(x, y));
+ }
+ while ((code & agg::path_cmd_end_poly) != agg::path_cmd_end_poly);
 
- // The result of each step is fed into the next (note the
- // swapping of polygon1 and polygon2 at each step).
- clip_to_rect_one_step(polygon1, polygon2, clip_to_rect_filters::xlt(xmax));
- clip_to_rect_one_step(polygon2, polygon1, clip_to_rect_filters::xgt(xmin));
- clip_to_rect_one_step(polygon1, polygon2, clip_to_rect_filters::ylt(ymax));
- clip_to_rect_one_step(polygon2, polygon1, clip_to_rect_filters::ygt(ymin));
+ // The result of each step is fed into the next (note the
+ // swapping of polygon1 and polygon2 at each step).
+ clip_to_rect_one_step(polygon1, polygon2, clip_to_rect_filters::xlt(xmax));
+ clip_to_rect_one_step(polygon2, polygon1, clip_to_rect_filters::xgt(xmin));
+ clip_to_rect_one_step(polygon1, polygon2, clip_to_rect_filters::ylt(ymax));
+ clip_to_rect_one_step(polygon2, polygon1, clip_to_rect_filters::ygt(ymin));
 
- // Empty polygons aren't very useful, so skip them
- if (polygon1.size())
- results.push_back(polygon1);
- } while (code != agg::path_cmd_stop);
+ // Empty polygons aren't very useful, so skip them
+ if (polygon1.size())
+ results.push_back(polygon1);
+ }
+ while (code != agg::path_cmd_stop);
 }
 
-Py::Object _path_module::clip_path_to_rect(const Py::Tuple &args) {
- args.verify_length(3);
+Py::Object _path_module::clip_path_to_rect(const Py::Tuple &args)
+{
+ args.verify_length(3);
 
- PathIterator path(args[0]);
- Py::Object bbox_obj = args[1];
- bool inside = Py::Int(args[2]);
+ PathIterator path(args[0]);
+ Py::Object bbox_obj = args[1];
+ bool inside = Py::Int(args[2]);
 
- double x0, y0, x1, y1;
- if (!py_convert_bbox(bbox_obj.ptr(), x0, y0, x1, y1))
- throw Py::TypeError("Argument 2 to clip_to_rect must be a Bbox object.");
+ double x0, y0, x1, y1;
+ if (!py_convert_bbox(bbox_obj.ptr(), x0, y0, x1, y1))
+ throw Py::TypeError("Argument 2 to clip_to_rect must be a Bbox object.");
 
- std::vector<Polygon> results;
+ std::vector<Polygon> results;
 
- ::clip_to_rect(path, x0, y0, x1, y1, inside, results);
+ ::clip_to_rect(path, x0, y0, x1, y1, inside, results);
 
- int dims[2];
- dims[1] = 2;
- PyObject* py_results = PyList_New(results.size());
- if (!py_results)
- throw Py::RuntimeError("Error creating results list");
- try {
- for (std::vector<Polygon>::const_iterator p = results.begin(); p != results.end(); ++p) {
- size_t size = p->size();
- dims[0] = p->size();
- PyArrayObject* pyarray = (PyArrayObject*)PyArray_FromDims(2, dims, PyArray_DOUBLE);
- for (size_t i = 0; i < size; ++i) {
-	((double *)pyarray->data)[2*i]	 = (*p)[i].x;
-	((double *)pyarray->data)[2*i+1] = (*p)[i].y;
- }
- if (PyList_SetItem(py_results, p - results.begin(), (PyObject *)pyarray) != -1) {
-	throw Py::RuntimeError("Error creating results list");
- }
+ int dims[2];
+ dims[1] = 2;
+ PyObject* py_results = PyList_New(results.size());
+ if (!py_results)
+ throw Py::RuntimeError("Error creating results list");
+ try
+ {
+ for (std::vector<Polygon>::const_iterator p = results.begin(); p != results.end(); ++p)
+ {
+ size_t size = p->size();
+ dims[0] = p->size();
+ PyArrayObject* pyarray = (PyArrayObject*)PyArray_FromDims(2, dims, PyArray_DOUBLE);
+ for (size_t i = 0; i < size; ++i)
+ {
+ ((double *)pyarray->data)[2*i]	 = (*p)[i].x;
+ ((double *)pyarray->data)[2*i+1] = (*p)[i].y;
+ }
+ if (PyList_SetItem(py_results, p - results.begin(), (PyObject *)pyarray) != -1)
+ {
+ throw Py::RuntimeError("Error creating results list");
+ }
+ }
 }
- } catch (...) {
- Py_XDECREF(py_results);
- throw;
- }
+ catch (...)
+ {
+ Py_XDECREF(py_results);
+ throw;
+ }
 
- return Py::Object(py_results, true);
+ return Py::Object(py_results, true);
 }
 
-Py::Object _path_module::affine_transform(const Py::Tuple& args) {
- args.verify_length(2);
+Py::Object _path_module::affine_transform(const Py::Tuple& args)
+{
+ args.verify_length(2);
 
- Py::Object vertices_obj = args[0];
- Py::Object transform_obj = args[1];
+ Py::Object vertices_obj = args[0];
+ Py::Object transform_obj = args[1];
 
- PyArrayObject* vertices = NULL;
- PyArrayObject* transform = NULL;
- PyArrayObject* result = NULL;
+ PyArrayObject* vertices = NULL;
+ PyArrayObject* transform = NULL;
+ PyArrayObject* result = NULL;
 
- try {
- vertices = (PyArrayObject*)PyArray_FromObject
- (vertices_obj.ptr(), PyArray_DOUBLE, 1, 2);
- if (!vertices ||
-	(PyArray_NDIM(vertices) == 2 && PyArray_DIM(vertices, 1) != 2) ||
-	(PyArray_NDIM(vertices) == 1 && PyArray_DIM(vertices, 0) != 2))
- throw Py::ValueError("Invalid vertices array.");
+ try
+ {
+ vertices = (PyArrayObject*)PyArray_FromObject
+ (vertices_obj.ptr(), PyArray_DOUBLE, 1, 2);
+ if (!vertices ||
+	 (PyArray_NDIM(vertices) == 2 && PyArray_DIM(vertices, 1) != 2) ||
+	 (PyArray_NDIM(vertices) == 1 && PyArray_DIM(vertices, 0) != 2))
+ throw Py::ValueError("Invalid vertices array.");
 
- transform = (PyArrayObject*) PyArray_FromObject
- (transform_obj.ptr(), PyArray_DOUBLE, 2, 2);
- if (!transform || PyArray_NDIM(transform) != 2 ||
-	PyArray_DIM(transform, 0) != 3 || PyArray_DIM(transform, 1) != 3)
- throw Py::ValueError("Invalid transform.");
+ transform = (PyArrayObject*) PyArray_FromObject
+ (transform_obj.ptr(), PyArray_DOUBLE, 2, 2);
+ if (!transform || PyArray_NDIM(transform) != 2 ||
+	 PyArray_DIM(transform, 0) != 3 || PyArray_DIM(transform, 1) != 3)
+ throw Py::ValueError("Invalid transform.");
 
- double a, b, c, d, e, f;
- {
- size_t stride0 = PyArray_STRIDE(transform, 0);
- size_t stride1 = PyArray_STRIDE(transform, 1);
- char* row0 = PyArray_BYTES(transform);
- char* row1 = row0 + stride0;
+ double a, b, c, d, e, f;
+ {
+ size_t stride0 = PyArray_STRIDE(transform, 0);
+ size_t stride1 = PyArray_STRIDE(transform, 1);
+ char* row0 = PyArray_BYTES(transform);
+ char* row1 = row0 + stride0;
 
- a = *(double*)(row0);
- row0 += stride1;
- c = *(double*)(row0);
- row0 += stride1;
- e = *(double*)(row0);
+ 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);
- }
+ b = *(double*)(row1);
+ row1 += stride1;
+ d = *(double*)(row1);
+ row1 += stride1;
+ f = *(double*)(row1);
+ }
 
- // I would have preferred to use PyArray_FromDims here, but on
- // 64-bit platforms, PyArray_DIMS() does not return the same thing
- // that PyArray_FromDims wants, requiring a copy, which I would
- // like to avoid in this critical section.
- result = (PyArrayObject*)PyArray_SimpleNew
- (PyArray_NDIM(vertices), PyArray_DIMS(vertices), PyArray_DOUBLE);
- if (PyArray_NDIM(vertices) == 2) {
- size_t n = PyArray_DIM(vertices, 0);
- char* vertex_in = PyArray_BYTES(vertices);
- double* vertex_out = (double*)PyArray_DATA(result);
- size_t stride0 = PyArray_STRIDE(vertices, 0);
- size_t stride1 = PyArray_STRIDE(vertices, 1);
- double x;
- double y;
+ // I would have preferred to use PyArray_FromDims here, but on
+ // 64-bit platforms, PyArray_DIMS() does not return the same thing
+ // that PyArray_FromDims wants, requiring a copy, which I would
+ // like to avoid in this critical section.
+ result = (PyArrayObject*)PyArray_SimpleNew
+ (PyArray_NDIM(vertices), PyArray_DIMS(vertices), PyArray_DOUBLE);
+ if (PyArray_NDIM(vertices) == 2)
+ {
+ size_t n = PyArray_DIM(vertices, 0);
+ char* vertex_in = PyArray_BYTES(vertices);
+ double* vertex_out = (double*)PyArray_DATA(result);
+ size_t stride0 = PyArray_STRIDE(vertices, 0);
+ size_t stride1 = PyArray_STRIDE(vertices, 1);
+ double x;
+ double y;
 
- for (size_t i = 0; i < n; ++i) {
-	x = *(double*)(vertex_in);
-	y = *(double*)(vertex_in + stride1);
+ for (size_t i = 0; i < n; ++i)
+ {
+ x = *(double*)(vertex_in);
+ y = *(double*)(vertex_in + stride1);
 
-	*vertex_out++ = a*x + c*y + e;
-	*vertex_out++ = b*x + d*y + f;
+ *vertex_out++ = a*x + c*y + e;
+ *vertex_out++ = b*x + d*y + f;
 
-	vertex_in += stride0;
- }
- } else {
- char* vertex_in = PyArray_BYTES(vertices);
- double* vertex_out = (double*)PyArray_DATA(result);
- size_t stride0 = PyArray_STRIDE(vertices, 0);
- double x;
- double y;
- x = *(double*)(vertex_in);
- y = *(double*)(vertex_in + stride0);
- *vertex_out++ = a*x + c*y + e;
- *vertex_out++ = b*x + d*y + f;
+ vertex_in += stride0;
+ }
+ }
+ else
+ {
+ char* vertex_in = PyArray_BYTES(vertices);
+ double* vertex_out = (double*)PyArray_DATA(result);
+ size_t stride0 = PyArray_STRIDE(vertices, 0);
+ double x;
+ double y;
+ x = *(double*)(vertex_in);
+ y = *(double*)(vertex_in + stride0);
+ *vertex_out++ = a*x + c*y + e;
+ *vertex_out++ = b*x + d*y + f;
+ }
 }
- } catch (...) {
+ catch (...)
+ {
+ Py_XDECREF(vertices);
+ Py_XDECREF(transform);
+ Py_XDECREF(result);
+ }
+
 Py_XDECREF(vertices);
 Py_XDECREF(transform);
- Py_XDECREF(result);
- }
 
- Py_XDECREF(vertices);
- Py_XDECREF(transform);
-
- return Py::Object((PyObject*)result, true);
+ return Py::Object((PyObject*)result, true);
 }
 
-Py::Object _path_module::count_bboxes_overlapping_bbox(const Py::Tuple& args) {
- args.verify_length(2);
+Py::Object _path_module::count_bboxes_overlapping_bbox(const Py::Tuple& args)
+{
+ args.verify_length(2);
 
- Py::Object		 bbox	 = args[0];
- Py::SeqBase<Py::Object> bboxes = args[1];
+ Py::Object		 bbox	 = args[0];
+ Py::SeqBase<Py::Object> bboxes = args[1];
 
- double ax0, ay0, ax1, ay1;
- double bx0, by0, bx1, by1;
- long count = 0;
+ double ax0, ay0, ax1, ay1;
+ double bx0, by0, bx1, by1;
+ long count = 0;
 
- if (py_convert_bbox(bbox.ptr(), ax0, ay0, ax1, ay1)) {
- if (ax1 < ax0)
- std::swap(ax0, ax1);
- if (ay1 < ay0)
- std::swap(ay0, ay1);
+ if (py_convert_bbox(bbox.ptr(), ax0, ay0, ax1, ay1))
+ {
+ if (ax1 < ax0)
+ std::swap(ax0, ax1);
+ if (ay1 < ay0)
+ std::swap(ay0, ay1);
 
- size_t num_bboxes = bboxes.size();
- for (size_t i = 0; i < num_bboxes; ++i) {
- Py::Object bbox_b = bboxes[i];
- if (py_convert_bbox(bbox_b.ptr(), bx0, by0, bx1, by1)) {
-	if (bx1 < bx0)
-	 std::swap(bx0, bx1);
-	if (by1 < by0)
-	 std::swap(by0, by1);
-	if (not ((bx1 <= ax0) or
-		 (by1 <= ay0) or
-		 (bx0 >= ax1) or
-		 (by0 >= ay1)))
-	 ++count;
- } else {
-	throw Py::ValueError("Non-bbox object in bboxes list");
- }
+ size_t num_bboxes = bboxes.size();
+ for (size_t i = 0; i < num_bboxes; ++i)
+ {
+ Py::Object bbox_b = bboxes[i];
+ if (py_convert_bbox(bbox_b.ptr(), bx0, by0, bx1, by1))
+ {
+ if (bx1 < bx0)
+ std::swap(bx0, bx1);
+ if (by1 < by0)
+ std::swap(by0, by1);
+ if (not ((bx1 <= ax0) or
+ (by1 <= ay0) or
+ (bx0 >= ax1) or
+ (by0 >= ay1)))
+ ++count;
+ }
+ else
+ {
+ throw Py::ValueError("Non-bbox object in bboxes list");
+ }
+ }
 }
- } else {
- throw Py::ValueError("First argument to count_bboxes_overlapping_bbox must be a Bbox object.");
- }
+ else
+ {
+ throw Py::ValueError("First argument to count_bboxes_overlapping_bbox must be a Bbox object.");
+ }
 
- return Py::Int(count);
+ return Py::Int(count);
 }
 
 bool segments_intersect(const double& x1, const double &y1,
-			const double& x2, const double &y2,
-			const double& x3, const double &y3,
-			const double& x4, const double &y4) {
- double den = ((y4-y3) * (x2-x1)) - ((x4-x3)*(y2-y1));
- if (den == 0.0)
- return false;
+ const double& x2, const double &y2,
+ const double& x3, const double &y3,
+ const double& x4, const double &y4)
+{
+ double den = ((y4-y3) * (x2-x1)) - ((x4-x3)*(y2-y1));
+ if (den == 0.0)
+ return false;
 
- double n1 = ((x4-x3) * (y1-y3)) - ((y4-y3)*(x1-x3));
- double n2 = ((x2-x1) * (y1-y3)) - ((y2-y1)*(x1-x3));
+ double n1 = ((x4-x3) * (y1-y3)) - ((y4-y3)*(x1-x3));
+ double n2 = ((x2-x1) * (y1-y3)) - ((y2-y1)*(x1-x3));
 
- double u1 = n1/den;
- double u2 = n2/den;
+ double u1 = n1/den;
+ double u2 = n2/den;
 
- return (u1 >= 0.0 && u1 <= 1.0 &&
-	 u2 >= 0.0 && u2 <= 1.0);
+ return (u1 >= 0.0 && u1 <= 1.0 &&
+ u2 >= 0.0 && u2 <= 1.0);
 }
 
-bool path_intersects_path(PathIterator& p1, PathIterator& p2) {
- typedef agg::conv_curve<PathIterator> curve_t;
+bool path_intersects_path(PathIterator& p1, PathIterator& p2)
+{
+ typedef agg::conv_curve<PathIterator> curve_t;
 
- if (p1.total_vertices() < 2 || p2.total_vertices() < 2)
- return false;
+ if (p1.total_vertices() < 2 || p2.total_vertices() < 2)
+ return false;
 
- curve_t c1(p1);
- curve_t c2(p2);
+ curve_t c1(p1);
+ curve_t c2(p2);
 
- double x11, y11, x12, y12;
- double x21, y21, x22, y22;
+ double x11, y11, x12, y12;
+ double x21, y21, x22, y22;
 
- c1.vertex(&x11, &y11);
- while (c1.vertex(&x12, &y12) != agg::path_cmd_stop) {
- c2.rewind(0);
- c2.vertex(&x21, &y21);
- while (c2.vertex(&x22, &y22) != agg::path_cmd_stop) {
- if (segments_intersect(x11, y11, x12, y12, x21, y21, x22, y22))
-	return true;
- x21 = x22; y21 = y22;
+ c1.vertex(&x11, &y11);
+ while (c1.vertex(&x12, &y12) != agg::path_cmd_stop)
+ {
+ c2.rewind(0);
+ c2.vertex(&x21, &y21);
+ while (c2.vertex(&x22, &y22) != agg::path_cmd_stop)
+ {
+ if (segments_intersect(x11, y11, x12, y12, x21, y21, x22, y22))
+ return true;
+ x21 = x22;
+ y21 = y22;
+ }
+ x11 = x12;
+ y11 = y12;
 }
- x11 = x12; y11 = y12;
- }
 
- return false;
+ return false;
 }
 
-Py::Object _path_module::path_intersects_path(const Py::Tuple& args) {
- args.verify_length(2);
+Py::Object _path_module::path_intersects_path(const Py::Tuple& args)
+{
+ args.verify_length(2);
 
- PathIterator p1(args[0]);
- PathIterator p2(args[1]);
+ PathIterator p1(args[0]);
+ PathIterator p2(args[1]);
 
- bool intersects = ::path_intersects_path(p1, p2);
- if (!intersects) {
- intersects = ::path_in_path(p1, agg::trans_affine(), p2, agg::trans_affine());
- if (!intersects) {
- intersects = ::path_in_path(p2, agg::trans_affine(), p1, agg::trans_affine());
- if (!intersects) {
-	return Py::Int(0);
- }
+ bool intersects = ::path_intersects_path(p1, p2);
+ if (!intersects)
+ {
+ intersects = ::path_in_path(p1, agg::trans_affine(), p2, agg::trans_affine());
+ if (!intersects)
+ {
+ intersects = ::path_in_path(p2, agg::trans_affine(), p1, agg::trans_affine());
+ if (!intersects)
+ {
+ return Py::Int(0);
+ }
+ }
 }
- }
- return Py::Int(1);
+ return Py::Int(1);
 }
 
 extern "C"
-DL_EXPORT(void)
- init_path(void)
+ DL_EXPORT(void)
+ init_path(void)
 {
- import_array();
+ import_array();
 
- static _path_module* _path = NULL;
- _path = new _path_module;
+ static _path_module* _path = NULL;
+ _path = new _path_module;
 };
Modified: branches/transforms/src/agg_py_path_iterator.h
===========...
 
[truncated message content]
From: <md...@us...> - 2007年12月18日 13:08:27
Revision: 4763
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4763&view=rev
Author: mdboom
Date: 2007年12月18日 05:08:04 -0800 (2007年12月18日)
Log Message:
-----------
Don't allocate the clipping path buffers unless we need them.
Modified Paths:
--------------
 branches/transforms/src/_backend_agg.cpp
 branches/transforms/src/_backend_agg.h
Modified: branches/transforms/src/_backend_agg.cpp
===================================================================
--- branches/transforms/src/_backend_agg.cpp	2007年12月18日 13:02:33 UTC (rev 4762)
+++ branches/transforms/src/_backend_agg.cpp	2007年12月18日 13:08:04 UTC (rev 4763)
@@ -239,27 +239,22 @@
 height(height),
 dpi(dpi),
 NUMBYTES(width*height*4),
+ alphaBuffer(NULL),
+ alphaMaskRenderingBuffer(NULL),
+ alphaMask(NULL),
+ pixfmtAlphaMask(NULL),
+ rendererBaseAlphaMask(NULL),
+ rendererAlphaMask(NULL),
+ scanlineAlphaMask(NULL),
 debug(debug)
 {
 _VERBOSE("RendererAgg::RendererAgg");
 unsigned stride(width*4);
 
-
 pixBuffer	 = new agg::int8u[NUMBYTES];
 renderingBuffer = new agg::rendering_buffer;
 renderingBuffer->attach(pixBuffer, width, height, stride);
 
- alphaBuffer		 = new agg::int8u[NUMBYTES];
- alphaMaskRenderingBuffer = new agg::rendering_buffer;
- alphaMaskRenderingBuffer->attach(alphaBuffer, width, height, stride);
- alphaMask		 = new alpha_mask_type(*alphaMaskRenderingBuffer);
-
- pixfmtAlphaMask	 = new agg::pixfmt_gray8(*alphaMaskRenderingBuffer);
- rendererBaseAlphaMask	 = new renderer_base_alpha_mask_type(*pixfmtAlphaMask);
- rendererAlphaMask	 = new renderer_alpha_mask_type(*rendererBaseAlphaMask);
- scanlineAlphaMask	 = new agg::scanline_p8();
-
-
 slineP8 = new scanline_p8;
 slineBin = new scanline_bin;
 
@@ -275,6 +270,21 @@
 
 };
 
+void RendererAgg::create_alpha_buffers() {
+ if (!alphaBuffer) {
+ unsigned stride(width*4);
+ alphaBuffer		 = new agg::int8u[NUMBYTES];
+ alphaMaskRenderingBuffer = new agg::rendering_buffer;
+ alphaMaskRenderingBuffer->attach(alphaBuffer, width, height, stride);
+ alphaMask		 = new alpha_mask_type(*alphaMaskRenderingBuffer);
+
+ pixfmtAlphaMask	 = new agg::pixfmt_gray8(*alphaMaskRenderingBuffer);
+ rendererBaseAlphaMask	 = new renderer_base_alpha_mask_type(*pixfmtAlphaMask);
+ rendererAlphaMask	 = new renderer_alpha_mask_type(*rendererBaseAlphaMask);
+ scanlineAlphaMask	 = new agg::scanline_p8();
+ }
+}
+
 template<class R>
 void
 RendererAgg::set_clipbox(const Py::Object& cliprect, R rasterizer) {
@@ -442,6 +452,7 @@
 if (has_clippath &&
 (clippath.ptr() != lastclippath.ptr() ||
 clippath_trans != lastclippath_transform)) {
+ create_alpha_buffers();
 agg::trans_affine trans(clippath_trans);
 trans *= agg::trans_affine_scaling(1.0, -1.0);
 trans *= agg::trans_affine_translation(0.0, (double)height);
@@ -617,7 +628,7 @@
 _color(color) {
 }
 
- void generate(color_type* output_span, int x, int y, unsigned len)
+ inline void generate(color_type* output_span, int x, int y, unsigned len)
 {
 _allocator.allocate(len);
 child_color_type* input_span = _allocator.span();
Modified: branches/transforms/src/_backend_agg.h
===================================================================
--- branches/transforms/src/_backend_agg.h	2007年12月18日 13:02:33 UTC (rev 4762)
+++ branches/transforms/src/_backend_agg.h	2007年12月18日 13:08:04 UTC (rev 4763)
@@ -77,7 +77,7 @@
 SafeSnap() : first(true), xsnap(0.0), lastx(0.0), lastxsnap(0.0),
 	 ysnap(0.0), lasty(0.0), lastysnap(0.0) {}
 SnapData snap (const float& x, const float& y);
- 
+
 private:
 bool first;
 float xsnap, lastx, lastxsnap, ysnap, lasty, lastysnap;
@@ -87,7 +87,7 @@
 // a class in the swig wrapper
 class BufferRegion : public Py::PythonExtension<BufferRegion> {
 public:
- BufferRegion(const agg::rect_i &r, bool freemem=true) : 
+ BufferRegion(const agg::rect_i &r, bool freemem=true) :
 rect(r), freemem(freemem) {
 width = r.x2 - r.x1;
 height = r.y2 - r.y1;
@@ -99,7 +99,7 @@
 int width;
 int height;
 int stride;
- 
+
 bool freemem;
 
 Py::Object to_string(const Py::Tuple &args);
@@ -151,7 +151,7 @@
 
 
 //struct AMRenderer {
-// 
+//
 //}
 
 // the renderer
@@ -246,6 +246,7 @@
 const Py::SeqBase<Py::Int>& antialiaseds);
 
 private:
+ void create_alpha_buffers();
 Py::Object lastclippath;
 agg::trans_affine lastclippath_transform;
 };
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.
Thanks for helping keep SourceForge clean.
X





Briefly describe the problem (required):
Upload screenshot of ad (required):
Select a file, or drag & drop file here.
Screenshot instructions:

Click URL instructions:
Right-click on the ad, choose "Copy Link", then paste here →
(This may not be possible with some types of ads)

More information about our ad policies

Ad destination/click URL:

AltStyle によって変換されたページ (->オリジナル) /