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-08-31 15:09:38
|
Revision: 3761 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3761&view=rev Author: mdboom Date: 2007-08-31 08:09:27 -0700 (Fri, 31 Aug 2007) Log Message: ----------- Fix typo. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py Modified: trunk/matplotlib/lib/matplotlib/backends/backend_agg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007-08-30 19:14:55 UTC (rev 3760) +++ trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007-08-31 15:09:27 UTC (rev 3761) @@ -172,7 +172,7 @@ """ if __debug__: verbose.report('RendererAgg.draw_mathtext', 'debug-annoying') - ox, oy, width, height, descent, fonts, used_characters = \ + ox, oy, width, height, descent, font_image, used_characters = \ self.mathtext_parser.parse(s, self.dpi.get(), prop) if angle == 90: @@ -183,10 +183,9 @@ else: x = int(x) + ox y = int(y) - height + oy - for font in fonts: - if angle == 90: - font.horiz_image_to_vert_image() # <-- Rotate - self._renderer.draw_text( font, x, y + 1, gc) + if angle == 90: + font_image.rotate() # <-- Rotate 90 deg + self._renderer.draw_text_image(font_image, x, y + 1, gc) if 0: self._renderer.draw_rectangle(gc, None, int(x), @@ -212,7 +211,7 @@ #print x, y, int(x), int(y) - self._renderer.draw_text(font, int(x), int(y) + 1, gc) + self._renderer.draw_text_image(font.get_image(), int(x), int(y) + 1, gc) def get_text_width_height_descent(self, s, prop, ismath, rgb=(0,0,0)): @@ -233,9 +232,9 @@ return n,m if ismath: - ox, oy, width, height, descent, fonts, used_characters = \ + ox, oy, width, height, descent, font_image, used_characters = \ self.mathtext_parser.parse(s, self.dpi.get(), prop) - return width, height, depth + return width, height, descent font = self._get_agg_font(prop) font.set_text(s, 0.0, flags=LOAD_DEFAULT) # the width and height of unrotated string w, h = font.get_width_height() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-08-30 19:15:39
|
Revision: 3760 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3760&view=rev Author: mdboom Date: 2007-08-30 12:14:55 -0700 (Thu, 30 Aug 2007) Log Message: ----------- Add valignment = 'baseline' feature to align text by its baseline. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/afm.py 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_gd.py trunk/matplotlib/lib/matplotlib/backends/backend_gdk.py trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py trunk/matplotlib/lib/matplotlib/backends/backend_ps.py trunk/matplotlib/lib/matplotlib/backends/backend_svg.py trunk/matplotlib/lib/matplotlib/backends/backend_template.py trunk/matplotlib/lib/matplotlib/backends/backend_wx.py trunk/matplotlib/lib/matplotlib/mathtext.py trunk/matplotlib/lib/matplotlib/text.py Modified: trunk/matplotlib/lib/matplotlib/afm.py =================================================================== --- trunk/matplotlib/lib/matplotlib/afm.py 2007-08-30 15:32:25 UTC (rev 3759) +++ trunk/matplotlib/lib/matplotlib/afm.py 2007-08-30 19:14:55 UTC (rev 3760) @@ -334,7 +334,7 @@ return totalw, maxy-miny - def get_str_bbox(self, s): + def get_str_bbox_and_descent(self, s): """ Return the string bounding box """ @@ -369,9 +369,15 @@ thismin = b if thismin<miny: miny = thismin - return left, miny, totalw, maxy-miny + return left, miny, totalw, maxy-miny, -miny + def get_str_bbox(self, s): + """ + Return the string bounding box + """ + return self.get_str_bbox_and_descent(s)[:4] + def get_name_char(self, c): """ Get the name of the character, ie, ';' is 'semicolon' Modified: trunk/matplotlib/lib/matplotlib/backend_bases.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backend_bases.py 2007-08-30 15:32:25 UTC (rev 3759) +++ trunk/matplotlib/lib/matplotlib/backend_bases.py 2007-08-30 19:14:55 UTC (rev 3760) @@ -421,12 +421,13 @@ """ return transforms.lbwh_to_bbox(0,0,1,1) # your values here - def get_text_width_height(self, s, prop, ismath): + def get_text_width_height_descent(self, s, prop, ismath): """ - get the width and height in display coords of the string s - with FontPropertry prop + get the width and height, and the offset from the bottom to the + baseline (descent), in display coords of the string s with + FontPropertry prop """ - return 1,1 + return 1,1,1 def new_gc(self): """ Modified: trunk/matplotlib/lib/matplotlib/backends/backend_agg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007-08-30 15:32:25 UTC (rev 3759) +++ trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007-08-30 19:14:55 UTC (rev 3760) @@ -172,7 +172,7 @@ """ if __debug__: verbose.report('RendererAgg.draw_mathtext', 'debug-annoying') - ox, oy, width, height, fonts, used_characters = \ + ox, oy, width, height, descent, fonts, used_characters = \ self.mathtext_parser.parse(s, self.dpi.get(), prop) if angle == 90: @@ -186,7 +186,7 @@ for font in fonts: if angle == 90: font.horiz_image_to_vert_image() # <-- Rotate - self._renderer.draw_text( font, x, y, gc) + self._renderer.draw_text( font, x, y + 1, gc) if 0: self._renderer.draw_rectangle(gc, None, int(x), @@ -212,10 +212,10 @@ #print x, y, int(x), int(y) - self._renderer.draw_text(font, int(x), int(y), gc) + self._renderer.draw_text(font, int(x), int(y) + 1, gc) - def get_text_width_height(self, s, prop, ismath, rgb=(0,0,0)): + def get_text_width_height_descent(self, s, prop, ismath, rgb=(0,0,0)): """ get the width and height in display coords of the string s with FontPropertry prop @@ -233,15 +233,17 @@ return n,m if ismath: - ox, oy, width, height, fonts, used_characters = \ + ox, oy, width, height, descent, fonts, used_characters = \ self.mathtext_parser.parse(s, self.dpi.get(), prop) - return width, height + return width, height, depth font = self._get_agg_font(prop) font.set_text(s, 0.0, flags=LOAD_DEFAULT) # the width and height of unrotated string w, h = font.get_width_height() + d = font.get_descent() w /= 64.0 # convert from subpixels h /= 64.0 - return w, h + d /= 64.0 + return w, h, d def draw_tex(self, gc, x, y, s, prop, angle): # todo, handle props, angle, origins @@ -250,7 +252,7 @@ dpi = self.dpi.get() flip = angle==90 - w,h = self.get_text_width_height(s, prop, 'TeX', rgb) + w,h,d = self.get_text_width_height_descent(s, prop, 'TeX', rgb) if flip: w,h = h,w x -= w Modified: trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py 2007-08-30 15:32:25 UTC (rev 3759) +++ trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py 2007-08-30 19:14:55 UTC (rev 3760) @@ -304,7 +304,7 @@ if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) ctx = gc.ctx - width, height, glyphs, rects = self.mathtext_parser.parse( + width, height, descent, glyphs, rects = self.mathtext_parser.parse( s, self.dpi.get(), prop) ctx.save() @@ -349,12 +349,12 @@ return self.width, self.height - def get_text_width_height(self, s, prop, ismath): + def get_text_width_height_descent(self, s, prop, ismath): if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) if ismath: - width, height, fonts, used_characters = self.mathtext_parser.parse( + width, height, descent, fonts, used_characters = self.mathtext_parser.parse( s, self.dpi.get(), prop) - return width, height + return width, height, descent ctx = self.text_ctx ctx.save() @@ -373,10 +373,10 @@ # save/restore prevents the problem ctx.set_font_size (size) - w, h = ctx.text_extents (s)[2:4] + y_bearing, w, h = ctx.text_extents (s)[1:4] ctx.restore() - return w, h + return w, h, h + y_bearing def new_gc(self): Modified: trunk/matplotlib/lib/matplotlib/backends/backend_gd.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_gd.py 2007-08-30 15:32:25 UTC (rev 3759) +++ trunk/matplotlib/lib/matplotlib/backends/backend_gd.py 2007-08-30 19:14:55 UTC (rev 3760) @@ -59,7 +59,7 @@ 'return the canvas width and height in display coords' return self.width, self.height - def get_text_width_height(self, s, prop, ismath): + def get_text_width_height_descent(self, s, prop, ismath): """ get the width and height in display coords of the string s with fontsize in points @@ -78,7 +78,7 @@ w = abs(lrx - llx) h = abs(lly - uly) - return w, h + return w, h, h def flipy(self): Modified: trunk/matplotlib/lib/matplotlib/backends/backend_gdk.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_gdk.py 2007-08-30 15:32:25 UTC (rev 3759) +++ trunk/matplotlib/lib/matplotlib/backends/backend_gdk.py 2007-08-30 19:14:55 UTC (rev 3760) @@ -199,7 +199,7 @@ def _draw_mathtext(self, gc, x, y, s, prop, angle): - width, height, fonts, used_characters = self.mathtext_parser.parse( + width, height, descent, fonts, used_characters = self.mathtext_parser.parse( s, self.dpi.get(), prop) if angle==90: @@ -340,15 +340,15 @@ def get_canvas_width_height(self): return self.width, self.height - def get_text_width_height(self, s, prop, ismath): + def get_text_width_height_descent(self, s, prop, ismath): if ismath: - width, height, fonts, used_characters = self.mathtext_parser.parse( + width, height, descent, fonts, used_characters = self.mathtext_parser.parse( s, self.dpi.get(), prop) - return width, height + return width, height, descent layout, inkRect, logicalRect = self._get_pango_layout(s, prop) l, b, w, h = inkRect - return w, h+1 + return w, h+1, h + 1 def new_gc(self): return GraphicsContextGDK(renderer=self) Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-08-30 15:32:25 UTC (rev 3759) +++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-08-30 19:14:55 UTC (rev 3760) @@ -1224,7 +1224,7 @@ def draw_mathtext(self, gc, x, y, s, prop, angle): # TODO: fix positioning and encoding - width, height, glyphs, rects, used_characters = \ + width, height, descent, glyphs, rects, used_characters = \ self.mathtext_parser.parse(s, 72, prop) self.merge_used_characters(used_characters) @@ -1465,31 +1465,28 @@ else: return draw_text_woven(chunks) - def get_text_width_height(self, s, prop, ismath): - # FT2Font can handle unicode, and so can we - # if isinstance(s, unicode): - # s = s.encode('cp1252', 'replace') - + def get_text_width_height_descent(self, s, prop, ismath): if ismath: - w, h, glyphs, rects, used_characters = \ + w, h, d, glyphs, rects, used_characters = \ self.mathtext_parser.parse(s, 72, prop) elif rcParams['pdf.use14corefonts']: font = self._get_font_afm(prop) - l, b, w, h = font.get_str_bbox(s) - fontsize = prop.get_size_in_points() - w *= fontsize / 1000 - h *= fontsize / 1000 - + l, b, w, h, d = font.get_str_bbox_and_descent(s) + scale = prop.get_size_in_points() / 1000.0 + w *= scale + h *= scale + d *= scale else: font = self._get_font_ttf(prop) font.set_text(s, 0.0, flags=LOAD_NO_HINTING) w, h = font.get_width_height() w /= 64.0 h /= 64.0 + d = font.get_descent() + d /= 64.0 + return w, h, d - return w, h - def _get_font_afm(self, prop): key = hash(prop) font = self.afm_font_cache.get(key) Modified: trunk/matplotlib/lib/matplotlib/backends/backend_ps.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2007-08-30 15:32:25 UTC (rev 3759) +++ trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2007-08-30 19:14:55 UTC (rev 3760) @@ -263,7 +263,7 @@ 'return the canvas width and height in display coords' return self.width, self.height - def get_text_width_height(self, s, prop, ismath): + def get_text_width_height_descent(self, s, prop, ismath): """ get the width and height in display coords of the string s with FontPropertry prop @@ -276,30 +276,36 @@ w = (r-l) h = (t-b) #print s, w, h - return w, h + # TODO: We need a way to get a good baseline from + # text.usetex + return w, h, h if ismath: - width, height, pswriter, used_characters = \ + width, height, descent, pswriter, used_characters = \ self.mathtext_parser.parse(s, 72, prop) - return width, height + return width, height, descent if rcParams['ps.useafm']: if ismath: s = s[1:-1] font = self._get_font_afm(prop) - l,b,w,h = font.get_str_bbox(s) + l,b,w,h,d = font.get_str_bbox_and_descent(s) fontsize = prop.get_size_in_points() - w *= 0.001*fontsize - h *= 0.001*fontsize - return w, h + scale = 0.001*fontsize + w *= scale + h *= scale + d *= scale + return w, h, d font = self._get_font_ttf(prop) font.set_text(s, 0.0, flags=LOAD_NO_HINTING) w, h = font.get_width_height() w /= 64.0 # convert from subpixels h /= 64.0 + d = font.get_descent() + d /= 64.0 #print s, w, h - return w, h + return w, h, d def flipy(self): 'return true if small y numbers are top for renderer' @@ -661,7 +667,7 @@ """ draw a Text instance """ - w, h = self.get_text_width_height(s, prop, ismath) + w, h, bl = self.get_text_width_height_baseline(s, prop, ismath) fontsize = prop.get_size_in_points() corr = 0#w/2*(fontsize-10)/10 pos = _nums_to_str(x-corr, y) @@ -857,7 +863,7 @@ if debugPS: self._pswriter.write("% mathtext\n") - width, height, pswriter, used_characters = \ + width, height, descent, pswriter, used_characters = \ self.mathtext_parser.parse(s, 72, prop) self.merge_used_characters(used_characters) self.set_color(*gc.get_rgb()) Modified: trunk/matplotlib/lib/matplotlib/backends/backend_svg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2007-08-30 15:32:25 UTC (rev 3759) +++ trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2007-08-30 19:14:55 UTC (rev 3760) @@ -232,7 +232,7 @@ def draw_rectangle(self, gc, rgbFace, x, y, width, height): details = 'width="%f" height="%f" x="%f" y="%f"' % (width, height, x, - self.height-y-height) + self.height-y-height) self._draw_svg_element('rect', details, gc, rgbFace) def draw_text(self, gc, x, y, s, prop, angle, ismath): @@ -241,7 +241,9 @@ return font = self._get_font(prop) - + font.set_text(s, 0.0, flags=LOAD_NO_HINTING) + y -= font.get_descent() / 64.0 + thetext = escape_xml_text(s) fontfamily = font.family_name fontstyle = font.style_name @@ -277,7 +279,7 @@ currx += kern/64.0 svg.append('<use xlink:href="#%s" transform="translate(%s)"/>\n' - % (charid, currx)) + % (charid, currx * (self.FONT_SCALE / fontsize))) currx += (glyph.linearHoriAdvance / 65536.0) svg.append('</g>\n') @@ -338,7 +340,7 @@ """ Draw math text using matplotlib.mathtext """ - width, height, svg_elements, used_characters = \ + width, height, descent, svg_elements, used_characters = \ self.mathtext_parser.parse(s, 72, prop) svg_glyphs = svg_elements.svg_glyphs svg_rects = svg_elements.svg_rects @@ -426,17 +428,19 @@ def get_canvas_width_height(self): return self.width, self.height - def get_text_width_height(self, s, prop, ismath): + def get_text_width_height_descent(self, s, prop, ismath): if ismath: - width, height, trash, used_characters = \ + width, height, descent, trash, used_characters = \ self.mathtext_parser.parse(s, 72, prop) - return width, height + return width, height, descent font = self._get_font(prop) font.set_text(s, 0.0, flags=LOAD_NO_HINTING) w, h = font.get_width_height() w /= 64.0 # convert from subpixels h /= 64.0 - return w, h + d = font.get_descent() + d /= 64.0 + return w, h, d class FigureCanvasSVG(FigureCanvasBase): Modified: trunk/matplotlib/lib/matplotlib/backends/backend_template.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_template.py 2007-08-30 15:32:25 UTC (rev 3759) +++ trunk/matplotlib/lib/matplotlib/backends/backend_template.py 2007-08-30 19:14:55 UTC (rev 3760) @@ -93,8 +93,8 @@ def get_canvas_width_height(self): return 100, 100 - def get_text_width_height(self, s, prop, ismath): - return 1, 1 + def get_text_width_height_descent(self, s, prop, ismath): + return 1, 1, 1 def new_gc(self): return GraphicsContextTemplate() Modified: trunk/matplotlib/lib/matplotlib/backends/backend_wx.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_wx.py 2007-08-30 15:32:25 UTC (rev 3759) +++ trunk/matplotlib/lib/matplotlib/backends/backend_wx.py 2007-08-30 19:14:55 UTC (rev 3760) @@ -253,7 +253,7 @@ def offset_text_height(self): return True - def get_text_width_height(self, s, prop, ismath): + def get_text_width_height_descent(self, s, prop, ismath): """ get the width and height in display coords of the string s with FontPropertry prop @@ -264,9 +264,9 @@ if self.gc is None: gc = self.new_gc() font = self.get_wx_font(s, prop) self.gc.SetFont(font) - w, h = self.gc.GetTextExtent(s) + w, h, descent, leading = self.gc.GetFullTextExtent(s) - return w, h + return w, h, descent def get_canvas_width_height(self): 'return the canvas width and height in display coords' @@ -376,7 +376,7 @@ gc.SetFont(font) assert gc.Ok(), "wxMemoryDC not OK to use" - w, h = self.get_text_width_height(s, prop, ismath) + w, h, d = self.get_text_width_height_descent(s, prop, ismath) x = int(x) y = int(y-h) Modified: trunk/matplotlib/lib/matplotlib/mathtext.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mathtext.py 2007-08-30 15:32:25 UTC (rev 3759) +++ trunk/matplotlib/lib/matplotlib/mathtext.py 2007-08-30 19:14:55 UTC (rev 3760) @@ -217,10 +217,11 @@ def __init__(self): self.fonts_object = None - def set_canvas_size(self, w, h): + def set_canvas_size(self, w, h, d): 'Dimension the drawing canvas; may be a noop' self.width = w self.height = h + self.depth = d def render_glyph(self, ox, oy, info): raise NotImplementedError() @@ -261,12 +262,16 @@ self._update_bbox(x1, y1, x2, y2) def get_results(self, box): + orig_height = box.height + orig_depth = box.depth ship(0, 0, box) bbox = self.bbox - bbox = [bbox[0] - 2, bbox[1] - 2, bbox[2] + 2, bbox[3] + 2] + bbox = [bbox[0] - 1, bbox[1] - 1, bbox[2] + 1, bbox[3] + 1] self._switch_to_real_backend() self.fonts_object.set_canvas_size( - bbox[2] - bbox[0], bbox[3] - bbox[1]) + bbox[2] - bbox[0], + (bbox[3] - bbox[1]) - orig_depth, + (bbox[3] - bbox[1]) - orig_height) ship(-bbox[0], -bbox[1], box) return self.fonts_object.get_results(box) @@ -285,10 +290,10 @@ self.oy = 0 MathtextBackend.__init__(self) - def set_canvas_size(self, w, h): - MathtextBackend.set_canvas_size(self, w, h) + def set_canvas_size(self, w, h, d): + MathtextBackend.set_canvas_size(self, w, h, d) for font in self.fonts_object.get_fonts(): - font.set_bitmap_size(int(w), int(h)) + font.set_bitmap_size(int(w), int(h) + int(d)) def render_glyph(self, ox, oy, info): info.font.draw_glyph_to_bitmap( @@ -302,7 +307,8 @@ return (self.ox, self.oy, self.width, - self.height, + self.height + self.depth, + self.depth, self.fonts_object.get_fonts(), self.fonts_object.get_used_characters()) @@ -341,9 +347,11 @@ self.pswriter.write(ps) def get_results(self, box): - ship(0, 0, box) + ship(0, -self.depth, box) + print self.depth return (self.width, - self.height, + self.height + self.depth, + self.depth, self.pswriter, self.fonts_object.get_used_characters()) @@ -363,9 +371,10 @@ self.rects.append((x1, self.height - y2, x2 - x1, y2 - y1)) def get_results(self, box): - ship(0, 0, box) + ship(0, -self.depth, box) return (self.width, - self.height, + self.height + self.depth, + self.depth, self.glyphs, self.rects, self.fonts_object.get_used_characters()) @@ -386,11 +395,12 @@ (x1, self.height - y1 + 1, x2 - x1, y2 - y1)) def get_results(self, box): - ship(0, 0, box) + ship(0, -self.depth, box) svg_elements = Bunch(svg_glyphs = self.svg_glyphs, svg_rects = self.svg_rects) return (self.width, - self.height, + self.height + self.depth, + self.depth, svg_elements, self.fonts_object.get_used_characters()) @@ -410,9 +420,10 @@ (x1, y1 - self.height, x2 - x1, y2 - y1)) def get_results(self, box): - ship(0, 0, box) + ship(0, -self.depth, box) return (self.width, - self.height, + self.height + self.depth, + self.depth, self.glyphs, self.rects) @@ -477,10 +488,10 @@ info = self._get_info(font, sym, fontsize, dpi) return info.metrics - def set_canvas_size(self, w, h): + def set_canvas_size(self, w, h, d): 'Dimension the drawing canvas; may be a noop' - self.width, self.height = ceil(w), ceil(h) - self.mathtext_backend.set_canvas_size(self.width, self.height) + self.width, self.height, self.depth = ceil(w), ceil(h), ceil(d) + self.mathtext_backend.set_canvas_size(self.width, self.height, self.depth) def render_glyph(self, ox, oy, facename, sym, fontsize, dpi): info = self._get_info(facename, sym, fontsize, dpi) @@ -2447,7 +2458,6 @@ cacheKey = (s, dpi, hash(prop)) result = self._cache.get(cacheKey) if result is not None: - del self._cache[cacheKey] return result if self._output == 'PS' and rcParams['ps.useafm']: @@ -2467,8 +2477,7 @@ self.__class__._parser = Parser() box = self._parser.parse(s, font_output, fontsize, dpi) - w, h = box.width, box.height + box.depth - font_output.set_canvas_size(w, h) + font_output.set_canvas_size(box.width, box.height, box.depth) result = font_output.get_results(box) self._cache[cacheKey] = result # Free up the transient data structures Modified: trunk/matplotlib/lib/matplotlib/text.py =================================================================== --- trunk/matplotlib/lib/matplotlib/text.py 2007-08-30 15:32:25 UTC (rev 3759) +++ trunk/matplotlib/lib/matplotlib/text.py 2007-08-30 19:14:55 UTC (rev 3760) @@ -20,54 +20,6 @@ import matplotlib.nxutils as nxutils -def scanner(s): - """ - Split a string into mathtext and non-mathtext parts. mathtext is - surrounded by $ symbols. quoted \$ are ignored - - All slash quotes dollar signs are ignored - - The number of unquoted dollar signs must be even - - Return value is a list of (substring, inmath) tuples - """ - if not len(s): return [(s, False)] - #print 'testing', s, type(s) - inddollar, = npy.nonzero(npy.asarray(npy.equal(s,'$'))) - quoted = dict([ (ind,1) for ind in npy.nonzero(npy.asarray(npy.equal(s,'\\')))[0]]) - indkeep = [ind for ind in inddollar if not quoted.has_key(ind-1)] - if len(indkeep)==0: - return [(s, False)] - if len(indkeep)%2: - raise ValueError('Illegal string "%s" (must have balanced dollar signs)'%s) - - Ns = len(s) - - indkeep = [ind for ind in indkeep] - # make sure we start with the first element - if indkeep[0]!=0: indkeep.insert(0,0) - # and end with one past the end of the string - indkeep.append(Ns+1) - - Nkeep = len(indkeep) - results = [] - - inmath = s[0] == '$' - for i in range(Nkeep-1): - i0, i1 = indkeep[i], indkeep[i+1] - if not inmath: - if i0>0: i0 +=1 - else: - i1 += 1 - if i0>=Ns: break - - results.append((s[i0:i1], inmath)) - inmath = not inmath - - return results - - - def _process_text_args(override, fontdict=None, **kwargs): "Return an override dict. See 'text' docstring for info" @@ -117,7 +69,7 @@ text: string transform: a matplotlib.transform transformation instance variant: [ 'normal' | 'small-caps' ] - verticalalignment or va: [ 'center' | 'top' | 'bottom' ] + verticalalignment or va: [ 'center' | 'top' | 'bottom' | 'baseline' ] visible: [True | False] weight or fontweight: [ 'normal' | 'bold' | 'heavy' | 'light' | 'ultrabold' | 'ultralight'] x: float @@ -130,9 +82,6 @@ Handle storing and drawing of text in window or data coordinates """ - # special case superscripting to speedup logplots - _rgxsuper = re.compile('\$([\-+0-9]+)\^\{(-?[0-9]+)\}\$') - zorder = 3 def __str__(self): return "Text(%g,%g,%s)"%(self._y,self._y,self._text) @@ -237,21 +186,21 @@ height = 0 xmin, ymin = thisx, thisy - if self.is_math_text(): - lines = [self._text] - else: - lines = self._text.split('\n') + lines = self._text.split('\n') whs = [] # Find full vertical extent of font, # including ascenders and descenders: - tmp, heightt = renderer.get_text_width_height( + tmp, heightt, bl = renderer.get_text_width_height_descent( 'lp', self._fontproperties, ismath=False) offsety = heightt * self._linespacing + baseline = None for line in lines: - w,h = renderer.get_text_width_height( - line, self._fontproperties, ismath=self.is_math_text()) + w, h, d = renderer.get_text_width_height_descent( + line, self._fontproperties, ismath=self.is_math_text(line)) + if baseline is None: + baseline = h - d whs.append( (w,h) ) horizLayout.append((line, thisx, thisy, w, h)) thisy -= offsety @@ -307,6 +256,7 @@ if valign=='center': offsety = ty - (ymin + height/2.0) elif valign=='top': offsety = ty - (ymin + height) + elif valign=='baseline': offsety = ty - (ymin + height) + baseline else: offsety = ty - ymin xmin += offsetx @@ -364,49 +314,9 @@ bbox_artist(self, renderer, self._bbox) angle = self.get_rotation() - ismath = self.is_math_text() - - if angle==0: - #print 'text', self._text - if ismath=='TeX': m = None - else: m = self._rgxsuper.match(self._text) - if m is not None: - bbox, info = self._get_layout_super(self._renderer, m) - base, xt, yt = info[0] - renderer.draw_text(gc, xt, yt, base, - self._fontproperties, angle, - ismath=False) - - exponent, xt, yt, fp = info[1] - renderer.draw_text(gc, xt, yt, exponent, - fp, angle, - ismath=False) - return - - - if len(self._substrings)>1: - # embedded mathtext - thisx, thisy = self._get_xy_display() - - for s,ismath in self._substrings: - w, h = renderer.get_text_width_height( - s, self._fontproperties, ismath) - - renderx, rendery = thisx, thisy - if renderer.flipy(): - canvasw, canvash = renderer.get_canvas_width_height() - rendery = canvash-rendery - - renderer.draw_text(gc, renderx, rendery, s, - self._fontproperties, angle, - ismath) - thisx += w - - - return bbox, info = self._get_layout(renderer) trans = self.get_transform() - if ismath=='TeX': + if rcParams['text.usetex']: canvasw, canvash = renderer.get_canvas_width_height() for line, wh, x, y in info: x, y = trans.xy_tup((x, y)) @@ -426,7 +336,7 @@ renderer.draw_text(gc, x, y, line, self._fontproperties, angle, - ismath=self.is_math_text()) + ismath=self.is_math_text(line)) def get_color(self): "Return the color of the text" @@ -523,13 +433,6 @@ raise RuntimeError('Cannot get window extent w/o renderer') angle = self.get_rotation() - if angle==0: - ismath = self.is_math_text() - if ismath=='TeX': m = None - else: m = self._rgxsuper.match(self._text) - if m is not None: - bbox, tmp = self._get_layout_super(self._renderer, m) - return bbox bbox, info = self._get_layout(self._renderer) return bbox @@ -734,9 +637,9 @@ """ Set the vertical alignment - ACCEPTS: [ 'center' | 'top' | 'bottom' ] + ACCEPTS: [ 'center' | 'top' | 'bottom' | 'baseline' ] """ - legal = ('top', 'bottom', 'center') + legal = ('top', 'bottom', 'center', 'baseline') if align not in legal: raise ValueError('Vertical alignment must be one of %s' % str(legal)) @@ -749,15 +652,12 @@ ACCEPTS: string or anything printable with '%s' conversion """ self._text = '%s' % (s,) - #self._substrings = scanner(s) # support embedded mathtext - self._substrings = [] # ignore embedded mathtext for now - def is_math_text(self): + def is_math_text(self, s): if rcParams['text.usetex']: return 'TeX' # Did we find an even number of non-escaped dollar signs? # If so, treat is as math text. - s = self._text dollar_count = s.count(r'$') - s.count(r'\$') if dollar_count > 0 and dollar_count % 2 == 0: return True @@ -772,56 +672,6 @@ """ self._fontproperties = fp - def _get_layout_super(self, renderer, m): - """ - a special case optimization if a log super and angle = 0 - Basically, mathtext is slow and we can do simple superscript layout "by hand" - """ - - key = self.get_prop_tup() - if self.cached.has_key(key): return self.cached[key] - - base, exponent = m.group(1), m.group(2) - size = self._fontproperties.get_size_in_points() - fpexp = self._fontproperties.copy() - fpexp.set_size(0.7*size) - wb,hb = renderer.get_text_width_height(base, self._fontproperties, False) - we,he = renderer.get_text_width_height(exponent, fpexp, False) - - w = wb+we - - xb, yb = self._get_xy_display() - xe = xb+1.1*wb - ye = yb+0.5*hb - h = ye+he-yb - - - - - if self._horizontalalignment=='center': xo = -w/2. - elif self._horizontalalignment=='right': xo = -w - else: xo = 0 - if self._verticalalignment=='center': yo = -hb/2. - elif self._verticalalignment=='top': yo = -hb - else: yo = 0 - - xb += xo - yb += yo - xe += xo - ye += yo - bbox = lbwh_to_bbox(xb, yb, w, h) - - if renderer.flipy(): - canvasw, canvash = renderer.get_canvas_width_height() - yb = canvash-yb - ye = canvash-ye - - - val = ( bbox, ((base, xb, yb), (exponent, xe, ye, fpexp))) - self.cached[key] = val - - return val - artist.kwdocd['Text'] = artist.kwdoc(Text) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <js...@us...> - 2007-08-30 15:32:27
|
Revision: 3759 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3759&view=rev Author: jswhit Date: 2007-08-30 08:32:25 -0700 (Thu, 30 Aug 2007) Log Message: ----------- better error message when matplotlib too old Modified Paths: -------------- trunk/toolkits/basemap/lib/matplotlib/toolkits/basemap/basemap.py Modified: trunk/toolkits/basemap/lib/matplotlib/toolkits/basemap/basemap.py =================================================================== --- trunk/toolkits/basemap/lib/matplotlib/toolkits/basemap/basemap.py 2007-08-30 15:12:27 UTC (rev 3758) +++ trunk/toolkits/basemap/lib/matplotlib/toolkits/basemap/basemap.py 2007-08-30 15:32:25 UTC (rev 3759) @@ -4,7 +4,7 @@ mpl_required_version = '0.90' if matplotlib_version < mpl_required_version: raise ImportError('your matplotlib is too old - basemap ' - 'requires at least %s'%mpl_required_version) + 'requires at least %s, you have %s'%(mpl_required_version,matplotlib_version)) from matplotlib.collections import LineCollection from matplotlib.patches import Ellipse, Circle, Polygon from matplotlib.lines import Line2D This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-08-30 15:12:29
|
Revision: 3758 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3758&view=rev Author: mdboom Date: 2007-08-30 08:12:27 -0700 (Thu, 30 Aug 2007) Log Message: ----------- Deal with Unicode and non-ASCII characters correctly when outputting Postscript with ps.useafm == True. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/afm.py trunk/matplotlib/lib/matplotlib/backends/backend_ps.py Modified: trunk/matplotlib/lib/matplotlib/afm.py =================================================================== --- trunk/matplotlib/lib/matplotlib/afm.py 2007-08-30 15:11:23 UTC (rev 3757) +++ trunk/matplotlib/lib/matplotlib/afm.py 2007-08-30 15:12:27 UTC (rev 3758) @@ -34,8 +34,8 @@ John D. Hunter <jdh...@ac...> """ - import sys, os +from _mathtext_data import uni2type1 #Convert string the a python type _to_int = int @@ -152,12 +152,13 @@ all the sample afm files I have """ - d = {} + ascii_d = {} + name_d = {} while 1: line = fh.readline() if not line: break line = line.rstrip() - if line.startswith('EndCharMetrics'): return d + if line.startswith('EndCharMetrics'): return ascii_d, name_d vals = line.split(';')[:4] if len(vals) !=4 : raise RuntimeError('Bad char metrics line: %s' % line) num = _to_int(vals[0].split()[1]) @@ -169,7 +170,8 @@ if name == 'Euro': num = 128 if num != -1: - d[num] = (wx, name, bbox) + ascii_d[num] = (wx, name, bbox) + name_d[name] = (wx, bbox) raise RuntimeError('Bad parse') def _parse_kern_pairs(fh): @@ -277,9 +279,9 @@ """ _sanity_check(fh) dhead = _parse_header(fh) - dcmetrics = _parse_char_metrics(fh) + dcmetrics_ascii, dcmetrics_name = _parse_char_metrics(fh) doptional = _parse_optional(fh) - return dhead, dcmetrics, doptional[0], doptional[1] + return dhead, dcmetrics_ascii, dcmetrics_name, doptional[0], doptional[1] class AFM: @@ -288,10 +290,12 @@ """ Parse the AFM file in file object fh """ - (dhead, dcmetrics, dkernpairs, dcomposite) = parse_afm(fh) + (dhead, dcmetrics_ascii, dcmetrics_name, dkernpairs, dcomposite) = \ + parse_afm(fh) self._header = dhead self._kern = dkernpairs - self._metrics = dcmetrics + self._metrics = dcmetrics_ascii + self._metrics_by_name = dcmetrics_name self._composite = dcomposite @@ -340,9 +344,16 @@ miny = 1e9 maxy = 0 left = 0 + if not isinstance(s, unicode): + s = s.decode() for c in s: if c == '\n': continue - wx, name, bbox = self._metrics[ord(c)] + name = uni2type1.get(ord(c), 'question') + try: + wx, bbox = self._metrics_by_name[name] + except KeyError: + name = 'question' + wx, bbox = self._metrics_by_name[name] l,b,w,h = bbox if l<left: left = l # find the width with kerning @@ -377,6 +388,13 @@ wx, name, bbox = self._metrics[c] return wx + def get_width_from_char_name(self, name): + """ + Get the width of the character from a type1 character name + """ + wx, bbox = self._metrics_by_name[name] + return wx + def get_height_char(self, c, isord=False): """ Get the height of character c from the bounding box. This is @@ -392,9 +410,16 @@ c2 """ name1, name2 = self.get_name_char(c1), self.get_name_char(c2) + return self.get_kern_dist_from_name(name1, name2) + + def get_kern_dist_from_name(self, name1, name2): + """ + Return the kerning pair distance (possibly 0) for chars c1 and + c2 + """ try: return self._kern[ (name1, name2) ] except: return 0 - + def get_fontname(self): "Return the font name, eg, Times-Roman" return self._header['FontName'] Modified: trunk/matplotlib/lib/matplotlib/backends/backend_ps.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2007-08-30 15:11:23 UTC (rev 3757) +++ trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2007-08-30 15:12:27 UTC (rev 3758) @@ -22,6 +22,7 @@ from matplotlib.ft2font import FT2Font, KERNING_DEFAULT, LOAD_NO_HINTING from matplotlib.ttconv import convert_ttf_to_ps from matplotlib.mathtext import MathTextParser +from matplotlib._mathtext_data import uni2type1 from matplotlib.text import Text from matplotlib.transforms import get_vec6_scales @@ -700,8 +701,10 @@ elif ismath: return self.draw_mathtext(gc, x, y, s, prop, angle) + elif isinstance(s, unicode): + return self.draw_unicode(gc, x, y, s, prop, angle) + elif rcParams['ps.useafm']: - if ismath: s = s[1:-1] font = self._get_font_afm(prop) l,b,w,h = font.get_str_bbox(s) @@ -735,8 +738,6 @@ """ % locals() self._draw_ps(ps, gc, None) - elif isinstance(s, unicode): - return self.draw_unicode(gc, x, y, s, prop, angle) else: font = self._get_font_ttf(prop) font.set_text(s, 0, flags=LOAD_NO_HINTING) @@ -762,50 +763,92 @@ """draw a unicode string. ps doesn't have unicode support, so we have to do this the hard way """ + if rcParams['ps.useafm']: + self.set_color(*gc.get_rgb()) - font = self._get_font_ttf(prop) + font = self._get_font_afm(prop) + fontname = font.get_fontname() + fontsize = prop.get_size_in_points() + scale = 0.001*fontsize - self.set_color(*gc.get_rgb()) - self.set_font(font.get_sfnt()[(1,0,0,6)], prop.get_size_in_points()) - self.track_characters(font, s) + thisx, thisy = 0, 0 + last_name = None + lines = [] + for c in s: + name = uni2type1.get(ord(c), 'question') + try: + width = font.get_width_from_char_name(name) + except KeyError: + name = 'question' + width = font.get_width_char('?') + if last_name is not None: + kern = font.get_kern_dist_from_name(last_name, name) + else: + kern = 0 + last_name = name + thisx += kern * scale + + lines.append('%f %f m /%s glyphshow'%(thisx, thisy, name)) - cmap = font.get_charmap() - lastgind = None - #print 'text', s - lines = [] - thisx, thisy = 0,0 - for c in s: - ccode = ord(c) - gind = cmap.get(ccode) - if gind is None: - ccode = ord('?') - name = '.notdef' - gind = 0 - else: - name = font.get_glyph_name(gind) - glyph = font.load_char(ccode, flags=LOAD_NO_HINTING) + thisx += width * scale - if lastgind is not None: - kern = font.get_kerning(lastgind, gind, KERNING_DEFAULT) - else: - kern = 0 - lastgind = gind - thisx += kern/64.0 - - lines.append('%f %f m /%s glyphshow'%(thisx, thisy, name)) - thisx += glyph.linearHoriAdvance/65536.0 - - - thetext = '\n'.join(lines) - ps = """gsave + thetext = "\n".join(lines) + ps = """\ +gsave +/%(fontname)s findfont +%(fontsize)s scalefont +setfont %(x)f %(y)f translate %(angle)f rotate %(thetext)s grestore -""" % locals() - self._pswriter.write(ps) + """ % locals() + self._pswriter.write(ps) + + else: + font = self._get_font_ttf(prop) + self.set_color(*gc.get_rgb()) + self.set_font(font.get_sfnt()[(1,0,0,6)], prop.get_size_in_points()) + self.track_characters(font, s) + cmap = font.get_charmap() + lastgind = None + #print 'text', s + lines = [] + thisx, thisy = 0,0 + for c in s: + ccode = ord(c) + gind = cmap.get(ccode) + if gind is None: + ccode = ord('?') + name = '.notdef' + gind = 0 + else: + name = font.get_glyph_name(gind) + glyph = font.load_char(ccode, flags=LOAD_NO_HINTING) + + if lastgind is not None: + kern = font.get_kerning(lastgind, gind, KERNING_DEFAULT) + else: + kern = 0 + lastgind = gind + thisx += kern/64.0 + + lines.append('%f %f m /%s glyphshow'%(thisx, thisy, name)) + thisx += glyph.linearHoriAdvance/65536.0 + + + thetext = '\n'.join(lines) + ps = """gsave + %(x)f %(y)f translate + %(angle)f rotate + %(thetext)s + grestore + """ % locals() + self._pswriter.write(ps) + + def draw_mathtext(self, gc, x, y, s, prop, angle): """ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-08-30 15:11:26
|
Revision: 3757 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3757&view=rev Author: mdboom Date: 2007-08-30 08:11:23 -0700 (Thu, 30 Aug 2007) Log Message: ----------- Remove the "markup" kwarg and rcParam everywhere and replace it with an automatic detection of math markup. Modified Paths: -------------- trunk/matplotlib/examples/accented_text.py trunk/matplotlib/examples/arrow_demo.py trunk/matplotlib/examples/dannys_example.py trunk/matplotlib/examples/histogram_demo.py trunk/matplotlib/examples/histogram_demo_canvasagg.py trunk/matplotlib/examples/integral_demo.py trunk/matplotlib/examples/legend_auto.py trunk/matplotlib/examples/mathtext_demo.py trunk/matplotlib/examples/mathtext_examples.py trunk/matplotlib/examples/quiver_demo.py trunk/matplotlib/examples/scatter_demo2.py trunk/matplotlib/examples/tex_demo.py trunk/matplotlib/examples/tex_unicode_demo.py trunk/matplotlib/examples/unicode_demo.py trunk/matplotlib/lib/matplotlib/config/mplconfig.py trunk/matplotlib/lib/matplotlib/config/rcsetup.py trunk/matplotlib/lib/matplotlib/legend.py trunk/matplotlib/lib/matplotlib/mathtext.py trunk/matplotlib/lib/matplotlib/quiver.py trunk/matplotlib/lib/matplotlib/rcsetup.py trunk/matplotlib/lib/matplotlib/table.py trunk/matplotlib/lib/matplotlib/text.py Modified: trunk/matplotlib/examples/accented_text.py =================================================================== --- trunk/matplotlib/examples/accented_text.py 2007-08-30 13:51:10 UTC (rev 3756) +++ trunk/matplotlib/examples/accented_text.py 2007-08-30 15:11:23 UTC (rev 3757) @@ -13,9 +13,9 @@ plot(range(10)) -title(r'$\ddot{o}\acute{e}\grave{e}\hat{O}\breve{i}\bar{A}\tilde{n}\vec{q}$', fontsize=20, markup="tex") +title(r'$\ddot{o}\acute{e}\grave{e}\hat{O}\breve{i}\bar{A}\tilde{n}\vec{q}$', fontsize=20) # shorthand is also supported and curly's are optional -xlabel(r"""$\"o\ddot o \'e\`e\~n\.x\^y$""", fontsize=20, markup="tex") +xlabel(r"""$\"o\ddot o \'e\`e\~n\.x\^y$""", fontsize=20) show() Modified: trunk/matplotlib/examples/arrow_demo.py =================================================================== --- trunk/matplotlib/examples/arrow_demo.py 2007-08-30 13:51:10 UTC (rev 3756) +++ trunk/matplotlib/examples/arrow_demo.py 2007-08-30 15:11:23 UTC (rev 3757) @@ -52,7 +52,7 @@ min_text_size = size label_text_size = size*2.5 text_params={'ha':'center', 'va':'center', 'family':'sans-serif',\ - 'fontweight':'bold', 'markup': 'tex'} + 'fontweight':'bold'} r2 = sqrt(2) deltas = {\ @@ -211,7 +211,7 @@ label = '$%s_{_{\mathrm{%s}}}$' % (orig_label[0], orig_label[1:]) text(x, y, label, size=label_text_size, ha='center', va='center', \ - color=labelcolor or fc, markup='tex') + color=labelcolor or fc) for p in positions.keys(): draw_arrow(p) Modified: trunk/matplotlib/examples/dannys_example.py =================================================================== --- trunk/matplotlib/examples/dannys_example.py 2007-08-30 13:51:10 UTC (rev 3756) +++ trunk/matplotlib/examples/dannys_example.py 2007-08-30 15:11:23 UTC (rev 3757) @@ -29,14 +29,14 @@ pylab.plot((-delta / 2, -delta / 2 + offset * 2), (height, height + offset), 'k', linewidth = 2) pylab.plot((delta / 2, delta / 2 - offset * 2), (height, height - offset), 'k', linewidth = 2) pylab.plot((delta / 2, delta / 2 - offset * 2), (height, height + offset), 'k', linewidth = 2) -pylab.text(-0.06, height - 0.06, r'$\delta$', {'color' : 'k', 'fontsize' : 24}, markup = 'tex') +pylab.text(-0.06, height - 0.06, r'$\delta$', {'color' : 'k', 'fontsize' : 24}) ## X-axis label pylab.xticks((-1, 0, 1), ('-1', '0', '1'), color = 'k', size = 20) ## Left Y-axis labels pylab.ylabel(r'\bf{phase field} $\phi$', {'color' : 'b', - 'fontsize' : 20 }, markup='tex') + 'fontsize' : 20 }) pylab.yticks((0, 0.5, 1), ('0', '.5', '1'), color = 'k', size = 20) ## Right Y-axis labels @@ -44,17 +44,16 @@ horizontalalignment = 'left', verticalalignment = 'center', rotation = 90, - clip_on = False, - markup = 'tex') + clip_on = False) pylab.text(1.01, -0.02, "-1", {'color' : 'k', 'fontsize' : 20}) pylab.text(1.01, 0.98, "1", {'color' : 'k', 'fontsize' : 20}) pylab.text(1.01, 0.48, "0", {'color' : 'k', 'fontsize' : 20}) ## level set equations -pylab.text(0.1, 0.85, r'$|\nabla\phi| = 1,$ \newline $ \frac{\partial \phi}{\partial t} + U|\nabla \phi| = 0$', {'color' : 'g', 'fontsize' : 20}, markup='tex') +pylab.text(0.1, 0.85, r'$|\nabla\phi| = 1,$ \newline $ \frac{\partial \phi}{\partial t} + U|\nabla \phi| = 0$', {'color' : 'g', 'fontsize' : 20}) ## phase field equations -pylab.text(0.2, 0.15, r'$\mathcal{F} = \int f\left( \phi, c \right) dV,$ \newline $ \frac{ \partial \phi } { \partial t } = -M_{ \phi } \frac{ \delta \mathcal{F} } { \delta \phi }$', {'color' : 'b', 'fontsize' : 20}, markup='tex') +pylab.text(0.2, 0.15, r'$\mathcal{F} = \int f\left( \phi, c \right) dV,$ \newline $ \frac{ \partial \phi } { \partial t } = -M_{ \phi } \frac{ \delta \mathcal{F} } { \delta \phi }$', {'color' : 'b', 'fontsize' : 20}) pylab.savefig('pfm-lsm.png') pylab.show() Modified: trunk/matplotlib/examples/histogram_demo.py =================================================================== --- trunk/matplotlib/examples/histogram_demo.py 2007-08-30 13:51:10 UTC (rev 3756) +++ trunk/matplotlib/examples/histogram_demo.py 2007-08-30 15:11:23 UTC (rev 3757) @@ -15,7 +15,7 @@ xlabel('Smarts') ylabel('Probability') -title(r'$\mathrm{Histogram\ of\ IQ:}\ \mu=100,\ \sigma=15$', markup='tex') +title(r'$\mathrm{Histogram\ of\ IQ:}\ \mu=100,\ \sigma=15$') axis([40, 160, 0, 0.03]) grid(True) Modified: trunk/matplotlib/examples/histogram_demo_canvasagg.py =================================================================== --- trunk/matplotlib/examples/histogram_demo_canvasagg.py 2007-08-30 13:51:10 UTC (rev 3756) +++ trunk/matplotlib/examples/histogram_demo_canvasagg.py 2007-08-30 15:11:23 UTC (rev 3757) @@ -33,7 +33,7 @@ ax.set_xlabel('Smarts') ax.set_ylabel('Probability') -ax.set_title(r'$\mathrm{Histogram of IQ: }\mu=100, \sigma=15$', markup='tex') +ax.set_title(r'$\mathrm{Histogram of IQ: }\mu=100, \sigma=15$') ax.set_xlim( (40, 160)) ax.set_ylim( (0, 0.03)) Modified: trunk/matplotlib/examples/integral_demo.py =================================================================== --- trunk/matplotlib/examples/integral_demo.py 2007-08-30 13:51:10 UTC (rev 3756) +++ trunk/matplotlib/examples/integral_demo.py 2007-08-30 15:11:23 UTC (rev 3757) @@ -23,7 +23,7 @@ text(0.5 * (a + b), 30, r"$\int_a^b f(x)\mathrm{d}x$", horizontalalignment='center', - fontsize=20, markup='tex') + fontsize=20) axis([0,10, 0, 180]) figtext(0.9, 0.05, 'x') Modified: trunk/matplotlib/examples/legend_auto.py =================================================================== --- trunk/matplotlib/examples/legend_auto.py 2007-08-30 13:51:10 UTC (rev 3756) +++ trunk/matplotlib/examples/legend_auto.py 2007-08-30 15:11:23 UTC (rev 3757) @@ -51,9 +51,9 @@ def fig_7(): figure(7) xx = x - (N/2.0) - plot(xx, (xx*xx)-1225, 'bo', label='$y=x^2$', markup='tex') - plot(xx, 25*xx, 'go', label='$y=25x$', markup='tex') - plot(xx, -25*xx, 'mo', label='$y=-25x$', markup='tex') + plot(xx, (xx*xx)-1225, 'bo', label='$y=x^2$') + plot(xx, 25*xx, 'go', label='$y=25x$') + plot(xx, -25*xx, 'mo', label='$y=-25x$') legend() def fig_8(): Modified: trunk/matplotlib/examples/mathtext_demo.py =================================================================== --- trunk/matplotlib/examples/mathtext_demo.py 2007-08-30 13:51:10 UTC (rev 3756) +++ trunk/matplotlib/examples/mathtext_demo.py 2007-08-30 15:11:23 UTC (rev 3757) @@ -13,12 +13,14 @@ x = npy.arange(0.0, 3.0, 0.1) ax.grid(True) -ax.set_xlabel(r'$\Delta_i^j$', fontsize=20, markup="tex") -ax.set_ylabel(r'$\Delta_{i+1}^j$', fontsize=20, markup="tex") +ax.set_xlabel(r'$\Delta_i^j$', fontsize=20) +ax.set_ylabel(r'$\Delta_{i+1}^j$', fontsize=20) tex = r'$\mathcal{R}\prod_{i=\alpha_{i+1}}^\infty a_i\sin(2 \pi f x_i)$' -ax.text(1, 1.6, tex, fontsize=20, va='bottom', markup="tex") +ax.text(1, 1.6, tex, fontsize=20, va='bottom') +ax.legend(("Foo", "Testing $x^2$")) + #title(r'$\Delta_i^j \hspace{0.4} \rm{versus} \hspace{0.4} \Delta_{i+1}^j$', fontsize=20) fig.savefig('mathtext_demo') Modified: trunk/matplotlib/examples/mathtext_examples.py =================================================================== --- trunk/matplotlib/examples/mathtext_examples.py 2007-08-30 13:51:10 UTC (rev 3756) +++ trunk/matplotlib/examples/mathtext_examples.py 2007-08-30 15:11:23 UTC (rev 3757) @@ -2,14 +2,18 @@ import os, sys, re +import gc + stests = [ r'Kerning: AVA $AVA$', + r'\$100.00 $\alpha$', + r'$\frac{\$100.00}{y}$', r'$x y$', r'$x+y\ x=y\ x<y\ x:y\ x,y\ x@y$', r'$100\%y\ x*y\ x/y x\$y$', r'$x\leftarrow y\ x\forall y\ x-y$', r'$x \sf x \bf x {\cal X} \rm x$', - r'$x\ x\,x\;x\quad x\qquad x\!x\hspace{0.5}y$', + r'$x\ x\,x\;x\quad x\qquad x\!x\hspace{ 0.5 }y$', r'$\{ \rm braces \}$', r'$\left[\left\lfloor\frac{5}{\frac{\left(3\right)}{4}} y\right)\right]$', r'$\left(x\right)$', @@ -59,10 +63,10 @@ yticks(arange(len(tests)) * -1) for i, s in enumerate(tests): print "%02d: %s" % (i, s) - text(0.1, -i, s, fontsize=20, markup="tex") + text(0.1, -i, s, fontsize=20) savefig('mathtext_example') - figure() + close('all') if '--latex' in sys.argv: fd = open("mathtext_examples.ltx", "w") Modified: trunk/matplotlib/examples/quiver_demo.py =================================================================== --- trunk/matplotlib/examples/quiver_demo.py 2007-08-30 13:51:10 UTC (rev 3756) +++ trunk/matplotlib/examples/quiver_demo.py 2007-08-30 15:11:23 UTC (rev 3757) @@ -18,8 +18,7 @@ figure() Q = quiver( U, V) qk = quiverkey(Q, 0.5, 0.92, 2, r'$2 \frac{m}{s}$', labelpos='W', - fontproperties={'weight': 'bold'}, - markup="tex") + fontproperties={'weight': 'bold'}) l,r,b,t = axis() dx, dy = r-l, t-b axis([l-0.05*dx, r+0.05*dx, b-0.05*dy, t+0.05*dy]) @@ -32,8 +31,7 @@ qk = quiverkey(Q, 0.9, 0.95, 2, r'$2 \frac{m}{s}$', labelpos='E', coordinates='figure', - fontproperties={'weight': 'bold'}, - markup="tex") + fontproperties={'weight': 'bold'}) axis([-1, 7, -1, 7]) title('scales with plot width, not view') @@ -41,7 +39,7 @@ figure() Q = quiver( X[::3, ::3], Y[::3, ::3], U[::3, ::3], V[::3, ::3], pivot='mid', color='r', units='inches' ) -qk = quiverkey(Q, 0.5, 0.03, 1, r'$1 \frac{m}{s}$', fontproperties={'weight': 'bold'}, markup="tex") +qk = quiverkey(Q, 0.5, 0.03, 1, r'$1 \frac{m}{s}$', fontproperties={'weight': 'bold'}) plot( X[::3, ::3], Y[::3, ::3], 'k.') axis([-1, 7, -1, 7]) title("pivot='mid'; every third arrow; units='inches'") @@ -52,8 +50,7 @@ Q = quiver( X, Y, U, V, M, units='x', pivot='tip', width=0.022, scale=1/0.15) qk = quiverkey(Q, 0.9, 1.05, 1, r'$1 \frac{m}{s}$', labelpos='E', - fontproperties={'weight': 'bold'}, - markup="tex") + fontproperties={'weight': 'bold'}) plot(X, Y, 'k.') axis([-1, 7, -1, 7]) title("scales with x view; pivot='tip'") @@ -63,7 +60,7 @@ Q = quiver( X[::3, ::3], Y[::3, ::3], U[::3, ::3], V[::3, ::3], color='r', units='x', linewidths=(2,), edgecolors=('k'), headaxislength=5 ) -qk = quiverkey(Q, 0.5, 0.03, 1, r'$1 \frac{m}{s}$', fontproperties={'weight': 'bold'}, markup="tex") +qk = quiverkey(Q, 0.5, 0.03, 1, r'$1 \frac{m}{s}$', fontproperties={'weight': 'bold'}) axis([-1, 7, -1, 7]) title("triangular head; scale with x view; black edges") Modified: trunk/matplotlib/examples/scatter_demo2.py =================================================================== --- trunk/matplotlib/examples/scatter_demo2.py 2007-08-30 13:51:10 UTC (rev 3756) +++ trunk/matplotlib/examples/scatter_demo2.py 2007-08-30 15:11:23 UTC (rev 3757) @@ -11,8 +11,8 @@ close = 0.003*intc.close[:-2]/0.003*intc.open[:-2] p = scatter(delta1[:-1], delta1[1:], c=close, s=volume, alpha=0.75) -xlabel(r'$\Delta_i$', size='x-large', markup='tex') -ylabel(r'$\Delta_{i+1}$', size='x-large', markup='tex') +xlabel(r'$\Delta_i$', size='x-large') +ylabel(r'$\Delta_{i+1}$', size='x-large') title(r'Volume and percent change') grid(True) #savefig('scatter_demo2') Modified: trunk/matplotlib/examples/tex_demo.py =================================================================== --- trunk/matplotlib/examples/tex_demo.py 2007-08-30 13:51:10 UTC (rev 3756) +++ trunk/matplotlib/examples/tex_demo.py 2007-08-30 15:11:23 UTC (rev 3757) @@ -23,10 +23,10 @@ s = cos(2*2*pi*t)+2 plot(t, s) -xlabel(r'\textbf{time (s)}', markup='tex') -ylabel(r'\textit{voltage (mV)}',fontsize=16, markup='tex') +xlabel(r'\textbf{time (s)}') +ylabel(r'\textit{voltage (mV)}',fontsize=16) title(r"\TeX\ is Number $\displaystyle\sum_{n=1}^\infty\frac{-e^{i\pi}}{2^n}$!", - fontsize=16, color='r', markup='tex') + fontsize=16, color='r') grid(True) savefig('tex_demo') Modified: trunk/matplotlib/examples/tex_unicode_demo.py =================================================================== --- trunk/matplotlib/examples/tex_unicode_demo.py 2007-08-30 13:51:10 UTC (rev 3756) +++ trunk/matplotlib/examples/tex_unicode_demo.py 2007-08-30 15:11:23 UTC (rev 3757) @@ -17,11 +17,11 @@ s = cos(2*2*pi*t)+2 plot(t, s) -xlabel(r'\textbf{time (s)}', markup='tex') +xlabel(r'\textbf{time (s)}') s = unicode(r'\textit{Velocity (\xB0/sec)}','latin-1') -ylabel(unicode(r'\textit{Velocity (\xB0/sec)}','latin-1'),fontsize=16, markup='tex') +ylabel(unicode(r'\textit{Velocity (\xB0/sec)}','latin-1'),fontsize=16) title(r"\TeX\ is Number $\displaystyle\sum_{n=1}^\infty\frac{-e^{i\pi}}{2^n}$!", - fontsize=16, color='r', markup='tex') + fontsize=16, color='r') grid(True) savefig('tex_demo') Modified: trunk/matplotlib/examples/unicode_demo.py =================================================================== --- trunk/matplotlib/examples/unicode_demo.py 2007-08-30 13:51:10 UTC (rev 3756) +++ trunk/matplotlib/examples/unicode_demo.py 2007-08-30 15:11:23 UTC (rev 3757) @@ -9,5 +9,5 @@ text( 0.5, 2.5, unicode('Institut f\xFCr Festk\xF6rperphysik', 'latin-1'), rotation=45) text( 1, 1.5, u'AVA (check kerning)') -savefig('test.svg') +savefig('test') show() Modified: trunk/matplotlib/lib/matplotlib/config/mplconfig.py =================================================================== --- trunk/matplotlib/lib/matplotlib/config/mplconfig.py 2007-08-30 13:51:10 UTC (rev 3756) +++ trunk/matplotlib/lib/matplotlib/config/mplconfig.py 2007-08-30 15:11:23 UTC (rev 3757) @@ -153,7 +153,6 @@ class text(TConfig): color = T.Trait('black',mplT.ColorHandler()) usetex = T.false - markup = T.Trait('plain', 'plain', 'tex') class latex(TConfig): unicode = T.false Modified: trunk/matplotlib/lib/matplotlib/config/rcsetup.py =================================================================== --- trunk/matplotlib/lib/matplotlib/config/rcsetup.py 2007-08-30 13:51:10 UTC (rev 3756) +++ trunk/matplotlib/lib/matplotlib/config/rcsetup.py 2007-08-30 15:11:23 UTC (rev 3757) @@ -203,11 +203,6 @@ parse_fontconfig_pattern(s) return s -validate_markup = ValidateInStrings( - 'markup', - ['plain', 'tex'], - ignorecase=True) - validate_verbose = ValidateInStrings('verbose',[ 'silent', 'helpful', 'debug', 'debug-annoying', ]) @@ -363,7 +358,6 @@ 'text.fontvariant' : ['normal', str], 'text.fontweight' : ['normal', str], 'text.fontsize' : ['medium', validate_fontsize], - 'text.markup' : ['plain', validate_markup], 'mathtext.cal' : ['cursive', validate_font_properties], 'mathtext.rm' : ['serif', validate_font_properties], Modified: trunk/matplotlib/lib/matplotlib/legend.py =================================================================== --- trunk/matplotlib/lib/matplotlib/legend.py 2007-08-30 13:51:10 UTC (rev 3756) +++ trunk/matplotlib/lib/matplotlib/legend.py 2007-08-30 15:11:23 UTC (rev 3757) @@ -123,8 +123,7 @@ handletextsep = None, # the space between the legend line and legend text axespad = None, # the border between the axes and legend edge - shadow = None, - markup = None + shadow = None ): """ parent # the artist that contains the legend @@ -204,7 +203,7 @@ else: self._xdata = npy.linspace(left, left + self.handlelen, self.numpoints) textleft = left+ self.handlelen+self.handletextsep - self.texts = self._get_texts(labels, textleft, top, markup) + self.texts = self._get_texts(labels, textleft, top) self.legendHandles = self._get_handles(handles, self.texts) @@ -405,7 +404,7 @@ 'return a list of text.Text instance in the legend' return silent_list('Text', self.texts) - def _get_texts(self, labels, left, upper, markup): + def _get_texts(self, labels, left, upper): # height in axes coords HEIGHT = self._approx_text_height() @@ -419,8 +418,7 @@ text=l, fontproperties=self.prop, verticalalignment='top', - horizontalalignment='left', - markup=markup + horizontalalignment='left' ) self._set_artist_props(text) ret.append(text) Modified: trunk/matplotlib/lib/matplotlib/mathtext.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mathtext.py 2007-08-30 13:51:10 UTC (rev 3756) +++ trunk/matplotlib/lib/matplotlib/mathtext.py 2007-08-30 15:11:23 UTC (rev 3757) @@ -1982,7 +1982,7 @@ math_delim =(~bslash + Literal('$')) - non_math = Regex(r"(?:[^$]|(?:\\\$))*" + non_math = Regex(r"(?:(?:\\[$])|[^$])*" ).setParseAction(self.non_math).setName("non_math").leaveWhitespace() self._expression << ( @@ -2056,7 +2056,8 @@ def non_math(self, s, loc, toks): #~ print "non_math", toks - symbols = [Char(c, self.get_state()) for c in toks[0]] + s = toks[0].replace(r'\$', '$') + symbols = [Char(c, self.get_state()) for c in s] hlist = Hlist(symbols) # We're going into math now, so set font to 'it' self.push_state() Modified: trunk/matplotlib/lib/matplotlib/quiver.py =================================================================== --- trunk/matplotlib/lib/matplotlib/quiver.py 2007-08-30 13:51:10 UTC (rev 3756) +++ trunk/matplotlib/lib/matplotlib/quiver.py 2007-08-30 15:11:23 UTC (rev 3757) @@ -173,14 +173,12 @@ self.labelpos = kw.pop('labelpos', 'N') self.labelcolor = kw.pop('labelcolor', None) self.fontproperties = kw.pop('fontproperties', dict()) - self.markup = kw.pop('markup', None) self.kw = kw _fp = self.fontproperties self.text = text.Text(text=label, horizontalalignment=self.halign[self.labelpos], verticalalignment=self.valign[self.labelpos], - fontproperties=font_manager.FontProperties(**_fp), - markup=self.markup) + fontproperties=font_manager.FontProperties(**_fp)) if self.labelcolor is not None: self.text.set_color(self.labelcolor) self._initialized = False Modified: trunk/matplotlib/lib/matplotlib/rcsetup.py =================================================================== --- trunk/matplotlib/lib/matplotlib/rcsetup.py 2007-08-30 13:51:10 UTC (rev 3756) +++ trunk/matplotlib/lib/matplotlib/rcsetup.py 2007-08-30 15:11:23 UTC (rev 3757) @@ -203,11 +203,6 @@ parse_fontconfig_pattern(s) return s -validate_markup = ValidateInStrings( - 'markup', - ['plain', 'tex'], - ignorecase=True) - validate_verbose = ValidateInStrings('verbose',[ 'silent', 'helpful', 'debug', 'debug-annoying', ]) @@ -363,7 +358,6 @@ 'text.fontvariant' : ['normal', str], 'text.fontweight' : ['normal', str], 'text.fontsize' : ['medium', validate_fontsize], - 'text.markup' : ['plain', validate_markup], 'mathtext.cal' : ['cursive', validate_font_properties], 'mathtext.rm' : ['serif', validate_font_properties], Modified: trunk/matplotlib/lib/matplotlib/table.py =================================================================== --- trunk/matplotlib/lib/matplotlib/table.py 2007-08-30 13:51:10 UTC (rev 3756) +++ trunk/matplotlib/lib/matplotlib/table.py 2007-08-30 15:11:23 UTC (rev 3757) @@ -47,8 +47,7 @@ fill=True, text='', loc=None, - fontproperties=None, - markup=None + fontproperties=None ): # Call base @@ -61,7 +60,7 @@ if loc is None: loc = 'right' self._loc = loc self._text = Text(x=xy[0], y=xy[1], text=text, - fontproperties=fontproperties, markup=markup) + fontproperties=fontproperties) self._text.set_clip_on(False) Modified: trunk/matplotlib/lib/matplotlib/text.py =================================================================== --- trunk/matplotlib/lib/matplotlib/text.py 2007-08-30 13:51:10 UTC (rev 3756) +++ trunk/matplotlib/lib/matplotlib/text.py 2007-08-30 15:11:23 UTC (rev 3757) @@ -146,7 +146,6 @@ fontproperties=None, # defaults to FontProperties() rotation=None, linespacing=None, - markup=None, **kwargs ): """ @@ -176,7 +175,6 @@ if linespacing is None: linespacing = 1.2 # Maybe use rcParam later. self._linespacing = linespacing - self.set_markup(markup) self.update(kwargs) #self.set_bbox(dict(pad=0)) __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd @@ -225,7 +223,6 @@ self._rotation = other._rotation self._picker = other._picker self._linespacing = other._linespacing - self._markup = other._markup def _get_layout(self, renderer): @@ -757,9 +754,14 @@ def is_math_text(self): if rcParams['text.usetex']: return 'TeX' - if self._markup.lower() == 'tex': - if not matplotlib._havemath: return False + + # Did we find an even number of non-escaped dollar signs? + # If so, treat is as math text. + s = self._text + dollar_count = s.count(r'$') - s.count(r'\$') + if dollar_count > 0 and dollar_count % 2 == 0: return True + return False def set_fontproperties(self, fp): @@ -770,20 +772,6 @@ """ self._fontproperties = fp - def set_markup(self, markup): - """ - Set the type of markup used for this text. - - ACCEPTS: 'plain' for plain text, 'tex' for TeX-like markup - None to use the default text.markup value. - """ - if markup is None: - self._markup = rcParams['text.markup'] - elif markup.lower() in ('plain', 'tex'): - self._markup = markup.lower() - else: - raise ValueError("Markup type must be 'plain' or 'tex'") - def _get_layout_super(self, renderer, m): """ a special case optimization if a log super and angle = 0 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-08-30 13:51:12
|
Revision: 3756 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3756&view=rev Author: mdboom Date: 2007-08-30 06:51:10 -0700 (Thu, 30 Aug 2007) Log Message: ----------- Reduce Ps files sizes when using mathtext Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/mathtext.py Modified: trunk/matplotlib/lib/matplotlib/mathtext.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mathtext.py 2007-08-30 13:41:52 UTC (rev 3755) +++ trunk/matplotlib/lib/matplotlib/mathtext.py 2007-08-30 13:51:10 UTC (rev 3756) @@ -315,6 +315,7 @@ class MathtextBackendPs(MathtextBackend): def __init__(self): self.pswriter = StringIO() + self.lastfont = None def render_glyph(self, ox, oy, info): oy = self.height - oy + info.offset @@ -322,12 +323,15 @@ fontsize = info.fontsize symbol_name = info.symbol_name - # TODO: Optimize out the font changes - - ps = """/%(postscript_name)s findfont + if (postscript_name, fontsize) != self.lastfont: + ps = """/%(postscript_name)s findfont %(fontsize)s scalefont setfont -%(ox)f %(oy)f moveto +""" % locals() + self.lastfont = postscript_name, fontsize + self.pswriter.write(ps) + + ps = """%(ox)f %(oy)f moveto /%(symbol_name)s glyphshow\n """ % locals() self.pswriter.write(ps) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-08-30 13:41:54
|
Revision: 3755 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3755&view=rev Author: mdboom Date: 2007-08-30 06:41:52 -0700 (Thu, 30 Aug 2007) Log Message: ----------- Fixes bounding box bug with Agg backend. Fixes spacing bug when using standard Ps fonts. Reduces memory usage by not caching mathtext expressions for too long. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/mathtext.py Modified: trunk/matplotlib/lib/matplotlib/mathtext.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mathtext.py 2007-08-30 13:38:22 UTC (rev 3754) +++ trunk/matplotlib/lib/matplotlib/mathtext.py 2007-08-30 13:41:52 UTC (rev 3755) @@ -253,9 +253,9 @@ def render_glyph(self, ox, oy, info): self._update_bbox(ox + info.metrics.xmin, - oy + info.metrics.ymin, + oy - info.metrics.ymax, ox + info.metrics.xmax, - oy + info.metrics.ymax) + oy - info.metrics.ymin) def render_rect_filled(self, x1, y1, x2, y2): self._update_bbox(x1, y1, x2, y2) @@ -265,7 +265,8 @@ bbox = self.bbox bbox = [bbox[0] - 2, bbox[1] - 2, bbox[2] + 2, bbox[3] + 2] self._switch_to_real_backend() - self.fonts_object.set_canvas_size(bbox[2] - bbox[0], bbox[3] - bbox[1]) + self.fonts_object.set_canvas_size( + bbox[2] - bbox[0], bbox[3] - bbox[1]) ship(-bbox[0], -bbox[1], box) return self.fonts_object.get_results(box) @@ -321,6 +322,8 @@ fontsize = info.fontsize symbol_name = info.symbol_name + # TODO: Optimize out the font changes + ps = """/%(postscript_name)s findfont %(fontsize)s scalefont setfont @@ -928,7 +931,7 @@ xmin, ymin, xmax, ymax = [val * scale for val in font.get_bbox_char(glyph)] metrics = Bunch( - advance = (xmax-xmin), + advance = font.get_width_char(glyph) * scale, width = font.get_width_char(glyph) * scale, height = font.get_height_char(glyph) * scale, xmin = xmin, @@ -2439,6 +2442,7 @@ cacheKey = (s, dpi, hash(prop)) result = self._cache.get(cacheKey) if result is not None: + del self._cache[cacheKey] return result if self._output == 'PS' and rcParams['ps.useafm']: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-08-30 13:38:24
|
Revision: 3754 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3754&view=rev Author: mdboom Date: 2007-08-30 06:38:22 -0700 (Thu, 30 Aug 2007) Log Message: ----------- Make examples match real defaults. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/mpl-data/matplotlibrc Modified: trunk/matplotlib/lib/matplotlib/mpl-data/matplotlibrc =================================================================== --- trunk/matplotlib/lib/matplotlib/mpl-data/matplotlibrc 2007-08-30 13:04:05 UTC (rev 3753) +++ trunk/matplotlib/lib/matplotlib/mpl-data/matplotlibrc 2007-08-30 13:38:22 UTC (rev 3754) @@ -164,12 +164,12 @@ # (See FontProperties for more details). # These settings are only used if mathtext.use_cm is False, otherwise, the # Bakoma TeX Computer Modern fonts are used. -#mathtext.cal : ['cursive'] -#mathtext.rm : ['serif'] -#mathtext.tt : ['monospace'] -#mathtext.it : ['serif'], style='oblique' -#mathtext.bf : ['serif'], weight='bold' -#mathtext.sf : ['sans-serif'] +#mathtext.cal : cursive +#mathtext.rm : serif +#mathtext.tt : monospace +#mathtext.it : serif:italic +#mathtext.bf : serif:bold +#mathtext.sf : sans #mathtext.use_cm : True #mathtext.fallback_to_cm : True # When True, use symbols from the Computer Modern # fonts when a symbol can not be found in one of This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-08-30 13:04:25
|
Revision: 3753 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3753&view=rev Author: mdboom Date: 2007-08-30 06:04:05 -0700 (Thu, 30 Aug 2007) Log Message: ----------- Fix bug where mathtext colors were not being set properly. 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-08-29 20:39:07 UTC (rev 3752) +++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-08-30 13:04:05 UTC (rev 3753) @@ -1348,8 +1348,8 @@ # this complication is avoided, but of course, those fonts can # not be subsetted. + self.check_gc(gc, gc._rgb) if ismath: return self.draw_mathtext(gc, x, y, s, prop, angle) - self.check_gc(gc, gc._rgb) fontsize = prop.get_size_in_points() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-08-29 20:39:20
|
Revision: 3752 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3752&view=rev Author: mdboom Date: 2007-08-29 13:39:07 -0700 (Wed, 29 Aug 2007) Log Message: ----------- Updated to match the real defaults. Modified Paths: -------------- trunk/matplotlib/matplotlibrc.template Modified: trunk/matplotlib/matplotlibrc.template =================================================================== --- trunk/matplotlib/matplotlibrc.template 2007-08-29 20:36:52 UTC (rev 3751) +++ trunk/matplotlib/matplotlibrc.template 2007-08-29 20:39:07 UTC (rev 3752) @@ -164,12 +164,12 @@ # (See FontProperties for more details). # These settings are only used if mathtext.use_cm is False, otherwise, the # Bakoma TeX Computer Modern fonts are used. -#mathtext.cal : "cursive" -#mathtext.rm : "serif" -#mathtext.tt : "monospace" -#mathtext.it : "serif:italic" -#mathtext.bf : "serif:bold" -#mathtext.sf : "sans" +#mathtext.cal : cursive +#mathtext.rm : serif +#mathtext.tt : monospace +#mathtext.it : serif:italic +#mathtext.bf : serif:bold +#mathtext.sf : sans #mathtext.use_cm : True #mathtext.fallback_to_cm : True # When True, use symbols from the Computer Modern # fonts when a symbol can not be found in one of This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-08-29 20:36:55
|
Revision: 3751 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3751&view=rev Author: mdboom Date: 2007-08-29 13:36:52 -0700 (Wed, 29 Aug 2007) Log Message: ----------- Updated to match the real defaults. Modified Paths: -------------- trunk/matplotlib/matplotlibrc.template Modified: trunk/matplotlib/matplotlibrc.template =================================================================== --- trunk/matplotlib/matplotlibrc.template 2007-08-29 17:54:42 UTC (rev 3750) +++ trunk/matplotlib/matplotlibrc.template 2007-08-29 20:36:52 UTC (rev 3751) @@ -164,12 +164,12 @@ # (See FontProperties for more details). # These settings are only used if mathtext.use_cm is False, otherwise, the # Bakoma TeX Computer Modern fonts are used. -#mathtext.cal : ['cursive'] -#mathtext.rm : ['serif'] -#mathtext.tt : ['monospace'] -#mathtext.it : ['serif'], style='oblique' -#mathtext.bf : ['serif'], weight='bold' -#mathtext.sf : ['sans-serif'] +#mathtext.cal : "cursive" +#mathtext.rm : "serif" +#mathtext.tt : "monospace" +#mathtext.it : "serif:italic" +#mathtext.bf : "serif:bold" +#mathtext.sf : "sans" #mathtext.use_cm : True #mathtext.fallback_to_cm : True # When True, use symbols from the Computer Modern # fonts when a symbol can not be found in one of This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-08-29 18:10:48
|
Revision: 3750 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3750&view=rev Author: mdboom Date: 2007-08-29 10:54:42 -0700 (Wed, 29 Aug 2007) Log Message: ----------- Fix leaks of FT2Font objects. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py trunk/matplotlib/lib/matplotlib/backends/backend_svg.py trunk/matplotlib/lib/matplotlib/mathtext.py Modified: trunk/matplotlib/lib/matplotlib/backends/backend_agg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007-08-28 20:29:37 UTC (rev 3749) +++ trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007-08-29 17:54:42 UTC (rev 3750) @@ -89,9 +89,7 @@ from _backend_agg import RendererAgg as _RendererAgg backend_version = 'v2.2' -_fontd = {} # a map from fname to font instances - class RendererAgg(RendererBase): """ The renderer handles all the drawing primitives using a graphics @@ -126,7 +124,8 @@ self.copy_from_bbox = self._renderer.copy_from_bbox self.restore_region = self._renderer.restore_region self.mathtext_parser = MathTextParser('Agg') - + self._fontd = {} + self.bbox = lbwh_to_bbox(0,0, self.width, self.height) if __debug__: verbose.report('RendererAgg.__init__ done', 'debug-annoying') @@ -298,12 +297,12 @@ 'debug-annoying') key = hash(prop) - font = _fontd.get(key) + font = self._fontd.get(key) if font is None: fname = findfont(prop) font = FT2Font(str(fname)) - _fontd[key] = font + self._fontd[key] = font font.clear() size = prop.get_size_in_points() Modified: trunk/matplotlib/lib/matplotlib/backends/backend_svg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2007-08-28 20:29:37 UTC (rev 3749) +++ trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2007-08-29 17:54:42 UTC (rev 3750) @@ -23,7 +23,6 @@ return manager -_fontd = {} _capstyle_d = {'projecting' : 'square', 'butt' : 'butt', 'round': 'round',} class RendererSVG(RendererBase): FONT_SCALE = 1200.0 @@ -41,6 +40,7 @@ self._clipd = {} self._char_defs = {} self.mathtext_parser = MathTextParser('SVG') + self.fontd = {} svgwriter.write(svgProlog%(width,height,width,height)) def _draw_svg_element(self, element, details, gc, rgbFace): @@ -56,11 +56,11 @@ def _get_font(self, prop): key = hash(prop) - font = _fontd.get(key) + font = self.fontd.get(key) if font is None: fname = findfont(prop) font = FT2Font(str(fname)) - _fontd[key] = font + self.fontd[key] = font font.clear() size = prop.get_size_in_points() font.set_size(size, 72.0) Modified: trunk/matplotlib/lib/matplotlib/mathtext.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mathtext.py 2007-08-28 20:29:37 UTC (rev 3749) +++ trunk/matplotlib/lib/matplotlib/mathtext.py 2007-08-29 17:54:42 UTC (rev 3750) @@ -430,6 +430,11 @@ self.mathtext_backend.fonts_object = self self.used_characters = {} + def destroy(self): + """Fix any cyclical references before the object is about + to be destroyed.""" + self.used_characters = None + def get_kern(self, font1, sym1, fontsize1, font2, sym2, fontsize2, dpi): """ @@ -461,7 +466,7 @@ xmin, xmax, ymin, ymax - the ink rectangle of the glyph iceberg - the distance from the baseline to the top of the glyph. horiBearingY in Truetype parlance, height in TeX parlance - """ + """ info = self._get_info(font, sym, fontsize, dpi) return info.metrics @@ -494,8 +499,10 @@ return self.mathtext_backend.get_results(box) def get_sized_alternatives_for_symbol(self, fontname, sym): - """Override if your font provides multiple sizes of the same - symbol.""" + """ + Override if your font provides multiple sizes of the same + symbol. + """ return [(fontname, sym)] class TruetypeFonts(Fonts): @@ -503,10 +510,6 @@ A generic base class for all font setups that use Truetype fonts (through ft2font) """ - """ - Use the Bakoma true type fonts for rendering - """ - # allocate a new set of fonts basepath = os.path.join( get_data_path(), 'fonts', 'ttf' ) class CachedFont: @@ -529,6 +532,14 @@ self.fonts['default'] = default_font + def destroy(self): + self.glyphd = None + for cached_font in self.fonts.values(): + cached_font.charmap = None + cached_font.glyphmap = None + cached_font.font = None + Fonts.destroy(self) + def _get_font(self, font): """Looks up a CachedFont with its charmap and inverse charmap. font may be a TeX font name (cal, rm, it etc.), or postscript name.""" @@ -2401,7 +2412,7 @@ ############################################################################## # MAIN -class MathTextParser: +class MathTextParser(object): """ Parse the math expression s, return the (bbox, fonts) tuple needed to render it. @@ -2453,7 +2464,10 @@ self._cache[cacheKey] = result # Free up the transient data structures self._parser.clear() - # Remove a cyclical reference + + # Fix cyclical references + font_output.destroy() font_output.mathtext_backend.fonts_object = None - + font_output.mathtext_backend = None + return result This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-08-28 20:29:39
|
Revision: 3749 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3749&view=rev Author: mdboom Date: 2007-08-28 13:29:37 -0700 (Tue, 28 Aug 2007) Log Message: ----------- Sped up get_valid_values to improve startup time. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/artist.py Modified: trunk/matplotlib/lib/matplotlib/artist.py =================================================================== --- trunk/matplotlib/lib/matplotlib/artist.py 2007-08-28 20:28:46 UTC (rev 3748) +++ trunk/matplotlib/lib/matplotlib/artist.py 2007-08-28 20:29:37 UTC (rev 3749) @@ -1,5 +1,5 @@ from __future__ import division -import sys +import sys, re from cbook import iterable, flatten from transforms import identity_transform import matplotlib.units as units @@ -484,6 +484,7 @@ aliases[fullname[4:]] = name[4:] return aliases + _get_valid_values_regex = re.compile(r"\n\s*ACCEPTS:\s*(.*)\n") def get_valid_values(self, attr): """ get the legal arguments for the setter associated with attr @@ -505,10 +506,10 @@ if docstring.startswith('alias for '): return None - for line in docstring.split('\n'): - line = line.lstrip() - if not line.startswith('ACCEPTS:'): continue - return line[8:].strip() + + match = self._get_valid_values_regex.search(docstring) + if match is not None: + return match.group(1) return 'unknown' def get_setters(self): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-08-28 20:28:50
|
Revision: 3748 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3748&view=rev Author: mdboom Date: 2007-08-28 13:28:46 -0700 (Tue, 28 Aug 2007) Log Message: ----------- Improved speed of revcmap -- a startup time offender. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/_cm.py Modified: trunk/matplotlib/lib/matplotlib/_cm.py =================================================================== --- trunk/matplotlib/lib/matplotlib/_cm.py 2007-08-28 19:49:53 UTC (rev 3747) +++ trunk/matplotlib/lib/matplotlib/_cm.py 2007-08-28 20:28:46 UTC (rev 3748) @@ -11,6 +11,7 @@ import matplotlib as mpl import matplotlib.colors as colors +from matplotlib.cbook import reversed LUTSIZE = mpl.rcParams['image.lut'] _binary_data = { @@ -5949,13 +5950,9 @@ def revcmap(data): data_r = {} - for key,val in data.iteritems(): - val = list(val) - valrev = val[::-1] - valnew = [] - for a,b,c in valrev: - valnew.append((1.-a,b,c)) - data_r[key]=valnew + for key, val in data.iteritems(): + valnew = [(1.-a, b, c) for a, b, c in reversed(val)] + data_r[key] = valnew return data_r cmapnames = datad.keys() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-08-28 19:50:03
|
Revision: 3747 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3747&view=rev Author: mdboom Date: 2007-08-28 12:49:53 -0700 (Tue, 28 Aug 2007) Log Message: ----------- A further optimization of the new dedent. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/cbook.py Modified: trunk/matplotlib/lib/matplotlib/cbook.py =================================================================== --- trunk/matplotlib/lib/matplotlib/cbook.py 2007-08-28 19:49:29 UTC (rev 3746) +++ trunk/matplotlib/lib/matplotlib/cbook.py 2007-08-28 19:49:53 UTC (rev 3747) @@ -577,7 +577,6 @@ _dedent_regex[nshift] = unindent result = unindent.sub("\n", s).strip() - print result return result This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-08-28 19:49:33
|
Revision: 3746 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3746&view=rev Author: mdboom Date: 2007-08-28 12:49:29 -0700 (Tue, 28 Aug 2007) Log Message: ----------- A further optimization of the new dedent. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/cbook.py Modified: trunk/matplotlib/lib/matplotlib/cbook.py =================================================================== --- trunk/matplotlib/lib/matplotlib/cbook.py 2007-08-28 19:20:08 UTC (rev 3745) +++ trunk/matplotlib/lib/matplotlib/cbook.py 2007-08-28 19:49:29 UTC (rev 3746) @@ -573,10 +573,11 @@ # beginning of each line. If it isn't in the cache, generate it. unindent = _dedent_regex.get(nshift, None) if unindent is None: - unindent = re.compile("\n\r?" + " ?" * nshift) + unindent = re.compile("\n\r? {0,%d}" % nshift) _dedent_regex[nshift] = unindent result = unindent.sub("\n", s).strip() + print result return result This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-08-28 19:20:13
|
Revision: 3745 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3745&view=rev Author: mdboom Date: 2007-08-28 12:20:08 -0700 (Tue, 28 Aug 2007) Log Message: ----------- Oops in last commit. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/cbook.py Modified: trunk/matplotlib/lib/matplotlib/cbook.py =================================================================== --- trunk/matplotlib/lib/matplotlib/cbook.py 2007-08-28 19:17:21 UTC (rev 3744) +++ trunk/matplotlib/lib/matplotlib/cbook.py 2007-08-28 19:20:08 UTC (rev 3745) @@ -572,7 +572,7 @@ # Get a regex that will remove *up to* nshift spaces from the # beginning of each line. If it isn't in the cache, generate it. unindent = _dedent_regex.get(nshift, None) - if unindent = None + if unindent is None: unindent = re.compile("\n\r?" + " ?" * nshift) _dedent_regex[nshift] = unindent This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-08-28 19:17:28
|
Revision: 3744 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3744&view=rev Author: mdboom Date: 2007-08-28 12:17:21 -0700 (Tue, 28 Aug 2007) Log Message: ----------- Use regular expressions to do dedenting. This is ~15X faster than the old implementation. dedent accounted for around 30% of the time spent in "import pylab", so was probably worthy of optimization, even if this regex approach is less clear. The results are identical to the old implementation, with the exception of a single docstring (in backend_bases.py) that needed to be fixed. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backend_bases.py trunk/matplotlib/lib/matplotlib/cbook.py Modified: trunk/matplotlib/lib/matplotlib/backend_bases.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backend_bases.py 2007-08-28 12:27:56 UTC (rev 3743) +++ trunk/matplotlib/lib/matplotlib/backend_bases.py 2007-08-28 19:17:21 UTC (rev 3744) @@ -1100,7 +1100,7 @@ return newCanvas def mpl_connect(self, s, func): - """\ + """ Connect event with string s to func. The signature of func is def func(event) Modified: trunk/matplotlib/lib/matplotlib/cbook.py =================================================================== --- trunk/matplotlib/lib/matplotlib/cbook.py 2007-08-28 12:27:56 UTC (rev 3743) +++ trunk/matplotlib/lib/matplotlib/cbook.py 2007-08-28 19:17:21 UTC (rev 3744) @@ -533,6 +533,12 @@ ret += pad + ' '.join(line) + '\n' return ret +# A regular expression used to determine the amount of space to +# remove. It looks for the first sequence of spaces immediately +# following the first newline, or at the beginning of the string. +_find_dedent_regex = re.compile("(?:(?:\n\r?)|^)( *)\S") +# A cache to hold the regexs that actually remove the indent. +_dedent_regex = {} def dedent(s): """ Remove excess indentation from docstrings. @@ -546,24 +552,34 @@ It is also faster in most cases. """ + # This implementation has a somewhat obtuse use of regular + # expressions. However, this function accounted for almost 30% of + # matplotlib startup time, so it is worthy of optimization at all + # costs. + if not s: # includes case of s is None return '' - lines = s.splitlines(False) - ii = 0 - while lines[ii].strip() == '': - ii += 1 - lines = lines[ii:] - nshift = len(lines[0]) - len(lines[0].lstrip()) - # Don't use first line in case of """blah... - if ii == 0 and len(lines) > 1: - nshift = len(lines[1]) - len(lines[1].lstrip()) - for i, line in enumerate(lines): - nwhite = len(line) - len(line.lstrip()) - lines[i] = line[min(nshift, nwhite):] - return '\n'.join(lines) + match = _find_dedent_regex.match(s) + if match is None: + return s + # This is the number of spaces to remove from the left-hand side. + nshift = match.end(1) - match.start(1) + if nshift == 0: + return s + # Get a regex that will remove *up to* nshift spaces from the + # beginning of each line. If it isn't in the cache, generate it. + unindent = _dedent_regex.get(nshift, None) + if unindent = None + unindent = re.compile("\n\r?" + " ?" * nshift) + _dedent_regex[nshift] = unindent + + result = unindent.sub("\n", s).strip() + return result + + def listFiles(root, patterns='*', recurse=1, return_folders=0): """ Recursively list files This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-08-28 15:31:56
|
Revision: 3743 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3743&view=rev Author: mdboom Date: 2007-08-28 05:27:56 -0700 (Tue, 28 Aug 2007) Log Message: ----------- Fix bug where some the images of some math expressions were truncated at the edges when using Agg backend. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py trunk/matplotlib/lib/matplotlib/mathtext.py Modified: trunk/matplotlib/lib/matplotlib/backends/backend_agg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007-08-27 19:34:23 UTC (rev 3742) +++ trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007-08-28 12:27:56 UTC (rev 3743) @@ -173,17 +173,21 @@ """ if __debug__: verbose.report('RendererAgg.draw_mathtext', 'debug-annoying') - width, height, fonts, used_characters = self.mathtext_parser.parse( - s, self.dpi.get(), prop) + ox, oy, width, height, fonts, used_characters = \ + self.mathtext_parser.parse(s, self.dpi.get(), prop) if angle == 90: width, height = height, width + ox, oy = oy, ox + x = int(x) - width + ox + y = int(y) - height + oy + else: + x = int(x) + ox + y = int(y) - height + oy for font in fonts: if angle == 90: font.horiz_image_to_vert_image() # <-- Rotate - self._renderer.draw_text( font, int(x)-width, int(y)-height, gc) - else: - self._renderer.draw_text( font, int(x), int(y)-height, gc) + self._renderer.draw_text( font, x, y, gc) if 0: self._renderer.draw_rectangle(gc, None, int(x), @@ -230,8 +234,8 @@ return n,m if ismath: - width, height, fonts, used_characters = self.mathtext_parser.parse( - s, self.dpi.get(), prop) + ox, oy, width, height, fonts, used_characters = \ + self.mathtext_parser.parse(s, self.dpi.get(), prop) return width, height font = self._get_agg_font(prop) font.set_text(s, 0.0, flags=LOAD_DEFAULT) # the width and height of unrotated string Modified: trunk/matplotlib/lib/matplotlib/mathtext.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mathtext.py 2007-08-27 19:34:23 UTC (rev 3742) +++ trunk/matplotlib/lib/matplotlib/mathtext.py 2007-08-28 12:27:56 UTC (rev 3743) @@ -215,7 +215,7 @@ class MathtextBackend(object): def __init__(self): - fonts_object = None + self.fonts_object = None def set_canvas_size(self, w, h): 'Dimension the drawing canvas; may be a noop' @@ -228,7 +228,7 @@ def render_filled_rect(self, x1, y1, x2, y2): raise NotImplementedError() - def get_results(self): + def get_results(self, box): """Return a backend specific tuple of things to return to the backend after all processing is done.""" raise NotImplementedError() @@ -236,7 +236,54 @@ def get_hinting_type(self): return LOAD_NO_HINTING -class MathtextBackendAgg(MathtextBackend): +class MathtextBackendBbox(MathtextBackend): + """A backend whose only purpose is to get a precise bounding box. + Only required for the Agg backend.""" + + def __init__(self, real_backend): + MathtextBackend.__init__(self) + self.bbox = [0, 0, 0, 0] + self.real_backend = real_backend + + def _update_bbox(self, x1, y1, x2, y2): + self.bbox = [min(self.bbox[0], x1), + min(self.bbox[1], y1), + max(self.bbox[2], x2), + max(self.bbox[3], y2)] + + def render_glyph(self, ox, oy, info): + self._update_bbox(ox + info.metrics.xmin, + oy + info.metrics.ymin, + ox + info.metrics.xmax, + oy + info.metrics.ymax) + + def render_rect_filled(self, x1, y1, x2, y2): + self._update_bbox(x1, y1, x2, y2) + + def get_results(self, box): + ship(0, 0, box) + bbox = self.bbox + bbox = [bbox[0] - 2, bbox[1] - 2, bbox[2] + 2, bbox[3] + 2] + self._switch_to_real_backend() + self.fonts_object.set_canvas_size(bbox[2] - bbox[0], bbox[3] - bbox[1]) + ship(-bbox[0], -bbox[1], box) + return self.fonts_object.get_results(box) + + def get_hinting_type(self): + return self.real_backend.get_hinting_type() + + def _switch_to_real_backend(self): + self.fonts_object.mathtext_backend = self.real_backend + self.real_backend.fonts_object = self.fonts_object + self.real_backend.ox = self.bbox[0] + self.real_backend.oy = self.bbox[1] + +class MathtextBackendAggRender(MathtextBackend): + def __init__(self): + self.ox = 0 + self.oy = 0 + MathtextBackend.__init__(self) + def set_canvas_size(self, w, h): MathtextBackend.set_canvas_size(self, w, h) for font in self.fonts_object.get_fonts(): @@ -248,10 +295,12 @@ def render_rect_filled(self, x1, y1, x2, y2): font = self.fonts_object.get_fonts()[0] - font.draw_rect_filled(x1, y1, x2, y2 - 1) + font.draw_rect_filled(x1, y1, x2, max(y2 - 1, y1)) - def get_results(self): - return (self.width, + def get_results(self, box): + return (self.ox, + self.oy, + self.width, self.height, self.fonts_object.get_fonts(), self.fonts_object.get_used_characters()) @@ -259,6 +308,9 @@ def get_hinting_type(self): return LOAD_DEFAULT +def MathtextBackendAgg(): + return MathtextBackendBbox(MathtextBackendAggRender()) + class MathtextBackendPs(MathtextBackend): def __init__(self): self.pswriter = StringIO() @@ -281,7 +333,8 @@ ps = "%f %f %f %f rectfill\n" % (x1, self.height - y2, x2 - x1, y2 - y1) self.pswriter.write(ps) - def get_results(self): + def get_results(self, box): + ship(0, 0, box) return (self.width, self.height, self.pswriter, @@ -302,7 +355,8 @@ def render_rect_filled(self, x1, y1, x2, y2): self.rects.append((x1, self.height - y2, x2 - x1, y2 - y1)) - def get_results(self): + def get_results(self, box): + ship(0, 0, box) return (self.width, self.height, self.glyphs, @@ -324,7 +378,8 @@ self.svg_rects.append( (x1, self.height - y1 + 1, x2 - x1, y2 - y1)) - def get_results(self): + def get_results(self, box): + ship(0, 0, box) svg_elements = Bunch(svg_glyphs = self.svg_glyphs, svg_rects = self.svg_rects) return (self.width, @@ -347,7 +402,8 @@ self.rects.append( (x1, y1 - self.height, x2 - x1, y2 - y1)) - def get_results(self): + def get_results(self, box): + ship(0, 0, box) return (self.width, self.height, self.glyphs, @@ -434,8 +490,8 @@ def get_used_characters(self): return self.used_characters - def get_results(self): - return self.mathtext_backend.get_results() + def get_results(self, box): + return self.mathtext_backend.get_results(box) def get_sized_alternatives_for_symbol(self, fontname, sym): """Override if your font provides multiple sizes of the same @@ -2384,17 +2440,16 @@ font_output = UnicodeFonts(prop, backend) fontsize = prop.get_size_in_points() + # This is a class variable so we don't rebuild the parser # with each request. if self._parser is None: self.__class__._parser = Parser() + box = self._parser.parse(s, font_output, fontsize, dpi) w, h = box.width, box.height + box.depth - w += 4 - h += 4 font_output.set_canvas_size(w, h) - ship(2, 2, box) - result = font_output.get_results() + result = font_output.get_results(box) self._cache[cacheKey] = result # Free up the transient data structures self._parser.clear() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-08-27 19:34:32
|
Revision: 3742 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3742&view=rev Author: mdboom Date: 2007-08-27 12:34:23 -0700 (Mon, 27 Aug 2007) Log Message: ----------- Better fontconfig pattern standards compliance. Added experimental (may be removed) fontconfig support. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/font_manager.py trunk/matplotlib/lib/matplotlib/fontconfig_pattern.py Modified: trunk/matplotlib/lib/matplotlib/font_manager.py =================================================================== --- trunk/matplotlib/lib/matplotlib/font_manager.py 2007-08-27 19:33:45 UTC (rev 3741) +++ trunk/matplotlib/lib/matplotlib/font_manager.py 2007-08-27 19:34:23 UTC (rev 3742) @@ -48,6 +48,8 @@ except ImportError: import pickle +USE_FONTCONFIG = False + verbose = matplotlib.verbose font_scalings = {'xx-small': 0.579, 'x-small': 0.694, 'small': 0.833, @@ -84,13 +86,14 @@ "/System/Library/Fonts/" ] -home = os.environ.get('HOME') -if home is not None: - # user fonts on OSX - path = os.path.join(home, 'Library', 'Fonts') - OSXFontDirectories.append(path) - path = os.path.join(home, '.fonts') - X11FontDirectories.append(path) +if not USE_FONTCONFIG: + home = os.environ.get('HOME') + if home is not None: + # user fonts on OSX + path = os.path.join(home, 'Library', 'Fonts') + OSXFontDirectories.append(path) + path = os.path.join(home, '.fonts') + X11FontDirectories.append(path) def win32FontDirectory(): """Return the user-specified font directory for Win32.""" @@ -609,10 +612,10 @@ family = rcParams['font.' + rcParams['font.family']] if is_string_like(family): family = [family] - slant = rcParams['font.style'] - variant = rcParams['font.variant'] - weight = rcParams['font.weight'] - stretch = rcParams['font.stretch'] + slant = [rcParams['font.style']] + variant = [rcParams['font.variant']] + weight = [rcParams['font.weight']] + stretch = [rcParams['font.stretch']] size = [rcParams['font.size']] file = None @@ -675,32 +678,35 @@ def get_style(self): """Return the font style. Values are: normal, italic or oblique.""" - return self.__props.slant + return self.__props.slant[0] def get_variant(self): """Return the font variant. Values are: normal or small-caps.""" - return self.__props.variant + return self.__props.variant[0] def get_weight(self): """ Return the font weight. See the FontProperties class for a a list of possible values. """ - return self.__props.weight + return self.__props.weight[0] def get_stretch(self): """ Return the font stretch or width. Options are: normal, narrow, condensed, or wide. """ - return self.__props.stretch + return self.__props.stretch[0] def get_size(self): """Return the font size.""" return float(self.__props.size[0]) def get_file(self): - return self.__props.file + if self.__props.file is not None: + return self.__props.file[0] + else: + return None def get_fontconfig_pattern(self): return generate_fontconfig_pattern(self.__props.__dict__) @@ -723,7 +729,7 @@ else: if style not in ('normal', 'italic', 'oblique'): raise ValueError("style must be normal, italic or oblique") - self.__props.slant = style + self.__props.slant = [style] def set_variant(self, variant): """Set the font variant. Values are: normal or small-caps.""" @@ -732,7 +738,7 @@ else: if variant not in ('normal', 'small-caps'): raise ValueError("variant must be normal or small-caps") - self.__props.variant = variant + self.__props.variant = [variant] def set_weight(self, weight): """ @@ -745,7 +751,7 @@ if (weight not in weight_dict and weight not in weight_dict.keys()): raise ValueError("weight is invalid") - self.__props.weight = weight + self.__props.weight = [weight] def set_stretch(self, stretch): """ @@ -755,7 +761,7 @@ if stretch is None: self.__props.__dict__.pop('stretch', None) else: - self.__props.stretch = stretch + self.__props.stretch = [stretch] def set_size(self, size): """Set the font size.""" @@ -774,13 +780,19 @@ self.__props.size = size def set_file(self, file): - self.__props.file = file + if file is None: + self.__props.__dict__.pop('file', None) + else: + self.__props.file = [file] get_size_in_points = get_size def set_fontconfig_pattern(self, pattern): self.__props.__dict__ = self._parse_fontconfig_pattern(pattern) - + + def add_property_pair(self, key, val): + self.__props.setdefault(key, []).append(val) + def copy(self): """Return a deep copy of self""" return FontProperties(_init = self.__props.__dict__) @@ -1026,29 +1038,60 @@ return self.defaultFont return fname +if USE_FONTCONFIG and sys.platform != 'win32': + import re -_fmcache = os.path.join(get_configdir(), 'fontManager.cache') + def fc_match(pattern, fontext): + import commands + ext = "." + fontext + status, output = commands.getstatusoutput('fc-match -sv "%s"' % pattern) + if status == 0: + for match in _fc_match_regex.finditer(output): + file = match.group(1) + if os.path.splitext(file)[1] == ext: + return file + return None -fontManager = None + _fc_match_regex = re.compile(r'\sfile:\s+"(.*)"') + _fc_match_cache = {} + + def findfont(prop, fontext='ttf'): + if not is_string_like(prop): + prop = prop.get_fontconfig_pattern() + cached = _fc_match_cache.get(prop) + if cached is not None: + return cached -def _rebuild(): - global fontManager - fontManager = FontManager() - pickle_dump(fontManager, _fmcache) - verbose.report("generated new fontManager") + result = fc_match(prop, fontext) + if result is None: + result = fc_match(':', fontext) -try: - fontManager = pickle_load(_fmcache) - verbose.report("Using fontManager instance from %s" % _fmcache) -except: - _rebuild() + _fc_match_cache[prop] = result + return result -def findfont(prop, **kw): - global fontManager - font = fontManager.findfont(prop, **kw) - if not os.path.exists(font): - verbose.report("%s returned by pickled fontManager does not exist" % font) +else: + _fmcache = os.path.join(get_configdir(), 'fontManager.cache') + + fontManager = None + + def _rebuild(): + global fontManager + fontManager = FontManager() + pickle_dump(fontManager, _fmcache) + verbose.report("generated new fontManager") + + try: + fontManager = pickle_load(_fmcache) + verbose.report("Using fontManager instance from %s" % _fmcache) + except: _rebuild() - font = fontManager.findfont(prop, **kw) - return font + def findfont(prop, **kw): + global fontManager + font = fontManager.findfont(prop, **kw) + if not os.path.exists(font): + verbose.report("%s returned by pickled fontManager does not exist" % font) + _rebuild() + font = fontManager.findfont(prop, **kw) + return font + Modified: trunk/matplotlib/lib/matplotlib/fontconfig_pattern.py =================================================================== --- trunk/matplotlib/lib/matplotlib/fontconfig_pattern.py 2007-08-27 19:33:45 UTC (rev 3741) +++ trunk/matplotlib/lib/matplotlib/fontconfig_pattern.py 2007-08-27 19:34:23 UTC (rev 3742) @@ -19,7 +19,7 @@ """ import re from matplotlib.pyparsing import Literal, OneOrMore, ZeroOrMore, \ - Optional, Regex, StringEnd, ParseException + Optional, Regex, StringEnd, ParseException, Suppress family_punc = r'\\\-:,' family_unescape = re.compile(r'\\([%s])' % family_punc).sub @@ -89,8 +89,12 @@ ).setParseAction(self._point_sizes) property =( (name - + Literal('=') - + value) + + Suppress(Literal('=')) + + value + + ZeroOrMore( + Suppress(Literal(',')) + + value) + ) | name ).setParseAction(self._property) @@ -142,9 +146,11 @@ if len(tokens) == 1: if tokens[0] in self._constants: key, val = self._constants[tokens[0]] - elif len(tokens) == 3: - key, op, val = tokens - self._properties[key] = val + self._properties.setdefault(key, []).append(val) + else: + key = tokens[0] + val = tokens[1:] + self._properties.setdefault(key, []).extend(val) return [] parse_fontconfig_pattern = FontconfigPatternParser().parse @@ -156,14 +162,9 @@ families = '' size = '' for key, val in d.items(): - if key == 'family': - families = [family_escape(r'\\\1', name) for name in val] - families = ','.join(families) - elif key == 'size': - size = '-' + ','.join([str(x) for x in val]) - elif val is not None: - val = value_escape(r'\\\1', str(val)) - props.append(":%s=%s" % (key, val)) - props = ''.join(props) - - return ''.join([families, size, props]) + if val is not None and val != []: + val = [value_escape(r'\\\1', str(x)) for x in val if x is not None] + if val != []: + val = ','.join(val) + props.append(":%s=%s" % (key, val)) + return ''.join(props) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-08-27 19:33:51
|
Revision: 3741 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3741&view=rev Author: mdboom Date: 2007-08-27 12:33:45 -0700 (Mon, 27 Aug 2007) Log Message: ----------- Allow markup kwarg in more places. Modified Paths: -------------- trunk/matplotlib/examples/quiver_demo.py trunk/matplotlib/lib/matplotlib/legend.py trunk/matplotlib/lib/matplotlib/quiver.py trunk/matplotlib/lib/matplotlib/table.py Modified: trunk/matplotlib/examples/quiver_demo.py =================================================================== --- trunk/matplotlib/examples/quiver_demo.py 2007-08-27 19:32:38 UTC (rev 3740) +++ trunk/matplotlib/examples/quiver_demo.py 2007-08-27 19:33:45 UTC (rev 3741) @@ -17,8 +17,9 @@ #1 figure() Q = quiver( U, V) -qk = quiverkey(Q, 0.5, 0.92, 2, '2 m/s', labelpos='W', - fontproperties={'weight': 'bold'}) +qk = quiverkey(Q, 0.5, 0.92, 2, r'$2 \frac{m}{s}$', labelpos='W', + fontproperties={'weight': 'bold'}, + markup="tex") l,r,b,t = axis() dx, dy = r-l, t-b axis([l-0.05*dx, r+0.05*dx, b-0.05*dy, t+0.05*dy]) @@ -28,10 +29,11 @@ #2 figure() Q = quiver( X, Y, U, V, units='width') -qk = quiverkey(Q, 0.9, 0.95, 2, '2 m/s', - labelpos='E', - coordinates='figure', - fontproperties={'weight': 'bold'}) +qk = quiverkey(Q, 0.9, 0.95, 2, r'$2 \frac{m}{s}$', + labelpos='E', + coordinates='figure', + fontproperties={'weight': 'bold'}, + markup="tex") axis([-1, 7, -1, 7]) title('scales with plot width, not view') @@ -39,7 +41,7 @@ figure() Q = quiver( X[::3, ::3], Y[::3, ::3], U[::3, ::3], V[::3, ::3], pivot='mid', color='r', units='inches' ) -qk = quiverkey(Q, 0.5, 0.03, 1, '1 m/s', fontproperties={'weight': 'bold'}) +qk = quiverkey(Q, 0.5, 0.03, 1, r'$1 \frac{m}{s}$', fontproperties={'weight': 'bold'}, markup="tex") plot( X[::3, ::3], Y[::3, ::3], 'k.') axis([-1, 7, -1, 7]) title("pivot='mid'; every third arrow; units='inches'") @@ -48,9 +50,10 @@ figure() M = sqrt(pow(U, 2) + pow(V, 2)) Q = quiver( X, Y, U, V, M, units='x', pivot='tip', width=0.022, scale=1/0.15) -qk = quiverkey(Q, 0.9, 1.05, 1, '1 m/s', +qk = quiverkey(Q, 0.9, 1.05, 1, r'$1 \frac{m}{s}$', labelpos='E', - fontproperties={'weight': 'bold'}) + fontproperties={'weight': 'bold'}, + markup="tex") plot(X, Y, 'k.') axis([-1, 7, -1, 7]) title("scales with x view; pivot='tip'") @@ -60,7 +63,7 @@ Q = quiver( X[::3, ::3], Y[::3, ::3], U[::3, ::3], V[::3, ::3], color='r', units='x', linewidths=(2,), edgecolors=('k'), headaxislength=5 ) -qk = quiverkey(Q, 0.5, 0.03, 1, '1 m/s', fontproperties={'weight': 'bold'}) +qk = quiverkey(Q, 0.5, 0.03, 1, r'$1 \frac{m}{s}$', fontproperties={'weight': 'bold'}, markup="tex") axis([-1, 7, -1, 7]) title("triangular head; scale with x view; black edges") Modified: trunk/matplotlib/lib/matplotlib/legend.py =================================================================== --- trunk/matplotlib/lib/matplotlib/legend.py 2007-08-27 19:32:38 UTC (rev 3740) +++ trunk/matplotlib/lib/matplotlib/legend.py 2007-08-27 19:33:45 UTC (rev 3741) @@ -123,7 +123,8 @@ handletextsep = None, # the space between the legend line and legend text axespad = None, # the border between the axes and legend edge - shadow= None, + shadow = None, + markup = None ): """ parent # the artist that contains the legend @@ -203,7 +204,7 @@ else: self._xdata = npy.linspace(left, left + self.handlelen, self.numpoints) textleft = left+ self.handlelen+self.handletextsep - self.texts = self._get_texts(labels, textleft, top) + self.texts = self._get_texts(labels, textleft, top, markup) self.legendHandles = self._get_handles(handles, self.texts) @@ -404,7 +405,7 @@ 'return a list of text.Text instance in the legend' return silent_list('Text', self.texts) - def _get_texts(self, labels, left, upper): + def _get_texts(self, labels, left, upper, markup): # height in axes coords HEIGHT = self._approx_text_height() @@ -419,6 +420,7 @@ fontproperties=self.prop, verticalalignment='top', horizontalalignment='left', + markup=markup ) self._set_artist_props(text) ret.append(text) Modified: trunk/matplotlib/lib/matplotlib/quiver.py =================================================================== --- trunk/matplotlib/lib/matplotlib/quiver.py 2007-08-27 19:32:38 UTC (rev 3740) +++ trunk/matplotlib/lib/matplotlib/quiver.py 2007-08-27 19:33:45 UTC (rev 3741) @@ -173,12 +173,14 @@ self.labelpos = kw.pop('labelpos', 'N') self.labelcolor = kw.pop('labelcolor', None) self.fontproperties = kw.pop('fontproperties', dict()) + self.markup = kw.pop('markup', None) self.kw = kw _fp = self.fontproperties self.text = text.Text(text=label, horizontalalignment=self.halign[self.labelpos], verticalalignment=self.valign[self.labelpos], - fontproperties=font_manager.FontProperties(**_fp)) + fontproperties=font_manager.FontProperties(**_fp), + markup=self.markup) if self.labelcolor is not None: self.text.set_color(self.labelcolor) self._initialized = False Modified: trunk/matplotlib/lib/matplotlib/table.py =================================================================== --- trunk/matplotlib/lib/matplotlib/table.py 2007-08-27 19:32:38 UTC (rev 3740) +++ trunk/matplotlib/lib/matplotlib/table.py 2007-08-27 19:33:45 UTC (rev 3741) @@ -47,6 +47,8 @@ fill=True, text='', loc=None, + fontproperties=None, + markup=None ): # Call base @@ -58,7 +60,8 @@ # Create text object if loc is None: loc = 'right' self._loc = loc - self._text = Text(x=xy[0], y=xy[1], text=text) + self._text = Text(x=xy[0], y=xy[1], text=text, + fontproperties=fontproperties, markup=markup) self._text.set_clip_on(False) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-08-27 19:32:41
|
Revision: 3740 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3740&view=rev Author: mdboom Date: 2007-08-27 12:32:38 -0700 (Mon, 27 Aug 2007) Log Message: ----------- Better mathtext error messages. Fix bug when using \sqrt without explicit root. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/mathtext.py Modified: trunk/matplotlib/lib/matplotlib/mathtext.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mathtext.py 2007-08-27 18:51:22 UTC (rev 3739) +++ trunk/matplotlib/lib/matplotlib/mathtext.py 2007-08-27 19:32:38 UTC (rev 3740) @@ -1932,7 +1932,14 @@ def parse(self, s, fonts_object, fontsize, dpi): self._state_stack = [self.State(fonts_object, 'default', fontsize, dpi)] - self._expression.parseString(s) + try: + self._expression.parseString(s) + except ParseException, err: + raise ValueError("\n".join([ + "", + err.line, + " " * (err.column - 1) + "^", + str(err)])) return self._expr # The state of the parser is maintained in a stack. Upon @@ -2155,7 +2162,7 @@ super = next1 sub = next2 else: - raise ParseFatalException("Subscript/superscript sequence is too long.") + raise ParseFatalException("Subscript/superscript sequence is too long. Use braces { } to remove ambiguity.") state = self.get_state() rule_thickness = state.font_output.get_underline_thickness( @@ -2277,7 +2284,7 @@ state.font, state.fontsize, state.dpi) if root is None: - root = Box() + root = Box(0., 0., 0.) else: if not isinstance(root, ParseResults): raise ParseFatalException( This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-08-27 18:51:29
|
Revision: 3739 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3739&view=rev Author: mdboom Date: 2007-08-27 11:51:22 -0700 (Mon, 27 Aug 2007) Log Message: ----------- Cleaned up some comments. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/mathtext.py Modified: trunk/matplotlib/lib/matplotlib/mathtext.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mathtext.py 2007-08-27 15:42:44 UTC (rev 3738) +++ trunk/matplotlib/lib/matplotlib/mathtext.py 2007-08-27 18:51:22 UTC (rev 3739) @@ -116,11 +116,6 @@ - Certainly there are some... -STATUS: - The *Unicode* classes were incomplete when I found them, and have - not been refactored to support intermingling of regular text and - math text yet. They are most likely broken. -- Michael Droettboom, July 2007 - Author : John Hunter <jdh...@ac...> Michael Droettboom <md...@st...> (rewrite based on TeX box layout algorithms) @@ -2400,9 +2395,3 @@ font_output.mathtext_backend.fonts_object = None return result - -# math_parse_s_ft2font = math_parse_s_ft2font_common('Agg') -# math_parse_s_ft2font_svg = math_parse_s_ft2font_common('SVG') -# math_parse_s_ps = math_parse_s_ft2font_common('PS') -# math_parse_s_pdf = math_parse_s_ft2font_common('PDF') -# math_parse_s_cairo = math_parse_s_ft2font_common('Cairo') This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-08-27 15:42:50
|
Revision: 3738 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3738&view=rev Author: mdboom Date: 2007-08-27 08:42:44 -0700 (Mon, 27 Aug 2007) Log Message: ----------- mathtext.* font rcParams now use fontconfig patterns to specify fonts. Support converting FontProperties objects to/from fontconfig patterns. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/config/mplconfig.py trunk/matplotlib/lib/matplotlib/config/mpltraits.py trunk/matplotlib/lib/matplotlib/config/rcsetup.py trunk/matplotlib/lib/matplotlib/font_manager.py trunk/matplotlib/lib/matplotlib/rcsetup.py trunk/matplotlib/lib/matplotlib/text.py Added Paths: ----------- trunk/matplotlib/lib/matplotlib/fontconfig_pattern.py Modified: trunk/matplotlib/lib/matplotlib/config/mplconfig.py =================================================================== --- trunk/matplotlib/lib/matplotlib/config/mplconfig.py 2007-08-26 06:56:07 UTC (rev 3737) +++ trunk/matplotlib/lib/matplotlib/config/mplconfig.py 2007-08-27 15:42:44 UTC (rev 3738) @@ -161,14 +161,12 @@ dvipnghack = T.false class mathtext(TConfig): - handler = mplT.FontPropertiesHandler - proxy = handler.FontPropertiesProxy - cal = T.Trait(proxy(['cursive']), handler()) - rm = T.Trait(proxy(['serif']), handler()) - tt = T.Trait(proxy(['monospace']), handler()) - it = T.Trait(proxy(['serif'], style='oblique'), handler()) - bf = T.Trait(proxy(['serif'], weight='bold'), handler()) - sf = T.Trait(proxy(['sans-serif']), handler()) + cal = T.Trait('cursive' , mplT.FontconfigPatternHandler()) + rm = T.Trait('serif' , mplT.FontconfigPatternHandler()) + tt = T.Trait('monospace' , mplT.FontconfigPatternHandler()) + it = T.Trait('serif:oblique' , mplT.FontconfigPatternHandler()) + bf = T.Trait('serif:bold' , mplT.FontconfigPatternHandler()) + sf = T.Trait('sans' , mplT.FontconfigPatternHandler()) use_cm = T.true fallback_to_cm = T.true Modified: trunk/matplotlib/lib/matplotlib/config/mpltraits.py =================================================================== --- trunk/matplotlib/lib/matplotlib/config/mpltraits.py 2007-08-26 06:56:07 UTC (rev 3737) +++ trunk/matplotlib/lib/matplotlib/config/mpltraits.py 2007-08-27 15:42:44 UTC (rev 3738) @@ -4,6 +4,9 @@ # Matplotlib-specific imports import cutils +# For the fontconfig pattern parser +from matplotlib.fontconfig_pattern import parse_fontconfig_pattern + # stolen from cbook def is_string_like(obj): if hasattr(obj, 'shape'): return 0 # this is a workaround @@ -145,64 +148,14 @@ 'prism', 'prism_r', 'spectral', 'spectral_r', 'spring', 'spring_r', 'summer', 'summer_r', 'winter', 'winter_r'] -class FontPropertiesHandler(T.TraitHandler): - class FontPropertiesProxy(object): - # In order to build a FontProperties object, various rcParams must - # already be known in order to set default values. That means a - # FontProperties object can not be created from a config file, - # since it depends on other values in the same config file. This - # proxy class is used as a temporary storage area for the settings - # in the config file, and the full FontProperties class is created - # only when the class is first used. It is defined here rather than - # in font_manager.py to avoid a cyclical import. - def __init__(self, - family = None, - style = None, - variant= None, - weight = None, - stretch= None, - size = None, - fname = None, # if this is set, it's a hardcoded filename to use - ): - self.__family = family - self.__style = style - self.__variant = variant - self.__weight = weight - self.__stretch = stretch - self.__size = size - self.__fname = fname - - self.__child = None - - def __get_child(self): - if self.__child is None: - from matplotlib.font_manager import FontProperties - self.__child = FontProperties( - family = self.__family, - style = self.__style, - variant = self.__variant, - weight = self.__weight, - stretch = self.__stretch, - size = self.__size, - fname = self.__fname) - return self.__child - - def __getattr__(self, attr): - return getattr(self.__get_child(), attr) - +class FontconfigPatternHandler(T.TraitHandler): + """This validates a fontconfig pattern by using the FontconfigPatternParser. + The results are not actually used here, since we can't instantiate a + FontProperties object at config-parse time.""" def validate(self, object, name, value): - from matplotlib.font_manager import FontProperties - if is_string_like(value): - try: - proxy = eval("FontProperties(%s)" % value, - {}, {'FontProperties': self.FontPropertiesProxy}) - except: - pass - else: - return proxy - else: - return value - self.error(object, name, value) - + # This will throw a ValueError if value does not parse correctly + parse_fontconfig_pattern(value) + return value + def info(self): - return 'a FontProperties object or a string containing the parameters to the FontProperties constructor.' + return """A fontconfig pattern. See the fontconfig user manual for more information.""" Modified: trunk/matplotlib/lib/matplotlib/config/rcsetup.py =================================================================== --- trunk/matplotlib/lib/matplotlib/config/rcsetup.py 2007-08-26 06:56:07 UTC (rev 3737) +++ trunk/matplotlib/lib/matplotlib/config/rcsetup.py 2007-08-27 15:42:44 UTC (rev 3738) @@ -9,6 +9,7 @@ """ import os +from matplotlib.fontconfig_pattern import parse_fontconfig_pattern class ValidateInStrings: def __init__(self, key, valid, ignorecase=False): @@ -197,64 +198,10 @@ return float(s) except ValueError: raise ValueError('not a valid font size') - -class FontPropertiesProxy: - # In order to build a FontProperties object, various rcParams must - # already be known in order to set default values. That means a - # FontProperties object can not be created from a config file, - # since it depends on other values in the same config file. This - # proxy class is used as a temporary storage area for the settings - # in the config file, and the full FontProperties class is created - # only when the class is first used. It is defined here rather than - # in font_manager.py to avoid a cyclical import. - def __init__(self, - family = None, - style = None, - variant= None, - weight = None, - stretch= None, - size = None, - fname = None, # if this is set, it's a hardcoded filename to use - ): - self.__family = family - self.__style = style - self.__variant = variant - self.__weight = weight - self.__stretch = stretch - self.__size = size - self.__fname = fname - - self.__child = None - - def __get_child(self): - if self.__child is None: - from font_manager import FontProperties - self.__child = FontProperties( - family = self.__family, - style = self.__style, - variant = self.__variant, - weight = self.__weight, - stretch = self.__stretch, - size = self.__size, - fname = self.__fname) - return self.__child - - def __getattr__(self, attr): - return getattr(self.__get_child(), attr) def validate_font_properties(s): - parsed = False - try: - prop = eval(u'FontProperties(%s)' % s, - {}, {'FontProperties': FontPropertiesProxy}) - except: - pass - else: - parsed = isinstance(prop, FontPropertiesProxy) - if not parsed: - raise ValueError( - 'Mathtext font specifier must be a set of arguments to the FontProperty constructor.') - return prop + parse_fontconfig_pattern(s) + return s validate_markup = ValidateInStrings( 'markup', @@ -418,12 +365,12 @@ 'text.fontsize' : ['medium', validate_fontsize], 'text.markup' : ['plain', validate_markup], - 'mathtext.cal' : [FontPropertiesProxy(['cursive']), validate_font_properties], - 'mathtext.rm' : [FontPropertiesProxy(['serif']), validate_font_properties], - 'mathtext.tt' : [FontPropertiesProxy(['monospace']), validate_font_properties], - 'mathtext.it' : [FontPropertiesProxy(['serif'], style='oblique'), validate_font_properties], - 'mathtext.bf' : [FontPropertiesProxy(['serif'], weight='bold'), validate_font_properties], - 'mathtext.sf' : [FontPropertiesProxy(['sans-serif']), validate_font_properties], + 'mathtext.cal' : ['cursive', validate_font_properties], + 'mathtext.rm' : ['serif', validate_font_properties], + 'mathtext.tt' : ['monospace', validate_font_properties], + 'mathtext.it' : ['serif:italic', validate_font_properties], + 'mathtext.bf' : ['serif:bold', validate_font_properties], + 'mathtext.sf' : ['sans\-serif', validate_font_properties], 'mathtext.use_cm' : [True, validate_bool], 'mathtext.fallback_to_cm' : [True, validate_bool], Modified: trunk/matplotlib/lib/matplotlib/font_manager.py =================================================================== --- trunk/matplotlib/lib/matplotlib/font_manager.py 2007-08-26 06:56:07 UTC (rev 3737) +++ trunk/matplotlib/lib/matplotlib/font_manager.py 2007-08-27 15:42:44 UTC (rev 3738) @@ -34,10 +34,14 @@ """ import os, sys, glob, shutil +from sets import Set import matplotlib from matplotlib import afm from matplotlib import ft2font from matplotlib import rcParams, get_home, get_configdir +from matplotlib.cbook import is_string_like +from matplotlib.fontconfig_pattern import \ + parse_fontconfig_pattern, generate_fontconfig_pattern try: import cPickle as pickle @@ -48,7 +52,7 @@ font_scalings = {'xx-small': 0.579, 'x-small': 0.694, 'small': 0.833, 'medium': 1.0, 'large': 1.200, 'x-large': 1.440, - 'xx-large': 1.728} + 'xx-large': 1.728, 'larger': 1.2, 'smaller': 0.833} weight_dict = {'light': 200, 'normal': 400, 'regular': 400, 'book': 400, 'medium': 500, 'roman': 500, 'semibold': 600, 'demibold': 600, @@ -552,8 +556,7 @@ for j in [600, 700, 800, 900]: font[j] = temp[700] - -class FontProperties: +class FontProperties(object): """ A class for storing and manipulating font properties. @@ -582,32 +585,37 @@ The default font property for TrueType fonts is: sans-serif, normal, normal, normal, 400, scalable. - The preferred usage of font sizes is to use the absolute values, e.g. + The preferred usage of font sizes is to use the relative values, e.g. large, instead of absolute font sizes, e.g. 12. This approach allows all text sizes to be made larger or smaller based on the font manager's default font size, i.e. by using the set_default_size() method of the font manager. - Examples: + This class will also accept a fontconfig pattern, if it is the only + argument provided. fontconfig patterns are described here: - # Load default font properties - >>> p = FontProperties() - >>> p.get_family() - ['Bitstream Vera Sans', 'Lucida Grande', 'Verdana', 'Geneva', 'Lucida', 'Arial', 'Helvetica', 'sans-serif'] + http://www.fontconfig.org/fontconfig-user.html - # Change font family to 'fantasy' - >>> p.set_family('fantasy') - >>> p.get_family() - ['Comic Sans MS', 'Chicago', 'Charcoal', 'Impact', 'Western', 'fantasy'] - - # Make these fonts highest priority in font family - >>> p.set_name(['foo', 'fantasy', 'bar', 'baz']) - Font name 'fantasy' is a font family. It is being deleted from the list. - >>> p.get_family() - ['foo', 'bar', 'baz', 'Comic Sans MS', 'Chicago', 'Charcoal', 'Impact', 'Western', 'fantasy'] - + Note that matplotlib's internal font manager and fontconfig use a + different algorithm to lookup fonts, so the results of the same pattern + may be different in matplotlib than in other applications that use + fontconfig. """ + class FontPropertiesSet(object): + """This class contains all of the default properties at the + class level, which are then overridden (only if provided) at + the instance level.""" + family = rcParams['font.' + rcParams['font.family']] + if is_string_like(family): + family = [family] + slant = rcParams['font.style'] + variant = rcParams['font.variant'] + weight = rcParams['font.weight'] + stretch = rcParams['font.stretch'] + size = [rcParams['font.size']] + file = None + def __init__(self, family = None, style = None, @@ -615,42 +623,51 @@ weight = None, stretch= None, size = None, - fname = None, # if this is set, it's a hardcoded filename to use + fname = None, # if this is set, it's a hardcoded filename to use + _init = None # used only by copy() ): + self.__props = self.FontPropertiesSet() - if family is None: family = rcParams['font.'+rcParams['font.family']] - if style is None: style = rcParams['font.style'] - if variant is None: variant= rcParams['font.variant'] - if weight is None: weight = rcParams['font.weight'] - if stretch is None: stretch= rcParams['font.stretch'] - if size is None: size = rcParams['font.size'] - + # This is used only by copy() + if _init is not None: + self.__props.__dict__.update(_init) + return + if isinstance(family, str): + # Treat family as a fontconfig pattern if it is the only + # parameter provided. + if (style is None and + variant is None and + weight is None and + stretch is None and + size is None and + fname is None): + self.__props.__dict__ = self._parse_fontconfig_pattern(family) + return family = [family] - self.__family = family - self.__style = style - self.__variant = variant - self.__weight = weight - self.__stretch = stretch - self.__size = size - self.__parent_size = fontManager.get_default_size() - self.fname = fname + self.set_family(family) + self.set_style(style) + self.set_variant(variant) + self.set_weight(weight) + self.set_stretch(stretch) + self.set_file(fname) + self.set_size(size) + + def _parse_fontconfig_pattern(self, pattern): + return parse_fontconfig_pattern(pattern) + def __hash__(self): - return hash( ( - tuple(self.__family), self.__style, self.__variant, - self.__weight, self.__stretch, self.__size, - self.__parent_size, self.fname)) + return hash(repr(self.__props)) def __str__(self): - return str((self.__family, self.__style, self.__variant, - self.__weight, self.__stretch, self.__size)) - + return self.get_fontconfig_pattern() + def get_family(self): """Return a list of font names that comprise the font family. """ - return self.__family + return self.__props.family def get_name(self): """Return the name of the font that best matches the font properties.""" @@ -658,120 +675,115 @@ def get_style(self): """Return the font style. Values are: normal, italic or oblique.""" - return self.__style + return self.__props.slant def get_variant(self): """Return the font variant. Values are: normal or small-caps.""" - return self.__variant + return self.__props.variant def get_weight(self): """ Return the font weight. See the FontProperties class for a a list of possible values. """ - return self.__weight + return self.__props.weight def get_stretch(self): """ Return the font stretch or width. Options are: normal, narrow, condensed, or wide. """ - return self.__stretch + return self.__props.stretch def get_size(self): """Return the font size.""" - return self.__size + return float(self.__props.size[0]) + def get_file(self): + return self.__props.file + + def get_fontconfig_pattern(self): + return generate_fontconfig_pattern(self.__props.__dict__) + def set_family(self, family): """ - Change the font family. Options are: serif, sans-serif, cursive, - fantasy, or monospace. + Change the font family. May be either an alias (generic name + is CSS parlance), such as: serif, sans-serif, cursive, + fantasy, or monospace, or a real font name. """ - try: - self.__family = rcParams['font.'+family] - if isinstance(self.__family, str): - self.__family = [self.__family] - except KeyError: - raise KeyError, '%s - use serif, sans-serif, cursive, fantasy, or monospace.' % family - - def set_name(self, names): - """ - Add one or more font names to the font family list. If the - font name is already in the list, then the font is given a higher - priority in the font family list. To change the font family, use the - set_family() method. - """ - - msg = "Font name '%s' is a font family. It is being deleted from the list." - font_family = ['serif', 'sans-serif', 'cursive', 'fantasy', - 'monospace'] - - if isinstance(names, str): - names = [names] - - # Remove family names from list of font names. - for name in names[:]: - if name.lower() in font_family: - verbose.report( msg % name) - while name in names: - names.remove(name.lower()) - - # Remove font names from family list. - for name in names: - while name in self.__family: - self.__family.remove(name) - - self.__family = names + self.__family - + if family is None: + self.__props.__dict__.pop('family', None) + else: + self.__props.family = family + def set_style(self, style): """Set the font style. Values are: normal, italic or oblique.""" - self.__style = style + if style is None: + self.__props.__dict__.pop('style', None) + else: + if style not in ('normal', 'italic', 'oblique'): + raise ValueError("style must be normal, italic or oblique") + self.__props.slant = style def set_variant(self, variant): """Set the font variant. Values are: normal or small-caps.""" - self.__variant = variant + if variant is None: + self.__props.__dict__.pop('variant', None) + else: + if variant not in ('normal', 'small-caps'): + raise ValueError("variant must be normal or small-caps") + self.__props.variant = variant def set_weight(self, weight): """ Set the font weight. See the FontProperties class for a a list of possible values. """ - self.__weight = weight + if weight is None: + self.__props.__dict__.pop('weight', None) + else: + if (weight not in weight_dict and + weight not in weight_dict.keys()): + raise ValueError("weight is invalid") + self.__props.weight = weight def set_stretch(self, stretch): """ Set the font stretch or width. Options are: normal, narrow, condensed, or wide. """ - self.__stretch = stretch + if stretch is None: + self.__props.__dict__.pop('stretch', None) + else: + self.__props.stretch = stretch def set_size(self, size): """Set the font size.""" - self.__size = size - - def get_size_in_points(self, parent_size=None): - """ - Return the size property as a numeric value. String values - are converted to their corresponding numeric value. - """ - if self.__size in font_scalings.keys(): - size = fontManager.get_default_size()*font_scalings[self.__size] - elif self.__size == 'larger': - size = self.__parent_size*1.2 - elif self.__size == 'smaller': - size = self.__parent_size/1.2 + if size is None: + self.__props.__dict__.pop('size', None) else: - size = self.__size - return float(size) + if is_string_like(size): + parent_size = fontManager.get_default_size() + scaling = font_scalings.get(size) + if scaling is not None: + size = parent_size * scaling + else: + size = parent_size + if isinstance(size, (int, float)): + size = [size] + self.__props.size = size + def set_file(self, file): + self.__props.file = file + + get_size_in_points = get_size + + def set_fontconfig_pattern(self, pattern): + self.__props.__dict__ = self._parse_fontconfig_pattern(pattern) + def copy(self): """Return a deep copy of self""" - return FontProperties(self.__family, - self.__style, - self.__variant, - self.__weight, - self.__stretch, - self.__size) + return FontProperties(_init = self.__props.__dict__) def ttfdict_to_fnames(d): 'flatten a ttfdict to all the filenames it contains' @@ -905,8 +917,10 @@ documentation for a description of the font finding algorithm. """ debug = False - if prop.fname is not None: - fname = prop.fname + if is_string_like(prop): + prop = FontProperties(prop) + fname = prop.get_file() + if fname is not None: verbose.report('findfont returning %s'%fname, 'debug') return fname @@ -957,6 +971,8 @@ if not font.has_key(weight): setWeights(font) + if not font.has_key(weight): + return None font = font[weight] if font.has_key(stretch): @@ -981,16 +997,19 @@ if fname is None: verbose.report('\tfindfont failed %(name)s, %(style)s, %(variant)s %(weight)s, %(stretch)s'%locals(), 'debug') else: - fontkey = FontKey(original_name, style, variant, weight, stretch, size) + fontkey = FontKey(",".join(prop.get_family()), style, variant, weight, stretch, size) add_filename(fontdict, fontkey, fname) verbose.report('\tfindfont found %(name)s, %(style)s, %(variant)s %(weight)s, %(stretch)s, %(size)s'%locals(), 'debug') verbose.report('findfont returning %s'%fname, 'debug') return fname - font_family_aliases = ['serif', 'sans-serif', 'cursive', 'fantasy', 'monospace'] + font_family_aliases = Set(['serif', 'sans-serif', 'cursive', + 'fantasy', 'monospace', 'sans']) for name in prop.get_family(): if name in font_family_aliases: + if name == 'sans': + name = 'sans-serif' for name2 in rcParams['font.' + name]: fname = lookup_name(name2) if fname: @@ -1001,9 +1020,9 @@ break if not fname: - fontkey = FontKey(original_name, style, variant, weight, stretch, size) + fontkey = FontKey(",".join(prop.get_family()), style, variant, weight, stretch, size) add_filename(fontdict, fontkey, self.defaultFont) - verbose.report('Could not match %s, %s, %s. Returning %s' % (name, style, variant, self.defaultFont)) + verbose.report('Could not match %s, %s, %s. Returning %s' % (name, style, weight, self.defaultFont)) return self.defaultFont return fname Added: trunk/matplotlib/lib/matplotlib/fontconfig_pattern.py =================================================================== --- trunk/matplotlib/lib/matplotlib/fontconfig_pattern.py (rev 0) +++ trunk/matplotlib/lib/matplotlib/fontconfig_pattern.py 2007-08-27 15:42:44 UTC (rev 3738) @@ -0,0 +1,169 @@ +""" +A module for parsing a fontconfig pattern. + +This class is defined here because it must be available in: + - The old-style config framework (rcsetup.py) + - The traits-based config framework (mpltraits.py) + - The font manager (font_manager.py) + +It probably logically belongs in font_manager.py, but +placing it in any of these places would have created cyclical +dependency problems, or an undesired dependency on traits even +when the traits-based config framework is not used. + +See here for a rough specification of these patterns: +http://www.fontconfig.org/fontconfig-user.html + +Author : Michael Droettboom <md...@st...> +License : matplotlib license (PSF compatible) +""" +import re +from matplotlib.pyparsing import Literal, OneOrMore, ZeroOrMore, \ + Optional, Regex, StringEnd, ParseException + +family_punc = r'\\\-:,' +family_unescape = re.compile(r'\\([%s])' % family_punc).sub +family_escape = re.compile(r'([%s])' % family_punc).sub + +value_punc = r'\\=_:,' +value_unescape = re.compile(r'\\([%s])' % value_punc).sub +value_escape = re.compile(r'([%s])' % value_punc).sub + +class FontconfigPatternParser: + """A simple pyparsing-based parser for fontconfig-style patterns. + + See here for a rough specification of these patterns: + http://www.fontconfig.org/fontconfig-user.html + """ + + + _constants = { + 'thin' : ('weight', 'light'), + 'extralight' : ('weight', 'light'), + 'ultralight' : ('weight', 'light'), + 'light' : ('weight', 'light'), + 'book' : ('weight', 'book'), + 'regular' : ('weight', 'regular'), + 'normal' : ('weight', 'normal'), + 'medium' : ('weight', 'medium'), + 'demibold' : ('weight', 'demibold'), + 'semibold' : ('weight', 'semibold'), + 'bold' : ('weight', 'bold'), + 'extrabold' : ('weight', 'extra bold'), + 'black' : ('weight', 'black'), + 'heavy' : ('weight', 'heavy'), + 'roman' : ('slant', 'normal'), + 'italic' : ('slant', 'italic'), + 'oblique' : ('slant', 'oblique'), + 'ultracondensed' : ('width', 'ultra-condensed'), + 'extracondensed' : ('width', 'extra-condensed'), + 'condensed' : ('width', 'condensed'), + 'semicondensed' : ('width', 'semi-condensed'), + 'expanded' : ('width', 'expanded'), + 'extraexpanded' : ('width', 'extra-expanded'), + 'ultraexpanded' : ('width', 'ultra-expanded') + } + + def __init__(self): + family = Regex(r'([^%s]|(\\[%s]))*' % + (family_punc, family_punc)) \ + .setParseAction(self._family) + size = Regex(r'[0-9.]+') \ + .setParseAction(self._size) + name = Regex(r'[a-z]+') \ + .setParseAction(self._name) + value = Regex(r'([^%s]|(\\[%s]))*' % + (value_punc, value_punc)) \ + .setParseAction(self._value) + + families =(family + + ZeroOrMore( + Literal(',') + + family) + ).setParseAction(self._families) + + point_sizes =(size + + ZeroOrMore( + Literal(',') + + size) + ).setParseAction(self._point_sizes) + + property =( (name + + Literal('=') + + value) + | name + ).setParseAction(self._property) + + pattern =(Optional( + families) + + Optional( + Literal('-') + + point_sizes) + + ZeroOrMore( + Literal(':') + + property) + + StringEnd() + ) + + self._parser = pattern + self.ParseException = ParseException + + def parse(self, pattern): + props = self._properties = {} + try: + self._parser.parseString(pattern) + except self.ParseException, e: + raise ValueError("Could not parse font string: '%s'\n%s" % (pattern, e)) + + self._properties = None + return props + + def _family(self, s, loc, tokens): + return [family_unescape(r'\1', tokens[0])] + + def _size(self, s, loc, tokens): + return [float(tokens[0])] + + def _name(self, s, loc, tokens): + return [tokens[0]] + + def _value(self, s, loc, tokens): + return [value_unescape(r'\1', tokens[0])] + + def _families(self, s, loc, tokens): + self._properties['family'] = tokens + return [] + + def _point_sizes(self, s, loc, tokens): + self._properties['size'] = tokens + return [] + + def _property(self, s, loc, tokens): + if len(tokens) == 1: + if tokens[0] in self._constants: + key, val = self._constants[tokens[0]] + elif len(tokens) == 3: + key, op, val = tokens + self._properties[key] = val + return [] + +parse_fontconfig_pattern = FontconfigPatternParser().parse + +def generate_fontconfig_pattern(d): + """Given a dictionary of key/value pairs, generates a fontconfig pattern + string.""" + props = [] + families = '' + size = '' + for key, val in d.items(): + if key == 'family': + families = [family_escape(r'\\\1', name) for name in val] + families = ','.join(families) + elif key == 'size': + size = '-' + ','.join([str(x) for x in val]) + elif val is not None: + val = value_escape(r'\\\1', str(val)) + props.append(":%s=%s" % (key, val)) + props = ''.join(props) + + return ''.join([families, size, props]) Modified: trunk/matplotlib/lib/matplotlib/rcsetup.py =================================================================== --- trunk/matplotlib/lib/matplotlib/rcsetup.py 2007-08-26 06:56:07 UTC (rev 3737) +++ trunk/matplotlib/lib/matplotlib/rcsetup.py 2007-08-27 15:42:44 UTC (rev 3738) @@ -9,6 +9,7 @@ """ import os +from matplotlib.fontconfig_pattern import parse_fontconfig_pattern class ValidateInStrings: def __init__(self, key, valid, ignorecase=False): @@ -197,64 +198,10 @@ return float(s) except ValueError: raise ValueError('not a valid font size') - -class FontPropertiesProxy(object): - # In order to build a FontProperties object, various rcParams must - # already be known in order to set default values. That means a - # FontProperties object can not be created from a config file, - # since it depends on other values in the same config file. This - # proxy class is used as a temporary storage area for the settings - # in the config file, and the full FontProperties class is created - # only when the class is first used. It is defined here rather than - # in font_manager.py to avoid a cyclical import. - def __init__(self, - family = None, - style = None, - variant= None, - weight = None, - stretch= None, - size = None, - fname = None, # if this is set, it's a hardcoded filename to use - ): - self.__family = family - self.__style = style - self.__variant = variant - self.__weight = weight - self.__stretch = stretch - self.__size = size - self.__fname = fname - - self.__child = None - - def __get_child(self): - if self.__child is None: - from font_manager import FontProperties - self.__child = FontProperties( - family = self.__family, - style = self.__style, - variant = self.__variant, - weight = self.__weight, - stretch = self.__stretch, - size = self.__size, - fname = self.__fname) - return self.__child - - def __getattr__(self, attr): - return getattr(self.__get_child(), attr) def validate_font_properties(s): - parsed = False - try: - prop = eval(u'FontProperties(%s)' % s, - {}, {'FontProperties': FontPropertiesProxy}) - except: - pass - else: - parsed = isinstance(prop, FontPropertiesProxy) - if not parsed: - raise ValueError( - 'Mathtext font specifier must be a set of arguments to the FontProperty constructor.') - return prop + parse_fontconfig_pattern(s) + return s validate_markup = ValidateInStrings( 'markup', @@ -418,12 +365,12 @@ 'text.fontsize' : ['medium', validate_fontsize], 'text.markup' : ['plain', validate_markup], - 'mathtext.cal' : [FontPropertiesProxy(['cursive']), validate_font_properties], - 'mathtext.rm' : [FontPropertiesProxy(['serif']), validate_font_properties], - 'mathtext.tt' : [FontPropertiesProxy(['monospace']), validate_font_properties], - 'mathtext.it' : [FontPropertiesProxy(['serif'], style='oblique'), validate_font_properties], - 'mathtext.bf' : [FontPropertiesProxy(['serif'], weight='bold'), validate_font_properties], - 'mathtext.sf' : [FontPropertiesProxy(['sans-serif']), validate_font_properties], + 'mathtext.cal' : ['cursive', validate_font_properties], + 'mathtext.rm' : ['serif', validate_font_properties], + 'mathtext.tt' : ['monospace', validate_font_properties], + 'mathtext.it' : ['serif:italic', validate_font_properties], + 'mathtext.bf' : ['serif:bold', validate_font_properties], + 'mathtext.sf' : ['sans\-serif', validate_font_properties], 'mathtext.use_cm' : [True, validate_bool], 'mathtext.fallback_to_cm' : [True, validate_bool], Modified: trunk/matplotlib/lib/matplotlib/text.py =================================================================== --- trunk/matplotlib/lib/matplotlib/text.py 2007-08-26 06:56:07 UTC (rev 3737) +++ trunk/matplotlib/lib/matplotlib/text.py 2007-08-27 15:42:44 UTC (rev 3738) @@ -162,6 +162,7 @@ if color is None: color = rcParams['text.color'] if fontproperties is None: fontproperties=FontProperties() + elif is_string_like(fontproperties): fontproperties=FontProperties(fontproperties) self.set_text(text) self.set_color(color) @@ -649,11 +650,11 @@ ACCEPTS: string eg, ['Sans' | 'Courier' | 'Helvetica' ...] """ - self._fontproperties.set_name(fontname) + self._fontproperties.set_family(fontname) def set_fontname(self, fontname): 'alias for set_name' - self.set_name(fontname) + self.set_family(fontname) def set_style(self, fontstyle): """ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ef...@us...> - 2007-08-27 14:37:30
|
Revision: 3737 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3737&view=rev Author: efiring Date: 2007-08-25 23:56:07 -0700 (Sat, 25 Aug 2007) Log Message: ----------- Added step plot based on patch by Manuel Metz Modified Paths: -------------- trunk/matplotlib/boilerplate.py trunk/matplotlib/examples/masked_demo.py trunk/matplotlib/lib/matplotlib/axes.py trunk/matplotlib/lib/matplotlib/pylab.py Added Paths: ----------- trunk/matplotlib/examples/step_demo.py Modified: trunk/matplotlib/boilerplate.py =================================================================== --- trunk/matplotlib/boilerplate.py 2007-08-24 18:17:51 UTC (rev 3736) +++ trunk/matplotlib/boilerplate.py 2007-08-26 06:56:07 UTC (rev 3737) @@ -80,6 +80,7 @@ 'specgram', 'spy', 'stem', + 'step', 'vlines', 'quiver', 'quiverkey', Modified: trunk/matplotlib/examples/masked_demo.py =================================================================== --- trunk/matplotlib/examples/masked_demo.py 2007-08-24 18:17:51 UTC (rev 3736) +++ trunk/matplotlib/examples/masked_demo.py 2007-08-26 06:56:07 UTC (rev 3737) @@ -6,15 +6,15 @@ break the line at the data gaps. ''' -import matplotlib.numerix.ma as M +import matplotlib.numerix.npyma as ma from pylab import * -x = M.arange(0, 2*pi, 0.02) -y = M.sin(x) +x = ma.arange(0, 2*pi, 0.02) +y = ma.sin(x) y1 = sin(2*x) y2 = sin(3*x) -ym1 = M.masked_where(y1 > 0.5, y1) -ym2 = M.masked_where(y2 < -0.5, y2) +ym1 = ma.masked_where(y1 > 0.5, y1) +ym2 = ma.masked_where(y2 < -0.5, y2) lines = plot(x, y, 'r', x, ym1, 'g', x, ym2, 'bo') setp(lines[0], linewidth = 4) Added: trunk/matplotlib/examples/step_demo.py =================================================================== --- trunk/matplotlib/examples/step_demo.py (rev 0) +++ trunk/matplotlib/examples/step_demo.py 2007-08-26 06:56:07 UTC (rev 3737) @@ -0,0 +1,24 @@ +import numpy as npy +from pylab import * + +x = npy.arange(1, 7, 0.4) +y0 = npy.sin(x) +y = y0.copy() + 2.5 + +step(x, y, label='pre (default)') + +y -= 0.5 +step(x, y, where='mid', label='mid') + +y -= 0.5 +step(x, y, where='post', label='post') + +y = npy.ma.masked_where((y0>-0.15)&(y0<0.15), y - 0.5) +step(x,y, label='masked (pre)') + +legend() + +xlim(0, 7) +ylim(-0.5, 4) + +show() Modified: trunk/matplotlib/lib/matplotlib/axes.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axes.py 2007-08-24 18:17:51 UTC (rev 3736) +++ trunk/matplotlib/lib/matplotlib/axes.py 2007-08-26 06:56:07 UTC (rev 3737) @@ -2964,7 +2964,59 @@ #### Specialized plotting + def step(self, x, y, *args, **kwargs): + ''' + step(x, y, *args, **kwargs) + x and y must be 1-D sequences, and it is assumed, but not checked, + that x is uniformly increasing. + + Make a step plot. The args and keyword args to step are the same + as the args to plot. See help plot for more info. + + Additional keyword args for step: + + * where: can be 'pre', 'post' or 'mid'; if 'pre', the + interval from x[i] to x[i+1] has level y[i]; + if 'post', that interval has level y[i+1]; + and if 'mid', the jumps in y occur half-way + between the x-values. Default is 'pre'. + ''' + + where = kwargs.pop('where', 'pre') + + if not cbook.iterable(x): + x = ma.array([x], dtype=npy.float_) + if not cbook.iterable(y): + y = ma.array([y], dtype=npy.float_) + + if where=='pre': + x2 = ma.zeros((2*len(x)-1,), npy.float_) + y2 = ma.zeros((2*len(y)-1,), npy.float_) + + x2[0::2], x2[1::2] = x, x[:-1] + y2[0::2], y2[1:-1:2] = y, y[1:] + + elif where=='post': + x2 = ma.zeros((2*len(x)-1,), npy.float_) + y2 = ma.zeros((2*len(y)-1,), npy.float_) + + x2[::2], x2[1:-1:2] = x, x[1:] + y2[0::2], y2[1::2] = y, y[:-1] + + elif where=='mid': + x2 = ma.zeros((2*len(x),), npy.float_) + y2 = ma.zeros((2*len(y),), npy.float_) + + x2[1:-1:2] = 0.5*(x[:-1]+x[1:]) + x2[2::2] = 0.5*(x[:-1]+x[1:]) + x2[0], x2[-1] = x[0], x[-1] + + y2[0::2], y2[1::2] = y, y + + return self.plot(x2, y2, *args, **kwargs) + + def bar(self, left, height, width=0.8, bottom=None, color=None, edgecolor=None, linewidth=None, yerr=None, xerr=None, ecolor=None, capsize=3, Modified: trunk/matplotlib/lib/matplotlib/pylab.py =================================================================== --- trunk/matplotlib/lib/matplotlib/pylab.py 2007-08-24 18:17:51 UTC (rev 3736) +++ trunk/matplotlib/lib/matplotlib/pylab.py 2007-08-26 06:56:07 UTC (rev 3737) @@ -1555,7 +1555,7 @@ def acorr(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -1576,7 +1576,7 @@ def arrow(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -1597,7 +1597,7 @@ def axhline(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -1618,7 +1618,7 @@ def axhspan(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -1639,7 +1639,7 @@ def axvline(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -1660,7 +1660,7 @@ def axvspan(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -1681,7 +1681,7 @@ def bar(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -1702,7 +1702,7 @@ def barh(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -1723,7 +1723,7 @@ def broken_barh(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -1744,7 +1744,7 @@ def boxplot(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -1765,7 +1765,7 @@ def cohere(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -1786,7 +1786,7 @@ def clabel(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -1807,7 +1807,7 @@ def contour(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -1828,7 +1828,7 @@ def contourf(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -1849,7 +1849,7 @@ def csd(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -1870,7 +1870,7 @@ def errorbar(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -1891,7 +1891,7 @@ def fill(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -1912,7 +1912,7 @@ def hist(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -1933,7 +1933,7 @@ def hlines(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -1954,7 +1954,7 @@ def imshow(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -1975,7 +1975,7 @@ def loglog(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -1996,7 +1996,7 @@ def pcolor(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -2017,7 +2017,7 @@ def pcolormesh(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -2038,7 +2038,7 @@ def pie(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -2059,7 +2059,7 @@ def plot(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -2080,7 +2080,7 @@ def plot_date(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -2101,7 +2101,7 @@ def psd(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -2122,7 +2122,7 @@ def scatter(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -2143,7 +2143,7 @@ def semilogx(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -2164,7 +2164,7 @@ def semilogy(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -2185,7 +2185,7 @@ def specgram(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -2206,7 +2206,7 @@ def spy(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -2227,7 +2227,7 @@ def stem(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -2245,10 +2245,31 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost +def step(*args, **kwargs): + # allow callers to override the hold state by passing hold=True|False + b = ishold() + h = kwargs.pop('hold', None) + if h is not None: + hold(h) + try: + ret = gca().step(*args, **kwargs) + draw_if_interactive() + except: + hold(b) + raise + + hold(b) + return ret +if Axes.step.__doc__ is not None: + step.__doc__ = dedent(Axes.step.__doc__) + """ +Addition kwargs: hold = [True|False] overrides default hold state""" + +# This function was autogenerated by boilerplate.py. Do not edit as +# changes will be lost def vlines(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -2269,7 +2290,7 @@ def quiver(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -2290,7 +2311,7 @@ def quiverkey(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -2311,7 +2332,7 @@ def xcorr(*args, **kwargs): # allow callers to override the hold state by passing hold=True|False b = ishold() - h = popd(kwargs, 'hold', None) + h = kwargs.pop('hold', None) if h is not None: hold(h) try: @@ -2582,3 +2603,4 @@ draw_if_interactive() + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |