summaryrefslogtreecommitdiffstats
path: root/vendor/wikimedia/less.php/lib/Less/Tree/Color.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/wikimedia/less.php/lib/Less/Tree/Color.php')
-rw-r--r--vendor/wikimedia/less.php/lib/Less/Tree/Color.php228
1 files changed, 228 insertions, 0 deletions
diff --git a/vendor/wikimedia/less.php/lib/Less/Tree/Color.php b/vendor/wikimedia/less.php/lib/Less/Tree/Color.php
new file mode 100644
index 0000000..427f47d
--- /dev/null
+++ b/vendor/wikimedia/less.php/lib/Less/Tree/Color.php
@@ -0,0 +1,228 @@
+<?php
+/**
+ * @private
+ */
+class Less_Tree_Color extends Less_Tree {
+ public $rgb;
+ public $alpha;
+ public $isTransparentKeyword;
+ public $type = 'Color';
+
+ public function __construct( $rgb, $a = 1, $isTransparentKeyword = null ) {
+ if ( $isTransparentKeyword ) {
+ $this->rgb = $rgb;
+ $this->alpha = $a;
+ $this->isTransparentKeyword = true;
+ return;
+ }
+
+ $this->rgb = [];
+ if ( is_array( $rgb ) ) {
+ $this->rgb = $rgb;
+ } elseif ( strlen( $rgb ) == 6 ) {
+ foreach ( str_split( $rgb, 2 ) as $c ) {
+ $this->rgb[] = hexdec( $c );
+ }
+ } else {
+ foreach ( str_split( $rgb, 1 ) as $c ) {
+ $this->rgb[] = hexdec( $c . $c );
+ }
+ }
+ $this->alpha = is_numeric( $a ) ? $a : 1;
+ }
+
+ public function luma() {
+ $r = $this->rgb[0] / 255;
+ $g = $this->rgb[1] / 255;
+ $b = $this->rgb[2] / 255;
+
+ $r = ( $r <= 0.03928 ) ? $r / 12.92 : pow( ( ( $r + 0.055 ) / 1.055 ), 2.4 );
+ $g = ( $g <= 0.03928 ) ? $g / 12.92 : pow( ( ( $g + 0.055 ) / 1.055 ), 2.4 );
+ $b = ( $b <= 0.03928 ) ? $b / 12.92 : pow( ( ( $b + 0.055 ) / 1.055 ), 2.4 );
+
+ return 0.2126 * $r + 0.7152 * $g + 0.0722 * $b;
+ }
+
+ /**
+ * @see Less_Tree::genCSS
+ */
+ public function genCSS( $output ) {
+ $output->add( $this->toCSS() );
+ }
+
+ public function toCSS( $doNotCompress = false ) {
+ $compress = Less_Parser::$options['compress'] && !$doNotCompress;
+ $alpha = Less_Functions::fround( $this->alpha );
+
+ //
+ // If we have some transparency, the only way to represent it
+ // is via `rgba`. Otherwise, we use the hex representation,
+ // which has better compatibility with older browsers.
+ // Values are capped between `0` and `255`, rounded and zero-padded.
+ //
+ if ( $alpha < 1 ) {
+ if ( ( $alpha === 0 || $alpha === 0.0 ) && isset( $this->isTransparentKeyword ) && $this->isTransparentKeyword ) {
+ return 'transparent';
+ }
+
+ $values = [];
+ foreach ( $this->rgb as $c ) {
+ $values[] = Less_Functions::clamp( round( $c ), 255 );
+ }
+ $values[] = $alpha;
+
+ $glue = ( $compress ? ',' : ', ' );
+ return "rgba(" . implode( $glue, $values ) . ")";
+ } else {
+
+ $color = $this->toRGB();
+
+ if ( $compress ) {
+
+ // Convert color to short format
+ if ( $color[1] === $color[2] && $color[3] === $color[4] && $color[5] === $color[6] ) {
+ $color = '#' . $color[1] . $color[3] . $color[5];
+ }
+ }
+
+ return $color;
+ }
+ }
+
+ //
+ // Operations have to be done per-channel, if not,
+ // channels will spill onto each other. Once we have
+ // our result, in the form of an integer triplet,
+ // we create a new Color node to hold the result.
+ //
+
+ /**
+ * @param string $op
+ */
+ public function operate( $op, $other ) {
+ $rgb = [];
+ $alpha = $this->alpha * ( 1 - $other->alpha ) + $other->alpha;
+ for ( $c = 0; $c < 3; $c++ ) {
+ $rgb[$c] = Less_Functions::operate( $op, $this->rgb[$c], $other->rgb[$c] );
+ }
+ return new Less_Tree_Color( $rgb, $alpha );
+ }
+
+ public function toRGB() {
+ return $this->toHex( $this->rgb );
+ }
+
+ public function toHSL() {
+ $r = $this->rgb[0] / 255;
+ $g = $this->rgb[1] / 255;
+ $b = $this->rgb[2] / 255;
+ $a = $this->alpha;
+
+ $max = max( $r, $g, $b );
+ $min = min( $r, $g, $b );
+ $l = ( $max + $min ) / 2;
+ $d = $max - $min;
+
+ $h = $s = 0;
+ if ( $max !== $min ) {
+ $s = $l > 0.5 ? $d / ( 2 - $max - $min ) : $d / ( $max + $min );
+
+ switch ( $max ) {
+ case $r:
+ $h = ( $g - $b ) / $d + ( $g < $b ? 6 : 0 );
+ break;
+ case $g:
+ $h = ( $b - $r ) / $d + 2;
+ break;
+ case $b:
+ $h = ( $r - $g ) / $d + 4;
+ break;
+ }
+ $h /= 6;
+ }
+ return [ 'h' => $h * 360, 's' => $s, 'l' => $l, 'a' => $a ];
+ }
+
+ // Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
+ public function toHSV() {
+ $r = $this->rgb[0] / 255;
+ $g = $this->rgb[1] / 255;
+ $b = $this->rgb[2] / 255;
+ $a = $this->alpha;
+
+ $max = max( $r, $g, $b );
+ $min = min( $r, $g, $b );
+
+ $v = $max;
+
+ $d = $max - $min;
+ if ( $max === 0 ) {
+ $s = 0;
+ } else {
+ $s = $d / $max;
+ }
+
+ $h = 0;
+ if ( $max !== $min ) {
+ switch ( $max ) {
+ case $r:
+ $h = ( $g - $b ) / $d + ( $g < $b ? 6 : 0 );
+ break;
+ case $g:
+ $h = ( $b - $r ) / $d + 2;
+ break;
+ case $b:
+ $h = ( $r - $g ) / $d + 4;
+ break;
+ }
+ $h /= 6;
+ }
+ return [ 'h' => $h * 360, 's' => $s, 'v' => $v, 'a' => $a ];
+ }
+
+ public function toARGB() {
+ $argb = array_merge( (array)Less_Parser::round( $this->alpha * 255 ), $this->rgb );
+ return $this->toHex( $argb );
+ }
+
+ public function compare( $x ) {
+ if ( !property_exists( $x, 'rgb' ) ) {
+ return -1;
+ }
+
+ return ( $x->rgb[0] === $this->rgb[0] &&
+ $x->rgb[1] === $this->rgb[1] &&
+ $x->rgb[2] === $this->rgb[2] &&
+ $x->alpha === $this->alpha ) ? 0 : -1;
+ }
+
+ public function toHex( $v ) {
+ $ret = '#';
+ foreach ( $v as $c ) {
+ $c = Less_Functions::clamp( Less_Parser::round( $c ), 255 );
+ if ( $c < 16 ) {
+ $ret .= '0';
+ }
+ $ret .= dechex( $c );
+ }
+
+ return $ret;
+ }
+
+ /**
+ * @param string $keyword
+ */
+ public static function fromKeyword( $keyword ) {
+ $keyword = strtolower( $keyword );
+
+ if ( Less_Colors::hasOwnProperty( $keyword ) ) {
+ // detect named color
+ return new Less_Tree_Color( substr( Less_Colors::color( $keyword ), 1 ) );
+ }
+
+ if ( $keyword === 'transparent' ) {
+ return new Less_Tree_Color( [ 0, 0, 0 ], 0, true );
+ }
+ }
+
+}