@@ -1155,6 +1155,57 @@ public function fileTypeIcon(string $type): string
1155
1155
return 'fas fa-file- ' . $ iconName ;
1156
1156
}
1157
1157
1158
+ private function relativeLuminance (string $ rgb ): float
1159
+ {
1160
+ // See https://en.wikipedia.org/wiki/Relative_luminance
1161
+ [$ r , $ g , $ b , $ a ] = Utils::parseHexColor ($ rgb );
1162
+
1163
+ [$ lr , $ lg , $ lb ] = [
1164
+ pow ($ r / 255 , 2.4 ),
1165
+ pow ($ g / 255 , 2.4 ),
1166
+ pow ($ b / 255 , 2.4 ),
1167
+ ];
1168
+
1169
+ return 0.2126 * $ lr + 0.7152 * $ lg + 0.0722 * $ lb ;
1170
+ }
1171
+
1172
+ private function apcaContrast (string $ fgColor , string $ bgColor ): float
1173
+ {
1174
+ // Based on WCAG 3.x (https://www.w3.org/TR/wcag-3.0/)
1175
+ $ luminanceForeground = $ this ->relativeLuminance ($ fgColor );
1176
+ $ luminanceBackground = $ this ->relativeLuminance ($ bgColor );
1177
+
1178
+ $ contrast = ($ luminanceBackground > $ luminanceForeground )
1179
+ ? (pow ($ luminanceBackground , 0.56 ) - pow ($ luminanceForeground , 0.57 )) * 1.14
1180
+ : (pow ($ luminanceBackground , 0.65 ) - pow ($ luminanceForeground , 0.62 )) * 1.14 ;
1181
+
1182
+ return round ($ contrast * 100 , 2 );
1183
+ }
1184
+
1185
+ /**
1186
+ * @return array{string, string}
1187
+ */
1188
+ private function hexToForegroundAndBorder (string $ rgb ): array
1189
+ {
1190
+ $ background = Utils::parseHexColor ($ rgb );
1191
+
1192
+ // Pick a border that's a bit darker.
1193
+ $ darker = $ background ;
1194
+ $ darker [0 ] = max ($ darker [0 ] - 64 , 0 );
1195
+ $ darker [1 ] = max ($ darker [1 ] - 64 , 0 );
1196
+ $ darker [2 ] = max ($ darker [2 ] - 64 , 0 );
1197
+ $ darker [3 ] = max ($ darker [3 ] - 64 , 0 );
1198
+ $ border = Utils::rgbToHex ($ darker );
1199
+
1200
+ // Pick the text color with the biggest absolute contrast.
1201
+ $ contrastWithWhite = $ this ->apcaContrast ('#ffffff ' , $ rgb );
1202
+ $ contrastWithBlack = $ this ->apcaContrast ('#000000 ' , $ rgb );
1203
+
1204
+ $ foreground = (abs ($ contrastWithBlack ) > abs ($ contrastWithWhite )) ? '#000000 ' : '#ffffff ' ;
1205
+
1206
+ return [$ foreground , $ border ];
1207
+ }
1208
+
1158
1209
public function problemBadge (ContestProblem $ problem , bool $ grayedOut = false ): string
1159
1210
{
1160
1211
$ rgb = Utils::convertToHex ($ problem ->getColor () ?? '#ffffff ' );
0 commit comments