Revision: 7112
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7112&view=rev
Author: jdh2358
Date: 2009-05-17 15:08:07 +0000 (Sun, 17 May 2009)
Log Message:
-----------
applied Michiel's sf patch 2792742 to speed up Cairo and macosx collections
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/lib/matplotlib/backend_bases.py
trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py
trunk/matplotlib/lib/matplotlib/backends/backend_gtkcairo.py
trunk/matplotlib/lib/matplotlib/backends/backend_macosx.py
trunk/matplotlib/lib/matplotlib/lines.py
trunk/matplotlib/lib/matplotlib/patches.py
trunk/matplotlib/lib/matplotlib/text.py
trunk/matplotlib/lib/mpl_toolkits/axes_grid/axislines.py
trunk/matplotlib/src/_macosx.m
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2009-05-17 14:54:57 UTC (rev 7111)
+++ trunk/matplotlib/CHANGELOG 2009-05-17 15:08:07 UTC (rev 7112)
@@ -1,4 +1,8 @@
+2009-05-19 applied Michiel's sf patch 2792742 to speed up Cairo and
+ macosx collections; speedups can be 20x
+
======================================================================
+
2008-05-17 Release 0.98.5.3 at r7107 from the branch - JDH
2009-05-13 An optional offset and bbox support in restore_bbox.
Modified: trunk/matplotlib/lib/matplotlib/backend_bases.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backend_bases.py 2009-05-17 14:54:57 UTC
(rev 7111)
+++ trunk/matplotlib/lib/matplotlib/backend_bases.py 2009-05-17 15:08:07 UTC
(rev 7112)
@@ -277,6 +277,7 @@
gc.set_url(urls[i % Nurls])
yield xo, yo, path_id, gc, rgbFace
+ gc.restore()
def get_image_magnification(self):
"""
@@ -459,6 +460,13 @@
self._url = gc._url
self._snap = gc._snap
+ def restore(self):
+ """
+ Restore the graphics context from the stack - needed only
+ for backends that save graphics contexts on a stack
+ """
+ pass
+
def get_alpha(self):
"""
Return the alpha value used for blending - not supported on
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py 2009-05-17
14:54:57 UTC (rev 7111)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py 2009-05-17
15:08:07 UTC (rev 7112)
@@ -91,13 +91,13 @@
"""
if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name())
self.dpi = dpi
+ self.gc = GraphicsContextCairo (renderer=self)
self.text_ctx = cairo.Context (
cairo.ImageSurface (cairo.FORMAT_ARGB32,1,1))
self.mathtext_parser = MathTextParser('Cairo')
def set_ctx_from_surface (self, surface):
- self.ctx = cairo.Context (surface)
- self.ctx.save() # restore, save - when call new_gc()
+ self.gc.ctx = cairo.Context (surface)
def set_width_height(self, width, height):
@@ -109,22 +109,6 @@
# font transform?
- def _do_clip(self, ctx, cliprect, clippath):
- if cliprect is not None:
- x,y,w,h = cliprect.bounds
- # pixel-aligned clip-regions are faster
- x,y,w,h = round(x), round(y), round(w), round(h)
- ctx.new_path()
- ctx.rectangle (x, self.height - h - y, w, h)
- ctx.clip ()
-
- if clippath is not None:
- tpath, affine = clippath.get_transformed_path_and_affine()
- ctx.new_path()
- affine = affine + Affine2D().scale(1.0, -1.0).translate(0.0,
self.height)
- RendererCairo.convert_path(ctx, tpath, affine)
- ctx.clip()
-
def _fill_and_stroke (self, ctx, fill_c, alpha):
if fill_c is not None:
ctx.save()
@@ -158,8 +142,6 @@
raise ValueError("The Cairo backend can not draw paths longer than
18980 points.")
ctx = gc.ctx
- ctx.save()
- self._do_clip(ctx, gc._cliprect, gc._clippath)
transform = transform + \
Affine2D().scale(1.0, -1.0).translate(0, self.height)
@@ -168,7 +150,6 @@
self.convert_path(ctx, path, transform)
self._fill_and_stroke(ctx, rgbFace, gc.get_alpha())
- ctx.restore()
def draw_image(self, x, y, im, bbox, clippath=None, clippath_trans=None):
# bbox - not currently used
@@ -180,7 +161,7 @@
surface = cairo.ImageSurface.create_for_data (
buf, cairo.FORMAT_ARGB32, cols, rows, cols*4)
# function does not pass a 'gc' so use renderer.ctx
- ctx = self.ctx
+ ctx = self.gc.ctx
ctx.save()
if clippath is not None:
ctx.new_path()
@@ -297,9 +278,8 @@
def new_gc(self):
if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name())
- self.ctx.restore() # matches save() in set_ctx_from_surface()
- self.ctx.save()
- return GraphicsContextCairo (renderer=self)
+ self.gc.ctx.save()
+ return self.gc
def points_to_pixels(self, points):
@@ -324,9 +304,12 @@
def __init__(self, renderer):
GraphicsContextBase.__init__(self)
self.renderer = renderer
- self.ctx = renderer.ctx
+ def restore(self):
+ self.ctx.restore()
+
+
def set_alpha(self, alpha):
self._alpha = alpha
rgb = self._rgb
@@ -346,10 +329,23 @@
def set_clip_rectangle(self, rectangle):
- self._cliprect = rectangle
+ if not rectangle: return
+ x,y,w,h = rectangle.bounds
+ # pixel-aligned clip-regions are faster
+ x,y,w,h = round(x), round(y), round(w), round(h)
+ ctx = self.ctx
+ ctx.new_path()
+ ctx.rectangle (x, self.renderer.height - h - y, w, h)
+ ctx.clip ()
def set_clip_path(self, path):
- self._clippath = path
+ if not path: return
+ tpath, affine = path.get_transformed_path_and_affine()
+ ctx = self.ctx
+ ctx.new_path()
+ affine = affine + Affine2D().scale(1.0, -1.0).translate(0.0,
self.renderer.height)
+ RendererCairo.convert_path(ctx, tpath, affine)
+ ctx.clip()
def set_dashes(self, offset, dashes):
self._dashes = offset, dashes
@@ -468,7 +464,7 @@
renderer = RendererCairo (self.figure.dpi)
renderer.set_width_height (width_in_points, height_in_points)
renderer.set_ctx_from_surface (surface)
- ctx = renderer.ctx
+ ctx = renderer.gc.ctx
if orientation == 'landscape':
ctx.rotate (npy.pi/2)
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_gtkcairo.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_gtkcairo.py
2009-05-17 14:54:57 UTC (rev 7111)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_gtkcairo.py
2009-05-17 15:08:07 UTC (rev 7112)
@@ -31,12 +31,10 @@
class RendererGTKCairo (backend_cairo.RendererCairo):
if gtk.pygtk_version >= (2,7,0):
def set_pixmap (self, pixmap):
- self.ctx = pixmap.cairo_create()
- self.ctx.save() # restore, save - when call new_gc()
+ self.gc.ctx = pixmap.cairo_create()
else:
def set_pixmap (self, pixmap):
- self.ctx = cairo.gtk.gdk_cairo_create (pixmap)
- self.ctx.save() # restore, save - when call new_gc()
+ self.gc.ctx = cairo.gtk.gdk_cairo_create (pixmap)
class FigureCanvasGTKCairo(backend_cairo.FigureCanvasCairo, FigureCanvasGTK):
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_macosx.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_macosx.py 2009-05-17
14:54:57 UTC (rev 7111)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_macosx.py 2009-05-17
15:08:07 UTC (rev 7112)
@@ -51,19 +51,11 @@
def draw_path(self, gc, path, transform, rgbFace=None):
if rgbFace is not None:
rgbFace = tuple(rgbFace)
- if gc!=self.gc:
- n = self.gc.level() - gc.level()
- for i in range(n): self.gc.restore()
- self.gc = gc
gc.draw_path(path, transform, rgbFace)
def draw_markers(self, gc, marker_path, marker_trans, path, trans,
rgbFace=None):
if rgbFace is not None:
rgbFace = tuple(rgbFace)
- if gc!=self.gc:
- n = self.gc.level() - gc.level()
- for i in range(n): self.gc.restore()
- self.gc = gc
gc.draw_markers(marker_path, marker_trans, path, trans, rgbFace)
def draw_path_collection(self, *args):
@@ -76,7 +68,7 @@
gc.draw_quad_mesh(*args)
def new_gc(self):
- self.gc.reset()
+ self.gc.save()
self.gc.set_hatch(None)
return self.gc
@@ -87,10 +79,6 @@
im.flipud_out()
def draw_tex(self, gc, x, y, s, prop, angle):
- if gc!=self.gc:
- n = self.gc.level() - gc.level()
- for i in range(n): self.gc.restore()
- self.gc = gc
# todo, handle props, angle, origins
size = prop.get_size_in_points()
texmanager = self.get_texmanager()
@@ -103,19 +91,11 @@
gc.draw_mathtext(x, y, angle, Z)
def _draw_mathtext(self, gc, x, y, s, prop, angle):
- if gc!=self.gc:
- n = self.gc.level() - gc.level()
- for i in range(n): self.gc.restore()
- self.gc = gc
ox, oy, width, height, descent, image, used_characters = \
self.mathtext_parser.parse(s, self.dpi, prop)
gc.draw_mathtext(x, y, angle, 255 - image.as_array())
def draw_text(self, gc, x, y, s, prop, angle, ismath=False):
- if gc!=self.gc:
- n = self.gc.level() - gc.level()
- for i in range(n): self.gc.restore()
- self.gc = gc
if ismath:
self._draw_mathtext(gc, x, y, s, prop, angle)
else:
Modified: trunk/matplotlib/lib/matplotlib/lines.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/lines.py 2009-05-17 14:54:57 UTC (rev
7111)
+++ trunk/matplotlib/lib/matplotlib/lines.py 2009-05-17 15:08:07 UTC (rev
7112)
@@ -540,7 +540,9 @@
markerFunc = getattr(self, funcname)
markerFunc(renderer, gc, subsampled, affine.frozen())
+ gc.restore()
+ gc.restore()
renderer.close_group('line2d')
def get_antialiased(self): return self._antialiased
Modified: trunk/matplotlib/lib/matplotlib/patches.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/patches.py 2009-05-17 14:54:57 UTC (rev
7111)
+++ trunk/matplotlib/lib/matplotlib/patches.py 2009-05-17 15:08:07 UTC (rev
7112)
@@ -302,6 +302,7 @@
renderer.draw_path(gc, tpath, affine, rgbFace)
+ gc.restore()
renderer.close_group('patch')
def get_path(self):
@@ -3705,4 +3706,5 @@
renderer.draw_path(gc, p, affine, None)
+ gc.restore()
renderer.close_group('patch')
Modified: trunk/matplotlib/lib/matplotlib/text.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/text.py 2009-05-17 14:54:57 UTC (rev
7111)
+++ trunk/matplotlib/lib/matplotlib/text.py 2009-05-17 15:08:07 UTC (rev
7112)
@@ -507,6 +507,7 @@
self._fontproperties, angle,
ismath=ismath)
+ gc.restore()
renderer.close_group('text')
def get_color(self):
Modified: trunk/matplotlib/lib/mpl_toolkits/axes_grid/axislines.py
===================================================================
--- trunk/matplotlib/lib/mpl_toolkits/axes_grid/axislines.py 2009-05-17
14:54:57 UTC (rev 7111)
+++ trunk/matplotlib/lib/mpl_toolkits/axes_grid/axislines.py 2009-05-17
15:08:07 UTC (rev 7112)
@@ -65,6 +65,7 @@
lineFunc = getattr(self, funcname)
lineFunc(renderer, gc, tpath, affine.frozen())
+ gc.restore()
renderer.close_group('line2d')
@@ -548,6 +549,7 @@
renderer.draw_markers(gc, self._tickvert_path, marker_transform,
Path(locs), path_trans.get_affine())
+ gc.restore()
Modified: trunk/matplotlib/src/_macosx.m
===================================================================
--- trunk/matplotlib/src/_macosx.m 2009-05-17 14:54:57 UTC (rev 7111)
+++ trunk/matplotlib/src/_macosx.m 2009-05-17 15:08:07 UTC (rev 7112)
@@ -374,6 +374,7 @@
PyObject_HEAD
CGContextRef cr;
NSSize size;
+ int level;
} GraphicsContext;
static CGMutablePathRef _create_path(void* iterator)
@@ -437,6 +438,7 @@
GraphicsContext* self = (GraphicsContext*)type->tp_alloc(type, 0);
if (!self) return NULL;
self->cr = NULL;
+ self->level = 0;
if (ngc==0)
{
@@ -467,7 +469,7 @@
}
static PyObject*
-GraphicsContext_reset (GraphicsContext* self)
+GraphicsContext_save (GraphicsContext* self)
{
CGContextRef cr = self->cr;
if (!cr)
@@ -475,9 +477,29 @@
PyErr_SetString(PyExc_RuntimeError, "CGContextRef is NULL");
return NULL;
}
+ CGContextSaveGState(cr);
+ self->level++;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+static PyObject*
+GraphicsContext_restore (GraphicsContext* self)
+{
+ CGContextRef cr = self->cr;
+ if (!cr)
+ {
+ PyErr_SetString(PyExc_RuntimeError, "CGContextRef is NULL");
+ return NULL;
+ }
+ if (self->level==0)
+ {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Attempting to execute CGContextRestoreGState on an empty stack");
+ return NULL;
+ }
CGContextRestoreGState(cr);
- CGContextSaveGState(cr);
+ self->level--;
Py_INCREF(Py_None);
return Py_None;
}
@@ -1543,11 +1565,15 @@
const double b = *(double*)PyArray_GETPTR2(facecolors, fi, 2);
const double a = *(double*)PyArray_GETPTR2(facecolors, fi, 3);
CGContextSetRGBFillColor(cr, r, g, b, a);
- CGContextDrawPath(cr, kCGPathFillStroke);
+ if (Nedgecolors > 0) CGContextDrawPath(cr, kCGPathFillStroke);
+ else CGContextFillPath(cr);
}
else if (Nfacecolors==1)
- CGContextDrawPath(cr, kCGPathFillStroke);
- else
+ {
+ if (Nedgecolors > 0) CGContextDrawPath(cr, kCGPathFillStroke);
+ else CGContextFillPath(cr);
+ }
+ else /* We checked Nedgecolors != 0 above */
CGContextStrokePath(cr);
CGContextRestoreGState(cr);
}
@@ -2480,11 +2506,16 @@
static PyMethodDef GraphicsContext_methods[] = {
- {"reset",
- (PyCFunction)GraphicsContext_reset,
+ {"save",
+ (PyCFunction)GraphicsContext_save,
METH_NOARGS,
- "Resets the current graphics context by restoring it from the stack and
copying it back onto the stack."
+ "Saves the current graphics context onto the stack."
},
+ {"restore",
+ (PyCFunction)GraphicsContext_restore,
+ METH_NOARGS,
+ "Restores the current graphics context from the stack."
+ },
{"get_text_width_height_descent",
(PyCFunction)GraphicsContext_get_text_width_height_descent,
METH_VARARGS,
@@ -4293,17 +4324,14 @@
CGContextRef cr = (CGContextRef) [[NSGraphicsContext currentContext]
graphicsPort];
gc->cr = cr;
+ gc->level = 0;
- CGContextSaveGState(cr);
- CGContextSetTextMatrix(cr, CGAffineTransformIdentity);
-
result = PyObject_CallMethod(figure, "draw", "O", renderer);
if(result)
Py_DECREF(result);
else
PyErr_Print();
- CGContextRestoreGState(cr);
gc->cr = nil;
if (!NSIsEmptyRect(rubberband)) NSFrameRect(rubberband);
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables
unlimited royalty-free distribution of the report engine
for externally facing server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins