@@ -8,6 +8,7 @@ package models
8
8
import (
9
9
"fmt"
10
10
"html/template"
11
+ "math"
11
12
"regexp"
12
13
"strconv"
13
14
"strings"
@@ -138,19 +139,44 @@ func (label *Label) BelongsToRepo() bool {
138
139
return label .RepoID > 0
139
140
}
140
141
142
+ // SrgbToLinear converts a component of an sRGB color to its linear intensity
143
+ // See: https://en.wikipedia.org/wiki/SRGB#The_reverse_transformation_(sRGB_to_CIE_XYZ)
144
+ func SrgbToLinear (color uint8 ) float64 {
145
+ flt := float64 (color ) / 255
146
+ if flt <= 0.04045 {
147
+ return flt / 12.92
148
+ }
149
+ return math .Pow ((flt + 0.055 )/ 1.055 , 2.4 )
150
+ }
151
+
152
+ // Luminance returns the luminance of an sRGB color
153
+ func Luminance (color uint32 ) float64 {
154
+ r := SrgbToLinear (uint8 (0xFF & (color >> 16 )))
155
+ g := SrgbToLinear (uint8 (0xFF & (color >> 8 )))
156
+ b := SrgbToLinear (uint8 (0xFF & color ))
157
+
158
+ // luminance ratios for sRGB
159
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b
160
+ }
161
+
162
+ // LuminanceThreshold is the luminance at which white and black appear to have the same contrast
163
+ // i.e. x such that 1.05 / (x + 0.05) = (x + 0.05) / 0.05
164
+ // i.e. math.Sqrt(1.05*0.05) - 0.05
165
+ const LuminanceThreshold float64 = 0.179
166
+
141
167
// ForegroundColor calculates the text color for labels based
142
168
// on their background color.
143
169
func (label * Label ) ForegroundColor () template.CSS {
144
170
if strings .HasPrefix (label .Color , "#" ) {
145
171
if color , err := strconv .ParseUint (label .Color [1 :], 16 , 64 ); err == nil {
146
- r := float32 (0xFF & (color >> 16 ))
147
- g := float32 (0xFF & (color >> 8 ))
148
- b := float32 (0xFF & color )
149
- luminance := (0.2126 * r + 0.7152 * g + 0.0722 * b ) / 255
172
+ // NOTE: see web_src/js/components/ContextPopup.vue for similar implementation
173
+ luminance := Luminance (uint32 (color ))
150
174
151
- if luminance < 0.66 {
175
+ // prefer white or black based upon contrast
176
+ if luminance < LuminanceThreshold {
152
177
return template .CSS ("#fff" )
153
178
}
179
+ return template .CSS ("#000" )
154
180
}
155
181
}
156
182
0 commit comments