PluginProbe
Depicter — Popup & Slider Builder / trunk
Depicter — Popup & Slider Builder vtrunk
4.8.1 trunk 1.0.0 1.1.0 1.1.2 1.1.4 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.5 1.3.8 1.5.0 1.5.1 1.5.2 1.5.5 1.6.0 1.6.1 1.6.2 1.7.0 All 76 releases
depicter / vendor / symfony / console / Color.php

Color.php in Depicter — Popup & Slider Builder trunk, at vendor/symfony/console/Color.php

181 lines 5.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.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
12 namespace Symfony\Component\Console;
13
14 use Symfony\Component\Console\Exception\InvalidArgumentException;
15
16 /**
17 * @author Fabien Potencier <fabien@symfony.com>
18 */
19 final class Color
20 {
21 private const COLORS = [
22 'black' => 0,
23 'red' => 1,
24 'green' => 2,
25 'yellow' => 3,
26 'blue' => 4,
27 'magenta' => 5,
28 'cyan' => 6,
29 'white' => 7,
30 'default' => 9,
31 ];
32
33 private const BRIGHT_COLORS = [
34 'gray' => 0,
35 'bright-red' => 1,
36 'bright-green' => 2,
37 'bright-yellow' => 3,
38 'bright-blue' => 4,
39 'bright-magenta' => 5,
40 'bright-cyan' => 6,
41 'bright-white' => 7,
42 ];
43
44 private const AVAILABLE_OPTIONS = [
45 'bold' => ['set' => 1, 'unset' => 22],
46 'underscore' => ['set' => 4, 'unset' => 24],
47 'blink' => ['set' => 5, 'unset' => 25],
48 'reverse' => ['set' => 7, 'unset' => 27],
49 'conceal' => ['set' => 8, 'unset' => 28],
50 ];
51
52 private $foreground;
53 private $background;
54 private $options = [];
55
56 public function __construct(string $foreground = '', string $background = '', array $options = [])
57 {
58 $this->foreground = $this->parseColor($foreground);
59 $this->background = $this->parseColor($background, true);
60
61 foreach ($options as $option) {
62 if (!isset(self::AVAILABLE_OPTIONS[$option])) {
63 throw new InvalidArgumentException(sprintf('Invalid option specified: "%s". Expected one of (%s).', $option, implode(', ', array_keys(self::AVAILABLE_OPTIONS))));
64 }
65
66 $this->options[$option] = self::AVAILABLE_OPTIONS[$option];
67 }
68 }
69
70 public function apply(string $text): string
71 {
72 return $this->set().$text.$this->unset();
73 }
74
75 public function set(): string
76 {
77 $setCodes = [];
78 if ('' !== $this->foreground) {
79 $setCodes[] = $this->foreground;
80 }
81 if ('' !== $this->background) {
82 $setCodes[] = $this->background;
83 }
84 foreach ($this->options as $option) {
85 $setCodes[] = $option['set'];
86 }
87 if (0 === \count($setCodes)) {
88 return '';
89 }
90
91 return sprintf("\033[%sm", implode(';', $setCodes));
92 }
93
94 public function unset(): string
95 {
96 $unsetCodes = [];
97 if ('' !== $this->foreground) {
98 $unsetCodes[] = 39;
99 }
100 if ('' !== $this->background) {
101 $unsetCodes[] = 49;
102 }
103 foreach ($this->options as $option) {
104 $unsetCodes[] = $option['unset'];
105 }
106 if (0 === \count($unsetCodes)) {
107 return '';
108 }
109
110 return sprintf("\033[%sm", implode(';', $unsetCodes));
111 }
112
113 private function parseColor(string $color, bool $background = false): string
114 {
115 if ('' === $color) {
116 return '';
117 }
118
119 if ('#' === $color[0]) {
120 $color = substr($color, 1);
121
122 if (3 === \strlen($color)) {
123 $color = $color[0].$color[0].$color[1].$color[1].$color[2].$color[2];
124 }
125
126 if (6 !== \strlen($color)) {
127 throw new InvalidArgumentException(sprintf('Invalid "%s" color.', $color));
128 }
129
130 return ($background ? '4' : '3').$this->convertHexColorToAnsi(hexdec($color));
131 }
132
133 if (isset(self::COLORS[$color])) {
134 return ($background ? '4' : '3').self::COLORS[$color];
135 }
136
137 if (isset(self::BRIGHT_COLORS[$color])) {
138 return ($background ? '10' : '9').self::BRIGHT_COLORS[$color];
139 }
140
141 throw new InvalidArgumentException(sprintf('Invalid "%s" color; expected one of (%s).', $color, implode(', ', array_merge(array_keys(self::COLORS), array_keys(self::BRIGHT_COLORS)))));
142 }
143
144 private function convertHexColorToAnsi(int $color): string
145 {
146 $r = ($color >> 16) & 255;
147 $g = ($color >> 8) & 255;
148 $b = $color & 255;
149
150 // see https://github.com/termstandard/colors/ for more information about true color support
151 if ('truecolor' !== getenv('COLORTERM')) {
152 return (string) $this->degradeHexColorToAnsi($r, $g, $b);
153 }
154
155 return sprintf('8;2;%d;%d;%d', $r, $g, $b);
156 }
157
158 private function degradeHexColorToAnsi(int $r, int $g, int $b): int
159 {
160 if (0 === round($this->getSaturation($r, $g, $b) / 50)) {
161 return 0;
162 }
163
164 return (round($b / 255) << 2) | (round($g / 255) << 1) | round($r / 255);
165 }
166
167 private function getSaturation(int $r, int $g, int $b): int
168 {
169 $r = $r / 255;
170 $g = $g / 255;
171 $b = $b / 255;
172 $v = max($r, $g, $b);
173
174 if (0 === $diff = $v - min($r, $g, $b)) {
175 return 0;
176 }
177
178 return (int) $diff * 100 / $v;
179 }
180 }
181