From 829dcaa1487eef72900268e2b38bcc0a7ac50911 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Sat, 29 Mar 2025 14:46:12 +0100 Subject: [PATCH] Improve output of dvi debug parsing. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To test, run e.g. ```python from pylab import * set_loglevel("debug") figtext(.5, .5, r"gff\textwon$\frac12$", usetex=True) show() ``` Grab the path of the dvi file that appears last in the log, then run ```bash python -mmatplotlib.dviread /path/to/dvi ``` Prior to this patch, the output was ``` === new page === (w: 1668654, h: 553676, d: 225994) font: 'cmss10' scale: 0.625 x y glyph chr w (glyphs) 983040 1441792 103 g 327681 1310721 1441792 11 . 382295 font: 'tcss1000' scale: 0.625 x y glyph chr w (glyphs) 1693016 1441792 142 . 618800 font: 'cmr7' scale: 0.4375 x y glyph chr w (glyphs) 2390459 1183756 49 1 261235 2390459 1667786 50 2 261235 x y h w (boxes) 2390459 1291058 26213 261235 ``` With this patch, the output is ``` === NEW PAGE === (w: 1668654, h: 553676, d: 225994) --- GLYPHS --- font: cmss10 (scale: 0.625) at /usr/local/texlive/2025/texmf-dist/fonts/type1/public/amsfonts/cm/cmss10.pfb x y glyph chr w 983040 1441792 103 g 327681 1310721 1441792 11 ff 382295 font: tcss1000 (scale: 0.625) at /usr/local/texlive/2025/texmf-dist/fonts/type1/public/cm-super/sfss1000.pfb x y glyph chr w 1693016 1441792 142 ₩ 618800 font: cmr7 (scale: 0.4375) at /usr/local/texlive/2025/texmf-dist/fonts/type1/public/amsfonts/cm/cmr7.pfb x y glyph chr w 2390459 1183756 49 1 261235 2390459 1667786 50 2 261235 --- BOXES --- x y h w 2390459 1291058 26213 261235 ``` Most importantly, glyphs are now resolved to their unicode representation (essentially by resolving the glyph name, similarly to the process described in Text.glyph_name_or_index), whereas many complex glyphs were just output as "." before. Furthermore, full font paths are printed, and the output is slightly better aligned. These improvements will be more significant with the future support for {xe,lua}tex, which can load a much wider variety of glyphs. --- lib/matplotlib/dviread.py | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/lib/matplotlib/dviread.py b/lib/matplotlib/dviread.py index 10fcd0aee8bb..1e6dcfdc4409 100644 --- a/lib/matplotlib/dviread.py +++ b/lib/matplotlib/dviread.py @@ -1108,26 +1108,44 @@ def _fontfile(cls, suffix, texname): from argparse import ArgumentParser import itertools + import fontTools.agl + + from matplotlib.ft2font import FT2Font + from matplotlib.textpath import TextToPath + parser = ArgumentParser() parser.add_argument("filename") parser.add_argument("dpi", nargs="?", type=float, default=None) args = parser.parse_args() + + def _print_fields(*args): + print(" ".join(map("{:>11}".format, args))) + with Dvi(args.filename, args.dpi) as dvi: fontmap = PsfontsMap(find_tex_file('pdftex.map')) for page in dvi: - print(f"=== new page === " + print(f"=== NEW PAGE === " f"(w: {page.width}, h: {page.height}, d: {page.descent})") + print("--- GLYPHS ---") for font, group in itertools.groupby( page.text, lambda text: text.font): - print(f"font: {font.texname.decode('latin-1')!r}\t" - f"scale: {font._scale / 2 ** 20}") - print("x", "y", "glyph", "chr", "w", "(glyphs)", sep="\t") + psfont = fontmap[font.texname] + fontpath = psfont.filename + print(f"font: {font.texname.decode('latin-1')} " + f"(scale: {font._scale / 2 ** 20}) at {fontpath}") + face = FT2Font(fontpath) + TextToPath._select_native_charmap(face) + _print_fields("x", "y", "glyph", "chr", "w") for text in group: - print(text.x, text.y, text.glyph, - chr(text.glyph) if chr(text.glyph).isprintable() - else ".", - text.width, sep="\t") + if psfont.encoding: + glyph_name = _parse_enc(psfont.encoding)[text.glyph] + else: + glyph_name = face.get_glyph_name( + face.get_char_index(text.glyph)) + glyph_str = fontTools.agl.toUnicode(glyph_name) + _print_fields(text.x, text.y, text.glyph, glyph_str, text.width) if page.boxes: - print("x", "y", "h", "w", "", "(boxes)", sep="\t") + print("--- BOXES ---") + _print_fields("x", "y", "h", "w") for box in page.boxes: - print(box.x, box.y, box.height, box.width, sep="\t") + _print_fields(box.x, box.y, box.height, box.width)