Skip to content

Fix mathtext image bounding box #4148

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

Merged
merged 4 commits into from
Feb 25, 2015
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/matplotlib/mathtext.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ def _update_bbox(self, x1, y1, x2, y2):
def set_canvas_size(self, w, h, d):
MathtextBackend.set_canvas_size(self, w, h, d)
if self.mode != 'bbox':
self.image = FT2Image(ceil(w), ceil(h + d))
self.image = FT2Image(ceil(w), ceil(h + max(d, 0)))

def render_glyph(self, ox, oy, info):
if self.mode == 'bbox':
Expand Down
20 changes: 19 additions & 1 deletion lib/matplotlib/tests/test_mathtext.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@

import six

import io

import numpy as np
import matplotlib
from matplotlib.testing.decorators import image_comparison, knownfailureif
from matplotlib.testing.decorators import image_comparison, knownfailureif, cleanup
import matplotlib.pyplot as plt
from matplotlib import mathtext

Expand Down Expand Up @@ -210,6 +212,22 @@ def test_mathtext_exceptions():
else:
assert False, "Expected '%s', but didn't get it" % msg

@cleanup
def test_single_minus_sign():
plt.figure(figsize=(0.3, 0.3))
plt.text(0.5, 0.5, '$-$')
for spine in plt.gca().spines.values():
spine.set_visible(False)
plt.gca().set_xticks([])
plt.gca().set_yticks([])

buff = io.BytesIO()
plt.savefig(buff, format="rgba", dpi=1000)
array = np.fromstring(buff.getvalue(), dtype=np.uint8)

# If this fails, it would be all white
assert not np.all(array == 0xff)


if __name__ == '__main__':
import nose
Expand Down
12 changes: 6 additions & 6 deletions src/ft2font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ FT2Image::~FT2Image()

void FT2Image::resize(long width, long height)
{
if (width < 0) {
if (width <= 0) {
width = 1;
}
if (height < 0) {
if (height <= 0) {
height = 1;
}
size_t numBytes = width * height;
Expand Down Expand Up @@ -146,11 +146,11 @@ FT2Image::draw_rect_filled(unsigned long x0, unsigned long y0, unsigned long x1,
{
x0 = std::min(x0, m_width);
y0 = std::min(y0, m_height);
x1 = std::min(x1, m_width);
y1 = std::min(y1, m_height);
x1 = std::min(x1 + 1, m_width);
y1 = std::min(y1 + 1, m_height);

for (size_t j = y0; j < y1 + 1; j++) {
for (size_t i = x0; i < x1 + 1; i++) {
for (size_t j = y0; j < y1; j++) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes the limits in the case where m_width is the minimum, is that intentional?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. x0 and x1 represent an inclusive range here, i.e. to fill, say, a one pixel line at pixel 5, x0 == 5, and x1 == 5. (One could argue that's not the best interface, but it's what we have). The problem is that occasionally, the line requested goes outside of the edge of the image, and we need to protect against that at all costs (because that would be a buffer overflow). This wasn't an issue in practice until the bounds of the image was corrected to something more accurate in mathtext.py.

for (size_t i = x0; i < x1; i++) {
m_buffer[i + j * m_width] = 255;
}
}
Expand Down