Revision: 6734
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6734&view=rev
Author:   leejjoon
Date:     2009-01-05 05:28:57 +0000 (Mon, 05 Jan 2009)

Log Message:
-----------
optional use of preview.sty in usetex mode

Modified Paths:
--------------
    trunk/matplotlib/CHANGELOG
    trunk/matplotlib/lib/matplotlib/backends/backend_agg.py
    trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py
    trunk/matplotlib/lib/matplotlib/backends/backend_ps.py
    trunk/matplotlib/lib/matplotlib/mpl-data/matplotlib.conf.template
    trunk/matplotlib/lib/matplotlib/rcsetup.py
    trunk/matplotlib/lib/matplotlib/texmanager.py

Added Paths:
-----------
    trunk/matplotlib/examples/pylab_examples/usetex_baseline_test.py

Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG  2009-01-02 17:56:15 UTC (rev 6733)
+++ trunk/matplotlib/CHANGELOG  2009-01-05 05:28:57 UTC (rev 6734)
@@ -1,3 +1,5 @@
+2009-01-05 optional use of preview.sty in usetex mode. - JJL
+
 2009-01-02 Allow multipage pdf files. - JKS
 
 2008-12-31 Improve pdf usetex by adding support for font effects

Added: trunk/matplotlib/examples/pylab_examples/usetex_baseline_test.py
===================================================================
--- trunk/matplotlib/examples/pylab_examples/usetex_baseline_test.py            
                (rev 0)
+++ trunk/matplotlib/examples/pylab_examples/usetex_baseline_test.py    
2009-01-05 05:28:57 UTC (rev 6734)
@@ -0,0 +1,76 @@
+
+import matplotlib
+import matplotlib.pyplot as plt
+import matplotlib.axes as maxes
+
+class Axes(maxes.Axes):
+    """
+    A hackish way to simultaneously draw texts w/ usetex=True and
+    usetex=False in the same figure. It does not work in the ps backend.
+    """
+    def __init__(self, *kl, **kw):
+        self.usetex = kw.pop("usetex", "False")
+        self.preview = kw.pop("preview", "False")
+
+        maxes.Axes.__init__(self, *kl, **kw)
+
+    def draw(self, renderer):
+        usetex = plt.rcParams["text.usetex"]
+        preview = plt.rcParams["text.latex.preview"]
+        plt.rcParams["text.usetex"] = self.usetex
+        plt.rcParams["text.latex.preview"] = self.preview
+
+        maxes.Axes.draw(self, renderer)
+
+        plt.rcParams["text.usetex"] = usetex
+        plt.rcParams["text.latex.preview"] = preview
+
+Subplot = maxes.subplot_class_factory(Axes)
+
+
+def test_window_extent(ax, usetex, preview):
+
+    va = "baseline"
+    ax.xaxis.set_visible(False)
+    ax.yaxis.set_visible(False)
+
+
+    #t = ax.text(0., 0., r"mlp", va="baseline", size=150)
+    text_kw = dict(va=va,
+                   size=50,
+                   bbox=dict(pad=0., ec="k", fc="none"))
+
+
+    test_strings = ["lg", r"$\frac{1}{2}\pi$",
+                    r"$p^{3^A}$", r"$p_{3_2}$"]
+
+    ax.axvline(0, color="r")
+
+    for i, s in enumerate(test_strings):
+
+        ax.axhline(i, color="r")
+        ax.text(0., 3-i, s, **text_kw)
+
+    ax.set_xlim(-0.1,1.1)
+    ax.set_ylim(-.8,3.9)
+
+
+    ax.set_title("usetex=%s\npreview=%s" % (str(usetex), str(preview)))
+
+
+
+F = plt.figure(figsize=(2.*3,6.5))
+
+for i, usetex, preview in [[0, False, False],
+                           [1, True, False],
+                           [2, True, True]]:
+    ax = Subplot(F, 1, 3, i+1, usetex=usetex, preview=preview)
+    F.add_subplot(ax)
+    F.subplots_adjust(top=0.85)
+
+    test_window_extent(ax, usetex=usetex, preview=preview)
+
+
+plt.draw()
+plt.show()
+

Modified: trunk/matplotlib/lib/matplotlib/backends/backend_agg.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py     2009-01-02 
17:56:15 UTC (rev 6733)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_agg.py     2009-01-05 
05:28:57 UTC (rev 6734)
@@ -146,10 +146,10 @@
             # todo: handle props
             size = prop.get_size_in_points()
             texmanager = self.get_texmanager()
-            Z = texmanager.get_grey(s, size, self.dpi)
-            m,n = Z.shape
-            # TODO: descent of TeX text (I am imitating backend_ps here -JKS)
-            return n, m, 0
+            fontsize = prop.get_size_in_points()
+            w, h, d = texmanager.get_text_width_height_descent(s, fontsize,
+                                                               renderer=self)
+            return w, h, d
 
         if ismath:
             ox, oy, width, height, descent, fonts, used_characters = \

Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py     2009-01-02 
17:56:15 UTC (rev 6733)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py     2009-01-05 
05:28:57 UTC (rev 6734)
@@ -612,7 +612,7 @@
         if 0:             flags |= 1 << 18 # TODO: force bold
 
         ft2font = FT2Font(fontfile)
-        
+
         descriptor = {
             'Type':        Name('FontDescriptor'),
             'FontName':    Name(t1font.prop['FontName']),
@@ -1602,12 +1602,10 @@
         if rcParams['text.usetex']:
             texmanager = self.get_texmanager()
             fontsize = prop.get_size_in_points()
-            dvifile = texmanager.make_dvi(s, fontsize)
-            dvi = dviread.Dvi(dvifile, 72)
-            page = iter(dvi).next()
-            dvi.close()
-            # A total height (including the descent) needs to be returned.
-            return page.width, page.height+page.descent, page.descent
+            w, h, d = texmanager.get_text_width_height_descent(s, fontsize,
+                                                               renderer=self)
+            return w, h, d
+
         if ismath:
             w, h, d, glyphs, rects, used_characters = \
                 self.mathtext_parser.parse(s, 72, prop)

Modified: trunk/matplotlib/lib/matplotlib/backends/backend_ps.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_ps.py      2009-01-02 
17:56:15 UTC (rev 6733)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_ps.py      2009-01-05 
05:28:57 UTC (rev 6734)
@@ -274,12 +274,9 @@
         if rcParams['text.usetex']:
             texmanager = self.get_texmanager()
             fontsize = prop.get_size_in_points()
-            l,b,r,t = texmanager.get_ps_bbox(s, fontsize)
-            w = (r-l)
-            h = (t-b)
-            # TODO: We need a way to get a good baseline from
-            # text.usetex
-            return w, h, 0
+            w, h, d = texmanager.get_text_width_height_descent(s, fontsize,
+                                                               renderer=self)
+            return w, h, d
 
         if ismath:
             width, height, descent, pswriter, used_characters = \

Modified: trunk/matplotlib/lib/matplotlib/mpl-data/matplotlib.conf.template
===================================================================
--- trunk/matplotlib/lib/matplotlib/mpl-data/matplotlib.conf.template   
2009-01-02 17:56:15 UTC (rev 6733)
+++ trunk/matplotlib/lib/matplotlib/mpl-data/matplotlib.conf.template   
2009-01-05 05:28:57 UTC (rev 6734)
@@ -357,6 +357,8 @@
         preamble = []
         # a boolean
         unicode = False
+        # a boolean
+        preview = False
 
 [verbose]
     # a file name or 'sys.stdout'

Modified: trunk/matplotlib/lib/matplotlib/rcsetup.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/rcsetup.py  2009-01-02 17:56:15 UTC (rev 
6733)
+++ trunk/matplotlib/lib/matplotlib/rcsetup.py  2009-01-05 05:28:57 UTC (rev 
6734)
@@ -386,6 +386,7 @@
     'text.usetex'         : [False, validate_bool],
     'text.latex.unicode'  : [False, validate_bool],
     'text.latex.preamble' : [[''], validate_stringlist],
+    'text.latex.preview' : [False, validate_bool],
     'text.dvipnghack'     : [None, validate_bool_maybe_none],
     'text.fontstyle'      : ['normal', str],
     'text.fontangle'      : ['normal', str],

Modified: trunk/matplotlib/lib/matplotlib/texmanager.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/texmanager.py       2009-01-02 17:56:15 UTC 
(rev 6733)
+++ trunk/matplotlib/lib/matplotlib/texmanager.py       2009-01-05 05:28:57 UTC 
(rev 6734)
@@ -45,6 +45,8 @@
 import matplotlib as mpl
 from matplotlib import rcParams
 from matplotlib._png import read_png
+import matplotlib.dviread as dviread
+import re
 
 DEBUG = False
 
@@ -262,12 +264,83 @@
 
         return texfile
 
+
+    _re_vbox = 
re.compile(r"MatplotlibBox:\(([\d.]+)pt\+([\d.]+)pt\)x([\d.]+)pt")
+
+    def make_tex_preview(self, tex, fontsize):
+        """
+        Generate a tex file to render the tex string at a specific
+        font size.  It uses the preview.sty to determin the dimension
+        (width, height, descent) of the output.
+
+        returns the file name
+        """
+        basefile = self.get_basefile(tex, fontsize)
+        texfile = '%s.tex'%basefile
+        fh = file(texfile, 'w')
+        custom_preamble = self.get_custom_preamble()
+        fontcmd = {'sans-serif' : r'{\sffamily %s}',
+                   'monospace'  : r'{\ttfamily %s}'}.get(self.font_family,
+                                                         r'{\rmfamily %s}')
+        tex = fontcmd % tex
+
+        if rcParams['text.latex.unicode']:
+            unicode_preamble = """\usepackage{ucs}
+\usepackage[utf8x]{inputenc}"""
+        else:
+            unicode_preamble = ''
+
+
+
+        # newbox, setbox, immediate, etc. are used to find the box
+        # extent of the rendered text.
+
+
+        s = r"""\documentclass{article}
+%s
+%s
+%s
+\usepackage[active,showbox,tightpage]{preview}
+%%\usepackage[papersize={72in,72in}, body={70in,70in}, 
margin={1in,1in}]{geometry}
+
+%% we override the default showbox as it is treated as an error and makes
+%% the exit status not zero
+\def\showbox#1{\immediate\write16{MatplotlibBox:(\the\ht#1+\the\dp#1)x\the\wd#1}}
+
+\begin{document}
+\begin{preview}
+{\fontsize{%f}{%f}%s}
+\end{preview}
+\end{document}
+""" % (self._font_preamble, unicode_preamble, custom_preamble,
+       fontsize, fontsize*1.25, tex)
+        if rcParams['text.latex.unicode']:
+            fh.write(s.encode('utf8'))
+        else:
+            try:
+                fh.write(s)
+            except UnicodeEncodeError, err:
+                mpl.verbose.report("You are using unicode and latex, but have "
+                            "not enabled the matplotlib 'text.latex.unicode' "
+                            "rcParam.", 'helpful')
+                raise
+
+        fh.close()
+
+        return texfile
+
+
     def make_dvi(self, tex, fontsize):
         """
         generates a dvi file containing latex's layout of tex string
 
         returns the file name
         """
+
+
+        if rcParams['text.latex.preview']:
+            return self.make_dvi_preview(tex, fontsize)
+
         basefile = self.get_basefile(tex, fontsize)
         dvifile = '%s.dvi'% basefile
 
@@ -298,6 +371,55 @@
 
         return dvifile
 
+
+    def make_dvi_preview(self, tex, fontsize):
+        """
+        generates a dvi file containing latex's layout of tex
+        string. It calls make_tex_preview() method and store the size
+        information (width, height, descent) in a separte file.
+
+        returns the file name
+        """
+        basefile = self.get_basefile(tex, fontsize)
+        dvifile = '%s.dvi'% basefile
+        baselinefile = '%s.baseline'% basefile
+
+        if DEBUG or not os.path.exists(dvifile) or \
+               not os.path.exists(baselinefile):
+            texfile = self.make_tex_preview(tex, fontsize)
+            outfile = basefile+'.output'
+            command = self._get_shell_cmd('cd "%s"'% self.texcache,
+                            'latex -interaction=nonstopmode %s > "%s"'\
+                            %(os.path.split(texfile)[-1], outfile))
+            mpl.verbose.report(command, 'debug')
+            exit_status = os.system(command)
+            try:
+                fh = file(outfile)
+                report = fh.read()
+                fh.close()
+
+            except IOError:
+                report = 'No latex error report available.'
+            if exit_status:
+                raise RuntimeError(('LaTeX was not able to process the 
following \
+string:\n%s\nHere is the full report generated by LaTeX: \n\n'% repr(tex)) + 
report)
+            else: mpl.verbose.report(report, 'debug')
+
+            # find the box extent information in the latex output
+            # file and store them in ".baseline" file
+            m = TexManager._re_vbox.search(report)
+            open(basefile+'.baseline',"w").write(" ".join(m.groups()))
+
+            for fname in glob.glob(basefile+'*'):
+                if fname.endswith('dvi'): pass
+                elif fname.endswith('tex'): pass
+                elif fname.endswith('baseline'): pass
+                else:
+                    try: os.remove(fname)
+                    except OSError: pass
+
+        return dvifile
+
     def make_png(self, tex, fontsize, dpi):
         """
         generates a png file containing latex's rendering of tex string
@@ -441,3 +563,37 @@
             self.rgba_arrayd[key] = Z
 
         return Z
+
+
+    def get_text_width_height_descent(self, tex, fontsize, renderer=None):
+        """
+        return width, heigth and descent of the text.
+        """
+
+        if renderer:
+            dpi_fraction = renderer.points_to_pixels(1.)
+        else:
+            dpi_fraction = 1.
+
+        if rcParams['text.latex.preview']:
+            # use preview.sty
+            basefile = self.get_basefile(tex, fontsize)
+            baselinefile = '%s.baseline'% basefile
+
+
+            if DEBUG or not os.path.exists(baselinefile):
+                dvifile = self.make_dvi_preview(tex, fontsize)
+
+            l = open(baselinefile).read().split()
+            height, depth, width = [float(l1)*dpi_fraction for l1 in l]
+            return width, height+depth, depth
+
+        else:
+            # use dviread. It sometimes returns a wrong descent.
+            dvifile = self.make_dvi(tex, fontsize)
+            dvi = dviread.Dvi(dvifile, 72*dpi_fraction)
+            page = iter(dvi).next()
+            dvi.close()
+            # A total height (including the descent) needs to be returned.
+            return page.width, page.height+page.descent, page.descent
+


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
_______________________________________________
Matplotlib-checkins mailing list
Matplotlib-checkins@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to