Passed
Branch master (48d769)
by Michael
02:30
created

ImageColor   B

Complexity

Total Complexity 45

Size/Duplication

Total Lines 665
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 665
rs 8.146
c 0
b 0
f 0
wmc 45

17 Methods

Rating   Name   Duplication   Size   Complexity  
A color2RGB() 0 11 2
A mixColors() 0 17 3
A hsv2rgb() 0 3 1
A setWebSafe() 0 3 1
A hex2rgb() 0 6 1
A setColors() 0 3 1
A setInternalColors() 0 7 3
A splitColor() 0 8 1
B namedColor2RGB() 0 156 3
A allocateColor() 0 5 1
B percentageColor2RGB() 0 23 4
B hsv2hex() 0 57 7
A returnColor() 0 3 1
A rgb2hex() 0 3 1
C getRange() 0 51 7
B changeLightness() 0 24 6
A getTextColor() 0 7 2

How to fix   Complexity   

Complex Class

Complex classes like ImageColor often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ImageColor, and based on these observations, apply Extract Interface, too.

1
<?php namespace XoopsModules\Pedigree;
2
3
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5
/**
6
 * Color.php is the implementation of ImageColor.
7
 *
8
 * PHP versions 4 and 5
9
 *
10
 * LICENSE: This source file is subject to version 3.0 of the PHP license
11
 * that is available through the world-wide-web at the following URI:
12
 * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
13
 * the PHP License and are unable to obtain it through the web, please
14
 * send a note to [email protected] so we can mail you a copy immediately.
15
 *
16
 * @category    Image
17
 * @package     ImageColor
18
 * @author      Jason Lotito <[email protected]>
19
 * @author      Andrew Morton <[email protected]>
20
 * @copyright   2003-2005 The PHP Group
21
 * @license     http://www.php.net/license/3_0.txt  PHP License 3.0
22
 * @version     1.1 2006/04/30
23
 * @link        http://pear.php.net/package/ImageColor
24
 */
25
26
/**
27
 * ImageColor handles color conversion and mixing.
28
 *
29
 * The class is quick, simple to use, and does its job fairly well but it's got
30
 * some code smells:
31
 *  - Call setColors() for some functions but not others.
32
 *  - Different functions expect different color formats. setColors() only
33
 *    accepts hex while allocateColor() will accept named or hex (provided the
34
 *    hex ones start with the # character).
35
 *  - Some conversions go in only one direction, ie HSV->RGB but no RGB->HSV.
36
 * I'm going to try to straighten out some of this but I'll be hard to do so
37
 * without breaking backwards compatibility.
38
 *
39
 * @category    Image
40
 * @package     ImageColor
41
 * @author      Jason Lotito <[email protected]>
42
 * @author      Andrew Morton <[email protected]>
43
 * @copyright   2003-2005 The PHP Group
44
 * @license     http://www.php.net/license/3_0.txt  PHP License 3.0
45
 * @version     Release: 0.1.2
46
 * @link        http://pear.php.net/package/ImageColor
47
 */
48
49
use XoopsModules\Pedigree;
50
51
/**
52
 * Class ImageColor
53
 */
54
class ImageColor
55
{
56
    /**
57
     * First color that the class handles for ranges and mixes.
58
     *
59
     * @var array
60
     * @access  public
61
     * @see     setColors()
62
     */
63
    public $color1 = [];
64
65
    /**
66
     * Second color that the class handles for ranges and mixes.
67
     *
68
     * @var array
69
     * @access  public
70
     * @see     setColors()
71
     */
72
    public $color2 = [];
73
74
    /**
75
     * Boolean value for determining whether colors outputted should be limited
76
     * to the web safe pallet or not.
77
     *
78
     * @var boolean
79
     * @access  private
80
     * @see     setWebSafe()
81
     */
82
    private $websafeb = false;
83
84
    /**
85
     * Mix two colors together by finding their average. If the colors are not
86
     * passed as parameters, the class's colors will be mixed instead.
87
     *
88
     * @param bool|string $col1 The first color you want to mix
89
     * @param bool|string $col2 The second color you want to mix
90
     *
91
     * @return string The mixed color.
92
     * @access  public
93
     * @author  Jason Lotito <[email protected]>
94
     * @uses    setInternalColors() to assign the colors if any are passed to the
95
     *                class.
96
     */
97
    public function mixColors($col1 = false, $col2 = false)
98
    {
99
        if ($col1) {
100
            $this->setInternalColors($col1, $col2);
0 ignored issues
show
Bug introduced by
It seems like $col1 can also be of type true; however, parameter $col1 of XoopsModules\Pedigree\Im...or::setInternalColors() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

100
            $this->setInternalColors(/** @scrutinizer ignore-type */ $col1, $col2);
Loading history...
101
        }
102
103
        // after finding the average, it will be a float. add 0.5 and then
104
        // cast to an integer to properly round it to an integer.
105
        $color3[0] = (int)((($this->color1[0] + $this->color2[0]) / 2) + 0.5);
0 ignored issues
show
Comprehensibility Best Practice introduced by
$color3 was never initialized. Although not strictly required by PHP, it is generally a good practice to add $color3 = array(); before regardless.
Loading history...
106
        $color3[1] = (int)((($this->color1[1] + $this->color2[1]) / 2) + 0.5);
107
        $color3[2] = (int)((($this->color1[2] + $this->color2[2]) / 2) + 0.5);
108
109
        if ($this->websafeb) {
110
            array_walk($color3, '_makeWebSafe');
111
        }
112
113
        return $this->rgb2hex($color3);
114
    }
115
116
    /**
117
     * Determines whether colors the returned by this class will be rounded to
118
     * the nearest web safe value.
119
     *
120
     * @param boolean $bool Indicates if colors should be limited to the
121
     *                      websafe pallet.
122
     *
123
     * @return void
124
     * @access  public
125
     * @author  Jason Lotito <[email protected]>
126
     */
127
    public function setWebSafe($bool = true)
128
    {
129
        $this->websafeb = (boolean)$bool;
130
    }
131
132
    /**
133
     * Set the two colors this class uses for mixing and ranges.
134
     *
135
     * @param string $col1 The first color in hex format
136
     * @param string $col2 The second color in hex format
137
     *
138
     * @return void
139
     * @access  public
140
     * @author  Jason Lotito <[email protected]>
141
     */
142
    public function setColors($col1, $col2)
143
    {
144
        $this->setInternalColors($col1, $col2);
145
    }
146
147
    /**
148
     * Get the range of colors between the class's two colors, given a degree.
149
     *
150
     * @param integer $degrees How large a 'step' we should take between the
151
     *                         colors.
152
     *
153
     * @return array Returns an array of hex strings, one element for each
154
     *               color.
155
     * @access  public
156
     * @author  Jason Lotito <[email protected]>
157
     * @todo    Allow for degrees for individual parts of the colors.
158
     */
159
    public function getRange($degrees = 2)
160
    {
161
        if (0 == $degrees) {
162
            $degrees = 1;
163
        }
164
165
        // The degrees give us how much we should advance each color at each
166
        // phase of the loop.  This way, the advance is equal throughout all
167
        // the colors.
168
169
        $red_steps   = ($this->color2[0] - $this->color1[0]) / $degrees;
170
        $green_steps = ($this->color2[1] - $this->color1[1]) / $degrees;
171
        $blue_steps  = ($this->color2[2] - $this->color1[2]) / $degrees;
172
173
        $allcolors = [];
174
175
        /**
176
         * The loop stops once any color has gone beyond the end color.
177
         */
178
179
        // Loop through all the degrees between the colors
180
        for ($x = 0; $x < $degrees; ++$x) {
181
            $col[0] = $red_steps * $x;
182
            $col[1] = $green_steps * $x;
183
            $col[2] = $blue_steps * $x;
184
185
            // Loop through each R, G, and B
186
            for ($i = 0; $i < 3; ++$i) {
187
                $partcolor = $this->color1[$i] + $col[$i];
188
                // If the color is less than 256
189
                if ($partcolor < 256) {
190
                    // Makes sure the colors is not less than 0
191
                    if ($partcolor > -1) {
192
                        $newcolor[$i] = $partcolor;
193
                    } else {
194
                        $newcolor[$i] = 0;
195
                    }
196
                    // Color was greater than 255
197
                } else {
198
                    $newcolor[$i] = 255;
199
                }
200
            }
201
202
            if ($this->websafeb) {
203
                array_walk($newcolor, '_makeWebSafe');
204
            }
205
206
            $allcolors[] = $this->rgb2hex($newcolor);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $newcolor does not seem to be defined for all execution paths leading up to this point.
Loading history...
207
        }
208
209
        return $allcolors;
210
    }
211
212
    /**
213
     * Change the lightness of the class's two colors.
214
     *
215
     * @param integer $degree The degree of the change. Positive values
216
     *                        lighten the color while negative values will darken it.
217
     *
218
     * @return void
219
     * @access  public
220
     * @author  Jason Lotito <[email protected]>
221
     * @uses    ImageColor::$color1 as an input and return value.
222
     * @uses    ImageColor::$color2 as an input and return value.
223
     */
224
    public function changeLightness($degree = 10)
225
    {
226
        $color1 =& $this->color1;
227
        $color2 =& $this->color2;
228
229
        for ($x = 0; $x < 3; ++$x) {
230
            if (($color1[$x] + $degree) < 256) {
231
                if (($color1[$x] + $degree) > -1) {
232
                    $color1[$x] += $degree;
233
                } else {
234
                    $color1[$x] = 0;
235
                }
236
            } else {
237
                $color1[$x] = 255;
238
            }
239
240
            if (($color2[$x] + $degree) < 256) {
241
                if (($color2[$x] + $degree) > -1) {
242
                    $color2[$x] += $degree;
243
                } else {
244
                    $color2[$x] = 0;
245
                }
246
            } else {
247
                $color2[$x] = 255;
248
            }
249
        }
250
    }
251
252
    /**
253
     * Determine if a light or dark text color would be more readable on a
254
     * background of a given color. This is determined by the G(reen) value of
255
     * RGB. You can change the dark and the light colors from their default
256
     * black and white.
257
     *
258
     * @param string $color The hex color to analyze
259
     * @param string $light The light color value to return if we should
260
     *                      have light text.
261
     * @param string $dark  The dark color value to return if we should have
262
     *                      dark text.
263
     *
264
     * @return string The light or dark value which would make the text most
265
     *                readable.
266
     * @access  public
267
     * @static
268
     * @author  Jason Lotito <[email protected]>
269
     */
270
    public function getTextColor($color, $light = '#FFFFFF', $dark = '#000000')
271
    {
272
        $color = $this->splitColor($color);
273
        if ($color[1] > hexdec('66')) {
274
            return $dark;
275
        } else {
276
            return $light;
277
        }
278
    }
279
280
    /**
281
     * Internal method to set the colors.
282
     *
283
     * @param string $col1 First color, either a name or hex value
284
     * @param string $col2 Second color, either a name or hex value
285
     *
286
     * @return void
287
     * @access  private
288
     * @author  Jason Lotito <[email protected]>
289
     */
290
    private function setInternalColors($col1, $col2)
291
    {
292
        if ($col1) {
293
            $this->color1 = $this->splitColor($col1);
294
        }
295
        if ($col2) {
296
            $this->color2 = $this->splitColor($col2);
297
        }
298
    }
299
300
    /**
301
     * Given a color, properly split it up into a 3 element RGB array.
302
     *
303
     * @param string $color The color.
304
     *
305
     * @return array A three element RGB array.
306
     * @access  private
307
     * @static
308
     * @author  Jason Lotito <[email protected]>
309
     */
310
    private function splitColor($color)
311
    {
312
        $color = str_replace('#', '', $color);
313
        $c[]   = hexdec(substr($color, 0, 2));
0 ignored issues
show
Comprehensibility Best Practice introduced by
$c was never initialized. Although not strictly required by PHP, it is generally a good practice to add $c = array(); before regardless.
Loading history...
314
        $c[]   = hexdec(substr($color, 2, 2));
315
        $c[]   = hexdec(substr($color, 4, 2));
316
317
        return $c;
318
    }
319
320
    /**
321
     * This is deprecated. Use rgb2hex() instead.
322
     *
323
     * @access     private
324
     * @deprecated Function deprecated after 1.0.1
325
     * @see        rgb2hex().
326
     *
327
     * @param $color
328
     *
329
     * @return string
330
     */
331
    private function returnColor($color)
0 ignored issues
show
Unused Code introduced by
The method returnColor() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
332
    {
333
        return $this->rgb2hex($color);
334
    }
335
336
    /**
337
     * Convert an RGB array to a hex string.
338
     *
339
     * @param array $color 3 element RGB array.
340
     *
341
     * @return string Hex color string.
342
     * @access  public
343
     * @static
344
     * @author  Jason Lotito <[email protected]>
345
     * @see     hex2rgb()
346
     */
347
    public function rgb2hex($color)
348
    {
349
        return sprintf('%02X%02X%02X', $color[0], $color[1], $color[2]);
350
    }
351
352
    /**
353
     * Convert a hex color string into an RGB array. An extra fourth element
354
     * will be returned with the original hex value.
355
     *
356
     * @param string $hex Hex color string.
357
     *
358
     * @return array RGB color array with an extra 'hex' element containing
359
     *               the original hex string.
360
     * @access  public
361
     * @static
362
     * @author  Jason Lotito <[email protected]>
363
     * @see     rgb2hex()
364
     */
365
    public function hex2rgb($hex)
366
    {
367
        $return        = $this->splitColor($hex);
368
        $return['hex'] = $hex;
369
370
        return $return;
371
    }
372
373
    /**
374
     * Convert an HSV (Hue, Saturation, Brightness) value to RGB.
375
     *
376
     * @param integer $h Hue
377
     * @param integer $s Saturation
378
     * @param integer $v Brightness
379
     *
380
     * @return array RGB array.
381
     * @access  public
382
     * @static
383
     * @author  Jason Lotito <[email protected]>
384
     * @uses    hsv2hex() to convert the HSV value to Hex.
385
     * @uses    hex2rgb() to convert the Hex value to RGB.
386
     */
387
    public function hsv2rgb($h, $s, $v)
388
    {
389
        return $this->hex2rgb($this->hsv2hex($h, $s, $v));
390
    }
391
392
    /**
393
     * Convert HSV (Hue, Saturation, Brightness) to a hex color string.
394
     *
395
     * Originally written by Jurgen Schwietering. Integrated into the class by
396
     * Jason Lotito.
397
     *
398
     * @param integer $h Hue
399
     * @param integer $s Saturation
400
     * @param integer $v Brightness
401
     *
402
     * @return string The hex string.
403
     * @access  public
404
     * @static
405
     * @author  Jurgen Schwietering <[email protected]>
406
     * @uses    rgb2hex() to convert the return value to a hex string.
407
     */
408
    public function hsv2hex($h, $s, $v)
409
    {
410
        $s /= 256.0;
411
        $v /= 256.0;
412
        if (0.0 == $s) {
413
            $r = $g = $b = $v;
0 ignored issues
show
Unused Code introduced by
The assignment to $b is dead and can be removed.
Loading history...
Unused Code introduced by
The assignment to $g is dead and can be removed.
Loading history...
Unused Code introduced by
The assignment to $r is dead and can be removed.
Loading history...
414
415
            return '';
416
        } else {
417
            $h = $h / 256.0 * 6.0;
418
            $i = floor($h);
419
            $f = $h - $i;
420
421
            $v *= 256.0;
422
            $p = (integer)($v * (1.0 - $s));
423
            $q = (integer)($v * (1.0 - $s * $f));
424
            $t = (integer)($v * (1.0 - $s * (1.0 - $f)));
425
            switch ($i) {
426
                case 0:
427
                    $r = $v;
428
                    $g = $t;
429
                    $b = $p;
430
                    break;
431
432
                case 1:
433
                    $r = $q;
434
                    $g = $v;
435
                    $b = $p;
436
                    break;
437
438
                case 2:
439
                    $r = $p;
440
                    $g = $v;
441
                    $b = $t;
442
                    break;
443
444
                case 3:
445
                    $r = $p;
446
                    $g = $q;
447
                    $b = $v;
448
                    break;
449
450
                case 4:
451
                    $r = $t;
452
                    $g = $p;
453
                    $b = $v;
454
                    break;
455
456
                default:
457
                    $r = $v;
458
                    $g = $p;
459
                    $b = $q;
460
                    break;
461
            }
462
        }
463
464
        return $this->rgb2hex([$r, $g, $b]);
465
    }
466
467
    /**
468
     * Allocates a color in the given image.
469
     *
470
     * User defined color specifications get translated into an array of RGB
471
     * values.
472
     *
473
     * @param resource     $img   Image handle
474
     * @param string|array $color Name or hex string or an RGB array.
475
     *
476
     * @return bool Image color handle.
477
     * @access  public
478
     * @static
479
     * @uses    imagefilledarc() to allocate the color.
480
     * @uses    color2RGB() to parse the color into RGB values.
481
     */
482
    public function allocateColor(&$img, $color)
483
    {
484
        $color = $this->color2RGB($color);
0 ignored issues
show
Bug introduced by
It seems like $color can also be of type array; however, parameter $color of XoopsModules\Pedigree\ImageColor::color2RGB() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

484
        $color = $this->color2RGB(/** @scrutinizer ignore-type */ $color);
Loading history...
485
486
        return imagefilledarc($img, $color[0], $color[1], $color[2]);
0 ignored issues
show
Bug introduced by
The call to imagefilledarc() has too few arguments starting with height. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

486
        return /** @scrutinizer ignore-call */ imagefilledarc($img, $color[0], $color[1], $color[2]);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
487
    }
488
489
    /**
490
     * Convert a named or hex color string to an RGB array. If the color begins
491
     * with the # character it will be treated as a hex value. Everything else
492
     * will be treated as a named color. If the named color is not known, black
493
     * will be returned.
494
     *
495
     * @param string $color
496
     *
497
     * @return array RGB color
498
     * @access  public
499
     * @static
500
     * @author  Laurent Laville <[email protected]>
501
     * @uses    hex2rgb() to convert colors begining with the # character.
502
     * @uses    namedColor2RGB() to convert everything not starting with a #.
503
     */
504
    public function color2RGB($color)
505
    {
506
        $c = [];
507
508
        if ('#' === $color{0}) {
509
            $c = $this->hex2rgb($color);
510
        } else {
511
            $c = $this->namedColor2RGB($color);
512
        }
513
514
        return $c;
515
    }
516
517
    /**
518
     * Convert a named color to an RGB array. If the color is unknown black
519
     * is returned.
520
     *
521
     * @param string $color Case insensitive color name.
522
     *
523
     * @return array RGB color array. If the color was unknown, the result
524
     *               will be black.
525
     * @access  public
526
     * @static
527
     * @author  Sebastian Bergmann <[email protected]>
528
     */
529
    public function namedColor2RGB($color)
530
    {
531
        static $colornames;
532
533
        if (!isset($colornames)) {
534
            $colornames = [
535
                'aliceblue'            => [240, 248, 255],
536
                'antiquewhite'         => [250, 235, 215],
537
                'aqua'                 => [0, 255, 255],
538
                'aquamarine'           => [127, 255, 212],
539
                'azure'                => [240, 255, 255],
540
                'beige'                => [245, 245, 220],
541
                'bisque'               => [255, 228, 196],
542
                'black'                => [0, 0, 0],
543
                'blanchedalmond'       => [255, 235, 205],
544
                'blue'                 => [0, 0, 255],
545
                'blueviolet'           => [138, 43, 226],
546
                'brown'                => [165, 42, 42],
547
                'burlywood'            => [222, 184, 135],
548
                'cadetblue'            => [95, 158, 160],
549
                'chartreuse'           => [127, 255, 0],
550
                'chocolate'            => [210, 105, 30],
551
                'coral'                => [255, 127, 80],
552
                'cornflowerblue'       => [100, 149, 237],
553
                'cornsilk'             => [255, 248, 220],
554
                'crimson'              => [220, 20, 60],
555
                'cyan'                 => [0, 255, 255],
556
                'darkblue'             => [0, 0, 13],
557
                'darkcyan'             => [0, 139, 139],
558
                'darkgoldenrod'        => [184, 134, 11],
559
                'darkgray'             => [169, 169, 169],
560
                'darkgreen'            => [0, 100, 0],
561
                'darkkhaki'            => [189, 183, 107],
562
                'darkmagenta'          => [139, 0, 139],
563
                'darkolivegreen'       => [85, 107, 47],
564
                'darkorange'           => [255, 140, 0],
565
                'darkorchid'           => [153, 50, 204],
566
                'darkred'              => [139, 0, 0],
567
                'darksalmon'           => [233, 150, 122],
568
                'darkseagreen'         => [143, 188, 143],
569
                'darkslateblue'        => [72, 61, 139],
570
                'darkslategray'        => [47, 79, 79],
571
                'darkturquoise'        => [0, 206, 209],
572
                'darkviolet'           => [148, 0, 211],
573
                'deeppink'             => [255, 20, 147],
574
                'deepskyblue'          => [0, 191, 255],
575
                'dimgray'              => [105, 105, 105],
576
                'dodgerblue'           => [30, 144, 255],
577
                'firebrick'            => [178, 34, 34],
578
                'floralwhite'          => [255, 250, 240],
579
                'forestgreen'          => [34, 139, 34],
580
                'fuchsia'              => [255, 0, 255],
581
                'gainsboro'            => [220, 220, 220],
582
                'ghostwhite'           => [248, 248, 255],
583
                'gold'                 => [255, 215, 0],
584
                'goldenrod'            => [218, 165, 32],
585
                'gray'                 => [128, 128, 128],
586
                'green'                => [0, 128, 0],
587
                'greenyellow'          => [173, 255, 47],
588
                'honeydew'             => [240, 255, 240],
589
                'hotpink'              => [255, 105, 180],
590
                'indianred'            => [205, 92, 92],
591
                'indigo'               => [75, 0, 130],
592
                'ivory'                => [255, 255, 240],
593
                'khaki'                => [240, 230, 140],
594
                'lavender'             => [230, 230, 250],
595
                'lavenderblush'        => [255, 240, 245],
596
                'lawngreen'            => [124, 252, 0],
597
                'lemonchiffon'         => [255, 250, 205],
598
                'lightblue'            => [173, 216, 230],
599
                'lightcoral'           => [240, 128, 128],
600
                'lightcyan'            => [224, 255, 255],
601
                'lightgoldenrodyellow' => [250, 250, 210],
602
                'lightgreen'           => [144, 238, 144],
603
                'lightgrey'            => [211, 211, 211],
604
                'lightpink'            => [255, 182, 193],
605
                'lightsalmon'          => [255, 160, 122],
606
                'lightseagreen'        => [32, 178, 170],
607
                'lightskyblue'         => [135, 206, 250],
608
                'lightslategray'       => [119, 136, 153],
609
                'lightsteelblue'       => [176, 196, 222],
610
                'lightyellow'          => [255, 255, 224],
611
                'lime'                 => [0, 255, 0],
612
                'limegreen'            => [50, 205, 50],
613
                'linen'                => [250, 240, 230],
614
                'magenta'              => [255, 0, 255],
615
                'maroon'               => [128, 0, 0],
616
                'mediumaquamarine'     => [102, 205, 170],
617
                'mediumblue'           => [0, 0, 205],
618
                'mediumorchid'         => [186, 85, 211],
619
                'mediumpurple'         => [147, 112, 219],
620
                'mediumseagreen'       => [60, 179, 113],
621
                'mediumslateblue'      => [123, 104, 238],
622
                'mediumspringgreen'    => [0, 250, 154],
623
                'mediumturquoise'      => [72, 209, 204],
624
                'mediumvioletred'      => [199, 21, 133],
625
                'midnightblue'         => [25, 25, 112],
626
                'mintcream'            => [245, 255, 250],
627
                'mistyrose'            => [255, 228, 225],
628
                'moccasin'             => [255, 228, 181],
629
                'navajowhite'          => [255, 222, 173],
630
                'navy'                 => [0, 0, 128],
631
                'oldlace'              => [253, 245, 230],
632
                'olive'                => [128, 128, 0],
633
                'olivedrab'            => [107, 142, 35],
634
                'orange'               => [255, 165, 0],
635
                'orangered'            => [255, 69, 0],
636
                'orchid'               => [218, 112, 214],
637
                'palegoldenrod'        => [238, 232, 170],
638
                'palegreen'            => [152, 251, 152],
639
                'paleturquoise'        => [175, 238, 238],
640
                'palevioletred'        => [219, 112, 147],
641
                'papayawhip'           => [255, 239, 213],
642
                'peachpuff'            => [255, 218, 185],
643
                'peru'                 => [205, 133, 63],
644
                'pink'                 => [255, 192, 203],
645
                'plum'                 => [221, 160, 221],
646
                'powderblue'           => [176, 224, 230],
647
                'purple'               => [128, 0, 128],
648
                'red'                  => [255, 0, 0],
649
                'rosybrown'            => [188, 143, 143],
650
                'royalblue'            => [65, 105, 225],
651
                'saddlebrown'          => [139, 69, 19],
652
                'salmon'               => [250, 128, 114],
653
                'sandybrown'           => [244, 164, 96],
654
                'seagreen'             => [46, 139, 87],
655
                'seashell'             => [255, 245, 238],
656
                'sienna'               => [160, 82, 45],
657
                'silver'               => [192, 192, 192],
658
                'skyblue'              => [135, 206, 235],
659
                'slateblue'            => [106, 90, 205],
660
                'slategray'            => [112, 128, 144],
661
                'snow'                 => [255, 250, 250],
662
                'springgreen'          => [0, 255, 127],
663
                'steelblue'            => [70, 130, 180],
664
                'tan'                  => [210, 180, 140],
665
                'teal'                 => [0, 128, 128],
666
                'thistle'              => [216, 191, 216],
667
                'tomato'               => [255, 99, 71],
668
                'turquoise'            => [64, 224, 208],
669
                'violet'               => [238, 130, 238],
670
                'wheat'                => [245, 222, 179],
671
                'white'                => [255, 255, 255],
672
                'whitesmoke'           => [245, 245, 245],
673
                'yellow'               => [255, 255, 0],
674
                'yellowgreen'          => [154, 205, 50]
675
            ];
676
        }
677
678
        $color = strtolower($color);
679
680
        if (isset($colornames[$color])) {
681
            return $colornames[$color];
682
        }
683
684
        return [0, 0, 0];
685
    }
686
687
    /**
688
     * Convert an RGB percentage string into an RGB array.
689
     *
690
     * @param string $color Percentage color string like "50%,20%,100%".
691
     *
692
     * @return array RGB color array.
693
     * @access  public
694
     * @static
695
     */
696
    public function percentageColor2RGB($color)
697
    {
698
        // remove spaces
699
        $color = str_replace(' ', '', $color);
700
        // remove the percent signs
701
        $color = str_replace('%', '', $color);
702
        // split the string by commas
703
        $color = explode(',', $color);
704
705
        $ret = [];
706
        foreach ($color as $k => $v) {
707
            // range checks
708
            if ($v <= 0) {
709
                $ret[$k] = 0;
710
            } elseif ($v <= 100) {
711
                // add 0.5 then cast to an integer to round the value.
712
                $ret[$k] = (integer)((2.55 * $v) + 0.5);
713
            } else {
714
                $ret[$k] = 255;
715
            }
716
        }
717
718
        return $ret;
719
    }
720
}
721
722
// For Array Walk
723
// {{{
724
/**
725
 * Function for array_walk() to round colors to the closest web safe value.
726
 *
727
 * @param integer $color One channel of an RGB color.
728
 *
729
 * @return integer The websafe equivalent of the color channel.
730
 * @author  Jason Lotito <[email protected]>
731
 * @author  Andrew Morton <[email protected]>
732
 * @access  private
733
 * @static
734
 */
735
function _makeWebSafe(&$color)
736
{
737
    if ($color < 0x1a) {
738
        $color = 0x00;
739
    } elseif ($color < 0x4d) {
740
        $color = 0x33;
741
    } elseif ($color < 0x80) {
742
        $color = 0x66;
743
    } elseif ($color < 0xB3) {
744
        $color = 0x99;
745
    } elseif ($color < 0xE6) {
746
        $color = 0xCC;
747
    } else {
748
        $color = 0xFF;
749
    }
750
751
    return $color;
752
}
753
// }}}
754