From: <md...@us...> - 2007-09-06 19:35:03
|
Revision: 3799 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3799&view=rev Author: mdboom Date: 2007-09-06 12:35:00 -0700 (Thu, 06 Sep 2007) Log Message: ----------- Add svgz support to backend_svg and backend_cairo. Put all styles inside of a separate <style> element in backend_svg, to save considerably on file size. Modified Paths: -------------- trunk/matplotlib/FILETYPES trunk/matplotlib/lib/matplotlib/backend_bases.py trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py trunk/matplotlib/lib/matplotlib/backends/backend_svg.py Modified: trunk/matplotlib/FILETYPES =================================================================== --- trunk/matplotlib/FILETYPES 2007-09-06 18:50:08 UTC (rev 3798) +++ trunk/matplotlib/FILETYPES 2007-09-06 19:35:00 UTC (rev 3799) @@ -7,54 +7,55 @@ A cell with a '+' in it denotes the rasterizer and the file writing infrastructure as separate pieces. -+--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ -| |bmp |emf |eps |jpeg |pcx |pdf |png |ps |raw |svg |tiff |xpm | -+--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ -|Agg | |emf |ps | | |pdf |agg * |ps |agg |svg | | | -+--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ -|Cairo | |emf |ps | | |cairo |cairo |cairo|agg |cairo| | | -|[1] | | |[2] | | | |* | | | | | | -+--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ -|CocoaAgg| |emf |ps | | |pdf |agg * |ps |agg |svg | | | -+--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ -|Emf | |emf *| | | | | | | | | | | -+--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ -|FltkAgg | |emf |ps | | |pdf |agg * |ps |agg |svg | | | -+--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ -|Gd | | | | | | |gd * | | | | | | -+--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ -|Gtk | |emf |ps |gdk + | |pdf |gdk + |ps |agg |svg | | | -|(gdk) | | | |pixbuf | | |pixbuf| | | | | | -| | | | | | | |* | | | | | | -+--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ -|GtkAgg | |emf |ps |agg + | |pdf |agg + |ps |agg |svg | | | -| | | | |pixbuf | | |pixbuf| | | | | | -| | | | | | | |* | | | | | | -+--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ -|GtkCairo| |emf |ps |cairo +| |cairo |cairo |cairo|agg |svg | | | -| | | | |pixbuf | | |* | | | | | | -+--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ -|Paint | | | | | | |libart| | | | | | -|(libart)| | | | | | |* | | | | | | -+--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ -|Pdf | | | | | |pdf * | | | | | | | -+--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ -|Ps | | |ps | | | | |ps * | | | | | -+--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ -|QtAgg | |emf |ps | | |pdf |agg * |ps |agg |svg | | | -+--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ -|Qt4Agg | |emf |ps | | |pdf |agg * |ps |agg |svg | | | -+--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ -|Svg | | | | | | | | | |svg *| | | -+--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ -|TkAgg | |emf |ps | | |pdf |agg * |ps |agg |svg | | | -+--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ -|Wx |wx + |emf |ps |wx + wx|wx + |pdf |wx + |ps |agg |svg |wx + |wx + | -| |wx | | | |wx | |wx * | | | |wx |wx | -+--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ -|WxAgg | |emf |ps | | |pdf |agg * |ps |agg |svg | | | -+--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+-----+ +| |bmp |emf |eps |jpeg |pcx |pdf |png |ps |raw |svg |svgz |tiff |xpm | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+-----+ +|Agg | |emf |ps | | |pdf |agg * |ps |agg |svg |svg | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+-----+ +|Cairo | |emf |ps | | |cairo |cairo |cairo|agg |cairo|cairo| | | +|[1] | | |[2] | | | |* | | | | | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+-----+ +|CocoaAgg| |emf |ps | | |pdf |agg * |ps |agg |svg |svg | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+-----+ +|Emf | |emf *| | | | | | | | | | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+-----+ +|FltkAgg | |emf |ps | | |pdf |agg * |ps |agg |svg |svg | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+-----+ +|Gd | | | | | | |gd * | | | | | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+-----+ +|Gtk | |emf |ps |gdk + | |pdf |gdk + |ps |agg |svg |svg | | | +|(gdk) | | | |pixbuf | | |pixbuf| | | | | | | +| | | | | | | |* | | | | | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+-----+ +|GtkAgg | |emf |ps |agg + | |pdf |agg + |ps |agg |svg |svg | | | +| | | | |pixbuf | | |pixbuf| | | | | | | +| | | | | | | |* | | | | | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+-----+ +|GtkCairo| |emf |ps |cairo +| |cairo |cairo |cairo|agg |svg |svg | | | +| | | | |pixbuf | | |* | | | | | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+-----+ +|Paint | | | | | | |libart| | | | | | | +|(libart)| | | | | | |* | | | | | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+-----+ +|Pdf | | | | | |pdf * | | | | | | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+-----+ +|Ps | | |ps | | | | |ps * | | | | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+-----+ +|QtAgg | |emf |ps | | |pdf |agg * |ps |agg |svg |svg | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+-----+ +|Qt4Agg | |emf |ps | | |pdf |agg * |ps |agg |svg |svg | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+-----+ +|Svg | | | | | | | | | |svg *|svg | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+-----+ +|TkAgg | |emf |ps | | |pdf |agg * |ps |agg |svg |svg | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+-----+ +|Wx |wx + |emf |ps |wx + wx|wx + |pdf |wx + |ps |agg |svg |svg |wx + |wx + | +| |wx | | | |wx | |wx * | | | | |wx |wx | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+-----+ +|WxAgg | |emf |ps | | |pdf |agg * |ps |agg |svg |svg | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+-----+ * Default filetype for the backend [1] Cairo's default filetype is specified in rcParams['cairo.format'] -[2] Cairo does not produce .eps files, and instead falls back on backend_ps.py \ No newline at end of file +[2] Cairo does not produce .eps files, and instead falls back on +backend_ps.py Modified: trunk/matplotlib/lib/matplotlib/backend_bases.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backend_bases.py 2007-09-06 18:50:08 UTC (rev 3798) +++ trunk/matplotlib/lib/matplotlib/backend_bases.py 2007-09-06 19:35:00 UTC (rev 3799) @@ -1081,6 +1081,7 @@ 'raw': 'Raw RGBA bitmap', 'rgb': 'Raw RGBA bitmap', 'svg': 'Scalable Vector Graphics', + 'svgz': 'Scalable Vector Graphics' } # All of these print_* functions do a lazy import because @@ -1123,7 +1124,12 @@ from backends.backend_svg import FigureCanvasSVG # lazy import svg = self.switch_backends(FigureCanvasSVG) return svg.print_svg(*args, **kwargs) - + + def print_svgz(self, *args, **kwargs): + from backends.backend_svg import FigureCanvasSVG # lazy import + svg = self.switch_backends(FigureCanvasSVG) + return svg.print_svgz(*args, **kwargs) + def get_supported_filetypes(self): return self.filetypes Modified: trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py 2007-09-06 18:50:08 UTC (rev 3798) +++ trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py 2007-09-06 19:35:00 UTC (rev 3799) @@ -19,7 +19,7 @@ """ from __future__ import division -import os, sys, warnings +import os, sys, warnings, gzip import numpy as npy @@ -36,7 +36,7 @@ from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\ FigureManagerBase, FigureCanvasBase -from matplotlib.cbook import enumerate, izip +from matplotlib.cbook import enumerate, izip, is_string_like from matplotlib.figure import Figure from matplotlib.mathtext import MathTextParser from matplotlib.transforms import Bbox @@ -46,10 +46,6 @@ _debug = False #_debug = True -# Image formats that this backend supports - for print_figure() -IMAGE_FORMAT = ['eps', 'pdf', 'png', 'ps', 'svg'] -IMAGE_FORMAT_DEFAULT = 'png' - # Image::color_conv(format) for draw_image() if sys.byteorder == 'little': BYTE_FORMAT = 0 # BGRA @@ -508,6 +504,9 @@ def print_svg(self, fobj, *args, **kwargs): return self._save(fobj, 'svg', *args, **kwargs) + def print_svgz(self, fobj, *args, **kwargs): + return self._save(fobj, 'svgz', *args, **kwargs) + def get_default_filetype(self): return rcParams['cairo.format'] @@ -534,10 +533,15 @@ raise RuntimeError ('cairo has not been compiled with PDF ' 'support enabled') surface = cairo.PDFSurface (fo, width_in_points, height_in_points) - elif format == 'svg': + elif format in ('svg', 'svgz'): if not cairo.HAS_SVG_SURFACE: raise RuntimeError ('cairo has not been compiled with SVG ' 'support enabled') + if format == 'svgz': + filename = fo + if is_string_like(fo): + fo = open(fo, 'wb') + fo = gzip.GzipFile(None, 'wb', fileobj=fo) surface = cairo.SVGSurface (fo, width_in_points, height_in_points) else: warnings.warn ("unknown format: %s" % format) Modified: trunk/matplotlib/lib/matplotlib/backends/backend_svg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2007-09-06 18:50:08 UTC (rev 3798) +++ trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2007-09-06 19:35:00 UTC (rev 3799) @@ -1,6 +1,6 @@ from __future__ import division -import os, codecs, base64, tempfile, urllib +import os, codecs, base64, tempfile, urllib, gzip from matplotlib import verbose, __version__, rcParams from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\ @@ -41,6 +41,7 @@ self._char_defs = {} self.mathtext_parser = MathTextParser('SVG') self.fontd = {} + self._styles = {} svgwriter.write(svgProlog%(width,height,width,height)) def _draw_svg_element(self, element, details, gc, rgbFace): @@ -50,9 +51,10 @@ else: clippath = 'clip-path="url(#%s)"' % clipid - self._svgwriter.write ('%s<%s %s %s %s/>\n' % ( + style = self._map_style(self._get_style(gc, rgbFace)) + self._svgwriter.write ('%s<%s class="%s" %s %s/>\n' % ( cliprect, - element, self._get_style(gc, rgbFace), clippath, details)) + element, style, clippath, details)) def _get_font(self, prop): key = hash(prop) @@ -85,8 +87,8 @@ linewidth = gc.get_linewidth() if linewidth: - return 'style="fill: %s; stroke: %s; stroke-width: %f; ' \ - 'stroke-linejoin: %s; stroke-linecap: %s; %s opacity: %f"' % ( + return 'fill: %s; stroke: %s; stroke-width: %f; ' \ + 'stroke-linejoin: %s; stroke-linecap: %s; %s opacity: %f' % ( fill, rgb2hex(gc.get_rgb()), linewidth, @@ -96,11 +98,16 @@ gc.get_alpha(), ) else: - return 'style="fill: %s; opacity: %f"' % (\ + return 'fill: %s; opacity: %f' % (\ fill, gc.get_alpha(), ) + def _map_style(self, style): + return self._styles.setdefault( + style, + "_%x" % len(self._styles)) + def _get_gc_clip_svg(self, gc): cliprect = gc.get_clip_rectangle() if cliprect is None: @@ -112,11 +119,12 @@ self._clipd[key] = cliprect x, y, w, h = cliprect y = self.height-(y+h) + style = self._map_style("stroke: gray; fill: none;") box = """\ <defs> <clipPath id="%(key)s"> <rect x="%(x)f" y="%(y)f" width="%(w)f" height="%(h)f" - style="stroke: gray; fill: none;"/> + class="%(style)s"/> </clipPath> </defs> """ % locals() @@ -286,12 +294,13 @@ svg = ''.join(svg) else: style = 'font-size: %f; font-family: %s; font-style: %s; fill: %s;'%(fontsize, fontfamily,fontstyle, color) + style_number = self._map_style(style) if angle!=0: transform = 'transform="translate(%f,%f) rotate(%1.1f) translate(%f,%f)"' % (x,y,-angle,-x,-y) # Inkscape doesn't support rotate(angle x y) else: transform = '' svg = """\ -<text style="%(style)s" x="%(x)f" y="%(y)f" %(transform)s>%(thetext)s</text> +<text class="%(style_number)s" x="%(x)f" y="%(y)f" %(transform)s>%(thetext)s</text> """ % locals() self._svgwriter.write (svg) @@ -348,8 +357,11 @@ self.open_group("mathtext") + style = "fill: %s" % color + style_number = self._map_style(style) + if rcParams['svg.embed_char_paths']: - svg = ['<g style="fill: %s" transform="' % color] + svg = ['<g class="%s" transform="' % style_number] if angle != 0: svg.append('translate(%f,%f) rotate(%1.1f)' % (x,y,-angle) ) @@ -364,7 +376,7 @@ (charid, new_x, -new_y_mtc, fontsize / self.FONT_SCALE)) svg.append('</g>\n') else: # not rcParams['svg.embed_char_paths'] - svg = ['<text style="fill: %s" x="%f" y="%f"' % (color,x,y)] + svg = ['<text class="%s" x="%f" y="%f"' % (style_number, x, y)] if angle != 0: svg.append(' transform="translate(%f,%f) rotate(%1.1f) translate(%f,%f)"' @@ -375,9 +387,10 @@ for font, fontsize, thetext, new_x, new_y_mtc, metrics in svg_glyphs: new_y = - new_y_mtc - - svg.append('<tspan style="font-size: %f; font-family: %s"' % - (fontsize, font.family_name)) + style = "font-size: %f; font-family: %s" % (fontsize, font.family_name) + style_number = self._map_style(style) + + svg.append('<tspan class="%s"' % style_number) xadvance = metrics.advance svg.append(' textLength="%f"' % xadvance) @@ -399,7 +412,8 @@ svg.append('</text>\n') if len(svg_rects): - svg.append('<g style="fill: black; stroke: none" transform="') + style_number = self._map_style("fill: black; stroke: none") + svg.append('<g class="%s" transform="' % style_number) if angle != 0: svg.append('translate(%f,%f) rotate(%1.1f)' % (x,y,-angle) ) @@ -415,12 +429,20 @@ self.close_group("mathtext") def finish(self): + write = self._svgwriter.write if len(self._char_defs): - self._svgwriter.write('<defs id="fontpaths">\n') + write('<defs id="fontpaths">\n') for path in self._char_defs.values(): - self._svgwriter.write(path) - self._svgwriter.write('</defs>\n') - self._svgwriter.write('</svg>\n') + write(path) + write('</defs>\n') + if len(self._styles): + write('<style type="text/css">\n') + styles = self._styles.items() + styles.sort() + for style, number in styles: + write('.%s { %s }\n' % (number, style)) + write('</style>\n') + write('</svg>\n') def flipy(self): return True @@ -444,14 +466,23 @@ class FigureCanvasSVG(FigureCanvasBase): - filetypes = {'svg': 'Scalable Vector Graphics'} + filetypes = {'svg': 'Scalable Vector Graphics', + 'svgz': 'Scalable Vector Graphics'} def print_svg(self, filename, *args, **kwargs): + svgwriter = codecs.open(filename, 'w', 'utf-8') + return self._print_svg(filename, svgwriter) + + def print_svgz(self, filename, *args, **kwargs): + gzipwriter = gzip.GzipFile(filename, 'w') + svgwriter = codecs.EncodedFile(gzipwriter, 'utf-8') + return self._print_svg(filename, svgwriter) + + def _print_svg(self, filename, svgwriter): self.figure.dpi.set(72) width, height = self.figure.get_size_inches() w, h = width*72, height*72 - svgwriter = codecs.open( filename, 'w', 'utf-8' ) renderer = RendererSVG(w, h, svgwriter, filename) self.figure.draw(renderer) renderer.finish() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |