Metadata-Version: 2.4
Name: cad-easy-font
Version: 0.1.1
Classifier: Programming Language :: Rust
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Multimedia :: Graphics :: Graphics Conversion
Summary: DXF text and AutoCAD SHX/BigFont support implemented with Rust and PyO3.
Author: easy_font contributors
License: MIT
Requires-Python: >=3.9
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM

# easy-font

`easy-font` is a PyO3/Rust Python extension focused on DXF text handling and
AutoCAD SHX font compatibility. It intentionally starts smaller than `ezdxf`:
the first milestone is reliable text/style extraction plus support for
AutoCAD-86 SHX `unifont` and `bigfont` files found in CAD datasets.

## Development

```sh
nix-shell
maturin develop
pytest
```

## Python API

```python
import easy_font as cad

font = cad.open_shx("cad-data/fonts/hztxt.shx", encoding="gbk")
print(font.kind, font.is_bigfont, font.glyph_count)
print(font.glyph_code_for_char("中"))  # GBK BigFont glyph code, e.g. 0xD6D0
print(font.missing_chars("中文ABC"))

doc = cad.readfile("cad-data/data/hatch.dxf")
for entity in doc.modelspace():
    if entity.dxftype == "TEXT":
        print(entity.text)

dwg = cad.readfile("cad-data/data/baseline-sample.dwg")
print(dwg.format, len(dwg.modelspace()))

# Resolve extracted text to local font files.
resolved_rows = cad.resolve_text_runs(dwg, ["cad-data/fonts"])
print(resolved_rows[0]["style"], resolved_rows[0]["font_path"])
```

### Render one line of Chinese CAD text

CAD text styles often pair a primary ASCII SHX font with a BigFont for Chinese
glyphs. `FontStack` keeps that split explicit, so ASCII such as `-2#` uses
`simplex.shx` while Chinese text is encoded through the BigFont mapping.

```python
from pathlib import Path

import easy_font as cad

fonts = Path("cad-data/fonts")
font = cad.FontStack(
    ascii_font=fonts / "simplex.shx",
    bigfont=fonts / "gbcbig.shx",
    encoding="gbk",
)

text = "明厚源悦府-2#"
print(font.glyph_code_for_char("明"))
print(font.encode(text))
print(font.missing_chars(text))

# Geometry in drawing units, already scaled to a 12-unit text height.
strokes = font.text_strokes(text, height=12, tracking=0.1, align="left")

# SVG path only, useful when embedding into a larger document.
path = font.text_svg_path("共1页，第1页", height=12, tracking=0.1, align="center")

# Complete SVG document and PNG bytes.
svg = font.render_text_svg(text, height=12, tracking=0.1, stroke_width=0.35, align="right")
Path("cad-text.svg").write_text(svg, encoding="utf-8")

png = font.render_text_png(text, height=120, stroke_width=3, align="left")
Path("cad-text.png").write_bytes(png)
```

For a single SHX font, the lower-level object also exposes
`glyph_code_for_char()`, `encode()`, `has_char()`, `missing_chars()`,
`glyph_metrics()`, `text_strokes()`, and `text_svg_path()`.

## Current scope

- Reads ASCII DXF group-code pairs.
- Reads DWG files using a handwritten Rust binary parser path.
- Extracts `STYLE` table records, including primary SHX font and BigFont file.
- Extracts common text entities from `ENTITIES`: `TEXT`, `MTEXT`, `ATTRIB`,
  and `ATTDEF`.
- Recognizes AutoCAD-86 SHX `unifont` and `bigfont` headers.
- Preserves raw SHX glyph records so BigFont files that `ezdxf` cannot load are
  still inspectable.
- Maps Unicode characters back to encoded SHX glyph codes for BigFont files
  such as GBK/CP936.
- Provides glyph metrics and high-level stroke/SVG/PNG helpers for one-line CAD
  text rendering.
- Decodes DXF text escapes such as `%%d`, `\P`, and `\U+4E2D`.
- Decodes encoded BigFont text bytes through Python codecs such as `gbk`,
  `big5`, and `shift_jis`.

Full DXF entity parity with `ezdxf` is out of scope for this initial
implementation.

## Font Resolution Workflow

```sh
python scripts/extract_and_resolve_fonts.py --input baseline-sample.dwg --limit 10
```

This script reads text entities from a drawing, resolves style fonts against
`cad-data/fonts`, and prints style/text font coverage.
For SHX fonts it verifies glyph coverage through `open_shx`; for TTF/OTF/TTC/WOFF
it verifies cmap coverage when `fontTools` is available.

To validate real render output for SFNT fonts (TTF/OTF/TTC/WOFF/WOFF2) and save
PNG previews:

```sh
python scripts/validate_render_output.py --input baseline-sample.dwg --max-rows 200 --preview-limit 20
```

