Initial commit — Copydev Imposing Tool
Outil d'imposition PDF desktop (PyQt6) remplacant Quite Imposing Plus. 9 fonctions : livret, n-up, step & repeat, imposition manuelle, jointure pages, pages blanches, numerotation, masquage, fonds perdus. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
66
app/engine/step_repeat.py
Normal file
66
app/engine/step_repeat.py
Normal file
@@ -0,0 +1,66 @@
|
||||
"""Moteur Step & Repeat : dupliquer une page plusieurs fois sur une feuille."""
|
||||
|
||||
from pypdf import PdfReader, PdfWriter, PageObject, Transformation
|
||||
from .pdf_utils import get_page_size, smart_crop_marks
|
||||
import math
|
||||
|
||||
|
||||
def step_and_repeat(input_path, output_path, sheet_size=(841.89, 595.28),
|
||||
copies_h=None, copies_v=None, spacing_h=0, spacing_v=0,
|
||||
crop_marks=False):
|
||||
"""Dupliquer chaque page sur une feuille.
|
||||
|
||||
copies_h, copies_v: nombre de copies horizontales/verticales (None = auto)
|
||||
spacing_h, spacing_v: espacement en points
|
||||
"""
|
||||
reader = PdfReader(input_path)
|
||||
sheet_w, sheet_h = sheet_size
|
||||
writer = PdfWriter()
|
||||
|
||||
for page in reader.pages:
|
||||
page_w, page_h = get_page_size(page)
|
||||
|
||||
# Auto-calcul du nombre de copies
|
||||
if copies_h is None:
|
||||
copies_h_calc = max(1, int((sheet_w + spacing_h) / (page_w + spacing_h)))
|
||||
else:
|
||||
copies_h_calc = copies_h
|
||||
|
||||
if copies_v is None:
|
||||
copies_v_calc = max(1, int((sheet_h + spacing_v) / (page_h + spacing_v)))
|
||||
else:
|
||||
copies_v_calc = copies_v
|
||||
|
||||
# Centrage sur la feuille
|
||||
total_w = copies_h_calc * page_w + (copies_h_calc - 1) * spacing_h
|
||||
total_h = copies_v_calc * page_h + (copies_v_calc - 1) * spacing_v
|
||||
start_x = (sheet_w - total_w) / 2
|
||||
start_y = (sheet_h - total_h) / 2
|
||||
|
||||
sheet = PageObject.create_blank_page(width=sheet_w, height=sheet_h)
|
||||
grid_positions = []
|
||||
|
||||
for row in range(copies_v_calc):
|
||||
for col in range(copies_h_calc):
|
||||
x = start_x + col * (page_w + spacing_h)
|
||||
y = start_y + (copies_v_calc - 1 - row) * (page_h + spacing_v)
|
||||
|
||||
overlay = PageObject.create_blank_page(width=sheet_w, height=sheet_h)
|
||||
overlay.merge_page(page)
|
||||
overlay.add_transformation(Transformation().translate(x, y))
|
||||
sheet.merge_page(overlay)
|
||||
grid_positions.append((col, row))
|
||||
|
||||
if crop_marks and grid_positions:
|
||||
marks = smart_crop_marks(
|
||||
sheet_w, sheet_h, grid_positions,
|
||||
page_w + spacing_h, page_h + spacing_v,
|
||||
start_x, sheet_h - start_y - total_h
|
||||
)
|
||||
sheet.merge_page(marks)
|
||||
|
||||
writer.add_page(sheet)
|
||||
|
||||
with open(output_path, "wb") as f:
|
||||
writer.write(f)
|
||||
return output_path
|
||||
Reference in New Issue
Block a user