Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]

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