Source of file SassColour.php
Size: 31,130 Bytes - Last Modified: 2021-12-23T10:32:55+00:00
/var/www/docs.ssmods.com/process/src/code/phpsass/script/literals/SassColour.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916 | <?php /* SVN FILE: $Id$ */ /** * SassColour class file. * @author Chris Yates <chris.l.yates@gmail.com> * @copyright Copyright (c) 2010 PBM Web Development * @license http://phamlp.googlecode.com/files/license.txt * @package PHamlP * @subpackage Sass.script.literals */ require_once('SassLiteral.php'); /** * SassColour class. * A SassScript object representing a CSS colour. * * A colour may be represented internally as RGBA, HSLA, or both. It is * originally represented as whatever its input is; if it’s created with RGB * values, it’s represented as RGBA, and if it’s created with HSL values, it’s * represented as HSLA. Once a property is accessed that requires the other * representation – for example, SassColour::red for an HSL color – that * component is calculated and cached. * * The alpha channel of a color is independent of its RGB or HSL representation. * It’s always stored, as 1 if nothing else is specified. If only the alpha * channel is modified using SassColour::with(), the cached RGB and HSL values * are retained. * * Colour operations are all piecewise, e.g. when adding two colours each * component is added independantly; Rr = R1 + R2, Gr = G1 + G2, Br = B1 + B2. * * Colours are returned as a named colour if possible or #rrggbb. * * @package PHamlP * @subpackage Sass.script.literals */ class SassColour extends SassLiteral { /**@#+ * Regexes for matching and extracting colours */ const MATCH = '/^((#([\da-f]{6}|[\da-f]{3}))|transparent|{CSS_COLOURS})/'; const EXTRACT_3 = '/#([\da-f])([\da-f])([\da-f])/'; const EXTRACT_6 = '/#([\da-f]{2})([\da-f]{2})([\da-f]{2})/'; const TRANSPARENT = 'transparent'; /**@#-*/ /**@#-*/ static public $svgColours = array( 'aliceblue' => '#f0f8ff', 'antiquewhite' => '#faebd7', 'aqua' => '#00ffff', 'aquamarine' => '#7fffd4', 'azure' => '#f0ffff', 'beige' => '#f5f5dc', 'bisque' => '#ffe4c4', 'black' => '#000000', 'blanchedalmond' => '#ffebcd', 'blue' => '#0000ff', 'blueviolet' => '#8a2be2', 'brown' => '#a52a2a', 'burlywood' => '#deb887', 'cadetblue' => '#5f9ea0', 'chartreuse' => '#7fff00', 'chocolate' => '#d2691e', 'coral' => '#ff7f50', 'cornflowerblue' => '#6495ed', 'cornsilk' => '#fff8dc', 'crimson' => '#dc143c', 'cyan' => '#00ffff', 'darkblue' => '#00008b', 'darkcyan' => '#008b8b', 'darkgoldenrod' => '#b8860b', 'darkgreen' => '#006400', 'darkkhaki' => '#bdb76b', 'darkmagenta' => '#8b008b', 'darkolivegreen' => '#556b2f', 'darkorange' => '#ff8c00', 'darkorchid' => '#9932cc', 'darkred' => '#8b0000', 'darksalmon' => '#e9967a', 'darkseagreen' => '#8fbc8f', 'darkslateblue' => '#483d8b', 'darkslategray' => '#2f4f4f', 'darkslategrey' => '#2f4f4f', 'darkturquoise' => '#00ced1', 'darkviolet' => '#9400d3', 'deeppink' => '#ff1493', 'deepskyblue' => '#00bfff', 'dimgray' => '#696969', 'dimgrey' => '#696969', 'dodgerblue' => '#1e90ff', 'firebrick' => '#b22222', 'floralwhite' => '#fffaf0', 'forestgreen' => '#228b22', 'fuchsia' => '#ff00ff', 'gainsboro' => '#dcdcdc', 'ghostwhite' => '#f8f8ff', 'gold' => '#ffd700', 'goldenrod' => '#daa520', 'gray' => '#808080', 'green' => '#008000', 'greenyellow' => '#adff2f', 'grey' => '#808080', 'honeydew' => '#f0fff0', 'hotpink' => '#ff69b4', 'indianred' => '#cd5c5c', 'indigo' => '#4b0082', 'ivory' => '#fffff0', 'khaki' => '#f0e68c', 'lavender' => '#e6e6fa', 'lavenderblush' => '#fff0f5', 'lawngreen' => '#7cfc00', 'lemonchiffon' => '#fffacd', 'lightblue' => '#add8e6', 'lightcoral' => '#f08080', 'lightcyan' => '#e0ffff', 'lightgoldenrodyellow' => '#fafad2', 'lightgray' => '#d3d3d3', 'lightgreen' => '#90ee90', 'lightgrey' => '#d3d3d3', 'lightpink' => '#ffb6c1', 'lightsalmon' => '#ffa07a', 'lightseagreen' => '#20b2aa', 'lightskyblue' => '#87cefa', 'lightslategray' => '#778899', 'lightslategrey' => '#778899', 'lightsteelblue' => '#b0c4de', 'lightyellow' => '#ffffe0', 'lime' => '#00ff00', 'limegreen' => '#32cd32', 'linen' => '#faf0e6', 'magenta' => '#ff00ff', 'maroon' => '#800000', 'mediumaquamarine' => '#66cdaa', 'mediumblue' => '#0000cd', 'mediumorchid' => '#ba55d3', 'mediumpurple' => '#9370db', 'mediumseagreen' => '#3cb371', 'mediumslateblue' => '#7b68ee', 'mediumspringgreen' => '#00fa9a', 'mediumturquoise' => '#48d1cc', 'mediumvioletred' => '#c71585', 'midnightblue' => '#191970', 'mintcream' => '#f5fffa', 'mistyrose' => '#ffe4e1', 'moccasin' => '#ffe4b5', 'navajowhite' => '#ffdead', 'navy' => '#000080', 'oldlace' => '#fdf5e6', 'olive' => '#808000', 'olivedrab' => '#6b8e23', 'orange' => '#ffa500', 'orangered' => '#ff4500', 'orchid' => '#da70d6', 'palegoldenrod' => '#eee8aa', 'palegreen' => '#98fb98', 'paleturquoise' => '#afeeee', 'palevioletred' => '#db7093', 'papayawhip' => '#ffefd5', 'peachpuff' => '#ffdab9', 'peru' => '#cd853f', 'pink' => '#ffc0cb', 'plum' => '#dda0dd', 'powderblue' => '#b0e0e6', 'purple' => '#800080', 'red' => '#ff0000', 'rosybrown' => '#bc8f8f', 'royalblue' => '#4169e1', 'saddlebrown' => '#8b4513', 'salmon' => '#fa8072', 'sandybrown' => '#f4a460', 'seagreen' => '#2e8b57', 'seashell' => '#fff5ee', 'sienna' => '#a0522d', 'silver' => '#c0c0c0', 'skyblue' => '#87ceeb', 'slateblue' => '#6a5acd', 'slategray' => '#708090', 'slategrey' => '#708090', 'snow' => '#fffafa', 'springgreen' => '#00ff7f', 'steelblue' => '#4682b4', 'tan' => '#d2b48c', 'teal' => '#008080', 'thistle' => '#d8bfd8', 'tomato' => '#ff6347', 'turquoise' => '#40e0d0', 'violet' => '#ee82ee', 'wheat' => '#f5deb3', 'white' => '#ffffff', 'whitesmoke' => '#f5f5f5', 'yellow' => '#ffff00', 'yellowgreen' => '#9acd32' ); /** * @var array reverse array (value => name) of named SVG1.0 colours */ static public $_svgColours; /** * @var array reverse array (value => name) of named HTML4 colours */ static public $_html4Colours = array( '#000000' => 'black', '#000080' => 'navy', '#0000ff' => 'blue', '#008000' => 'green', '#008080' => 'teal', '#00ff00' => 'lime', '#00ffff' => 'aqua', '#800000' => 'maroon', '#800080' => 'purple', '#808000' => 'olive', '#808080' => 'gray', '#c0c0c0' => 'silver', '#ff0000' => 'red', '#ff00ff' => 'fuchsia', '#ffff00' => 'yellow', '#ffffff' => 'white', ); static public $regex; /**@#+ * RGB colour components */ /** * @var array RGB colour components. Used to check for RGB attributes. */ static public $rgb = array('red', 'green', 'blue'); /** * @var integer red component. 0 - 255 */ public $red; /** * @var integer green component. 0 - 255 */ public $green; /** * @var integer blue component. 0 - 255 */ public $blue; /**@#-*/ /**@#+ * HSL colour components */ /** * @var array HSL colour components. Used to check for HSL attributes. */ static public $hsl = array('hue', 'saturation', 'lightness'); /** * @var float hue component. 0 - 360 */ public $hue; /** * @var float saturation component. 0 - 100 */ public $saturation; /** * @var float lightness component. 0 - 100 */ public $lightness; /**@#-*/ /** * @var float alpha component. 0 - 1 */ public $alpha = 1; /** * Constructs an RGB or HSL color object, optionally with an alpha channel. * RGB values must be between 0 and 255. Saturation and lightness values must * be between 0 and 100. The alpha value must be between 0 and 1. * The colour can be specified as: * + a string that is an SVG colour or of the form #rgb or #rrggbb * + an array with either 'red', 'green', and 'blue' keys, and optionally * an alpha key. * + an array with 'hue', 'saturation', and 'lightness' keys, and optionally * an alpha key. * + an array of red, green, and blue values, and optionally an alpha value. * @param mixed the colour * @return SassColour */ public function __construct($colour) { if (is_string($colour)) { $colour = strtolower($colour); if ($colour === self::TRANSPARENT) { $this->red = 0; $this->green = 0; $this->blue = 0; $this->alpha = 0; } else { if (array_key_exists($colour, self::$svgColours)) { $colour = self::$svgColours[$colour]; } if (strlen($colour) == 4) { preg_match(self::EXTRACT_3, $colour, $matches); for ($i = 1; $i < 4; $i++) { $matches[$i] = str_repeat($matches[$i], 2); } } else { preg_match(self::EXTRACT_6, $colour, $matches); } if (empty($matches)) { throw new SassColourException('Invalid SassColour string', SassScriptParser::$context->node); } $this->red = intval($matches[1], 16); $this->green = intval($matches[2], 16); $this->blue = intval($matches[3], 16); $this->alpha = 1; } } elseif (is_array($colour)) { $scheme = $this->assertValid($colour); if ($scheme == 'rgb') { $this->red = $colour['red']; $this->green = $colour['green']; $this->blue = $colour['blue']; $this->alpha = (isset($colour['alpha']) ? $colour['alpha'] : 1); } elseif ($scheme == 'hsl') { $this->hue = $colour['hue']; $this->saturation = $colour['saturation']; $this->lightness = $colour['lightness']; $this->alpha = (isset($colour['alpha']) ? $colour['alpha'] : 1); } else { $this->red = $colour[0]; $this->green = $colour[1]; $this->blue = $colour[2]; $this->alpha = (isset($colour[3]) ? $colour[3] : 1); } } else { throw new SassColourException('Colour must be a array', SassScriptParser::$context->node); } } /** * Colour addition * @param mixed SassColour|SassNumber value to add * @return sassColour the colour result */ public function op_plus($other) { if ($other instanceof SassNumber) { if (!$other->isUnitless()) { return new SassString($this->toString() . $other->value); throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node); } $this->red = $this->getRed() + $other->value; $this->green = $this->getGreen() + $other->value; $this->blue = $this->getBlue() + $other->value; } elseif (!$other instanceof SassColour) { return new SassString($this->toString() . $other->value); throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node); } else { $this->red = $this->getRed() + $other->getRed(); $this->green = $this->getGreen() + $other->getGreen(); $this->blue = $this->getBlue() + $other->getBlue(); } return $this; } /** * Colour subraction * @param mixed value (SassColour or SassNumber) to subtract * @return sassColour the colour result */ public function op_minus($other) { if ($other instanceof SassNumber) { if (!$other->isUnitless()) { throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node); } $this->red = $this->getRed() - $other->value; $this->green = $this->getGreen() - $other->value; $this->blue = $this->getBlue() - $other->value; } elseif (!$other instanceof SassColour) { throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node); } else { $this->red = $this->getRed() - $other->getRed(); $this->green = $this->getGreen() - $other->getGreen(); $this->blue = $this->getBlue() - $other->getBlue(); } return $this; } /** * Colour multiplication * @param mixed SassColour|SassNumber value to multiply by * @return sassColour the colour result */ public function op_times($other) { if ($other instanceof SassNumber) { if (!$other->isUnitless()) { throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node); } $this->red = $this->getRed() * $other->value; $this->green = $this->getGreen() * $other->value; $this->blue = $this->getBlue() * $other->value; } elseif (!$other instanceof SassColour) { throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node); } else { $this->red = $this->getRed() * $other->getRed(); $this->green = $this->getGreen() * $other->getGreen(); $this->blue = $this->getBlue() * $other->getBlue(); } return $this; } /** * Colour division * @param mixed value (SassColour or SassNumber) to divide by * @return sassColour the colour result */ public function op_div($other) { if ($other instanceof SassNumber) { if (!$other->isUnitless()) { throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node); } $this->red = $this->getRed() / $other->value; $this->green = $this->getGreen() / $other->value; $this->blue = $this->getBlue() / $other->value; } elseif (!$other instanceof SassColour) { throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node); } else { $this->red = $this->getRed() / $other->getRed(); $this->green = $this->getGreen() / $other->getGreen(); $this->blue = $this->getBlue() / $other->getBlue(); } return $this; } /** * Colour modulus * @param mixed value (SassColour or SassNumber) to divide by * @return sassColour the colour result */ public function op_modulo($other) { if ($other instanceof SassNumber) { if (!$other->isUnitless()) { throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node); } $this->red = fmod($this->getRed(), $other->value); $this->green = fmod($this->getGreen(), $other->value); $this->blue = fmod($this->getBlue(), $other->value); } elseif (!$other instanceof SassColour) { throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node); } else { $this->red = fmod($this->getRed(), $other->getRed()); $this->green = fmod($this->getGreen(), $other->getGreen()); $this->blue = fmod($this->getBlue(), $other->getBlue()); } return $this; } /** * Colour bitwise AND * @param mixed value (SassColour or SassNumber) to bitwise AND with * @return sassColour the colour result */ public function op_bw_and($other) { if ($other instanceof SassNumber) { if (!$other->isUnitless()) { throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node); } $this->red = $this->getRed() & $other->value; $this->green = $this->getGreen() & $other->value; $this->blue = $this->getBlue() & $other->value; } elseif (!$other instanceof SassColour) { throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node); } else { $this->red = $this->getRed() & $other->getRed(); $this->green = $this->getGreen() & $other->getGreen(); $this->blue = $this->getBlue() & $other->getBlue(); } return $this; } /** * Colour bitwise OR * @param mixed value (SassColour or SassNumber) to bitwise OR with * @return sassColour the colour result */ public function op_bw_or($other) { if ($other instanceof SassNumber) { if (!$other->isUnitless()) { throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node); } $this->red = $this->getRed() | $other->value; $this->green = $this->getGreen() | $other->value; $this->blue = $this->getBlue() | $other->value; } elseif (!$other instanceof SassColour) { throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node); } else { $this->red = $this->getRed() | $other->getRed(); $this->green = $this->getGreen() | $other->getGreen(); $this->blue = $this->getBlue() | $other->getBlue(); } return $this; } /** * Colour bitwise XOR * @param mixed value (SassColour or SassNumber) to bitwise XOR with * @return sassColour the colour result */ public function op_bw_xor($other) { if ($other instanceof SassNumber) { if (!$other->isUnitless()) { throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node); } $this->red = $this->getRed() ^ $other->value; $this->green = $this->getGreen() ^ $other->value; $this->blue = $this->getBlue() ^ $other->value; } elseif (!$other instanceof SassColour) { throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node); } else { $this->red = $this->getRed() ^ $other->getRed(); $this->green = $this->getGreen() ^ $other->getGreen(); $this->blue = $this->getBlue() ^ $other->getBlue(); } return $this; } /** * Colour bitwise NOT * @return sassColour the colour result */ public function op_not() { $this->red = ~$this->getRed(); $this->green = ~$this->getGreen(); $this->blue = ~$this->getBlue(); return $this; } /** * Colour bitwise Shift Left * @param sassNumber amount to shift left by * @return sassColour the colour result */ public function op_shiftl($other) { if (!$other instanceof SassNumber ||!$other->isUnitless()) { throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node); } $this->red = $this->getRed() << $other->value; $this->green = $this->getGreen() << $other->value; $this->blue = $this->getBlue() << $other->value; return $this; } /** * Colour bitwise Shift Right * @param sassNumber amount to shift right by * @return sassColour the colour result */ public function op_shiftr($other) { if (!$other instanceof SassNumber || !$other->isUnitless()) { throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node); } $this->red = $this->getRed() >> $other->value; $this->green = $this->getGreen() >> $other->value; $this->blue = $this->getBlue() >> $other->value; return $this; } /** * Returns a copy of this colour with one or more channels changed. * RGB or HSL attributes may be changed, but not both at once. * @param array attributes to change */ public function with($attributes) { if ($this->assertValid($attributes, false) === 'hsl') { $colour = array_merge(array( 'hue' => $this->getHue(), 'saturation' => $this->getSaturation(), 'lightness' => $this->getLightness(), 'alpha' => $this->alpha ), $attributes); } else { $colour = array_merge(array( 'red' => $this->getRed(), 'green' => $this->getGreen(), 'blue' => $this->getBlue(), 'alpha' => $this->alpha ), $attributes); } $colour = new SassColour($colour); $colour->getRed(); # will get RGB and HSL return $colour; } /** * Returns the alpha component (opacity) of this colour. * @return float the alpha component (opacity) of this colour. */ public function getAlpha($value = false) { if ($value && isset($this->alpha->$value)) { return $this->alpha->value; } return $this->alpha; } /** * Returns the hue of this colour. * @return float the hue of this colour. */ public function getHue($value = false) { if (is_null($this->hue)) { $this->rgb2hsl(); } if ($value && isset($this->hue->value)) { return $this->hue->value; } return $this->hue; } /** * Returns the saturation of this colour. * @return float the saturation of this colour. */ public function getSaturation($value = false) { if (is_null($this->saturation)) { $this->rgb2hsl(); } if ($value && isset($this->saturation->value)) { return $this->saturation->value; } return $this->saturation; } /** * Returns the lightness of this colour. * @return float the lightness of this colour. */ public function getLightness($value = false) { if (is_null($this->lightness)) { $this->rgb2hsl(); } if ($value && isset($this->lightness->value)) { return $this->lightness->value; } return $this->lightness; } /** * Returns the blue component of this colour. * @return integer the blue component of this colour. */ public function getBlue($value = false) { if (is_null($this->blue)) { $this->hsl2rgb(); } if ($value && isset($this->blue->value)) { return $this->blue->value; } return max(0, min(255, round($this->blue))); } /** * Returns the green component of this colour. * @return integer the green component of this colour. */ public function getGreen($value = false) { if (is_null($this->green)) { $this->hsl2rgb(); } if ($value && isset($this->green->value)) { return $this->green->value; } return max(0, min(255, round($this->green))); } /** * Returns the red component of this colour. * @return integer the red component of this colour. */ public function getRed($value = false) { if (is_null($this->red)) { $this->hsl2rgb(); } if ($value && isset($this->red->value)) { return $this->red->value; } return max(0, min(255, round($this->red))); } /** * Returns an array with the RGB components of this colour. * @return array the RGB components of this colour */ public function getRgb() { return array($this->red, $this->green, $this->blue); } /** * Returns an array with the RGB and alpha components of this colour. * @return array the RGB and alpha components of this colour */ public function getRgba() { return array($this->getRed(), $this->getGreen(), $this->getBlue(), $this->alpha); } /** * Returns an array with the HSL components of this colour. * @return array the HSL components of this colour */ public function getHsl() { return array($this->getHue(), $this->getSaturation(), $this->getLightness()); } /** * Returns an array with the HSL and alpha components of this colour. * @return array the HSL and alpha components of this colour */ public function getHsla() { return array($this->getHue(), $this->getSaturation(), $this->getLightness(), $this->alpha); } /** * Returns the value of this colour. * @return array the colour * @deprecated */ public function getValue() { return $this->rgb; } /** * Returns whether this colour object is translucent; that is, whether the alpha channel is non-1. * @return boolean true if this colour is translucent, false if not */ public function isTranslucent() { return $this->alpha < 1; } /** * Converts the colour to a string. * @param boolean whether to use CSS3 SVG1.0 colour names * @return string the colour as a named colour, rgba(r,g,g,a) or #rrggbb */ public function toString($css3 = true) { $rgba = $this->getRgba(); foreach ($rgba as $k => $v) { if (is_object($v)) { $rgba[$k] = $v->value; } } if ($rgba[3] == 0) { return 'transparent'; } elseif ($rgba[3] < 1) { $rgba[3] = round($rgba[3], 2); return sprintf('rgba(%d, %d, %d, %s)', $rgba[0], $rgba[1], $rgba[2], $rgba[3]); } else { $colour = sprintf('#%02x%02x%02x', round($rgba[0]), round($rgba[1]), round($rgba[2])); } if ($css3) { if (empty(self::$_svgColours)) { self::$_svgColours = array_flip(self::$svgColours); } return (array_key_exists($colour, self::$_svgColours) ? self::$_svgColours[$colour] : $colour); } else { return (array_key_exists($colour, self::$_html4Colours) ? self::$_html4Colours[$colour] : $colour); } } public function asHex($inc_hash = TRUE) { return sprintf(($inc_hash ? '#' : '') . '%02x%02x%02x', round($this->red), round($this->green), round($this->blue)); } /** * Converts from HSL to RGB colourspace * Algorithm from the CSS3 spec: {@link http://www.w3.org/TR/css3-color/#hsl-color} * @uses hue2rgb() */ public function hsl2rgb() { $h = $this->getHue(true) / 360; $s = $this->getSaturation(true) / 100; $l = $this->getLightness(true) / 100; $q = $l < 0.5 ? $l * (1 + $s) : $l + $s - $l * $s; $p = 2 * $l - $q; $this->red = $this->hue2rgb($p, $q, $h + 1/3); $this->green = $this->hue2rgb($p, $q, $h); $this->blue = $this->hue2rgb($p, $q, $h - 1/3); } /** * Converts from hue to RGB colourspace */ public function hue2rgb($p, $q, $t) { if ($t < 0) $t += 1; if ($t > 1) $t -= 1; if ($t < 1/6) $p = $p + ($q - $p) * 6 * $t; else if ($t < 1/2) $p = $q; else if ($t < 2/3) $p = $p + ($q - $p) * (2/3 - $t) * 6; return round($p * 255); } /** * Converts from RGB to HSL colourspace * Algorithm adapted from {@link http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript} */ public function rgb2hsl() { list($r, $g, $b) = array($this->red / 255, $this->green / 255, $this->blue / 255); $max = max($r, $g, $b); $min = min($r, $g, $b); $d = $max - $min; if ($max == $min) { $h = 0; $s = 0; } else if ($max == $r) $h = 60 * ($g - $b) / $d; else if ($max == $g) $h = 60 * ($b - $r) / $d + 120; else if ($max == $b) $h = 60 * ($r - $g) / $d + 240; $l = ($max + $min) / 2; $s = $l > 0.5 ? $d / (2 - $max - $min) : $d / ($max + $min); while ($h > 360) $h -= 360; while ($h < 0) $h += 360; $this->hue = $h; $this->saturation = $s * 100; $this->lightness = $l * 100; } /** * Asserts that the colour space is valid. * Returns the name of the colour space: 'rgb' if red, green, or blue keys given; * 'hsl' if hue, saturation or lightness keys given; null if a non-associative array * @param array the colour to test * @param boolean whether all colour space keys must be given * @return string name of the colour space * @throws SassColourException if mixed colour space keys given or not all * keys for a colour space are required but not given (contructor) */ public function assertValid($colour, $all = true) { if (array_key_exists('red', $colour) || array_key_exists('green', $colour) || array_key_exists('blue', $colour)) { if (array_key_exists('hue', $colour) || array_key_exists('saturation', $colour) || array_key_exists('lightness', $colour)) { throw new SassColourException('SassColour can not have HSL and RGB keys specified', SassScriptParser::$context->node); } if ($all && (!array_key_exists('red', $colour) || !array_key_exists('green', $colour) || !array_key_exists('blue', $colour))) { throw new SassColourException('SassColour must have all RGB keys specified', SassScriptParser::$context->node); } return 'rgb'; } elseif (array_key_exists('hue', $colour) || array_key_exists('saturation', $colour) || array_key_exists('lightness', $colour)) { if ($all && (!array_key_exists('hue', $colour) || !array_key_exists('saturation', $colour) || !array_key_exists('lightness', $colour))) { throw new SassColourException('SassColour must have all HSL keys specified', SassScriptParser::$context->node); } return 'hsl'; } elseif ($all && sizeof($colour) < 3) { throw new SassColourException('SassColour array must have at least 3 elements', SassScriptParser::$context->node); } } /** * Returns a value indicating if a token of this type can be matched at * the start of the subject string. * @param string the subject string * @return mixed match at the start of the string or false if no match */ static public function isa($subject) { if (empty(self::$regex)) { self::$regex = str_replace('{CSS_COLOURS}', join('|', array_reverse(array_keys(self::$svgColours))), self::MATCH); } return (preg_match(self::$regex, strtolower($subject), $matches) ? $matches[0] : false); } } |