Skip to content

fix(import): apply the sRGB transfer function to srgb-linear colours and keep alpha - #702

Merged
rubenvdlinde merged 1 commit into
developmentfrom
fix/695-dtcg-linear-and-alpha
Sep 28, 2026
Merged

rubenvdlinde merged 1 commit into
developmentfrom
fix/695-dtcg-linear-and-alpha

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Importing a W3C design tokens file gave the wrong colour for an srgb-linear colour and for any colour with alpha.

The defect

DesignTokensMapper::serializeColorObject() sent srgb and srgb-linear components to the same converter, which scaled each component by 255 without the sRGB transfer function and wrote three channels only. A linear 0.5 grey became #808080 instead of about #bcbcbc, and alpha was never read, so a translucent colour imported opaque. Nothing was reported.

The tests that were red

In tests/Unit/Service/DesignTokensMapperTest.php: testSrgbLinearAppliesTransferFunction, testSrgbLinearNearBlackUsesTheLinearSegment, testAlphaKeptAsEightDigitHex, testSrgbLinearWithAlpha and testAlphaIsAddedToTheHexFallback. testOpaqueColourStaysSixDigitHex guards existing sets.

The fix

  • srgb-linear components go through the CSS Color 4 sRGB transfer function before scaling, including its linear segment near black.
  • An alpha below 1 is kept as the fourth pair of an 8-digit hex, on the components path and on the 6-digit hex fallback. An opaque colour stays a 6-digit hex, so existing imports do not change.

The other colour spaces and the out-of-gamut reasons in authoring-dtcg-export task 2.2 are not part of this change. The contrast audit and the dark palette do not read 8-digit hex yet; that is #696.

Verified

  • composer check:strict: exit 0 (its test:all skips in a bare clone, so PHPUnit ran separately).
  • PHPUnit with the server's lib/private on the autoloader: 861 tests, the same 11 errors and 7 failures as on development (missing Symfony and server classes outside a Nextcloud tree).
  • npm run lint, format, test:l10n, check:l10n-js, check:manifest, test:unit: all exit 0.
  • Hydra gates --scope-to-diff: exit 0.

Fixes #695

…and keep alpha

A DTCG colour given as components was scaled straight to 0-255, so an
srgb-linear colour came out too dark (a linear 0.5 grey became #808080
instead of #bcbcbc), and its alpha was never read, so a translucent colour
imported opaque. Linear components now go through the sRGB transfer
function, and an alpha below 1 is kept as the fourth pair of an 8-digit
hex, also on the hex fallback. Opaque colours stay 6-digit.

Fixes #695
@rubenvdlinde
rubenvdlinde merged commit 19e4c49 into development Sep 28, 2026
32 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/thematiq @ d087570

Check PHP Vue Security License Tests
lint ✅
phpcs ✅
phpmd ✅
psalm ✅
phpstan ✅
phpmetrics ✅
eslint ✅
stylelint ✅
build ✅
check-manifest ✅
test-l10n ✅
format ✅
composer ✅ ✅ 107/107
npm ✅ ✅ 2/2
app:check-code ⏭️
info.xml ✅
REUSE ✅
lockfile sync ✅
PHPUnit ✅
Newman ✅
Playwright ⏭️ deferred: E2E runs locally and on the promotion path only. This pull request targets development, so the suite is asked once per promotion into beta and main rather than once per push per open pull request. Run it on any branch from the Actions tab, or locally with npx playwright test.
Hydra gates ✅

Quality workflow — 2026-09-28 15:18 UTC

Download the full PDF report from the workflow artifacts.

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