diff options
Diffstat (limited to 'vendor/wikimedia/less.php/lib/Less/Tree/Color.php')
-rw-r--r-- | vendor/wikimedia/less.php/lib/Less/Tree/Color.php | 228 |
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 ); + } + } + +} |