68 lines
2.5 KiB
PHP
68 lines
2.5 KiB
PHP
<?php
|
||
|
||
if (! function_exists('format_event_url')) {
|
||
/**
|
||
* format an event url with a given calendar ID and event ID
|
||
*/
|
||
function format_event_url(string $eid, string $cid): string
|
||
{
|
||
return 'calendar/'.$cid.'/event/'.$eid;
|
||
}
|
||
}
|
||
|
||
if (! function_exists('contrast_text_color')) {
|
||
/**
|
||
* Choose an accessible foreground (#fff or #000) against a HEX background.
|
||
*
|
||
* Rule set:
|
||
* 1. Calculate WCAG contrast ratios for both black and white.
|
||
* 2. Prefer the colour with the *higher* ratio.
|
||
* 3. Override: if black wins but ratio < 5.5 AND white > 4, use white.
|
||
*
|
||
* @param string $hex Background colour (3- or 6-digit hex, with or without #)
|
||
* @param string $light Return value for “white” (default '#ffffff')
|
||
* @param string $dark Return value for “black” (default '#000000')
|
||
* @return string
|
||
*/
|
||
function contrast_text_color(string $hex, string $light = '#ffffff', string $dark = '#000000'): string
|
||
{
|
||
// --- normalise ----------------------------------------------------
|
||
$hex = ltrim($hex, '#');
|
||
if (strlen($hex) === 3) { // #abc → #aabbcc
|
||
$hex = preg_replace('/./', '$0$0', $hex);
|
||
}
|
||
|
||
[$r, $g, $b] = [
|
||
hexdec(substr($hex, 0, 2)) / 255,
|
||
hexdec(substr($hex, 2, 2)) / 255,
|
||
hexdec(substr($hex, 4, 2)) / 255,
|
||
];
|
||
|
||
// --- convert sRGB → linear RGB -----------------------------------
|
||
$linear = function (float $c): float {
|
||
return $c <= 0.04045 ? $c / 12.92 : pow(($c + 0.055) / 1.055, 2.4);
|
||
};
|
||
|
||
$R = $linear($r);
|
||
$G = $linear($g);
|
||
$B = $linear($b);
|
||
|
||
// --- relative luminance (ITU-R BT.709) ----------------------------
|
||
$L_bg = 0.2126 * $R + 0.7152 * $G + 0.0722 * $B; // 0–1
|
||
|
||
// --- contrast ratios vs black (L=0) and white (L=1) ---------------
|
||
$contrast_black = ($L_bg + 0.05) / 0.05; // bg lighter than black
|
||
$contrast_white = 1.05 / ($L_bg + 0.05); // white vs bg
|
||
|
||
// --- pick the winner ---------------------------------------------
|
||
$useDark = $contrast_black >= $contrast_white;
|
||
|
||
// override rule if dark is true but white "looks better"
|
||
if ($useDark && $contrast_black < 5.5 && $contrast_white > 4) {
|
||
$useDark = false; // switch to white
|
||
}
|
||
|
||
return $useDark ? $dark : $light;
|
||
}
|
||
}
|