73 lines
3.2 KiB
Python
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()
|