1<?php
2//============================================================+
3// File name   : tcpdf_colors.php
4// Version     : 1.0.004
5// Begin       : 2002-04-09
6// Last Update : 2014-04-25
7// Author      : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
8// License     : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
9// -------------------------------------------------------------------
10// Copyright (C) 2002-2013  Nicola Asuni - Tecnick.com LTD
11//
12// This file is part of TCPDF software library.
13//
14// TCPDF is free software: you can redistribute it and/or modify it
15// under the terms of the GNU Lesser General Public License as
16// published by the Free Software Foundation, either version 3 of the
17// License, or (at your option) any later version.
18//
19// TCPDF is distributed in the hope that it will be useful, but
20// WITHOUT ANY WARRANTY; without even the implied warranty of
21// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
22// See the GNU Lesser General Public License for more details.
23//
24// You should have received a copy of the GNU Lesser General Public License
25// along with TCPDF.  If not, see <http://www.gnu.org/licenses/>.
26//
27// See LICENSE.TXT file for more information.
28// -------------------------------------------------------------------
29//
30// Description : Array of WEB safe colors
31//
32//============================================================+
33
34/**
35 * @file
36 * PHP color class for TCPDF
37 * @author Nicola Asuni
38 * @package com.tecnick.tcpdf
39 */
40
41/**
42 * @class TCPDF_COLORS
43 * PHP color class for TCPDF
44 * @package com.tecnick.tcpdf
45 * @version 1.0.004
46 * @author Nicola Asuni - info@tecnick.com
47 */
48class TCPDF_COLORS {
49
50	/**
51	 * Array of WEB safe colors
52	 * @public static
53	 */
54	public static $webcolor = array (
55		'aliceblue' => 'f0f8ff',
56		'antiquewhite' => 'faebd7',
57		'aqua' => '00ffff',
58		'aquamarine' => '7fffd4',
59		'azure' => 'f0ffff',
60		'beige' => 'f5f5dc',
61		'bisque' => 'ffe4c4',
62		'black' => '000000',
63		'blanchedalmond' => 'ffebcd',
64		'blue' => '0000ff',
65		'blueviolet' => '8a2be2',
66		'brown' => 'a52a2a',
67		'burlywood' => 'deb887',
68		'cadetblue' => '5f9ea0',
69		'chartreuse' => '7fff00',
70		'chocolate' => 'd2691e',
71		'coral' => 'ff7f50',
72		'cornflowerblue' => '6495ed',
73		'cornsilk' => 'fff8dc',
74		'crimson' => 'dc143c',
75		'cyan' => '00ffff',
76		'darkblue' => '00008b',
77		'darkcyan' => '008b8b',
78		'darkgoldenrod' => 'b8860b',
79		'dkgray' => 'a9a9a9',
80		'darkgray' => 'a9a9a9',
81		'darkgrey' => 'a9a9a9',
82		'darkgreen' => '006400',
83		'darkkhaki' => 'bdb76b',
84		'darkmagenta' => '8b008b',
85		'darkolivegreen' => '556b2f',
86		'darkorange' => 'ff8c00',
87		'darkorchid' => '9932cc',
88		'darkred' => '8b0000',
89		'darksalmon' => 'e9967a',
90		'darkseagreen' => '8fbc8f',
91		'darkslateblue' => '483d8b',
92		'darkslategray' => '2f4f4f',
93		'darkslategrey' => '2f4f4f',
94		'darkturquoise' => '00ced1',
95		'darkviolet' => '9400d3',
96		'deeppink' => 'ff1493',
97		'deepskyblue' => '00bfff',
98		'dimgray' => '696969',
99		'dimgrey' => '696969',
100		'dodgerblue' => '1e90ff',
101		'firebrick' => 'b22222',
102		'floralwhite' => 'fffaf0',
103		'forestgreen' => '228b22',
104		'fuchsia' => 'ff00ff',
105		'gainsboro' => 'dcdcdc',
106		'ghostwhite' => 'f8f8ff',
107		'gold' => 'ffd700',
108		'goldenrod' => 'daa520',
109		'gray' => '808080',
110		'grey' => '808080',
111		'green' => '008000',
112		'greenyellow' => 'adff2f',
113		'honeydew' => 'f0fff0',
114		'hotpink' => 'ff69b4',
115		'indianred' => 'cd5c5c',
116		'indigo' => '4b0082',
117		'ivory' => 'fffff0',
118		'khaki' => 'f0e68c',
119		'lavender' => 'e6e6fa',
120		'lavenderblush' => 'fff0f5',
121		'lawngreen' => '7cfc00',
122		'lemonchiffon' => 'fffacd',
123		'lightblue' => 'add8e6',
124		'lightcoral' => 'f08080',
125		'lightcyan' => 'e0ffff',
126		'lightgoldenrodyellow' => 'fafad2',
127		'ltgray' => 'd3d3d3',
128		'lightgray' => 'd3d3d3',
129		'lightgrey' => 'd3d3d3',
130		'lightgreen' => '90ee90',
131		'lightpink' => 'ffb6c1',
132		'lightsalmon' => 'ffa07a',
133		'lightseagreen' => '20b2aa',
134		'lightskyblue' => '87cefa',
135		'lightslategray' => '778899',
136		'lightslategrey' => '778899',
137		'lightsteelblue' => 'b0c4de',
138		'lightyellow' => 'ffffe0',
139		'lime' => '00ff00',
140		'limegreen' => '32cd32',
141		'linen' => 'faf0e6',
142		'magenta' => 'ff00ff',
143		'maroon' => '800000',
144		'mediumaquamarine' => '66cdaa',
145		'mediumblue' => '0000cd',
146		'mediumorchid' => 'ba55d3',
147		'mediumpurple' => '9370d8',
148		'mediumseagreen' => '3cb371',
149		'mediumslateblue' => '7b68ee',
150		'mediumspringgreen' => '00fa9a',
151		'mediumturquoise' => '48d1cc',
152		'mediumvioletred' => 'c71585',
153		'midnightblue' => '191970',
154		'mintcream' => 'f5fffa',
155		'mistyrose' => 'ffe4e1',
156		'moccasin' => 'ffe4b5',
157		'navajowhite' => 'ffdead',
158		'navy' => '000080',
159		'oldlace' => 'fdf5e6',
160		'olive' => '808000',
161		'olivedrab' => '6b8e23',
162		'orange' => 'ffa500',
163		'orangered' => 'ff4500',
164		'orchid' => 'da70d6',
165		'palegoldenrod' => 'eee8aa',
166		'palegreen' => '98fb98',
167		'paleturquoise' => 'afeeee',
168		'palevioletred' => 'd87093',
169		'papayawhip' => 'ffefd5',
170		'peachpuff' => 'ffdab9',
171		'peru' => 'cd853f',
172		'pink' => 'ffc0cb',
173		'plum' => 'dda0dd',
174		'powderblue' => 'b0e0e6',
175		'purple' => '800080',
176		'red' => 'ff0000',
177		'rosybrown' => 'bc8f8f',
178		'royalblue' => '4169e1',
179		'saddlebrown' => '8b4513',
180		'salmon' => 'fa8072',
181		'sandybrown' => 'f4a460',
182		'seagreen' => '2e8b57',
183		'seashell' => 'fff5ee',
184		'sienna' => 'a0522d',
185		'silver' => 'c0c0c0',
186		'skyblue' => '87ceeb',
187		'slateblue' => '6a5acd',
188		'slategray' => '708090',
189		'slategrey' => '708090',
190		'snow' => 'fffafa',
191		'springgreen' => '00ff7f',
192		'steelblue' => '4682b4',
193		'tan' => 'd2b48c',
194		'teal' => '008080',
195		'thistle' => 'd8bfd8',
196		'tomato' => 'ff6347',
197		'turquoise' => '40e0d0',
198		'violet' => 'ee82ee',
199		'wheat' => 'f5deb3',
200		'white' => 'ffffff',
201		'whitesmoke' => 'f5f5f5',
202		'yellow' => 'ffff00',
203		'yellowgreen' => '9acd32'
204	); // end of web colors
205
206	/**
207	 * Array of valid JavaScript color names
208	 * @public static
209	 */
210	public static $jscolor = array ('transparent', 'black', 'white', 'red', 'green', 'blue', 'cyan', 'magenta', 'yellow', 'dkGray', 'gray', 'ltGray');
211
212	/**
213	 * Array of Spot colors (C,M,Y,K,name)
214	 * Color keys must be in lowercase and without spaces.
215	 * As long as no open standard for spot colours exists, you have to buy a colour book by one of the colour manufacturers and insert the values and names of spot colours directly.
216	 * Common industry standard spot colors are: ANPA-COLOR, DIC, FOCOLTONE, GCMI, HKS, PANTONE, TOYO, TRUMATCH.
217	 * @public static
218	 */
219	public static $spotcolor = array (
220		// special registration colors
221		'none'    => array(  0,   0,   0,   0, 'None'),
222		'all'     => array(100, 100, 100, 100, 'All'),
223		// standard CMYK colors
224		'cyan'    => array(100,   0,   0,   0, 'Cyan'),
225		'magenta' => array(  0, 100,   0,   0, 'Magenta'),
226		'yellow'  => array(  0,   0, 100,   0, 'Yellow'),
227		'key'     => array(  0,   0,   0, 100, 'Key'),
228		// alias
229		'white'   => array(  0,   0,   0,   0, 'White'),
230		'black'   => array(  0,   0,   0, 100, 'Black'),
231		// standard RGB colors
232		'red'     => array(  0, 100, 100,   0, 'Red'),
233		'green'   => array(100,   0, 100,   0, 'Green'),
234		'blue'    => array(100, 100,   0,   0, 'Blue'),
235		// Add here standard spot colors or dynamically define them with AddSpotColor()
236		// ...
237	); // end of spot colors
238
239	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
240
241	/**
242	 * Return the Spot color array.
243	 * @param $name (string) Name of the spot color.
244	 * @param $spotc (array) Reference to an array of spot colors.
245	 * @return (array) Spot color array or false if not defined.
246	 * @since 5.9.125 (2011-10-03)
247	 * @public static
248	 */
249	public static function getSpotColor($name, &$spotc) {
250		if (isset($spotc[$name])) {
251			return $spotc[$name];
252		}
253		$color = preg_replace('/[\s]*/', '', $name); // remove extra spaces
254		$color = strtolower($color);
255		if (isset(self::$spotcolor[$color])) {
256			if (!isset($spotc[$name])) {
257				$i = (1 + count($spotc));
258				$spotc[$name] = array('C' => self::$spotcolor[$color][0], 'M' => self::$spotcolor[$color][1], 'Y' => self::$spotcolor[$color][2], 'K' => self::$spotcolor[$color][3], 'name' => self::$spotcolor[$color][4], 'i' => $i);
259			}
260			return $spotc[self::$spotcolor[$color][4]];
261		}
262		return false;
263	}
264
265	/**
266	 * Returns an array (RGB or CMYK) from an html color name, or a six-digit (i.e. #3FE5AA), or three-digit (i.e. #7FF) hexadecimal color, or a javascript color array, or javascript color name.
267	 * @param $hcolor (string) HTML color.
268	 * @param $spotc (array) Reference to an array of spot colors.
269	 * @param $defcol (array) Color to return in case of error.
270	 * @return array RGB or CMYK color, or false in case of error.
271	 * @public static
272	 */
273	public static function convertHTMLColorToDec($hcolor, &$spotc, $defcol=array('R'=>128,'G'=>128,'B'=>128)) {
274		$color = preg_replace('/[\s]*/', '', $hcolor); // remove extra spaces
275		$color = strtolower($color);
276		// check for javascript color array syntax
277		if (strpos($color, '[') !== false) {
278			if (preg_match('/[\[][\"\'](t|g|rgb|cmyk)[\"\'][\,]?([0-9\.]*)[\,]?([0-9\.]*)[\,]?([0-9\.]*)[\,]?([0-9\.]*)[\]]/', $color, $m) > 0) {
279				$returncolor = array();
280				switch ($m[1]) {
281					case 'cmyk': {
282						// RGB
283						$returncolor['C'] = max(0, min(100, (floatval($m[2]) * 100)));
284						$returncolor['M'] = max(0, min(100, (floatval($m[3]) * 100)));
285						$returncolor['Y'] = max(0, min(100, (floatval($m[4]) * 100)));
286						$returncolor['K'] = max(0, min(100, (floatval($m[5]) * 100)));
287						break;
288					}
289					case 'rgb': {
290						// RGB
291						$returncolor['R'] = max(0, min(255, (floatval($m[2]) * 255)));
292						$returncolor['G'] = max(0, min(255, (floatval($m[3]) * 255)));
293						$returncolor['B'] = max(0, min(255, (floatval($m[4]) * 255)));
294						break;
295					}
296					case 'g': {
297						// grayscale
298						$returncolor['G'] = max(0, min(255, (floatval($m[2]) * 255)));
299						break;
300					}
301					case 't':
302					default: {
303						// transparent (empty array)
304						break;
305					}
306				}
307				return $returncolor;
308			}
309		} elseif ((substr($color, 0, 4) != 'cmyk') AND (substr($color, 0, 3) != 'rgb') AND (($dotpos = strpos($color, '.')) !== false)) {
310			// remove class parent (i.e.: color.red)
311			$color = substr($color, ($dotpos + 1));
312			if ($color == 'transparent') {
313				// transparent (empty array)
314				return array();
315			}
316		}
317		if (strlen($color) == 0) {
318			return $defcol;
319		}
320		// RGB ARRAY
321		if (substr($color, 0, 3) == 'rgb') {
322			$codes = substr($color, 4);
323			$codes = str_replace(')', '', $codes);
324			$returncolor = explode(',', $codes);
325			foreach ($returncolor as $key => $val) {
326				if (strpos($val, '%') > 0) {
327					// percentage
328					$returncolor[$key] = (255 * intval($val) / 100);
329				} else {
330					$returncolor[$key] = intval($val);
331				}
332				// normalize value
333				$returncolor[$key] = max(0, min(255, $returncolor[$key]));
334			}
335			return $returncolor;
336		}
337		// CMYK ARRAY
338		if (substr($color, 0, 4) == 'cmyk') {
339			$codes = substr($color, 5);
340			$codes = str_replace(')', '', $codes);
341			$returncolor = explode(',', $codes);
342			foreach ($returncolor as $key => $val) {
343				if (strpos($val, '%') !== false) {
344					// percentage
345					$returncolor[$key] = (100 * intval($val) / 100);
346				} else {
347					$returncolor[$key] = intval($val);
348				}
349				// normalize value
350				$returncolor[$key] = max(0, min(100, $returncolor[$key]));
351			}
352			return $returncolor;
353		}
354		if ($color[0] != '#') {
355			// COLOR NAME
356			if (isset(self::$webcolor[$color])) {
357				// web color
358				$color_code = self::$webcolor[$color];
359			} else {
360				// spot color
361				$returncolor = self::getSpotColor($color, $spotc);
362				if ($returncolor === false) {
363					$returncolor = $defcol;
364				}
365				return $returncolor;
366			}
367		} else {
368			$color_code = substr($color, 1);
369		}
370		// HEXADECIMAL REPRESENTATION
371		switch (strlen($color_code)) {
372			case 3: {
373				// 3-digit RGB hexadecimal representation
374				$r = substr($color_code, 0, 1);
375				$g = substr($color_code, 1, 1);
376				$b = substr($color_code, 2, 1);
377				$returncolor = array();
378				$returncolor['R'] = max(0, min(255, hexdec($r.$r)));
379				$returncolor['G'] = max(0, min(255, hexdec($g.$g)));
380				$returncolor['B'] = max(0, min(255, hexdec($b.$b)));
381				break;
382			}
383			case 6: {
384				// 6-digit RGB hexadecimal representation
385				$returncolor = array();
386				$returncolor['R'] = max(0, min(255, hexdec(substr($color_code, 0, 2))));
387				$returncolor['G'] = max(0, min(255, hexdec(substr($color_code, 2, 2))));
388				$returncolor['B'] = max(0, min(255, hexdec(substr($color_code, 4, 2))));
389				break;
390			}
391			case 8: {
392				// 8-digit CMYK hexadecimal representation
393				$returncolor = array();
394				$returncolor['C'] = max(0, min(100, round(hexdec(substr($color_code, 0, 2)) / 2.55)));
395				$returncolor['M'] = max(0, min(100, round(hexdec(substr($color_code, 2, 2)) / 2.55)));
396				$returncolor['Y'] = max(0, min(100, round(hexdec(substr($color_code, 4, 2)) / 2.55)));
397				$returncolor['K'] = max(0, min(100, round(hexdec(substr($color_code, 6, 2)) / 2.55)));
398				break;
399			}
400			default: {
401				$returncolor = $defcol;
402				break;
403			}
404		}
405		return $returncolor;
406	}
407
408	/**
409	 * Convert a color array into a string representation.
410	 * @param $c (array) Array of colors.
411	 * @return (string) The color array representation.
412	 * @since 5.9.137 (2011-12-01)
413	 * @public static
414	 */
415	public static function getColorStringFromArray($c) {
416		$c = array_values($c);
417		$color = '[';
418		switch (count($c)) {
419			case 4: {
420				// CMYK
421				$color .= sprintf('%F %F %F %F', (max(0, min(100, floatval($c[0]))) / 100), (max(0, min(100, floatval($c[1]))) / 100), (max(0, min(100, floatval($c[2]))) / 100), (max(0, min(100, floatval($c[3]))) / 100));
422				break;
423			}
424			case 3: {
425				// RGB
426				$color .= sprintf('%F %F %F', (max(0, min(255, floatval($c[0]))) / 255), (max(0, min(255, floatval($c[1]))) / 255), (max(0, min(255, floatval($c[2]))) / 255));
427				break;
428			}
429			case 1: {
430				// grayscale
431				$color .= sprintf('%F', (max(0, min(255, floatval($c[0]))) / 255));
432				break;
433			}
434		}
435		$color .= ']';
436		return $color;
437	}
438
439	/**
440	 * Convert color to javascript color.
441	 * @param $color (string) color name or "#RRGGBB"
442	 * @protected
443	 * @since 2.1.002 (2008-02-12)
444	 * @public static
445	 */
446	public static function _JScolor($color) {
447		if (substr($color, 0, 1) == '#') {
448			return sprintf("['RGB',%F,%F,%F]", (hexdec(substr($color, 1, 2)) / 255), (hexdec(substr($color, 3, 2)) / 255), (hexdec(substr($color, 5, 2)) / 255));
449		}
450		if (!in_array($color, self::$jscolor)) {
451			// default transparent color
452			$color = $jscolor[0];
453		}
454		return 'color.'.$color;
455	}
456
457
458} // END OF TCPDF_COLORS CLASS
459
460//============================================================+
461// END OF FILE
462//============================================================+
463