From: <md...@us...> - 2008-06-11 15:49:22
|
Revision: 5471 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5471&view=rev Author: mdboom Date: 2008-06-11 08:49:11 -0700 (Wed, 11 Jun 2008) Log Message: ----------- Fix some mathtext scaling bugs Add new mathtext symbols Use mathtext to render math in the docs (the dog-fooding patch!) Move PNG reading/writing to its own module and remove it from _backend_agg and _image Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/doc/conf.py trunk/matplotlib/doc/devel/outline.rst trunk/matplotlib/doc/sphinxext/mathpng.py trunk/matplotlib/doc/users/mathtext.rst trunk/matplotlib/examples/pylab_examples/mathtext_examples.py trunk/matplotlib/lib/matplotlib/_mathtext_data.py trunk/matplotlib/lib/matplotlib/backends/backend_agg.py trunk/matplotlib/lib/matplotlib/backends/backend_svg.py trunk/matplotlib/lib/matplotlib/image.py trunk/matplotlib/lib/matplotlib/mathtext.py trunk/matplotlib/lib/matplotlib/texmanager.py trunk/matplotlib/matplotlibrc.template trunk/matplotlib/setup.py trunk/matplotlib/setupext.py trunk/matplotlib/src/_backend_agg.cpp trunk/matplotlib/src/_backend_agg.h trunk/matplotlib/src/_image.cpp trunk/matplotlib/src/_image.h trunk/matplotlib/src/ft2font.cpp trunk/matplotlib/src/ft2font.h Added Paths: ----------- trunk/matplotlib/doc/sphinxext/math_symbol_table.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2008-06-11 15:31:21 UTC (rev 5470) +++ trunk/matplotlib/CHANGELOG 2008-06-11 15:49:11 UTC (rev 5471) @@ -1,3 +1,13 @@ +2008-06-11 Use matplotlib.mathtext to render math expressions in + online docs - MGD + +2008-06-11 Move PNG loading/saving to its own extension module, and + remove duplicate code in _backend_agg.cpp and _image.cpp + that does the same thing - MGD + +2008-06-11 Numerous mathtext bugfixes, primarily related to + dpi-independence - MGD + 2008-06-10 Bar now applies the label only to the first patch only, and sets '_nolegend_' for the other patch labels. This lets autolegend work as expected for hist and bar - see Modified: trunk/matplotlib/doc/conf.py =================================================================== --- trunk/matplotlib/doc/conf.py 2008-06-11 15:31:21 UTC (rev 5470) +++ trunk/matplotlib/doc/conf.py 2008-06-11 15:49:11 UTC (rev 5471) @@ -27,7 +27,7 @@ # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['mathpng', 'sphinx.ext.autodoc'] +extensions = ['mathpng', 'math_symbol_table', 'sphinx.ext.autodoc'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -150,7 +150,11 @@ latex_logo = None # Additional stuff for the LaTeX preamble. -latex_preamble = '' +latex_preamble = """ + \usepackage{amsmath} + \usepackage{amsfonts} + \usepackage{amssymb} +""" # Documents to append as an appendix to all manuals. latex_appendices = [] Modified: trunk/matplotlib/doc/devel/outline.rst =================================================================== --- trunk/matplotlib/doc/devel/outline.rst 2008-06-11 15:31:21 UTC (rev 5470) +++ trunk/matplotlib/doc/devel/outline.rst 2008-06-11 15:49:11 UTC (rev 5471) @@ -113,13 +113,29 @@ ported over to rest and included in the API so the links from the user's guide tutorial work. + - There's nothing in the mathtext module that I really consider a + "public" API (i.e. that would be useful to people just doing + plots). If mathtext.py were to be documented, I would put it in + the developer's docs. Maybe I should just take the link in the + user's guide out. - MGD + #. This section might also benefit from a little more detail on the customizations that are possible (eg an example fleshing out the rc options a little bit). Admittedly, this is pretty clear from readin ghte rc file, but it might be helpful to a newbie. + - The only rcParam that is currently useful is mathtext.fontset, + which is documented here. The others only apply when + mathtext.fontset == 'custom', which I'd like to declare + "unsupported". It's really hard to get a good set of math fonts + working that way, though it might be useful in a bind when + someone has to use a specific wacky font for mathtext and only + needs basics, like sub/superscripts. - MGD + #. There is still a TODO in the file to include a complete list of symbols + - Done. It's pretty extensive, thanks to STIX... - MGD + coding guide (reviewed by EF) ----------------------------- Added: trunk/matplotlib/doc/sphinxext/math_symbol_table.py =================================================================== --- trunk/matplotlib/doc/sphinxext/math_symbol_table.py (rev 0) +++ trunk/matplotlib/doc/sphinxext/math_symbol_table.py 2008-06-11 15:49:11 UTC (rev 5471) @@ -0,0 +1,164 @@ +symbols = [ + ["Lower-case Greek", + 5, + r"""\alpha \beta \gamma \chi \delta \epsilon \eta \iota \kappa + \lambda \mu \nu \omega \phi \pi \psi \rho \sigma \tau \theta + \upsilon \xi \zeta \digamma \varepsilon \varkappa \varphi + \varpi \varrho \varsigma \vartheta"""], + ["Upper-case Greek", + 6, + r"""\Delta \Gamma \Lambda \Omega \Phi \Pi \Psi \Sigma \Theta + \Upsilon \Xi \mho \nabla"""], + ["Hebrew", + 4, + r"""\aleph \beth \daleth \gimel"""], + ["Delimiters", + 6, + r"""| \{ \lfloor / \Uparrow \llcorner \vert \} \rfloor \backslash + \uparrow \lrcorner \| \langle \lceil [ \Downarrow \ulcorner + \Vert \rangle \rceil ] \downarrow \urcorner"""], + ["Big symbols", + 5, + r"""\bigcap \bigcup \bigodot \bigoplus \bigotimes \biguplus + \bigvee \bigwedge \coprod \oint \prod \sum \int"""], + ["Standard Function Names", + 4, + r"""\arccos \csc \ker \min \arcsin \deg \lg \Pr \arctan \det \lim + \gcd \ln \sup \cot \hom \log \tan \coth \inf \max \tanh + \sec \arg \dim \liminf \sin \cos \exp \limsup \sinh \cosh"""], + ["Binary Operation and Relation Symbols", + 3, + r"""\ast \pm \slash \cap \star \mp \cup \cdot \uplus + \triangleleft \circ \odot \sqcap \triangleright \bullet \ominus + \sqcup \bigcirc \oplus \wedge \diamond \oslash \vee + \bigtriangledown \times \otimes \dag \bigtriangleup \div \wr + \ddag \barwedge \veebar \boxplus \curlywedge \curlyvee \boxminus + \Cap \Cup \boxtimes \bot \top \dotplus \boxdot \intercal + \rightthreetimes \divideontimes \leftthreetimes \equiv \leq \geq + \perp \cong \prec \succ \mid \neq \preceq \succeq \parallel \sim + \ll \gg \bowtie \simeq \subset \supset \Join \approx \subseteq + \supseteq \ltimes \asymp \sqsubset \sqsupset \rtimes \doteq + \sqsubseteq \sqsupseteq \smile \propto \dashv \vdash \frown + \models \in \ni \notin \approxeq \leqq \geqq \lessgtr \leqslant + \geqslant \lesseqgtr \backsim \lessapprox \gtrapprox \lesseqqgtr + \backsimeq \lll \ggg \gtreqqless \triangleq \lessdot \gtrdot + \gtreqless \circeq \lesssim \gtrsim \gtrless \bumpeq \eqslantless + \eqslantgtr \backepsilon \Bumpeq \precsim \succsim \between + \doteqdot \precapprox \succapprox \pitchfork \Subset \Supset + \fallingdotseq \subseteqq \supseteqq \risingdotseq \sqsubset + \sqsupset \varpropto \preccurlyeq \succcurlyeq \Vdash \therefore + \curlyeqprec \curlyeqsucc \vDash \because \blacktriangleleft + \blacktriangleright \Vvdash \eqcirc \trianglelefteq + \trianglerighteq \neq \vartriangleleft \vartriangleright \ncong + \nleq \ngeq \nsubseteq \nmid \nsupseteq \nparallel \nless \ngtr + \nprec \nsucc \subsetneq \nsim \supsetneq \nVDash \precnapprox + \succnapprox \subsetneqq \nvDash \precnsim \succnsim \supsetneqq + \nvdash \lnapprox \gnapprox \ntriangleleft \ntrianglelefteq + \lneqq \gneqq \ntriangleright \lnsim \gnsim \ntrianglerighteq + \approxident \origof \imageof \coloneq \triangleeq \stareq \nsime + \dotminus \eqsim \nequiv \Equiv \measeq \napprox \eqless + \kernelcontraction \nsupset \doublebarwedge \nVdash \arceq + \backcong \Doteq \eqdef \wedgeq \questeq \eqgtr \cupdot + \veeeq \nsubset \eqcolon \ne + """], + ["Arrow Symbols", + 2, + r"""\leftarrow \longleftarrow \uparrow \Leftarrow \Longleftarrow + \Uparrow \rightarrow \longrightarrow \downarrow \Rightarrow + \Longrightarrow \Downarrow \leftrightarrow \updownarrow + \longleftrightarrow \updownarrow \Leftrightarrow + \Longleftrightarrow \Updownarrow \mapsto \longmapsto \nearrow + \hookleftarrow \hookrightarrow \searrow \leftharpoonup + \rightharpoonup \swarrow \leftharpoondown \rightharpoondown + \nwarrow \rightleftharpoons \leadsto \dashrightarrow + \dashleftarrow \leftleftarrows \leftrightarrows \Lleftarrow + \Rrightarrow \twoheadleftarrow \leftarrowtail \looparrowleft + \leftrightharpoons \curvearrowleft \circlearrowleft \Lsh + \upuparrows \upharpoonleft \downharpoonleft \multimap + \leftrightsquigarrow \rightrightarrows \rightleftarrows + \rightrightarrows \rightleftarrows \twoheadrightarrow + \rightarrowtail \looparrowright \rightleftharpoons + \curvearrowright \circlearrowright \Rsh \downdownarrows + \upharpoonright \downharpoonright \rightsquigarrow \nleftarrow + \nrightarrow \nLeftarrow \nRightarrow \nleftrightarrow + \nLeftrightarrow \to \Swarrow \Searrow \Nwarrow \Nearrow + \barleftarrow \mapsup \mapsdown \mapsfrom \rightarrowbar + \twoheaduparrow \updownarrowbar \leftsquigarrow \rightzigzagarrow + \twoheaddownarrow \downzigzagarrow + """], + ["Miscellaneous Symbols", + 3, + r"""\neg \invnot \turnednot \infty \forall \wp \exists \bigstar + \angle \partial \nexists \measuredangle \eth \emptyset + \sphericalangle \clubsuit \varnothing \complement \diamondsuit + \imath \Finv \triangledown \heartsuit \jmath \Game \spadesuit + \ell \hbar \vartriangle \cdots \hslash \vdots \blacksquare \ldots + \blacktriangle \ddots \sharp \prime \blacktriangledown \Im \flat + \backprime \Re \natural \circledS \P \O \copyright \ss \Ldsh + \frakZ \l \carriagereturn \circledR \S \sterling \L \yen \danger + \d \OE \AA \AE \scurel \oe \o \checkmark \Rdsh \ae \ac \prurel \$ + \iiint \iint \iint \oiiint"""] +] + +from docutils import nodes, statemachine +from docutils.parsers.rst import Directive +class math_symbol_table_directive(Directive): + has_content = True + def run(self): + def get_n(n, l): + part = [] + for x in l: + part.append(x) + if len(part) == n: + yield part + part = [] + yield part + + lines = [] + for category, columns, syms in symbols: + syms = syms.split() + syms.sort() + lines.append("**%s**" % category) + lines.append('') + max_width = 0 + for sym in syms: + max_width = max(max_width, len(sym)) + max_width = max_width * 2 + 16 + header = " " + (('=' * max_width) + ' ') * columns + format = '%%%ds' % max_width + for chunk in get_n(20, get_n(columns, syms)): + lines.append(header) + for part in chunk: + line = [] + for sym in part: + line.append(format % (":math:`%s` ``%s``" % (sym, sym))) + lines.append(" " + " ".join(line)) + lines.append(header) + lines.append('') + self.state_machine.insert_input(lines, "Symbol table") + return [] + +from docutils.parsers.rst import directives +directives.register_directive('math_symbol_table', + math_symbol_table_directive) + +if __name__ == "__main__": + # Do some verification of the tables + from matplotlib import _mathtext_data + + print "SYMBOLS NOT IN STIX:" + all_symbols = {} + for category, columns, syms in symbols: + if category == "Standard Function Names": + continue + syms = syms.split() + for sym in syms: + if len(sym) > 1: + all_symbols[sym[1:]] = None + if sym[1:] not in _mathtext_data.tex2uni: + print sym + + print "SYMBOLS NOT IN TABLE:" + for sym in _mathtext_data.tex2uni: + if sym not in all_symbols: + print sym Modified: trunk/matplotlib/doc/sphinxext/mathpng.py =================================================================== --- trunk/matplotlib/doc/sphinxext/mathpng.py 2008-06-11 15:31:21 UTC (rev 5470) +++ trunk/matplotlib/doc/sphinxext/mathpng.py 2008-06-11 15:49:11 UTC (rev 5471) @@ -3,7 +3,7 @@ from hashlib import md5 except ImportError: from md5 import md5 - + from docutils import nodes from docutils.writers.html4css1 import HTMLTranslator from sphinx.latexwriter import LaTeXTranslator @@ -39,7 +39,7 @@ else: class math_directive(Directive): has_content = True - def run(self): + def run(self): latex = ' '.join(self.content) node = latex_math(self.block_text) node['latex'] = latex @@ -75,26 +75,44 @@ LaTeXTranslator.depart_latex_math = depart_latex_math_latex from os.path import isfile + +# This calls out to LaTeX to render the expression +def latex2png(latex, name): + f = open('math.tex', 'w') + f.write(r"""\documentclass[12pt]{article} + \pagestyle{empty} + \begin{document}""") + if inline: + f.write('$%s$' % latex) + else: + f.write(r'\[ %s \]' % latex) + f.write('\end{document}') + f.close() + os.system('latex --interaction=nonstopmode math.tex > /dev/null') + os.system('dvipng -bgTransparent -Ttight --noghostscript -l10 ' + + '-o %s math.dvi > /dev/null' % name) + +# This uses mathtext to render the expression +def latex2png(latex, filename): + from matplotlib import rcParams + from matplotlib import _png + from matplotlib.mathtext import MathTextParser + rcParams['mathtext.fontset'] = 'cm' + mathtext_parser = MathTextParser("Bitmap") + ftimage = mathtext_parser.parse("$%s$" % latex, 120) + _png.write_png(ftimage.as_rgba_str(), ftimage.get_width(), + ftimage.get_height(), filename) + # LaTeX to HTML translation stuff: def latex2html(node, source): inline = isinstance(node.parent, nodes.TextElement) latex = node['latex'] - print latex - name = 'math-' + md5(latex).hexdigest()[-10:] - if not isfile('_static/%s.png' % name): - f = open('math.tex', 'w') - f.write(r"""\documentclass[12pt]{article} - \pagestyle{empty} - \begin{document}""") - if inline: - f.write('$%s$' % latex) - else: - f.write(r'\[ %s \]' % latex) - f.write('\end{document}') - f.close() - os.system('latex --interaction=nonstopmode math.tex > /dev/null') - os.system('dvipng -bgTransparent -Ttight --noghostscript -l10 ' + - '-o _static/%s.png math.dvi > /dev/null' % name) + print latex.encode("ascii", "backslashreplace") + name = 'math-%s' % md5(latex).hexdigest()[-10:] + dest = '_static/%s.png' % name + if not isfile(dest): + latex2png(latex, dest) + path = '_static' count = source.split('/doc/')[-1].count('/') for i in range(count): @@ -110,3 +128,4 @@ else: cls = 'class="center" ' return '<img src="%s/%s.png" %s%s/>' % (path, name, align, cls) + Modified: trunk/matplotlib/doc/users/mathtext.rst =================================================================== --- trunk/matplotlib/doc/users/mathtext.rst 2008-06-11 15:31:21 UTC (rev 5470) +++ trunk/matplotlib/doc/users/mathtext.rst 2008-06-11 15:49:11 UTC (rev 5471) @@ -3,13 +3,11 @@ Writing mathematical expressions ================================ - -You can use TeX markup in any matplotlib text string; see the -:mod:`matplotlib.mathtext` module documentation for details. Note -that you do not need to have TeX installed, since matplotlib ships its -own TeX expression parser, layout engine and fonts. The layout engine -is a fairly direct adaptation of the layout algorithms in Donald -Knuth's TeX, so the quality is quite good (matplotlib also provides a +You can use TeX markup in any matplotlib text string. Note that you +do not need to have TeX installed, since matplotlib ships its own TeX +expression parser, layout engine and fonts. The layout engine is a +fairly direct adaptation of the layout algorithms in Donald Knuth's +TeX, so the quality is quite good (matplotlib also provides a ``usetex`` option for those who do want to call out to TeX to generate their text (see :ref:`usetex-tutorial`). @@ -37,9 +35,6 @@ produces ":math:`\alpha > \beta`". -.. TODO: Include a complete list here - - Subscripts and superscripts --------------------------- @@ -106,7 +101,7 @@ Radicals -------- -Radicals can be produced with the ``\sqrt[]{}`` command. For example: +Radicals can be produced with the ``\sqrt[]{}`` command. For example:: r'$\sqrt{2}$' @@ -116,7 +111,7 @@ Any base can (optionally) be provided inside square brackets. Note that the base must be a simple expression, and can not contain layout -commands such as fractions or sub/superscripts. +commands such as fractions or sub/superscripts:: r'$\sqrt[3]{x}$' @@ -181,6 +176,42 @@ .. image:: ../_static/stixsans_fontset.png +Custom fonts +~~~~~~~~~~~~ + +mathtext also provides a way to use custom fonts for math. This +method is fairly tricky to use, and should be considered an +experimental feature for patient users only. By setting the rcParam +``mathtext.fontset`` to ``custom``, you can then set the following +parameters, which control which font file to use for a particular set +of math characters. + + ============================== ================================= + Parameter Corresponds to + ============================== ================================= + ``mathtext.it`` ``\mathit{}`` or default italic + ``mathtext.rm`` ``\mathrm{}`` Roman (upright) + ``mathtext.tt`` ``\mathtt{}`` Typewriter (monospace) + ``mathtext.bf`` ``\mathbf{}`` bold italic + ``mathtext.cal`` ``\mathcal{}`` calligraphic + ``mathtext.sf`` ``\mathsf{}`` sans-serif + ============================== ================================= + +Each parameter should be set to a fontconfig font descriptor (as +defined in the yet-to-be-written font chapter). + +.. TODO: Link to font chapter + +The fonts used should have a Unicode mapping in order to find any +non-Latin characters, such as Greek. If you want to use a math symbol +that is not contained in your custom fonts, you can set the rcParam +``mathtext.fallback_to_cm`` to ``True`` which will cause the mathtext +system to use characters from the default Computer Modern fonts +whenever a particular character can not be found in the custom font. + +Note that the math glyphs specified in Unicode have evolved over time, +and many fonts may not have glyphs in the correct place for mathtext. + Accents ------- @@ -211,19 +242,29 @@ ``\widetilde{xyz}`` :math:`\widetilde{xyz}` ============================== ================================= +Care should be taken when putting accents on lower-case i's and j's. +Note that in the following ``\mathi`` is used to avoid the extra dot +over the i:: + r"$\hat i\ \ \hat \imath$" + +.. math:: + + \hat i\ \ \hat \imath + Symbols ------- You can also use a large number of the TeX symbols, as in ``\infty``, -``\leftarrow``, ``\sum``, ``\int``; see :mod:`matplotlib.mathtext` for a -complete list. +``\leftarrow``, ``\sum``, ``\int``. +.. math_symbol_table:: + If a particular symbol does not have a name (as is true of many of the more obscure symbols in the STIX fonts), Unicode characters can also be used:: - ur'Generic symbol: $\u23ce$' + ur'$\u23ce$' Example ------- Modified: trunk/matplotlib/examples/pylab_examples/mathtext_examples.py =================================================================== --- trunk/matplotlib/examples/pylab_examples/mathtext_examples.py 2008-06-11 15:31:21 UTC (rev 5470) +++ trunk/matplotlib/examples/pylab_examples/mathtext_examples.py 2008-06-11 15:49:11 UTC (rev 5471) @@ -5,7 +5,7 @@ import gc stests = [ - r'Kerning: AVA $AVA$ $$', + r'$x \doteq y$', r'\$100.00 $\alpha \_$', r'$\frac{\$100.00}{y}$', r'$x y$', Modified: trunk/matplotlib/lib/matplotlib/_mathtext_data.py =================================================================== --- trunk/matplotlib/lib/matplotlib/_mathtext_data.py 2008-06-11 15:31:21 UTC (rev 5470) +++ trunk/matplotlib/lib/matplotlib/_mathtext_data.py 2008-06-11 15:49:11 UTC (rev 5471) @@ -37,6 +37,8 @@ r'\}' : ('cmex10', 130), r'\leftangle' : ('cmex10', 97), r'\rightangle' : ('cmex10', 64), + r'\langle' : ('cmex10', 97), + r'\rangle' : ('cmex10', 64), r'\widehat' : ('cmex10', 15), r'\widetilde' : ('cmex10', 52), @@ -1758,6 +1760,54 @@ tex2uni = { 'widehat': 0x0302, 'widetilde': 0x0303, +'langle': 0x27e8, +'rangle': 0x27e9, +'perp': 0x27c2, +'neq': 0x2260, +'Join': 0x2a1d, +'leqslant': 0x2a7d, +'geqslant': 0x2a7e, +'lessapprox': 0x2a85, +'gtrapprox': 0x2a86, +'lesseqqgtr': 0x2a8b, +'gtreqqless': 0x2a8c, +'triangleeq': 0x225c, +'eqslantless': 0x2a95, +'eqslantgtr': 0x2a96, +'backepsilon': 0x03f6, +'precapprox': 0x2ab7, +'succapprox': 0x2ab8, +'fallingdotseq': 0x2252, +'subseteqq': 0x2ac5, +'supseteqq': 0x2ac6, +'varpropto': 0x221d, +'precnapprox': 0x2ab9, +'succnapprox': 0x2aba, +'subsetneqq': 0x2acb, +'supsetneqq': 0x2acc, +'lnapprox': 0x2ab9, +'gnapprox': 0x2aba, +'longleftarrow': 0x27f5, +'longrightarrow': 0x27f6, +'longleftrightarrow': 0x27f7, +'Longleftarrow': 0x27f8, +'Longrightarrow': 0x27f9, +'Longleftrightarrow': 0x27fa, +'longmapsto': 0x27fc, +'leadsto': 0x21dd, +'dashleftarrow': 0x290e, +'dashrightarrow': 0x290f, +'circlearrowleft': 0x21ba, +'circlearrowright': 0x21bb, +'leftrightsquigarrow': 0x21ad, +'leftsquigarrow': 0x219c, +'rightsquigarrow': 0x219d, +'Game': 0x2141, +'hbar': 0x0127, +'hslash': 0x210f, +'ldots': 0x22ef, +'vdots': 0x22ee, +'doteqdot': 0x2251, 'doteq': 8784, 'partial': 8706, 'gg': 8811, @@ -1922,7 +1972,7 @@ 'napprox': 8777, 'ast': 8727, 'twoheaduparrow': 8607, -'doublebarwedge ?': 8966, +'doublebarwedge': 8966, 'Sigma': 931, 'leftharpoonaccent': 8400, 'ntrianglelefteq': 8940, Modified: trunk/matplotlib/lib/matplotlib/backends/backend_agg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2008-06-11 15:31:21 UTC (rev 5470) +++ trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2008-06-11 15:49:11 UTC (rev 5471) @@ -40,6 +40,7 @@ from matplotlib.transforms import Affine2D, Bbox from _backend_agg import RendererAgg as _RendererAgg +from matplotlib import _png backend_version = 'v2.2' @@ -302,5 +303,9 @@ renderer.dpi = self.figure.dpi if is_string_like(filename_or_obj): filename_or_obj = file(filename_or_obj, 'wb') - self.get_renderer()._renderer.write_png(filename_or_obj, self.figure.dpi) + renderer = self.get_renderer() + x = renderer._renderer.buffer_rgba(0, 0) + _png.write_png(renderer._renderer.buffer_rgba(0, 0), + renderer.width, renderer.height, + filename_or_obj, self.figure.dpi) renderer.dpi = original_dpi Modified: trunk/matplotlib/lib/matplotlib/backends/backend_svg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2008-06-11 15:31:21 UTC (rev 5470) +++ trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2008-06-11 15:49:11 UTC (rev 5471) @@ -1,6 +1,6 @@ from __future__ import division -import os, codecs, base64, tempfile, urllib, gzip, md5 +import os, codecs, base64, tempfile, urllib, gzip, md5, cStringIO from matplotlib import verbose, __version__, rcParams from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\ @@ -14,6 +14,7 @@ from matplotlib.mathtext import MathTextParser from matplotlib.path import Path from matplotlib.transforms import Affine2D +from matplotlib import _png from xml.sax.saxutils import escape as escape_xml_text @@ -46,6 +47,7 @@ self._char_defs = {} self._markers = {} self._path_collection_id = 0 + self._imaged = {} self.mathtext_parser = MathTextParser('SVG') svgwriter.write(svgProlog%(width,height,width,height)) @@ -267,33 +269,20 @@ ) if rcParams['svg.image_inline']: - class Base64Writer(object): - def __init__(self, write_method): - self._write_method = write_method - self._buffer = '' - def write(self, data): - self._buffer += data - while len(self._buffer) >= 64: - self._write_method(base64.encodestring(buffer[:64])) - self._write_method('\n') - self._buffer = self._buffer[64:] - def flush(self): - self._write_method(base64.encodestring(self._buffer)) - self._write_method('\n') - self._svgwriter.write("data:image/png;base64,\n") - base64writer = Base64Writer(self._svgwriter.write) - + stringio = cStringIO.StringIO() im.flipud_out() - im.write_png(base64writer) + rows, cols, buffer = im.as_rgba_str() + _png.write_png(buffer, cols, rows, stringio) im.flipud_out() - base64writer.flush() + self._svgwriter.write(base64.encodestring(stringio.getvalue())) else: self._imaged[self.basename] = self._imaged.get(self.basename,0) + 1 filename = '%s.image%d.png'%(self.basename, self._imaged[self.basename]) verbose.report( 'Writing image file for inclusion: %s' % filename) im.flipud_out() - im.write_png(filename) + rows, cols, buffer = im.as_rgba_str() + _png.write_png(buffer, cols, rows, filename) im.flipud_out() self._svgwriter.write(filename) Modified: trunk/matplotlib/lib/matplotlib/image.py =================================================================== --- trunk/matplotlib/lib/matplotlib/image.py 2008-06-11 15:31:21 UTC (rev 5470) +++ trunk/matplotlib/lib/matplotlib/image.py 2008-06-11 15:49:11 UTC (rev 5471) @@ -16,6 +16,7 @@ # For clarity, names from _image are given explicitly in this module: from matplotlib import _image +from matplotlib import _png # For user convenience, the names from _image are also imported into # the image namespace: @@ -256,12 +257,13 @@ """Write the image to png file with fname""" im = self.make_image() if noscale: - numrows,numcols = im.get_size() + numrows, numcols = im.get_size() im.reset_matrix() im.set_interpolation(0) im.resize(numcols, numrows) im.flipud_out() - im.write_png(fname) + rows, cols, buffer = im.as_rgba_str() + _png.write_png(buffer, cols, rows, fname) def set_data(self, A, shape=None): """ @@ -661,7 +663,8 @@ def write_png(self, fname): """Write the image to png file with fname""" im = self.make_image() - im.write_png(fname) + rows, cols, buffer = im.as_rgba_str() + _png.write_png(buffer, cols, rows, fname) def imread(fname): """ @@ -686,7 +689,7 @@ return pil_to_array(image) - handlers = {'png' :_image.readpng, + handlers = {'png' :_png.read_png, } basename, ext = os.path.splitext(fname) ext = ext.lower()[1:] Modified: trunk/matplotlib/lib/matplotlib/mathtext.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mathtext.py 2008-06-11 15:31:21 UTC (rev 5470) +++ trunk/matplotlib/lib/matplotlib/mathtext.py 2008-06-11 15:49:11 UTC (rev 5471) @@ -655,8 +655,9 @@ return xHeight def get_underline_thickness(self, font, fontsize, dpi): - cached_font = self._get_font(font) - return (cached_font.font.underline_thickness / 64.0 / fontsize) * (dpi) + # This function used to grab underline thickness from the font, + # but that information is just too un-reliable, so it is now hardcoded. + return ((0.75 / 12.0) * fontsize * dpi) / 72.0 def get_kern(self, font1, fontclass1, sym1, fontsize1, font2, fontclass2, sym2, fontsize2, dpi): @@ -682,6 +683,8 @@ fontmap = {} def __init__(self, *args, **kwargs): + self._stix_fallback = StixFonts(*args, **kwargs) + TruetypeFonts.__init__(self, *args, **kwargs) if not len(self.fontmap): for key, val in self._fontmap.iteritems(): @@ -689,6 +692,7 @@ self.fontmap[key] = fullpath self.fontmap[val] = fullpath + _slanted_symbols = Set(r"\int \oint".split()) def _get_glyph(self, fontname, font_class, sym, fontsize): @@ -717,6 +721,7 @@ cached_font.charmap[num]) if symbol_name is None: + return self._stix_fallback._get_glyph(fontname, font_class, sym, fontsize) warn("Unrecognized symbol '%s'. Substituting with a dummy symbol." % sym.encode('ascii', 'backslashreplace'), MathTextWarning) fontname = 'it' @@ -868,6 +873,8 @@ return self.cm_fallback._get_glyph( fontname, 'it', sym, fontsize) else: + if fontname == 'it' and isinstance(self, StixFonts): + return self._get_glyph('rm', font_class, sym, fontsize) warn("Substituting with a dummy symbol.", MathTextWarning) fontname = 'rm' new_fontname = fontname @@ -2031,7 +2038,8 @@ bslash = Literal('\\') - accent = oneOf(self._accent_map.keys() + list(self._wide_accents)) + accent = oneOf(self._accent_map.keys() + + list(self._wide_accents)) function = oneOf(list(self._function_names)) @@ -2057,10 +2065,10 @@ unicode_range = u"\U00000080-\U0001ffff" symbol =(Regex(UR"([a-zA-Z0-9 +\-*/<>=:,.;!'@()\[\]|%s])|(\\[%%${}\[\]_|])" % unicode_range) - | Combine( + | (Combine( bslash + oneOf(tex2uni.keys()) - ) + ) + FollowedBy(Regex("[^a-zA-Z]"))) ).setParseAction(self.symbol).leaveWhitespace() c_over_c =(Suppress(bslash) @@ -2486,14 +2494,14 @@ if super is not None: hlist = HCentered([super]) hlist.hpack(width, 'exactly') - vlist.extend([hlist, Kern(rule_thickness * 2.0)]) + vlist.extend([hlist, Kern(rule_thickness * 3.0)]) hlist = HCentered([nucleus]) hlist.hpack(width, 'exactly') vlist.append(hlist) if sub is not None: hlist = HCentered([sub]) hlist.hpack(width, 'exactly') - vlist.extend([Kern(rule_thickness * 2.0), hlist]) + vlist.extend([Kern(rule_thickness * 3.0), hlist]) shift = hlist.height + hlist.depth + rule_thickness * 2.0 vlist = Vlist(vlist) vlist.shift_amount = shift + nucleus.depth * 0.5 Modified: trunk/matplotlib/lib/matplotlib/texmanager.py =================================================================== --- trunk/matplotlib/lib/matplotlib/texmanager.py 2008-06-11 15:31:21 UTC (rev 5470) +++ trunk/matplotlib/lib/matplotlib/texmanager.py 2008-06-11 15:49:11 UTC (rev 5471) @@ -38,7 +38,7 @@ import numpy as np import matplotlib as mpl from matplotlib import rcParams -from matplotlib._image import readpng +from matplotlib._png import read_png DEBUG = False @@ -364,7 +364,7 @@ if alpha is None: pngfile = self.make_png(tex, fontsize, dpi) - X = readpng(os.path.join(self.texcache, pngfile)) + X = read_png(os.path.join(self.texcache, pngfile)) if rcParams['text.dvipnghack'] is not None: hack = rcParams['text.dvipnghack'] Modified: trunk/matplotlib/matplotlibrc.template =================================================================== --- trunk/matplotlib/matplotlibrc.template 2008-06-11 15:31:21 UTC (rev 5470) +++ trunk/matplotlib/matplotlibrc.template 2008-06-11 15:49:11 UTC (rev 5471) @@ -162,6 +162,8 @@ # The following settings allow you to select the fonts in math mode. # They map from a TeX font name to a fontconfig font pattern. # These settings are only used if mathtext.fontset is 'custom'. +# Note that this "custom" mode is unsupported and may go away in the +# future. #mathtext.cal : cursive #mathtext.rm : serif #mathtext.tt : monospace Modified: trunk/matplotlib/setup.py =================================================================== --- trunk/matplotlib/setup.py 2008-06-11 15:31:21 UTC (rev 5470) +++ trunk/matplotlib/setup.py 2008-06-11 15:49:11 UTC (rev 5471) @@ -34,7 +34,7 @@ check_for_cairo, check_provide_traits, check_provide_pytz, \ check_provide_dateutil, check_provide_configobj, check_for_dvipng, \ check_for_ghostscript, check_for_latex, check_for_pdftops, \ - check_for_datetime, options + check_for_datetime, options, build_png #import distutils.sysconfig # jdh @@ -100,16 +100,20 @@ print_raw("") print_raw("OPTIONAL BACKEND DEPENDENCIES") +has_libpng = check_for_libpng() -if check_for_libpng() and options['build_agg']: +if has_libpng and options['build_agg']: build_agg(ext_modules, packages) rc['backend'] = 'Agg' else: rc['backend'] = 'SVG' -if options['build_image']: +if has_libpng and options['build_image']: build_image(ext_modules, packages) +if has_libpng and options['build_agg'] or options['build_image']: + build_png(ext_modules, packages) + if options['build_windowing'] and sys.platform=='win32': build_windowing(ext_modules, packages) Modified: trunk/matplotlib/setupext.py =================================================================== --- trunk/matplotlib/setupext.py 2008-06-11 15:31:21 UTC (rev 5470) +++ trunk/matplotlib/setupext.py 2008-06-11 15:49:11 UTC (rev 5471) @@ -79,6 +79,7 @@ True = True False = False +BUILT_PNG = False BUILT_AGG = False BUILT_FT2FONT = False BUILT_TTCONV = False @@ -248,9 +249,6 @@ status, output = commands.getstatusoutput( "%s %s %s" % (pkg_config_exec, flags, packages)) - #if packages.startswith('pygtk'): - # print 'status', status, output - # raise SystemExit if status == 0: for token in output.split(): attr = _flags.get(token[:2], None) @@ -570,12 +568,18 @@ import numpy module.include_dirs.append(numpy.get_include()) +def add_png_flags(module): + try_pkgconfig(module, 'libpng', 'png') + add_base_flags(module) + add_numpy_flags(module) + module.libraries.append('z') + module.include_dirs.extend(['.']) + module.libraries.extend(std_libs) + def add_agg_flags(module): 'Add the module flags to build extensions which use agg' # before adding the freetype flags since -z comes later - try_pkgconfig(module, 'libpng', 'png') - module.libraries.append('z') add_base_flags(module) add_numpy_flags(module) module.include_dirs.extend(['src', '%s/include'%AGG_VERSION, '.']) @@ -1201,7 +1205,26 @@ ext_modules.append(module) BUILT_WXAGG = True +def build_png(ext_modules, packages): + global BUILT_PNG + if BUILT_PNG: return # only build it if you you haven't already + deps = ['src/_png.cpp', 'src/mplutils.cpp'] + deps.extend(glob.glob('CXX/*.cxx')) + deps.extend(glob.glob('CXX/*.c')) + + module = Extension( + 'matplotlib._png', + deps, + include_dirs=numpy_inc_dirs, + ) + + add_png_flags(module) + ext_modules.append(module) + + BUILT_PNG = True + + def build_agg(ext_modules, packages): global BUILT_AGG if BUILT_AGG: return # only build it if you you haven't already Modified: trunk/matplotlib/src/_backend_agg.cpp =================================================================== --- trunk/matplotlib/src/_backend_agg.cpp 2008-06-11 15:31:21 UTC (rev 5470) +++ trunk/matplotlib/src/_backend_agg.cpp 2008-06-11 15:49:11 UTC (rev 5471) @@ -1356,136 +1356,7 @@ return Py::Object(); } -static void write_png_data(png_structp png_ptr, png_bytep data, png_size_t length) { - PyObject* py_file_obj = (PyObject*)png_get_io_ptr(png_ptr); - PyObject* write_method = PyObject_GetAttrString(py_file_obj, "write"); - PyObject* result = NULL; - if (write_method) - result = PyObject_CallFunction(write_method, (char *)"s#", data, length); - Py_XDECREF(write_method); - Py_XDECREF(result); -} - -static void flush_png_data(png_structp png_ptr) { - PyObject* py_file_obj = (PyObject*)png_get_io_ptr(png_ptr); - PyObject* flush_method = PyObject_GetAttrString(py_file_obj, "flush"); - PyObject* result = NULL; - if (flush_method) - result = PyObject_CallFunction(flush_method, (char *)""); - Py_XDECREF(flush_method); - Py_XDECREF(result); -} - -// this code is heavily adapted from the paint license, which is in -// the file paint.license (BSD compatible) included in this -// distribution. TODO, add license file to MANIFEST.in and CVS Py::Object -RendererAgg::write_png(const Py::Tuple& args) -{ - _VERBOSE("RendererAgg::write_png"); - - args.verify_length(1, 2); - - FILE *fp = NULL; - bool close_file = false; - Py::Object py_fileobj = Py::Object(args[0]); - if (py_fileobj.isString()) { - std::string fileName = Py::String(py_fileobj); - const char *file_name = fileName.c_str(); - if ((fp = fopen(file_name, "wb")) == NULL) - throw Py::RuntimeError( Printf("Could not open file %s", file_name).str() ); - close_file = true; - } else if (PyFile_CheckExact(py_fileobj.ptr())) { - fp = PyFile_AsFile(py_fileobj.ptr()); - } - else { - PyObject* write_method = PyObject_GetAttrString(py_fileobj.ptr(), "write"); - if (!(write_method && PyCallable_Check(write_method))) { - Py_XDECREF(write_method); - throw Py::TypeError("Object does not appear to be a 8-bit string path or a Python file-like object"); - } - Py_XDECREF(write_method); - } - - png_bytep *row_pointers = NULL; - png_structp png_ptr = NULL; - png_infop info_ptr = NULL; - - try { - struct png_color_8_struct sig_bit; - png_uint_32 row; - - row_pointers = new png_bytep[height]; - for (row = 0; row < height; ++row) { - row_pointers[row] = pixBuffer + row * width * 4; - } - - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (png_ptr == NULL) { - throw Py::RuntimeError("Could not create write struct"); - } - - info_ptr = png_create_info_struct(png_ptr); - if (info_ptr == NULL) { - throw Py::RuntimeError("Could not create info struct"); - } - - if (setjmp(png_ptr->jmpbuf)) { - throw Py::RuntimeError("Error building image"); - } - - if (fp) { - png_init_io(png_ptr, fp); - } else { - png_set_write_fn(png_ptr, (void*)py_fileobj.ptr(), - &write_png_data, &flush_png_data); - } - png_set_IHDR(png_ptr, info_ptr, - width, height, 8, - PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - - // Save the dpi of the image in the file - if (args.size() == 2) { - double dpi = Py::Float(args[1]); - size_t dots_per_meter = (size_t)(dpi / (2.54 / 100.0)); - png_set_pHYs(png_ptr, info_ptr, dots_per_meter, dots_per_meter, PNG_RESOLUTION_METER); - } - - // this a a color image! - sig_bit.gray = 0; - sig_bit.red = 8; - sig_bit.green = 8; - sig_bit.blue = 8; - /* if the image has an alpha channel then */ - sig_bit.alpha = 8; - png_set_sBIT(png_ptr, info_ptr, &sig_bit); - - png_write_info(png_ptr, info_ptr); - png_write_image(png_ptr, row_pointers); - png_write_end(png_ptr, info_ptr); - - - } catch (...) { - if (fp && close_file) fclose(fp); - delete [] row_pointers; - /* Changed calls to png_destroy_write_struct to follow - http://www.libpng.org/pub/png/libpng-manual.txt. - This ensures the info_ptr memory is released. - */ - if (png_ptr && info_ptr) png_destroy_write_struct(&png_ptr, &info_ptr); - throw; - } - - png_destroy_write_struct(&png_ptr, &info_ptr); - delete [] row_pointers; - if (fp && close_file) fclose(fp); - - return Py::Object(); -} - - -Py::Object RendererAgg::tostring_rgb(const Py::Tuple& args) { //"Return the rendered buffer as an RGB string"; @@ -1763,8 +1634,6 @@ "draw_image(x, y, im)"); add_varargs_method("write_rgba", &RendererAgg::write_rgba, "write_rgba(fname)"); - add_varargs_method("write_png", &RendererAgg::write_png, - "write_png(fname, dpi=None)"); add_varargs_method("tostring_rgb", &RendererAgg::tostring_rgb, "s = tostring_rgb()"); add_varargs_method("tostring_argb", &RendererAgg::tostring_argb, Modified: trunk/matplotlib/src/_backend_agg.h =================================================================== --- trunk/matplotlib/src/_backend_agg.h 2008-06-11 15:31:21 UTC (rev 5470) +++ trunk/matplotlib/src/_backend_agg.h 2008-06-11 15:49:11 UTC (rev 5471) @@ -176,7 +176,6 @@ Py::Object write_rgba(const Py::Tuple & args); - Py::Object write_png(const Py::Tuple & args); Py::Object tostring_rgb(const Py::Tuple & args); Py::Object tostring_argb(const Py::Tuple & args); Py::Object tostring_bgra(const Py::Tuple & args); Modified: trunk/matplotlib/src/_image.cpp =================================================================== --- trunk/matplotlib/src/_image.cpp 2008-06-11 15:31:21 UTC (rev 5470) +++ trunk/matplotlib/src/_image.cpp 2008-06-11 15:49:11 UTC (rev 5471) @@ -1,11 +1,9 @@ -#include <png.h> - // To remove a gcc warning #ifdef _POSIX_C_SOURCE #undef _POSIX_C_SOURCE #endif -#include "Python.h" //after png.h due to setjmp bug +#include "Python.h" #include <string> #include <iostream> @@ -644,131 +642,7 @@ return Py::Object(); } -static void write_png_data(png_structp png_ptr, png_bytep data, png_size_t length) { - PyObject* py_file_obj = (PyObject*)png_get_io_ptr(png_ptr); - PyObject* write_method = PyObject_GetAttrString(py_file_obj, "write"); - PyObject* result = NULL; - if (write_method) - result = PyObject_CallFunction(write_method, (char *)"s#", data, length); - Py_XDECREF(write_method); - Py_XDECREF(result); -} -static void flush_png_data(png_structp png_ptr) { - PyObject* py_file_obj = (PyObject*)png_get_io_ptr(png_ptr); - PyObject* flush_method = PyObject_GetAttrString(py_file_obj, "flush"); - PyObject* result = NULL; - if (flush_method) - result = PyObject_CallFunction(flush_method, (char *)""); - Py_XDECREF(flush_method); - Py_XDECREF(result); -} - -// this code is heavily adapted from the paint license, which is in -// the file paint.license (BSD compatible) included in this -// distribution. TODO, add license file to MANIFEST.in and CVS -char Image::write_png__doc__[] = -"write_png(fname)\n" -"\n" -"Write the image to filename fname as png\n" -; -Py::Object -Image::write_png(const Py::Tuple& args) -{ - //small memory leak in this function - JDH 2004-06-08 - _VERBOSE("Image::write_png"); - - args.verify_length(1); - - FILE *fp = NULL; - Py::Object py_fileobj = Py::Object(args[0]); - if (py_fileobj.isString()) { - std::string fileName = Py::String(py_fileobj); - const char *file_name = fileName.c_str(); - if ((fp = fopen(file_name, "wb")) == NULL) - throw Py::RuntimeError( Printf("Could not open file %s", file_name).str() ); - } - else { - PyObject* write_method = PyObject_GetAttrString(py_fileobj.ptr(), "write"); - if (!(write_method && PyCallable_Check(write_method))) { - Py_XDECREF(write_method); - throw Py::TypeError("Object does not appear to be a path or a Python file-like object"); - } - Py_XDECREF(write_method); - } - - png_structp png_ptr; - png_infop info_ptr; - struct png_color_8_struct sig_bit; - png_uint_32 row=0; - - //todo: allocate on heap - png_bytep *row_pointers = NULL; - std::pair<agg::int8u*,bool> bufpair; - bufpair.first = NULL; - bufpair.second = false; - - try { - row_pointers = new png_bytep[rowsOut]; - if (!row_pointers) - throw Py::RuntimeError("Out of memory"); - - bufpair = _get_output_buffer(); - for (row = 0; row < rowsOut; ++row) - row_pointers[row] = bufpair.first + row * colsOut * 4; - - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (png_ptr == NULL) - throw Py::RuntimeError("Could not create write struct"); - - info_ptr = png_create_info_struct(png_ptr); - if (info_ptr == NULL) - throw Py::RuntimeError("Could not create info struct"); - - if (setjmp(png_ptr->jmpbuf)) - throw Py::RuntimeError("Error building image"); - - if (fp) { - png_init_io(png_ptr, fp); - } else { - png_set_write_fn(png_ptr, (void*)py_fileobj.ptr(), - &write_png_data, &flush_png_data); - } - png_set_IHDR(png_ptr, info_ptr, - colsOut, rowsOut, 8, - PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - - // this a a color image! - sig_bit.gray = 0; - sig_bit.red = 8; - sig_bit.green = 8; - sig_bit.blue = 8; - /* if the image has an alpha channel then */ - sig_bit.alpha = 8; - png_set_sBIT(png_ptr, info_ptr, &sig_bit); - - png_write_info(png_ptr, info_ptr); - png_write_image(png_ptr, row_pointers); - png_write_end(png_ptr, info_ptr); - png_destroy_write_struct(&png_ptr, &info_ptr); - } catch (...) { - if (bufpair.second) delete [] bufpair.first; - if (fp) fclose(fp); - png_destroy_write_struct(&png_ptr, &info_ptr); - delete [] row_pointers; - throw; - } - - if (fp) fclose(fp); - delete [] row_pointers; - if (bufpair.second) delete [] bufpair.first; - - return Py::Object(); -} - - - char Image::set_aspect__doc__[] = "set_aspect(scheme)\n" "\n" @@ -812,7 +686,6 @@ add_varargs_method( "set_interpolation", &Image::set_interpolation, Image::set_interpolation__doc__); add_varargs_method( "set_resample", &Image::set_resample, Image::set_resample__doc__); add_varargs_method( "set_aspect", &Image::set_aspect, Image::set_aspect__doc__); - add_varargs_method( "write_png", &Image::write_png, Image::write_png__doc__); add_varargs_method( "set_bg", &Image::set_bg, Image::set_bg__doc__); add_varargs_method( "flipud_out", &Image::flipud_out, Image::flipud_out__doc__); add_varargs_method( "flipud_in", &Image::flipud_in, Image::flipud_in__doc__); @@ -901,118 +774,6 @@ } - -char _image_module_readpng__doc__[] = -"readpng(fname)\n" -"\n" -"Load an image from png file into a numerix array of MxNx4 float"; -Py::Object -_image_module::readpng(const Py::Tuple& args) { - - args.verify_length(1); - std::string fname = Py::String(args[0]); - - png_byte header[8]; // 8 is the maximum size that can be checked - - FILE *fp = fopen(fname.c_str(), "rb"); - if (!fp) - throw Py::RuntimeError(Printf("_image_module::readpng could not open PNG file %s for reading", fname.c_str()).str()); - - if (fread(header, 1, 8, fp) != 8) - throw Py::RuntimeError("_image_module::readpng: error reading PNG header"); - if (png_sig_cmp(header, 0, 8)) - throw Py::RuntimeError("_image_module::readpng: file not recognized as a PNG file"); - - - /* initialize stuff */ - png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - - if (!png_ptr) - throw Py::RuntimeError("_image_module::readpng: png_create_read_struct failed"); - - png_infop info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) - throw Py::RuntimeError("_image_module::readpng: png_create_info_struct failed"); - - if (setjmp(png_jmpbuf(png_ptr))) - throw Py::RuntimeError("_image_module::readpng: error during init_io"); - - png_init_io(png_ptr, fp); - png_set_sig_bytes(png_ptr, 8); - - png_read_info(png_ptr, info_ptr); - - png_uint_32 width = info_ptr->width; - png_uint_32 height = info_ptr->height; - - // convert misc color types to rgb for simplicity - if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY || - info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - png_set_gray_to_rgb(png_ptr); - else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - png_set_palette_to_rgb(png_ptr); - - - int bit_depth = info_ptr->bit_depth; - if (bit_depth == 16) png_set_strip_16(png_ptr); - - - png_set_interlace_handling(png_ptr); - png_read_update_info(png_ptr, info_ptr); - - bool rgba = info_ptr->color_type == PNG_COLOR_TYPE_RGBA; - if ( (info_ptr->color_type != PNG_COLOR_TYPE_RGB) && !rgba) { - std::cerr << "Found color type " << (int)info_ptr->color_type << std::endl; - throw Py::RuntimeError("_image_module::readpng: cannot handle color_type"); - } - - /* read file */ - if (setjmp(png_jmpbuf(png_ptr))) - throw Py::RuntimeError("_image_module::readpng: error during read_image"); - - png_bytep *row_pointers = new png_bytep[height]; - png_uint_32 row; - - for (row = 0; row < height; row++) - row_pointers[row] = new png_byte[png_get_rowbytes(png_ptr,info_ptr)]; - - png_read_image(png_ptr, row_pointers); - - - - int dimensions[3]; - dimensions[0] = height; //numrows - dimensions[1] = width; //numcols - dimensions[2] = 4; - - PyArrayObject *A = (PyArrayObject *) PyArray_FromDims(3, dimensions, PyArray_FLOAT); - - - for (png_uint_32 y = 0; y < height; y++) { - png_byte* row = row_pointers[y]; - for (png_uint_32 x = 0; x < width; x++) { - - png_byte* ptr = (rgba) ? &(row[x*4]) : &(row[x*3]); - size_t offset = y*A->strides[0] + x*A->strides[1]; - //if ((y<10)&&(x==10)) std::cout << "r = " << ptr[0] << " " << ptr[0]/255.0 << std::endl; - *(float*)(A->data + offset + 0*A->strides[2]) = (float)(ptr[0]/255.0f); - *(float*)(A->data + offset + 1*A->strides[2]) = (float)(ptr[1]/255.0f); - *(float*)(A->data + offset + 2*A->strides[2]) = (float)(ptr[2]/255.0f); - *(float*)(A->data + offset + 3*A->strides[2]) = rgba ? (float)(ptr[3]/255.0f) : 1.0f; - } - } - - //free the png memory - png_read_end(png_ptr, info_ptr); - png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); - fclose(fp); - for (row = 0; row < height; row++) - delete [] row_pointers[row]; - delete [] row_pointers; - return Py::asObject((PyObject*)A); -} - - char _image_module_fromarray__doc__[] = "fromarray(A, isoutput)\n" "\n" Modified: trunk/matplotlib/src/_image.h =================================================================== --- trunk/matplotlib/src/_image.h 2008-06-11 15:31:21 UTC (rev 5470) +++ trunk/matplotlib/src/_image.h 2008-06-11 15:49:11 UTC (rev 5471) @@ -38,7 +38,6 @@ Py::Object get_interpolation(const Py::Tuple& args); Py::Object set_interpolation(const Py::Tuple& args); Py::Object set_aspect(const Py::Tuple& args); - Py::Object write_png(const Py::Tuple& args); Py::Object set_bg(const Py::Tuple& args); Py::Object flipud_out(const Py::Tuple& args); Py::Object flipud_in(const Py::Tuple& args); @@ -100,7 +99,6 @@ static char get_interpolation__doc__[]; static char set_interpolation__doc__[]; static char set_aspect__doc__[]; - static char write_png__doc__[]; static char set_bg__doc__[]; static char flipud_out__doc__[]; static char flipud_in__doc__[]; @@ -133,8 +131,6 @@ "frombyte"); add_varargs_method("frombuffer", &_image_module::frombuffer, "frombuffer"); - add_varargs_method("readpng", &_image_module::readpng, - "readpng"); add_varargs_method("from_images", &_image_module::from_images, "from_images"); add_varargs_method("pcolor", &_image_module::pcolor, @@ -153,7 +149,6 @@ Py::Object fromarray2 (const Py::Tuple &args); Py::Object pcolor (const Py::Tuple &args); Py::Object pcolor2 (const Py::Tuple &args); - Py::Object readpng (const Py::Tuple &args); Py::Object from_images (const Py::Tuple &args); static char _image_module_fromarray__doc__[]; Modified: trunk/matplotlib/src/ft2font.cpp =================================================================== --- trunk/matplotlib/src/ft2font.cpp 2008-06-11 15:31:21 UTC (rev 5470) +++ trunk/matplotlib/src/ft2font.cpp 2008-06-11 15:49:11 UTC (rev 5471) @@ -69,7 +69,9 @@ delete _rgbaCopy; } -void FT2Image::resize(unsigned long width, unsigned long height) { +void FT2Image::resize(long width, long height) { + if (width < 0) width = 1; + if (height < 0) height = 1; size_t numBytes = width*height; if (width != _width || height != _height) { Modified: trunk/matplotlib/src/ft2font.h =================================================================== --- trunk/matplotlib/src/ft2font.h 2008-06-11 15:31:21 UTC (rev 5470) +++ trunk/matplotlib/src/ft2font.h 2008-06-11 15:49:11 UTC (rev 5471) @@ -66,7 +66,7 @@ void makeRgbCopy(); void makeRgbaCopy(); - void resize(unsigned long width, unsigned long height); + void resize(long width, long height); }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |