1<?php
2
3/*
4 * This file is part of the Imagine package.
5 *
6 * (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Imagine\Image\Palette\Color;
13
14use Imagine\Image\Palette\CMYK as CMYKPalette;
15use Imagine\Exception\RuntimeException;
16use Imagine\Exception\InvalidArgumentException;
17
18final class CMYK implements ColorInterface
19{
20    /**
21     * @var integer
22     */
23    private $c;
24
25    /**
26     * @var integer
27     */
28    private $m;
29
30    /**
31     * @var integer
32     */
33    private $y;
34
35    /**
36     * @var integer
37     */
38    private $k;
39
40    /**
41     *
42     * @var CMYK
43     */
44    private $palette;
45
46    public function __construct(CMYKPalette $palette, array $color)
47    {
48        $this->palette = $palette;
49        $this->setColor($color);
50    }
51
52    /**
53     * {@inheritdoc}
54     */
55    public function getValue($component)
56    {
57        switch ($component) {
58            case ColorInterface::COLOR_CYAN:
59                return $this->getCyan();
60            case ColorInterface::COLOR_MAGENTA:
61                return $this->getMagenta();
62            case ColorInterface::COLOR_YELLOW:
63                return $this->getYellow();
64            case ColorInterface::COLOR_KEYLINE:
65                return $this->getKeyline();
66            default:
67                throw new InvalidArgumentException(sprintf('Color component %s is not valid', $component));
68        }
69    }
70
71    /**
72     * Returns Cyan value of the color
73     *
74     * @return integer
75     */
76    public function getCyan()
77    {
78        return $this->c;
79    }
80
81    /**
82     * Returns Magenta value of the color
83     *
84     * @return integer
85     */
86    public function getMagenta()
87    {
88        return $this->m;
89    }
90
91    /**
92     * Returns Yellow value of the color
93     *
94     * @return integer
95     */
96    public function getYellow()
97    {
98        return $this->y;
99    }
100
101    /**
102     * Returns Key value of the color
103     *
104     * @return integer
105     */
106    public function getKeyline()
107    {
108        return $this->k;
109    }
110
111    /**
112     * {@inheritdoc}
113     */
114    public function getPalette()
115    {
116        return $this->palette;
117    }
118
119    /**
120     * {@inheritdoc}
121     */
122    public function getAlpha()
123    {
124        return null;
125    }
126
127    /**
128     * {@inheritdoc}
129     */
130    public function dissolve($alpha)
131    {
132        throw new RuntimeException('CMYK does not support dissolution');
133    }
134
135    /**
136     * {@inheritdoc}
137     */
138    public function lighten($shade)
139    {
140        return $this->palette->color(
141            array(
142                $this->c,
143                $this->m,
144                $this->y,
145                max(0, $this->k - $shade),
146            )
147        );
148    }
149
150    /**
151     * {@inheritdoc}
152     */
153    public function darken($shade)
154    {
155        return $this->palette->color(
156            array(
157                $this->c,
158                $this->m,
159                $this->y,
160                min(100, $this->k + $shade),
161            )
162        );
163    }
164
165    /**
166     * {@inheritdoc}
167     */
168    public function grayscale()
169    {
170        $color = array(
171            $this->c * (1 - $this->k / 100) + $this->k,
172            $this->m * (1 - $this->k / 100) + $this->k,
173            $this->y * (1 - $this->k / 100) + $this->k,
174        );
175
176        $gray = min(100, round(0.299 * $color[0] + 0.587 * $color[1] + 0.114 * $color[2]));
177
178        return $this->palette->color(array($gray, $gray, $gray, $this->k));
179    }
180
181    /**
182     * {@inheritdoc}
183     */
184    public function isOpaque()
185    {
186        return true;
187    }
188
189    /**
190     * Returns hex representation of the color
191     *
192     * @return string
193     */
194    public function __toString()
195    {
196        return sprintf('cmyk(%d%%, %d%%, %d%%, %d%%)', $this->c, $this->m, $this->y, $this->k);
197    }
198
199    /**
200     * Internal, Performs checks for color validity (an of array(C, M, Y, K))
201     *
202     * @param array $color
203     *
204     * @throws InvalidArgumentException
205     */
206    private function setColor(array $color)
207    {
208        if (count($color) !== 4) {
209            throw new InvalidArgumentException('Color argument must look like array(C, M, Y, K), where C, M, Y, K are the integer values between 0 and 255 for cyan, magenta, yellow and black color indexes accordingly');
210        }
211
212        $colors = array_values($color);
213        array_walk($colors, function ($color) {
214            return max(0, min(100, $color));
215        });
216
217        list($this->c, $this->m, $this->y, $this->k) = $colors;
218    }
219}
220