diff --git a/CHANGES b/CHANGES index 20d3f5269..2764a2a8e 100644 --- a/CHANGES +++ b/CHANGES @@ -1,11 +1,14 @@ Release 0.5.1 (in development) ============================== +* #65: Fix storage of depth information for PNGs generated by the + pngmath extension. + * Fix autodoc crash when automethod is used outside a class context. -* Fix LaTeX writer output for images with specified height. +* #68: Fix LaTeX writer output for images with specified height. -* Fix wrong generated image path when including images in sources +* #60: Fix wrong generated image path when including images in sources in subdirectories. * Fix the JavaScript search when html_copy_source is off. @@ -182,33 +185,33 @@ New features added Bugs fixed ---------- -* Escape configuration values placed in HTML templates. +* #51: Escape configuration values placed in HTML templates. -* Fix small problems in HTML help index generation. +* #44: Fix small problems in HTML help index generation. * Fix LaTeX output for line blocks in tables. -* Fix "illegal unit" error when using pixel image widths/heights. +* #38: Fix "illegal unit" error when using pixel image widths/heights. * Support table captions in LaTeX output. -* Work around a bug in Jinja that caused "" to be +* #39: Work around a bug in Jinja that caused "" to be emitted in HTML output. * Fix a problem with module links not being generated in LaTeX output. * Fix the handling of images in different directories. -* Support option lists in the text writer. Make sure that dashes +* #29: Support option lists in the text writer. Make sure that dashes introducing long option names are not contracted to en-dashes. * Support the "scale" option for images in HTML output. -* Properly escape quotes in HTML help attribute values. +* #25: Properly escape quotes in HTML help attribute values. * Fix LaTeX build for some description environments with ``:noindex:``. -* Don't crash on weird casing of role names (like ``:Class:``). +* #24: Don't crash on uncommon casing of role names (like ``:Class:``). * Only output ANSI colors on color terminals. diff --git a/sphinx/ext/pngmath.py b/sphinx/ext/pngmath.py index 8dd3e6004..02b6b8204 100644 --- a/sphinx/ext/pngmath.py +++ b/sphinx/ext/pngmath.py @@ -24,6 +24,7 @@ except ImportError: from docutils import nodes from sphinx.util import ensuredir +from sphinx.util.png import read_png_depth, write_png_depth from sphinx.application import SphinxError from sphinx.ext.mathbase import setup as mathbase_setup, wrap_displaymath @@ -79,7 +80,8 @@ def render_math(self, math): relfn = posixpath.join(self.builder.imgpath, 'math', shasum) outfn = path.join(self.builder.outdir, '_images', 'math', shasum) if path.isfile(outfn): - return relfn, self.builder.env._pngmath_depth.get(shasum, None) + depth = read_png_depth(outfn) + return relfn, depth latex = DOC_HEAD + self.builder.config.pngmath_latex_preamble latex += (use_preview and DOC_BODY_PREVIEW or DOC_BODY) % math @@ -158,15 +160,11 @@ def render_math(self, math): m = depth_re.match(line) if m: depth = int(m.group(1)) - self.builder.env._pngmath_depth[shasum] = depth + write_png_depth(outfn, depth) break return relfn, depth -def ensure_depthcache(app, env): - if not hasattr(env, '_pngmath_depth'): - env._pngmath_depth = {} - def cleanup_tempdir(app, exc): if exc: return @@ -221,5 +219,4 @@ def setup(app): app.add_config_value('pngmath_use_preview', False, False) app.add_config_value('pngmath_dvipng_args', ['-gamma 1.5', '-D 110'], False) app.add_config_value('pngmath_latex_preamble', '', False) - app.connect('env-updated', ensure_depthcache) app.connect('build-finished', cleanup_tempdir) diff --git a/sphinx/util/png.py b/sphinx/util/png.py new file mode 100644 index 000000000..a22acba2e --- /dev/null +++ b/sphinx/util/png.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +""" + sphinx.util.png + ~~~~~~~~~~~~~~~ + + PNG image manipulation helpers. + + :copyright: 2008 by Georg Brandl. + :license: BSD. +""" + +import struct +import binascii + +LEN_IEND = 12 +LEN_DEPTH = 22 + +DEPTH_CHUNK_LEN = struct.pack('!i', 10) +DEPTH_CHUNK_START = 'tEXtDepth\x00' +IEND_CHUNK = '\x00\x00\x00\x00IEND\xAE\x42\x60\x82' + + +def read_png_depth(filename): + """ + Read the special tEXt chunk indicating the depth from a PNG file. + """ + result = None + f = open(filename, 'rb') + try: + f.seek(- (LEN_IEND + LEN_DEPTH), 2) + depthchunk = f.read(LEN_DEPTH) + if not depthchunk.startswith(DEPTH_CHUNK_LEN + DEPTH_CHUNK_START): + # either not a PNG file or not containing the depth chunk + return None + result = struct.unpack('!i', depthchunk[14:18])[0] + finally: + f.close() + return result + + +def write_png_depth(filename, depth): + """ + Write the special tEXt chunk indicating the depth to a PNG file. + The chunk is placed immediately before the special IEND chunk. + """ + data = struct.pack('!i', depth) + f = open(filename, 'r+b') + try: + # seek to the beginning of the IEND chunk + f.seek(-LEN_IEND, 2) + # overwrite it with the depth chunk + f.write(DEPTH_CHUNK_LEN + DEPTH_CHUNK_START + data) + # calculate the checksum over chunk name and data + f.write(struct.pack('!i', binascii.crc32(DEPTH_CHUNK_START + data))) + # replace the IEND chunk + f.write(IEND_CHUNK) + finally: + f.close()