/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* $Id: ColorWithAlternatives.java 1804124 2017-08-04 14:13:54Z ssteiner $ */

package org.apache.xmlgraphics.java2d.color;

import java.awt.Color;
import java.awt.color.ColorSpace;
import java.util.Arrays;

Extended Color class allowing to specify a prioritized list of alternative colors. The alternative colors shall be the ones that are preferred if an output format supports them. This is normally used for passing device-specific colors through to the output format.

This class only adds a single reference to a color array which should not increase memory consumption by much if no alternative colors are specified.

Important: Due to a flaw in Color.equals(Object), the equals() method should not be used to compare two colors, especially when used to update the current color for some output format. Color only takes the sRGB values into account but not more the advanced facets of this class. Use ColorUtil.isSameColor(Color, Color) for such a check.

/** * Extended {@link Color} class allowing to specify a prioritized list of alternative colors. * The alternative colors shall be the ones that are preferred if an output format supports them. * This is normally used for passing device-specific colors through to the output format. * <p> * This class only adds a single reference to a color array which should not increase memory * consumption by much if no alternative colors are specified. * <p> * <b>Important:</b> Due to a flaw in {@link Color#equals(Object)}, the <code>equals()</code> * method should not be used to compare two colors, especially when used to update the current * color for some output format. {@link Color} only takes the sRGB values into account but not * more the advanced facets of this class. Use {@link ColorUtil#isSameColor(Color, Color)} for * such a check. */
public class ColorWithAlternatives extends Color { private static final long serialVersionUID = -6125884937776779150L; private Color[] alternativeColors;
Constructor for RGBA colors.
Params:
  • r – the red component
  • g – the green component
  • b – the blue component
  • a – the alpha component
  • alternativeColors – the prioritized list of alternative colors.
See Also:
/** * Constructor for RGBA colors. * @param r the red component * @param g the green component * @param b the blue component * @param a the alpha component * @param alternativeColors the prioritized list of alternative colors. * @see Color#Color(float, float, float, float) */
public ColorWithAlternatives(float r, float g, float b, float a, Color[] alternativeColors) { super(r, g, b, a); initAlternativeColors(alternativeColors); }
Constructor for RGB colors.
Params:
  • r – the red component
  • g – the green component
  • b – the blue component
  • alternativeColors – the prioritized list of alternative colors.
See Also:
/** * Constructor for RGB colors. * @param r the red component * @param g the green component * @param b the blue component * @param alternativeColors the prioritized list of alternative colors. * @see Color#Color(float, float, float) */
public ColorWithAlternatives(float r, float g, float b, Color[] alternativeColors) { super(r, g, b); initAlternativeColors(alternativeColors); }
Constructor for RGBA colors.
Params:
  • rgba – the combined RGBA value
  • hasalpha – true if the alpha bits are valid, false otherwise
  • alternativeColors – the prioritized list of alternative colors.
See Also:
/** * Constructor for RGBA colors. * @param rgba the combined RGBA value * @param hasalpha true if the alpha bits are valid, false otherwise * @param alternativeColors the prioritized list of alternative colors. * @see Color#Color(int, boolean) */
public ColorWithAlternatives(int rgba, boolean hasalpha, Color[] alternativeColors) { super(rgba, hasalpha); initAlternativeColors(alternativeColors); }
Constructor for RGBA colors.
Params:
  • r – the red component
  • g – the green component
  • b – the blue component
  • a – the alpha component
  • alternativeColors – the prioritized list of alternative colors.
See Also:
/** * Constructor for RGBA colors. * @param r the red component * @param g the green component * @param b the blue component * @param a the alpha component * @param alternativeColors the prioritized list of alternative colors. * @see Color#Color(int, int, int, int) */
public ColorWithAlternatives(int r, int g, int b, int a, Color[] alternativeColors) { super(r, g, b, a); initAlternativeColors(alternativeColors); }
Constructor for RGB colors.
Params:
  • r – the red component
  • g – the green component
  • b – the blue component
  • alternativeColors – the prioritized list of alternative colors.
See Also:
/** * Constructor for RGB colors. * @param r the red component * @param g the green component * @param b the blue component * @param alternativeColors the prioritized list of alternative colors. * @see Color#Color(int, int, int) */
public ColorWithAlternatives(int r, int g, int b, Color[] alternativeColors) { super(r, g, b); initAlternativeColors(alternativeColors); }
Constructor for RGB colors.
Params:
  • rgb – the combined RGB components
  • alternativeColors – the prioritized list of alternative colors.
See Also:
/** * Constructor for RGB colors. * @param rgb the combined RGB components * @param alternativeColors the prioritized list of alternative colors. * @see Color#Color(int) */
public ColorWithAlternatives(int rgb, Color[] alternativeColors) { super(rgb); initAlternativeColors(alternativeColors); }
Constructor for colors with an arbitrary color space.
Params:
  • cspace – the color space
  • components – the color components
  • alpha – the alpha component
  • alternativeColors – the prioritized list of alternative colors.
See Also:
/** * Constructor for colors with an arbitrary color space. * @param cspace the color space * @param components the color components * @param alpha the alpha component * @param alternativeColors the prioritized list of alternative colors. * @see Color#Color(ColorSpace, float[], float) */
public ColorWithAlternatives(ColorSpace cspace, float[] components, float alpha, Color[] alternativeColors) { super(cspace, components, alpha); initAlternativeColors(alternativeColors); } private void initAlternativeColors(Color[] colors) { if (colors != null) { //Colors are immutable but array are not, so copy this.alternativeColors = new Color[colors.length]; System.arraycopy(colors, 0, this.alternativeColors, 0, colors.length); } }
Returns the list of alternative colors. An empty array will be returned if no alternative colors are available.
Returns:the list of alternative colors
/** * Returns the list of alternative colors. An empty array will be returned if no alternative * colors are available. * @return the list of alternative colors */
public Color[] getAlternativeColors() { if (this.alternativeColors != null) { Color[] cols = new Color[this.alternativeColors.length]; System.arraycopy(this.alternativeColors, 0, cols, 0, this.alternativeColors.length); return cols; } else { return new Color[0]; } }
Indicates whether alternative colors are available.
Returns:true if alternative colors are available.
/** * Indicates whether alternative colors are available. * @return true if alternative colors are available. */
public boolean hasAlternativeColors() { return this.alternativeColors != null && this.alternativeColors.length > 0; }
Indicates whether another instance has the same alternative colors.
Params:
  • col – the color to compare the alternatives to
Returns:true if the same alternative colors are present
/** * Indicates whether another instance has the same alternative colors. * @param col the color to compare the alternatives to * @return true if the same alternative colors are present */
public boolean hasSameAlternativeColors(ColorWithAlternatives col) { if (!hasAlternativeColors()) { return !col.hasAlternativeColors(); } // this.hasAlternativeColors() if (!col.hasAlternativeColors()) { return false; } // this.hasAlternativeColors() && col.hasAlternativeColors() Color[] alt1 = getAlternativeColors(); Color[] alt2 = col.getAlternativeColors(); if (alt1.length != alt2.length) { return false; } for (int i = 0, c = alt1.length; i < c; i++) { Color c1 = alt1[i]; Color c2 = alt2[i]; if (!ColorUtil.isSameColor(c1, c2)) { return false; } } return true; }
Returns the first alternative color found with the given color space type.
Params:
  • colorSpaceType – the color space type (ColorSpace.TYPE_*).
Returns:the requested alternative color or null, if no match was found
/** * Returns the first alternative color found with the given color space type. * @param colorSpaceType the color space type ({@link ColorSpace}.TYPE_*). * @return the requested alternative color or null, if no match was found */
public Color getFirstAlternativeOfType(int colorSpaceType) { if (hasAlternativeColors()) { for (Color alternativeColor : this.alternativeColors) { if (alternativeColor.getColorSpace().getType() == colorSpaceType) { return alternativeColor; } } } return null; } public int hashCode() { int hash = super.hashCode(); if (alternativeColors != null) { hash = 37 * hash + Arrays.hashCode(alternativeColors); } return hash; } }