# Design : affichage de l'image originale sur la page solution **Date :** 2026-05-20 ## Contexte La page solution affiche actuellement la grille remplie (cellules noires). L'utilisateur souhaite voir également l'image d'origine dont la grille est issue, pour faciliter la vérification et enrichir le rendu visuel. ## Mise en page choisie Page portrait A4. La page solution est divisée en **deux colonnes égales** : - **Colonne gauche** : grille solution (indices + cellules remplies) — identique à aujourd'hui mais réduite pour tenir dans la moitié de la largeur - **Colonne droite** : image originale redimensionnée à la même hauteur et largeur que la grille, centrée verticalement Espacement entre les deux colonnes : gouttière fixe de 10 mm. Si `image_bytes` est `None`, la page solution se comporte comme avant (grille seule, pleine largeur). ## Changements requis ### 1. `src/logimage/domain/entities/puzzle.py` Ajouter un champ `image_bytes: bytes | None = None` à `NonogramPuzzle` : ```python @dataclass(frozen=True) class NonogramPuzzle: grid: Grid row_clues: tuple[Clue, ...] col_clues: tuple[Clue, ...] title: str image_bytes: bytes | None = None ``` Étendre `from_grid()` pour accepter et transmettre ce paramètre : ```python @classmethod def from_grid(cls, grid: Grid, title: str, image_bytes: bytes | None = None) -> "NonogramPuzzle": ... return cls(grid=grid, row_clues=row_clues, col_clues=col_clues, title=title, image_bytes=image_bytes) ``` ### 2. `src/logimage/application/use_cases/generate_puzzles.py` Passer `image_data.content` lors de la construction du puzzle : ```python puzzle = NonogramPuzzle.from_grid(grid, image_data.title, image_data.content) ``` ### 3. `src/logimage/infrastructure/pdf/reportlab_exporter.py` Modifier `_draw_page()` pour la page solution (`filled=True`) : - Si `puzzle.image_bytes` est `None` : comportement actuel inchangé. - Si `puzzle.image_bytes` est présent : calculer la largeur disponible en divisant en deux colonnes (`(avail_w - gutter) / 2`). Réduire la grille à cette demi-largeur. Rendre l'image dans la colonne droite via `reportlab.lib.utils.ImageReader` avec `canvas.drawImage()`, aux mêmes dimensions que la grille (même x, y, width, height). ## Ce qui ne change pas - La page puzzle (non solution) reste inchangée - Le port `PdfExporter` reste inchangé (signature de `export()` inchangée) - Le port `ImageSource` reste inchangé - Les tests existants restent valides (le champ `image_bytes` est optionnel) ## Tests - `NonogramPuzzle.from_grid()` avec et sans `image_bytes` - `ReportLabPdfExporter` : vérifier que le PDF généré avec `with_solution=True` et des bytes image est plus grand (taille fichier) que sans image - Vérifier que `with_solution=True` sans `image_bytes` se comporte comme avant (rétrocompatibilité)