diff --git a/lib/matplotlib/tests/baseline_images/test_text/text_contains.png b/lib/matplotlib/tests/baseline_images/test_text/text_contains.png new file mode 100644 index 000000000000..4adb105d849a Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_text/text_contains.png differ diff --git a/lib/matplotlib/tests/test_text.py b/lib/matplotlib/tests/test_text.py index 5d144e1d59d7..7a3cec0c0d40 100644 --- a/lib/matplotlib/tests/test_text.py +++ b/lib/matplotlib/tests/test_text.py @@ -18,7 +18,10 @@ def find_matplotlib_font(**kw): return FontProperties(fname=path) from matplotlib.font_manager import FontProperties, findfont - warnings.filterwarnings('ignore','findfont: Font family \[\'Foo\'\] not found. Falling back to .',UserWarning,module='matplotlib.font_manager') + warnings.filterwarnings('ignore','findfont: Font family \[\'Foo\'\] '+ \ + 'not found. Falling back to .', + UserWarning, + module='matplotlib.font_manager') fig = plt.figure() ax = plt.subplot( 1, 1, 1 ) @@ -89,8 +92,10 @@ def test_antialiasing(): matplotlib.rcParams['text.antialiased'] = True fig = plt.figure(figsize=(5.25, 0.75)) - fig.text(0.5, 0.75, "antialiased", horizontalalignment='center', verticalalignment='center') - fig.text(0.5, 0.25, "$\sqrt{x}$", horizontalalignment='center', verticalalignment='center') + fig.text(0.5, 0.75, "antialiased", horizontalalignment='center', + verticalalignment='center') + fig.text(0.5, 0.25, "$\sqrt{x}$", horizontalalignment='center', + verticalalignment='center') # NOTE: We don't need to restore the rcParams here, because the # test cleanup will do it for us. In fact, if we do it here, it # will turn antialiasing back off before the images are actually @@ -105,3 +110,40 @@ def test_afm_kerning(): with open(fn, 'rb') as fh: afm = AFM(fh) assert afm.string_width_height('VAVAVAVAVAVA') == (7174.0, 718) + + +@image_comparison(baseline_images=['text_contains'], extensions=['png']) +def test_contains(): + import matplotlib.backend_bases as mbackend + + fig = plt.figure() + ax = plt.axes() + + mevent = mbackend.MouseEvent('button_press_event', fig.canvas, 0.5, + 0.5, 1, None) + + xs = np.linspace(0.25, 0.75, 30) + ys = np.linspace(0.25, 0.75, 30) + xs, ys = np.meshgrid(xs, ys) + + txt = plt.text(0.48, 0.52, 'hello world', ha='center', fontsize=30, + rotation=30) + # uncomment to draw the text's bounding box + # txt.set_bbox(dict(edgecolor='black', facecolor='none')) + + # draw the text. This is important, as the contains method can only work + # when a renderer exists. + plt.draw() + + for x, y in zip(xs.flat, ys.flat): + mevent.x, mevent.y = plt.gca().transAxes.transform_point([x, y]) + + contains, _ = txt.contains(mevent) + + color = 'yellow' if contains else 'red' + + # capture the viewLim, plot a point, and reset the viewLim + vl = ax.viewLim.frozen() + ax.plot(x, y, 'o', color=color) + ax.viewLim.set(vl) + diff --git a/lib/matplotlib/text.py b/lib/matplotlib/text.py index ec325d21052c..f54b35a5ba36 100644 --- a/lib/matplotlib/text.py +++ b/lib/matplotlib/text.py @@ -207,11 +207,10 @@ def contains(self,mouseevent): return False,{} l,b,w,h = self.get_window_extent().bounds - - r = l+w - t = b+h + r, t = l+w, b+h + x, y = mouseevent.x, mouseevent.y - inside = (x >= l and x <= r and y >= t and y <= b) + inside = (l <= x <= r and b <= y <= t) return inside, {} def _get_xy_display(self): @@ -361,7 +360,8 @@ def get_text_width_height_descent(*kl, **kwargs): width = xmax - xmin height = ymax - ymin - # Now move the box to the targe position offset the display bbox by alignment + # Now move the box to the target position offset the display + # bbox by alignment halign = self._horizontalalignment valign = self._verticalalignment @@ -1805,17 +1805,14 @@ def __init__(self, s, xy, else: self.arrow_patch = None - def contains(self,event): - t,tinfo = Text.contains(self,event) + contains, tinfo = Text.contains(self,event) if self.arrow is not None: - a,ainfo=self.arrow.contains(event) - t = t or a - + in_arrow, _ = self.arrow.contains(event) + contains = contains or in_arrow # self.arrow_patch is currently not checked as this can be a line - JJ - return t,tinfo - + return contains, tinfo def set_figure(self, fig):