Cleanup panel

Font and Proxy Report

Lists the proxy objects in the drawing and the fonts its text styles name that AutoCAD cannot find, then exports the list to Excel or remaps the missing fonts.

On the ribbonButton, Cleanup panel
NeedsAn open drawing (the button is greyed without one)
CommandPYFONTANDPROXYREPORT
AliasFPR

What it does#

Looks for two things that make a drawing behave differently on another machine:

  • Proxies. An object made by an application this AutoCAD does not have (its object enabler is missing). The tool finds proxy entities in model space, every layout and every block definition, and proxy objects in the drawing's named object dictionary and the dictionaries inside it. It groups them by the original class and the application that made them.
  • Missing fonts. Each text style's font file, its big font (for Asian text) and any shape file loaded for complex linetypes, looked up the way AutoCAD looks for them: the support paths, the drawing's folder and, for TrueType, the Windows fonts. Styles that come from xrefs are left out.

If it finds neither, a toast says so and that is all. Otherwise it shows the report and offers to export it or remap the fonts.

How to use it#

  1. Click Font and Proxy Report, or type PYFONTANDPROXYREPORT.
  2. Read the report. It opens with counts ("3 proxy entities, 1 proxy object"), the proxy classes most common first, then each missing font as Style: file. Each list stops after 15 lines; Copy puts the report on the clipboard and the Excel export carries everything. Click OK.
  3. Choose what next: Export to Excel, Remap missing fonts (offered only when a style's own font is missing) or Done. After one choice the others are offered again, until you click Done.
  4. Export to Excel asks where to save. The name starts as <drawing> font and proxy report.xlsx. If the file exists it is replaced, not added to.
  5. Remap missing fonts asks once for the missing SHX fonts (suggesting simplex.shx) and once for the missing TrueType fonts (suggesting arial.ttf), naming the styles each answer will change. Leave the box empty or cancel to leave that kind alone. If AutoCAD cannot find the replacement either, the tool asks before using it.
  6. The remapped styles are listed in a toast, and a REGENALL is queued so the text redraws in the new font.

The Excel sheet#

One sheet, Fonts and proxies, with a bold header row and one row per proxy, then one per missing font:

ColumnFor a proxyFor a missing font
IssueProxy entity or Proxy object Missing font, Missing big font or Missing shape file
NameThe original class name, or (unknown class) The text style
DetailThe application that made itThe font file
WhereThe layout (Model or its name), BLOCK:Name for a block definition, or Named objects Empty
HandleThe proxy's handleEmpty

Limitations#

  • The tool reports proxies; it does not remove or explode them. The fix is the missing object enabler, or the application that made them.
  • Only a style's own font is remapped. Missing big fonts and shape files are reported and left alone.
  • A remap clears the style's TrueType typeface so the font file you typed is what counts. Bold or italic set on a TrueType style is cleared with it.
  • A style that names a font only by typeface, with no font file, is not checked.
  • Mtext that sets its own font inline keeps it; only the style changes.

Good to know#

The remap happens inside the tool's own command, so Undo takes it back (the queued REGENALL is a separate command after it). The export dialog starts wherever the Save dialog last was, not necessarily in the drawing's folder.

Other uses#

  • Check every drawing a consultant sends before you xref it: proxies there usually mean they work in an AutoCAD-based product you do not have.
  • Keep the Excel export with a transmittal as a record of what you received.
  • Before you send drawings out, remap company SHX fonts the recipient will not have to simplex.shx, on a copy.

Source#

The tool's own files, word for word as shipped in Cleanup.panel/Font_Proxy_Report.pushbutton. Every pyACAD tool is an ordinary bundle: copy these into your own extension and change what you like.

script.py Runs on a click. View on GitHub
# -*- coding: utf-8 -*-
"""Reports the proxies in the drawing and the fonts its text styles name that
AutoCAD cannot find, then offers an Excel export and a font remap.

A proxy is an object made by software this AutoCAD does not have (an object
enabler is missing), so the report groups them by the class and application
that made them. Fonts are looked up the way AutoCAD looks for them: the
support paths, the drawing's folder and, for TrueType, the Windows fonts.
Big fonts and shape files are checked too. The remap points a style's own
font at a replacement (simplex.shx or arial.ttf unless you type another);
big fonts and shape files are reported but left alone.
"""

import os

from pyacad import audit, doc, forms, script, toast, xl

__title__ = 'Font and Proxy Report'

TITLE = 'Font and Proxy Report'
EXPORT = 'Export to Excel'
REMAP = 'Remap missing fonts'
DONE = 'Done'


def has_drawing():
    try:
        doc.active()
    except RuntimeError:
        return False
    return True


def default_name():
    path = script.get_document_path() or 'untitled'
    stem = os.path.splitext(os.path.basename(path))[0] or 'untitled'
    return stem + ' font and proxy report.xlsx'


def export(details, missing):
    """Writes the report to a workbook the person picks; True once written."""
    path = forms.save_file('Excel workbooks (*.xlsx)|*.xlsx', default_name(),
                           'Export the font and proxy report')
    if path is None:
        return False                                    # cancelled: say nothing
    try:
        # The save dialog already asked about replacing the file, and xl.write
        # would otherwise add a sheet to the old workbook instead.
        if os.path.exists(path):
            os.remove(path)
        xl.write(path, audit.font_report_rows(details, missing),
                 headers=audit.FONT_REPORT_HEADERS, sheet='Fonts and proxies')
    except Exception as error:
        script.get_logger().error('export to %s failed: %s' % (path, error))
        toast.error('Could not write the workbook', str(error))
        return False
    toast.success('Report exported', path)
    return True


def styles_text(styles):
    """'2 styles (Notes, Title)', at most five names."""
    names = ', '.join(styles[:5])
    if len(styles) > 5:
        names += ' and %d more' % (len(styles) - 5)
    return '%d style%s (%s)' % (len(styles), '' if len(styles) == 1 else 's', names)


def remap(missing):
    """Asks for a replacement per kind of font (SHX, TrueType) and applies
    it; returns the styles changed."""
    found = audit.font_finder()
    changed = []
    for kind, default, styles in audit.remap_plan(missing):
        answer = forms.ask_string(
            'Replace the missing %s font of %s with:'
            % ('SHX' if kind == 'shx' else 'TrueType', styles_text(styles)),
            default, TITLE)
        if answer is None or not answer.strip():
            continue                                    # cancelled: leave this kind alone
        answer = answer.strip()
        if not found(answer) and not forms.confirm(
                '%s was not found in the support paths either, so the text would '
                'still show a substitute font.\n\nUse it anyway?' % answer, TITLE):
            continue
        for style in styles:
            try:
                audit.set_text_style_font(style, answer)
            except Exception as error:
                script.get_logger().error('remapping %s failed: %s' % (style, error))
                toast.error('Could not remap %s' % style, str(error))
            else:
                changed.append(style)
    return changed


def run():
    if not has_drawing():
        toast.warning('No drawing is open', 'Open a drawing, then run Font and Proxy Report')
        return

    details = audit.proxy_details()
    missing = audit.missing_fonts(audit.text_style_fonts(), audit.font_finder())
    if not details and not missing:
        toast.success('No proxies and no missing fonts',
                      'Every font the text styles use was found')
        return

    report = audit.format_font_report(details, missing)
    forms.alert(report, TITLE, copy=report)

    options = [EXPORT]
    if audit.remap_plan(missing):
        options.append(REMAP)
    while options:
        choice = forms.ask_options('What next?', options + [DONE], TITLE)
        if choice is None or choice == DONE:
            break
        if choice == EXPORT:
            if export(details, missing):
                options.remove(EXPORT)
        elif choice == REMAP:
            options.remove(REMAP)
            changed = remap(missing)
            if changed:
                doc.send_command('_.REGENALL')          # redraw text in the new font
                toast.success('%d text style%s remapped' % (len(changed), '' if len(changed) == 1 else 's'),
                              ', '.join(changed))


if '__commandpath__' in globals():
    run()
bundle.yaml The bundle contract: the keys pyACAD reads for this tool. View on GitHub
title: Font and Proxy Report
tooltip: Lists the proxy objects in the drawing and the fonts its text styles name that AutoCAD cannot find. Export the list to Excel, or point the styles with a missing font at a replacement such as simplex.shx.
context: doc
keytip: CF
alias: FPR