Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Log annotate bug #403

Merged
merged 2 commits into from Jul 25, 2011
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/matplotlib/axes.py
Expand Up @@ -3001,7 +3001,7 @@ def contains_point(self, point):
required.

"""
return self.patch.contains_point(point)
return self.patch.contains_point(point, radius=1.0)

def pick(self, *args):
"""
Expand Down
19 changes: 9 additions & 10 deletions lib/matplotlib/backends/backend_svg.py
Expand Up @@ -447,7 +447,7 @@ def _write_svgfonts(self):
glyph = font.load_char(char, flags=LOAD_NO_HINTING)
verts, codes = font.get_path()
path = Path(verts, codes)
path_data = self._convert_path(path, None)
path_data = self._convert_path(path)
# name = font.get_glyph_name(char)
writer.element(
'glyph',
Expand Down Expand Up @@ -479,7 +479,7 @@ def option_image_nocomposite(self):
"""
return rcParams['svg.image_noscale']

def _convert_path(self, path, transform, clip=None, simplify=None):
def _convert_path(self, path, transform=None, clip=None, simplify=None):
if clip:
clip = (0.0, 0.0, self.width, self.height)
else:
Expand Down Expand Up @@ -798,24 +798,23 @@ def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath):
y -= ((font.get_descent() / 64.0) *
(prop.get_size_in_points() / text2path.FONT_SCALE))

_flip = Affine2D().scale(1.0, -1.0)

if glyph_map_new:
writer.start('defs')
for char_id, glyph_path in glyph_map_new.iteritems():
path = Path(*glyph_path)
path_data = self._convert_path(path, _flip, simplify=False)
path_data = self._convert_path(path, simplify=False)
writer.element('path', id=char_id, d=path_data)
writer.end('defs')

glyph_map.update(glyph_map_new)

attrib = {}
attrib['style'] = generate_css(style)
font_scale = fontsize / text2path.FONT_SCALE
attrib['transform'] = generate_transform([
('translate', (x, y)),
('rotate', (-angle,)),
('scale', (fontsize / text2path.FONT_SCALE,))])
('scale', (font_scale, -font_scale))])

writer.start('g', attrib=attrib)
for glyph_id, xposition, yposition, scale in glyph_info:
Expand Down Expand Up @@ -851,19 +850,19 @@ def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath):
path_data = ""
else:
path = Path(*glyph_path)
path_data = self._convert_path(path, None, simplify=False)
path_data = self._convert_path(path, simplify=False)
writer.element('path', id=char_id, d=path_data)
writer.end('defs')

glyph_map.update(glyph_map_new)

attrib = {}
font_scale = fontsize / text2path.FONT_SCALE
attrib['style'] = generate_css(style)
attrib['transform'] = generate_transform([
('translate', (x, y)),
('rotate', (-angle,)),
('scale', (fontsize / text2path.FONT_SCALE,
-fontsize / text2path.FONT_SCALE))])
('scale', (font_scale, - font_scale))])

writer.start('g', attrib=attrib)
for char_id, xposition, yposition, scale in glyph_info:
Expand All @@ -879,7 +878,7 @@ def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath):

for verts, codes in rects:
path = Path(verts, codes)
path_data = self._convert_path(path, None, simplify=False)
path_data = self._convert_path(path, simplify=False)
writer.element('path', d=path_data)

writer.end('g')
Expand Down
14 changes: 8 additions & 6 deletions lib/matplotlib/patches.py
Expand Up @@ -112,7 +112,7 @@ def get_verts(self):
return polygons[0]
return []

def contains(self, mouseevent):
def contains(self, mouseevent, radius=None):
"""Test whether the mouse event occurred in the patch.

Returns T/F, {}
Expand All @@ -122,18 +122,20 @@ def contains(self, mouseevent):
# algebraic solution to hit-testing should override this
# method.
if callable(self._contains): return self._contains(self,mouseevent)

if radius is None:
radius = self.get_linewidth()
inside = self.get_path().contains_point(
(mouseevent.x, mouseevent.y), self.get_transform())
(mouseevent.x, mouseevent.y), self.get_transform(), radius)
return inside, {}

def contains_point(self, point):
def contains_point(self, point, radius=None):
"""
Returns *True* if the given point is inside the path
(transformed with its transform attribute).
"""
return self.get_path().contains_point(point,
self.get_transform())
if radius is None:
radius = self.get_linewidth()
return self.get_path().contains_point(point, self.get_transform(), radius)

def update_from(self, other):
"""
Expand Down
5 changes: 3 additions & 2 deletions lib/matplotlib/path.py
Expand Up @@ -265,7 +265,7 @@ def transformed(self, transform):
return Path(transform.transform(self.vertices), self.codes,
self._interpolation_steps)

def contains_point(self, point, transform=None):
def contains_point(self, point, transform=None, radius=0.0):
"""
Returns *True* if the path contains the given point.

Expand All @@ -274,7 +274,8 @@ def contains_point(self, point, transform=None):
"""
if transform is not None:
transform = transform.frozen()
return point_in_path(point[0], point[1], self, transform)
result = point_in_path(point[0], point[1], radius, self, transform)
return result

def contains_path(self, path, transform=None):
"""
Expand Down
1 change: 1 addition & 0 deletions setupext.py
Expand Up @@ -1192,6 +1192,7 @@ def build_path(ext_modules, packages):
if BUILT_PATH: return # only build it if you you haven't already

agg = (
'agg_vcgen_contour.cpp',
'agg_curves.cpp',
'agg_bezier_arc.cpp',
'agg_trans_affine.cpp',
Expand Down
21 changes: 13 additions & 8 deletions src/_path.cpp
Expand Up @@ -9,6 +9,7 @@

#include "CXX/Extensions.hxx"

#include "agg_conv_contour.h"
#include "agg_conv_curve.h"
#include "agg_conv_stroke.h"
#include "agg_conv_transform.h"
Expand Down Expand Up @@ -225,12 +226,13 @@ point_in_path_impl(const double tx, const double ty, T& path)
}

inline bool
point_in_path(double x, double y, PathIterator& path,
point_in_path(double x, double y, double r, PathIterator& path,
const agg::trans_affine& trans)
{
typedef agg::conv_transform<PathIterator> transformed_path_t;
typedef PathNanRemover<transformed_path_t> no_nans_t;
typedef agg::conv_curve<no_nans_t> curve_t;
typedef agg::conv_contour<curve_t> contour_t;

if (path.total_vertices() < 3)
{
Expand All @@ -240,7 +242,9 @@ point_in_path(double x, double y, PathIterator& path,
transformed_path_t trans_path(path, trans);
no_nans_t no_nans_path(trans_path, true, path.has_curves());
curve_t curved_path(no_nans_path);
return point_in_path_impl(x, y, curved_path);
contour_t contoured_path(curved_path);
contoured_path.width(fabs(r));
return point_in_path_impl(x, y, contoured_path);
}

inline bool
Expand All @@ -263,14 +267,15 @@ point_on_path(double x, double y, double r, PathIterator& path,
Py::Object
_path_module::point_in_path(const Py::Tuple& args)
{
args.verify_length(4);
args.verify_length(5);

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].ptr(), false);
double r = Py::Float(args[2]);
PathIterator path(args[3]);
agg::trans_affine trans = py_to_agg_transformation_matrix(args[4].ptr(), false);

if (::point_in_path(x, y, path, trans))
if (::point_in_path(x, y, r, path, trans))
{
return Py::Int(1);
}
Expand Down Expand Up @@ -664,7 +669,7 @@ _path_module::point_in_path_collection(const Py::Tuple& args)

if (filled)
{
if (::point_in_path(x, y, path, trans))
if (::point_in_path(x, y, radius, path, trans))
result.append(Py::Int((int)i));
}
else
Expand Down Expand Up @@ -696,7 +701,7 @@ path_in_path(PathIterator& a, const agg::trans_affine& atrans,
b_curved.rewind(0);
while (b_curved.vertex(&x, &y) != agg::path_cmd_stop)
{
if (!::point_in_path(x, y, a, atrans))
if (!::point_in_path(x, y, 0.0, a, atrans))
return false;
}

Expand Down