You can subscribe to this list here.
2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(115) |
Aug
(120) |
Sep
(137) |
Oct
(170) |
Nov
(461) |
Dec
(263) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2008 |
Jan
(120) |
Feb
(74) |
Mar
(35) |
Apr
(74) |
May
(245) |
Jun
(356) |
Jul
(240) |
Aug
(115) |
Sep
(78) |
Oct
(225) |
Nov
(98) |
Dec
(271) |
2009 |
Jan
(132) |
Feb
(84) |
Mar
(74) |
Apr
(56) |
May
(90) |
Jun
(79) |
Jul
(83) |
Aug
(296) |
Sep
(214) |
Oct
(76) |
Nov
(82) |
Dec
(66) |
2010 |
Jan
(46) |
Feb
(58) |
Mar
(51) |
Apr
(77) |
May
(58) |
Jun
(126) |
Jul
(128) |
Aug
(64) |
Sep
(50) |
Oct
(44) |
Nov
(48) |
Dec
(54) |
2011 |
Jan
(68) |
Feb
(52) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
2018 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <md...@us...> - 2007-09-07 18:07:44
|
Revision: 3811 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3811&view=rev Author: mdboom Date: 2007-09-07 11:07:43 -0700 (Fri, 07 Sep 2007) Log Message: ----------- Note that .bmp is no longer an alias for .raw Modified Paths: -------------- trunk/matplotlib/CHANGELOG Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2007-09-07 15:23:32 UTC (rev 3810) +++ trunk/matplotlib/CHANGELOG 2007-09-07 18:07:43 UTC (rev 3811) @@ -1,3 +1,5 @@ +2007-09-06 .bmp file format is now longer an alias for .raw + 2007-09-07 Added clip path support to pdf backend. - JKS 2007-09-06 Fixed a bug in the embedding of Type 1 fonts in PDF. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-09-07 15:23:34
|
Revision: 3810 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3810&view=rev Author: mdboom Date: 2007-09-07 08:23:32 -0700 (Fri, 07 Sep 2007) Log Message: ----------- Merged revisions 3806-3809 via svnmerge from http://matplotlib.svn.sf.net/svnroot/matplotlib/trunk/matplotlib ........ r3807 | mdboom | 2007-09-07 10:34:51 -0400 (Fri, 07 Sep 2007) | 2 lines Backout stylesheet optimization. Breaks on inkscape and Adobe SVG viewer. ........ r3808 | mdboom | 2007-09-07 10:55:55 -0400 (Fri, 07 Sep 2007) | 3 lines Fix embedded glyph rendering bug revealed by Inkscape and Safari (but not Firefox) ........ Modified Paths: -------------- branches/transforms/lib/matplotlib/backends/backend_svg.py Property Changed: ---------------- branches/transforms/ Property changes on: branches/transforms ___________________________________________________________________ Name: svnmerge-integrated - /trunk/matplotlib:1-3805 + /trunk/matplotlib:1-3809 Modified: branches/transforms/lib/matplotlib/backends/backend_svg.py =================================================================== --- branches/transforms/lib/matplotlib/backends/backend_svg.py 2007-09-07 15:02:52 UTC (rev 3809) +++ branches/transforms/lib/matplotlib/backends/backend_svg.py 2007-09-07 15:23:32 UTC (rev 3810) @@ -41,7 +41,6 @@ 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): @@ -51,10 +50,9 @@ else: clippath = 'clip-path="url(#%s)"' % clipid - style = self._map_style(self._get_style(gc, rgbFace)) - self._svgwriter.write ('%s<%s class="%s" %s %s/>\n' % ( - cliprect, - element, style, clippath, details)) + style = self._get_style(gc, rgbFace) + self._svgwriter.write ('%s<%s style="%s" %s %s/>\n' % ( + cliprect, element, style, clippath, details)) def _get_font(self, prop): key = hash(prop) @@ -82,13 +80,13 @@ if seq is None: dashes = '' else: - dashes = 'stroke-dasharray: %s; stroke-dashoffset: %f;' % ( - ','.join(['%f'%val for val in seq]), offset) + dashes = 'stroke-dasharray: %s; stroke-dashoffset: %s;' % ( + ','.join(['%s'%val for val in seq]), offset) linewidth = gc.get_linewidth() if linewidth: - return 'fill: %s; stroke: %s; stroke-width: %f; ' \ - 'stroke-linejoin: %s; stroke-linecap: %s; %s opacity: %f' % ( + return 'fill: %s; stroke: %s; stroke-width: %s; ' \ + 'stroke-linejoin: %s; stroke-linecap: %s; %s opacity: %s' % ( fill, rgb2hex(gc.get_rgb()), linewidth, @@ -98,16 +96,11 @@ gc.get_alpha(), ) else: - return 'fill: %s; opacity: %f' % (\ + return 'fill: %s; opacity: %s' % (\ 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: @@ -119,12 +112,12 @@ self._clipd[key] = cliprect x, y, w, h = cliprect y = self.height-(y+h) - style = self._map_style("stroke: gray; fill: none;") + style = "stroke: gray; fill: none;" box = """\ <defs> <clipPath id="%(key)s"> - <rect x="%(x)f" y="%(y)f" width="%(w)f" height="%(h)f" - class="%(style)s"/> + <rect x="%(x)s" y="%(y)s" width="%(w)s" height="%(h)s" + style="%(style)s"/> </clipPath> </defs> """ % locals() @@ -144,7 +137,7 @@ """ Ignores angles for now """ - details = 'cx="%f" cy="%f" rx="%f" ry="%f" transform="rotate(%f %f %f)"' % \ + details = 'cx="%s" cy="%s" rx="%s" ry="%s" transform="rotate(%1.1f %s %s)"' % \ (x, self.height-y, width/2.0, height/2.0, -rotation, x, self.height-y) self._draw_svg_element('ellipse', details, gc, rgbFace) @@ -163,7 +156,7 @@ trans[4] += trans[0] trans[5] += trans[3] trans[5] = -trans[5] - transstr = 'transform="matrix(%f %f %f %f %f %f)" '%tuple(trans) + transstr = 'transform="matrix(%s %s %s %s %s %s)" '%tuple(trans) assert trans[1] == 0 assert trans[2] == 0 numrows,numcols = im.get_size() @@ -207,12 +200,12 @@ hrefstr = filename self._svgwriter.write ( - '<image x="%f" y="%f" width="%f" height="%f" ' + '<image x="%s" y="%s" width="%s" height="%s" ' 'xlink:href="%s" %s/>\n'%(x/trans[0], (self.height-y)/trans[3]-h, w, h, hrefstr, transstr) ) def draw_line(self, gc, x1, y1, x2, y2): - details = 'd="M %f,%f L %f,%f"' % (x1, self.height-y1, + details = 'd="M%s,%sL%s,%s"' % (x1, self.height-y1, x2, self.height-y2) self._draw_svg_element('path', details, gc, None) @@ -222,11 +215,11 @@ raise ValueError('x and y must be the same length') y = self.height - y - details = ['d="M %f,%f' % (x[0], y[0])] + details = ['d="M%s,%s' % (x[0], y[0])] xys = zip(x[1:], y[1:]) - details.extend(['L %f,%f' % tup for tup in xys]) + details.extend(['L%s,%s' % tup for tup in xys]) details.append('"') - details = ' '.join(details) + details = ''.join(details) self._draw_svg_element('path', details, gc, None) def draw_point(self, gc, x, y): @@ -234,12 +227,12 @@ self.draw_arc(gc, gc.get_rgb(), x, y, 1, 0, 0, 0, 0) def draw_polygon(self, gc, rgbFace, points): - details = 'points = "%s"' % ' '.join(['%f,%f'%(x,self.height-y) + details = 'points = "%s"' % ' '.join(['%s,%s'%(x,self.height-y) for x, y in points]) self._draw_svg_element('polygon', details, gc, rgbFace) def draw_rectangle(self, gc, rgbFace, x, y, width, height): - details = 'width="%f" height="%f" x="%f" y="%f"' % (width, height, x, + details = 'width="%s" height="%s" x="%s" y="%s"' % (width, height, x, self.height-y-height) self._draw_svg_element('rect', details, gc, rgbFace) @@ -260,12 +253,11 @@ if rcParams['svg.embed_char_paths']: svg = ['<g transform="'] - if angle!=0: - # Inkscape doesn't support rotate(angle x y) - svg.append('translate(%f,%f) rotate(%1.1f) ' % (x,y,-angle)) - else: - svg.append('translate(%f,%f)' % (x,y)) - svg.append(' scale(%f)">\n' % (fontsize / self.FONT_SCALE)) + if angle != 0: + svg.append('translate(%s,%s)rotate(%1.1f)' % (x,y,-angle)) + elif x != 0 or y != 0: + svg.append('translate(%s,%s)' % (x, y)) + svg.append('scale(%s)">\n' % (fontsize / self.FONT_SCALE)) cmap = font.get_charmap() lastgind = None @@ -286,21 +278,24 @@ lastgind = gind currx += kern/64.0 - svg.append('<use xlink:href="#%s" transform="translate(%s)"/>\n' - % (charid, currx * (self.FONT_SCALE / fontsize))) - + svg.append('<use xlink:href="#%s"' % charid) + if currx != 0: + svg.append(' transform="translate(%s)"' % + (currx * (self.FONT_SCALE / fontsize))) + svg.append('/>\n') currx += (glyph.linearHoriAdvance / 65536.0) svg.append('</g>\n') 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 = '' + transform = 'transform="translate(%s,%s) rotate(%1.1f) translate(%s,%s)"' % (x,y,-angle,-x,-y) + # Inkscape doesn't support rotate(angle x y) + else: + transform = '' svg = """\ -<text class="%(style_number)s" x="%(x)f" y="%(y)f" %(transform)s>%(thetext)s</text> +<text style="%(style)s" x="%(x)s" y="%(y)s" %(transform)s>%(thetext)s</text> """ % locals() self._svgwriter.write (svg) @@ -313,16 +308,17 @@ font.set_size(self.FONT_SCALE, 72) ps_name = font.get_sfnt()[(1,0,0,6)] char_id = urllib.quote('%s-%d' % (ps_name, ord(char))) - if char_id in self._char_defs: - return char_id + char_num, path = self._char_defs.get(char_id, (None, None)) + if char_num is not None: + return char_num path_data = [] glyph = font.load_char(ord(char), flags=LOAD_NO_HINTING) currx, curry = 0.0, 0.0 for step in glyph.path: if step[0] == 0: # MOVE_TO - path_data.append("m%s %s" % - (step[1] - currx, -step[2] - curry)) + path_data.append("M%s %s" % + (step[1], -step[2])) elif step[0] == 1: # LINE_TO path_data.append("l%s %s" % (step[1] - currx, -step[2] - curry)) @@ -336,15 +332,16 @@ step[3] - currx, -step[4] - curry, step[5] - currx, -step[6] - curry)) elif step[0] == 4: # ENDPOLY - path_data.append("Z") + path_data.append("z") + currx, curry = 0.0, 0.0 if step[0] != 4: currx, curry = step[-2], -step[-1] - path_element = '<path id="%s" d="%s"/>\n' % (char_id, " ".join(path_data)) + char_num = 'c_%x' % len(self._char_defs) + path_element = '<path id="%s" d="%s"/>\n' % (char_num, ''.join(path_data)) + self._char_defs[char_id] = (char_num, path_element) + return char_num - self._char_defs[char_id] = path_element - return char_id - def _draw_mathtext(self, gc, x, y, s, prop, angle): """ Draw math text using matplotlib.mathtext @@ -358,25 +355,24 @@ self.open_group("mathtext") style = "fill: %s" % color - style_number = self._map_style(style) if rcParams['svg.embed_char_paths']: - svg = ['<g class="%s" transform="' % style_number] + svg = ['<g style="%s" transform="' % style] if angle != 0: - svg.append('translate(%f,%f) rotate(%1.1f)' + svg.append('translate(%s,%s)rotate(%1.1f)' % (x,y,-angle) ) else: - svg.append('translate(%f,%f)' % (x, y)) + svg.append('translate(%s,%s)' % (x, y)) svg.append('">\n') for font, fontsize, thetext, new_x, new_y_mtc, metrics in svg_glyphs: charid = self._add_char_def(font, thetext) - svg.append('<use xlink:href="#%s" transform="translate(%s, %s) scale(%s)"/>\n' % + svg.append('<use xlink:href="#%s" transform="translate(%s,%s)scale(%s)"/>\n' % (charid, new_x, -new_y_mtc, fontsize / self.FONT_SCALE)) svg.append('</g>\n') else: # not rcParams['svg.embed_char_paths'] - svg = ['<text class="%s" x="%f" y="%f"' % (style_number, x, y)] + svg = ['<text style="%s" x="%f" y="%f"' % (style, x, y)] if angle != 0: svg.append(' transform="translate(%f,%f) rotate(%1.1f) translate(%f,%f)"' @@ -388,19 +384,18 @@ for font, fontsize, thetext, new_x, new_y_mtc, metrics in svg_glyphs: new_y = - new_y_mtc style = "font-size: %f; font-family: %s" % (fontsize, font.family_name) - style_number = self._map_style(style) - svg.append('<tspan class="%s"' % style_number) + svg.append('<tspan style="%s"' % style) xadvance = metrics.advance - svg.append(' textLength="%f"' % xadvance) + svg.append(' textLength="%s"' % xadvance) dx = new_x - curr_x if dx != 0.0: - svg.append(' dx="%f"' % dx) + svg.append(' dx="%s"' % dx) dy = new_y - curr_y if dy != 0.0: - svg.append(' dy="%f"' % dy) + svg.append(' dy="%s"' % dy) thetext = escape_xml_text(thetext) @@ -412,13 +407,13 @@ svg.append('</text>\n') if len(svg_rects): - style_number = self._map_style("fill: black; stroke: none") - svg.append('<g class="%s" transform="' % style_number) + style = "fill: black; stroke: none" + svg.append('<g style="%s" transform="' % style) if angle != 0: - svg.append('translate(%f,%f) rotate(%1.1f)' + svg.append('translate(%s,%s) rotate(%1.1f)' % (x,y,-angle) ) else: - svg.append('translate(%f,%f)' % (x, y)) + svg.append('translate(%s,%s)' % (x, y)) svg.append('">\n') for x, y, width, height in svg_rects: @@ -432,16 +427,9 @@ write = self._svgwriter.write if len(self._char_defs): write('<defs id="fontpaths">\n') - for path in self._char_defs.values(): + for char_num, path in self._char_defs.values(): 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): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-09-07 15:02:56
|
Revision: 3809 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3809&view=rev Author: mdboom Date: 2007-09-07 08:02:52 -0700 (Fri, 07 Sep 2007) Log Message: ----------- Initialized merge tracking via "svnmerge" with revisions "1-3805" from http://matplotlib.svn.sf.net/svnroot/matplotlib/trunk/matplotlib Property Changed: ---------------- branches/transforms/ Property changes on: branches/transforms ___________________________________________________________________ Name: svnmerge-integrated + /trunk/matplotlib:1-3805 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-09-07 14:55:58
|
Revision: 3808 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3808&view=rev Author: mdboom Date: 2007-09-07 07:55:55 -0700 (Fri, 07 Sep 2007) Log Message: ----------- Fix embedded glyph rendering bug revealed by Inkscape and Safari (but not Firefox) Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backends/backend_svg.py Modified: trunk/matplotlib/lib/matplotlib/backends/backend_svg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2007-09-07 14:34:51 UTC (rev 3807) +++ trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2007-09-07 14:55:55 UTC (rev 3808) @@ -317,8 +317,8 @@ currx, curry = 0.0, 0.0 for step in glyph.path: if step[0] == 0: # MOVE_TO - path_data.append("m%s %s" % - (step[1] - currx, -step[2] - curry)) + path_data.append("M%s %s" % + (step[1], -step[2])) elif step[0] == 1: # LINE_TO path_data.append("l%s %s" % (step[1] - currx, -step[2] - curry)) @@ -332,7 +332,8 @@ step[3] - currx, -step[4] - curry, step[5] - currx, -step[6] - curry)) elif step[0] == 4: # ENDPOLY - path_data.append("Z") + path_data.append("z") + currx, curry = 0.0, 0.0 if step[0] != 4: currx, curry = step[-2], -step[-1] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-09-07 14:34:52
|
Revision: 3807 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3807&view=rev Author: mdboom Date: 2007-09-07 07:34:51 -0700 (Fri, 07 Sep 2007) Log Message: ----------- Backout stylesheet optimization. Breaks on inkscape and Adobe SVG viewer. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backends/backend_svg.py Modified: trunk/matplotlib/lib/matplotlib/backends/backend_svg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2007-09-07 14:04:36 UTC (rev 3806) +++ trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2007-09-07 14:34:51 UTC (rev 3807) @@ -41,7 +41,6 @@ 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): @@ -51,10 +50,9 @@ else: clippath = 'clip-path="url(#%s)"' % clipid - style = self._map_style(self._get_style(gc, rgbFace)) - self._svgwriter.write ('%s<%s class="%s" %s %s/>\n' % ( - cliprect, - element, style, clippath, details)) + style = self._get_style(gc, rgbFace) + self._svgwriter.write ('%s<%s style="%s" %s %s/>\n' % ( + cliprect, element, style, clippath, details)) def _get_font(self, prop): key = hash(prop) @@ -82,13 +80,13 @@ if seq is None: dashes = '' else: - dashes = 'stroke-dasharray: %s; stroke-dashoffset: %f;' % ( - ','.join(['%f'%val for val in seq]), offset) + dashes = 'stroke-dasharray: %s; stroke-dashoffset: %s;' % ( + ','.join(['%s'%val for val in seq]), offset) linewidth = gc.get_linewidth() if linewidth: - return 'fill: %s; stroke: %s; stroke-width: %f; ' \ - 'stroke-linejoin: %s; stroke-linecap: %s; %s opacity: %f' % ( + return 'fill: %s; stroke: %s; stroke-width: %s; ' \ + 'stroke-linejoin: %s; stroke-linecap: %s; %s opacity: %s' % ( fill, rgb2hex(gc.get_rgb()), linewidth, @@ -98,16 +96,11 @@ gc.get_alpha(), ) else: - return 'fill: %s; opacity: %f' % (\ + return 'fill: %s; opacity: %s' % (\ 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: @@ -119,12 +112,12 @@ self._clipd[key] = cliprect x, y, w, h = cliprect y = self.height-(y+h) - style = self._map_style("stroke: gray; fill: none;") + style = "stroke: gray; fill: none;" box = """\ <defs> <clipPath id="%(key)s"> - <rect x="%(x)f" y="%(y)f" width="%(w)f" height="%(h)f" - class="%(style)s"/> + <rect x="%(x)s" y="%(y)s" width="%(w)s" height="%(h)s" + style="%(style)s"/> </clipPath> </defs> """ % locals() @@ -144,7 +137,7 @@ """ Ignores angles for now """ - details = 'cx="%f" cy="%f" rx="%f" ry="%f" transform="rotate(%f %f %f)"' % \ + details = 'cx="%s" cy="%s" rx="%s" ry="%s" transform="rotate(%1.1f %s %s)"' % \ (x, self.height-y, width/2.0, height/2.0, -rotation, x, self.height-y) self._draw_svg_element('ellipse', details, gc, rgbFace) @@ -163,7 +156,7 @@ trans[4] += trans[0] trans[5] += trans[3] trans[5] = -trans[5] - transstr = 'transform="matrix(%f %f %f %f %f %f)" '%tuple(trans) + transstr = 'transform="matrix(%s %s %s %s %s %s)" '%tuple(trans) assert trans[1] == 0 assert trans[2] == 0 numrows,numcols = im.get_size() @@ -207,12 +200,12 @@ hrefstr = filename self._svgwriter.write ( - '<image x="%f" y="%f" width="%f" height="%f" ' + '<image x="%s" y="%s" width="%s" height="%s" ' 'xlink:href="%s" %s/>\n'%(x/trans[0], (self.height-y)/trans[3]-h, w, h, hrefstr, transstr) ) def draw_line(self, gc, x1, y1, x2, y2): - details = 'd="M %f,%f L %f,%f"' % (x1, self.height-y1, + details = 'd="M%s,%sL%s,%s"' % (x1, self.height-y1, x2, self.height-y2) self._draw_svg_element('path', details, gc, None) @@ -222,11 +215,11 @@ raise ValueError('x and y must be the same length') y = self.height - y - details = ['d="M %f,%f' % (x[0], y[0])] + details = ['d="M%s,%s' % (x[0], y[0])] xys = zip(x[1:], y[1:]) - details.extend(['L %f,%f' % tup for tup in xys]) + details.extend(['L%s,%s' % tup for tup in xys]) details.append('"') - details = ' '.join(details) + details = ''.join(details) self._draw_svg_element('path', details, gc, None) def draw_point(self, gc, x, y): @@ -234,12 +227,12 @@ self.draw_arc(gc, gc.get_rgb(), x, y, 1, 0, 0, 0, 0) def draw_polygon(self, gc, rgbFace, points): - details = 'points = "%s"' % ' '.join(['%f,%f'%(x,self.height-y) + details = 'points = "%s"' % ' '.join(['%s,%s'%(x,self.height-y) for x, y in points]) self._draw_svg_element('polygon', details, gc, rgbFace) def draw_rectangle(self, gc, rgbFace, x, y, width, height): - details = 'width="%f" height="%f" x="%f" y="%f"' % (width, height, x, + details = 'width="%s" height="%s" x="%s" y="%s"' % (width, height, x, self.height-y-height) self._draw_svg_element('rect', details, gc, rgbFace) @@ -260,12 +253,11 @@ if rcParams['svg.embed_char_paths']: svg = ['<g transform="'] - if angle!=0: - # Inkscape doesn't support rotate(angle x y) - svg.append('translate(%f,%f) rotate(%1.1f) ' % (x,y,-angle)) - else: - svg.append('translate(%f,%f)' % (x,y)) - svg.append(' scale(%f)">\n' % (fontsize / self.FONT_SCALE)) + if angle != 0: + svg.append('translate(%s,%s)rotate(%1.1f)' % (x,y,-angle)) + elif x != 0 or y != 0: + svg.append('translate(%s,%s)' % (x, y)) + svg.append('scale(%s)">\n' % (fontsize / self.FONT_SCALE)) cmap = font.get_charmap() lastgind = None @@ -286,21 +278,24 @@ lastgind = gind currx += kern/64.0 - svg.append('<use xlink:href="#%s" transform="translate(%s)"/>\n' - % (charid, currx * (self.FONT_SCALE / fontsize))) - + svg.append('<use xlink:href="#%s"' % charid) + if currx != 0: + svg.append(' transform="translate(%s)"' % + (currx * (self.FONT_SCALE / fontsize))) + svg.append('/>\n') currx += (glyph.linearHoriAdvance / 65536.0) svg.append('</g>\n') 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 = '' + transform = 'transform="translate(%s,%s) rotate(%1.1f) translate(%s,%s)"' % (x,y,-angle,-x,-y) + # Inkscape doesn't support rotate(angle x y) + else: + transform = '' svg = """\ -<text class="%(style_number)s" x="%(x)f" y="%(y)f" %(transform)s>%(thetext)s</text> +<text style="%(style)s" x="%(x)s" y="%(y)s" %(transform)s>%(thetext)s</text> """ % locals() self._svgwriter.write (svg) @@ -313,8 +308,9 @@ font.set_size(self.FONT_SCALE, 72) ps_name = font.get_sfnt()[(1,0,0,6)] char_id = urllib.quote('%s-%d' % (ps_name, ord(char))) - if char_id in self._char_defs: - return char_id + char_num, path = self._char_defs.get(char_id, (None, None)) + if char_num is not None: + return char_num path_data = [] glyph = font.load_char(ord(char), flags=LOAD_NO_HINTING) @@ -340,11 +336,11 @@ if step[0] != 4: currx, curry = step[-2], -step[-1] - path_element = '<path id="%s" d="%s"/>\n' % (char_id, " ".join(path_data)) + char_num = 'c_%x' % len(self._char_defs) + path_element = '<path id="%s" d="%s"/>\n' % (char_num, ''.join(path_data)) + self._char_defs[char_id] = (char_num, path_element) + return char_num - self._char_defs[char_id] = path_element - return char_id - def _draw_mathtext(self, gc, x, y, s, prop, angle): """ Draw math text using matplotlib.mathtext @@ -358,25 +354,24 @@ self.open_group("mathtext") style = "fill: %s" % color - style_number = self._map_style(style) if rcParams['svg.embed_char_paths']: - svg = ['<g class="%s" transform="' % style_number] + svg = ['<g style="%s" transform="' % style] if angle != 0: - svg.append('translate(%f,%f) rotate(%1.1f)' + svg.append('translate(%s,%s)rotate(%1.1f)' % (x,y,-angle) ) else: - svg.append('translate(%f,%f)' % (x, y)) + svg.append('translate(%s,%s)' % (x, y)) svg.append('">\n') for font, fontsize, thetext, new_x, new_y_mtc, metrics in svg_glyphs: charid = self._add_char_def(font, thetext) - svg.append('<use xlink:href="#%s" transform="translate(%s, %s) scale(%s)"/>\n' % + svg.append('<use xlink:href="#%s" transform="translate(%s,%s)scale(%s)"/>\n' % (charid, new_x, -new_y_mtc, fontsize / self.FONT_SCALE)) svg.append('</g>\n') else: # not rcParams['svg.embed_char_paths'] - svg = ['<text class="%s" x="%f" y="%f"' % (style_number, x, y)] + svg = ['<text style="%s" x="%f" y="%f"' % (style, x, y)] if angle != 0: svg.append(' transform="translate(%f,%f) rotate(%1.1f) translate(%f,%f)"' @@ -388,19 +383,18 @@ for font, fontsize, thetext, new_x, new_y_mtc, metrics in svg_glyphs: new_y = - new_y_mtc style = "font-size: %f; font-family: %s" % (fontsize, font.family_name) - style_number = self._map_style(style) - svg.append('<tspan class="%s"' % style_number) + svg.append('<tspan style="%s"' % style) xadvance = metrics.advance - svg.append(' textLength="%f"' % xadvance) + svg.append(' textLength="%s"' % xadvance) dx = new_x - curr_x if dx != 0.0: - svg.append(' dx="%f"' % dx) + svg.append(' dx="%s"' % dx) dy = new_y - curr_y if dy != 0.0: - svg.append(' dy="%f"' % dy) + svg.append(' dy="%s"' % dy) thetext = escape_xml_text(thetext) @@ -412,13 +406,13 @@ svg.append('</text>\n') if len(svg_rects): - style_number = self._map_style("fill: black; stroke: none") - svg.append('<g class="%s" transform="' % style_number) + style = "fill: black; stroke: none" + svg.append('<g style="%s" transform="' % style) if angle != 0: - svg.append('translate(%f,%f) rotate(%1.1f)' + svg.append('translate(%s,%s) rotate(%1.1f)' % (x,y,-angle) ) else: - svg.append('translate(%f,%f)' % (x, y)) + svg.append('translate(%s,%s)' % (x, y)) svg.append('">\n') for x, y, width, height in svg_rects: @@ -432,16 +426,9 @@ write = self._svgwriter.write if len(self._char_defs): write('<defs id="fontpaths">\n') - for path in self._char_defs.values(): + for char_num, path in self._char_defs.values(): 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): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-09-07 14:04:37
|
Revision: 3806 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3806&view=rev Author: mdboom Date: 2007-09-07 07:04:36 -0700 (Fri, 07 Sep 2007) Log Message: ----------- Creating branch to work on transforms/projections refactoring. Added Paths: ----------- branches/transforms/ Copied: branches/transforms (from rev 3805, trunk/matplotlib) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-09-07 13:55:46
|
Revision: 3805 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3805&view=rev Author: mdboom Date: 2007-09-07 06:55:45 -0700 (Fri, 07 Sep 2007) Log Message: ----------- Removing obsolete branch for mathtext improvements (merged to trunk a long time ago Removed Paths: ------------- branches/mathtext_mgd/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-09-07 12:25:40
|
Revision: 3804 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3804&view=rev Author: mdboom Date: 2007-09-07 05:25:37 -0700 (Fri, 07 Sep 2007) Log Message: ----------- Fix a couple of backend_svg buglets. 1. Dashed lines did not render properly 2. Resulting SVG was scaled wrong (width and height should be specified in points, not pixels.) Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backends/backend_svg.py Modified: trunk/matplotlib/lib/matplotlib/backends/backend_svg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2007-09-07 06:58:00 UTC (rev 3803) +++ trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2007-09-07 12:25:37 UTC (rev 3804) @@ -83,7 +83,7 @@ dashes = '' else: dashes = 'stroke-dasharray: %s; stroke-dashoffset: %f;' % ( - ' '.join(['%f'%val for val in seq]), offset) + ','.join(['%f'%val for val in seq]), offset) linewidth = gc.get_linewidth() if linewidth: @@ -501,7 +501,7 @@ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <!-- Created with matplotlib (http://matplotlib.sourceforge.net/) --> -<svg width="%i" height="%i" viewBox="0 0 %i %i" +<svg width="%ipt" height="%ipt" viewBox="0 0 %i %i" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jo...@us...> - 2007-09-07 06:58:04
|
Revision: 3803 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3803&view=rev Author: jouni Date: 2007-09-06 23:58:00 -0700 (Thu, 06 Sep 2007) Log Message: ----------- Clip path support in pdf backend Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2007-09-06 20:13:11 UTC (rev 3802) +++ trunk/matplotlib/CHANGELOG 2007-09-07 06:58:00 UTC (rev 3803) @@ -1,3 +1,5 @@ +2007-09-07 Added clip path support to pdf backend. - JKS + 2007-09-06 Fixed a bug in the embedding of Type 1 fonts in PDF. Now it doesn't crash Preview.app. - JKS Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-09-06 20:13:11 UTC (rev 3802) +++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-09-07 06:58:00 UTC (rev 3803) @@ -64,11 +64,9 @@ # # Some tricky points: # -# 1. The clip rectangle (which could in pdf be an arbitrary path, not -# necessarily a rectangle) can only be widened by popping from the -# state stack. Thus the state must be pushed onto the stack before -# narrowing the rectangle. This is taken care of by -# GraphicsContextPdf. +# 1. The clip path can only be widened by popping from the state +# stack. Thus the state must be pushed onto the stack before narrowing +# the clip path. This is taken care of by GraphicsContextPdf. # # 2. Sometimes it is necessary to refer to something (e.g. font, # image, or extended graphics state, which contains the alpha value) @@ -1072,6 +1070,7 @@ self.writePath(path, fillp) self.endStream() + #@staticmethod def pathBbox(path, lw): path.rewind(0) x, y = [], [] @@ -1086,25 +1085,32 @@ return min(x)-lw, min(y)-lw, max(x)+lw, max(y)+lw pathBbox = staticmethod(pathBbox) - def writePath(self, path, fillp): + #@staticmethod + def pathOperations(path): path.rewind(0) + result = [] while True: - code, xp, yp = path.vertex() + code, x, y = path.vertex() code = code & agg.path_cmd_mask if code == agg.path_cmd_stop: break elif code == agg.path_cmd_move_to: - self.output(xp, yp, Op.moveto) + result += (x, y, Op.moveto) elif code == agg.path_cmd_line_to: - self.output(xp, yp, Op.lineto) + result += (x, y, Op.lineto) elif code == agg.path_cmd_curve3: - pass + pass # TODO elif code == agg.path_cmd_curve4: - pass + pass # TODO elif code == agg.path_cmd_end_poly: - self.output(Op.closepath) + result += (Op.closepath,) else: - print >>sys.stderr, "writePath", code, xp, yp + print >>sys.stderr, "pathOperations", code, xp, yp + return result + pathOperations = staticmethod(pathOperations) + + def writePath(self, path, fillp): + self.output(*self.pathOperations(path)) if fillp: self.output(Op.fill_stroke) else: @@ -1785,49 +1791,64 @@ self.parent = self.parent.parent return [Op.grestore] - def cliprect_cmd(self, cliprect): + def clip_cmd(self, cliprect, clippath): """Set clip rectangle. Calls self.pop() and self.push().""" cmds = [] - while self._cliprect != cliprect and self.parent is not None: + # Pop graphics state until we hit the right one or the stack is empty + while (self._cliprect, self._clippath) != (cliprect, clippath) \ + and self.parent is not None: cmds.extend(self.pop()) - if self._cliprect != cliprect: - cmds.extend(self.push() + - [t for t in cliprect] + - [Op.rectangle, Op.clip, Op.endpath]) + # Unless we hit the right one, set the clip polygon + if (self._cliprect, self._clippath) != (cliprect, clippath): + cmds.append(self.push()) + if self._cliprect != cliprect: + cmds.extend([t for t in cliprect] + + [Op.rectangle, Op.clip, Op.endpath]) + if self._clippath != clippath: + cmds.extend(PdfFile.pathOperations(clippath) + + [Op.clip, Op.endpath]) return cmds commands = ( - ('_cliprect', cliprect_cmd), # must come first since may pop - ('_alpha', alpha_cmd), - ('_capstyle', capstyle_cmd), - ('_fillcolor', fillcolor_cmd), - ('_joinstyle', joinstyle_cmd), - ('_linewidth', linewidth_cmd), - ('_dashes', dash_cmd), - ('_rgb', rgb_cmd), - ('_hatch', hatch_cmd), # must come after fillcolor and rgb + (('_cliprect', '_clippath'), clip_cmd), # must come first since may pop + (('_alpha',), alpha_cmd), + (('_capstyle',), capstyle_cmd), + (('_fillcolor',), fillcolor_cmd), + (('_joinstyle',), joinstyle_cmd), + (('_linewidth',), linewidth_cmd), + (('_dashes',), dash_cmd), + (('_rgb',), rgb_cmd), + (('_hatch',), hatch_cmd), # must come after fillcolor and rgb ) # TODO: _linestyle - def copy_properties(self, other): - """Copy properties of other into self.""" - GraphicsContextBase.copy_properties(self, other) - self._fillcolor = other._fillcolor - def delta(self, other): - """Copy properties of other into self and return PDF commands + """ + Copy properties of other into self and return PDF commands needed to transform self into other. """ cmds = [] - for param, cmd in self.commands: - if getattr(self, param) != getattr(other, param): - cmds.extend(cmd(self, getattr(other, param))) - setattr(self, param, getattr(other, param)) + for params, cmd in self.commands: + ours = [ getattr(self, p) for p in params ] + theirs = [ getattr(other, p) for p in params ] + if ours != theirs: + cmds.extend(cmd(self, *theirs)) + for p in params: + setattr(self, p, getattr(other, p)) return cmds + def copy_properties(self, other): + """ + Copy properties of other into self. + """ + GraphicsContextBase.copy_properties(self, other) + self._fillcolor = other._fillcolor + def finalize(self): - """Make sure every pushed graphics state is popped.""" + """ + Make sure every pushed graphics state is popped. + """ cmds = [] while self.parent is not None: cmds.extend(self.pop()) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jo...@us...> - 2007-09-06 20:13:12
|
Revision: 3802 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3802&view=rev Author: jouni Date: 2007-09-06 13:13:11 -0700 (Thu, 06 Sep 2007) Log Message: ----------- A more careful reading of the pdf spec reveals that Type 1 fonts embedded in pdf files are not actually supposed to be in pfa format, but a similar format where the encrypted part is not encoded in hexadecimal, and where the "fixed-content" part at the end may be omitted. This fixes the problems with Preview.app. Modified Paths: -------------- trunk/matplotlib/API_CHANGES trunk/matplotlib/CHANGELOG trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py trunk/matplotlib/lib/matplotlib/type1font.py Modified: trunk/matplotlib/API_CHANGES =================================================================== --- trunk/matplotlib/API_CHANGES 2007-09-06 19:36:34 UTC (rev 3801) +++ trunk/matplotlib/API_CHANGES 2007-09-06 20:13:11 UTC (rev 3802) @@ -7,9 +7,9 @@ The file type1font.py contains a new class for Type 1 fonts. Currently it simply reads pfa and pfb format files and stores the - data in pfa format, which is the format for embedding Type 1 fonts - in postscript and pdf files. In the future the class might - actually parse the font to allow e.g. subsetting. + data in a way that is suitable for embedding in pdf files. In the + future the class might actually parse the font to allow e.g. + subsetting. FT2Font now supports FT_Attach_File. In practice this can be used to read an afm file in addition to a pfa/pfb file, to get metrics Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2007-09-06 19:36:34 UTC (rev 3801) +++ trunk/matplotlib/CHANGELOG 2007-09-06 20:13:11 UTC (rev 3802) @@ -1,3 +1,6 @@ +2007-09-06 Fixed a bug in the embedding of Type 1 fonts in PDF. + Now it doesn't crash Preview.app. - JKS + 2007-09-06 Refactored image saving code so that all GUI backends can save most image types. See FILETYPES for a matrix of backends and their supported file types. Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-09-06 19:36:34 UTC (rev 3801) +++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-09-06 20:13:11 UTC (rev 3802) @@ -607,13 +607,13 @@ self.writeObject(widthsObject, widths) self.writeObject(fontdescObject, descriptor) - fontdata = type1font.Type1Font(filename) - len1, len2, len3 = fontdata.lengths() + t1font = type1font.Type1Font(filename) self.beginStream(fontfileObject.id, None, - { 'Length1': len1, - 'Length2': len2, - 'Length3': len3 }) - self.currentstream.write(fontdata.data) + { 'Length1': len(t1font.parts[0]), + 'Length2': len(t1font.parts[1]), + 'Length3': 0 }) + self.currentstream.write(t1font.parts[0]) + self.currentstream.write(t1font.parts[1]) self.endStream() return fontdictObject Modified: trunk/matplotlib/lib/matplotlib/type1font.py =================================================================== --- trunk/matplotlib/lib/matplotlib/type1font.py 2007-09-06 19:36:34 UTC (rev 3801) +++ trunk/matplotlib/lib/matplotlib/type1font.py 2007-09-06 20:13:11 UTC (rev 3802) @@ -1,9 +1,10 @@ """ A class representing a Type 1 font. -This version merely allows reading in pfa and pfb files, and stores -the data in pfa format (which can be embedded in PostScript or PDF -files). A more complete class might support subsetting. +This version merely allows reading in pfa and pfb files, stores the +data in pfa format, and allows reading the parts of the data in a +format suitable for embedding in pdf files. A more complete class +might support subsetting. Usage: font = Type1Font(filename) somefile.write(font.data) # writes out font in pfa format @@ -23,9 +24,10 @@ def __init__(self, filename): file = open(filename, 'rb') try: - self._read(file) + data = self._read(file) finally: file.close() + self.parts = self._split(data) def _read(self, file): rawdata = file.read() @@ -33,7 +35,7 @@ self.data = rawdata return - self.data = '' + data = '' while len(rawdata) > 0: if not rawdata.startswith(chr(128)): raise RuntimeError, \ @@ -46,9 +48,9 @@ rawdata = rawdata[6+length:] if type == 1: # ASCII text: include verbatim - self.data += segment + data += segment elif type == 2: # binary data: encode in hexadecimal - self.data += ''.join(['%02x' % ord(char) + data += ''.join(['%02x' % ord(char) for char in segment]) elif type == 3: # end of file break @@ -56,9 +58,11 @@ raise RuntimeError, \ 'Unknown segment type %d in pfb file' % type - def lengths(self): + return data + + def _split(self, data): """ - Compute the lengths of the three parts of a Type 1 font. + Split the Type 1 font into its three main parts. The three parts are: (1) the cleartext part, which ends in a eexec operator; (2) the encrypted part; (3) the fixed part, @@ -66,28 +70,33 @@ lines, a cleartomark operator, and possibly something else. """ - # Cleartext part: just find the eexec and skip the eol char(s) - idx = self.data.index('eexec') + # Cleartext part: just find the eexec and skip whitespace + idx = data.index('eexec') idx += len('eexec') - while self.data[idx] in ('\n', '\r'): + while data[idx] in ' \t\r\n': idx += 1 len1 = idx # Encrypted part: find the cleartomark operator and count # zeros backward - idx = self.data.rindex('cleartomark') - 1 + idx = data.rindex('cleartomark') - 1 zeros = 512 - while zeros and self.data[idx] in ('0', '\n', '\r'): - if self.data[idx] == '0': + while zeros and data[idx] in ('0', '\n', '\r'): + if data[idx] == '0': zeros -= 1 idx -= 1 if zeros: raise RuntimeError, 'Insufficiently many zeros in Type 1 font' - len2 = idx - len1 - len3 = len(self.data) - idx + # Convert encrypted part to binary (if we read a pfb file, we + # may end up converting binary to hexadecimal to binary again; + # but if we read a pfa file, this part is already in hex, and + # I am not quite sure if even the pfb format guarantees that + # it will be in binary). + binary = ''.join([chr(int(data[i:i+2], 16)) + for i in range(len1, idx, 2)]) - return len1, len2, len3 + return data[:len1], binary, data[idx:] if __name__ == '__main__': import sys This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-09-06 19:36:36
|
Revision: 3801 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3801&view=rev Author: mdboom Date: 2007-09-06 12:36:34 -0700 (Thu, 06 Sep 2007) Log Message: ----------- Fix typo Modified Paths: -------------- trunk/matplotlib/FILETYPES Modified: trunk/matplotlib/FILETYPES =================================================================== --- trunk/matplotlib/FILETYPES 2007-09-06 19:36:14 UTC (rev 3800) +++ trunk/matplotlib/FILETYPES 2007-09-06 19:36:34 UTC (rev 3801) @@ -31,7 +31,7 @@ | | | | |pixbuf | | |pixbuf| | | | | | | | | | | | | | |* | | | | | | | +--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+-----+ -|GtkCairo| |emf |ps |cairo +| |cairo |cairo |cairo|agg |svg |cairo| | | +|GtkCairo| |emf |ps |cairo +| |cairo |cairo |cairo|agg |cairo|cairo| | | | | | | |pixbuf | | |* | | | | | | | +--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+-----+ |Paint | | | | | | |libart| | | | | | | This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-09-06 19:36:18
|
Revision: 3800 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3800&view=rev Author: mdboom Date: 2007-09-06 12:36:14 -0700 (Thu, 06 Sep 2007) Log Message: ----------- Fix typo Modified Paths: -------------- trunk/matplotlib/FILETYPES Modified: trunk/matplotlib/FILETYPES =================================================================== --- trunk/matplotlib/FILETYPES 2007-09-06 19:35:00 UTC (rev 3799) +++ trunk/matplotlib/FILETYPES 2007-09-06 19:36:14 UTC (rev 3800) @@ -31,7 +31,7 @@ | | | | |pixbuf | | |pixbuf| | | | | | | | | | | | | | |* | | | | | | | +--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+-----+ -|GtkCairo| |emf |ps |cairo +| |cairo |cairo |cairo|agg |svg |svg | | | +|GtkCairo| |emf |ps |cairo +| |cairo |cairo |cairo|agg |svg |cairo| | | | | | | |pixbuf | | |* | | | | | | | +--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+-----+ |Paint | | | | | | |libart| | | | | | | This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
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. |
From: <md...@us...> - 2007-09-06 18:50:14
|
Revision: 3798 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3798&view=rev Author: mdboom Date: 2007-09-06 11:50:08 -0700 (Thu, 06 Sep 2007) Log Message: ----------- Refactoring of FigureCanvas*.print_figure so that each backend does not have to track all other possible filetypes. This should make it easier to add new filetype backends without updating lots of places. All GUI backends have the same base set of filetypes they support, defined in FigureCanvasBase. Non-GUI backends, for the most part will still only write to their own file format (and not do any switch_backend magic.) All GUI backends (where possible) now generate a list of file patterns for their file chooser dialogs, rather than having hard-coded lists. See FILETYPES for matrix of filetypes supported by each backend. Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/lib/matplotlib/backend_bases.py trunk/matplotlib/lib/matplotlib/backends/backend_agg.py trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py trunk/matplotlib/lib/matplotlib/backends/backend_emf.py trunk/matplotlib/lib/matplotlib/backends/backend_fltkagg.py trunk/matplotlib/lib/matplotlib/backends/backend_gd.py trunk/matplotlib/lib/matplotlib/backends/backend_gdk.py trunk/matplotlib/lib/matplotlib/backends/backend_gtk.py trunk/matplotlib/lib/matplotlib/backends/backend_gtkagg.py trunk/matplotlib/lib/matplotlib/backends/backend_gtkcairo.py trunk/matplotlib/lib/matplotlib/backends/backend_paint.py trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py trunk/matplotlib/lib/matplotlib/backends/backend_ps.py trunk/matplotlib/lib/matplotlib/backends/backend_qt.py trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py trunk/matplotlib/lib/matplotlib/backends/backend_qt4agg.py trunk/matplotlib/lib/matplotlib/backends/backend_qtagg.py trunk/matplotlib/lib/matplotlib/backends/backend_svg.py trunk/matplotlib/lib/matplotlib/backends/backend_template.py trunk/matplotlib/lib/matplotlib/backends/backend_tkagg.py trunk/matplotlib/lib/matplotlib/backends/backend_wx.py trunk/matplotlib/lib/matplotlib/backends/backend_wxagg.py trunk/matplotlib/lib/matplotlib/figure.py Added Paths: ----------- trunk/matplotlib/FILETYPES Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/CHANGELOG 2007-09-06 18:50:08 UTC (rev 3798) @@ -1,3 +1,11 @@ +2007-09-06 Refactored image saving code so that all GUI backends can + save most image types. See FILETYPES for a matrix of + backends and their supported file types. + Backend canvases should no longer write their own print_figure() + method -- instead they should write a print_xxx method for + each filetype they can output and add an entry to their + class-scoped filetypes dictionary. - MGD + 2007-09-05 Fixed Qt version reporting in setupext.py - DSD 2007-09-04 Embedding Type 1 fonts in PDF, and thus usetex support Added: trunk/matplotlib/FILETYPES =================================================================== --- trunk/matplotlib/FILETYPES (rev 0) +++ trunk/matplotlib/FILETYPES 2007-09-06 18:50:08 UTC (rev 3798) @@ -0,0 +1,60 @@ +This is a table of the output formats supported by each backend. + +You may need to expand your terminal window to read this table +correctly. It may be edited with emacs' table mode. + +Each cell specifies the backend that actually handles the file format. +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 | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ + +* 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 Modified: trunk/matplotlib/lib/matplotlib/backend_bases.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backend_bases.py 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backend_bases.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -4,7 +4,7 @@ """ from __future__ import division -import sys, warnings +import os, sys, warnings import numpy as npy import matplotlib.numerix.npyma as ma @@ -12,6 +12,7 @@ import matplotlib.colors as colors import matplotlib.transforms as transforms import matplotlib.widgets as widgets +from matplotlib import rcParams class RendererBase: """An abstract base class to handle drawing/rendering operations @@ -1071,8 +1072,70 @@ (depending on the backend), truncated to integers""" return int(self.figure.bbox.width()), int(self.figure.bbox.height()) + filetypes = { + 'emf': 'Enhanced Metafile', + 'eps': 'Encapsulated Postscript', + 'pdf': 'Portable Document Format', + 'png': 'Portable Network Graphics', + 'ps' : 'Postscript', + 'raw': 'Raw RGBA bitmap', + 'rgb': 'Raw RGBA bitmap', + 'svg': 'Scalable Vector Graphics', + } + + # All of these print_* functions do a lazy import because + # a) otherwise we'd have cyclical imports, since all of these + # classes inherit from FigureCanvasBase + # b) so we don't import a bunch of stuff the user may never use + + def print_emf(self, *args, **kwargs): + from backends.backend_emf import FigureCanvasEMF # lazy import + emf = self.switch_backends(FigureCanvasEMF) + return emf.print_emf(*args, **kwargs) + + def print_eps(self, *args, **kwargs): + from backends.backend_ps import FigureCanvasPS # lazy import + ps = self.switch_backends(FigureCanvasPS) + return ps.print_eps(*args, **kwargs) + + def print_pdf(self, *args, **kwargs): + from backends.backend_pdf import FigureCanvasPdf # lazy import + pdf = self.switch_backends(FigureCanvasPdf) + return pdf.print_pdf(*args, **kwargs) + + def print_png(self, *args, **kwargs): + from backends.backend_agg import FigureCanvasAgg # lazy import + agg = self.switch_backends(FigureCanvasAgg) + return agg.print_png(*args, **kwargs) + + def print_ps(self, *args, **kwargs): + from backends.backend_ps import FigureCanvasPS # lazy import + ps = self.switch_backends(FigureCanvasPS) + return ps.print_ps(*args, **kwargs) + + def print_raw(self, *args, **kwargs): + from backends.backend_agg import FigureCanvasAgg # lazy import + agg = self.switch_backends(FigureCanvasAgg) + return agg.print_raw(*args, **kwargs) + print_bmp = print_rgb = print_raw + + def print_svg(self, *args, **kwargs): + from backends.backend_svg import FigureCanvasSVG # lazy import + svg = self.switch_backends(FigureCanvasSVG) + return svg.print_svg(*args, **kwargs) + + def get_supported_filetypes(self): + return self.filetypes + + def get_supported_filetypes_grouped(self): + groupings = {} + for ext, name in self.filetypes.items(): + groupings.setdefault(name, []).append(ext) + groupings[name].sort() + return groupings + def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w', - orientation='portrait', **kwargs): + orientation='portrait', format=None, **kwargs): """ Render the figure to hardcopy. Set the figure patch face and edge colors. This is useful because some of the GUIs have a gray figure @@ -1085,9 +1148,57 @@ facecolor - the facecolor of the figure edgecolor - the edgecolor of the figure orientation - 'landscape' | 'portrait' (not supported on all backends) + format - when set, forcibly set the file format to save to """ - pass + if format is None: + if cbook.is_string_like(filename): + format = os.path.splitext(filename)[1][1:] + if format is None or format == '': + format = self.get_default_filetype() + if cbook.is_string_like(filename): + filename = filename.rstrip('.') + '.' + format + format = format.lower() + method_name = 'print_%s' % format + if (format not in self.filetypes or + not hasattr(self, method_name)): + formats = self.filetypes.keys() + formats.sort() + raise ValueError( + 'Format "%s" is not supported.\n' + 'Supported formats: ' + '%s.' % (format, ', '.join(formats))) + + if dpi is None: + dpi = rcParams['savefig.dpi'] + + origDPI = self.figure.dpi.get() + origfacecolor = self.figure.get_facecolor() + origedgecolor = self.figure.get_edgecolor() + + self.figure.dpi.set(dpi) + self.figure.set_facecolor(facecolor) + self.figure.set_edgecolor(edgecolor) + + try: + result = getattr(self, method_name)( + filename, + dpi=dpi, + facecolor=facecolor, + edgecolor=edgecolor, + orientation=orientation, + **kwargs) + finally: + self.figure.dpi.set(origDPI) + self.figure.set_facecolor(origfacecolor) + self.figure.set_edgecolor(origedgecolor) + self.figure.set_canvas(self) + + return result + + def get_default_filetype(self): + raise NotImplementedError + def switch_backends(self, FigureCanvasClass): """ instantiate an instance of FigureCanvasClass Modified: trunk/matplotlib/lib/matplotlib/backends/backend_agg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -405,95 +405,15 @@ 'debug-annoying') return self.renderer.buffer_rgba(x,y) - def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w', - orientation='portrait', **kwargs): - """ - Render the figure to hardcopy. Set the figure patch face and - edge colors. This is useful because some of the GUIs have a - gray figure face color background and you'll probably want to - override this on hardcopy + def get_default_filetype(self): + return 'png' - If the extension matches PNG, write a PNG file - - If the extension matches BMP or RAW, write an RGBA bitmap file - - If filename is a fileobject, write png to file object (thus - you can, for example, write the png to stdout - """ - if __debug__: verbose.report('FigureCanvasAgg.print_figure', - 'debug-annoying') - if dpi is None: dpi = matplotlib.rcParams['savefig.dpi'] - - # store the orig figure dpi, color and size information so we - # can restore them later. For image creation alone, this is - # not important since after the print the figure is done. But - # backend_agg may be used as a renderer for a GUI figure, and - # restoring figure props will be important in that case. - # TODO: move most of this functionality into backend_bases - - origDPI = self.figure.dpi.get() - origfacecolor = self.figure.get_facecolor() - origedgecolor = self.figure.get_edgecolor() - - self.figure.dpi.set(dpi) - self.figure.set_facecolor(facecolor) - self.figure.set_edgecolor(edgecolor) - - # render the printed figure + def print_raw(self, filename, *args, **kwargs): self.draw() - - printfunc = None - if not is_string_like(filename): - # assume png and write to fileobject - self.renderer._renderer.write_png(filename) - #pass - else: - # take a look at the extension and choose the print handler - basename, ext = os.path.splitext(filename) - if not len(ext): - ext = '.png' - filename += ext - - ext = ext.lower() - if (ext.find('rgb')>=0 or - ext.find('raw')>=0 or - ext.find('bmp')>=0 ): - # agg doesn't handle unicode yet - self.renderer._renderer.write_rgba(str(filename)) - elif ext.find('png')>=0: - # agg doesn't handle unicode yet - self.renderer._renderer.write_png(str(filename)) - #pass - elif ext.find('svg')>=0: - from backend_svg import FigureCanvasSVG - svg = self.switch_backends(FigureCanvasSVG) - printfunc = svg.print_figure - elif ext.find('ps')>=0 or ext.find('ep')>=0: - from backend_ps import FigureCanvasPS # lazy import - ps = self.switch_backends(FigureCanvasPS) - printfunc = ps.print_figure - elif ext.find('pdf')>=0: - from backend_pdf import FigureCanvasPdf - pdf = self.switch_backends(FigureCanvasPdf) - printfunc = pdf.print_figure - else: - raise IOError('Do not know know to handle extension *%s' % ext) - - if printfunc is not None: - try: - printfunc(filename, dpi, facecolor, edgecolor, orientation, **kwargs) - except: - # restore the original figure properties - self.figure.dpi.set(origDPI) - self.figure.set_facecolor(origfacecolor) - self.figure.set_edgecolor(origedgecolor) - self.figure.set_canvas(self) - raise - - # restore the original figure properties - self.figure.dpi.set(origDPI) - self.figure.set_facecolor(origfacecolor) - self.figure.set_edgecolor(origedgecolor) - self.figure.set_canvas(self) - - + self.get_renderer()._renderer.write_rgba(str(filename)) + print_rgba = print_raw + + def print_png(self, filename, *args, **kwargs): + self.draw() + self.get_renderer()._renderer.write_png(str(filename)) + Modified: trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -488,41 +488,7 @@ class FigureCanvasCairo (FigureCanvasBase): - def print_figure(self, fo, dpi=150, facecolor='w', edgecolor='w', - orientation='portrait', format=None, **kwargs): - if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) - # settings for printing - self.figure.dpi.set(dpi) - self.figure.set_facecolor(facecolor) - self.figure.set_edgecolor(edgecolor) - - if format is None and isinstance (fo, basestring): - # get format from filename extension - format = os.path.splitext(fo)[1][1:] - if format == '': - format = rcParams['cairo.format'] - fo = '%s.%s' % (fo, format) - - if format is not None: - format = format.lower() - - if format == 'png': - self._save_png (fo) - elif format in ('pdf', 'ps', 'svg'): - self._save (fo, format, orientation, **kwargs) - elif format == 'eps': # backend_ps for eps - warnings.warn('eps format is printed by ps backend, not cairo') - from backend_ps import FigureCanvasPS as FigureCanvas - fc = FigureCanvas(self.figure) - fc.print_figure (fo, dpi, facecolor, edgecolor, - orientation, **kwargs) - else: - warnings.warn('Format "%s" is not supported.\n' - 'Supported formats: ' - '%s.' % (format, ', '.join(IMAGE_FORMAT))) - - - def _save_png (self, fobj): + def print_png(self, fobj, *args, **kwargs): width, height = self.get_width_height() renderer = RendererCairo (self.figure.dpi) @@ -532,9 +498,20 @@ self.figure.draw (renderer) surface.write_to_png (fobj) + + def print_pdf(self, fobj, *args, **kwargs): + return self._save(fobj, 'pdf', *args, **kwargs) + def print_ps(self, fobj, *args, **kwargs): + return self._save(fobj, 'ps', *args, **kwargs) - def _save (self, fo, format, orientation, **kwargs): + def print_svg(self, fobj, *args, **kwargs): + return self._save(fobj, 'svg', *args, **kwargs) + + def get_default_filetype(self): + return rcParams['cairo.format'] + + def _save (self, fo, format, **kwargs): # save PDF/PS/SVG orientation = kwargs.get('orientation', 'portrait') Modified: trunk/matplotlib/lib/matplotlib/backends/backend_emf.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_emf.py 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backends/backend_emf.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -599,36 +599,17 @@ """ pass - def print_figure(self, filename, dpi=300, facecolor='w', edgecolor='w', - orientation='portrait', **kwargs): - """ - Render the figure to hardcopy. Set the figure patch face and edge - colors. This is useful because some of the GUIs have a gray figure - face color background and you'll probably want to override this on - hardcopy. - - Following the style of backend_ps and backend_gd - """ - basename, ext = os.path.splitext(filename) - if not ext: - ext = '.emf' - filename += ext - - # set the DPI to this hardcoded value for now, because libEMF - # doesn't allow any changes to the device pixel size (1024 - # pixels per 320 mm) - #dpi=1024.0/320.0*25.4 - #dpi=300 - self.figure.dpi.set(dpi) + filetypes = {'emf': 'Enhanced Metafile'} + + def print_emf(self, filename, dpi=300, **kwargs): width, height = self.figure.get_size_inches() - self.figure.set_facecolor(facecolor) - self.figure.set_edgecolor(edgecolor) - renderer = RendererEMF(filename,width,height,dpi) self.figure.draw(renderer) renderer.save() - + def get_default_filetype(self): + return 'emf' + class FigureManagerEMF(FigureManagerBase): """ Wrap everything up into a window for the pylab interface Modified: trunk/matplotlib/lib/matplotlib/backends/backend_fltkagg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_fltkagg.py 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backends/backend_fltkagg.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -242,17 +242,8 @@ def blit(self,bbox): self.canvas.blit(bbox) - show = draw - def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w', - orientation='portrait', **kwargs): - if dpi is None: dpi = matplotlib.rcParams['savefig.dpi'] - agg = self.switch_backends(FigureCanvasAgg) - agg.print_figure(filename, dpi, facecolor, edgecolor, orientation, - **kwargs) - self.figure.set_canvas(self) - def widget(self): return self.canvas @@ -493,7 +484,23 @@ def save_figure(ptr,base): + filetypes = base.canvas.get_supported_filetypes() + default_filetype = base.canvas.get_default_filetype() + sorted_filetypes = filetypes.items() + sorted_filetypes.sort() + + selected_filter = 0 + filters = [] + for i, (ext, name) in enumerate(sorted_filetypes): + filter = '%s (*.%s)' % (name, ext) + filters.append(filter) + if ext == default_filetype: + selected_filter = i + filters = '\t'.join(filters) + file_chooser=base._fc + file_chooser.filter(filters) + file_chooser.filter_value(selected_filter) file_chooser.show() while file_chooser.visible() : Fltk.Fl.wait() @@ -507,9 +514,10 @@ #start from last directory lastDir = os.path.dirname(fname) file_chooser.directory(lastDir) - + format = sorted_filetypes[file_chooser.filter_value()][0] + try: - base.canvas.print_figure(fname) + base.canvas.print_figure(fname, format=format) except IOError, msg: err = '\n'.join(map(str, msg)) msg = 'Failed to save %s: Error msg was\n\n%s' % ( Modified: trunk/matplotlib/lib/matplotlib/backends/backend_gd.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_gd.py 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backends/backend_gd.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -329,38 +329,15 @@ class FigureCanvasGD(FigureCanvasBase): + filetypes = {'PNG': 'Portable Network Graphics'} - def print_figure(self, filename, dpi=150, facecolor='w', edgecolor='w', - orientation='portrait', **kwargs): - - """ - Render the figure to hardcopy using self.renderer as the - renderer if neccessary - - filename can be a string filename or writable file instance - - """ - - origDPI = self.figure.dpi.get() - origfacecolor = self.figure.get_facecolor() - origedgecolor = self.figure.get_edgecolor() - - self.figure.dpi.set(dpi) - self.figure.set_facecolor(facecolor) - self.figure.set_edgecolor(edgecolor) - + def print_png(self, filename, *args, **kwargs): im = self.draw() - - if is_string_like(filename): - basename, ext = os.path.splitext(filename) - if not len(ext): filename += '.png' - - im.writePng( filename ) - - self.figure.dpi.set(origDPI) - self.figure.set_facecolor(origfacecolor) - self.figure.set_edgecolor(origedgecolor) - + im.writePng(filename) + + def get_default_filetype(self): + return 'png' + def draw(self): """ Draw to a gd image and return the image instance Modified: trunk/matplotlib/lib/matplotlib/backends/backend_gdk.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_gdk.py 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backends/backend_gdk.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -199,26 +199,24 @@ def _draw_mathtext(self, gc, x, y, s, prop, angle): - width, height, descent, fonts, used_characters = self.mathtext_parser.parse( - s, self.dpi.get(), prop) + ox, oy, width, height, descent, font_image, used_characters = \ + self.mathtext_parser.parse(s, self.dpi.get(), prop) if angle==90: width, height = height, width x -= width y -= height - imw, imh, image_str = fonts[0].image_as_str() - N = imw*imh + imw = font_image.get_width() + imh = font_image.get_height() + N = imw * imh # a numpixels by num fonts array - Xall = npy.zeros((N,len(fonts)), npy.uint8) + Xall = npy.zeros((N,1), npy.uint8) + + image_str = font_image.as_str() + Xall[:,0] = npy.fromstring(image_str, npy.uint8) - for i, font in enumerate(fonts): - if angle == 90: - font.get_image().rotate() # <-- Rotate - imw, imh, image_str = font.image_as_str() - Xall[:,i] = npy.fromstring(image_str, npy.uint8) - # get the max alpha at each pixel Xs = npy.amax(Xall,axis=1) @@ -342,8 +340,8 @@ def get_text_width_height_descent(self, s, prop, ismath): if ismath: - width, height, descent, fonts, used_characters = self.mathtext_parser.parse( - s, self.dpi.get(), prop) + ox, oy, width, height, descent, font_image, used_characters = \ + self.mathtext_parser.parse(s, self.dpi.get(), prop) return width, height, descent layout, inkRect, logicalRect = self._get_pango_layout(s, prop) @@ -478,55 +476,28 @@ self._renderer.set_width_height (width, height) self.figure.draw (self._renderer) - def print_figure(self, filename, dpi=150, facecolor='w', edgecolor='w', - orientation='portrait', **kwargs): - root, ext = os.path.splitext(filename) - ext = ext[1:] - if ext == '': - ext = IMAGE_FORMAT_DEFAULT - filename = filename + '.' + ext + filetypes = FigureCanvasBase.filetypes.copy() + filetypes['jpg'] = 'JPEG' + filetypes['jpeg'] = 'JPEG' - self.figure.dpi.set(dpi) - self.figure.set_facecolor(facecolor) - self.figure.set_edgecolor(edgecolor) + def print_jpeg(self, filename, *args, **kwargs): + return self._print_image(filename, 'jpeg') + print_jpg = print_jpeg - ext = ext.lower() - if ext in ('jpg', 'png'): # native printing - width, height = self.get_width_height() - pixmap = gtk.gdk.Pixmap (None, width, height, depth=24) - self._render_figure(pixmap, width, height) + def print_png(self, filename, *args, **kwargs): + return self._print_image(filename, 'png') + + def _print_image(self, filename, format, *args, **kwargs): + width, height = self.get_width_height() + pixmap = gtk.gdk.Pixmap (None, width, height, depth=24) + self._render_figure(pixmap, width, height) - # jpg colors don't match the display very well, png colors match - # better - pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, 0, 8, - width, height) - pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(), - 0, 0, 0, 0, width, height) + # jpg colors don't match the display very well, png colors match + # better + pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, 0, 8, + width, height) + pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(), + 0, 0, 0, 0, width, height) - # pixbuf.save() recognises 'jpeg' not 'jpg' - if ext == 'jpg': ext = 'jpeg' - - pixbuf.save(filename, ext) - - elif ext in ('eps', 'ps', 'svg',): - if ext == 'svg': - from backend_svg import FigureCanvasSVG as FigureCanvas - else: - from backend_ps import FigureCanvasPS as FigureCanvas - - - fc = self.switch_backends(FigureCanvas) - fc.print_figure(filename, dpi, facecolor, edgecolor, orientation, - **kwargs) - elif ext in ('bmp', 'raw', 'rgb',): - - from backend_agg import FigureCanvasAgg as FigureCanvas - fc = self.switch_backends(FigureCanvas) - fc.print_figure(filename, dpi, facecolor, edgecolor, orientation, - **kwargs) - - else: - raise ValueError('Format "%s" is not supported.\nSupported formats are %s.' % - (ext, ', '.join(IMAGE_FORMAT))) - - self.figure.set_canvas(self) + pixbuf.save(filename, format) + Modified: trunk/matplotlib/lib/matplotlib/backends/backend_gtk.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_gtk.py 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backends/backend_gtk.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -36,14 +36,6 @@ # see http://groups.google.com/groups?q=screen+dpi+x11&hl=en&lr=&ie=UTF-8&oe=UTF-8&safe=off&selm=7077.26e81ad5%40swift.cs.tcd.ie&rnum=5 for some info about screen dpi PIXELS_PER_INCH = 96 -# Image formats that this backend supports - for FileChooser and print_figure() -IMAGE_FORMAT = ['bmp', 'eps', 'jpg', 'png', 'ps', 'svg'] -# pdf not ready yet -#IMAGE_FORMAT = ['bmp', 'eps', 'jpg', 'png', 'pdf', 'ps', 'svg'] -IMAGE_FORMAT.sort() -IMAGE_FORMAT_DEFAULT = 'png' - - cursord = { cursors.MOVE : gdk.Cursor(gdk.FLEUR), cursors.HAND : gdk.Cursor(gdk.HAND2), @@ -344,105 +336,44 @@ self._pixmap, x, y, x, y, w, h) return False # finish event propagation? + filetypes = FigureCanvasBase.filetypes.copy() + filetypes['jpg'] = 'JPEG' + filetypes['jpeg'] = 'JPEG' + filetypes['png'] = 'Portable Network Graphics' - def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w', - orientation='portrait', **kwargs): - # TODO - use gdk/cairo/agg print_figure? - if dpi is None: dpi = matplotlib.rcParams['savefig.dpi'] - root, ext = os.path.splitext(filename) - ext = ext[1:] - if ext == '': - ext = IMAGE_FORMAT_DEFAULT - filename = filename + '.' + ext + def print_jpeg(self, filename, *args, **kwargs): + return self._print_image(filename, 'jpeg') + print_jpg = print_jpeg - # save figure settings - origDPI = self.figure.dpi.get() - origfacecolor = self.figure.get_facecolor() - origedgecolor = self.figure.get_edgecolor() - origWIn, origHIn = self.figure.get_size_inches() + def print_png(self, filename, *args, **kwargs): + return self._print_image(filename, 'png') + def _print_image(self, filename, format): if self.flags() & gtk.REALIZED == 0: # for self.window(for pixmap) and has a side effect of altering # figure width,height (via configure-event?) gtk.DrawingArea.realize(self) - - self.figure.dpi.set(dpi) - self.figure.set_facecolor(facecolor) - self.figure.set_edgecolor(edgecolor) - - ext = ext.lower() - if ext in ('jpg', 'png'): # native printing - width, height = self.get_width_height() - pixmap = gdk.Pixmap (self.window, width, height) - self._renderer.set_pixmap (pixmap) - self._render_figure(pixmap, width, height) - - # jpg colors don't match the display very well, png colors match - # better - pixbuf = gdk.Pixbuf(gdk.COLORSPACE_RGB, 0, 8, width, height) - pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(), + + width, height = self.get_width_height() + pixmap = gdk.Pixmap (self.window, width, height) + self._renderer.set_pixmap (pixmap) + self._render_figure(pixmap, width, height) + + # jpg colors don't match the display very well, png colors match + # better + pixbuf = gdk.Pixbuf(gdk.COLORSPACE_RGB, 0, 8, width, height) + pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(), 0, 0, 0, 0, width, height) - # pixbuf.save() recognises 'jpeg' not 'jpg' - if ext == 'jpg': ext = 'jpeg' - try: - pixbuf.save(filename, ext) - except gobject.GError, exc: - error_msg_gtk('Save figure failure:\n%s' % (exc,), parent=self) + try: + pixbuf.save(filename, format) + except gobject.GError, exc: + error_msg_gtk('Save figure failure:\n%s' % (exc,), parent=self) - elif ext in ('eps', 'ps', 'svg',): - if ext == 'svg': - from backend_svg import FigureCanvasSVG as FigureCanvas - else: - from backend_ps import FigureCanvasPS as FigureCanvas + def get_default_filetype(self): + return 'png' - try: - fc = self.switch_backends(FigureCanvas) - fc.print_figure(filename, dpi, facecolor, edgecolor, - orientation, **kwargs) - except IOError, exc: - error_msg_gtk("Save figure failure:\n%s: %s" % - (exc.filename, exc.strerror), parent=self) - except Exception, exc: - error_msg_gtk("Save figure failure:\n%s" % exc, parent=self) - - elif ext in ('bmp', 'raw', 'rgb',): - try: - from backend_agg import FigureCanvasAgg as FigureCanvas - except: - error_msg_gtk('Save figure failure:\n' - 'Agg must be installed to save as bmp, raw and rgb', - parent=self) - else: - fc = self.switch_backends(FigureCanvas) - fc.print_figure(filename, dpi, facecolor, edgecolor, - orientation, **kwargs) - - elif ext in ('pdf',): - try: - from backend_cairo import FigureCanvasCairo as FigureCanvas - except: - error_msg_gtk('Save figure failure:\n' - 'Cairo must be installed to save as pdf', - parent=self) - else: - fc = self.switch_backends(FigureCanvas) - fc.print_figure(filename, dpi, facecolor, edgecolor, - orientation, **kwargs) - - else: - error_msg_gtk('Format "%s" is not supported.\nSupported formats are %s.' % - (ext, ', '.join(IMAGE_FORMAT)), - parent=self) - - # restore figure settings - self.figure.dpi.set(origDPI) - self.figure.set_facecolor(origfacecolor) - self.figure.set_edgecolor(origedgecolor) - self.figure.set_size_inches(origWIn, origHIn) - self.figure.set_canvas(self) - - + class FigureManagerGTK(FigureManagerBase): """ Public attributes @@ -685,14 +616,20 @@ self.show_all() - self.fileselect = FileChooserDialog(title='Save the figure', - parent=self.win,) + self.fileselect = FileChooserDialog( + title='Save the figure', + parent=self.win, + filetypes=self.canvas.get_supported_filetypes(), + default_filetype=self.canvas.get_default_filetype()) def save_figure(self, button): - fname = self.fileselect.get_filename_from_user() + fname, format = self.fileselect.get_filename_from_user() if fname: - self.canvas.print_figure(fname) + try: + self.canvas.print_figure(fname, format=format) + except Exception, e: + error_msg_gtk(str(e), parent=self) def configure_subplots(self, button): toolfig = Figure(figsize=(6,3)) @@ -777,8 +714,11 @@ if gtk.pygtk_version >= (2,4,0): self._create_toolitems_2_4() self.update = self._update_2_4 - self.fileselect = FileChooserDialog(title='Save the figure', - parent=self.win,) + self.fileselect = FileChooserDialog( + title='Save the figure', + parent=self.win, + formats=self.canvas.get_supported_filetypes(), + default_type=self.canvas.get_default_filetype()) else: self._create_toolitems_2_2() self.update = self._update_2_2 @@ -999,35 +939,13 @@ def save_figure(self, button): - fname = self.fileselect.get_filename_from_user() + fname, format = self.fileselect.get_filename_from_user() if fname: - self.canvas.print_figure(fname) + try: + self.canvas.print_figure(fname, format=format) + except Exception, e: + error_msg_gtk(str(e), parent=self) - -class FileSelection(gtk.FileSelection): - """GTK+ 2.2 and lower file selector which remembers the last - file/directory selected - """ - def __init__(self, path=None, title='Select a file', parent=None): - super(FileSelection, self).__init__(title) - - if path: self.path = path - else: self.path = os.getcwd() + os.sep - - if parent: self.set_transient_for(parent) - - def get_filename_from_user(self, path=None, title=None): - if path: self.path = path - if title: self.set_title(title) - self.set_filename(self.path) - - filename = None - if self.run() == gtk.RESPONSE_OK: - self.path = filename = self.get_filename() - self.hide() - return filename - - if gtk.pygtk_version >= (2,4,0): class FileChooserDialog(gtk.FileChooserDialog): """GTK+ 2.4 file selector which remembers the last file/directory @@ -1040,6 +958,8 @@ buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK), path = None, + filetypes = [], + default_filetype = None ): super (FileChooserDialog, self).__init__ (title, parent, action, buttons) @@ -1049,10 +969,10 @@ # create an extra widget to list supported image formats self.set_current_folder (path) - self.set_current_name ('image.' + IMAGE_FORMAT_DEFAULT) + self.set_current_name ('image.' + default_filetype) hbox = gtk.HBox (spacing=10) - hbox.pack_start (gtk.Label ("Image Format:"), expand=False) + hbox.pack_start (gtk.Label ("File Format:"), expand=False) liststore = gtk.ListStore(gobject.TYPE_STRING) cbox = gtk.ComboBox(liststore) @@ -1061,21 +981,27 @@ cbox.add_attribute(cell, 'text', 0) hbox.pack_start (cbox) - for item in IMAGE_FORMAT: - cbox.append_text (item) - cbox.set_active (IMAGE_FORMAT.index (IMAGE_FORMAT_DEFAULT)) - self.ext = IMAGE_FORMAT_DEFAULT + self.filetypes = filetypes + self.sorted_filetypes = filetypes.items() + self.sorted_filetypes.sort() + default = 0 + for i, (ext, name) in enumerate(self.sorted_filetypes): + cbox.append_text ("%s (*.%s)" % (name, ext)) + if ext == default_filetype: + default = i + cbox.set_active(default) + self.ext = default_filetype def cb_cbox_changed (cbox, data=None): """File extension changed""" head, filename = os.path.split(self.get_filename()) root, ext = os.path.splitext(filename) ext = ext[1:] - new_ext = IMAGE_FORMAT[cbox.get_active()] + new_ext = self.sorted_filetypes[cbox.get_active()][0] self.ext = new_ext - if ext in IMAGE_FORMAT: - filename = filename.replace(ext, new_ext) + if ext in self.filetypes: + filename = root + '.' + new_ext elif ext == '': filename = filename.rstrip('.') + '.' + new_ext @@ -1091,24 +1017,40 @@ if self.run() != gtk.RESPONSE_OK: break filename = self.get_filename() - root, ext = os.path.splitext (filename) - ext = ext[1:] - if ext == '': - ext = self.ext - filename += '.' + ext + break + + self.hide() + return filename, self.ext +else: + class FileSelection(gtk.FileSelection): + """GTK+ 2.2 and lower file selector which remembers the last + file/directory selected + """ + def __init__(self, path=None, title='Select a file', parent=None): + super(FileSelection, self).__init__(title) - if ext in IMAGE_FORMAT: - self.path = filename - break - else: - error_msg_gtk ('Image format "%s" is not supported' % ext, - parent=self) - self.set_current_name (os.path.split(root)[1] + '.' + - self.ext) + if path: self.path = path + else: self.path = os.getcwd() + os.sep + if parent: self.set_transient_for(parent) + + def get_filename_from_user(self, path=None, title=None): + if path: self.path = path + if title: self.set_title(title) + self.set_filename(self.path) + + filename = None + if self.run() == gtk.RESPONSE_OK: + self.path = filename = self.get_filename() self.hide() - return filename + ext = None + if filename is not None: + ext = os.path.splitext(filename)[1] + if ext.startswith('.'): + ext = ext[1:] + return filename, ext + class DialogLineprops: """ Modified: trunk/matplotlib/lib/matplotlib/backends/backend_gtkagg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_gtkagg.py 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backends/backend_gtkagg.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -45,7 +45,9 @@ if DEBUG: print 'backend_gtkagg.new_figure_manager done' class FigureCanvasGTKAgg(FigureCanvasGTK, FigureCanvasAgg): - + filetypes = FigureCanvasGTK.filetypes.copy() + filetypes.update(FigureCanvasAgg.filetypes) + def configure_event(self, widget, event=None): if DEBUG: print 'FigureCanvasGTKAgg.configure_event' @@ -95,34 +97,7 @@ 0, 0, 0, 0, w, h) if DEBUG: print 'FigureCanvasGTKAgg.done' - def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w', - orientation='portrait', **kwargs): - if DEBUG: print 'FigureCanvasGTKAgg.print_figure' - # delete the renderer to prevent improper blitting after print - if dpi is None: dpi = matplotlib.rcParams['savefig.dpi'] - root, ext = os.path.splitext(filename) - ext = ext.lower()[1:] - if ext == 'jpg': - FigureCanvasGTK.print_figure(self, filename, dpi, facecolor, - edgecolor, orientation, **kwargs) - - else: - agg = self.switch_backends(FigureCanvasAgg) - try: - agg.print_figure(filename, dpi, facecolor, edgecolor, - orientation, **kwargs) - except IOError, msg: - error_msg_gtk('Failed to save\nError message: %s'%(msg,), self) - except: - self.figure.set_canvas(self) - raise - - self.figure.set_canvas(self) - if DEBUG: print 'FigureCanvasGTKAgg.print_figure done' - - - """\ Traceback (most recent call last): File "/home/titan/johnh/local/lib/python2.3/site-packages/matplotlib/backends/backend_gtk.py", line 304, in expose_event Modified: trunk/matplotlib/lib/matplotlib/backends/backend_gtkcairo.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_gtkcairo.py 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backends/backend_gtkcairo.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -39,7 +39,10 @@ self.ctx.save() # restore, save - when call new_gc() -class FigureCanvasGTKCairo(FigureCanvasGTK): +class FigureCanvasGTKCairo(backend_cairo.FigureCanvasCairo, FigureCanvasGTK): + filetypes = FigureCanvasGTK.filetypes.copy() + filetypes.update(backend_cairo.FigureCanvasCairo.filetypes) + def _renderer_init(self): """Override to use cairo (rather than GDK) renderer""" if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) Modified: trunk/matplotlib/lib/matplotlib/backends/backend_paint.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_paint.py 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backends/backend_paint.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -240,31 +240,14 @@ self.figure.draw(renderer) return renderer - def print_figure(self, filename, dpi=150, facecolor='w', edgecolor='w', - orientation='portrait, '**kwargs): - - """ - Render the figure to hardcopy using self.renderer as the - renderer if neccessary - """ - origDPI = self.figure.dpi.get() - origfacecolor = self.figure.get_facecolor() - origedgecolor = self.figure.get_edgecolor() - - self.figure.dpi.set(dpi) - self.figure.set_facecolor(facecolor) - self.figure.set_edgecolor(edgecolor) - + filetypes = {'png': 'Portable Network Graphics'} + + def print_png(self, filename, *args, **kwargs): renderer = self.draw() - - basename, ext = os.path.splitext(filename) - if not len(ext): filename += '.png' renderer.image.write_png(filename) - # now restore the old figure params - self.figure.set_facecolor(origfacecolor) - self.figure.set_edgecolor(origedgecolor) - self.figure.dpi.set(origDPI) + def get_default_filetype(self): + return 'png' ######################################################################## # Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -1869,25 +1869,15 @@ def draw(self): pass - def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w', - orientation='portrait', **kwargs): - """ - Render the figure to hardcopy. Set the figure patch face and edge - colors. This is useful because some of the GUIs have a gray figure - face color background and you'll probably want to override this on - hardcopy. - - orientation - only currently applies to PostScript printing. - """ - self.figure.dpi.set(72) # ignore the dpi kwarg - self.figure.set_facecolor(facecolor) - self.figure.set_edgecolor(edgecolor) + filetypes = {'pdf': 'Portable Document Format'} + + def get_default_filetype(self): + return 'pdf' + + def print_pdf(self, filename, **kwargs): + dpi = kwargs.get('dpi', None) + self.figure.set_dpi(72) # Override the dpi kwarg width, height = self.figure.get_size_inches() - - basename, ext = os.path.splitext(filename) - if ext == '': - filename += '.pdf' - file = PdfFile(width, height, filename) renderer = RendererPdf(file, dpi) self.figure.draw(renderer) Modified: trunk/matplotlib/lib/matplotlib/backends/backend_ps.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -960,8 +960,46 @@ def draw(self): pass - def print_figure(self, outfile, dpi=72, facecolor='w', edgecolor='w', - orientation='portrait', papertype=None): + filetypes = {'ps' : 'Postscript', + 'eps' : 'Encapsulated Postscript'} + + def get_default_filetype(self): + return 'ps' + + def print_ps(self, outfile, *args, **kwargs): + return self._print_ps(outfile, 'ps', *args, **kwargs) + + def print_eps(self, outfile, *args, **kwargs): + return self._print_ps(outfile, 'eps', *args, **kwargs) + + def _print_ps(self, outfile, format, *args, **kwargs): + papertype = kwargs.get("papertype", rcParams['ps.papersize']) + papertype = papertype.lower() + if papertype == 'auto': + pass + elif papertype not in papersize: + raise RuntimeError( '%s is not a valid papertype. Use one \ + of %s'% (papertype, ', '.join( papersize.keys() )) ) + + orientation = kwargs.get("orientation", "portrait").lower() + if orientation == 'landscape': isLandscape = True + elif orientation == 'portrait': isLandscape = False + else: raise RuntimeError('Orientation must be "portrait" or "landscape"') + + self.figure.set_dpi(72) # Override the dpi kwarg + dpi = kwargs.get("dpi", 72) + facecolor = kwargs.get("facecolor", "w") + edgecolor = kwargs.get("edgecolor", "w") + + if rcParams['text.usetex']: + self._print_figure_tex(outfile, format, dpi, facecolor, edgecolor, + orientation, isLandscape, papertype) + else: + self._print_figure(outfile, format, dpi, facecolor, edgecolor, + orientation, isLandscape, papertype) + + def _print_figure(self, outfile, format, dpi=72, facecolor='w', edgecolor='w', + orientation='portrait', isLandscape=False, papertype=None): """ Render the figure to hardcopy. Set the figure patch face and edge colors. This is useful because some of the GUIs have a @@ -975,176 +1013,137 @@ If outfile is a file object, a stand-alone PostScript file is written into this file object. """ - if not papertype: papertype = rcParams['ps.papersize'] - papertype = papertype.lower() - if papertype == 'auto': pass - elif not papersize.has_key(papertype): - raise RuntimeError( '%s is not a valid papertype. Use one \ - of %s'% (papertype, ', '.join( papersize.keys() )) ) + isEPSF = format == 'eps' + title = outfile - orientation = orientation.lower() - if orientation == 'landscape': isLandscape = True - elif orientation == 'portrait': isLandscape = False - else: raise RuntimeError('Orientation must be "portrait" or "landscape"') + # write to a temp file, we'll move it to outfile when done + tmpfile = os.path.join(gettempdir(), md5.md5(outfile).hexdigest()) + fh = file(tmpfile, 'w') - self.figure.dpi.set(72) # ignore the dpi kwarg + # find the appropriate papertype + width, height = self.figure.get_size_inches() + if papertype == 'auto': + if isLandscape: papertype = _get_papertype(height, width) + else: papertype = _get_papertype(width, height) - if rcParams['text.usetex']: - # Let's keep the usetex stuff seperate from the generic postscript - self._print_figure_tex(outfile, dpi, facecolor, edgecolor, - orientation, papertype) - else: - if isinstance(outfile, file): - # assume plain PostScript and write to fileobject - basename = outfile.name - ext = '.ps' - title = None - else: - basename, ext = os.path.splitext(outfile) - if not ext: - ext = '.ps' - outfile += ext - isEPSF = ext.lower().startswith('.ep') - title = outfile + if isLandscape: paperHeight, paperWidth = papersize[papertype] + else: paperWidth, paperHeight = papersize[papertype] - # write to a temp file, we'll move it to outfile when done - tmpfile = os.path.join(gettempdir(), md5.md5(basename).hexdigest()) - fh = file(tmpfile, 'w') + if rcParams['ps.usedistiller'] and not papertype == 'auto': + # distillers will improperly clip eps files if the pagesize is + # too small + if width>paperWidth or height>paperHeight: + if isLandscape: + papertype = _get_papertype(height, width) + paperHeight, paperWidth = papersize[papertype] + else: + papertype = _get_papertype(width, height) + paperWidth, paperHeight = papersize[papertype] - # find the appropriate papertype - width, height = self.figure.get_size_inches() - if papertype == 'auto': - if isLandscape: papertype = _get_papertype(height, width) - else: papertype = _get_papertype(width, height) + # center the figure on the paper + xo = 72*0.5*(paperWidth - width) + yo = 72*0.5*(paperHeight - height) - if isLandscape: paperHeight, paperWidth = papersize[papertype] - else: paperWidth, paperHeight = papersize[papertype] + l, b, w, h = self.figure.bbox.get_bounds() + llx = xo + lly = yo + urx = llx + w + ury = lly + h + rotation = 0 + if isLandscape: + llx, lly, urx, ury = lly, llx, ury, urx + xo, yo = 72*paperHeight - yo, xo + rotation = 90 + bbox = (llx, lly, urx, ury) - if rcParams['ps.usedistiller'] and not papertype == 'auto': - # distillers will improperly clip eps files if the pagesize is - # too small - if width>paperWidth or height>paperHeight: - if isLandscape: - papertype = _get_papertype(height, width) - paperHeight, paperWidth = papersize[papertype] - else: - papertype = _get_papertype(width, height) - paperWidth, paperHeight = papersize[papertype] + # generate PostScript code for the figure and store it in a string + origfacecolor = self.figure.get_facecolor() + origedgecolor = self.figure.get_edgecolor() + self.figure.set_facecolor(facecolor) + self.figure.set_edgecolor(edgecolor) - # center the figure on the paper - xo = 72*0.5*(paperWidth - width) - yo = 72*0.5*(paperHeight - height) + self._pswriter = StringIO() + renderer = RendererPS(width, height, self._pswriter, dpi=dpi) + self.figure.draw(renderer) - l, b, w, h = self.figure.bbox.get_bounds() - llx = xo - lly = yo - urx = llx + w - ury = lly + h - rotation = 0 - if isLandscape: - llx, lly, urx, ury = lly, llx, ury, urx - xo, yo = 72*paperHeight - yo, xo - rotation = 90 - bbox = (llx, lly, urx, ury) + self.figure.set_facecolor(origfacecolor) + self.figure.set_edgecolor(origedgecolor) - # generate PostScript code for the figure and store it in a string - origfacecolor = self.figure.get_facecolor() - origedgecolor = self.figure.get_edgecolor() - self.figure.set_facecolor(facecolor) - self.figure.set_edgecolor(edgecolor) + # write the PostScript headers + if isEPSF: print >>fh, "%!PS-Adobe-3.0 EPSF-3.0" + else: print >>fh, "%!PS-Adobe-3.0" + if title: print >>fh, "%%Title: "+title + print >>fh, ("%%Creator: matplotlib version " + +__version__+", http://matplotlib.sourceforge... [truncated message content] |
From: <jo...@us...> - 2007-09-06 14:46:56
|
Revision: 3797 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3797&view=rev Author: jouni Date: 2007-09-06 07:46:49 -0700 (Thu, 06 Sep 2007) Log Message: ----------- Small bugfix in pdf backend Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-09-06 12:10:07 UTC (rev 3796) +++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-09-06 14:46:49 UTC (rev 3797) @@ -1435,9 +1435,8 @@ return x+x1, y+y1 else: def mytrans(x1, y1, x=x, y=y, a=angle / 180.0 * pi): - x1 = x + cos(a)*x1 - sin(a)*y1 - y1 = y + sin(a)*x1 + cos(a)*y1 - return x1, y1 + return x + cos(a)*x1 - sin(a)*y1, \ + y + sin(a)*x1 + cos(a)*y1 self.check_gc(gc, gc._rgb) self.file.output(Op.begin_text) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-09-06 12:12:48
|
Revision: 3796 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3796&view=rev Author: mdboom Date: 2007-09-06 05:10:07 -0700 (Thu, 06 Sep 2007) Log Message: ----------- Undoing last commit. I don't understand why a gray8 buffer is four bytes per pixel, but there's a lot I don't understand about Agg. Modified Paths: -------------- trunk/matplotlib/src/_backend_agg.cpp Modified: trunk/matplotlib/src/_backend_agg.cpp =================================================================== --- trunk/matplotlib/src/_backend_agg.cpp 2007-09-06 12:09:08 UTC (rev 3795) +++ trunk/matplotlib/src/_backend_agg.cpp 2007-09-06 12:10:07 UTC (rev 3796) @@ -247,7 +247,7 @@ renderingBuffer = new agg::rendering_buffer; renderingBuffer->attach(pixBuffer, width, height, stride); - alphaBuffer = new agg::int8u[width*height]; + alphaBuffer = new agg::int8u[NUMBYTES]; alphaMaskRenderingBuffer = new agg::rendering_buffer; alphaMaskRenderingBuffer->attach(alphaBuffer, width, height, stride); alphaMask = new alpha_mask_type(*alphaMaskRenderingBuffer); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-09-06 12:10:58
|
Revision: 3795 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3795&view=rev Author: mdboom Date: 2007-09-06 05:09:08 -0700 (Thu, 06 Sep 2007) Log Message: ----------- Fix set_name call. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/font_manager.py Modified: trunk/matplotlib/lib/matplotlib/font_manager.py =================================================================== --- trunk/matplotlib/lib/matplotlib/font_manager.py 2007-09-05 21:50:01 UTC (rev 3794) +++ trunk/matplotlib/lib/matplotlib/font_manager.py 2007-09-06 12:09:08 UTC (rev 3795) @@ -637,7 +637,7 @@ self.__props.__dict__.update(_init) return - if isinstance(family, str): + if is_string_like(family): # Treat family as a fontconfig pattern if it is the only # parameter provided. if (style is None and @@ -720,8 +720,11 @@ if family is None: self.__props.__dict__.pop('family', None) else: + if is_string_like(family): + family = [family] self.__props.family = family - + set_name = set_family + def set_style(self, style): """Set the font style. Values are: normal, italic or oblique.""" if style is None: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pki...@us...> - 2007-09-05 21:50:07
|
Revision: 3794 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3794&view=rev Author: pkienzle Date: 2007-09-05 14:50:01 -0700 (Wed, 05 Sep 2007) Log Message: ----------- Fix get_xyz_where() typo so spy_demos works again Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/mlab.py Modified: trunk/matplotlib/lib/matplotlib/mlab.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mlab.py 2007-09-05 21:40:41 UTC (rev 3793) +++ trunk/matplotlib/lib/matplotlib/mlab.py 2007-09-05 21:50:01 UTC (rev 3794) @@ -949,7 +949,7 @@ where x and y are the indices into Z and z are the values of Z at those indices. x,y,z are 1D arrays """ - X,Y = npy.indices(z.shape) + X,Y = npy.indices(Z.shape) return X[Cond], Y[Cond], Z[Cond] def get_sparse_matrix(M,N,frac=0.1): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pki...@us...> - 2007-09-05 21:40:44
|
Revision: 3793 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3793&view=rev Author: pkienzle Date: 2007-09-05 14:40:41 -0700 (Wed, 05 Sep 2007) Log Message: ----------- Convert to numpy Modified Paths: -------------- trunk/matplotlib/examples/quadmesh_demo.py trunk/matplotlib/examples/simple3d.py Modified: trunk/matplotlib/examples/quadmesh_demo.py =================================================================== --- trunk/matplotlib/examples/quadmesh_demo.py 2007-09-05 19:38:27 UTC (rev 3792) +++ trunk/matplotlib/examples/quadmesh_demo.py 2007-09-05 21:40:41 UTC (rev 3793) @@ -4,23 +4,21 @@ with some restrictions. """ -from matplotlib.mlab import linspace, meshgrid -import matplotlib.numerix as nx +import numpy as nx from pylab import figure,show -import matplotlib.numerix.ma as ma from matplotlib import cm, colors n = 56 -x = linspace(-1.5,1.5,n) -X,Y = meshgrid(x,x); +x = nx.linspace(-1.5,1.5,n) +X,Y = nx.meshgrid(x,x); Qx = nx.cos(Y) - nx.cos(X) Qz = nx.sin(Y) + nx.sin(X) Qx = (Qx + 1.1) Z = nx.sqrt(X**2 + Y**2)/5; -Z = (Z - nx.mlab.amin(Z)) / (nx.mlab.amax(Z) - nx.mlab.amin(Z)) +Z = (Z - nx.amin(Z)) / (nx.amax(Z) - nx.amin(Z)) # The color array can include masked values: -Zm = ma.masked_where(nx.fabs(Qz) < 0.5*nx.mlab.amax(Qz), Z) +Zm = nx.ma.masked_where(nx.fabs(Qz) < 0.5*nx.amax(Qz), Z) fig = figure() Modified: trunk/matplotlib/examples/simple3d.py =================================================================== --- trunk/matplotlib/examples/simple3d.py 2007-09-05 19:38:27 UTC (rev 3792) +++ trunk/matplotlib/examples/simple3d.py 2007-09-05 21:40:41 UTC (rev 3793) @@ -1,11 +1,6 @@ #!/usr/bin/env python -import matplotlib -matplotlib.rcParams['numerix'] = 'numpy' -import numpy as np -from numpy import arange, cos, linspace, ones, pi, sin -import matplotlib.numerix as nx -from matplotlib.numerix import outerproduct +from numpy import arange, cos, linspace, ones, pi, sin, outer import pylab import matplotlib.axes3d as axes3d @@ -20,9 +15,9 @@ u = arange(0, 2*pi+(delta*2), delta*2) v = arange(0, pi+delta, delta) -x = outerproduct(cos(u),sin(v)) -y = outerproduct(sin(u),sin(v)) -z = outerproduct(ones(u.shape), cos(v)) +x = outer(cos(u),sin(v)) +y = outer(sin(u),sin(v)) +z = outer(ones(u.shape), cos(v)) #ax3d.plot_wireframe(x,y,z) surf = ax3d.plot_surface(x, y, z) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ds...@us...> - 2007-09-05 19:38:31
|
Revision: 3792 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3792&view=rev Author: dsdale Date: 2007-09-05 12:38:27 -0700 (Wed, 05 Sep 2007) Log Message: ----------- fixed some minor bugs related to mathtext: text markup in new config, uncommented print statement Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/config/mplconfig.py trunk/matplotlib/lib/matplotlib/mathtext.py Modified: trunk/matplotlib/lib/matplotlib/config/mplconfig.py =================================================================== --- trunk/matplotlib/lib/matplotlib/config/mplconfig.py 2007-09-05 16:44:31 UTC (rev 3791) +++ trunk/matplotlib/lib/matplotlib/config/mplconfig.py 2007-09-05 19:38:27 UTC (rev 3792) @@ -337,7 +337,6 @@ 'text.latex.unicode' : (self.tconfig.text.latex, 'unicode'), 'text.latex.preamble' : (self.tconfig.text.latex, 'preamble'), 'text.dvipnghack' : (self.tconfig.text.latex, 'dvipnghack'), - 'text.markup' : (self.tconfig.text, 'markup'), 'mathtext.cal' : (self.tconfig.mathtext, 'cal'), 'mathtext.rm' : (self.tconfig.mathtext, 'rm'), Modified: trunk/matplotlib/lib/matplotlib/mathtext.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mathtext.py 2007-09-05 16:44:31 UTC (rev 3791) +++ trunk/matplotlib/lib/matplotlib/mathtext.py 2007-09-05 19:38:27 UTC (rev 3792) @@ -355,7 +355,7 @@ def get_results(self, box): ship(0, -self.depth, box) - print self.depth + #print self.depth return (self.width, self.height + self.depth, self.depth, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-09-05 16:44:34
|
Revision: 3791 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3791&view=rev Author: mdboom Date: 2007-09-05 09:44:31 -0700 (Wed, 05 Sep 2007) Log Message: ----------- Bugfix #1671570: Invalid CSS 2 styles in SVG output Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backends/backend_svg.py Modified: trunk/matplotlib/lib/matplotlib/backends/backend_svg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2007-09-05 15:47:35 UTC (rev 3790) +++ trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2007-09-05 16:44:31 UTC (rev 3791) @@ -246,7 +246,7 @@ thetext = escape_xml_text(s) fontfamily = font.family_name - fontstyle = font.style_name + fontstyle = prop.get_style() fontsize = prop.get_size_in_points() color = rgb2hex(gc.get_rgb()) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-09-05 15:47:40
|
Revision: 3790 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3790&view=rev Author: mdboom Date: 2007-09-05 08:47:35 -0700 (Wed, 05 Sep 2007) Log Message: ----------- Fix some recent reference counting bugs in ft2font.cpp (Thanks to Paul Kienzle). Modified Paths: -------------- trunk/matplotlib/src/ft2font.cpp Modified: trunk/matplotlib/src/ft2font.cpp =================================================================== --- trunk/matplotlib/src/ft2font.cpp 2007-09-05 15:28:21 UTC (rev 3789) +++ trunk/matplotlib/src/ft2font.cpp 2007-09-05 15:47:35 UTC (rev 3790) @@ -743,8 +743,7 @@ { _VERBOSE("FT2Font::~FT2Font"); - if(image) - Py::_XDECREF(image); + Py_XDECREF(image); FT_Done_Face ( face ); for (size_t i=0; i<glyphs.size(); i++) { @@ -781,7 +780,7 @@ _VERBOSE("FT2Font::clear"); args.verify_length(0); - delete image; + Py_XDECREF(image); image = NULL; angle = 0.0; @@ -1037,7 +1036,7 @@ if ( (size_t)num >= gms.size()) throw Py::ValueError("Glyph index out of range"); - //todo: refcount? + Py_INCREF(gms[num]); return Py::asObject(gms[num]); } @@ -1667,8 +1666,11 @@ Py::Object FT2Font::get_image (const Py::Tuple &args) { args.verify_length(0); - Py_INCREF(image); - return Py::asObject(image); + if (image) { + Py_XINCREF(image); + return Py::asObject(image); + } + throw Py::RuntimeError("You must call .set_text() before .get_image()"); } char FT2Font::attach_file__doc__ [] = This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-09-05 15:28:23
|
Revision: 3789 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3789&view=rev Author: mdboom Date: 2007-09-05 08:28:21 -0700 (Wed, 05 Sep 2007) Log Message: ----------- Bugfix #1767997: Zoom to rectangle and home, previous, next buttons The "original" position of the axes was not being saved/restored in the history stack. This patch saves both "original" and "active" position. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backend_bases.py Modified: trunk/matplotlib/lib/matplotlib/backend_bases.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backend_bases.py 2007-09-05 15:23:29 UTC (rev 3788) +++ trunk/matplotlib/lib/matplotlib/backend_bases.py 2007-09-05 15:28:21 UTC (rev 3789) @@ -1446,7 +1446,10 @@ xmin, xmax = a.get_xlim() ymin, ymax = a.get_ylim() lims.append( (xmin, xmax, ymin, ymax) ) - pos.append( tuple( a.get_position() ) ) + # Store both the original and modified positions + pos.append( ( + tuple( a.get_position(True) ), + tuple( a.get_position() ) ) ) self._views.push(lims) self._positions.push(pos) self.set_history_buttons() @@ -1660,7 +1663,9 @@ xmin, xmax, ymin, ymax = lims[i] a.set_xlim((xmin, xmax)) a.set_ylim((ymin, ymax)) - a.set_position( pos[i] ) + # Restore both the original and modified positions + a.set_position( pos[i][0], 'original' ) + a.set_position( pos[i][1], 'active' ) self.draw() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jd...@us...> - 2007-09-05 15:23:31
|
Revision: 3788 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3788&view=rev Author: jdh2358 Date: 2007-09-05 08:23:29 -0700 (Wed, 05 Sep 2007) Log Message: ----------- fixed a load numpification bug Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/mlab.py Modified: trunk/matplotlib/lib/matplotlib/mlab.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mlab.py 2007-09-05 15:23:09 UTC (rev 3787) +++ trunk/matplotlib/lib/matplotlib/mlab.py 2007-09-05 15:23:29 UTC (rev 3788) @@ -1252,7 +1252,7 @@ r,c = X.shape if r==1 or c==1: X.shape = max(r,c), - if unpack: X.transpose() + if unpack: return X.transpose() return X def csv2rec(fname, comments='#', skiprows=0, checkrows=5, delimiter=',', This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-09-05 15:23:22
|
Revision: 3787 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3787&view=rev Author: mdboom Date: 2007-09-05 08:23:09 -0700 (Wed, 05 Sep 2007) Log Message: ----------- Use cmex for symbols that don't have any equivalent in Unicode (the vertically sized things, in particular). Simplify fallback_to_cm code, now that font buffers are handled differently. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/_mathtext_data.py trunk/matplotlib/lib/matplotlib/mathtext.py Modified: trunk/matplotlib/lib/matplotlib/_mathtext_data.py =================================================================== --- trunk/matplotlib/lib/matplotlib/_mathtext_data.py 2007-09-05 15:21:08 UTC (rev 3786) +++ trunk/matplotlib/lib/matplotlib/_mathtext_data.py 2007-09-05 15:23:09 UTC (rev 3787) @@ -243,6 +243,29 @@ r'\spadesuit' : ('cmsy10', 7), } +latex_to_cmex = { + r'\__sqrt__' : 112, + r'\bigcap' : 92, + r'\bigcup' : 91, + r'\bigodot' : 75, + r'\bigoplus' : 77, + r'\bigotimes' : 79, + r'\biguplus' : 93, + r'\bigvee' : 95, + r'\bigwedge' : 94, + r'\coprod' : 97, + r'\int' : 90, + r'\leftangle' : 173, + r'\leftbrace' : 169, + r'\oint' : 73, + r'\prod' : 89, + r'\rightangle' : 174, + r'\rightbrace' : 170, + r'\sum' : 88, + r'\widehat' : 98, + r'\widetilde' : 101, +} + latex_to_standard = { r'\cong' : ('psyr', 64), r'\Delta' : ('psyr', 68), Modified: trunk/matplotlib/lib/matplotlib/mathtext.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mathtext.py 2007-09-05 15:21:08 UTC (rev 3786) +++ trunk/matplotlib/lib/matplotlib/mathtext.py 2007-09-05 15:23:09 UTC (rev 3787) @@ -146,7 +146,8 @@ from matplotlib.ft2font import FT2Font, FT2Image, KERNING_DEFAULT, LOAD_DEFAULT, LOAD_NO_HINTING from matplotlib.font_manager import findfont, FontProperties from matplotlib._mathtext_data import latex_to_bakoma, \ - latex_to_standard, tex2uni, type12uni, tex2type1, uni2type1 + latex_to_standard, tex2uni, type12uni, tex2type1, uni2type1, \ + latex_to_cmex from matplotlib import get_data_path, rcParams #################### @@ -581,10 +582,9 @@ self.fonts[font.postscript_name.lower()] = cached_font return cached_font - def get_fonts(self): - return list(set([x.font for x in self.fonts.values()])) - def _get_offset(self, cached_font, glyph, fontsize, dpi): + if cached_font.font.postscript_name == 'Cmex10': + return glyph.height/64.0/2.0 + 256.0/64.0 * dpi/72.0 return 0. def _get_info (self, fontname, sym, fontsize, dpi, mark_as_used=True): @@ -676,11 +676,6 @@ self.fontmap[key] = fullpath self.fontmap[val] = fullpath - def _get_offset(self, cached_font, glyph, fontsize, dpi): - if cached_font.font.postscript_name == 'Cmex10': - return glyph.height/64.0/2.0 + 256.0/64.0 * dpi/72.0 - return 0. - _slanted_symbols = Set(r"\int \oint".split()) def _get_glyph(self, fontname, sym, fontsize): @@ -719,21 +714,21 @@ ('ex', '\x22')], ']' : [('rm', ']'), ('ex', '\xa4'), ('ex', '\x69'), ('ex', '\x23')], - r'\lfloor' : [('cal', '\x62'), ('ex', '\xa5'), ('ex', '\x6a'), + r'\lfloor' : [('ex', '\xa5'), ('ex', '\x6a'), ('ex', '\xb9'), ('ex', '\x24')], - r'\rfloor' : [('cal', '\x63'), ('ex', '\xa6'), ('ex', '\x6b'), + r'\rfloor' : [('ex', '\xa6'), ('ex', '\x6b'), ('ex', '\xba'), ('ex', '\x25')], - r'\lceil' : [('cal', '\x64'), ('ex', '\xa7'), ('ex', '\x6c'), + r'\lceil' : [('ex', '\xa7'), ('ex', '\x6c'), ('ex', '\xbb'), ('ex', '\x26')], - r'\rceil' : [('cal', '\x65'), ('ex', '\xa8'), ('ex', '\x6d'), + r'\rceil' : [('ex', '\xa8'), ('ex', '\x6d'), ('ex', '\xbc'), ('ex', '\x27')], - r'\langle' : [('cal', '\x68'), ('ex', '\xad'), ('ex', '\x44'), + r'\langle' : [('ex', '\xad'), ('ex', '\x44'), ('ex', '\xbf'), ('ex', '\x2a')], - r'\rangle' : [('cal', '\x69'), ('ex', '\xae'), ('ex', '\x45'), + r'\rangle' : [('ex', '\xae'), ('ex', '\x45'), ('ex', '\xc0'), ('ex', '\x2b')], - r'\__sqrt__' : [('cal', '\x70'), ('ex', '\x70'), ('ex', '\x71'), + r'\__sqrt__' : [('ex', '\x70'), ('ex', '\x71'), ('ex', '\x72'), ('ex', '\x73')], - r'\backslash': [('cal', '\x6e'), ('ex', '\xb2'), ('ex', '\x2f'), + r'\backslash': [('ex', '\xb2'), ('ex', '\x2f'), ('ex', '\xc2'), ('ex', '\x2d')], r'/' : [('rm', '/'), ('ex', '\xb1'), ('ex', '\x2e'), ('ex', '\xcb'), ('ex', '\x2c')], @@ -775,24 +770,27 @@ prop = rcParams['mathtext.' + texfont] font = findfont(prop) self.fontmap[texfont] = font + prop = FontProperties('cmex10') + font = findfont(prop) + self.fontmap['ex'] = font - def _get_offset(self, cached_font, glyph, fontsize, dpi): - return 0. - + _slanted_symbols = Set(r"\int \oint".split()) + def _get_glyph(self, fontname, sym, fontsize): found_symbol = False - try: - uniindex = get_unicode_index(sym) + uniindex = latex_to_cmex.get(sym) + if uniindex is not None: + fontname = 'ex' found_symbol = True - except ValueError: - # This is a total hack, but it works for now - if sym.startswith('\\big'): - uniindex = get_unicode_index(sym[4:]) - fontsize *= GROW_FACTOR - else: + else: + try: + uniindex = get_unicode_index(sym) + found_symbol = True + except ValueError: uniindex = ord('?') - warn("No TeX to unicode mapping for '%s'" % sym.encode('ascii', 'replace'), + warn("No TeX to unicode mapping for '%s'" % + sym.encode('ascii', 'replace'), MathTextWarning) # Only characters in the "Letter" class should be italicized in 'it' @@ -806,19 +804,20 @@ or unicodedata.name(unistring).startswith("GREEK CAPITAL")): new_fontname = 'rm' - slanted = (new_fontname == 'it') + slanted = (new_fontname == 'it') or sym in self._slanted_symbols cached_font = self._get_font(new_fontname) try: glyphindex = cached_font.charmap[uniindex] except KeyError: warn("Font '%s' does not have a glyph for '%s'" % - (cached_font.font.postscript_name, sym.encode('ascii', 'replace')), + (cached_font.font.postscript_name, + sym.encode('ascii', 'replace')), MathTextWarning) found_symbol = False if not found_symbol: if self.cm_fallback: - warn("Substituting with a symbol from the Computer Modern family.", + warn("Substituting with a symbol from Computer Modern.", MathTextWarning) return self.cm_fallback._get_glyph(fontname, sym, fontsize) else: @@ -831,26 +830,12 @@ symbol_name = cached_font.font.get_glyph_name(glyphindex) return cached_font, uniindex, symbol_name, fontsize, slanted - def set_canvas_size(self, w, h): - 'Dimension the drawing canvas; may be a noop' - TruetypeFonts.set_canvas_size(self, w, h) + def get_sized_alternatives_for_symbol(self, fontname, sym): if self.cm_fallback: - self.cm_fallback.set_canvas_size(w, h) - - def get_used_characters(self): - used_characters = dict(self.used_characters) - if self.cm_fallback: - fallback_characters = self.cm_fallback.get_used_characters() - for key, val in fallback_characters: - used_characters.setdefault(key, Set()).update(val) - return used_characters - - def get_fonts(self): - fonts = [x.font for x in self.fonts.values()] - if self.cm_fallback: - fonts.extend(self.cm_fallback.get_fonts()) - return list(set(fonts)) - + return self.cm_fallback.get_sized_alternatives_for_symbol( + fontname, sym) + return [(fontname, sym)] + class StandardPsFonts(Fonts): """ Use the standard postscript fonts for rendering to backend_ps @@ -896,9 +881,6 @@ self.fonts[cached_font.get_fontname()] = cached_font return cached_font - def get_fonts(self): - return list(set(self.fonts.values())) - def _get_info (self, fontname, sym, fontsize, dpi): 'load the cmfont, metrics and glyph with caching' key = fontname, sym, fontsize, dpi This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |