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. |