63 lines
2.9 KiB
Python
63 lines
2.9 KiB
Python
"""Diagnose early-overflow: edit the real Technologies paragraph with a long single-run text and
|
|
report where each resulting line lands (page + baseline) vs the page-bottom limit.
|
|
|
|
Run: gateway/.venv/Scripts/python.exe tests/edits/_overflow_diag.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(), "")
|
|
m = doc.get_page(0).extract_document_model()
|
|
tech = next(p for p in m.paragraphs if "Technologies" in ptext(p))
|
|
oi = [i for ln in tech.lines for r in ln.runs for i in r.object_indices]
|
|
cl = min(ln.x for ln in tech.lines); cr = max(ln.x + ln.w for ln in tech.lines)
|
|
fb = max(ln.baseline_y for ln in tech.lines)
|
|
bls = sorted({round(ln.baseline_y, 1) for ln in tech.lines}, reverse=True)
|
|
lead = abs(bls[0]-bls[1]) if len(bls) > 1 else 14.0
|
|
page_h = doc.get_page(0).height
|
|
tops = []
|
|
for p in m.paragraphs:
|
|
for ln in p.lines:
|
|
if (ln.x + ln.w) > cl and ln.x < cr:
|
|
tops.append(ln.y + ln.h)
|
|
max_top = max(tops) if tops else 0
|
|
mirror = page_h - max_top
|
|
bottom_limit = max(18.0, min(mirror, page_h * 0.25))
|
|
print(f"page_h={page_h:.0f} tech firstBaselineY={fb:.1f} leading={lead:.1f} cols=[{cl:.0f},{cr:.0f}]")
|
|
print(f"max_top(in-col)={max_top:.1f} mirror={mirror:.1f} bottomLimitY(approx)={bottom_limit:.1f}")
|
|
room_lines = int((fb - bottom_limit) / lead)
|
|
print(f"=> room for ~{room_lines} lines on page 0 before hitting the bottom limit")
|
|
|
|
new_text = ptext(tech).strip() + " " + " ".join(f"w{n}" for n in range(40))
|
|
op = {"version": "1.0", "operations": [{"id": "g", "type": "reflow_paragraph", "pageIndex": 0, "data": {
|
|
"objectIndices": oi, "runs": [{"text": new_text, "internalFontId": tech.lines[0].runs[0].internal_font_id,
|
|
"fontSize": 11.0, "color": "#000000"}], "columnLeft": cl, "columnRight": cr, "firstBaselineY": fb,
|
|
"leading": lead, "oldLineCount": len(tech.lines), "align": "left", "paraId": "DIAG"}}]}
|
|
doc.apply_edits(json.dumps(op))
|
|
r = pdfengine.PdfDocument.load_from_memory(doc.save_full(), "")
|
|
print(f"\nAFTER edit: pages={r.page_count}")
|
|
for i in range(r.page_count):
|
|
mm = r.get_page(i).extract_document_model()
|
|
diag_lines = [ln for p in mm.paragraphs for ln in p.lines
|
|
if any(getattr(rr, "para_id", "") == "DIAG" for rr in ln.runs)]
|
|
ys = sorted((ln.baseline_y for ln in diag_lines), reverse=True)
|
|
print(f" page {i}: {len(diag_lines)} DIAG line(s) baselineY range "
|
|
f"{ys[0]:.0f}..{ys[-1]:.0f}" if ys else f" page {i}: 0 DIAG lines")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|