Skip to content

Read the soft masks, and draw a transparency group as one thing - #12

Merged
tannevaled merged 1 commit into
mainfrom
soft-masks
Aug 27, 2026
Merged

Read the soft masks, and draw a transparency group as one thing#12
tannevaled merged 1 commit into
mainfrom
soft-masks

Conversation

@tannevaled

Copy link
Copy Markdown
Contributor

A soft mask says that what is drawn from here on shows through by an amount that varies from one place on the page to another. It is not a number but a whole little drawing of its own — a form, on paper of its own — and what is read off that drawing is the mask: how light each pixel came out, or how much of it was painted at all. It is how nearly every drop shadow, soft edge and faded surface in an illustration is written.

The corpus was asked first: 1 286 of its pages name one — seven times as many as carry a mesh shading. 871 read the light in the drawing and 415 how much of it was painted; 337 name a backdrop colour and 58 a transfer function. All four are read here.

The second half is what the first half made visible

A form that says it is a transparency group has to be drawn as one thing: everything inside it at full strength against a copy of the page, and then the alpha and the mask in force where it was used applied to the whole result.

Drawn one mark at a time instead, a figure's own graphics state — set inside the form, where it starts again at 1 — throws the page's away, and every overlap inside the group doubles up. That is the difference between a shadow that fades and a slab.

Measured

On the 1 286 pages the corpus says this can reach: 1 276 drawn each way, no panics, 1 217 changed. Put beside macOS's own renderer, a circular zoom-inset that was an opaque rectangle over half a figure cuts to its circle; panel backgrounds that were solid colour become the faint tints they were meant to be; a code panel that came out blank draws in full; an isometric diagram that was a green slab becomes the wash it is.

The full-corpus A/B is still running and will be posted here. On a 3 000-page sample run back to back against v0.7.0 the cost is 1.8% (4:57.16 → 5:02.52).

Also

A mask is a byte a pixel rather than a float — it is read off an eight-bit picture, so a float held no more information — and only 64 are kept, because a page may name a great many.

Two correctness fixes found in review: the mask cache was keyed on the form rather than on the mask dictionary, so two states sharing a form but differing in backdrop or transfer function would have shared a mask; and a mask named in the middle of a run of text moved the pen, because gs is legal inside BT…ET and the text matrices live on the renderer.

100% statement coverage, go vet and -race clean, nine cross-compile targets.

A soft mask is how a PDF says that what is drawn from here on shows through
by an amount that varies from one place on the page to another. It is not a
number but a whole little drawing of its own — a form, on paper of its own —
and what is read off that drawing is the mask: how light each pixel came out,
or how much of it was painted at all. It is how nearly every drop shadow,
every soft edge and every faded surface in an illustration is written.

The corpus was asked first: 1 286 of its pages name one, seven times as many
as carry a mesh shading. 871 read the light in the drawing and 415 how much
of it was painted; 337 name a backdrop colour and 58 a transfer function.
All four are read here.

The second half of the change is what the first half made visible. A form
that says it is a transparency group has to be drawn as one thing: everything
inside it goes on at full strength against a copy of the page, and then the
alpha and the mask in force where it was used are applied to the whole of the
result. Drawn one mark at a time instead, a figure's own graphics state — set
inside the form, where it starts again at one — throws the page's away, and
every overlap inside the group doubles up. That is the difference between a
shadow that fades and a slab.

A mask is a byte a pixel rather than a float, since it is read off an
eight-bit picture and holding it wider than it was measured would only cost
memory; and only so many are kept, because a page may name a great many.

Measured on the 1 286 pages the corpus says this can reach: 1 276 drawn each
way with no panics, 1 217 changed. Put beside macOS's own renderer, a
circular zoom-inset that was an opaque rectangle over half a figure cuts to
its circle; panel backgrounds that were solid colour become the faint tints
they were meant to be; a code panel that came out blank draws in full; and an
isometric diagram that was a green slab becomes the wash it is.
@tannevaled
tannevaled merged commit 5857012 into main Aug 27, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant