Commit | Line | Data |
---|---|---|
49f42e3c CW |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
bc77d7c0 | 4 | | Copyright CiviCRM LLC. All rights reserved. | |
49f42e3c | 5 | | | |
bc77d7c0 TO |
6 | | This work is published under the GNU AGPLv3 license with some | |
7 | | permitted exceptions and without any warranty. For full license | | |
8 | | and copyright information, see https://civicrm.org/licensing | | |
49f42e3c CW |
9 | +--------------------------------------------------------------------+ |
10 | */ | |
11 | ||
12 | /** | |
13 | * | |
14 | * @package CRM | |
ca5cec67 | 15 | * @copyright CiviCRM LLC https://civicrm.org/licensing |
49f42e3c CW |
16 | */ |
17 | ||
18 | /** | |
19 | * Static utility functions for working with colors | |
20 | */ | |
21 | class CRM_Utils_Color { | |
22 | ||
0f4485f5 CW |
23 | const COLOR_FILE = '[civicrm.root]/bower_components/css-color-names/css-color-names.json'; |
24 | ||
49f42e3c CW |
25 | /** |
26 | * Determine the appropriate text color for a given background. | |
27 | * | |
28 | * Based on YIQ value. | |
29 | * | |
0f4485f5 | 30 | * @param string $color |
8a52ae34 CW |
31 | * @param string $black |
32 | * @param string $white | |
49f42e3c CW |
33 | * @return string |
34 | */ | |
0f4485f5 CW |
35 | public static function getContrast($color, $black = 'black', $white = 'white') { |
36 | list($r, $g, $b) = self::getRgb($color); | |
49f42e3c | 37 | $yiq = (($r * 299) + ($g * 587) + ($b * 114)) / 1000; |
8a52ae34 CW |
38 | return ($yiq >= 128) ? $black : $white; |
39 | } | |
40 | ||
41 | /** | |
0f4485f5 CW |
42 | * Parse any color string into rgb decimal values |
43 | * | |
44 | * Accepted formats: | |
45 | * Full hex: "#ffffff" | |
46 | * Short hex: "#fff" | |
47 | * Color name "white" | |
48 | * RGB notation: "rgb(255, 255, 255)" | |
8a52ae34 | 49 | * |
0f4485f5 CW |
50 | * @param string $color |
51 | * @return int[]|null | |
8a52ae34 CW |
52 | * [red, green, blue] |
53 | */ | |
0f4485f5 CW |
54 | public static function getRgb($color) { |
55 | $color = str_replace(' ', '', $color); | |
56 | $color = self::nameToHex($color) ?? $color; | |
57 | if (strpos($color, 'rgb(') === 0) { | |
58 | return explode(',', substr($color, 4, strpos($color, ')') - 4)); | |
59 | } | |
60 | $color = ltrim($color, '#'); | |
61 | if (strlen($color) === 3) { | |
62 | $color = $color[0] . $color[0] . $color[1] . $color[1] . $color[2] . $color[2]; | |
63 | } | |
64 | if (!CRM_Utils_Rule::color('#' . $color)) { | |
65 | return NULL; | |
8a52ae34 CW |
66 | } |
67 | return [ | |
0f4485f5 CW |
68 | hexdec(substr($color, 0, 2)), |
69 | hexdec(substr($color, 2, 2)), | |
70 | hexdec(substr($color, 4, 2)), | |
8a52ae34 CW |
71 | ]; |
72 | } | |
73 | ||
74 | /** | |
75 | * Calculate a highlight color from a base color | |
76 | * | |
0f4485f5 | 77 | * @param $color |
8a52ae34 CW |
78 | * @return string |
79 | */ | |
0f4485f5 CW |
80 | public static function getHighlight($color) { |
81 | $rgb = self::getRgb($color); | |
8a52ae34 CW |
82 | $avg = array_sum($rgb) / 3; |
83 | foreach ($rgb as &$v) { | |
84 | if ($avg > 242) { | |
85 | // For very bright values, lower the brightness | |
86 | $v -= 50; | |
87 | } | |
88 | else { | |
89 | // Bump up brightness on a nonlinear curve - darker colors get more of a boost | |
90 | $v = min(255, intval((-.0035 * ($v - 242) ** 2) + 260)); | |
91 | } | |
92 | } | |
0f4485f5 CW |
93 | return self::rgbToHex($rgb); |
94 | } | |
95 | ||
96 | /** | |
97 | * Convert named color (e.g. springgreen) to hex | |
98 | * | |
99 | * @param $colorName | |
100 | * @return string|null | |
101 | */ | |
102 | public static function nameToHex($colorName) { | |
103 | if (strpos($colorName, '#') !== FALSE || strpos($colorName, '(') !== FALSE) { | |
104 | return NULL; | |
105 | } | |
106 | if (empty(Civi::$statics[__CLASS__]['names'])) { | |
107 | Civi::$statics[__CLASS__]['names'] = json_decode(file_get_contents(Civi::paths()->getPath(self::COLOR_FILE)), TRUE); | |
108 | } | |
109 | return Civi::$statics[__CLASS__]['names'][strtolower($colorName)] ?? NULL; | |
110 | } | |
111 | ||
112 | /** | |
113 | * Converts rgb array to hex string | |
114 | * | |
115 | * @param int[] $rgb | |
116 | * @return string | |
117 | */ | |
118 | public static function rgbToHex($rgb) { | |
119 | $ret = '#'; | |
120 | foreach ($rgb as $dec) { | |
121 | $ret .= str_pad(dechex($dec), 2, '0', STR_PAD_LEFT); | |
122 | } | |
123 | return $ret; | |
124 | } | |
125 | ||
126 | /** | |
127 | * Validate color input and convert it to standard hex notation | |
128 | * | |
129 | * @param string $color | |
130 | * @return bool | |
131 | */ | |
132 | public static function normalize(&$color) { | |
133 | $rgb = self::getRgb($color); | |
134 | if ($rgb) { | |
135 | $color = self::rgbToHex($rgb); | |
136 | return TRUE; | |
137 | } | |
138 | return FALSE; | |
49f42e3c CW |
139 | } |
140 | ||
141 | } |