Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
 
3
namespace PhpOffice\PhpSpreadsheet\Style;
4
 
5
class Color extends Supervisor
6
{
7
    const NAMED_COLORS = [
8
        'Black',
9
        'White',
10
        'Red',
11
        'Green',
12
        'Blue',
13
        'Yellow',
14
        'Magenta',
15
        'Cyan',
16
    ];
17
 
18
    // Colors
19
    const COLOR_BLACK = 'FF000000';
20
    const COLOR_WHITE = 'FFFFFFFF';
21
    const COLOR_RED = 'FFFF0000';
22
    const COLOR_DARKRED = 'FF800000';
23
    const COLOR_BLUE = 'FF0000FF';
24
    const COLOR_DARKBLUE = 'FF000080';
25
    const COLOR_GREEN = 'FF00FF00';
26
    const COLOR_DARKGREEN = 'FF008000';
27
    const COLOR_YELLOW = 'FFFFFF00';
28
    const COLOR_DARKYELLOW = 'FF808000';
29
    const COLOR_MAGENTA = 'FFFF00FF';
30
    const COLOR_CYAN = 'FF00FFFF';
31
 
32
    const NAMED_COLOR_TRANSLATIONS = [
33
        'Black' => self::COLOR_BLACK,
34
        'White' => self::COLOR_WHITE,
35
        'Red' => self::COLOR_RED,
36
        'Green' => self::COLOR_GREEN,
37
        'Blue' => self::COLOR_BLUE,
38
        'Yellow' => self::COLOR_YELLOW,
39
        'Magenta' => self::COLOR_MAGENTA,
40
        'Cyan' => self::COLOR_CYAN,
41
    ];
42
 
43
    const VALIDATE_ARGB_SIZE = 8;
44
    const VALIDATE_RGB_SIZE = 6;
45
    const VALIDATE_COLOR_6 = '/^[A-F0-9]{6}$/i';
46
    const VALIDATE_COLOR_8 = '/^[A-F0-9]{8}$/i';
47
 
48
    private const INDEXED_COLORS = [
49
        1 => 'FF000000', //  System Colour #1 - Black
50
        2 => 'FFFFFFFF', //  System Colour #2 - White
51
        3 => 'FFFF0000', //  System Colour #3 - Red
52
        4 => 'FF00FF00', //  System Colour #4 - Green
53
        5 => 'FF0000FF', //  System Colour #5 - Blue
54
        6 => 'FFFFFF00', //  System Colour #6 - Yellow
55
        7 => 'FFFF00FF', //  System Colour #7- Magenta
56
        8 => 'FF00FFFF', //  System Colour #8- Cyan
57
        9 => 'FF800000', //  Standard Colour #9
58
        10 => 'FF008000', //  Standard Colour #10
59
        11 => 'FF000080', //  Standard Colour #11
60
        12 => 'FF808000', //  Standard Colour #12
61
        13 => 'FF800080', //  Standard Colour #13
62
        14 => 'FF008080', //  Standard Colour #14
63
        15 => 'FFC0C0C0', //  Standard Colour #15
64
        16 => 'FF808080', //  Standard Colour #16
65
        17 => 'FF9999FF', //  Chart Fill Colour #17
66
        18 => 'FF993366', //  Chart Fill Colour #18
67
        19 => 'FFFFFFCC', //  Chart Fill Colour #19
68
        20 => 'FFCCFFFF', //  Chart Fill Colour #20
69
        21 => 'FF660066', //  Chart Fill Colour #21
70
        22 => 'FFFF8080', //  Chart Fill Colour #22
71
        23 => 'FF0066CC', //  Chart Fill Colour #23
72
        24 => 'FFCCCCFF', //  Chart Fill Colour #24
73
        25 => 'FF000080', //  Chart Line Colour #25
74
        26 => 'FFFF00FF', //  Chart Line Colour #26
75
        27 => 'FFFFFF00', //  Chart Line Colour #27
76
        28 => 'FF00FFFF', //  Chart Line Colour #28
77
        29 => 'FF800080', //  Chart Line Colour #29
78
        30 => 'FF800000', //  Chart Line Colour #30
79
        31 => 'FF008080', //  Chart Line Colour #31
80
        32 => 'FF0000FF', //  Chart Line Colour #32
81
        33 => 'FF00CCFF', //  Standard Colour #33
82
        34 => 'FFCCFFFF', //  Standard Colour #34
83
        35 => 'FFCCFFCC', //  Standard Colour #35
84
        36 => 'FFFFFF99', //  Standard Colour #36
85
        37 => 'FF99CCFF', //  Standard Colour #37
86
        38 => 'FFFF99CC', //  Standard Colour #38
87
        39 => 'FFCC99FF', //  Standard Colour #39
88
        40 => 'FFFFCC99', //  Standard Colour #40
89
        41 => 'FF3366FF', //  Standard Colour #41
90
        42 => 'FF33CCCC', //  Standard Colour #42
91
        43 => 'FF99CC00', //  Standard Colour #43
92
        44 => 'FFFFCC00', //  Standard Colour #44
93
        45 => 'FFFF9900', //  Standard Colour #45
94
        46 => 'FFFF6600', //  Standard Colour #46
95
        47 => 'FF666699', //  Standard Colour #47
96
        48 => 'FF969696', //  Standard Colour #48
97
        49 => 'FF003366', //  Standard Colour #49
98
        50 => 'FF339966', //  Standard Colour #50
99
        51 => 'FF003300', //  Standard Colour #51
100
        52 => 'FF333300', //  Standard Colour #52
101
        53 => 'FF993300', //  Standard Colour #53
102
        54 => 'FF993366', //  Standard Colour #54
103
        55 => 'FF333399', //  Standard Colour #55
104
        56 => 'FF333333', //  Standard Colour #56
105
    ];
106
 
107
    /**
108
     * ARGB - Alpha RGB.
109
     *
110
     * @var null|string
111
     */
112
    protected $argb;
113
 
114
    /** @var bool */
115
    private $hasChanged = false;
116
 
117
    /**
118
     * Create a new Color.
119
     *
120
     * @param string $colorValue ARGB value for the colour, or named colour
121
     * @param bool $isSupervisor Flag indicating if this is a supervisor or not
122
     *                                    Leave this value at default unless you understand exactly what
123
     *                                        its ramifications are
124
     * @param bool $isConditional Flag indicating if this is a conditional style or not
125
     *                                    Leave this value at default unless you understand exactly what
126
     *                                        its ramifications are
127
     */
128
    public function __construct($colorValue = self::COLOR_BLACK, $isSupervisor = false, $isConditional = false)
129
    {
130
        //    Supervisor?
131
        parent::__construct($isSupervisor);
132
 
133
        //    Initialise values
134
        if (!$isConditional) {
135
            $this->argb = $this->validateColor($colorValue) ?: self::COLOR_BLACK;
136
        }
137
    }
138
 
139
    /**
140
     * Get the shared style component for the currently active cell in currently active sheet.
141
     * Only used for style supervisor.
142
     *
143
     * @return Color
144
     */
145
    public function getSharedComponent()
146
    {
147
        /** @var Style */
148
        $parent = $this->parent;
149
        /** @var Border|Fill $sharedComponent */
150
        $sharedComponent = $parent->getSharedComponent();
151
        if ($sharedComponent instanceof Fill) {
152
            if ($this->parentPropertyName === 'endColor') {
153
                return $sharedComponent->getEndColor();
154
            }
155
 
156
            return $sharedComponent->getStartColor();
157
        }
158
 
159
        return $sharedComponent->getColor();
160
    }
161
 
162
    /**
163
     * Build style array from subcomponents.
164
     *
165
     * @param array $array
166
     *
167
     * @return array
168
     */
169
    public function getStyleArray($array)
170
    {
171
        /** @var Style */
172
        $parent = $this->parent;
173
 
174
        return $parent->/** @scrutinizer ignore-call */ getStyleArray([$this->parentPropertyName => $array]);
175
    }
176
 
177
    /**
178
     * Apply styles from array.
179
     *
180
     * <code>
181
     * $spreadsheet->getActiveSheet()->getStyle('B2')->getFont()->getColor()->applyFromArray(['rgb' => '808080']);
182
     * </code>
183
     *
184
     * @param array $styleArray Array containing style information
185
     *
186
     * @return $this
187
     */
188
    public function applyFromArray(array $styleArray)
189
    {
190
        if ($this->isSupervisor) {
191
            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($styleArray));
192
        } else {
193
            if (isset($styleArray['rgb'])) {
194
                $this->setRGB($styleArray['rgb']);
195
            }
196
            if (isset($styleArray['argb'])) {
197
                $this->setARGB($styleArray['argb']);
198
            }
199
        }
200
 
201
        return $this;
202
    }
203
 
204
    private function validateColor(?string $colorValue): string
205
    {
206
        if ($colorValue === null || $colorValue === '') {
207
            return self::COLOR_BLACK;
208
        }
209
        $named = ucfirst(strtolower($colorValue));
210
        if (array_key_exists($named, self::NAMED_COLOR_TRANSLATIONS)) {
211
            return self::NAMED_COLOR_TRANSLATIONS[$named];
212
        }
213
        if (preg_match(self::VALIDATE_COLOR_8, $colorValue) === 1) {
214
            return $colorValue;
215
        }
216
        if (preg_match(self::VALIDATE_COLOR_6, $colorValue) === 1) {
217
            return 'FF' . $colorValue;
218
        }
219
 
220
        return '';
221
    }
222
 
223
    /**
224
     * Get ARGB.
225
     */
226
    public function getARGB(): ?string
227
    {
228
        if ($this->isSupervisor) {
229
            return $this->getSharedComponent()->getARGB();
230
        }
231
 
232
        return $this->argb;
233
    }
234
 
235
    /**
236
     * Set ARGB.
237
     *
238
     * @param string $colorValue  ARGB value, or a named color
239
     *
240
     * @return $this
241
     */
242
    public function setARGB(?string $colorValue = self::COLOR_BLACK)
243
    {
244
        $this->hasChanged = true;
245
        $colorValue = $this->validateColor($colorValue);
246
        if ($colorValue === '') {
247
            return $this;
248
        }
249
 
250
        if ($this->isSupervisor) {
251
            $styleArray = $this->getStyleArray(['argb' => $colorValue]);
252
            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);
253
        } else {
254
            $this->argb = $colorValue;
255
        }
256
 
257
        return $this;
258
    }
259
 
260
    /**
261
     * Get RGB.
262
     */
263
    public function getRGB(): string
264
    {
265
        if ($this->isSupervisor) {
266
            return $this->getSharedComponent()->getRGB();
267
        }
268
 
269
        return substr($this->argb ?? '', 2);
270
    }
271
 
272
    /**
273
     * Set RGB.
274
     *
275
     * @param string $colorValue RGB value, or a named color
276
     *
277
     * @return $this
278
     */
279
    public function setRGB(?string $colorValue = self::COLOR_BLACK)
280
    {
281
        return $this->setARGB($colorValue);
282
    }
283
 
284
    /**
285
     * Get a specified colour component of an RGB value.
286
     *
287
     * @param string $rgbValue The colour as an RGB value (e.g. FF00CCCC or CCDDEE
288
     * @param int $offset Position within the RGB value to extract
289
     * @param bool $hex Flag indicating whether the component should be returned as a hex or a
290
     *                                    decimal value
291
     *
292
     * @return int|string The extracted colour component
293
     */
294
    private static function getColourComponent($rgbValue, $offset, $hex = true)
295
    {
296
        $colour = substr($rgbValue, $offset, 2) ?: '';
297
        if (preg_match('/^[0-9a-f]{2}$/i', $colour) !== 1) {
298
            $colour = '00';
299
        }
300
 
301
        return ($hex) ? $colour : (int) hexdec($colour);
302
    }
303
 
304
    /**
305
     * Get the red colour component of an RGB value.
306
     *
307
     * @param string $rgbValue The colour as an RGB value (e.g. FF00CCCC or CCDDEE
308
     * @param bool $hex Flag indicating whether the component should be returned as a hex or a
309
     *                                    decimal value
310
     *
311
     * @return int|string The red colour component
312
     */
313
    public static function getRed($rgbValue, $hex = true)
314
    {
315
        return self::getColourComponent($rgbValue, strlen($rgbValue) - 6, $hex);
316
    }
317
 
318
    /**
319
     * Get the green colour component of an RGB value.
320
     *
321
     * @param string $rgbValue The colour as an RGB value (e.g. FF00CCCC or CCDDEE
322
     * @param bool $hex Flag indicating whether the component should be returned as a hex or a
323
     *                                    decimal value
324
     *
325
     * @return int|string The green colour component
326
     */
327
    public static function getGreen($rgbValue, $hex = true)
328
    {
329
        return self::getColourComponent($rgbValue, strlen($rgbValue) - 4, $hex);
330
    }
331
 
332
    /**
333
     * Get the blue colour component of an RGB value.
334
     *
335
     * @param string $rgbValue The colour as an RGB value (e.g. FF00CCCC or CCDDEE
336
     * @param bool $hex Flag indicating whether the component should be returned as a hex or a
337
     *                                    decimal value
338
     *
339
     * @return int|string The blue colour component
340
     */
341
    public static function getBlue($rgbValue, $hex = true)
342
    {
343
        return self::getColourComponent($rgbValue, strlen($rgbValue) - 2, $hex);
344
    }
345
 
346
    /**
347
     * Adjust the brightness of a color.
348
     *
349
     * @param string $hexColourValue The colour as an RGBA or RGB value (e.g. FF00CCCC or CCDDEE)
350
     * @param float $adjustPercentage The percentage by which to adjust the colour as a float from -1 to 1
351
     *
352
     * @return string The adjusted colour as an RGBA or RGB value (e.g. FF00CCCC or CCDDEE)
353
     */
354
    public static function changeBrightness($hexColourValue, $adjustPercentage)
355
    {
356
        $rgba = (strlen($hexColourValue) === 8);
357
        $adjustPercentage = max(-1.0, min(1.0, $adjustPercentage));
358
 
359
        /** @var int $red */
360
        $red = self::getRed($hexColourValue, false);
361
        /** @var int $green */
362
        $green = self::getGreen($hexColourValue, false);
363
        /** @var int $blue */
364
        $blue = self::getBlue($hexColourValue, false);
365
 
366
        return (($rgba) ? 'FF' : '') . RgbTint::rgbAndTintToRgb($red, $green, $blue, $adjustPercentage);
367
    }
368
 
369
    /**
370
     * Get indexed color.
371
     *
372
     * @param int $colorIndex Index entry point into the colour array
373
     * @param bool $background Flag to indicate whether default background or foreground colour
374
     *                                            should be returned if the indexed colour doesn't exist
375
     */
376
    public static function indexedColor($colorIndex, $background = false, ?array $palette = null): self
377
    {
378
        // Clean parameter
379
        $colorIndex = (int) $colorIndex;
380
 
381
        if (empty($palette)) {
382
            if (isset(self::INDEXED_COLORS[$colorIndex])) {
383
                return new self(self::INDEXED_COLORS[$colorIndex]);
384
            }
385
        } else {
386
            if (isset($palette[$colorIndex])) {
387
                return new self($palette[$colorIndex]);
388
            }
389
        }
390
 
391
        return ($background) ? new self(self::COLOR_WHITE) : new self(self::COLOR_BLACK);
392
    }
393
 
394
    /**
395
     * Get hash code.
396
     *
397
     * @return string Hash code
398
     */
399
    public function getHashCode(): string
400
    {
401
        if ($this->isSupervisor) {
402
            return $this->getSharedComponent()->getHashCode();
403
        }
404
 
405
        return md5(
406
            $this->argb .
407
            __CLASS__
408
        );
409
    }
410
 
411
    protected function exportArray1(): array
412
    {
413
        $exportedArray = [];
414
        $this->exportArray2($exportedArray, 'argb', $this->getARGB());
415
 
416
        return $exportedArray;
417
    }
418
 
419
    public function getHasChanged(): bool
420
    {
421
        if ($this->isSupervisor) {
422
            return $this->getSharedComponent()->hasChanged;
423
        }
424
 
425
        return $this->hasChanged;
426
    }
427
}