fix: a picture prints as the picture, where and as large as the teacher asks

The black bars above and below a printed picture were neither in the
picture nor in the layout. A PNG or JPEG in a tab of its own is shown by
the engine on a viewer page whose background is rgb(14, 14, 14), and Qt
prints page backgrounds by default; 0.2.6.1 printed that page.

A picture is now taken as itself — drawn onto white, capped at 300 dpi
across Letter — and laid out on the printer's paper by the preview, with
Size (as large as fits down to 25%), Position (nine squares), Paper
(automatic, upright, sideways) and Fill the whole page, which says it
cuts the edges off and is never the default. The preview is the PDF that
prints, laid out again after each change. Worksheet PDFs and lesson pages
get no picture controls and are unchanged.

Page backgrounds are no longer printed for lesson pages either, as in
Chrome; Blink darkens light text when it does that, so a white-on-black
page prints readable grey on white. "Colour" is "Color" in the print
interface and the manual.

Lab: 135 print checks, now including eight picture layouts measured on
the job file CUPS kept — byte-identical to the preview, within 1 point of
where asked, no ink anywhere else. Printed from the real session with the
pointer: 50% top left, Elmer-66, the same. Not yet on paper.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
ekklesia
2026-09-23 21:41:15 -05:00
co-authored by Claude Opus 5.5
parent 6946bae455
commit 940f63e0e5
10 changed files with 662 additions and 13 deletions
+46 -5
View File
@@ -23,9 +23,8 @@ from PyQt6.QtWebEngineCore import QWebEngineProfile, QWebEngineSettings
notes = []
wi.notify = lambda s, b: (notes.append(s), print("NOTIFY", s, "|", b, flush=True))
app = QApplication(sys.argv)
profile = QWebEngineProfile("rig", app)
for a in ("PdfViewerEnabled", "PluginsEnabled"):
profile.settings().setAttribute(getattr(QWebEngineSettings.WebAttribute, a), True)
# Wonder Ink's own profile, settings and all — not one of the rig's.
profile = wi.build_profile(app, "rig")
window = wi.WonderInk(profile)
profile.downloadRequested.connect(window.on_download)
window.resize(1280, 800); window.show()
@@ -60,7 +59,7 @@ def when(cond, then, label, limit=30):
def preview(): return window._preview
def ready(): return preview() is not None and preview()._pdf is not None
def describe(d):
return f"shown={d._page in d._images} pages={d._pages} printers={[d._printer.itemText(i) for i in range(d._printer.count())]} paper={d.paper()} colour_offered={d._colour.isVisible()} status={d._status.text()!r}"
return f"picture={d._picture_box.isVisible()} shown={d._page in d._images} pages={d._pages} printers={[d._printer.itemText(i) for i in range(d._printer.count())]} paper={d.paper()} colour_offered={d._colour.isVisible()} status={d._status.text()!r}"
def finish(code=0):
stamp(f"RESULT notes={notes} preview_open={preview() is not None} tabs={window._tabs.count()}")
@@ -101,7 +100,49 @@ actions = {
QTimer.singleShot(800, lambda: (stamp(f"second request while open: still one preview={preview() is not None}"), press_print()))), "preview"),
}
if scenario == "repeat":
if scenario.startswith("picture:"):
# picture:FILE:SIZE:POSITION:PAPER:FILL[:color]
# Opens a picture on its own, chooses the layout with the preview's own
# controls, keeps the exact PDF the preview showed, then prints it.
_, name, size, position, paper, fill, *rest = scenario.split(":")
view = window.open_tab(); view.load(QUrl(f"http://127.0.0.1:8089/{name}"))
def ready_picture():
d = preview()
return d is not None and d._picture is not None and d._pdf is not None
def choose():
d = preview()
d._size.setCurrentIndex(d._size.findData(int(size)))
d._place.choose(position.replace("-", " "))
d._turned.setCurrentIndex(d._turned.findData(paper))
d._fill.setChecked(fill == "fill")
if rest and rest[0] == "gray":
d._colour.setCurrentIndex(1)
QTimer.singleShot(900, keep_and_print)
def keep_and_print():
import shutil
d = preview()
out = Path("/tmp/rig-out"); out.mkdir(exist_ok=True)
shutil.copy(d._pdf, out / "preview.pdf")
stamp(f"PICTURE picture_box={d._picture_box.isVisible()} size_enabled={d._size.isEnabled()} "
f"image={d._picture.width()}x{d._picture.height()} labels={d._colour_label.text()!r},{d._colour.itemText(0)!r}")
press_print()
QTimer.singleShot(2500, lambda: (QTimer.singleShot(0, lambda: window.print_view(view)),
when(ready_picture, choose, "picture preview")))
elif scenario == "dark-page":
# A lesson page with a black background. Chrome does not print page
# backgrounds unless asked, and neither may Wonder Ink.
view = window.open_tab()
view.setHtml("<html><head><title>Night sky</title></head><body style='background:#000;color:#fff'>"
+ "<h1>Stars</h1>" + "<p>God made the stars. </p>" * 40 + "</body></html>",
QUrl("https://app.wonderink.org/night"))
def keep_dark():
import shutil
out = Path("/tmp/rig-out"); out.mkdir(exist_ok=True)
shutil.copy(preview()._pdf, out / "preview.pdf")
press_print()
view.loadFinished.connect(lambda ok: (QTimer.singleShot(0, lambda: window.print_view(view)),
when(ready, keep_dark, "dark preview")))
elif scenario == "repeat":
view = window.open_tab(); lesson(view); n = [0]
def once():
if n[0] == 5: return finish()