@@ -8,6 +8,7 @@ package models
88import (
99 "fmt"
1010 "html/template"
11+ "math"
1112 "regexp"
1213 "strconv"
1314 "strings"
@@ -138,19 +139,44 @@ func (label *Label) BelongsToRepo() bool {
138139 return label .RepoID > 0
139140}
140141
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+
141167// ForegroundColor calculates the text color for labels based
142168// on their background color.
143169func (label * Label ) ForegroundColor () template.CSS {
144170 if strings .HasPrefix (label .Color , "#" ) {
145171 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 ))
150174
151- if luminance < 0.66 {
175+ // prefer white or black based upon contrast
176+ if luminance < LuminanceThreshold {
152177 return template .CSS ("#fff" )
153178 }
179+ return template .CSS ("#000" )
154180 }
155181 }
156182
0 commit comments