PluginProbe
TablePress – Tables in WordPress made easy / 3.4
TablePress – Tables in WordPress made easy v3.4
3.4 3.3.4 3.3.3 3.3.2 3.3.1 trunk 1.12 1.14 1.9.2 2.0.4 2.1.7 2.1.8 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3 2.3.1 2.3.2 2.4 2.4.1 2.4.2 2.4.3 All 45 releases
tablepress / libraries / vendor / PhpSpreadsheet / Style / RgbTint.php

RgbTint.php in TablePress – Tables in WordPress made easy 3.4, at libraries/vendor/PhpSpreadsheet/Style/RgbTint.php

173 lines 4.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace TablePress\PhpOffice\PhpSpreadsheet\Style;
4
5 /**
6 * Class to handle tint applied to color.
7 * Code borrows heavily from some Python projects.
8 *
9 * @see https://docs.python.org/3/library/colorsys.html
10 * @see https://gist.github.com/Mike-Honey/b36e651e9a7f1d2e1d60ce1c63b9b633
11 */
12 class RgbTint
13 {
14 private const ONE_THIRD = 1.0 / 3.0;
15 private const ONE_SIXTH = 1.0 / 6.0;
16 private const TWO_THIRD = 2.0 / 3.0;
17 private const RGBMAX = 255.0;
18 /**
19 * MS Excel's tint function expects that HLS is base 240.
20 *
21 * @see https://social.msdn.microsoft.com/Forums/en-US/e9d8c136-6d62-4098-9b1b-dac786149f43/excel-color-tint-algorithm-incorrect?forum=os_binaryfile#d3c2ac95-52e0-476b-86f1-e2a697f24969
22 */
23 private const HLSMAX = 240.0;
24
25 /**
26 * Convert red/green/blue to hue/luminance/saturation.
27 *
28 * @param float $red 0.0 through 1.0
29 * @param float $green 0.0 through 1.0
30 * @param float $blue 0.0 through 1.0
31 *
32 * @return float[]
33 */
34 private static function rgbToHls(float $red, float $green, float $blue): array
35 {
36 $maxc = max($red, $green, $blue);
37 $minc = min($red, $green, $blue);
38 $luminance = ($minc + $maxc) / 2.0;
39 if ($minc === $maxc) {
40 return [0.0, $luminance, 0.0];
41 }
42 $maxMinusMin = $maxc - $minc;
43 if ($luminance <= 0.5) {
44 $s = $maxMinusMin / ($maxc + $minc);
45 } else {
46 $s = $maxMinusMin / (2.0 - $maxc - $minc);
47 }
48 $rc = ($maxc - $red) / $maxMinusMin;
49 $gc = ($maxc - $green) / $maxMinusMin;
50 $bc = ($maxc - $blue) / $maxMinusMin;
51 if ($red === $maxc) {
52 $h = $bc - $gc;
53 } elseif ($green === $maxc) {
54 $h = 2.0 + $rc - $bc;
55 } else {
56 $h = 4.0 + $gc - $rc;
57 }
58 $h = self::positiveDecimalPart($h / 6.0);
59
60 return [$h, $luminance, $s];
61 }
62
63 /**
64 * Convert hue/luminance/saturation to red/green/blue.
65 *
66 * @param float $hue 0.0 through 1.0
67 * @param float $luminance 0.0 through 1.0
68 * @param float $saturation 0.0 through 1.0
69 *
70 * @return float[]
71 */
72 private static function hlsToRgb(float $hue, float $luminance, float $saturation): array
73 {
74 if ($saturation === 0.0) {
75 return [$luminance, $luminance, $luminance];
76 }
77 if ($luminance <= 0.5) {
78 $m2 = $luminance * (1.0 + $saturation);
79 } else {
80 $m2 = $luminance + $saturation - ($luminance * $saturation);
81 }
82 $m1 = 2.0 * $luminance - $m2;
83
84 return [
85 self::vFunction($m1, $m2, $hue + self::ONE_THIRD),
86 self::vFunction($m1, $m2, $hue),
87 self::vFunction($m1, $m2, $hue - self::ONE_THIRD),
88 ];
89 }
90
91 private static function vFunction(float $m1, float $m2, float $hue): float
92 {
93 $hue = self::positiveDecimalPart($hue);
94 if ($hue < self::ONE_SIXTH) {
95 return $m1 + ($m2 - $m1) * $hue * 6.0;
96 }
97 if ($hue < 0.5) {
98 return $m2;
99 }
100 if ($hue < self::TWO_THIRD) {
101 return $m1 + ($m2 - $m1) * (self::TWO_THIRD - $hue) * 6.0;
102 }
103
104 return $m1;
105 }
106
107 private static function positiveDecimalPart(float $hue): float
108 {
109 $hue = fmod($hue, 1.0);
110
111 return ($hue >= 0.0) ? $hue : (1.0 + $hue);
112 }
113
114 /**
115 * Convert red/green/blue to HLSMAX-based hue/luminance/saturation.
116 *
117 * @return int[]
118 */
119 private static function rgbToMsHls(int $red, int $green, int $blue): array
120 {
121 $red01 = $red / self::RGBMAX;
122 $green01 = $green / self::RGBMAX;
123 $blue01 = $blue / self::RGBMAX;
124 [$hue, $luminance, $saturation] = self::rgbToHls($red01, $green01, $blue01);
125
126 return [
127 (int) round($hue * self::HLSMAX),
128 (int) round($luminance * self::HLSMAX),
129 (int) round($saturation * self::HLSMAX),
130 ];
131 }
132
133 /**
134 * Converts HLSMAX based HLS values to rgb values in the range (0,1).
135 *
136 * @return float[]
137 */
138 private static function msHlsToRgb(int $hue, int $lightness, int $saturation): array
139 {
140 return self::hlsToRgb($hue / self::HLSMAX, $lightness / self::HLSMAX, $saturation / self::HLSMAX);
141 }
142
143 /**
144 * Tints HLSMAX based luminance.
145 *
146 * @see http://ciintelligence.blogspot.co.uk/2012/02/converting-excel-theme-color-and-tint.html
147 */
148 private static function tintLuminance(float $tint, float $luminance): int
149 {
150 if ($tint < 0) {
151 return (int) round($luminance * (1.0 + $tint));
152 }
153
154 return (int) round($luminance * (1.0 - $tint) + (self::HLSMAX - self::HLSMAX * (1.0 - $tint)));
155 }
156
157 /**
158 * Return result of tinting supplied rgb as 6 hex digits.
159 */
160 public static function rgbAndTintToRgb(int $red, int $green, int $blue, float $tint): string
161 {
162 [$hue, $luminance, $saturation] = self::rgbToMsHls($red, $green, $blue);
163 [$red, $green, $blue] = self::msHlsToRgb($hue, self::tintLuminance($tint, $luminance), $saturation);
164
165 return sprintf(
166 '%02X%02X%02X',
167 (int) round($red * self::RGBMAX),
168 (int) round($green * self::RGBMAX),
169 (int) round($blue * self::RGBMAX)
170 );
171 }
172 }
173