Skip to content
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
9 changes: 7 additions & 2 deletions lib/matplotlib/backends/backend_macosx.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ def draw_gouraud_triangle(self, gc, points, colors, transform):
points = transform.transform(points)
gc.draw_gouraud_triangle(points, colors)

def get_image_magnification(self):
return self.gc.get_image_magnification()

def draw_image(self, gc, x, y, im):
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Unfortunately, CoreGraphics bitmaps don't really have a sense of scale about them, so far as I can tell. It would be cleaner to tell gc.draw_image what the scale factor was directly, but that would change the backend interface. Maybe an auxiliary setter?

im.flipud_out()
nrows, ncols, data = im.as_rgba_str()
Expand All @@ -115,19 +118,21 @@ def draw_image(self, gc, x, y, im):

def draw_tex(self, gc, x, y, s, prop, angle, ismath='TeX!', mtext=None):
# todo, handle props, angle, origins
scale = self.gc.get_image_magnification()
size = prop.get_size_in_points()
texmanager = self.get_texmanager()
key = s, size, self.dpi, angle, texmanager.get_font_config()
im = self.texd.get(key) # Not sure what this does; just copied from backend_agg.py
if im is None:
Z = texmanager.get_grey(s, size, self.dpi)
Z = texmanager.get_grey(s, size, self.dpi*scale)
Z = numpy.array(255.0 - Z * 255.0, numpy.uint8)

gc.draw_mathtext(x, y, angle, Z)

def _draw_mathtext(self, gc, x, y, s, prop, angle):
scale = self.gc.get_image_magnification()
ox, oy, width, height, descent, image, used_characters = \
self.mathtext_parser.parse(s, self.dpi, prop)
self.mathtext_parser.parse(s, self.dpi*scale, prop)
gc.draw_mathtext(x, y, angle, 255 - image.as_array())

def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
Expand Down
37 changes: 34 additions & 3 deletions src/_macosx.m
Original file line number Diff line number Diff line change
Expand Up @@ -2996,6 +2996,18 @@ static void _data_provider_release(void* info, const void* data, size_t size)
Py_DECREF(image);
}

/* Consider the drawing origin to be in user coordinates
* but the image size to be in device coordinates */
static void draw_image_user_coords_device_size(CGContextRef cr, CGImageRef im,
float x, float y, npy_intp ncols, npy_intp nrows)
{
CGRect dst;
dst.origin = CGPointMake(x,y);
dst.size = CGContextConvertSizeToUserSpace(cr, CGSizeMake(ncols,nrows));
dst.size.height = fabs(dst.size.height); /* believe it or not... */
CGContextDrawImage(cr, dst, im);
}

static PyObject*
GraphicsContext_draw_mathtext(GraphicsContext* self, PyObject* args)
{
Expand Down Expand Up @@ -3078,14 +3090,14 @@ static void _data_provider_release(void* info, const void* data, size_t size)

if (angle==0.0)
{
CGContextDrawImage(cr, CGRectMake(x,y,ncols,nrows), bitmap);
draw_image_user_coords_device_size(cr, bitmap, x, y, ncols, nrows);
}
else
{
CGContextSaveGState(cr);
CGContextTranslateCTM(cr, x, y);
CGContextRotateCTM(cr, angle*M_PI/180);
CGContextDrawImage(cr, CGRectMake(0,0,ncols,nrows), bitmap);
draw_image_user_coords_device_size(cr, bitmap, 0, 0, ncols, nrows);
CGContextRestoreGState(cr);
}
CGImageRelease(bitmap);
Expand Down Expand Up @@ -3175,13 +3187,27 @@ static void _data_provider_release(void* info, const void* data, size_t size)
return NULL;
}

CGContextDrawImage(cr, CGRectMake(x,y,ncols,nrows), bitmap);
draw_image_user_coords_device_size(cr, bitmap, x, y, ncols, nrows);
CGImageRelease(bitmap);

Py_INCREF(Py_None);
return Py_None;
}

static PyObject*
GraphicsContext_get_image_magnification(GraphicsContext* self)
{
CGContextRef cr = self->cr;
if (!cr)
{
PyErr_SetString(PyExc_RuntimeError, "CGContextRef is NULL");
return NULL;
}

CGSize pixelSize = CGContextConvertSizeToDeviceSpace(cr, CGSizeMake(1,1));
return PyFloat_FromDouble(pixelSize.width);
}


static PyMethodDef GraphicsContext_methods[] = {
{"save",
Expand Down Expand Up @@ -3294,6 +3320,11 @@ static void _data_provider_release(void* info, const void* data, size_t size)
METH_VARARGS,
"Draw an image at (x,y) in the graphics context."
},
{"get_image_magnification",
(PyCFunction)GraphicsContext_get_image_magnification,
METH_NOARGS,
"Returns the scale factor between user and device coordinates."
},
{NULL} /* Sentinel */
};

Expand Down