misuzu/src/Colour.php

97 lines
2.6 KiB
PHP

<?php
namespace Misuzu;
use InvalidArgumentException;
class Colour {
private const FLAG_INHERIT = 0x40000000;
private const READABILITY_THRESHOLD = 186;
private const LUMINANCE_WEIGHT_RED = .299;
private const LUMINANCE_WEIGHT_GREEN = .587;
private const LUMINANCE_WEIGHT_BLUE = .114;
private int $raw = 0;
public function __construct(?int $raw = 0) {
$this->raw = ($raw ?? 0) & 0x7FFFFFFF;
}
public static function none(): self {
return new Colour(self::FLAG_INHERIT);
}
public static function fromRgb(int $red, int $green, int $blue): self {
$raw = (($red & 0xFF) << 16)
| (($green & 0xFF) << 8)
| ($blue & 0xFF);
return new Colour($raw);
}
public static function fromHex(string $hex): self {
if($hex[0] === '#')
$hex = mb_substr($hex, 1);
if(!ctype_xdigit($hex))
throw new InvalidArgumentException('Argument contains invalid characters.');
$length = mb_strlen($hex);
if($length === 3) {
$hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
} elseif($length !== 6) {
throw new InvalidArgumentException('Argument is not a hex string.');
}
return new Colour(hexdec($hex));
}
public function getRaw(): int {
return $this->raw;
}
public function getInherit(): bool {
return ($this->getRaw() & self::FLAG_INHERIT) > 0;
}
public function getRed(): int {
return ($this->getRaw() & 0xFF0000) >> 16;
}
public function getGreen(): int {
return ($this->getRaw() & 0xFF00) >> 8;
}
public function getBlue(): int {
return ($this->getRaw() & 0xFF);
}
public function getLuminance(): float {
return self::LUMINANCE_WEIGHT_RED * $this->getRed()
+ self::LUMINANCE_WEIGHT_GREEN * $this->getGreen()
+ self::LUMINANCE_WEIGHT_BLUE * $this->getBlue();
}
public function getHex(): string {
return str_pad(dechex($this->getRaw() & 0xFFFFFF), 6, '0', STR_PAD_LEFT);
}
public function getCSS(): string {
if($this->getInherit())
return 'inherit';
return '#' . $this->getHex();
}
public function extractCSSContract(
string $dark = 'dark', string $light = 'light', bool $inheritIsDark = true
): string {
if($this->getInherit())
return $inheritIsDark ? $dark : $light;
return $this->getLuminance() > self::READABILITY_THRESHOLD ? $dark : $light;
}
public function __toString() {
return $this->getCSS();
}
}