Files
pdf/tests/edits/_font_fallback_check.py

73 lines
3.2 KiB
Python

"""Phase 1 check: editing a styled run with characters NOT in its embedded subset now falls back to
the bundled Carlito (metric-compatible with Calibri) instead of OS Arial/Helvetica, and the new
glyphs survive.
Run: gateway/.venv/Scripts/python.exe tests/edits/_font_fallback_check.py
"""
from __future__ import annotations
import json, sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, r"C:\Users\furqa\pdfeng-build\win-local-pdfium\lib")
sys.path.insert(1, str(ROOT / "gateway"))
import pdfengine
PDF = ROOT / "Mo-Faishal-Qureshi.pdf"
def ptext(p):
return "".join(r.text for ln in p.lines for r in ln.runs)
def main():
doc = pdfengine.PdfDocument.load_from_memory(PDF.read_bytes(), "")
for pageno in range(doc.page_count):
m = doc.get_page(pageno).extract_document_model()
para = next((p for p in m.paragraphs if "Present" in ptext(p)), None)
if para:
break
if not para:
print("FAIL: couldn't find the 'Present' italic paragraph"); return
fonts_before = sorted({r.internal_font_id for ln in para.lines for r in ln.runs if r.text.strip()})
print("para text:", ptext(para)[:70])
print("fonts before:", fonts_before)
oi = [i for ln in para.lines for r in ln.runs for i in r.object_indices]
cl = min(ln.x for ln in para.lines); cr = max(ln.x + ln.w for ln in para.lines)
fb = max(ln.baseline_y for ln in para.lines)
bls = sorted({round(ln.baseline_y, 1) for ln in para.lines}, reverse=True)
lead = abs(bls[0]-bls[1]) if len(bls) > 1 else 13.0
fid = para.lines[0].runs[0].internal_font_id
new_text = ptext(para).strip() + " Zephyr xkcd | the quux"
op = {"version": "1.0", "operations": [{"id": "f", "type": "reflow_paragraph", "pageIndex": pageno, "data": {
"objectIndices": oi, "runs": [{"text": new_text, "internalFontId": fid, "fontSize": 11.0, "color": "#1a5276"}],
"columnLeft": cl, "columnRight": cr, "firstBaselineY": fb, "leading": lead,
"oldLineCount": len(para.lines), "align": "left", "paraId": "FONTCHK"}}]}
doc.apply_edits(json.dumps(op))
r = pdfengine.PdfDocument.load_from_memory(doc.save_full(), "")
edited = None
for pageno2 in range(r.page_count):
mm = r.get_page(pageno2).extract_document_model()
for p in mm.paragraphs:
if "Zephyr" in ptext(p):
edited = p; break
if edited:
break
if not edited:
print("FAIL: edited paragraph not found after save"); return
names = sorted({(r.font_name or "") for ln in edited.lines for r in ln.runs if r.text.strip()})
txt = ptext(edited)
print("\nedited fonts:", names)
print("glyphs survived: Zephyr=%s '|'=%s the=%s xkcd=%s" %
("Zephyr" in txt, "|" in txt, "the" in txt.replace(" ", ""), "xkcd" in txt.replace(" ", "")))
carlito = any("carlito" in n.lower() for n in names)
arial = any(("arial" in n.lower() or "helvetica" in n.lower() or "liberation" in n.lower()) for n in names)
print(f"\n=> fallback uses Carlito: {carlito} (uses Arial/Helvetica: {arial})")
print("PHASE1 OK" if carlito and not arial else "PHASE1: check fonts above")
if __name__ == "__main__":
main()