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:
co-authored by
Claude Opus 5.5
parent
6946bae455
commit
940f63e0e5
@@ -225,3 +225,77 @@ def submit(pdf, printer, copies=1, pages=None, gray=None, title="Wonder Ink"):
|
||||
# without the program's name in front of it.
|
||||
message = re.sub(r"^lp:\s*", "", message) or "The printer did not accept the job."
|
||||
return False, message
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- pictures
|
||||
#
|
||||
# A picture a lesson opens in a tab of its own is not a page: the engine
|
||||
# shows it on a near-black viewer page (body background rgb(14, 14, 14),
|
||||
# measured) scaled to the window, and printing that page printed the black
|
||||
# around the picture — the bars teachers saw above and below the artwork.
|
||||
# So a picture is laid out on the paper here instead, from the picture
|
||||
# itself, and the teacher chooses how large and where.
|
||||
|
||||
# How large, as a share of the largest size that fits the page.
|
||||
PICTURE_SIZES = (100, 75, 50, 33, 25)
|
||||
|
||||
# Where, as (column, row): 0 left or top, 1 centre, 2 right or bottom.
|
||||
PICTURE_POSITIONS = {
|
||||
"top left": (0, 0), "top": (1, 0), "top right": (2, 0),
|
||||
"left": (0, 1), "centre": (1, 1), "right": (2, 1),
|
||||
"bottom left": (0, 2), "bottom": (1, 2), "bottom right": (2, 2),
|
||||
}
|
||||
|
||||
# Portrait or landscape: "auto" follows the picture's own shape.
|
||||
ORIENTATIONS = ("auto", "portrait", "landscape")
|
||||
|
||||
|
||||
def picture_landscape(orientation, width, height):
|
||||
"""Should the page be landscape for this picture?"""
|
||||
if orientation == "landscape":
|
||||
return True
|
||||
|
||||
if orientation == "portrait":
|
||||
return False
|
||||
|
||||
return width > height
|
||||
|
||||
|
||||
def picture_rect(page, margin, picture, size=100, position="centre", fill=False):
|
||||
"""Where a picture goes on a page, as (x, y, width, height).
|
||||
|
||||
PAGE is (width, height) and MARGIN the blank edge, both in the same
|
||||
units; PICTURE is the picture's (width, height) in pixels. Never
|
||||
stretched: the picture keeps its own proportions.
|
||||
|
||||
Fit (the default) is the largest size that shows ALL of the picture
|
||||
inside the margins, times SIZE percent, placed at POSITION. Fill covers
|
||||
the whole printable area and so cuts off whatever overhangs — which a
|
||||
teacher asks for by name, never by default; SIZE and POSITION do not
|
||||
apply to it.
|
||||
"""
|
||||
page_width, page_height = page
|
||||
width, height = picture
|
||||
|
||||
if width <= 0 or height <= 0:
|
||||
raise ValueError("the picture has no size")
|
||||
|
||||
area_x, area_y = margin, margin
|
||||
area_width = max(1.0, page_width - 2 * margin)
|
||||
area_height = max(1.0, page_height - 2 * margin)
|
||||
|
||||
if fill:
|
||||
scale = max(area_width / width, area_height / height)
|
||||
drawn_width, drawn_height = width * scale, height * scale
|
||||
return (area_x + (area_width - drawn_width) / 2,
|
||||
area_y + (area_height - drawn_height) / 2,
|
||||
drawn_width, drawn_height)
|
||||
|
||||
size = max(1, min(100, int(size)))
|
||||
scale = min(area_width / width, area_height / height) * size / 100
|
||||
drawn_width, drawn_height = width * scale, height * scale
|
||||
column, row = PICTURE_POSITIONS.get(position, (1, 1))
|
||||
|
||||
return (area_x + (area_width - drawn_width) * column / 2,
|
||||
area_y + (area_height - drawn_height) * row / 2,
|
||||
drawn_width, drawn_height)
|
||||
|
||||
Reference in New Issue
Block a user