color.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. <?php
  2. class Kint_Parsers_Color extends kintParser
  3. {
  4. private static $_css3Named = array(
  5. 'aliceblue'=>'#f0f8ff','antiquewhite'=>'#faebd7','aqua'=>'#00ffff','aquamarine'=>'#7fffd4','azure'=>'#f0ffff',
  6. 'beige'=>'#f5f5dc','bisque'=>'#ffe4c4','black'=>'#000000','blanchedalmond'=>'#ffebcd','blue'=>'#0000ff',
  7. 'blueviolet'=>'#8a2be2','brown'=>'#a52a2a','burlywood'=>'#deb887','cadetblue'=>'#5f9ea0','chartreuse'=>'#7fff00',
  8. 'chocolate'=>'#d2691e','coral'=>'#ff7f50','cornflowerblue'=>'#6495ed','cornsilk'=>'#fff8dc','crimson'=>'#dc143c',
  9. 'cyan'=>'#00ffff','darkblue'=>'#00008b','darkcyan'=>'#008b8b','darkgoldenrod'=>'#b8860b','darkgray'=>'#a9a9a9',
  10. 'darkgrey'=>'#a9a9a9','darkgreen'=>'#006400','darkkhaki'=>'#bdb76b','darkmagenta'=>'#8b008b',
  11. 'darkolivegreen'=>'#556b2f','darkorange'=>'#ff8c00','darkorchid'=>'#9932cc','darkred'=>'#8b0000',
  12. 'darksalmon'=>'#e9967a','darkseagreen'=>'#8fbc8f','darkslateblue'=>'#483d8b','darkslategray'=>'#2f4f4f',
  13. 'darkslategrey'=>'#2f4f4f','darkturquoise'=>'#00ced1','darkviolet'=>'#9400d3','deeppink'=>'#ff1493',
  14. 'deepskyblue'=>'#00bfff','dimgray'=>'#696969','dimgrey'=>'#696969','dodgerblue'=>'#1e90ff',
  15. 'firebrick'=>'#b22222','floralwhite'=>'#fffaf0','forestgreen'=>'#228b22','fuchsia'=>'#ff00ff',
  16. 'gainsboro'=>'#dcdcdc','ghostwhite'=>'#f8f8ff','gold'=>'#ffd700','goldenrod'=>'#daa520','gray'=>'#808080',
  17. 'grey'=>'#808080','green'=>'#008000','greenyellow'=>'#adff2f','honeydew'=>'#f0fff0','hotpink'=>'#ff69b4',
  18. 'indianred'=>'#cd5c5c','indigo'=>'#4b0082','ivory'=>'#fffff0','khaki'=>'#f0e68c','lavender'=>'#e6e6fa',
  19. 'lavenderblush'=>'#fff0f5','lawngreen'=>'#7cfc00','lemonchiffon'=>'#fffacd','lightblue'=>'#add8e6',
  20. 'lightcoral'=>'#f08080','lightcyan'=>'#e0ffff','lightgoldenrodyellow'=>'#fafad2','lightgray'=>'#d3d3d3',
  21. 'lightgrey'=>'#d3d3d3','lightgreen'=>'#90ee90','lightpink'=>'#ffb6c1','lightsalmon'=>'#ffa07a',
  22. 'lightseagreen'=>'#20b2aa','lightskyblue'=>'#87cefa','lightslategray'=>'#778899','lightslategrey'=>'#778899',
  23. 'lightsteelblue'=>'#b0c4de','lightyellow'=>'#ffffe0','lime'=>'#00ff00','limegreen'=>'#32cd32','linen'=>'#faf0e6',
  24. 'magenta'=>'#ff00ff','maroon'=>'#800000','mediumaquamarine'=>'#66cdaa','mediumblue'=>'#0000cd',
  25. 'mediumorchid'=>'#ba55d3','mediumpurple'=>'#9370d8','mediumseagreen'=>'#3cb371','mediumslateblue'=>'#7b68ee',
  26. 'mediumspringgreen'=>'#00fa9a','mediumturquoise'=>'#48d1cc','mediumvioletred'=>'#c71585',
  27. 'midnightblue'=>'#191970','mintcream'=>'#f5fffa','mistyrose'=>'#ffe4e1','moccasin'=>'#ffe4b5',
  28. 'navajowhite'=>'#ffdead','navy'=>'#000080','oldlace'=>'#fdf5e6','olive'=>'#808000','olivedrab'=>'#6b8e23',
  29. 'orange'=>'#ffa500','orangered'=>'#ff4500','orchid'=>'#da70d6','palegoldenrod'=>'#eee8aa','palegreen'=>'#98fb98',
  30. 'paleturquoise'=>'#afeeee','palevioletred'=>'#d87093','papayawhip'=>'#ffefd5','peachpuff'=>'#ffdab9',
  31. 'peru'=>'#cd853f','pink'=>'#ffc0cb','plum'=>'#dda0dd','powderblue'=>'#b0e0e6','purple'=>'#800080',
  32. 'red'=>'#ff0000','rosybrown'=>'#bc8f8f','royalblue'=>'#4169e1','saddlebrown'=>'#8b4513','salmon'=>'#fa8072',
  33. 'sandybrown'=>'#f4a460','seagreen'=>'#2e8b57','seashell'=>'#fff5ee','sienna'=>'#a0522d','silver'=>'#c0c0c0',
  34. 'skyblue'=>'#87ceeb','slateblue'=>'#6a5acd','slategray'=>'#708090','slategrey'=>'#708090','snow'=>'#fffafa',
  35. 'springgreen'=>'#00ff7f','steelblue'=>'#4682b4','tan'=>'#d2b48c','teal'=>'#008080','thistle'=>'#d8bfd8',
  36. 'tomato'=>'#ff6347','turquoise'=>'#40e0d0','violet'=>'#ee82ee','wheat'=>'#f5deb3','white'=>'#ffffff',
  37. 'whitesmoke'=>'#f5f5f5','yellow'=>'#ffff00','yellowgreen'=>'#9acd32'
  38. );
  39. protected function _parse( & $variable )
  40. {
  41. if ( !self::_fits( $variable ) ) return false;
  42. $this->type = 'CSS color';
  43. $variants = self::_convert( $variable );
  44. $this->value =
  45. "<div style=\"background:{$variable}\" class=\"kint-color-preview\">{$variable}</div>"
  46. . "<strong>hex :</strong> {$variants['hex']}\n"
  47. . "<strong>rgb :</strong> {$variants['rgb']}\n"
  48. . ( isset( $variants['name'] ) ? "<strong>name:</strong> {$variants['name']}\n" : '' )
  49. . "<strong>hsl :</strong> {$variants['hsl']}";
  50. }
  51. private static function _fits( $variable )
  52. {
  53. if ( !is_string( $variable ) ) return false;
  54. $var = strtolower( trim( $variable ) );
  55. return isset( self::$_css3Named[$var] )
  56. || preg_match(
  57. '/^(?:#[0-9A-Fa-f]{3}|#[0-9A-Fa-f]{6}|(?:rgb|hsl)a?\s*\((?:\s*[0-9.%]+\s*,?){3,4}\))$/',
  58. $var
  59. );
  60. }
  61. private static function _convert( $color )
  62. {
  63. $color = strtolower( $color );
  64. $decimalColors = array();
  65. $variants = array(
  66. 'hex' => null,
  67. 'rgb' => null,
  68. 'name' => null,
  69. 'hsl' => null,
  70. );
  71. if ( isset( self::$_css3Named[ $color ] ) ) {
  72. $variants['name'] = $color;
  73. $color = self::$_css3Named[ $color ];
  74. }
  75. if ( $color{0} === '#' ) {
  76. $variants['hex'] = $color;
  77. $color = substr( $color, 1 );
  78. if ( strlen( $color ) === 6 ) {
  79. $colors = str_split( $color, 2 );
  80. } else {
  81. $colors = array(
  82. $color{0} . $color{0},
  83. $color{1} . $color{1},
  84. $color{2} . $color{2},
  85. );
  86. }
  87. $decimalColors = array_map( 'hexdec', $colors );
  88. } elseif ( substr( $color, 0, 3 ) === 'rgb' ) {
  89. $variants['rgb'] = $color;
  90. preg_match_all( '#([0-9.%]+)#', $color, $matches );
  91. $decimalColors = $matches[1];
  92. foreach ( $decimalColors as &$color ) {
  93. if ( strpos( $color, '%' ) !== false ) {
  94. $color = str_replace( '%', '', $color ) * 2.55;
  95. }
  96. }
  97. } elseif ( substr( $color, 0, 3 ) === 'hsl' ) {
  98. $variants['hsl'] = $color;
  99. preg_match_all( '#([0-9.%]+)#', $color, $matches );
  100. $colors = $matches[1];
  101. $colors[0] /= 360;
  102. $colors[1] = str_replace( '%', '', $colors[1] ) / 100;
  103. $colors[2] = str_replace( '%', '', $colors[2] ) / 100;
  104. $decimalColors = self::_HSLtoRGB( $colors );
  105. if ( isset( $colors[3] ) ) {
  106. $decimalColors[] = $colors[3];
  107. }
  108. }
  109. if ( isset( $decimalColors[3] ) ) {
  110. $alpha = $decimalColors[3];
  111. unset( $decimalColors[3] );
  112. } else {
  113. $alpha = null;
  114. }
  115. foreach ( $variants as $type => &$variant ) {
  116. if ( isset( $variant ) ) continue;
  117. switch ( $type ) {
  118. case 'hex':
  119. $variant = '#';
  120. foreach ( $decimalColors as &$color ) {
  121. $variant .= str_pad( dechex( $color ), 2, "0", STR_PAD_LEFT );
  122. }
  123. $variant .= isset( $alpha ) ? ' (alpha omitted)' : '';
  124. break;
  125. case 'rgb':
  126. $rgb = $decimalColors;
  127. if ( isset( $alpha ) ) {
  128. $rgb[] = $alpha;
  129. $a = 'a';
  130. } else {
  131. $a = '';
  132. }
  133. $variant = "rgb{$a}( " . implode( ', ', $rgb ) . " )";
  134. break;
  135. case 'hsl':
  136. $rgb = self::_RGBtoHSL( $decimalColors );
  137. if ( $rgb === null ) {
  138. unset( $variants[ $type ] );
  139. break;
  140. }
  141. if ( isset( $alpha ) ) {
  142. $rgb[] = $alpha;
  143. $a = 'a';
  144. } else {
  145. $a = '';
  146. }
  147. $variant = "hsl{$a}( " . implode( ', ', $rgb ) . " )";
  148. break;
  149. case 'name':
  150. // [!] name in initial variants array must go after hex
  151. if ( ( $key = array_search( $variants['hex'], self::$_css3Named, true ) ) !== false ) {
  152. $variant = $key;
  153. } else {
  154. unset( $variants[ $type ] );
  155. }
  156. break;
  157. }
  158. }
  159. return $variants;
  160. }
  161. private static function _HSLtoRGB( array $hsl )
  162. {
  163. list( $h, $s, $l ) = $hsl;
  164. $m2 = ( $l <= 0.5 ) ? $l * ( $s + 1 ) : $l + $s - $l * $s;
  165. $m1 = $l * 2 - $m2;
  166. return array(
  167. round( self::_hue2rgb( $m1, $m2, $h + 0.33333 ) * 255 ),
  168. round( self::_hue2rgb( $m1, $m2, $h ) * 255 ),
  169. round( self::_hue2rgb( $m1, $m2, $h - 0.33333 ) * 255 ),
  170. );
  171. }
  172. /**
  173. * Helper function for _color_hsl2rgb().
  174. */
  175. private static function _hue2rgb( $m1, $m2, $h )
  176. {
  177. $h = ( $h < 0 ) ? $h + 1 : ( ( $h > 1 ) ? $h - 1 : $h );
  178. if ( $h * 6 < 1 ) return $m1 + ( $m2 - $m1 ) * $h * 6;
  179. if ( $h * 2 < 1 ) return $m2;
  180. if ( $h * 3 < 2 ) return $m1 + ( $m2 - $m1 ) * ( 0.66666 - $h ) * 6;
  181. return $m1;
  182. }
  183. private static function _RGBtoHSL( array $rgb )
  184. {
  185. list( $clrR, $clrG, $clrB ) = $rgb;
  186. $clrMin = min( $clrR, $clrG, $clrB );
  187. $clrMax = max( $clrR, $clrG, $clrB );
  188. $deltaMax = $clrMax - $clrMin;
  189. $L = ( $clrMax + $clrMin ) / 510;
  190. if ( 0 == $deltaMax ) {
  191. $H = 0;
  192. $S = 0;
  193. } else {
  194. if ( 0.5 > $L ) {
  195. $S = $deltaMax / ( $clrMax + $clrMin );
  196. } else {
  197. $S = $deltaMax / ( 510 - $clrMax - $clrMin );
  198. }
  199. if ( $clrMax == $clrR ) {
  200. $H = ( $clrG - $clrB ) / ( 6.0 * $deltaMax );
  201. } else if ( $clrMax == $clrG ) {
  202. $H = 1 / 3 + ( $clrB - $clrR ) / ( 6.0 * $deltaMax );
  203. } else {
  204. $H = 2 / 3 + ( $clrR - $clrG ) / ( 6.0 * $deltaMax );
  205. }
  206. if ( 0 > $H ) $H += 1;
  207. if ( 1 < $H ) $H -= 1;
  208. }
  209. return array(
  210. round( $H * 360 ),
  211. round( $S * 100 ) . '%',
  212. round( $L * 100 ) . '%'
  213. );
  214. }
  215. }
  216. /* *************
  217. * TEST DATA
  218. *
  219. dd(array(
  220. 'hsl(0, 100%,50%)',
  221. 'hsl(30, 100%,50%)',
  222. 'hsl(60, 100%,50%)',
  223. 'hsl(90, 100%,50%)',
  224. 'hsl(120,100%,50%)',
  225. 'hsl(150,100%,50%)',
  226. 'hsl(180,100%,50%)',
  227. 'hsl(210,100%,50%)',
  228. 'hsl(240,100%,50%)',
  229. 'hsl(270,100%,50%)',
  230. 'hsl(300,100%,50%)',
  231. 'hsl(330,100%,50%)',
  232. 'hsl(360,100%,50%)',
  233. 'hsl(120,100%,25%)',
  234. 'hsl(120,100%,50%)',
  235. 'hsl(120,100%,75%)',
  236. 'hsl(120,100%,50%)',
  237. 'hsl(120, 67%,50%)',
  238. 'hsl(120, 33%,50%)',
  239. 'hsl(120, 0%,50%)',
  240. 'hsl(120, 60%,70%)',
  241. '#f03',
  242. '#F03',
  243. '#ff0033',
  244. '#FF0033',
  245. 'rgb(255,0,51)',
  246. 'rgb(255, 0, 51)',
  247. 'rgb(100%,0%,20%)',
  248. 'rgb(100%, 0%, 20%)',
  249. 'hsla(240,100%,50%,0.05)',
  250. 'hsla(240,100%,50%, 0.4)',
  251. 'hsla(240,100%,50%, 0.7)',
  252. 'hsla(240,100%,50%, 1)',
  253. 'rgba(255,0,0,0.1)',
  254. 'rgba(255,0,0,0.4)',
  255. 'rgba(255,0,0,0.7)',
  256. 'rgba(255,0,0, 1)',
  257. 'black',
  258. 'silver',
  259. 'gray',
  260. 'white',
  261. 'maroon',
  262. 'red',
  263. 'purple',
  264. 'fuchsia',
  265. 'green',
  266. 'lime',
  267. 'olive',
  268. 'yellow',
  269. 'navy',
  270. 'blue',
  271. 'teal',
  272. 'aqua',
  273. 'orange',
  274. 'aliceblue',
  275. 'antiquewhite',
  276. 'aquamarine',
  277. 'azure',
  278. 'beige',
  279. 'bisque',
  280. 'blanchedalmond',
  281. 'blueviolet',
  282. 'brown',
  283. 'burlywood',
  284. 'cadetblue',
  285. 'chartreuse',
  286. 'chocolate',
  287. 'coral',
  288. 'cornflowerblue',
  289. 'cornsilk',
  290. 'crimson',
  291. 'darkblue',
  292. 'darkcyan',
  293. 'darkgoldenrod',
  294. 'darkgray',
  295. 'darkgreen',
  296. 'darkgrey',
  297. 'darkkhaki',
  298. 'darkmagenta',
  299. 'darkolivegreen',
  300. 'darkorange',
  301. 'darkorchid',
  302. 'darkred',
  303. 'darksalmon',
  304. 'darkseagreen',
  305. 'darkslateblue',
  306. 'darkslategray',
  307. 'darkslategrey',
  308. 'darkturquoise',
  309. 'darkviolet',
  310. 'deeppink',
  311. 'deepskyblue',
  312. 'dimgray',
  313. 'dimgrey',
  314. 'dodgerblue',
  315. 'firebrick',
  316. 'floralwhite',
  317. 'forestgreen',
  318. 'gainsboro',
  319. 'ghostwhite',
  320. 'gold',
  321. 'goldenrod',
  322. 'greenyellow',
  323. 'grey',
  324. 'honeydew',
  325. 'hotpink',
  326. 'indianred',
  327. 'indigo',
  328. 'ivory',
  329. 'khaki',
  330. 'lavender',
  331. 'lavenderblush',
  332. 'lawngreen',
  333. 'lemonchiffon',
  334. 'lightblue',
  335. 'lightcoral',
  336. 'lightcyan',
  337. 'lightgoldenrodyellow',
  338. 'lightgray',
  339. 'lightgreen',
  340. 'lightgrey',
  341. 'lightpink',
  342. 'lightsalmon',
  343. 'lightseagreen',
  344. 'lightskyblue',
  345. 'lightslategray',
  346. 'lightslategrey',
  347. 'lightsteelblue',
  348. 'lightyellow',
  349. 'limegreen',
  350. 'linen',
  351. 'mediumaquamarine',
  352. 'mediumblue',
  353. 'mediumorchid',
  354. 'mediumpurple',
  355. 'mediumseagreen',
  356. 'mediumslateblue',
  357. 'mediumspringgreen',
  358. 'mediumturquoise',
  359. 'mediumvioletred',
  360. 'midnightblue',
  361. 'mintcream',
  362. 'mistyrose',
  363. 'moccasin',
  364. 'navajowhite',
  365. 'oldlace',
  366. 'olivedrab',
  367. ));*/