Revision: 4399
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4399&view=rev
Author: mdboom
Date: 2007-11-20 14:00:51 -0800 (Tue, 20 Nov 2007)
Log Message:
-----------
Reduce file sizes for mixed-mode PDFs by only outputting the part of
the image with non-transparent pixels.
Minor speed improvement in MixedModeRenderer.
Modified Paths:
--------------
branches/transforms/lib/matplotlib/backends/backend_agg.py
branches/transforms/lib/matplotlib/backends/backend_mixed.py
branches/transforms/src/_backend_agg.cpp
branches/transforms/src/_backend_agg.h
Modified: branches/transforms/lib/matplotlib/backends/backend_agg.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_agg.py 2007-11-20
21:00:20 UTC (rev 4398)
+++ branches/transforms/lib/matplotlib/backends/backend_agg.py 2007-11-20
22:00:51 UTC (rev 4399)
@@ -68,6 +68,7 @@
self.draw_image = self._renderer.draw_image
self.copy_from_bbox = self._renderer.copy_from_bbox
self.restore_region = self._renderer.restore_region
+ self.tostring_rgba_minimized = self._renderer.tostring_rgba_minimized
self.mathtext_parser = MathTextParser('Agg')
self._fontd = {}
Modified: branches/transforms/lib/matplotlib/backends/backend_mixed.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_mixed.py
2007-11-20 21:00:20 UTC (rev 4398)
+++ branches/transforms/lib/matplotlib/backends/backend_mixed.py
2007-11-20 22:00:51 UTC (rev 4399)
@@ -34,14 +34,28 @@
assert not vector_renderer.option_image_nocomposite()
self._vector_renderer = vector_renderer
- vector_renderer.start_rasterizing = self.start_rasterizing
- vector_renderer.stop_rasterizing = self.stop_rasterizing
self._raster_renderer = None
self._rasterizing = False
- self._renderer = self._vector_renderer
+ self._set_current_renderer(vector_renderer)
+ _methods = """
+ open_group close_group draw_path draw_markers
+ draw_path_collection draw_quad_mesh get_image_magnification
+ draw_image draw_tex draw_text flipy option_image_nocomposite
+ get_texmanager get_text_width_height_descent new_gc
+ points_to_pixels strip_math finalize
+ """.split()
+ def _set_current_renderer(self, renderer):
+ self._renderer = renderer
+
+ for method in self._methods:
+ if hasattr(renderer, method):
+ setattr(self, method, getattr(renderer, method))
+ renderer.start_rasterizing = self.start_rasterizing
+ renderer.stop_rasterizing = self.stop_rasterizing
+
def start_rasterizing(self):
"""
Enter "raster" mode. All subsequent drawing commands (until
@@ -54,9 +68,7 @@
if not self._rasterizing:
self._raster_renderer = self._raster_renderer_class(
self._width*self._dpi, self._height*self._dpi, self._dpi)
- self._raster_renderer.start_rasterizing = self.start_rasterizing
- self._raster_renderer.stop_rasterizing = self.stop_rasterizing
- self._renderer = self._raster_renderer
+ self._set_current_renderer(self._raster_renderer)
self._rasterizing = True
def stop_rasterizing(self):
@@ -69,74 +81,19 @@
start_rasterizing is called, this method has no effect.
"""
if self._rasterizing:
+ self._set_current_renderer(self._vector_renderer)
+
width, height = self._width * self._dpi, self._height * self._dpi
- buffer = self._raster_renderer.buffer_rgba(0, 0)
- image = frombuffer(buffer, width, height, True)
- image.is_grayscale = False
+ buffer, bounds = self._raster_renderer.tostring_rgba_minimized()
+ l, b, w, h = bounds
+ if w > 0 and h > 0:
+ image = frombuffer(buffer, w, h, True)
+ image.is_grayscale = False
- self._renderer = self._vector_renderer
- self._renderer.draw_image(0, 0, image, None)
+ self._renderer.draw_image(l, height - b - h, image, None)
self._raster_renderer = None
self._rasterizing = False
def get_canvas_width_height(self):
'return the canvas width and height in display coords'
return self._width, self._height
-
- # The rest of this methods simply delegate to the currently active
- # rendering backend.
-
- def open_group(self, *args, **kwargs):
- return self._renderer.open_group(*args, **kwargs)
-
- def close_group(self, *args, **kwargs):
- return self._renderer.close_group(*args, **kwargs)
-
- def draw_path(self, *args, **kwargs):
- return self._renderer.draw_path(*args, **kwargs)
-
- def draw_markers(self, *args, **kwargs):
- return self._renderer.draw_markers(*args, **kwargs)
-
- def draw_path_collection(self, *args, **kwargs):
- return self._renderer.draw_path_collection(*args, **kwargs)
-
- def draw_quad_mesh(self, *args, **kwargs):
- return self._renderer.draw_quad_mesh(*args, **kwargs)
-
- def get_image_magnification(self, *args, **kwargs):
- return self._renderer.get_image_magnification(*args, **kwargs)
-
- def draw_image(self, *args, **kwargs):
- return self._renderer.draw_image(*args, **kwargs)
-
- def draw_tex(self, *args, **kwargs):
- return self._renderer.draw_tex(*args, **kwargs)
-
- def draw_text(self, *args, **kwargs):
- return self._renderer.draw_text(*args, **kwargs)
-
- def flipy(self, *args, **kwargs):
- return self._renderer.flipy(*args, **kwargs)
-
- def option_image_nocomposite(self, *args, **kwargs):
- return self._vector_renderer.option_image_nocomposite(*args, **kwargs)
-
- def get_texmanager(self, *args, **kwargs):
- return self._renderer.get_texmanager(*args, **kwargs)
-
- def get_text_width_height_descent(self, *args, **kwargs):
- return self._renderer.get_text_width_height_descent(*args, **kwargs)
-
- def new_gc(self, *args, **kwargs):
- return self._renderer.new_gc(*args, **kwargs)
-
- def points_to_pixels(self, *args, **kwargs):
- return self._renderer.points_to_pixels(*args, **kwargs)
-
- def strip_math(self, *args, **kwargs):
- return self._renderer(*args, **kwargs)
-
- def finalize(self, *args, **kwargs):
- return self._renderer.finalize(*args, **kwargs)
-
Modified: branches/transforms/src/_backend_agg.cpp
===================================================================
--- branches/transforms/src/_backend_agg.cpp 2007-11-20 21:00:20 UTC (rev
4398)
+++ branches/transforms/src/_backend_agg.cpp 2007-11-20 22:00:51 UTC (rev
4399)
@@ -1474,8 +1474,66 @@
return Py::asObject(PyBuffer_FromMemory( pixBuffer+start,
row_len*height-start));
}
+Py::Object
+RendererAgg::tostring_rgba_minimized(const Py::Tuple& args) {
+ args.verify_length(0);
+ int xmin = width;
+ int ymin = height;
+ int xmax = 0;
+ int ymax = 0;
+
+ // Looks at the alpha channel to find the minimum extents of the image
+ unsigned char* pixel = pixBuffer + 3;
+ for (int y = 0; y < (int)height; ++y) {
+ for (int x = 0; x < (int)width; ++x) {
+ if (*pixel) {
+ if (x < xmin) xmin = x;
+ if (y < ymin) ymin = y;
+ if (x > xmax) xmax = x;
+ if (y > ymax) ymax = y;
+ }
+ pixel += 4;
+ }
+ }
+ int newwidth = 0;
+ int newheight = 0;
+ Py::String data;
+ if (xmin < xmax and ymin < ymax) {
+ // Expand the bounds by 1 pixel on all sides
+ xmin = std::max(0, xmin - 1);
+ ymin = std::max(0, ymin - 1);
+ xmax = std::min(xmax, (int)width);
+ ymax = std::min(ymax, (int)height);
+
+ newwidth = xmax - xmin;
+ newheight = ymax - ymin;
+ int newsize = newwidth * newheight * 4;
+
+ unsigned char* buf = new unsigned char[newsize];
+ unsigned int* dst = (unsigned int*)buf;
+ unsigned int* src = (unsigned int*)pixBuffer;
+ for (int y = ymin; y < ymax; ++y)
+ for (int x = xmin; x < xmax; ++x, ++dst)
+ *dst = src[y * width + x];
+
+ data = Py::String((const char *)buf, (int)newsize);
+ }
+
+ Py::Tuple bounds(4);
+ bounds[0] = Py::Int(xmin);
+ bounds[1] = Py::Int(ymin);
+ bounds[2] = Py::Int(newwidth);
+ bounds[3] = Py::Int(newheight);
+
+ Py::Tuple result(2);
+ result[0] = data;
+ result[1] = bounds;
+
+ return result;
+}
+
Py::Object
RendererAgg::clear(const Py::Tuple& args) {
//"clear the rendered buffer";
@@ -1605,6 +1663,8 @@
"s = tostring_argb()");
add_varargs_method("tostring_bgra", &RendererAgg::tostring_bgra,
"s = tostring_bgra()");
+ add_varargs_method("tostring_rgba_minimized",
&RendererAgg::tostring_rgba_minimized,
+ "s = tostring_rgba_minimized()");
add_varargs_method("buffer_rgba", &RendererAgg::buffer_rgba,
"buffer = buffer_rgba()");
add_varargs_method("clear", &RendererAgg::clear,
Modified: branches/transforms/src/_backend_agg.h
===================================================================
--- branches/transforms/src/_backend_agg.h 2007-11-20 21:00:20 UTC (rev
4398)
+++ branches/transforms/src/_backend_agg.h 2007-11-20 22:00:51 UTC (rev
4399)
@@ -179,6 +179,7 @@
Py::Object tostring_rgb(const Py::Tuple & args);
Py::Object tostring_argb(const Py::Tuple & args);
Py::Object tostring_bgra(const Py::Tuple & args);
+ Py::Object tostring_rgba_minimized(const Py::Tuple & args);
Py::Object buffer_rgba(const Py::Tuple & args);
Py::Object clear(const Py::Tuple & args);
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins