Add Color class
This commit is contained in:
parent
f81d27060a
commit
26294b3fa0
1 changed files with 300 additions and 0 deletions
300
base/src/main/java/de/staropensource/engine/base/type/Color.java
Normal file
300
base/src/main/java/de/staropensource/engine/base/type/Color.java
Normal file
|
@ -0,0 +1,300 @@
|
|||
/*
|
||||
* STAROPENSOURCE ENGINE SOURCE FILE
|
||||
* Copyright (c) 2024 The StarOpenSource Engine Authors
|
||||
* Licensed under the GNU Affero General Public License v3
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.staropensource.engine.base.type;
|
||||
|
||||
import de.staropensource.engine.base.EngineConfiguration;
|
||||
import de.staropensource.engine.base.utility.Math;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.SneakyThrows;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Range;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.HexFormat;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* A class dedicated to colors.
|
||||
* Uses the RGBA format, but can also interpret
|
||||
* the RGB, HEX and HSV color formats.
|
||||
*
|
||||
* @since v1-alpha6
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@SuppressWarnings({ "JavadocDeclaration" })
|
||||
public final class Color {
|
||||
/**
|
||||
* Contains the red color value.
|
||||
*
|
||||
* @since v1-alpha6
|
||||
* -- GETTER --
|
||||
* Returns the red color value.
|
||||
*
|
||||
* @return red color value
|
||||
* @since v1-alpha6
|
||||
* -- SETTER --
|
||||
* Sets the red color value.
|
||||
*
|
||||
* @param red new red color value
|
||||
* @since v1-alpha6
|
||||
*/
|
||||
private @Range(from = 0, to = 255) int red;
|
||||
/**
|
||||
* Contains the green color value.
|
||||
*
|
||||
* @since v1-alpha6
|
||||
* -- GETTER --
|
||||
* Returns the green color value.
|
||||
*
|
||||
* @return green color value
|
||||
* @since v1-alpha6
|
||||
* -- SETTER --
|
||||
* Sets the green color value.
|
||||
*
|
||||
* @param green new green color value
|
||||
* @since v1-alpha6
|
||||
*/
|
||||
private @Range(from = 0, to = 255) int green;
|
||||
/**
|
||||
* Contains the blue color value.
|
||||
*
|
||||
* @since v1-alpha6
|
||||
* -- GETTER --
|
||||
* Returns the blue color value.
|
||||
*
|
||||
* @return blue color value
|
||||
* @since v1-alpha6
|
||||
* -- SETTER --
|
||||
* Sets the blue color value.
|
||||
*
|
||||
* @param blue new blue color value
|
||||
* @since v1-alpha6
|
||||
*/
|
||||
private @Range(from = 0, to = 255) int blue;
|
||||
/**
|
||||
* Contains the alpha channel value.
|
||||
*
|
||||
* @since v1-alpha6
|
||||
* -- GETTER --
|
||||
* Returns the alpha channel value.
|
||||
*
|
||||
* @return alpha channel value
|
||||
* @since v1-alpha6
|
||||
* -- SETTER --
|
||||
* Sets the alpha channel value.
|
||||
*
|
||||
* @param red new alpha channel value
|
||||
* @since v1-alpha6
|
||||
*/
|
||||
private @Range(from = 0, to = 255) int alpha;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param red red color value
|
||||
* @param green green color value
|
||||
* @param blue blue color value
|
||||
* @param alpha alpha channel value
|
||||
* @since v1-alpha6
|
||||
*/
|
||||
private Color(int red, int green, int blue, int alpha) {
|
||||
this.red = Math.boundNumber(0, 255, red);
|
||||
this.green = Math.boundNumber(0, 255, green);
|
||||
this.blue = Math.boundNumber(0, 255, blue);
|
||||
this.alpha = Math.boundNumber(0, 255, alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the a set of numbers in
|
||||
* the RGBA format into a new instance.
|
||||
*
|
||||
* @param red red color value
|
||||
* @param blue blue color value
|
||||
* @param green green color value
|
||||
* @param alpha alpha color value
|
||||
* @return new {@link Color} instance
|
||||
* @since v1-alpha6
|
||||
*/
|
||||
public static @NotNull Color fromRGBA(@Range(from = 0, to = 255) int red, @Range(from = 0, to = 255) int green,
|
||||
@Range(from = 0, to = 255) int blue, @Range(from = 0, to = 255) int alpha) {
|
||||
return new Color(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the an array of numbers in
|
||||
* the RGBA format into a new instance.
|
||||
*
|
||||
* @param intArray integer array
|
||||
* @return new {@link Color} instance
|
||||
* @throws IndexOutOfBoundsException if the array contains more or less than four integers
|
||||
* @since v1-alpha6
|
||||
*/
|
||||
public static @NotNull Color fromRGBA(int @NotNull [] intArray) {
|
||||
if (intArray.length != 4)
|
||||
throw new StringIndexOutOfBoundsException("Can't contains more or less than four integers");
|
||||
|
||||
return new Color(intArray[0], intArray[1], intArray[2], intArray[3]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the a set of numbers in
|
||||
* the RGB format into a new instance.
|
||||
*
|
||||
* @param red red color value
|
||||
* @param blue blue color value
|
||||
* @param green green color value
|
||||
* @return new {@link Color} instance
|
||||
* @since v1-alpha6
|
||||
*/
|
||||
public static @NotNull Color fromRGB(@Range(from = 0, to = 255) int red, @Range(from = 0, to = 255) int green,
|
||||
@Range(from = 0, to = 255) int blue) {
|
||||
return new Color(red, green, blue, 255);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the an array of numbers in
|
||||
* the RGBA format into a new instance.
|
||||
*
|
||||
* @param intArray integer array
|
||||
* @return new {@link Color} instance
|
||||
* @throws IndexOutOfBoundsException if the array contains more or less than four integers
|
||||
* @since v1-alpha6
|
||||
*/
|
||||
public static @NotNull Color fromRGB(int @NotNull [] intArray) {
|
||||
if (intArray.length != 3)
|
||||
throw new StringIndexOutOfBoundsException("Can't contains more or less than four integers");
|
||||
|
||||
return new Color(intArray[0], intArray[1], intArray[2], 255);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an array of bytes into a new instance.
|
||||
*
|
||||
* @param bytes byte array
|
||||
* @return new {@link Color} instance
|
||||
* @throws IndexOutOfBoundsException if the array contains less than three or more than four bytes
|
||||
* @since v1-alpha6
|
||||
*/
|
||||
public static @NotNull Color fromBytes(byte @NotNull [] bytes) throws IndexOutOfBoundsException {
|
||||
if (bytes.length == 3)
|
||||
return new Color(bytes[0] & 0xFF, bytes[1] & 0xFF, bytes[2] & 0xFF, 255);
|
||||
else if (bytes.length == 4)
|
||||
return new Color(bytes[0] & 0xFF, bytes[1] & 0xFF, bytes[2] & 0xFF, bytes[3] & 0xFF);
|
||||
else
|
||||
throw new StringIndexOutOfBoundsException("Can't contain less than three or more than four bytes");
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a hex string into a new instance.
|
||||
*
|
||||
* @param hexString hex string
|
||||
* @return new {@link Color} instance
|
||||
* @throws IndexOutOfBoundsException if the string contains less than three or more than four bytes
|
||||
* @since v1-alpha6
|
||||
*/
|
||||
public static @NotNull Color fromHex(@NotNull String hexString) throws IndexOutOfBoundsException {
|
||||
return fromBytes(HexFormat.of().parseHex(hexString));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an identical copy of this instance.
|
||||
*
|
||||
* @return identical copy
|
||||
* @since v1-alpha6
|
||||
*/
|
||||
@SneakyThrows
|
||||
public @NotNull Color clone() {
|
||||
return (Color) super.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this instance.
|
||||
*
|
||||
* @return string representation
|
||||
* @since v1-alpha6
|
||||
*/
|
||||
@Override
|
||||
public @NotNull String toString() {
|
||||
return (EngineConfiguration.getInstance().isHideFullTypePath()
|
||||
? getClass().getName().replace(getClass().getPackage() + ".", "")
|
||||
: getClass().getName())
|
||||
+ "(r=" + red + " g=" + green + " b=" + blue + " a=" + alpha + ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the colors represented by
|
||||
* this instance into an integer array
|
||||
* in the RGBA format.
|
||||
*
|
||||
* @return {@code int} array with RGBA values
|
||||
* @since v1-alpha6
|
||||
*/
|
||||
public int @NotNull [] toRGBA() {
|
||||
return new int[]{ red, green, blue, alpha };
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the colors represented by
|
||||
* this instance into an integer array
|
||||
* in the RGB format.
|
||||
*
|
||||
* @return {@code int} array with RGB values
|
||||
* @since v1-alpha6
|
||||
*/
|
||||
public int @NotNull [] toRGB() {
|
||||
return new int[]{ red, green, blue };
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the colors represented by
|
||||
* this instance into a byte array.
|
||||
*
|
||||
* @param includeAlpha whether to include alpha or not
|
||||
* @return RGBA or RGB format as a byte array
|
||||
* @since v1-alpha6
|
||||
*/
|
||||
public byte @NotNull [] toBytes(boolean includeAlpha) {
|
||||
ByteBuffer buffer = ByteBuffer.allocate(includeAlpha ? 4 : 3);
|
||||
|
||||
buffer
|
||||
.put((byte) red)
|
||||
.put((byte) green)
|
||||
.put((byte) blue);
|
||||
|
||||
if (includeAlpha)
|
||||
buffer.put((byte) alpha);
|
||||
|
||||
return buffer.array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the colors represented by
|
||||
* this instance into the hex format.
|
||||
*
|
||||
* @param includeAlpha whether to include alpha or not
|
||||
* @return RGBA or RGB format as a hex string
|
||||
* @since v1-alpha6
|
||||
*/
|
||||
public @NotNull String toHex(boolean includeAlpha) {
|
||||
return HexFormat.of().formatHex(toBytes(includeAlpha)).toUpperCase(Locale.ROOT);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue