X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=CRM%2FUtils%2FColor.php;h=95872433f52598cc65e7334f0850928545d5de4e;hb=2c2c4aa4fb2555ec3ceb089d326a648c135c5dbd;hp=5d965dd342e6371c5a411c3ae76594c5d4a0a2ca;hpb=b8ebe34c530297a2c8b6a7380ac204c6153ff74c;p=civicrm-core.git diff --git a/CRM/Utils/Color.php b/CRM/Utils/Color.php index 5d965dd342..95872433f5 100644 --- a/CRM/Utils/Color.php +++ b/CRM/Utils/Color.php @@ -3,7 +3,7 @@ +--------------------------------------------------------------------+ | CiviCRM version 5 | +--------------------------------------------------------------------+ - | Copyright CiviCRM LLC (c) 2004-2018 | + | Copyright CiviCRM LLC (c) 2004-2019 | +--------------------------------------------------------------------+ | This file is a part of CiviCRM. | | | @@ -28,7 +28,7 @@ /** * * @package CRM - * @copyright CiviCRM LLC (c) 2004-2018 + * @copyright CiviCRM LLC (c) 2004-2019 */ /** @@ -36,21 +36,122 @@ */ class CRM_Utils_Color { + const COLOR_FILE = '[civicrm.root]/bower_components/css-color-names/css-color-names.json'; + /** * Determine the appropriate text color for a given background. * * Based on YIQ value. * - * @param string $hexcolor + * @param string $color + * @param string $black + * @param string $white * @return string */ - public static function getContrast($hexcolor) { - $hexcolor = trim($hexcolor, ' #'); - $r = hexdec(substr($hexcolor, 0, 2)); - $g = hexdec(substr($hexcolor, 2, 2)); - $b = hexdec(substr($hexcolor, 4, 2)); + public static function getContrast($color, $black = 'black', $white = 'white') { + list($r, $g, $b) = self::getRgb($color); $yiq = (($r * 299) + ($g * 587) + ($b * 114)) / 1000; - return ($yiq >= 128) ? 'black' : 'white'; + return ($yiq >= 128) ? $black : $white; + } + + /** + * Parse any color string into rgb decimal values + * + * Accepted formats: + * Full hex: "#ffffff" + * Short hex: "#fff" + * Color name "white" + * RGB notation: "rgb(255, 255, 255)" + * + * @param string $color + * @return int[]|null + * [red, green, blue] + */ + public static function getRgb($color) { + $color = str_replace(' ', '', $color); + $color = self::nameToHex($color) ?? $color; + if (strpos($color, 'rgb(') === 0) { + return explode(',', substr($color, 4, strpos($color, ')') - 4)); + } + $color = ltrim($color, '#'); + if (strlen($color) === 3) { + $color = $color[0] . $color[0] . $color[1] . $color[1] . $color[2] . $color[2]; + } + if (!CRM_Utils_Rule::color('#' . $color)) { + return NULL; + } + return [ + hexdec(substr($color, 0, 2)), + hexdec(substr($color, 2, 2)), + hexdec(substr($color, 4, 2)), + ]; + } + + /** + * Calculate a highlight color from a base color + * + * @param $color + * @return string + */ + public static function getHighlight($color) { + $rgb = self::getRgb($color); + $avg = array_sum($rgb) / 3; + foreach ($rgb as &$v) { + if ($avg > 242) { + // For very bright values, lower the brightness + $v -= 50; + } + else { + // Bump up brightness on a nonlinear curve - darker colors get more of a boost + $v = min(255, intval((-.0035 * ($v - 242) ** 2) + 260)); + } + } + return self::rgbToHex($rgb); + } + + /** + * Convert named color (e.g. springgreen) to hex + * + * @param $colorName + * @return string|null + */ + public static function nameToHex($colorName) { + if (strpos($colorName, '#') !== FALSE || strpos($colorName, '(') !== FALSE) { + return NULL; + } + if (empty(Civi::$statics[__CLASS__]['names'])) { + Civi::$statics[__CLASS__]['names'] = json_decode(file_get_contents(Civi::paths()->getPath(self::COLOR_FILE)), TRUE); + } + return Civi::$statics[__CLASS__]['names'][strtolower($colorName)] ?? NULL; + } + + /** + * Converts rgb array to hex string + * + * @param int[] $rgb + * @return string + */ + public static function rgbToHex($rgb) { + $ret = '#'; + foreach ($rgb as $dec) { + $ret .= str_pad(dechex($dec), 2, '0', STR_PAD_LEFT); + } + return $ret; + } + + /** + * Validate color input and convert it to standard hex notation + * + * @param string $color + * @return bool + */ + public static function normalize(&$color) { + $rgb = self::getRgb($color); + if ($rgb) { + $color = self::rgbToHex($rgb); + return TRUE; + } + return FALSE; } }