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