Skip to content

Commit 48c8b55

Browse files
committed
Fix clarifications for unlinked problems
Closes: #3032
1 parent 2873500 commit 48c8b55

File tree

2 files changed

+59
-4
lines changed

2 files changed

+59
-4
lines changed

webapp/src/Controller/Jury/ClarificationController.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,12 @@ public function viewAction(Request $request, int $id): Response
193193
$clarcontest = $contest->getShortname();
194194
$data['subjectlink'] = null;
195195
if ($clar->getProblem()) {
196-
$concernssubject = $contest->getCid() . "-" . $clar->getProblem()->getProbid();
196+
if ($clar->getContestProblem()) {
197+
$concernssubject = $contest->getCid() . "-" . $clar->getProblem()->getProbid();
198+
} else {
199+
// Very special case, this problem is unlinked.
200+
$concernssubject = "";
201+
}
197202
$data['subjectlink'] = $this->generateUrl('jury_problem', ['probId' => $clar->getProblem()->getProbid()]);
198203
} elseif ($clar->getCategory()) {
199204
$concernssubject = $contest->getCid() . "-" . $clar->getCategory();

webapp/src/Twig/TwigExtension.php

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,9 +1179,59 @@ public function fileTypeIcon(string $type): string
11791179
return 'fas fa-file-' . $iconName;
11801180
}
11811181

1182-
public function problemBadge(ContestProblem $problem, bool $grayedOut = false): string
1182+
private function relativeLuminance(string $rgb): float
11831183
{
1184-
$rgb = Utils::convertToHex($problem->getColor() ?? '#ffffff');
1184+
// See https://en.wikipedia.org/wiki/Relative_luminance
1185+
[$r, $g, $b] = Utils::parseHexColor($rgb);
1186+
1187+
[$lr, $lg, $lb] = [
1188+
pow($r / 255, 2.4),
1189+
pow($g / 255, 2.4),
1190+
pow($b / 255, 2.4),
1191+
];
1192+
1193+
return 0.2126 * $lr + 0.7152 * $lg + 0.0722 * $lb;
1194+
}
1195+
1196+
private function apcaContrast(string $fgColor, string $bgColor): float
1197+
{
1198+
// Based on WCAG 3.x (https://www.w3.org/TR/wcag-3.0/)
1199+
$luminanceForeground = $this->relativeLuminance($fgColor);
1200+
$luminanceBackground = $this->relativeLuminance($bgColor);
1201+
1202+
$contrast = ($luminanceBackground > $luminanceForeground)
1203+
? (pow($luminanceBackground, 0.56) - pow($luminanceForeground, 0.57)) * 1.14
1204+
: (pow($luminanceBackground, 0.65) - pow($luminanceForeground, 0.62)) * 1.14;
1205+
1206+
return round($contrast * 100, 2);
1207+
}
1208+
1209+
/**
1210+
* @return array{string, string}
1211+
*/
1212+
private function hexToForegroundAndBorder(string $rgb): array
1213+
{
1214+
$background = Utils::parseHexColor($rgb);
1215+
1216+
// Pick a border that's a bit darker.
1217+
$darker = $background;
1218+
$darker[0] = max($darker[0] - 64, 0);
1219+
$darker[1] = max($darker[1] - 64, 0);
1220+
$darker[2] = max($darker[2] - 64, 0);
1221+
$border = Utils::rgbToHex($darker);
1222+
1223+
// Pick the text color with the biggest absolute contrast.
1224+
$contrastWithWhite = $this->apcaContrast('#ffffff', $rgb);
1225+
$contrastWithBlack = $this->apcaContrast('#000000', $rgb);
1226+
1227+
$foreground = (abs($contrastWithBlack) > abs($contrastWithWhite)) ? '#000000' : '#ffffff';
1228+
1229+
return [$foreground, $border];
1230+
}
1231+
1232+
public function problemBadge(?ContestProblem $problem, bool $grayedOut = false): string
1233+
{
1234+
$rgb = Utils::convertToHex($problem?->getColor() ?? '#ffffff');
11851235
if ($grayedOut || empty($rgb)) {
11861236
$rgb = Utils::convertToHex('whitesmoke');
11871237
}
@@ -1197,7 +1247,7 @@ public function problemBadge(ContestProblem $problem, bool $grayedOut = false):
11971247
$rgb,
11981248
$border,
11991249
$foreground,
1200-
$problem->getShortname()
1250+
$problem?->getShortname() ?? '?'
12011251
);
12021252
}
12031253

0 commit comments

Comments
 (0)