File size: 4,542 Bytes
f340984
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#!/usr/bin/env python3
from __future__ import annotations

import argparse
from pathlib import Path

from PIL import Image, ImageDraw, ImageFont


def resolve_font_pair(regular_override: Path | None, bold_override: Path | None) -> tuple[Path, Path]:
    if (regular_override is None) != (bold_override is None):
        raise SystemExit("--regular-font and --bold-font must be supplied together")
    if regular_override and bold_override:
        if not regular_override.is_file() or not bold_override.is_file():
            raise SystemExit("one or both explicit font paths do not exist")
        return regular_override, bold_override

    families = (
        ("DejaVuSans.ttf", "DejaVuSans-Bold.ttf"),
        ("LiberationSans-Regular.ttf", "LiberationSans-Bold.ttf"),
    )
    roots = (Path("/usr/share/fonts"), Path("/usr/local/share/fonts"))
    for regular_name, bold_name in families:
        for root in roots:
            regular_matches = sorted(root.rglob(regular_name)) if root.is_dir() else []
            bold_matches = sorted(root.rglob(bold_name)) if root.is_dir() else []
            if regular_matches and bold_matches:
                return regular_matches[0], bold_matches[0]
    raise SystemExit("no DejaVu Sans or Liberation Sans font pair found; pass --regular-font and --bold-font")


def main() -> None:
    parser = argparse.ArgumentParser(description="Generate a deterministic OCR validation page")
    parser.add_argument("--output", type=Path, required=True)
    parser.add_argument("--pdf-output", type=Path, help="also write the page as a 150-DPI PDF")
    parser.add_argument("--regular-font", type=Path, help="regular TrueType/OpenType font override")
    parser.add_argument("--bold-font", type=Path, help="bold TrueType/OpenType font override")
    args = parser.parse_args()

    regular_path, bold_path = resolve_font_pair(args.regular_font, args.bold_font)
    image = Image.new("RGB", (1600, 2000), "white")
    draw = ImageDraw.Draw(image)
    title = ImageFont.truetype(str(bold_path), 68)
    heading = ImageFont.truetype(str(bold_path), 38)
    body = ImageFont.truetype(str(regular_path), 34)
    small = ImageFont.truetype(str(regular_path), 28)

    draw.text((120, 100), "Unlimited OCR RDNA4 Smoke Test", font=title, fill="black")
    draw.line((120, 205, 1480, 205), fill="black", width=4)
    draw.text((120, 265), "Invoice No. OCR-2026-0731", font=body, fill="black")
    draw.text((120, 325), "Date: 31 July 2026", font=body, fill="black")
    draw.text((120, 385), "GPU target: AMD gfx1201", font=body, fill="black")

    draw.text((120, 505), "Items", font=heading, fill="black")
    left, top, right, bottom = 120, 580, 1480, 1050
    columns = (left, 930, 1120, right)
    rows = (top, 690, 810, 930, bottom)
    for x in columns:
        draw.line((x, top, x, bottom), fill="black", width=3)
    for y in rows:
        draw.line((left, y, right, y), fill="black", width=3)
    draw.text((145, 610), "Item", font=heading, fill="black")
    draw.text((960, 610), "Qty", font=heading, fill="black")
    draw.text((1150, 610), "Price", font=heading, fill="black")
    draw.text((145, 725), "Document scan", font=body, fill="black")
    draw.text((980, 725), "2", font=body, fill="black")
    draw.text((1150, 725), "€19.50", font=body, fill="black")
    draw.text((145, 845), "Table extraction", font=body, fill="black")
    draw.text((980, 845), "1", font=body, fill="black")
    draw.text((1150, 845), "€9.50", font=body, fill="black")
    draw.text((145, 965), "Total", font=heading, fill="black")
    draw.text((1150, 965), "€48.50", font=heading, fill="black")

    draw.text((120, 1190), "Verification notes", font=heading, fill="black")
    notes = [
        "• AMD Radeon RX 9070 XT",
        "• ROCm architecture: gfx1201",
        "• Expected checksum: RDNA4-OCR-PASS",
        "• Formula sample: E = mc²",
    ]
    for index, note in enumerate(notes):
        draw.text((150, 1270 + index * 70), note, font=body, fill="black")

    draw.line((120, 1780, 1480, 1780), fill="black", width=2)
    draw.text((120, 1820), "Synthetic validation page; no private data.", font=small, fill="black")
    args.output.parent.mkdir(parents=True, exist_ok=True)
    image.save(args.output, format="PNG", optimize=True)
    print(args.output)

    if args.pdf_output:
        args.pdf_output.parent.mkdir(parents=True, exist_ok=True)
        image.save(args.pdf_output, format="PDF", resolution=150.0)
        print(args.pdf_output)


if __name__ == "__main__":
    main()