Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
}