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.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to