diff --git a/paper-api/src/main/java/org/bukkit/Color.java b/paper-api/src/main/java/org/bukkit/Color.java index 1720800720b4..ccc0e9ecde43 100644 --- a/paper-api/src/main/java/org/bukkit/Color.java +++ b/paper-api/src/main/java/org/bukkit/Color.java @@ -6,10 +6,12 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; +import net.kyori.adventure.util.ARGBLike; import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.SerializableAs; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Range; /** * A container for a color palette. This class is immutable; the set methods @@ -17,7 +19,7 @@ * but subject to change. */ @SerializableAs("Color") -public final class Color implements ConfigurationSerializable { +public final class Color implements ConfigurationSerializable, ARGBLike { private static final int BIT_MASK = 0xff; private static final int DEFAULT_ALPHA = 255; @@ -122,7 +124,12 @@ public final class Color implements ConfigurationSerializable { * @throws IllegalArgumentException if any value is strictly {@literal >255 or <0} */ @NotNull - public static Color fromARGB(int alpha, int red, int green, int blue) throws IllegalArgumentException { + public static Color fromARGB( + final @Range(from = 0, to = 255) int alpha, + final @Range(from = 0, to = 255) int red, + final @Range(from = 0, to = 255) int green, + final @Range(from = 0, to = 255) int blue + ) throws IllegalArgumentException { return new Color(alpha, red, green, blue); } @@ -136,7 +143,11 @@ public static Color fromARGB(int alpha, int red, int green, int blue) throws Ill * @throws IllegalArgumentException if any value is strictly {@literal >255 or <0} */ @NotNull - public static Color fromRGB(int red, int green, int blue) throws IllegalArgumentException { + public static Color fromRGB( + final @Range(from = 0, to = 255) int red, + final @Range(from = 0, to = 255) int green, + final @Range(from = 0, to = 255) int blue + ) throws IllegalArgumentException { return new Color(DEFAULT_ALPHA, red, green, blue); } @@ -150,7 +161,11 @@ public static Color fromRGB(int red, int green, int blue) throws IllegalArgument * @throws IllegalArgumentException if any value is strictly {@literal >255 or <0} */ @NotNull - public static Color fromBGR(int blue, int green, int red) throws IllegalArgumentException { + public static Color fromBGR( + final @Range(from = 0, to = 255) int blue, + final @Range(from = 0, to = 255) int green, + final @Range(from = 0, to = 255) int red + ) throws IllegalArgumentException { return new Color(DEFAULT_ALPHA, red, green, blue); } @@ -164,7 +179,7 @@ public static Color fromBGR(int blue, int green, int red) throws IllegalArgument * bits */ @NotNull - public static Color fromRGB(int rgb) throws IllegalArgumentException { + public static Color fromRGB(final int rgb) throws IllegalArgumentException { Preconditions.checkArgument((rgb >> 24) == 0, "Extraneous data in: %s", rgb); return fromRGB(rgb >> 16 & BIT_MASK, rgb >> 8 & BIT_MASK, rgb & BIT_MASK); } @@ -177,7 +192,7 @@ public static Color fromRGB(int rgb) throws IllegalArgumentException { * @return a new color object for specified values */ @NotNull - public static Color fromARGB(int argb) { + public static Color fromARGB(final int argb) { return fromARGB(argb >> 24 & BIT_MASK, argb >> 16 & BIT_MASK, argb >> 8 & BIT_MASK, argb & BIT_MASK); } @@ -191,16 +206,16 @@ public static Color fromARGB(int argb) { * bits */ @NotNull - public static Color fromBGR(int bgr) throws IllegalArgumentException { + public static Color fromBGR(final int bgr) throws IllegalArgumentException { Preconditions.checkArgument((bgr >> 24) == 0, "Extrenuous data in: %s", bgr); return fromBGR(bgr >> 16 & BIT_MASK, bgr >> 8 & BIT_MASK, bgr & BIT_MASK); } - private Color(int red, int green, int blue) { + private Color(final int red, final int green, final int blue) { this(DEFAULT_ALPHA, red, green, blue); } - private Color(int alpha, int red, int green, int blue) { + private Color(final int alpha, final int red, final int green, final int blue) { Preconditions.checkArgument(alpha >= 0 && alpha <= 0xff, "Alpha[%s] is not between 0-255", alpha); Preconditions.checkArgument(red >= 0 && red <= 0xff, "Red[%s] is not between 0-255", red); Preconditions.checkArgument(green >= 0 && green <= 0xff, "Green[%s] is not between 0-255", green); @@ -213,83 +228,123 @@ private Color(int alpha, int red, int green, int blue) { } /** - * Gets the alpha component + * Gets the alpha component. * * @return alpha component, from 0 to 255 */ - public int getAlpha() { + public @Range(from = 0, to = 255) int getAlpha() { return BIT_MASK & alpha; } /** - * Creates a new Color object with specified component + * Gets the alpha component. + * + * @return alpha component, from 0 to 255 + */ + @Override + public @Range(from = 0, to = 255) int alpha() { + return this.getAlpha(); + } + + /** + * Creates a new Color object with a specified component. * * @param alpha the alpha component, from 0 to 255 * @return a new color object with the alpha component */ @NotNull - public Color setAlpha(int alpha) { - return fromARGB(alpha, getRed(), getGreen(), getBlue()); + public Color setAlpha(final @Range(from = 0, to = 255) int alpha) { + return fromARGB(alpha, this.getRed(), this.getGreen(), this.getBlue()); } /** - * Gets the red component + * Gets the red component. * * @return red component, from 0 to 255 */ - public int getRed() { - return BIT_MASK & red; + public @Range(from = 0, to = 255) int getRed() { + return BIT_MASK & this.red; } /** - * Creates a new Color object with specified component + * Gets the red component. + * + * @return red component, from 0 to 255 + */ + @Override + public @Range(from = 0, to = 255) int red() { + return this.getRed(); + } + + /** + * Creates a new Color object with a specified component. * * @param red the red component, from 0 to 255 * @return a new color object with the red component */ @NotNull - public Color setRed(int red) { - return fromARGB(getAlpha(), red, getGreen(), getBlue()); + public Color setRed(final @Range(from = 0, to = 255) int red) { + return fromARGB(this.getAlpha(), red, this.getGreen(), this.getBlue()); + } + + /** + * Gets the green component. + * + * @return green component, from 0 to 255 + */ + public @Range(from = 0, to = 255) int getGreen() { + return BIT_MASK & this.green; } /** - * Gets the green component + * Gets the green component. * * @return green component, from 0 to 255 */ - public int getGreen() { - return BIT_MASK & green; + @Override + public @Range(from = 0, to = 255) int green() { + return this.getGreen(); } /** - * Creates a new Color object with specified component + * Creates a new Color object with a specified component. * * @param green the green component, from 0 to 255 * @return a new color object with the green component */ @NotNull - public Color setGreen(int green) { - return fromARGB(getAlpha(), getRed(), green, getBlue()); + public Color setGreen(final @Range(from = 0, to = 255) int green) { + return fromARGB(this.getAlpha(), this.getRed(), green, this.getBlue()); } /** - * Gets the blue component + * Gets the blue component. * * @return blue component, from 0 to 255 */ - public int getBlue() { - return BIT_MASK & blue; + public @Range(from = 0, to = 255) int getBlue() { + return BIT_MASK & this.blue; } /** - * Creates a new Color object with specified component + * Gets the blue component. + * + * @return blue component, from 0 to 255 + */ + @Override + public @Range(from = 0, to = 255) int blue() { + return this.getBlue(); + } + + /** + * Creates a new Color object with a specified component. * * @param blue the blue component, from 0 to 255 * @return a new color object with the blue component */ @NotNull - public Color setBlue(int blue) { - return fromARGB(getAlpha(), getRed(), getGreen(), blue); + public Color setBlue(final @Range(from = 0, to = 255) int blue) { + return fromARGB(this.getAlpha(), this.getRed(), this.getGreen(), blue); } /** @@ -298,7 +353,7 @@ public Color setBlue(int blue) { * @return An integer representation of this color, as 0xRRGGBB */ public int asRGB() { - return getRed() << 16 | getGreen() << 8 | getBlue(); + return this.getRed() << 16 | this.getGreen() << 8 | this.getBlue(); } /** @@ -307,7 +362,7 @@ public int asRGB() { * @return An integer representation of this color, as 0xAARRGGBB */ public int asARGB() { - return getAlpha() << 24 | getRed() << 16 | getGreen() << 8 | getBlue(); + return this.getAlpha() << 24 | this.getRed() << 16 | this.getGreen() << 8 | this.getBlue(); } /** @@ -316,33 +371,33 @@ public int asARGB() { * @return An integer representation of this color, as 0xBBGGRR */ public int asBGR() { - return getBlue() << 16 | getGreen() << 8 | getRed(); + return this.getBlue() << 16 | this.getGreen() << 8 | this.getRed(); } /** * Creates a new color with its RGB components changed as if it was dyed - * with the colors passed in, replicating vanilla workbench dyeing + * with the colors passed in, replicating vanilla workbench dyeing. * * @param colors The DyeColors to dye with * @return A new color with the changed rgb components */ // TODO: Javadoc what this method does, not what it mimics. API != Implementation @NotNull - public Color mixDyes(@NotNull DyeColor... colors) { + public Color mixDyes(final @NotNull DyeColor... colors) { Preconditions.checkArgument(colors != null && Arrays.stream(colors).allMatch(Objects::nonNull), "DyeColor cannot be null or contain null values"); - Color[] toPass = new Color[colors.length]; + final Color[] toPass = new Color[colors.length]; for (int i = 0; i < colors.length; i++) { toPass[i] = colors[i].getColor(); } - return mixColors(toPass); + return this.mixColors(toPass); } /** * Creates a new color with its RGB components changed as if it was dyed * with the colors passed in, replicating vanilla workbench dyeing. - * + *
* Note that this method does not currently take into account alpha * components. * @@ -351,7 +406,7 @@ public Color mixDyes(@NotNull DyeColor... colors) { */ // TODO: Javadoc what this method does, not what it mimics. API != Implementation @NotNull - public Color mixColors(@NotNull Color... colors) { + public Color mixColors(final @NotNull Color... colors) { Preconditions.checkArgument(colors != null && Arrays.stream(colors).allMatch(Objects::nonNull), "Colors cannot be null"); int totalRed = this.getRed(); @@ -365,44 +420,43 @@ public Color mixColors(@NotNull Color... colors) { totalMax += Math.max(Math.max(color.getRed(), color.getGreen()), color.getBlue()); } - float averageRed = totalRed / (colors.length + 1); - float averageGreen = totalGreen / (colors.length + 1); - float averageBlue = totalBlue / (colors.length + 1); - float averageMax = totalMax / (colors.length + 1); + final float averageRed = totalRed / (colors.length + 1); + final float averageGreen = totalGreen / (colors.length + 1); + final float averageBlue = totalBlue / (colors.length + 1); + final float averageMax = totalMax / (colors.length + 1); - float maximumOfAverages = Math.max(Math.max(averageRed, averageGreen), averageBlue); - float gainFactor = averageMax / maximumOfAverages; + final float maximumOfAverages = Math.max(Math.max(averageRed, averageGreen), averageBlue); + final float gainFactor = averageMax / maximumOfAverages; return Color.fromRGB((int) (averageRed * gainFactor), (int) (averageGreen * gainFactor), (int) (averageBlue * gainFactor)); } @Override - public boolean equals(Object o) { - if (!(o instanceof Color)) { + public boolean equals(final Object o) { + if (!(o instanceof Color that)) { return false; } - final Color that = (Color) o; return this.alpha == that.alpha && this.blue == that.blue && this.green == that.green && this.red == that.red; } @Override public int hashCode() { - return asARGB() ^ Color.class.hashCode(); + return this.asARGB() ^ Color.class.hashCode(); } @Override @NotNull public Map serialize() { return ImmutableMap.of( - "ALPHA", getAlpha(), - "RED", getRed(), - "BLUE", getBlue(), - "GREEN", getGreen() + "ALPHA", this.getAlpha(), + "RED", this.getRed(), + "BLUE", this.getBlue(), + "GREEN", this.getGreen() ); } @NotNull - public static Color deserialize(@NotNull Map map) { + public static Color deserialize(final @NotNull Map map) { return fromARGB( asInt("ALPHA", map, DEFAULT_ALPHA), asInt("RED", map), @@ -411,23 +465,23 @@ public static Color deserialize(@NotNull Map map) { ); } - private static int asInt(@NotNull String string, @NotNull Map map) { + private static int asInt(final @NotNull String string, final @NotNull Map map) { return asInt(string, map, null); } - private static int asInt(@NotNull String string, @NotNull Map map, @Nullable Object defaultValue) { - Object value = map.getOrDefault(string, defaultValue); + private static int asInt(final @NotNull String string, final @NotNull Map map, final @Nullable Object defaultValue) { + final Object value = map.getOrDefault(string, defaultValue); if (value == null) { throw new IllegalArgumentException(string + " not in map " + map); } - if (!(value instanceof Number)) { + if (!(value instanceof Number number)) { throw new IllegalArgumentException(string + '(' + value + ") is not a number"); } - return ((Number) value).intValue(); + return number.intValue(); } @Override public String toString() { - return "Color:[argb0x" + Integer.toHexString(asARGB()).toUpperCase(Locale.ROOT) + "]"; + return "Color:[argb0x" + Integer.toHexString(this.asARGB()).toUpperCase(Locale.ROOT) + "]"; } }