Skip to content

Degenerate paint servers: Chromium dithers the substituted colour #93

Description

@softmarshmallow

Split out of the stop-color/stop-opacity rung so it does not ride an unrelated tick.

What is refused

svg-gradient-degenerate-precision in the Web-first refusal register: a degenerate paint server (coincident linear endpoints, or a zero/negative radial radius) whose substituted colour does not land exactly on an eight-bit value.

Why

Chromium does not paint a degenerate paint server as a flat colour. It keeps a shader, and that shader dithers.

Where every stage is a byte there is nothing to dither, and the flat solid this engine substitutes is byte-identical. Those cases are celled in fixtures/web-first/svg-gradient-stop-degenerate-float.svg:

  • a repeat ramp average of 77/255 and 129/255 landing exactly on 103/255
  • a reflect colour average of 0 and 3 landing on 1.5 and rounding up to 2
  • pad taking a byte-exact translucent last stop
  • the zero-radius radial route

Where a stage is not a byte, Chromium's output matched no flat solid and no constant ramp a probe could construct. A degenerate pad at stop alpha 0.5 under fill-opacity=".7" sat 2,560–4,096 pixels away from every candidate at Δ1 — the signature of a dither pattern tied to the degenerate shader's own geometry, which this engine cannot express because collapsing degeneracy is precisely what keeps downstream preflight inside its checked gradient domain.

Guessing that rule would be a silent wrong pixel, so it refuses by name instead.

Scope

This is a gradient-geometry gap, not a stop-grammar one: it fires on the collapsed value however it arose. Two byte-exact stop-colors whose ramp average lands between codes trip it with no stop-opacity present at all. It therefore belongs to the already-ticked <linearGradient>/<radialGradient> rows and does not hold the stop-color/stop-opacity rows open.

What a rung here would need

An account of Skia's degenerate-gradient dither that is measured rather than inferred, and a way for the resolved contract to carry a degenerate paint server without collapsing it — or a demonstration that the collapse can reproduce the dither exactly.

No conformance score is implied. FLIP is untouched.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions