You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nextcloud-server/lib/public/Color.php

151 lines
3.9 KiB

<?php
/**
* @copyright Copyright (c) 2016, John Molakvoæ <skjnldsv@protonmail.com>
*
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author Morris Jobke <hey@morrisjobke.de>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCP;
/**
* Simple RGB color container
* @since 25.0.0
*/
class Color {
private int $r;
private int $g;
private int $b;
/**
* @since 25.0.0
*/
public function __construct($r, $g, $b) {
$this->r = $r;
$this->g = $g;
$this->b = $b;
}
/**
* Returns the red color component of this color as an int from 0 to 255
*
* @since 25.0.0
*/
public function red(): int {
return $this->r;
}
/**
* Returns the red color component of this color as a float from 0 to 1
*
* @since 25.0.0
*/
public function redF(): float {
return $this->r / 255;
}
/**
* Returns the green color component of this color as an int from 0 to 255
*
* @since 25.0.0
*/
public function green(): int {
return $this->g;
}
/**
* Returns the green color component of this color as a float from 0 to 1
*
* @since 25.0.0
*/
public function greenF(): float {
return $this->g / 255;
}
/**
* Returns the green blue component of this color as an int from 0 to 255
*
* @since 25.0.0
*/
public function blue(): int {
return $this->b;
}
/**
* Returns the blue color component of this color as a float from 0 to 1
*
* @since 25.0.0
*/
public function blueF(): float {
return $this->g / 255;
}
/**
* Returns the name of the color in the format "#RRGGBB"; i.e. a "#" character followed by three two-digit hexadecimal numbers.
*
* @since 25.0.0
*/
public function name(): string {
return sprintf("#%02x%02x%02x", $this->r, $this->g, $this->b);
}
/**
* Mix two colors
*
* @param int $steps the number of intermediate colors that should be generated for the palette
* @param Color $color1 the first color
* @param Color $color2 the second color
* @return list<Color>
* @since 25.0.0
*/
public static function mixPalette(int $steps, Color $color1, Color $color2): array {
$palette = [$color1];
$step = self::stepCalc($steps, [$color1, $color2]);
for ($i = 1; $i < $steps; $i++) {
$r = intval($color1->red() + ($step[0] * $i));
$g = intval($color1->green() + ($step[1] * $i));
$b = intval($color1->blue() + ($step[2] * $i));
$palette[] = new Color($r, $g, $b);
}
return $palette;
}
public function alphaBlending(float $opacity, Color $source): Color {
return new Color(
(int)((1 - $opacity) * $source->red() + $opacity * $this->red()),
(int)((1 - $opacity) * $source->green() + $opacity * $this->green()),
(int)((1 - $opacity) * $source->blue() + $opacity * $this->blue())
);
}
/**
* Calculate steps between two Colors
* @param int $steps start color
* @param Color[] $ends end color
* @return array{0: int, 1: int, 2: int} [r,g,b] steps for each color to go from $steps to $ends
* @since 25.0.0
*/
private static function stepCalc(int $steps, array $ends): array {
$step = [];
$step[0] = ($ends[1]->red() - $ends[0]->red()) / $steps;
$step[1] = ($ends[1]->green() - $ends[0]->green()) / $steps;
$step[2] = ($ends[1]->blue() - $ends[0]->blue()) / $steps;
return $step;
}
}