Parcourir la source

Remove stuff I don't use and which I didn't write in IColorCenter and friends

smelc il y a 7 ans
Parent
commit
a230650e54

+ 251 - 396
squidlib-util/src/main/java/squidpony/IColorCenter.java

@@ -1,11 +1,11 @@
 package squidpony;
 
-import squidpony.panel.IColoredString;
-import squidpony.squidmath.RNG;
-
 import java.util.HashMap;
 import java.util.Map;
 
+import squidpony.panel.IColoredString;
+import squidpony.squidmath.RNG;
+
 /**
  * How to manage colors, making sure that a color is allocated at most once.
  * 
@@ -39,64 +39,35 @@ public interface IColorCenter<T> {
 
 	/**
 	 * @param red
-	 *            The red component. For screen colors, in-between 0 (inclusive)
-     *            and 256 (exclusive).
+	 *            The red component. For screen colors, in-between 0 (inclusive) and
+	 *            256 (exclusive).
 	 * @param green
 	 *            The green component. For screen colors, in-between 0 (inclusive)
-     *            and 256 (exclusive).
+	 *            and 256 (exclusive).
 	 * @param blue
 	 *            The blue component. For screen colors, in-between 0 (inclusive)
-     *            and 256 (exclusive).
+	 *            and 256 (exclusive).
 	 * @param opacity
-	 *            The alpha component. In-between 0 (inclusive) and 256
-	 *            (exclusive). Larger values mean more opacity; 0 is clear.
+	 *            The alpha component. In-between 0 (inclusive) and 256 (exclusive).
+	 *            Larger values mean more opacity; 0 is clear.
 	 * @return A possibly transparent color.
 	 */
 	T get(int red, int green, int blue, int opacity);
 
 	/**
 	 * @param red
-	 *            The red component. For screen colors, in-between 0 (inclusive)
-     *            and 256 (exclusive).
+	 *            The red component. For screen colors, in-between 0 (inclusive) and
+	 *            256 (exclusive).
 	 * @param green
 	 *            The green component. For screen colors, in-between 0 (inclusive)
-     *            and 256 (exclusive).
+	 *            and 256 (exclusive).
 	 * @param blue
 	 *            The blue component. For screen colors, in-between 0 (inclusive)
-     *            and 256 (exclusive).
+	 *            and 256 (exclusive).
 	 * @return An opaque color.
 	 */
 	T get(int red, int green, int blue);
 
-    /**
-     *
-     * @param hue The hue of the desired color from 0.0 (red, inclusive) towards orange, then
-     *            yellow, and eventually to purple before looping back to almost the same red
-     *            (1.0, exclusive)
-     * @param saturation the saturation of the color from 0.0 (a grayscale color; inclusive)
-     *                   to 1.0 (a bright color, exclusive)
-     * @param value the value (essentially lightness) of the color from 0.0 (black,
-     *                   inclusive) to 1.0 (inclusive) for screen colors or arbitrarily high
-     *                   for HDR colors.
-     * @param opacity the alpha component as a float; 0.0f is clear, 1.0f is opaque.
-     * @return a possibly transparent color
-     */
-    T getHSV(float hue, float saturation, float value, float opacity);
-
-    /**
-     *
-     * @param hue The hue of the desired color from 0.0 (red, inclusive) towards orange, then
-     *            yellow, and eventually to purple before looping back to almost the same red
-     *            (1.0, exclusive)
-     * @param saturation the saturation of the color from 0.0 (a grayscale color; inclusive)
-     *                   to 1.0 (a bright color, exclusive)
-     * @param value the value (essentially lightness) of the color from 0.0 (black,
-     *                   inclusive) to 1.0 (inclusive) for screen colors or arbitrarily high
-     *                   for HDR colors.
-     * @return an opaque color
-     */
-    T getHSV(float hue, float saturation, float value);
-
 	/**
 	 * @return Opaque white.
 	 */
@@ -113,69 +84,62 @@ public interface IColorCenter<T> {
 	T getTransparent();
 
 	/**
-	 * @param rng an RNG from SquidLib.
+	 * @param rng
+	 *            an RNG from SquidLib.
 	 * @param opacity
-	 *            The alpha component. In-between 0 (inclusive) and 256
-	 *            (exclusive). Larger values mean more opacity; 0 is clear.
+	 *            The alpha component. In-between 0 (inclusive) and 256 (exclusive).
+	 *            Larger values mean more opacity; 0 is clear.
 	 * @return A random color, except for the alpha component.
 	 */
 	T getRandom(RNG rng, int opacity);
 
 	/**
-	 * @param c a concrete color
-	 * @return The red component. For screen colors, in-between 0 (inclusive) and 256 (exclusive).
+	 * @param c
+	 *            a concrete color
+	 * @return The red component. For screen colors, in-between 0 (inclusive) and
+	 *         256 (exclusive).
 	 */
 	int getRed(T c);
 
 	/**
-	 * @param c a concrete color
-	 * @return The green component. For screen colors, in-between 0 (inclusive) and 256
-	 *         (exclusive).
+	 * @param c
+	 *            a concrete color
+	 * @return The green component. For screen colors, in-between 0 (inclusive) and
+	 *         256 (exclusive).
 	 */
 	int getGreen(T c);
 
 	/**
-	 * @param c a concrete color
-	 * @return The blue component. For screen colors, in-between 0 (inclusive) and 256 (exclusive).
+	 * @param c
+	 *            a concrete color
+	 * @return The blue component. For screen colors, in-between 0 (inclusive) and
+	 *         256 (exclusive).
 	 */
 	int getBlue(T c);
 
 	/**
-	 * @param c a concrete color
-	 * @return The alpha component. In-between 0 (inclusive) and 256
-	 *         (exclusive).
+	 * @param c
+	 *            a concrete color
+	 * @return The alpha component. In-between 0 (inclusive) and 256 (exclusive).
 	 */
 	int getAlpha(T c);
 
-    /**
-     *
-     * @param c a concrete color
-     * @return The hue of the color from 0.0 (red, inclusive) towards orange, then yellow, and
-     * eventually to purple before looping back to almost the same red (1.0, exclusive)
-     */
-    float getHue(T c);
-
-    /**
-     *
-     * @param c a concrete color
-     * @return the saturation of the color from 0.0 (a grayscale color; inclusive) to 1.0 (a
-     * bright color, exclusive)
-     */
-    float getSaturation(T c);
-
-    /**
-     *
-     * @param c a concrete color
-     * @return the value (essentially lightness) of the color from 0.0 (black, inclusive) to
-     * 1.0 (inclusive) for screen colors or arbitrarily high for HDR colors.
-     */
-    float getValue(T c);
-
-    /**
-     * @param c
-     * @return The color that {@code this} shows when {@code c} is requested. May be {@code c} itself.
-     */
-    T filter(T c);
+	/**
+	 *
+	 * @param c
+	 *            a concrete color
+	 * @return the value (essentially lightness) of the color from 0.0 (black,
+	 *         inclusive) to 1.0 (inclusive) for screen colors or arbitrarily high
+	 *         for HDR colors.
+	 */
+	float getValue(T c);
+
+	/**
+	 * @param c
+	 * @return The color that {@code this} shows when {@code c} is requested. May be
+	 *         {@code c} itself.
+	 */
+	T filter(T c);
 
 	/**
 	 * @param ics
@@ -185,111 +149,71 @@ public interface IColorCenter<T> {
 	IColoredString<T> filter(IColoredString<T> ics);
 
 	/**
-	 * Gets a copy of t and modifies it to make a shade of gray with the same brightness.
-	 * The doAlpha parameter causes the alpha to be considered in the calculation of brightness and also changes the
-	 * returned alpha of the color.
+	 * Gets a copy of t and modifies it to make a shade of gray with the same
+	 * brightness. The doAlpha parameter causes the alpha to be considered in the
+	 * calculation of brightness and also changes the returned alpha of the color.
 	 * Not related to reified types or any usage of "reify."
-	 * @param t a T to copy; only the copy will be modified
+	 * 
+	 * @param t
+	 *            a T to copy; only the copy will be modified
 	 * @param doAlpha
 	 *            Whether to include (and hereby change) the alpha component.
 	 * @return A monochromatic variation of {@code t}.
 	 */
-	T greify(/*@Nullable*/ T t, boolean doAlpha);
-
-    /**
-     * Gets the linear interpolation from Color start to Color end, changing by the fraction given by change.
-     * @param start the initial color T
-     * @param end the "target" color T
-     * @param change the degree to change closer to end; a change of 0.0f produces start, 1.0f produces end
-     * @return a new T between start and end
-     */
-    T lerp(T start, T end, float change);
-    /**
-     * Gets a fully-desaturated version of the given color (keeping its brightness, but making it grayscale).
-     * Keeps alpha the same; if you want alpha to be considered (and brightness to be calculated differently), then
-     * you can use greify() in this class instead.
-     * @param color the color T to desaturate (will not be modified)
-     * @return the grayscale version of color
-     */
-    T desaturated(T color);
-
-    /**
-     * Brings a color closer to grayscale by the specified degree and returns the new color (desaturated somewhat).
-     * Alpha is left unchanged.
-     * @param color the color T to desaturate
-     * @param degree a float between 0.0f and 1.0f; more makes it less colorful
-     * @return the desaturated (and if a filter is used, also filtered) new color T
-     */
-    T desaturate(T color, float degree);
-
-    /**
-     * Fully saturates color (makes it a vivid color like red or green and less gray) and returns the modified copy.
-     * Leaves alpha unchanged.
-     * @param color the color T to saturate (will not be modified)
-     * @return the saturated version of color
-     */
-    T saturated(T color);
-
-
-    /**
-     * Saturates color (makes it closer to a vivid color like red or green and less gray) by the specified degree and
-     * returns the new color (saturated somewhat). If this is called on a color that is very close to gray, this does
-     * not necessarily return a specific color, but most implementations will treat a hue of 0 as red.
-     * @param color the color T to saturate
-     * @param degree a float between 0.0f and 1.0f; more makes it more colorful
-     * @return the saturated (and if a filter is used, also filtered) new color
-     */
-    public T saturate(T color, float degree);
-
-    /**
+	T greify(/* @Nullable */ T t, boolean doAlpha);
+
+	/**
 	 * A skeletal implementation of {@link IColorCenter}.
 	 * 
 	 * @author smelC
 	 * 
-	 * @param <T> a concrete color type
+	 * @param <T>
+	 *            a concrete color type
 	 */
 	abstract class Skeleton<T> implements IColorCenter<T> {
 
 		private final Map<Long, T> cache = new HashMap<>(256);
 
-		protected /*Nullable*/ IFilter<T> filter;
+		protected /* Nullable */ IFilter<T> filter;
 
 		/**
 		 * @param filter
-		 * 			The filter to use, or {@code null} for no filter.
+		 *            The filter to use, or {@code null} for no filter.
 		 */
-		protected Skeleton(/*Nullable*/ IFilter<T> filter) {
+		protected Skeleton(/* Nullable */ IFilter<T> filter) {
 			this.filter = filter;
 		}
 
-        /**
-         * It clears the cache. You may need to do this to limit the cache to the colors used in a specific section.
-		 * This is also useful if a Filter changes what colors it should return on a frame-by-frame basis; in that case,
-		 * you can call clearCache() at the start or end of a frame to ensure the next frame gets different colors.
-         */
-        public void clearCache()
-        {
-            cache.clear();
-        }
-
-        /**
-         * You may want to copy colors between IColorCenter instances that have different create() methods -- and as
-         * such, will have different values for the same keys in the cache. This allows you to copy the cache from other
-         * into this Skeleton, but using this Skeleton's create() method.
-         * @param other another Skeleton of the same type that will have its cache copied into this Skeleton
-         */
-        public void copyCache(Skeleton<T> other)
-        {
-            for (Map.Entry<Long, T> k : other.cache.entrySet())
-            {
-                cache.put(k.getKey(), create(getRed(k.getValue()), getGreen(k.getValue()), getBlue(k.getValue()),
-                        getAlpha(k.getValue())));
-            }
-        }
+		/**
+		 * It clears the cache. You may need to do this to limit the cache to the colors
+		 * used in a specific section. This is also useful if a Filter changes what
+		 * colors it should return on a frame-by-frame basis; in that case, you can call
+		 * clearCache() at the start or end of a frame to ensure the next frame gets
+		 * different colors.
+		 */
+		public void clearCache() {
+			cache.clear();
+		}
+
+		/**
+		 * You may want to copy colors between IColorCenter instances that have
+		 * different create() methods -- and as such, will have different values for the
+		 * same keys in the cache. This allows you to copy the cache from other into
+		 * this Skeleton, but using this Skeleton's create() method.
+		 * 
+		 * @param other
+		 *            another Skeleton of the same type that will have its cache copied
+		 *            into this Skeleton
+		 */
+		public void copyCache(Skeleton<T> other) {
+			for (Map.Entry<Long, T> k : other.cache.entrySet()) {
+				cache.put(k.getKey(), create(getRed(k.getValue()), getGreen(k.getValue()), getBlue(k.getValue()),
+						getAlpha(k.getValue())));
+			}
+		}
 
 		/**
-		 * If you're changing the filter, you should likely call
-		 * {@link #clearCache()}.
+		 * If you're changing the filter, you should likely call {@link #clearCache()}.
 		 * 
 		 * @param filter
 		 *            The filter to use, or {@code null} to turn filtering OFF.
@@ -302,7 +226,7 @@ public interface IColorCenter<T> {
 
 		@Override
 		public T get(int red, int green, int blue, int opacity) {
-			final Long value = getUniqueIdentifier((short)red, (short)green, (short)blue, (short)opacity);
+			final Long value = getUniqueIdentifier((short) red, (short) green, (short) blue, (short) opacity);
 			T t = cache.get(value);
 			if (t == null) {
 				/* Miss */
@@ -318,184 +242,141 @@ public interface IColorCenter<T> {
 			return get(red, green, blue, 255);
 		}
 
-        @Override
-        public T getHSV(float hue, float saturation, float value, float opacity) {
-            if ( saturation < 0.0001 )                       //HSV from 0 to 1
-            {
-                return get(Math.round(value * 255), Math.round(value * 255), Math.round(value * 255),
-                        Math.round(opacity * 255));
-            }
-            else
-            {
-                float h = hue * 6f;
-                if ( h >= 6 ) h = 0;      //H must be < 1
-                int i = (int)h;             //Or ... var_i = floor( var_h )
-                float a = value * ( 1 - saturation );
-                float b = value * ( 1 - saturation * ( h - i ) );
-                float c = value * ( 1 - saturation * ( 1 - ( h - i ) ) );
-
-                switch (i)
-                {
-                    case 0: return get(Math.round(value * 255), Math.round(c * 255), Math.round(a * 255),
-                            Math.round(opacity * 255));
-                    case 1: return get(Math.round(b * 255), Math.round(value * 255), Math.round(a * 255),
-                            Math.round(opacity * 255));
-                    case 2: return get(Math.round(a * 255), Math.round(value * 255), Math.round(c * 255),
-                            Math.round(opacity * 255));
-                    case 3: return get(Math.round(a * 255), Math.round(b * 255), Math.round(value * 255),
-                            Math.round(opacity * 255));
-                    case 4: return get(Math.round(c * 255), Math.round(a * 255), Math.round(value * 255),
-                            Math.round(opacity * 255));
-                    default: return get(Math.round(value * 255), Math.round(a * 255), Math.round(b * 255),
-                            Math.round(opacity * 255));
-                }
-            }
-        }
-
-        @Override
-        public T getHSV(float hue, float saturation, float value) {
-            return getHSV(hue, saturation, value, 1.0f);
-        }
-
-        @Override
-		public T getWhite() {
+		@Override
+		public final T getWhite() {
 			return get(255, 255, 255, 255);
 		}
 
 		@Override
-		public T getBlack() {
+		public final T getBlack() {
 			return get(0, 0, 0, 255);
 		}
 
 		@Override
-		public T getTransparent() {
+		public final T getTransparent() {
 			return get(0, 0, 0, 0);
 		}
 
 		@Override
-		public T getRandom(RNG rng, int opacity) {
+		public final T getRandom(RNG rng, int opacity) {
 			return get(rng.nextInt(256), rng.nextInt(256), rng.nextInt(256), opacity);
 		}
 
-        /**
-         * @param r the red component in 0.0 to 1.0 range, typically
-         * @param g the green component in 0.0 to 1.0 range, typically
-         * @param b the blue component in 0.0 to 1.0 range, typically
-         * @return the saturation of the color from 0.0 (a grayscale color; inclusive) to 1.0 (a
-         * bright color, exclusive)
-         */
-        public float getSaturation(float r, float g, float b) {
-            float min = Math.min(Math.min(r, g ), b);    //Min. value of RGB
-            float max = Math.max(Math.max(r, g), b);    //Min. value of RGB
-            float delta = max - min;                     //Delta RGB value
-
-            float saturation;
-
-            if ( delta < 0.0001f )                     //This is a gray, no chroma...
-            {
-                saturation = 0;
-            }
-            else                                    //Chromatic data...
-            {
-                saturation = delta / max;
-            }
-            return saturation;
-        }
-        /**
-         * @param c a concrete color
-         * @return the saturation of the color from 0.0 (a grayscale color; inclusive) to 1.0 (a
-         * bright color, exclusive)
-         */
-        @Override
-        public float getSaturation(T c) {
-            return getSaturation(getRed(c) / 255f, getGreen(c) / 255f, getBlue(c) / 255f);
-        }
-
-        /**
-         * @param r the red component in 0.0 to 1.0 range, typically
-         * @param g the green component in 0.0 to 1.0 range, typically
-         * @param b the blue component in 0.0 to 1.0 range, typically
-         * @return the value (essentially lightness) of the color from 0.0 (black, inclusive) to
-         * 1.0 (inclusive) for screen colors or arbitrarily high for HDR colors.
-         */
-        public float getValue(float r, float g, float b)
-        {
-            return Math.max(Math.max(r, g), b);
-        }
-        /**
-         * @param c a concrete color
-         * @return the value (essentially lightness) of the color from 0.0 (black, inclusive) to
-         * 1.0 (inclusive) for screen colors or arbitrarily high for HDR colors.
-         */
-        @Override
-        public float getValue(T c) {
-            float r = getRed(c) / 255f;                     //RGB from 0 to 255
-            float g = getGreen(c) / 255f;
-            float b = getBlue(c) / 255f;
-
-            return Math.max(Math.max(r, g), b);
-        }
-
-        /**
-         * @param r the red component in 0.0 to 1.0 range, typically
-         * @param g the green component in 0.0 to 1.0 range, typically
-         * @param b the blue component in 0.0 to 1.0 range, typically
-         * @return The hue of the color from 0.0 (red, inclusive) towards orange, then yellow, and
-         * eventually to purple before looping back to almost the same red (1.0, exclusive)
-         */
-        public float getHue(float r, float g, float b) {
-            float min = Math.min(Math.min(r, g ), b);    //Min. value of RGB
-            float max = Math.max(Math.max(r, g), b);    //Min. value of RGB
-            float delta = max - min;                     //Delta RGB value
-
-            float hue;
-
-            if ( delta < 0.0001f )                     //This is a gray, no chroma...
-            {
-                hue = 0;                                //HSV results from 0 to 1
-            }
-            else                                    //Chromatic data...
-            {
-                float rDelta = ( ( ( max - r ) / 6f ) + ( delta / 2f ) ) / delta;
-                float gDelta = ( ( ( max - g ) / 6f ) + ( delta / 2f ) ) / delta;
-                float bDelta = ( ( ( max - b ) / 6f ) + ( delta / 2f ) ) / delta;
-
-                if       ( r == max ) hue = bDelta - gDelta;
-                else if ( g == max ) hue = ( 1f / 3f ) + rDelta - bDelta;
-                else                 hue = ( 2f / 3f ) + gDelta - rDelta;
-
-                if ( hue < 0 ) hue += 1f;
-                else if ( hue > 1 ) hue -= 1;
-            }
-            return hue;
-        }
-
-        /**
-         * @param c a concrete color
-         * @return The hue of the color from 0.0 (red, inclusive) towards orange, then yellow, and
-         * eventually to purple before looping back to almost the same red (1.0, exclusive)
-         */
-        @Override
-        public float getHue(T c) {
-            return getHue(getRed(c) / 255f, getGreen(c) / 255f, getBlue(c) / 255f);
-        }
-
-        @Override
-		public T filter(T c)
-        {
-        	return c == null ? c : get(getRed(c), getGreen(c), getBlue(c), getAlpha(c));
-        }
+		/**
+		 * @param r
+		 *            the red component in 0.0 to 1.0 range, typically
+		 * @param g
+		 *            the green component in 0.0 to 1.0 range, typically
+		 * @param b
+		 *            the blue component in 0.0 to 1.0 range, typically
+		 * @return the saturation of the color from 0.0 (a grayscale color; inclusive)
+		 *         to 1.0 (a bright color, exclusive)
+		 */
+		public float getSaturation(float r, float g, float b) {
+			float min = Math.min(Math.min(r, g), b); // Min. value of RGB
+			float max = Math.max(Math.max(r, g), b); // Min. value of RGB
+			float delta = max - min; // Delta RGB value
+
+			float saturation;
+
+			if (delta < 0.0001f) // This is a gray, no chroma...
+			{
+				saturation = 0;
+			} else // Chromatic data...
+			{
+				saturation = delta / max;
+			}
+			return saturation;
+		}
+
+		/**
+		 * @param r
+		 *            the red component in 0.0 to 1.0 range, typically
+		 * @param g
+		 *            the green component in 0.0 to 1.0 range, typically
+		 * @param b
+		 *            the blue component in 0.0 to 1.0 range, typically
+		 * @return the value (essentially lightness) of the color from 0.0 (black,
+		 *         inclusive) to 1.0 (inclusive) for screen colors or arbitrarily high
+		 *         for HDR colors.
+		 */
+		public float getValue(float r, float g, float b) {
+			return Math.max(Math.max(r, g), b);
+		}
+
+		/**
+		 * @param c
+		 *            a concrete color
+		 * @return the value (essentially lightness) of the color from 0.0 (black,
+		 *         inclusive) to 1.0 (inclusive) for screen colors or arbitrarily high
+		 *         for HDR colors.
+		 */
+		@Override
+		public float getValue(T c) {
+			float r = getRed(c) / 255f; // RGB from 0 to 255
+			float g = getGreen(c) / 255f;
+			float b = getBlue(c) / 255f;
+
+			return Math.max(Math.max(r, g), b);
+		}
+
+		/**
+		 * @param r
+		 *            the red component in 0.0 to 1.0 range, typically
+		 * @param g
+		 *            the green component in 0.0 to 1.0 range, typically
+		 * @param b
+		 *            the blue component in 0.0 to 1.0 range, typically
+		 * @return The hue of the color from 0.0 (red, inclusive) towards orange, then
+		 *         yellow, and eventually to purple before looping back to almost the
+		 *         same red (1.0, exclusive)
+		 */
+		public float getHue(float r, float g, float b) {
+			float min = Math.min(Math.min(r, g), b); // Min. value of RGB
+			float max = Math.max(Math.max(r, g), b); // Min. value of RGB
+			float delta = max - min; // Delta RGB value
+
+			float hue;
+
+			if (delta < 0.0001f) // This is a gray, no chroma...
+			{
+				hue = 0; // HSV results from 0 to 1
+			} else // Chromatic data...
+			{
+				float rDelta = (((max - r) / 6f) + (delta / 2f)) / delta;
+				float gDelta = (((max - g) / 6f) + (delta / 2f)) / delta;
+				float bDelta = (((max - b) / 6f) + (delta / 2f)) / delta;
+
+				if (r == max)
+					hue = bDelta - gDelta;
+				else if (g == max)
+					hue = (1f / 3f) + rDelta - bDelta;
+				else
+					hue = (2f / 3f) + gDelta - rDelta;
+
+				if (hue < 0)
+					hue += 1f;
+				else if (hue > 1)
+					hue -= 1;
+			}
+			return hue;
+		}
+
+		@Override
+		public T filter(T c) {
+			return c == null ? c : get(getRed(c), getGreen(c), getBlue(c), getAlpha(c));
+		}
 
 		@Override
 		public IColoredString<T> filter(IColoredString<T> ics) {
 			/*
-			 * It is common not to have a filter or to have the identity one. To
-			 * avoid always copying strings in this case, we first roll over the
-			 * string to see if there'll be a change.
+			 * It is common not to have a filter or to have the identity one. To avoid
+			 * always copying strings in this case, we first roll over the string to see if
+			 * there'll be a change.
 			 * 
-			 * This is clearly a subjective design choice but my industry
-			 * experience is that minimizing allocations is the thing to do for
-			 * performances, hence I prefer iterating twice to do that.
+			 * This is clearly a subjective design choice but my industry experience is that
+			 * minimizing allocations is the thing to do for performances, hence I prefer
+			 * iterating twice to do that.
 			 */
 			boolean change = false;
 			for (IColoredString.Bucket<T> bucket : ics) {
@@ -518,12 +399,15 @@ public interface IColorCenter<T> {
 				/* Only one allocation: the iterator, yay \o/ */
 				return ics;
 		}
+
 		/**
-		 * Gets a copy of t and modifies it to make a shade of gray with the same brightness.
-		 * The doAlpha parameter causes the alpha to be considered in the calculation of brightness and also changes the
-		 * returned alpha of the color.
+		 * Gets a copy of t and modifies it to make a shade of gray with the same
+		 * brightness. The doAlpha parameter causes the alpha to be considered in the
+		 * calculation of brightness and also changes the returned alpha of the color.
 		 * Not related to reified types or any usage of "reify."
-		 * @param t a T to copy; only the copy will be modified
+		 * 
+		 * @param t
+		 *            a T to copy; only the copy will be modified
 		 * @param doAlpha
 		 *            Whether to include (and hereby change) the alpha component.
 		 * @return A monochromatic variation of {@code t}.
@@ -552,86 +436,57 @@ public interface IColorCenter<T> {
 		}
 
 		/**
-		 * Gets the linear interpolation from Color start to Color end, changing by the fraction given by change.
-         * This implementation tries to work with colors in a way that is as general as possible, using getRed() instead
-         * of some specific detail that depends on how a color is implemented. Other implementations that specialize in
-         * a specific type of color may be able to be more efficient.
-         * @param start the initial color T
-         * @param end the "target" color T
-         * @param change the degree to change closer to end; a change of 0.0f produces start, 1.0f produces end
-         * @return a new T between start and end
+		 * Gets the linear interpolation from Color start to Color end, changing by the
+		 * fraction given by change. This implementation tries to work with colors in a
+		 * way that is as general as possible, using getRed() instead of some specific
+		 * detail that depends on how a color is implemented. Other implementations that
+		 * specialize in a specific type of color may be able to be more efficient.
+		 * 
+		 * @param start
+		 *            the initial color T
+		 * @param end
+		 *            the "target" color T
+		 * @param change
+		 *            the degree to change closer to end; a change of 0.0f produces
+		 *            start, 1.0f produces end
+		 * @return a new T between start and end
 		 */
-		public T lerp(T start, T end, float change)
-		{
-			if(start == null || end == null)
+		public T lerp(T start, T end, float change) {
+			if (start == null || end == null)
 				return null;
 			final int sr = getRed(start), sg = getGreen(start), sb = getBlue(start), sa = getAlpha(start),
 					er = getRed(end), eg = getGreen(end), eb = getBlue(end), ea = getAlpha(end);
-			return get(
-					(int)(sr + change * (er - sr)),
-					(int)(sg + change
-							* (eg - sg)),
-					(int)(sb + change * (eb - sb)),
-					(int)(sa + change * (ea - sa))
-			);
+			return get((int) (sr + change * (er - sr)), (int) (sg + change * (eg - sg)),
+					(int) (sb + change * (eb - sb)), (int) (sa + change * (ea - sa)));
 		}
+
 		/**
-		 * Gets a fully-desaturated version of the given color (keeping its brightness, but making it grayscale).
-		 * Keeps alpha the same; if you want alpha to be considered (and brightness to be calculated differently), then
-		 * you can use greify() in this class instead.
-		 * @param color the color T to desaturate (will not be modified)
+		 * Gets a fully-desaturated version of the given color (keeping its brightness,
+		 * but making it grayscale). Keeps alpha the same; if you want alpha to be
+		 * considered (and brightness to be calculated differently), then you can use
+		 * greify() in this class instead.
+		 * 
+		 * @param color
+		 *            the color T to desaturate (will not be modified)
 		 * @return the grayscale version of color
 		 */
-		public T desaturated(T color)
-		{
-			int f = (int)Math.min(255, getRed(color) * 0.299f + getGreen(color) * 0.587f + getBlue(color) * 0.114f);
+		public T desaturated(T color) {
+			int f = (int) Math.min(255, getRed(color) * 0.299f + getGreen(color) * 0.587f + getBlue(color) * 0.114f);
 			return get(f, f, f, getAlpha(color));
 		}
 
 		/**
-		 * Brings a color closer to grayscale by the specified degree and returns the new color (desaturated somewhat).
-		 * Alpha is left unchanged.
-		 * @param color the color T to desaturate
-		 * @param degree a float between 0.0f and 1.0f; more makes it less colorful
-		 * @return the desaturated (and if a filter is used, also filtered) new color T
-		 */
-		public T desaturate(T color, float degree)
-		{
-			return lerp(color, desaturated(color), degree);
-		}
-
-        /**
-         * Fully saturates color (makes it a vivid color like red or green and less gray) and returns the modified copy.
-         * Leaves alpha unchanged.
-         * @param color the color T to saturate (will not be modified)
-         * @return the saturated version of color
-         */
-        public T saturated(T color)
-        {
-            return getHSV(getHue(color), 1f, getValue(color), getAlpha(color));
-        }
-		/**
-		 * Saturates color (makes it closer to a vivid color like red or green and less gray) by the specified degree and
-		 * returns the new color (saturated somewhat). If this is called on a color that is very close to gray, this is
-		 * likely to produce a red hue by default (if there's no hue to make vivid, it needs to choose something).
-		 * @param color the color T to saturate
-		 * @param degree a float between 0.0f and 1.0f; more makes it more colorful
-		 * @return the saturated (and if a filter is used, also filtered) new color
-		 */
-		public T saturate(T color, float degree)
-		{
-			return lerp(color, saturated(color), degree);
-		}
-
-
-		/**
-		 * Create a concrete instance of the color type given as a type parameter. That's the
-		 * place to use the {@link #filter}.
+		 * Create a concrete instance of the color type given as a type parameter.
+		 * That's the place to use the {@link #filter}.
 		 * 
-		 * @param red the red component of the desired color
-		 * @param green the green component of the desired color
-		 * @param blue the blue component of the desired color
-		 * @param opacity the alpha component or opacity of the desired color
+		 * @param red
+		 *            the red component of the desired color
+		 * @param green
+		 *            the green component of the desired color
+		 * @param blue
+		 *            the blue component of the desired color
+		 * @param opacity
+		 *            the alpha component or opacity of the desired color
 		 * @return a fresh instance of the concrete color type
 		 */
 		protected abstract T create(int red, int green, int blue, int opacity);

+ 413 - 414
squidlib/src/main/java/squidpony/squidgrid/gui/gdx/SquidColorCenter.java

@@ -1,42 +1,44 @@
 package squidpony.squidgrid.gui.gdx;
 
+import java.util.ArrayList;
+
 import com.badlogic.gdx.graphics.Color;
 import com.badlogic.gdx.math.Interpolation;
+
 import squidpony.IColorCenter;
 import squidpony.IFilter;
 import squidpony.squidmath.CoordPacker;
 import squidpony.squidmath.StatefulRNG;
 
-import java.util.ArrayList;
-
 /**
- * A concrete implementation of {@link IColorCenter} for libgdx's {@link com.badlogic.gdx.graphics.Color}.
- * Supports filtering any colors that this creates using a {@link Filter}, such as one from {@link Filters}.
+ * A concrete implementation of {@link IColorCenter} for libgdx's
+ * {@link com.badlogic.gdx.graphics.Color}. Supports filtering any colors that
+ * this creates using a {@link Filter}, such as one from {@link Filters}.
  *
  * @author smelC
  * @author Tommy Ettinger
- * @see SColor Another way to obtain colors by using pre-allocated (and named) instances.
+ * @see SColor Another way to obtain colors by using pre-allocated (and named)
+ *      instances.
  */
 public class SquidColorCenter extends IColorCenter.Skeleton<Color> {
 
-    /**
-     * A fresh filter-less color center.
-     */
-    public SquidColorCenter()
-    {
-    	this(null);
-    }
+	/**
+	 * A fresh filter-less color center.
+	 */
+	public SquidColorCenter() {
+		this(null);
+	}
 
-    /**
+	/**
 	 * A fresh filtered color center.
 	 * 
 	 * @param filterEffect
 	 *            The filter to use.
 	 */
-    public SquidColorCenter(/*Nullable*/IFilter<Color> filterEffect)
-    {
-    	super(filterEffect);
-    }
+	public SquidColorCenter(/* Nullable */IFilter<Color> filterEffect) {
+		super(filterEffect);
+	}
+
 	@Override
 	protected Color create(int red, int green, int blue, int opacity) {
 		if (filter == null)
@@ -46,42 +48,44 @@ public class SquidColorCenter extends IColorCenter.Skeleton<Color> {
 			/* Some filtering */
 			return filter.alter(red / 255f, green / 255f, blue / 255f, opacity / 255f);
 	}
-    @Override
-	public Color filter(Color c)
-    {
-        if(c == null)
-            return Color.CLEAR;
-        else
-        	return super.filter(c);
-    }
-    public Color get(long c)
-    {
-        return get((int)((c >> 24) & 0xff), (int)((c >> 16) & 0xff), (int)((c >> 8) & 0xff), (int)(c & 0xff));
-    }
-    public Color get(float r, float g, float b, float a)
-    {
-        return get(Math.round(255 * r), Math.round(255 * g), Math.round(255 * b), Math.round(255 * a));
-    }
-
-    /**
-     * Gets the linear interpolation from Color start to Color end, changing by the fraction given by change.
-     * @param start the initial Color
-     * @param end the "target" color
-     * @param change the degree to change closer to end; a change of 0.0f produces start, 1.0f produces end
-     * @return a new Color
-     */
-    @Override
-    public Color lerp(Color start, Color end, float change)
-    {
-        if(start == null || end == null)
-            return Color.CLEAR;
-        return get(
-                start.r + change * (end.r - start.r),
-                start.g + change * (end.g - start.g),
-                start.b + change * (end.b - start.b),
-                start.a + change * (end.a - start.a)
-        );
-    }
+
+	@Override
+	public Color filter(Color c) {
+		if (c == null)
+			return Color.CLEAR;
+		else
+			return super.filter(c);
+	}
+
+	public Color get(long c) {
+		return get((int) ((c >> 24) & 0xff), (int) ((c >> 16) & 0xff), (int) ((c >> 8) & 0xff), (int) (c & 0xff));
+	}
+
+	public Color get(float r, float g, float b, float a) {
+		return get(Math.round(255 * r), Math.round(255 * g), Math.round(255 * b), Math.round(255 * a));
+	}
+
+	/**
+	 * Gets the linear interpolation from Color start to Color end, changing by the
+	 * fraction given by change.
+	 * 
+	 * @param start
+	 *            the initial Color
+	 * @param end
+	 *            the "target" color
+	 * @param change
+	 *            the degree to change closer to end; a change of 0.0f produces
+	 *            start, 1.0f produces end
+	 * @return a new Color
+	 */
+	@Override
+	public Color lerp(Color start, Color end, float change) {
+		if (start == null || end == null)
+			return Color.CLEAR;
+		return get(start.r + change * (end.r - start.r), start.g + change * (end.g - start.g),
+				start.b + change * (end.b - start.b), start.a + change * (end.a - start.a));
+	}
+
 	@Override
 	public int getRed(Color c) {
 		return Math.round(c.r * 255f);
@@ -102,365 +106,360 @@ public class SquidColorCenter extends IColorCenter.Skeleton<Color> {
 		return Math.round(c.a * 255f);
 	}
 
-    public static int encode (Color color) {
-        if (color == null)
-            return 0;
-        return (Math.round(color.r * 255.0f) << 24)
-                | (Math.round(color.g * 255.0f) << 16)
-                | (Math.round(color.b * 255.0f) << 8)
-                | Math.round(color.a * 255.0f);
-    }
-
-    /**
-     * Gets a modified copy of color as if it is lit with a colored light source.
-     * @param color the color to shine the light on
-     * @param light the color of the light source
-     * @return a copy of the Color color that factors in the lighting of the Color light.
-     */
-    public Color lightWith(Color color, Color light)
-    {
-        return filter(color.cpy().mul(light));
-    }
-
-    /**
-     * Lightens a color by degree and returns the new color (mixed with white).
-     * @param color the color to lighten
-     * @param degree a float between 0.0f and 1.0f; more makes it lighter
-     * @return the lightened (and if a filter is used, also filtered) new color
-     */
-    public Color light(Color color, float degree)
-    {
-        return lerp(color, Color.WHITE, degree);
-    }
-    /**
-     * Lightens a color slightly and returns the new color (10% mix with white).
-     * @param color the color to lighten
-     * @return the lightened (and if a filter is used, also filtered) new color
-     */
-    public Color light(Color color)
-    {
-        return lerp(color, Color.WHITE, 0.1f);
-    }
-    /**
-     * Lightens a color significantly and returns the new color (30% mix with white).
-     * @param color the color to lighten
-     * @return the lightened (and if a filter is used, also filtered) new color
-     */
-    public Color lighter(Color color)
-    {
-        return lerp(color, Color.WHITE, 0.3f);
-    }
-    /**
-     * Lightens a color massively and returns the new color (70% mix with white).
-     * @param color the color to lighten
-     * @return the lightened (and if a filter is used, also filtered) new color
-     */
-    public Color lightest(Color color)
-    {
-        return lerp(color, Color.WHITE, 0.7f);
-    }
-
-    /**
-     * Darkens a color by the specified degree and returns the new color (mixed with black).
-     * @param color the color to darken
-     * @param degree a float between 0.0f and 1.0f; more makes it darker
-     * @return the darkened (and if a filter is used, also filtered) new color
-     */
-    public Color dim(Color color, float degree)
-    {
-        return lerp(color, Color.BLACK, degree);
-    }
-    /**
-     * Darkens a color slightly and returns the new color (10% mix with black).
-     * @param color the color to darken
-     * @return the darkened (and if a filter is used, also filtered) new color
-     */
-    public Color dim(Color color)
-    {
-        return lerp(color, Color.BLACK, 0.1f);
-    }
-    /**
-     * Darkens a color significantly and returns the new color (30% mix with black).
-     * @param color the color to darken
-     * @return the darkened (and if a filter is used, also filtered) new color
-     */
-    public Color dimmer(Color color)
-    {
-        return lerp(color, Color.BLACK, 0.3f);
-    }
-    /**
-     * Darkens a color massively and returns the new color (70% mix with black).
-     * @param color the color to darken
-     * @return the darkened (and if a filter is used, also filtered) new color
-     */
-    public Color dimmest(Color color)
-    {
-        return lerp(color, Color.BLACK, 0.7f);
-    }
-
-
-    /**
-     * Gets a fully-desaturated version of the given color (keeping its brightness, but making it grayscale).
-     * @param color the color to desaturate (will not be modified)
-     * @return the grayscale version of color
-     */
-    @Override
-    public Color desaturated(Color color)
-    {
-        float f = color.r * 0.299f + color.g * 0.587f + color.b * 0.114f;
-        return get(f, f, f, color.a);
-    }
-
-    /**
-     * Brings a color closer to grayscale by the specified degree and returns the new color (desaturated somewhat).
-     * @param color the color to desaturate
-     * @param degree a float between 0.0f and 1.0f; more makes it less colorful
-     * @return the desaturated (and if a filter is used, also filtered) new color
-     */
-    @Override
-    public Color desaturate(Color color, float degree)
-    {
-        return lerp(color, desaturated(color), degree);
-    }
-
-    /**
-     * Fully saturates color (makes it a vivid color like red or green and less gray) and returns the modified copy.
-     * Leaves alpha unchanged.
-     *
-     * @param color the color T to saturate (will not be modified)
-     * @return the saturated version of color
-     */
-    @Override
-    public Color saturated(Color color) {
-        return getHSV(getHue(color), 1f, getValue(color), getAlpha(color));
-    }
-
-    /**
-     * Saturates color (makes it closer to a vivid color like red or green and less gray) by the specified degree and
-     * returns the new color (saturated somewhat). If this is called on a color that is very close to gray, this is
-     * likely to produce a red hue by default (if there's no hue to make vivid, it needs to choose something).
-     * @param color the color to saturate
-     * @param degree a float between 0.0f and 1.0f; more makes it more colorful
-     * @return the saturated (and if a filter is used, also filtered) new color
-     */
-    @Override
-    public Color saturate(Color color, float degree)
-    {
-        return lerp(color, saturated(color), degree);
-    }
-    /**
-     * Gets a fully random color that is only required to be opaque.
-     * @return a random Color
-     */
-    public Color random()
-    {
-        StatefulRNG rng = DefaultResources.getGuiRandom();
-        return get(rng.nextFloat(), rng.nextFloat(), rng.nextFloat(), 1f);
-    }
-
-    /**
-     * Blends a color with a random (opaque) color by a factor of 10% random.
-     * @param color the color to randomize
-     * @return the randomized (and if a filter is used, also filtered) new color
-     */
-    public Color randomize(Color color)
-    {
-        return lerp(color, random(), 0.1f);
-    }
-    /**
-     * Blends a color with a random (opaque) color by a factor of 30% random.
-     * @param color the color to randomize
-     * @return the randomized (and if a filter is used, also filtered) new color
-     */
-    public Color randomizeMore(Color color)
-    {
-        return lerp(color, random(), 0.3f);
-    }
-    /**
-     * Blends a color with a random (opaque) color by a factor of 70% random.
-     * @param color the color to randomize
-     * @return the randomized (and if a filter is used, also filtered) new color
-     */
-    public Color randomizeMost(Color color)
-    {
-        return lerp(color, random(), 0.7f);
-    }
-
-    /**
-     * Blends the colors A and B by a random degree.
-     * @param a a color to mix in
-     * @param b another color to mix in
-     * @return a random blend of a and b.
-     */
-    public Color randomBlend(Color a, Color b)
-    {
-        return lerp(a, b, DefaultResources.getGuiRandom().nextFloat());
-    }
-
-    /**
-     * Finds a 16-step gradient going from fromColor to toColor, both included in the gradient.
-     * @param fromColor the color to start with, included in the gradient
-     * @param toColor the color to end on, included in the gradient
-     * @return a 16-element ArrayList composed of the blending steps from fromColor to toColor
-     */
-    public ArrayList<Color> gradient(Color fromColor, Color toColor)
-    {
-        ArrayList<Color> colors = new ArrayList<>(16);
-        for (int i = 0; i < 16; i++) {
-            colors.add(lerp(fromColor, toColor, i / 15f));
-        }
-        return colors;
-    }
-
-    /**
-     * Finds a gradient with the specified number of steps going from fromColor to toColor,
-     * both included in the gradient.
-     * @param fromColor the color to start with, included in the gradient
-     * @param toColor the color to end on, included in the gradient
-     * @param steps the number of elements to use in the gradient
-     * @return an ArrayList composed of the blending steps from fromColor to toColor, with length equal to steps
-     */
-    public ArrayList<Color> gradient(Color fromColor, Color toColor, int steps)
-    {
-        return gradient(fromColor, toColor, steps, Interpolation.linear);
-    }
-
-
-    /**
-     * Finds a gradient with the specified number of steps going from fromColor to midColor, then midColor to (possibly)
-     * fromColor, with both included in the gradient but fromColor only repeated at the end if the number of steps is odd.
-     * @param fromColor the color to start with (and end with, if steps is an odd number), included in the gradient
-     * @param midColor the color to use in the middle of the loop, included in the gradient
-     * @param steps the number of elements to use in the gradient, will be at least 3
-     * @return an ArrayList composed of the blending steps from fromColor to midColor to fromColor again, with length equal to steps
-     */
-    public ArrayList<Color> loopingGradient(Color fromColor, Color midColor, int steps)
-    {
-        return loopingGradient(fromColor, midColor, steps, Interpolation.linear);
-    }
-
-    /**
-     * Finds a gradient with the specified number of steps going from fromColor to toColor, both included in the
-     * gradient. The interpolation argument can be used to make the color stay close to fromColor and/or toColor longer
-     * than it would normally, or shorter if the middle colors are desirable.
-     * @param fromColor the color to start with, included in the gradient
-     * @param toColor the color to end on, included in the gradient
-     * @param steps the number of elements to use in the gradient
-     * @param interpolation a libGDX Interpolation that defines how quickly the color changes during the transition
-     * @return an ArrayList composed of the blending steps from fromColor to toColor, with length equal to steps
-     */
-    public ArrayList<Color> gradient(Color fromColor, Color toColor, int steps, Interpolation interpolation)
-    {
-        ArrayList<Color> colors = new ArrayList<>((steps > 1) ? steps : 1);
-        colors.add(filter(fromColor));
-        if(steps < 2)
-            return colors;
-        for (float i = 1; i < steps; i++) {
-            colors.add(lerp(fromColor, toColor, interpolation.apply(i / (steps - 1))));
-        }
-        return colors;
-    }
-
-    /**
-     * Finds a gradient with the specified number of steps going from fromColor to midColor, then midColor to (possibly)
-     * fromColor, with both included in the gradient but fromColor only repeated at the end if the number of steps is
-     * odd. The interpolation argument can be used to make the color linger for a while with colors close to fromColor
-     * or midColor, or to do the opposite and quickly change from one and spend more time in the middle.
-     * @param fromColor the color to start with (and end with, if steps is an odd number), included in the gradient
-     * @param midColor the color to use in the middle of the loop, included in the gradient
-     * @param steps the number of elements to use in the gradient, will be at least 3
-     * @param interpolation a libGDX Interpolation that defines how quickly the color changes at the start and end of
-     *                      each transition, both from fromColor to midColor as well as back to fromColor
-     * @return an ArrayList composed of the blending steps from fromColor to midColor to fromColor again, with length equal to steps
-     */
-    public ArrayList<Color> loopingGradient(Color fromColor, Color midColor, int steps, Interpolation interpolation)
-    {
-        ArrayList<Color> colors = new ArrayList<>((steps > 3) ? steps : 3);
-        colors.add(filter(fromColor));
-        for (float i = 1; i < steps / 2; i++) {
-            colors.add(lerp(fromColor, midColor, interpolation.apply(i / (steps / 2))));
-        }
-        for (float i = 0, c = steps / 2; c < steps; i++, c++) {
-            colors.add(lerp(midColor, fromColor, interpolation.apply(i / (steps / 2))));
-        }
-        return colors;
-    }
-
-    /**
-     * Generates a hue-shifted rainbow of colors, starting at red and going through orange, yellow, green, blue, and
-     * purple before getting close to red at the end again. If the given number of steps is less than 6 or so, you should
-     * expect to see only some of those colors; if steps is larger (36 may be reasonable for gradients), you are more
-     * likely to see colors that appear for shorter spans on the color wheel, like orange.
-     * Produces fully saturated and max-brightness colors on the rainbow, which is what many people expect for a rainbow.
-     * @param steps the number of different Color elements to generate in the returned ArrayList
-     * @return an ArrayList of Color where each element goes around the color wheel, starting at red, then orange, etc.
-     */
-    public ArrayList<Color> rainbow(int steps)
-    {
-        return rainbow(1.0f, 1.0f, steps);
-    }
-
-    /**
-     * Generates a hue-shifted rainbow of colors, starting at red and going through orange, yellow, green, blue, and
-     * purple before getting close to red at the end again. If the given number of steps is less than 6 or so, you should
-     * expect to see only some of those colors; if steps is larger (36 may be reasonable for gradients), you are more
-     * likely to see colors that appear for shorter spans on the color wheel, like orange.
-     * Uses the given saturation and value for all colors in the rainbow, and only changes hue.
-     * @param saturation the saturation of the rainbow's colors; 1.0 is boldest and 0.0 is grayscale
-     * @param value the brightness of the rainbow's colors; 1.0 is brightest
-     * @param steps the number of different Color elements to generate in the returned ArrayList
-     * @return an ArrayList of Color where each element goes around the color wheel, starting at red, then orange, etc.
-     */
-    public ArrayList<Color> rainbow(float saturation, float value, int steps)
-    {
-        steps = (steps > 1) ? steps : 1;
-        ArrayList<Color> colors = new ArrayList<>(steps);
-        for (float i = 0; i < 1f - 0.5f / steps; i+= 1.0f / steps) {
-            colors.add(filter(getHSV(i, saturation, value)));
-        }
-        return colors;
-    }
-
-    /**
-     * Finds a gradient with the specified number of steps going from fromColor to toColor, both included in the
-     * gradient. This does not typically take a direct path on its way between fromColor and toColor, and is useful to
-     * generate a wide variety of colors that can be confined to a rough amount of maximum difference by choosing values
-     * for fromColor and toColor that are more similar.
-     * <br>
-     * Try using colors for fromColor and toColor that have different r, g, and b values, such as gray and white, then
-     * compare to colors that don't differ on, for example, r, such as bright red and pink. In the first case, red,
-     * green, blue, and many other colors will be generated if there are enough steps; in the second case, red will be
-     * at the same level in all generated colors (very high, so no pure blue or pure green, but purple and yellow are
-     * possible). This should help illustrate how this chooses how far to "zig-zag" off the straight-line path.
-     * @param fromColor the color to start with, included in the gradient
-     * @param toColor the color to end on, included in the gradient
-     * @param steps the number of elements to use in the gradient; ideally no greater than 345 to avoid duplicates
-     * @return an ArrayList composed of the zig-zag steps from fromColor to toColor, with length equal to steps
-     */
-    public ArrayList<Color> zigzagGradient(Color fromColor, Color toColor, int steps)
-    {
-        ArrayList<Color> colors = new ArrayList<>((steps > 1) ? steps : 1);
-        colors.add(filter(fromColor));
-        if(steps < 2)
-            return colors;
-        float dr = toColor.r - fromColor.r, dg = toColor.g - fromColor.g, db = toColor.b - fromColor.b,
-                a = fromColor.a, cr, cg, cb;
-        int decoded;
-        for (float i = 1; i < steps; i++) {
-            // 345 happens to be the distance on our 3D Hilbert curve that corresponds to (7,7,7).
-            decoded = Math.round(345 * (i / (steps - 1)));
-            cr = (CoordPacker.hilbert3X[decoded] / 7f) * dr + fromColor.r;
-            cg = (CoordPacker.hilbert3Y[decoded] / 7f) * dg + fromColor.g;
-            cb = (CoordPacker.hilbert3Z[decoded] / 7f) * db + fromColor.b;
-            colors.add(get(cr, cg, cb, a));
-        }
-        return colors;
-    }
-
-    @Override
-    public String toString() {
-        return "SquidColorCenter{" +
-                "filter=" + (filter == null ? "null" : filter.getClass().getSimpleName()) +
-                '}';
-    }
+	public static int encode(Color color) {
+		if (color == null)
+			return 0;
+		return (Math.round(color.r * 255.0f) << 24) | (Math.round(color.g * 255.0f) << 16)
+				| (Math.round(color.b * 255.0f) << 8) | Math.round(color.a * 255.0f);
+	}
+
+	/**
+	 * Gets a modified copy of color as if it is lit with a colored light source.
+	 * 
+	 * @param color
+	 *            the color to shine the light on
+	 * @param light
+	 *            the color of the light source
+	 * @return a copy of the Color color that factors in the lighting of the Color
+	 *         light.
+	 */
+	public Color lightWith(Color color, Color light) {
+		return filter(color.cpy().mul(light));
+	}
+
+	/**
+	 * Lightens a color by degree and returns the new color (mixed with white).
+	 * 
+	 * @param color
+	 *            the color to lighten
+	 * @param degree
+	 *            a float between 0.0f and 1.0f; more makes it lighter
+	 * @return the lightened (and if a filter is used, also filtered) new color
+	 */
+	public Color light(Color color, float degree) {
+		return lerp(color, Color.WHITE, degree);
+	}
+
+	/**
+	 * Lightens a color slightly and returns the new color (10% mix with white).
+	 * 
+	 * @param color
+	 *            the color to lighten
+	 * @return the lightened (and if a filter is used, also filtered) new color
+	 */
+	public Color light(Color color) {
+		return lerp(color, Color.WHITE, 0.1f);
+	}
+
+	/**
+	 * Lightens a color significantly and returns the new color (30% mix with
+	 * white).
+	 * 
+	 * @param color
+	 *            the color to lighten
+	 * @return the lightened (and if a filter is used, also filtered) new color
+	 */
+	public Color lighter(Color color) {
+		return lerp(color, Color.WHITE, 0.3f);
+	}
+
+	/**
+	 * Lightens a color massively and returns the new color (70% mix with white).
+	 * 
+	 * @param color
+	 *            the color to lighten
+	 * @return the lightened (and if a filter is used, also filtered) new color
+	 */
+	public Color lightest(Color color) {
+		return lerp(color, Color.WHITE, 0.7f);
+	}
+
+	/**
+	 * Darkens a color by the specified degree and returns the new color (mixed with
+	 * black).
+	 * 
+	 * @param color
+	 *            the color to darken
+	 * @param degree
+	 *            a float between 0.0f and 1.0f; more makes it darker
+	 * @return the darkened (and if a filter is used, also filtered) new color
+	 */
+	public Color dim(Color color, float degree) {
+		return lerp(color, Color.BLACK, degree);
+	}
+
+	/**
+	 * Darkens a color slightly and returns the new color (10% mix with black).
+	 * 
+	 * @param color
+	 *            the color to darken
+	 * @return the darkened (and if a filter is used, also filtered) new color
+	 */
+	public Color dim(Color color) {
+		return lerp(color, Color.BLACK, 0.1f);
+	}
+
+	/**
+	 * Darkens a color significantly and returns the new color (30% mix with black).
+	 * 
+	 * @param color
+	 *            the color to darken
+	 * @return the darkened (and if a filter is used, also filtered) new color
+	 */
+	public Color dimmer(Color color) {
+		return lerp(color, Color.BLACK, 0.3f);
+	}
+
+	/**
+	 * Darkens a color massively and returns the new color (70% mix with black).
+	 * 
+	 * @param color
+	 *            the color to darken
+	 * @return the darkened (and if a filter is used, also filtered) new color
+	 */
+	public Color dimmest(Color color) {
+		return lerp(color, Color.BLACK, 0.7f);
+	}
+
+	/**
+	 * Gets a fully-desaturated version of the given color (keeping its brightness,
+	 * but making it grayscale).
+	 * 
+	 * @param color
+	 *            the color to desaturate (will not be modified)
+	 * @return the grayscale version of color
+	 */
+	@Override
+	public Color desaturated(Color color) {
+		float f = color.r * 0.299f + color.g * 0.587f + color.b * 0.114f;
+		return get(f, f, f, color.a);
+	}
+
+	/**
+	 * Gets a fully random color that is only required to be opaque.
+	 * 
+	 * @return a random Color
+	 */
+	public Color random() {
+		StatefulRNG rng = DefaultResources.getGuiRandom();
+		return get(rng.nextFloat(), rng.nextFloat(), rng.nextFloat(), 1f);
+	}
+
+	/**
+	 * Blends a color with a random (opaque) color by a factor of 10% random.
+	 * 
+	 * @param color
+	 *            the color to randomize
+	 * @return the randomized (and if a filter is used, also filtered) new color
+	 */
+	public Color randomize(Color color) {
+		return lerp(color, random(), 0.1f);
+	}
+
+	/**
+	 * Blends a color with a random (opaque) color by a factor of 30% random.
+	 * 
+	 * @param color
+	 *            the color to randomize
+	 * @return the randomized (and if a filter is used, also filtered) new color
+	 */
+	public Color randomizeMore(Color color) {
+		return lerp(color, random(), 0.3f);
+	}
+
+	/**
+	 * Blends a color with a random (opaque) color by a factor of 70% random.
+	 * 
+	 * @param color
+	 *            the color to randomize
+	 * @return the randomized (and if a filter is used, also filtered) new color
+	 */
+	public Color randomizeMost(Color color) {
+		return lerp(color, random(), 0.7f);
+	}
+
+	/**
+	 * Blends the colors A and B by a random degree.
+	 * 
+	 * @param a
+	 *            a color to mix in
+	 * @param b
+	 *            another color to mix in
+	 * @return a random blend of a and b.
+	 */
+	public Color randomBlend(Color a, Color b) {
+		return lerp(a, b, DefaultResources.getGuiRandom().nextFloat());
+	}
+
+	/**
+	 * Finds a 16-step gradient going from fromColor to toColor, both included in
+	 * the gradient.
+	 * 
+	 * @param fromColor
+	 *            the color to start with, included in the gradient
+	 * @param toColor
+	 *            the color to end on, included in the gradient
+	 * @return a 16-element ArrayList composed of the blending steps from fromColor
+	 *         to toColor
+	 */
+	public ArrayList<Color> gradient(Color fromColor, Color toColor) {
+		ArrayList<Color> colors = new ArrayList<>(16);
+		for (int i = 0; i < 16; i++) {
+			colors.add(lerp(fromColor, toColor, i / 15f));
+		}
+		return colors;
+	}
+
+	/**
+	 * Finds a gradient with the specified number of steps going from fromColor to
+	 * toColor, both included in the gradient.
+	 * 
+	 * @param fromColor
+	 *            the color to start with, included in the gradient
+	 * @param toColor
+	 *            the color to end on, included in the gradient
+	 * @param steps
+	 *            the number of elements to use in the gradient
+	 * @return an ArrayList composed of the blending steps from fromColor to
+	 *         toColor, with length equal to steps
+	 */
+	public ArrayList<Color> gradient(Color fromColor, Color toColor, int steps) {
+		return gradient(fromColor, toColor, steps, Interpolation.linear);
+	}
+
+	/**
+	 * Finds a gradient with the specified number of steps going from fromColor to
+	 * midColor, then midColor to (possibly) fromColor, with both included in the
+	 * gradient but fromColor only repeated at the end if the number of steps is
+	 * odd.
+	 * 
+	 * @param fromColor
+	 *            the color to start with (and end with, if steps is an odd number),
+	 *            included in the gradient
+	 * @param midColor
+	 *            the color to use in the middle of the loop, included in the
+	 *            gradient
+	 * @param steps
+	 *            the number of elements to use in the gradient, will be at least 3
+	 * @return an ArrayList composed of the blending steps from fromColor to
+	 *         midColor to fromColor again, with length equal to steps
+	 */
+	public ArrayList<Color> loopingGradient(Color fromColor, Color midColor, int steps) {
+		return loopingGradient(fromColor, midColor, steps, Interpolation.linear);
+	}
+
+	/**
+	 * Finds a gradient with the specified number of steps going from fromColor to
+	 * toColor, both included in the gradient. The interpolation argument can be
+	 * used to make the color stay close to fromColor and/or toColor longer than it
+	 * would normally, or shorter if the middle colors are desirable.
+	 * 
+	 * @param fromColor
+	 *            the color to start with, included in the gradient
+	 * @param toColor
+	 *            the color to end on, included in the gradient
+	 * @param steps
+	 *            the number of elements to use in the gradient
+	 * @param interpolation
+	 *            a libGDX Interpolation that defines how quickly the color changes
+	 *            during the transition
+	 * @return an ArrayList composed of the blending steps from fromColor to
+	 *         toColor, with length equal to steps
+	 */
+	public ArrayList<Color> gradient(Color fromColor, Color toColor, int steps, Interpolation interpolation) {
+		ArrayList<Color> colors = new ArrayList<>((steps > 1) ? steps : 1);
+		colors.add(filter(fromColor));
+		if (steps < 2)
+			return colors;
+		for (float i = 1; i < steps; i++) {
+			colors.add(lerp(fromColor, toColor, interpolation.apply(i / (steps - 1))));
+		}
+		return colors;
+	}
+
+	/**
+	 * Finds a gradient with the specified number of steps going from fromColor to
+	 * midColor, then midColor to (possibly) fromColor, with both included in the
+	 * gradient but fromColor only repeated at the end if the number of steps is
+	 * odd. The interpolation argument can be used to make the color linger for a
+	 * while with colors close to fromColor or midColor, or to do the opposite and
+	 * quickly change from one and spend more time in the middle.
+	 * 
+	 * @param fromColor
+	 *            the color to start with (and end with, if steps is an odd number),
+	 *            included in the gradient
+	 * @param midColor
+	 *            the color to use in the middle of the loop, included in the
+	 *            gradient
+	 * @param steps
+	 *            the number of elements to use in the gradient, will be at least 3
+	 * @param interpolation
+	 *            a libGDX Interpolation that defines how quickly the color changes
+	 *            at the start and end of each transition, both from fromColor to
+	 *            midColor as well as back to fromColor
+	 * @return an ArrayList composed of the blending steps from fromColor to
+	 *         midColor to fromColor again, with length equal to steps
+	 */
+	public ArrayList<Color> loopingGradient(Color fromColor, Color midColor, int steps, Interpolation interpolation) {
+		ArrayList<Color> colors = new ArrayList<>((steps > 3) ? steps : 3);
+		colors.add(filter(fromColor));
+		for (float i = 1; i < steps / 2; i++) {
+			colors.add(lerp(fromColor, midColor, interpolation.apply(i / (steps / 2))));
+		}
+		for (float i = 0, c = steps / 2; c < steps; i++, c++) {
+			colors.add(lerp(midColor, fromColor, interpolation.apply(i / (steps / 2))));
+		}
+		return colors;
+	}
+
+	/**
+	 * Finds a gradient with the specified number of steps going from fromColor to
+	 * toColor, both included in the gradient. This does not typically take a direct
+	 * path on its way between fromColor and toColor, and is useful to generate a
+	 * wide variety of colors that can be confined to a rough amount of maximum
+	 * difference by choosing values for fromColor and toColor that are more
+	 * similar. <br>
+	 * Try using colors for fromColor and toColor that have different r, g, and b
+	 * values, such as gray and white, then compare to colors that don't differ on,
+	 * for example, r, such as bright red and pink. In the first case, red, green,
+	 * blue, and many other colors will be generated if there are enough steps; in
+	 * the second case, red will be at the same level in all generated colors (very
+	 * high, so no pure blue or pure green, but purple and yellow are possible).
+	 * This should help illustrate how this chooses how far to "zig-zag" off the
+	 * straight-line path.
+	 * 
+	 * @param fromColor
+	 *            the color to start with, included in the gradient
+	 * @param toColor
+	 *            the color to end on, included in the gradient
+	 * @param steps
+	 *            the number of elements to use in the gradient; ideally no greater
+	 *            than 345 to avoid duplicates
+	 * @return an ArrayList composed of the zig-zag steps from fromColor to toColor,
+	 *         with length equal to steps
+	 */
+	public ArrayList<Color> zigzagGradient(Color fromColor, Color toColor, int steps) {
+		ArrayList<Color> colors = new ArrayList<>((steps > 1) ? steps : 1);
+		colors.add(filter(fromColor));
+		if (steps < 2)
+			return colors;
+		float dr = toColor.r - fromColor.r, dg = toColor.g - fromColor.g, db = toColor.b - fromColor.b, a = fromColor.a,
+				cr, cg, cb;
+		int decoded;
+		for (float i = 1; i < steps; i++) {
+			// 345 happens to be the distance on our 3D Hilbert curve that corresponds to
+			// (7,7,7).
+			decoded = Math.round(345 * (i / (steps - 1)));
+			cr = (CoordPacker.hilbert3X[decoded] / 7f) * dr + fromColor.r;
+			cg = (CoordPacker.hilbert3Y[decoded] / 7f) * dg + fromColor.g;
+			cb = (CoordPacker.hilbert3Z[decoded] / 7f) * db + fromColor.b;
+			colors.add(get(cr, cg, cb, a));
+		}
+		return colors;
+	}
+
+	@Override
+	public String toString() {
+		return "SquidColorCenter{" + "filter=" + (filter == null ? "null" : filter.getClass().getSimpleName()) + '}';
+	}
 }

Fichier diff supprimé car celui-ci est trop grand
+ 1178 - 1119
squidlib/src/main/java/squidpony/squidgrid/gui/gdx/SquidPanel.java