Skip to content

enhance(ui): improve luminance calculations - #38682

Open
silverwind wants to merge 2 commits into
go-gitea:mainfrom
silverwind:linearize-contrast-luminance
Open

enhance(ui): improve luminance calculations#38682
silverwind wants to merge 2 commits into
go-gitea:mainfrom
silverwind:linearize-contrast-luminance

Conversation

@silverwind

@silverwind silverwind commented Jul 28, 2026

Copy link
Copy Markdown
Member

Improve luminance calculations for label text colors and project columns as per #37477 (comment) which improves contrast on a few mid-tones as seen in screenshot below.

Channels are now linearized before weighting, which is what WCAG relative luminance requires, and the flip point moves from 0.453 to 0.36 to best match APCA. Scoped label shading keeps the old gamma-encoded value via GetPerceivedBrightness.

Left side text is main, right is this branch:

image

The luminance used to pick black or white foreground text summed
gamma-encoded channels, so it was not a relative luminance despite the
name. Linearize the channels first, and move the flip point from 0.453 to
0.36, which tracks APCA far more closely than either the old value or
WCAG's own 0.179 crossover.

Scoped label shading keeps the previous gamma-space value via
GetPerceivedBrightness, because it derives factors that scale the raw
channels proportionally and only holds in that space.

Assisted-by: Claude Code:Opus 5
@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Jul 28, 2026
@silverwind silverwind changed the title fix: linearize luminance and retune contrast color threshold enhance: linearize luminance and retune contrast color threshold Jul 28, 2026
@github-actions github-actions Bot added type/enhancement An improvement of existing functionality and removed type/bug labels Jul 28, 2026
@silverwind silverwind changed the title enhance: linearize luminance and retune contrast color threshold enhance: improve luminance calculations for label colors Jul 28, 2026
@silverwind silverwind changed the title enhance: improve luminance calculations for label colors enhance: improve luminance calculations Jul 28, 2026
The scoped label local held a gamma-encoded brightness, not a luminance.
getRelativeLuminance lost its only caller outside the package when scoped
label shading moved to GetPerceivedBrightness, so it no longer needs to be
exported.

Assisted-by: Claude Code:Opus 5
@silverwind silverwind changed the title enhance: improve luminance calculations enhance(ui): improve luminance calculations Jul 28, 2026
@github-actions github-actions Bot added the topic/ui Change the appearance of the Gitea UI label Jul 28, 2026
Comment thread modules/util/color.go
Comment on lines +59 to 62
func GetPerceivedBrightness(color string) float64 {
r, g, b := HexToRBGColor(color)
return (0.2126729*r + 0.7151522*g + 0.0721750*b) / 255
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is technically computing the luma, which is a quick-and-dirty approximation of the gamma-encoded luminance. It is used in video only because it can be computed very cheaply, even with simple resistors in an analog circuit. Luma is a reasonable approximation of brightness for low-saturation colors. However, it is quite bad when the colors get saturated.

If you want a representation of the luminance in the same gamma-encoded color space as the initial sRGB values, the proper solution is to gamma-encode the output of getRelativeLuminance(), i.e. to perform the linearizeChannel() transform backwards on the relative luminance. This ensures that colors have the same “perceived brightness” if and only if the have the same luminance, which is required by the definition of “luminance”.

@silverwind silverwind Jul 28, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think ultimately the approximation is good enough for our use case, but sure I will investigate a bit more. The current implementation is already better than what browser vendors recently implemented as part of color-contrast.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't know about color-contrast. Thanks for the pointer! Luma is indeed a very common approximation, so it is presumably good enough most of the time. It can still be pretty bad with saturated colors, like pure blue:

luma           = 0.0722 * 255 = 18.411, rounded to 18 = 0x12
luminance      = 0.0722,
gamma-encoded to 0.2979 * 255 = 75.963, rounded to 76 = 0x4c

See the figure below: each blue rectangle is supposed to have the same “brightness” as the grey rectangle around it, for two different meanings of “brightness”. YMMV but, to my eyes, luma here fails miserably at conveying the brightness of the blue box.

luminance-vs-luma

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. topic/ui Change the appearance of the Gitea UI type/enhancement An improvement of existing functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants