Region compositing
Five operators combine the regions (silhouettes) of two children, named after Figma's boolean operations (see issues #196 / #202). They are the public primitives the cut mark composes from.
Each takes exactly two children [A, B] — the binary SVG-filter implementations do not generalize to three or more, so passing any other number of children throws. The n-ary forms in the table below describe the intended eventual semantics; today only the binary case is implemented.
| Operator | Region algebra | Notes |
|---|---|---|
intersect | A ∩ B | Draw only where both regions overlap. |
exclude | A ^ B (odd-overlap parity) | Draw the symmetric difference. |
subtract | A − B | Draw A with B's region removed. |
paint | A ∪ (B ∩ A) | A is a base surface; B is painted onto it, clipped to A. Sized to A. |
mask | B ∩ A, A not drawn | A is a clip region; B is painted inside it without drawing A. Sized to A. |
paint and mask both clip to A but differ in intent: paint keeps A as a visible surface, while mask uses A only as a stencil and never draws it.
Union (A ∪ B) is intentionally not part of the public surface — it is conceptually layer. Use layer to overlay regions.
from gofish import paint, rect
paint([
rect(x=0, y=0, w=120, h=120, fill="#6aa9d6"),
rect(x=40, y=40, w=120, h=120, fill="#e06666"),
]).render(w=160, h=160)Here A is the blue square (the surface) and B is the red square; B is only drawn where it overlaps A, so the result is clipped to the blue square's bounds.
Renamed from the Porter-Duff spellings
These were previously named after the Porter-Duff compositing operators (inside / xor / out / atop). The Stage-2 rename (#196 / #202) gave them the Figma-inspired names above — a clean break, no aliases:
| Old (Porter-Duff) | New (Figma) |
|---|---|
inside | intersect |
xor | exclude |
out | subtract |
atop | paint |
mask | mask |
Signatures
intersect(children, **options) # [A, B]
exclude(children, **options) # [A, B]
subtract(children, **options) # [A, B]
paint(children, **options) # [A, B]
mask(children) # [A, B]Parameters
intersect
Draw only where both regions overlap: A ∩ B. Binary only.
| Option | Type | Default | Description |
|---|---|---|---|
blend_mode | str | "color" | Blend used where the two regions combine. |
exclude
Symmetric difference (odd-overlap parity): A ^ B. Binary only.
| Option | Type | Default | Description |
|---|---|---|---|
blend_mode | str | "color" | Blend used where the two regions combine. |
subtract
Draw A with B removed: A − B. Binary only.
| Option | Type | Default | Description |
|---|---|---|---|
blend_mode | str | "color" | Blend used where the two regions combine. |
paint
A is a base surface B is painted onto, clipped to A: A ∪ (B ∩ A). Result sized to A. Binary only.
| Option | Type | Default | Description |
|---|---|---|---|
blend_mode | str | "color" | Blend used where the two regions combine. |
mask
Use A's region as a clip and paint B inside it without drawing A itself: B ∩ A, reporting A's bounds. Binary only. No options.
No options.
Arity
All five operators require exactly two children and throw otherwise. The n-ary forms (A ∩ B ∩ ..., A − B − C − ..., etc.) are not yet implemented.
