From: <lee...@us...> - 2009-01-05 05:29:01
|
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. |