Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402]
1 <?php 2 3 namespace Sabberworm\CSS\Value; 4 5 use Sabberworm\CSS\OutputFormat; 6 use Sabberworm\CSS\Parsing\ParserState; 7 use Sabberworm\CSS\Parsing\UnexpectedEOFException; 8 use Sabberworm\CSS\Parsing\UnexpectedTokenException; 9 10 class Color extends CSSFunction 11 { 12 /** 13 * @param array<int, RuleValueList|CSSFunction|CSSString|LineName|Size|URL|string> $aColor 14 * @param int $iLineNo 15 */ 16 public function __construct(array $aColor, $iLineNo = 0) 17 { 18 parent::__construct(implode('', array_keys($aColor)), $aColor, ',', $iLineNo); 19 } 20 21 /** 22 * @return Color|CSSFunction 23 * 24 * @throws UnexpectedEOFException 25 * @throws UnexpectedTokenException 26 */ 27 public static function parse(ParserState $oParserState) 28 { 29 $aColor = []; 30 if ($oParserState->comes('#')) { 31 $oParserState->consume('#'); 32 $sValue = $oParserState->parseIdentifier(false); 33 if ($oParserState->strlen($sValue) === 3) { 34 $sValue = $sValue[0] . $sValue[0] . $sValue[1] . $sValue[1] . $sValue[2] . $sValue[2]; 35 } elseif ($oParserState->strlen($sValue) === 4) { 36 $sValue = $sValue[0] . $sValue[0] . $sValue[1] . $sValue[1] . $sValue[2] . $sValue[2] . $sValue[3] 37 . $sValue[3]; 38 } 39 40 if ($oParserState->strlen($sValue) === 8) { 41 $aColor = [ 42 'r' => new Size(intval($sValue[0] . $sValue[1], 16), null, true, $oParserState->currentLine()), 43 'g' => new Size(intval($sValue[2] . $sValue[3], 16), null, true, $oParserState->currentLine()), 44 'b' => new Size(intval($sValue[4] . $sValue[5], 16), null, true, $oParserState->currentLine()), 45 'a' => new Size( 46 round(self::mapRange(intval($sValue[6] . $sValue[7], 16), 0, 255, 0, 1), 2), 47 null, 48 true, 49 $oParserState->currentLine() 50 ), 51 ]; 52 } else { 53 $aColor = [ 54 'r' => new Size(intval($sValue[0] . $sValue[1], 16), null, true, $oParserState->currentLine()), 55 'g' => new Size(intval($sValue[2] . $sValue[3], 16), null, true, $oParserState->currentLine()), 56 'b' => new Size(intval($sValue[4] . $sValue[5], 16), null, true, $oParserState->currentLine()), 57 ]; 58 } 59 } else { 60 $sColorMode = $oParserState->parseIdentifier(true); 61 $oParserState->consumeWhiteSpace(); 62 $oParserState->consume('('); 63 64 $bContainsVar = false; 65 $iLength = $oParserState->strlen($sColorMode); 66 for ($i = 0; $i < $iLength; ++$i) { 67 $oParserState->consumeWhiteSpace(); 68 if ($oParserState->comes('var')) { 69 $aColor[$sColorMode[$i]] = CSSFunction::parseIdentifierOrFunction($oParserState); 70 $bContainsVar = true; 71 } else { 72 $aColor[$sColorMode[$i]] = Size::parse($oParserState, true); 73 } 74 75 if ($bContainsVar && $oParserState->comes(')')) { 76 // With a var argument the function can have fewer arguments 77 break; 78 } 79 80 $oParserState->consumeWhiteSpace(); 81 if ($i < ($iLength - 1)) { 82 $oParserState->consume(','); 83 } 84 } 85 $oParserState->consume(')'); 86 87 if ($bContainsVar) { 88 return new CSSFunction($sColorMode, array_values($aColor), ',', $oParserState->currentLine()); 89 } 90 } 91 return new Color($aColor, $oParserState->currentLine()); 92 } 93 94 /** 95 * @param float $fVal 96 * @param float $fFromMin 97 * @param float $fFromMax 98 * @param float $fToMin 99 * @param float $fToMax 100 * 101 * @return float 102 */ 103 private static function mapRange($fVal, $fFromMin, $fFromMax, $fToMin, $fToMax) 104 { 105 $fFromRange = $fFromMax - $fFromMin; 106 $fToRange = $fToMax - $fToMin; 107 $fMultiplier = $fToRange / $fFromRange; 108 $fNewVal = $fVal - $fFromMin; 109 $fNewVal *= $fMultiplier; 110 return $fNewVal + $fToMin; 111 } 112 113 /** 114 * @return array<int, RuleValueList|CSSFunction|CSSString|LineName|Size|URL|string> 115 */ 116 public function getColor() 117 { 118 return $this->aComponents; 119 } 120 121 /** 122 * @param array<int, RuleValueList|CSSFunction|CSSString|LineName|Size|URL|string> $aColor 123 * 124 * @return void 125 */ 126 public function setColor(array $aColor) 127 { 128 $this->setName(implode('', array_keys($aColor))); 129 $this->aComponents = $aColor; 130 } 131 132 /** 133 * @return string 134 */ 135 public function getColorDescription() 136 { 137 return $this->getName(); 138 } 139 140 /** 141 * @return string 142 */ 143 public function __toString() 144 { 145 return $this->render(new OutputFormat()); 146 } 147 148 /** 149 * @return string 150 */ 151 public function render(OutputFormat $oOutputFormat) 152 { 153 // Shorthand RGB color values 154 if ($oOutputFormat->getRGBHashNotation() && implode('', array_keys($this->aComponents)) === 'rgb') { 155 $sResult = sprintf( 156 '%02x%02x%02x', 157 $this->aComponents['r']->getSize(), 158 $this->aComponents['g']->getSize(), 159 $this->aComponents['b']->getSize() 160 ); 161 return '#' . (($sResult[0] == $sResult[1]) && ($sResult[2] == $sResult[3]) && ($sResult[4] == $sResult[5]) 162 ? "$sResult[0]$sResult[2]$sResult[4]" : $sResult); 163 } 164 return parent::render($oOutputFormat); 165 } 166 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body