Skip to content

Commit

Permalink
Fix orientation for double-sided printing
Browse files Browse the repository at this point in the history
  • Loading branch information
pjkundert committed Dec 8, 2024
1 parent 012598e commit 3697547
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 13 deletions.
6 changes: 3 additions & 3 deletions slip39/gui/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -595,12 +595,12 @@ def update_seed_data( event, window, values ):
# We're recovering the BIP-39 Seed Phrase *Entropy*, NOT the derived (decrypted) 512-bit
# Seed Data! So, we don't deal in Passphrases, here. The Passphrase (to encrypt the Seed,
# when "Using BIP-39") is only required to display the correct wallet addresses.
window['-SD-DATA-F-'].update( "BIP-39 Mnemonic to Back Up: " )
window['-SD-DATA-F-'].update( "BIP-39 Mnemonic to Recover or Back Up: " )
window['-SD-DATA-F-'].update( visible=True )
window['-SD-PASS-C-'].update( visible=False )
window['-SD-PASS-F-'].update( visible=False )
elif 'SLIP' in update_seed_data.src:
window['-SD-DATA-F-'].update( "SLIP-39 Mnemonics to Back Up: " )
window['-SD-DATA-F-'].update( "SLIP-39 Mnemonics to Recover or Back Up: " )
window['-SD-DATA-F-'].update( visible=True )
window['-SD-PASS-C-'].update( visible=True )
window['-SD-PASS-F-'].update(
Expand Down Expand Up @@ -1532,7 +1532,7 @@ def deficiency( *deficiencies ):
continue
name_len = max( len( name ) for name in details )
status = '\n'.join(
f"Saved {name}"
f"{'Print' if printer else 'Saved'}: {name}"
for name in details
)
# Finally, success has been assured; turn off emboldened status line
Expand Down
15 changes: 11 additions & 4 deletions slip39/layout/pdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ def produce_pdf(

# Find the best PDF and orientation, by max of returned cards_pp (cards per page). Assumes
# layout_pdf returns a tuple that can be compared; cards_pp,orientation,... will always sort.
# This card orientation defines the overall orientation of the entire PDF; we'll rotate other
# elements (cover, paper wallets) to match.
page_margin_mm = PAGE_MARGIN * MM_IN
cards_pp,orientation,page_xy,pdf,_ = max(
layout_pdf( card_dim, page_margin_mm, orientation=orientation, paper_format=paper_format )
Expand Down Expand Up @@ -335,6 +337,8 @@ def produce_pdf(
cover_sent += "\n".join( slip39_group )
tpl_cover['cover-sent'] = cover_sent

# Add the cover page(s), rotated to match the orientation deduced for the cards. Thus, the
# whole PDF will be printable with the deduced card page orientation.
pdf.add_page()
if orientation.lower().startswith( 'p' ):
tpl_cover.render( offsetx=pdf.epw, rotate=-90.0 )
Expand Down Expand Up @@ -520,7 +524,9 @@ def write_pdfs(

# Unless no card_format (False) or paper wallet password specified, produce a PDF containing
# the SLIP-39 mnemonic recovery cards; remember the deduced (<pdf_paper>,<pdf_orient>). If
# we're producing paper wallets, always force portrait orientation for the cards, to match.
# we're producing paper wallets, always force portrait orientation for the cards, to match
# the layout of the paper wallets, so that all page orientations will match; this may result
# in a sub-optimal card layout, but mixing orientations in a PDF confuses some printers.
if card_format is not False or wallet_pwd is not None:
(pdf_paper,pdf_orient),pdf,_ = produce_pdf(
*details,
Expand All @@ -547,7 +553,8 @@ def write_pdfs(

if wallet_pwd is not None:
# Deduce the paper wallet size and create a template. All layouts are in specified in
# inches; template dimensions are in mm.
# inches; template dimensions are in mm. Paper wallets are always formatted for
# portrait orientation; we've forced that, above, if paper wallets are desired.
try:
(wall_h,wall_w),wall_margin = WALLET_SIZES[wallet_format.lower() if wallet_format else WALLET]
except KeyError:
Expand All @@ -557,8 +564,8 @@ def write_pdfs(
wall_dim = wall.mm()

# Lay out wallets, always in Portrait orientation, defaulting to the Card paper_format
# if it is a standard size (a str, not an (x,y) tuple), otherwise to "Letter" paper. Printers may
# have problems with a PDF mixing Landscape and Portrait, but do it if desired...
# if it is a standard size (a str, not an (x,y) tuple), otherwise to "Letter" paper.
# Rotate the wallets to match the card's orientation (like the cover page).
if wallet_paper is None:
wallet_paper = paper_format if type(paper_format) is str else PAPER

Expand Down
17 changes: 12 additions & 5 deletions slip39/layout/printer.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,15 @@ def printer_output(
"""
double_sided = True if double_sided is None else bool( double_sided )
if sys.platform == 'darwin':
command = [ '/usr/bin/lpr', '-o', 'sides=one-sided' ]
command = [ '/usr/bin/lpr' ]
command_input = binary

# Find the desired printer's system name; otherwise use default printer
printer_system = None
if printer:
printer_list = list( printers_available() )
for system,human in printer_list:
if human.lower() == printer.lower() or system.lower() == printer.lower():
if ( human and human.lower() == printer.lower() ) or ( system and system.lower() == printer.lower()):
printer_system = system
assert printer_system, \
f"Couldn't locate printer matching {printer!r}, in {', '.join( h for s,h in printer_list )}"
Expand All @@ -114,11 +114,18 @@ def printer_output(
command += [ '-o', f"media={paper_format.capitalize()}" ]
if orientation:
# -o orientation-requested=N Specify portrait (3) or landscape (4) orientation
N = { 'p': 3, 'l': 4 }[orientation.lower()[0]]
N = { 'p': 3, 'l': 4 }[orientation.lower()[0]]
command += [ '-o', f"orientation-requested={N}" ]
if double_sided:
# Regardless of desired orientation, layout assumes long-edge double-sided
command += [ '-o', "sides=two-sided-long-edge" ]
# The layout of the *cards* is what determines the "edge" upon which the double-sided
# page is intended to flip. Unless correct, the right QR code won't be on the back!
# Default to long-edge, unless explicitly oriented landscape.
if orientation and orientation.lower().startswith( 'l' ):
command += [ '-o', "sides=two-sided-short-edge" ]
else:
command += [ '-o', "sides=two-sided-long-edge" ]
else:
command += [ '-o', 'sides=one-sided' ]

log.info( f"Printing via: {' '.join( command )}" )
subproc = subprocess.run(
Expand Down
2 changes: 1 addition & 1 deletion slip39/version.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
__version_info__ = ( 13, 0, 1 )
__version_info__ = ( 13, 0, 2 )
__version__ = '.'.join( map( str, __version_info__ ))

0 comments on commit 3697547

Please sign in to comment.