summaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
authorClar Fon <usr@ltdk.xyz>2021-08-25 13:55:47 -0400
committerGitHub <noreply@github.com>2021-08-25 12:55:47 -0500
commit29b971b6d5451d0bba1fea21b981ea86a600aaaa (patch)
tree9d36bbe57d1110cefd94d3e0cd5192bfa4f94de6 /models
parent20efc6b56c4b56352496e33b3dcde5a4ae2f8a66 (diff)
downloadgitea-29b971b6d5451d0bba1fea21b981ea86a600aaaa.tar.gz
gitea-29b971b6d5451d0bba1fea21b981ea86a600aaaa.zip
Actually compute proper foreground color for labels (#16729)
Diffstat (limited to 'models')
-rw-r--r--models/issue_label.go36
1 files changed, 31 insertions, 5 deletions
diff --git a/models/issue_label.go b/models/issue_label.go
index 5d50203b5a..936dd71e38 100644
--- a/models/issue_label.go
+++ b/models/issue_label.go
@@ -8,6 +8,7 @@ package models
import (
"fmt"
"html/template"
+ "math"
"regexp"
"strconv"
"strings"
@@ -138,19 +139,44 @@ func (label *Label) BelongsToRepo() bool {
return label.RepoID > 0
}
+// SrgbToLinear converts a component of an sRGB color to its linear intensity
+// See: https://en.wikipedia.org/wiki/SRGB#The_reverse_transformation_(sRGB_to_CIE_XYZ)
+func SrgbToLinear(color uint8) float64 {
+ flt := float64(color) / 255
+ if flt <= 0.04045 {
+ return flt / 12.92
+ }
+ return math.Pow((flt+0.055)/1.055, 2.4)
+}
+
+// Luminance returns the luminance of an sRGB color
+func Luminance(color uint32) float64 {
+ r := SrgbToLinear(uint8(0xFF & (color >> 16)))
+ g := SrgbToLinear(uint8(0xFF & (color >> 8)))
+ b := SrgbToLinear(uint8(0xFF & color))
+
+ // luminance ratios for sRGB
+ return 0.2126*r + 0.7152*g + 0.0722*b
+}
+
+// LuminanceThreshold is the luminance at which white and black appear to have the same contrast
+// i.e. x such that 1.05 / (x + 0.05) = (x + 0.05) / 0.05
+// i.e. math.Sqrt(1.05*0.05) - 0.05
+const LuminanceThreshold float64 = 0.179
+
// ForegroundColor calculates the text color for labels based
// on their background color.
func (label *Label) ForegroundColor() template.CSS {
if strings.HasPrefix(label.Color, "#") {
if color, err := strconv.ParseUint(label.Color[1:], 16, 64); err == nil {
- r := float32(0xFF & (color >> 16))
- g := float32(0xFF & (color >> 8))
- b := float32(0xFF & color)
- luminance := (0.2126*r + 0.7152*g + 0.0722*b) / 255
+ // NOTE: see web_src/js/components/ContextPopup.vue for similar implementation
+ luminance := Luminance(uint32(color))
- if luminance < 0.66 {
+ // prefer white or black based upon contrast
+ if luminance < LuminanceThreshold {
return template.CSS("#fff")
}
+ return template.CSS("#000")
}
}