Printing Notes: the dodge/burn map and print recipe as a printer writes them - #767
Merged
Conversation
… exportable A darkroom printer keeps a printing record: paper, grade, exposure, then the dodge/burn instructions in stops, often sketched onto the straight print. Every number for that record was already in the config; nothing showed it the way a printer reads it and nothing left the app with it. The Export tab's new Printing Notes section previews the marked-up work print on the canvas (Shift+N) and exports it as `<stem>_notes.jpg`: burns hatched, dodges open, each mask badged with its value in stops, and the recipe in a band below. Display-only — a normal export is never annotated. Stops are written in the exposure domain a printing record uses, so a burn reads + and a dodge reads −, inverting PolygonMask.strength in one helper. The sheet is baked from the frame the canvas already rendered, so screen and file agree by construction (resolution follows the preview; HQ gives a full-res sheet). The inverse uv_grid lookup behind CanvasOverlay._raw_to_screen moves to CoordinateMapping.map_raw_to_viewport so the canvas and the sheet share one mapping and cannot drift.
marcinz606
marked this pull request as ready for review
August 6, 2026 18:18
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A darkroom printer keeps a printing record — paper, grade, exposure, then the dodge/burn instructions in stops, often sketched straight onto the work print. Every number that record needs was already in the config (
PolygonMask.strengthis EV stops, the recipe lives inExposureConfig,FinishConfig.vignette_stopsis an edge burn), but nothing showed it the way a printer reads it and nothing left the app with it.The Export tab gets a Printing Notes section with two side-by-side buttons:
Shift+N) — draws the marked-up work print over the frame: burns hatched, dodges left open, each mask badged with its number and value in stops, plus a card with the print recipe. Display-only.<stem>_notes.jpginto the export folder: the same map baked onto the rendered frame with the recipe in a band underneath. A separate file; a normal export is never annotated.Conventions (borrowed, not invented)
+, a dodge reads−.PolygonMask.strengthis the opposite sign (+ = dodge = brighter), somask_notesinverts it in one place and a test pins that. Values snap to ⅓/½/¼ glyphs when they land close, otherwise decimals.How it is built
services/view/printing_notes.py— pure text:stops_label,mask_notes,recipe_lines(defaults omitted). No Qt, and it takes sub-configs rather thanWorkspaceConfigsincedomain/modelsimports the features.desktop/view/canvas/printing_notes.py— the painting, shared by canvas and sheet;scalesizes pens/hatch/type so a full-res sheet is not hairlines.uv_gridthrough the export path for no legibility gain.CanvasOverlay._raw_to_screenmoved toCoordinateMapping.map_raw_to_viewport(the mirror of the existingmap_click_to_raw), so the canvas and the sheet map coordinates through one implementation.Verification
make allgreen (3442 passed).tests/test_printing_notes.py(labels, sign inversion, recipe contents),tests/test_printing_notes_overlay.py(when the map paints, hatch on burns only, sheet geometry),tests/test_printing_notes_panel.py(the section, both buttons, no toggle echo).samples/DSC00448.ARW: real render → dodge + burn masks → sheet baked; masks land where the pipeline puts them, recipe reads1 Burn +1 · 2 Dodge −½.Docs updated in the same change:
docs/USER_GUIDE.md§6.3 (overlay + conventions) and §11 (the section). NoPIPELINE.mdchange — nothing touches pixels.