Give every mask an eye and a colour, and put the brush where the mask is

The first build of seeing a mask showed the selected layer's, in one global
style, from a strip at the top of the panel. It answered the wrong question and
answered it somewhere nobody looked. What a photographer asks of two masks is
how they meet — where the sky's edge sits against the building's — and that
needs both on screen at once, in colours that can be told apart.

So each row of the stack has an eye, drawn in the colour its mask is shown in,
and each mask has six swatches to choose that colour from. Several can be open
at once; a new one comes up open, in the first colour nothing else is using.
The style — tint, alpha, outline — is the one setting that stays global, above
the stack, because three styles at once are three pictures that cannot be read
against each other. Alpha now draws every shown mask, each in its colour, on
black. In the pipeline a `Reveal` is a list of `(layer, colour)` rather than
one layer, and every reveal block carries its own colour.

The brush moves too. Select, Paint and Erase and the three sliders under them
sat at the top of the panel, appeared only once a row was selected, and said
nothing about which mask they acted on — so "how do I paint" and "how do I
correct the model's outline" both had the same answer and nobody found it.
They sit under the selected mask's parts now, beside the swatches, and on a
subject or a category the hint says what a stroke there does: it becomes a
part of this mask, joined to the model's, and can be taken out again.

Eyes and colours are viewing state, on the session and not on the layer, so a
photograph reopened has every eye closed — the stored-mask round-trip test
asserts it.
This commit is contained in:
2026-09-11 19:03:51 +02:00
parent 936490880b
commit a87139b838
12 changed files with 759 additions and 287 deletions
+9 -7
View File
@@ -517,13 +517,15 @@ hardness and flow the photographer sets. Strokes are stored as normalised source
rasterised on the device, so a correction stays on what it was painted on through a crop, a zoom and
an export at any size. A whole stroke is one step in the history.
**FR-DEV-19c — Seeing the mask.** The mask a selected layer actually resolves to shall be drawable
over the photograph, in a tint, as an alpha, or as an outline. What is shown is the finished mask —
every part folded, with the layer's feather, falloff, morphology, invert and opacity applied — and
it is shown for a layer that carries no adjustment yet, which is the state every mask is in for its
first few seconds. No rendered output ever carries it: the reveal is a property of looking at an
edit, not of the edit, so it reaches the pipeline through the composition that draws the canvas and
through no other.
**FR-DEV-19c — Seeing the mask.** Each layer's mask shall be drawable over the photograph, switched
per layer by an eye on its row and drawn in a colour of that layer's own, so that several can be
shown at once and told apart; the style — a tint, an alpha, or an outline — is one setting for all
of them. What is shown is the finished mask — every part folded, with the layer's feather, falloff,
morphology, invert and opacity applied — and it is shown for a layer that carries no adjustment
yet, which is the state every mask is in for its first few seconds. No rendered output ever carries
it: the reveal is a property of looking at an edit, not of the edit, so it reaches the pipeline
through the composition that draws the canvas and through no other, and it does not travel in a
sidecar.
Nobody can refine an edge they are not being shown. Before this the only thing drawn on the
photograph was FR-DEV-3's region overlay — a false-coloured picture of what the *model detected*,