diff --git a/src/java/org/apache/xmlgraphics/java2d/color/ColorConverter.java b/src/java/org/apache/xmlgraphics/java2d/color/ColorConverter.java index 24a06b5b..25dc7d68 100644 --- a/src/java/org/apache/xmlgraphics/java2d/color/ColorConverter.java +++ b/src/java/org/apache/xmlgraphics/java2d/color/ColorConverter.java @@ -1,36 +1,36 @@ -/* - * 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:$ */ - -package org.apache.xmlgraphics.java2d.color; - -import java.awt.Color; - -/** - * Utility for implementing a color conversion scheme. - */ -public interface ColorConverter { - - /** - * @param color to convert - * @return converted color - */ - - Color convert(Color color); - -} +/* + * 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$ */ + +package org.apache.xmlgraphics.java2d.color; + +import java.awt.Color; + +/** + * Utility for implementing a color conversion scheme. + */ +public interface ColorConverter { + + /** + * @param color to convert + * @return converted color + */ + + Color convert(Color color); + +} diff --git a/src/java/org/apache/xmlgraphics/java2d/color/ColorUtil.java b/src/java/org/apache/xmlgraphics/java2d/color/ColorUtil.java index 3b35006c..9708d857 100644 --- a/src/java/org/apache/xmlgraphics/java2d/color/ColorUtil.java +++ b/src/java/org/apache/xmlgraphics/java2d/color/ColorUtil.java @@ -1,165 +1,165 @@ -/* - * 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: ColorUtil.java 815938 2009-09-16 19:38:13Z jeremias $ */ - -package org.apache.xmlgraphics.java2d.color; - -import java.awt.Color; - - -/** - * Generic Color helper class. - *
- * This class supports parsing string values into color values and creating - * color values for strings. It provides a list of standard color names. - */ -public final class ColorUtil { - - /** - * Private constructor since this is an utility class. - */ - private ColorUtil() { - } - - - /** - * Lightens up a color for groove, ridge, inset and outset border effects. - * @param col the color to lighten up - * @param factor factor by which to lighten up (negative values darken the color) - * @return the modified color - */ - public static Color lightenColor(Color col, float factor) { - // TODO: This function converts the color into the sRGB namespace. - // This should be avoided if possible. - float[] cols = new float[4]; - cols = col.getRGBComponents(cols); - if (factor > 0) { - cols[0] += (1.0 - cols[0]) * factor; - cols[1] += (1.0 - cols[1]) * factor; - cols[2] += (1.0 - cols[2]) * factor; - } else { - cols[0] -= cols[0] * -factor; - cols[1] -= cols[1] * -factor; - cols[2] -= cols[2] * -factor; - } - return new ColorWithAlternatives(cols[0], cols[1], cols[2], cols[3], null); - } - - - - /** - * Indicates whether the color is a gray value. - * @param col the color - * @return true if it is a gray value - */ - public static boolean isGray(Color col) { - return (col.getRed() == col.getBlue() && col.getRed() == col.getGreen()); - } - - /** - * Creates an uncalibrated CMYK color with the given gray value. - * @param black the gray component (0 - 1) - * @return the CMYK color - */ - public static Color toCMYKGrayColor(float black) { - //Calculated color components - float[] cmyk = new float[] {0f, 0f, 0f, 1.0f - black}; - //Create native color - return DeviceCMYKColorSpace.createCMYKColor(cmyk); - } - - /** - * Converts an arbitrary {@link Color} to a plain sRGB color doing the conversion at the - * best possible conversion quality. - * @param col the original color - * @return the sRGB equivalent - */ - public static Color toSRGBColor(Color col) { - if (col.getColorSpace().isCS_sRGB()) { - return col; //Don't convert if already sRGB to avoid conversion differences - } - float[] comps = col.getColorComponents(null); - float[] srgb = col.getColorSpace().toRGB(comps); - comps = col.getComponents(null); - float alpha = comps[comps.length - 1]; - return new Color(srgb[0], srgb[1], srgb[2], alpha); - } - - /** - * Checks if two colors are the same color. This check is much more restrictive than - * {@link Color#equals(Object)} in that it doesn't only check if both colors result in the - * same sRGB value. For example, if two colors not of the same exact class are compared, - * they are treated as not the same. - *
- * Note: At the moment, this method only supports {@link Color} and - * {@link ColorWithAlternatives} only. Other subclasses of {@link Color} are checked only using - * the {@link Color#equals(Object)} method. - * @param col1 the first color - * @param col2 the second color - * @return true if both colors are the same color - */ - public static boolean isSameColor(Color col1, Color col2) { - //Check fallback sRGB values first, then go into details - if (!col1.equals(col2)) { - return false; - } - - //Consider same-ness only between colors of the same class (not subclasses) - //but consider a ColorWithAlternatives without alternatives to be the same as a Color. - Class> cl1 = col1.getClass(); - if (col1 instanceof ColorWithAlternatives - && !((ColorWithAlternatives) col1).hasAlternativeColors()) { - cl1 = Color.class; - } - Class> cl2 = col2.getClass(); - if (col2 instanceof ColorWithAlternatives - && !((ColorWithAlternatives) col2).hasAlternativeColors()) { - cl2 = Color.class; - } - if (cl1 != cl2) { - return false; - } - - //Check color space - if (!col1.getColorSpace().equals(col2.getColorSpace())) { - return false; - } - - //Check native components - float[] comps1 = col1.getComponents(null); - float[] comps2 = col2.getComponents(null); - if (comps1.length != comps2.length) { - return false; - } - for (int i = 0, c = comps1.length; i < c; i++) { - if (comps1[i] != comps2[i]) { - return false; - } - } - - //Compare alternative colors, order is relevant - if (col1 instanceof ColorWithAlternatives && col2 instanceof ColorWithAlternatives) { - ColorWithAlternatives ca1 = (ColorWithAlternatives) col1; - ColorWithAlternatives ca2 = (ColorWithAlternatives) col2; - return ca1.hasSameAlternativeColors(ca2); - } - - return true; - } - -} +/* + * 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$ */ + +package org.apache.xmlgraphics.java2d.color; + +import java.awt.Color; + + +/** + * Generic Color helper class. + *
+ * This class supports parsing string values into color values and creating + * color values for strings. It provides a list of standard color names. + */ +public final class ColorUtil { + + /** + * Private constructor since this is an utility class. + */ + private ColorUtil() { + } + + + /** + * Lightens up a color for groove, ridge, inset and outset border effects. + * @param col the color to lighten up + * @param factor factor by which to lighten up (negative values darken the color) + * @return the modified color + */ + public static Color lightenColor(Color col, float factor) { + // TODO: This function converts the color into the sRGB namespace. + // This should be avoided if possible. + float[] cols = new float[4]; + cols = col.getRGBComponents(cols); + if (factor > 0) { + cols[0] += (1.0 - cols[0]) * factor; + cols[1] += (1.0 - cols[1]) * factor; + cols[2] += (1.0 - cols[2]) * factor; + } else { + cols[0] -= cols[0] * -factor; + cols[1] -= cols[1] * -factor; + cols[2] -= cols[2] * -factor; + } + return new ColorWithAlternatives(cols[0], cols[1], cols[2], cols[3], null); + } + + + + /** + * Indicates whether the color is a gray value. + * @param col the color + * @return true if it is a gray value + */ + public static boolean isGray(Color col) { + return (col.getRed() == col.getBlue() && col.getRed() == col.getGreen()); + } + + /** + * Creates an uncalibrated CMYK color with the given gray value. + * @param black the gray component (0 - 1) + * @return the CMYK color + */ + public static Color toCMYKGrayColor(float black) { + //Calculated color components + float[] cmyk = new float[] {0f, 0f, 0f, 1.0f - black}; + //Create native color + return DeviceCMYKColorSpace.createCMYKColor(cmyk); + } + + /** + * Converts an arbitrary {@link Color} to a plain sRGB color doing the conversion at the + * best possible conversion quality. + * @param col the original color + * @return the sRGB equivalent + */ + public static Color toSRGBColor(Color col) { + if (col.getColorSpace().isCS_sRGB()) { + return col; //Don't convert if already sRGB to avoid conversion differences + } + float[] comps = col.getColorComponents(null); + float[] srgb = col.getColorSpace().toRGB(comps); + comps = col.getComponents(null); + float alpha = comps[comps.length - 1]; + return new Color(srgb[0], srgb[1], srgb[2], alpha); + } + + /** + * Checks if two colors are the same color. This check is much more restrictive than + * {@link Color#equals(Object)} in that it doesn't only check if both colors result in the + * same sRGB value. For example, if two colors not of the same exact class are compared, + * they are treated as not the same. + *
+ * Note: At the moment, this method only supports {@link Color} and + * {@link ColorWithAlternatives} only. Other subclasses of {@link Color} are checked only using + * the {@link Color#equals(Object)} method. + * @param col1 the first color + * @param col2 the second color + * @return true if both colors are the same color + */ + public static boolean isSameColor(Color col1, Color col2) { + //Check fallback sRGB values first, then go into details + if (!col1.equals(col2)) { + return false; + } + + //Consider same-ness only between colors of the same class (not subclasses) + //but consider a ColorWithAlternatives without alternatives to be the same as a Color. + Class> cl1 = col1.getClass(); + if (col1 instanceof ColorWithAlternatives + && !((ColorWithAlternatives) col1).hasAlternativeColors()) { + cl1 = Color.class; + } + Class> cl2 = col2.getClass(); + if (col2 instanceof ColorWithAlternatives + && !((ColorWithAlternatives) col2).hasAlternativeColors()) { + cl2 = Color.class; + } + if (cl1 != cl2) { + return false; + } + + //Check color space + if (!col1.getColorSpace().equals(col2.getColorSpace())) { + return false; + } + + //Check native components + float[] comps1 = col1.getComponents(null); + float[] comps2 = col2.getComponents(null); + if (comps1.length != comps2.length) { + return false; + } + for (int i = 0, c = comps1.length; i < c; i++) { + if (comps1[i] != comps2[i]) { + return false; + } + } + + //Compare alternative colors, order is relevant + if (col1 instanceof ColorWithAlternatives && col2 instanceof ColorWithAlternatives) { + ColorWithAlternatives ca1 = (ColorWithAlternatives) col1; + ColorWithAlternatives ca2 = (ColorWithAlternatives) col2; + return ca1.hasSameAlternativeColors(ca2); + } + + return true; + } + +} diff --git a/src/java/org/apache/xmlgraphics/java2d/color/ColorWithAlternatives.java b/src/java/org/apache/xmlgraphics/java2d/color/ColorWithAlternatives.java index ea945d57..4f4d0d15 100644 --- a/src/java/org/apache/xmlgraphics/java2d/color/ColorWithAlternatives.java +++ b/src/java/org/apache/xmlgraphics/java2d/color/ColorWithAlternatives.java @@ -1,212 +1,212 @@ -/* - * 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: ColorExt.java 884117 2009-11-25 14:42:48Z jeremias $ */ - -package org.apache.xmlgraphics.java2d.color; - -import java.awt.Color; -import java.awt.color.ColorSpace; - -/** - * 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. - *
- * 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 {@link 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. {@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.
- * @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.
- * @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.
- * @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.
- * @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.
- * @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.
- * @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.
- * @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.
- * @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.
- * @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.
- * @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.
- * @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 (int i = 0, c = this.alternativeColors.length; i < c; i++) {
- if (this.alternativeColors[i].getColorSpace().getType() == colorSpaceType) {
- return this.alternativeColors[i];
- }
- }
- }
- return null;
- }
-
-}
+/*
+ * 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$ */
+
+package org.apache.xmlgraphics.java2d.color;
+
+import java.awt.Color;
+import java.awt.color.ColorSpace;
+
+/**
+ * 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.
+ *
+ * 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 {@link 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. {@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.
+ * @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.
+ * @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.
+ * @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.
+ * @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.
+ * @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.
+ * @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.
+ * @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.
+ * @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.
+ * @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.
+ * @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.
+ * @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 (int i = 0, c = this.alternativeColors.length; i < c; i++) {
+ if (this.alternativeColors[i].getColorSpace().getType() == colorSpaceType) {
+ return this.alternativeColors[i];
+ }
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/test/java/org/apache/xmlgraphics/xmp/XMPPropertyTest.java b/test/java/org/apache/xmlgraphics/xmp/XMPPropertyTest.java
index 8c875467..27bfa789 100644
--- a/test/java/org/apache/xmlgraphics/xmp/XMPPropertyTest.java
+++ b/test/java/org/apache/xmlgraphics/xmp/XMPPropertyTest.java
@@ -1,186 +1,186 @@
-/*
- * 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$ */
-
-package org.apache.xmlgraphics.xmp;
-
-import java.io.StringWriter;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Locale;
-import java.util.Set;
-import java.util.TimeZone;
-
-import javax.xml.transform.stream.StreamResult;
-import javax.xml.transform.stream.StreamSource;
-
-import junit.framework.TestCase;
-
-import org.apache.xmlgraphics.util.QName;
-import org.apache.xmlgraphics.xmp.schemas.DublinCoreAdapter;
-import org.apache.xmlgraphics.xmp.schemas.DublinCoreSchema;
-import org.apache.xmlgraphics.xmp.schemas.XMPBasicAdapter;
-import org.apache.xmlgraphics.xmp.schemas.XMPBasicSchema;
-
-/**
- * Tests property access methods.
- */
-public class XMPPropertyTest extends TestCase {
-
- public void testPropertyAccess() throws Exception {
- Metadata xmp = new Metadata();
- DublinCoreAdapter dc = DublinCoreSchema.getAdapter(xmp);
- assertNull(dc.getContributors());
-
- dc.addContributor("Contributor1");
- assertEquals(1, dc.getContributors().length);
- assertEquals("Contributor1", dc.getContributors()[0]);
- dc.removeContributor("Contributor1");
- assertNull(dc.getContributors());
-
- dc.addContributor("Contributor1");
- assertEquals(1, dc.getContributors().length);
- dc.addContributor("Contributor2");
- assertEquals(2, dc.getContributors().length);
- assertFalse(dc.removeContributor("DoesNotExist"));
- assertTrue(dc.removeContributor("Contributor1"));
- assertEquals(1, dc.getContributors().length);
- assertTrue(dc.removeContributor("Contributor2"));
- assertFalse(dc.removeContributor("Contributor2"));
- assertNull(dc.getContributors());
- }
-
- public void testPropertyRemovalLangAlt() throws Exception {
- Metadata xmp = new Metadata();
- DublinCoreAdapter dc = DublinCoreSchema.getAdapter(xmp);
-
- //dc:title is a "Lang Alt"
- dc.setTitle("en", "The title");
- String title = dc.removeTitle("en");
- assertEquals("The title", title);
- dc.setTitle("en", "The title");
- dc.setTitle("de", "Der Titel");
- title = dc.removeTitle("en");
- assertEquals("The title", title);
- title = dc.removeTitle("en");
- assertNull(title);
-
- title = dc.removeTitle("de");
- assertEquals("Der Titel", title);
- title = dc.removeTitle("de");
- assertNull(title);
- }
-
- public void testReplaceLangAlt() throws Exception {
- Metadata xmp = new Metadata();
- DublinCoreAdapter dc = DublinCoreSchema.getAdapter(xmp);
- dc.setTitle("Default title");
- StringWriter writer = new StringWriter();
- XMPSerializer.writeXML(xmp, new StreamResult(writer));
- String xmpString = writer.toString();
- xmp = XMPParser.parseXMP(new StreamSource(new java.io.StringReader(xmpString)));
- dc = DublinCoreSchema.getAdapter(xmp);
- assertEquals("Default title", dc.getTitle());
- dc.setTitle("Updated title");
- XMPProperty prop = xmp.getProperty(new QName(DublinCoreSchema.NAMESPACE, "title"));
- XMPArray array = prop.getArrayValue();
- assertNotNull(array);
- //Check that only one title is present. There used to be a bug that didn't set the
- //non-qualified value equal to the value qualified with "x-default".
- assertEquals(1, array.getSize());
- assertEquals("Updated title", array.getValue(0));
- }
-
- public void testPropertyValues() throws Exception {
- Metadata xmp = new Metadata();
- DublinCoreAdapter dc = DublinCoreSchema.getAdapter(xmp);
-
- String format = dc.getFormat();
- assertNull(format);
-
- dc.setFormat("application/pdf");
- format = dc.getFormat();
- assertEquals("application/pdf", format);
-
- dc.setFormat("image/jpeg");
- format = dc.getFormat();
- assertEquals("image/jpeg", format);
-
- dc.setFormat(null);
- format = dc.getFormat();
- assertNull(format);
-
- dc.setFormat(""); //Empty string same as null value
- format = dc.getFormat();
- assertNull(format);
-
- dc.setTitle("title");
- String title = dc.getTitle();
- assertEquals("title", title);
-
- dc.setTitle("Titel");
- title = dc.getTitle();
- assertEquals("Titel", title);
-
- dc.setTitle(null);
- title = dc.getTitle();
- assertNull(title);
-
- dc.setTitle("");
- title = dc.getTitle();
- assertNull(title);
- }
-
- public void testDates() throws Exception {
- Metadata xmp = new Metadata();
- XMPBasicAdapter basic = XMPBasicSchema.getAdapter(xmp);
-
- Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.ENGLISH);
- cal.set(2008, Calendar.FEBRUARY, 07, 15, 11, 07);
- cal.set(Calendar.MILLISECOND, 0);
- Date dt = cal.getTime();
-
- assertNull(basic.getCreateDate());
- basic.setCreateDate(dt);
- Date dt2 = basic.getCreateDate();
- assertEquals(dt2, dt);
- }
-
- public void testQualifiers() throws Exception {
- Metadata xmp = new Metadata();
- XMPBasicAdapter basic = XMPBasicSchema.getAdapter(xmp);
-
- basic.addIdentifier("x123");
- basic.setIdentifier("id1", "system1");
- basic.setIdentifier("12345", "system2");
-
- String[] ids = basic.getIdentifiers();
- assertEquals(3, ids.length);
- Set set = new java.util.HashSet(Arrays.asList(ids));
- assertTrue(set.contains("x123"));
- assertTrue(set.contains("id1"));
- assertTrue(set.contains("12345"));
-
- assertEquals("id1", basic.getIdentifier("system1"));
- basic.setIdentifier("id2", "system1");
- assertEquals("id2", basic.getIdentifier("system1"));
- assertEquals(3, basic.getIdentifiers().length);
- }
-
-}
+/*
+ * 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$ */
+
+package org.apache.xmlgraphics.xmp;
+
+import java.io.StringWriter;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Set;
+import java.util.TimeZone;
+
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import junit.framework.TestCase;
+
+import org.apache.xmlgraphics.util.QName;
+import org.apache.xmlgraphics.xmp.schemas.DublinCoreAdapter;
+import org.apache.xmlgraphics.xmp.schemas.DublinCoreSchema;
+import org.apache.xmlgraphics.xmp.schemas.XMPBasicAdapter;
+import org.apache.xmlgraphics.xmp.schemas.XMPBasicSchema;
+
+/**
+ * Tests property access methods.
+ */
+public class XMPPropertyTest extends TestCase {
+
+ public void testPropertyAccess() throws Exception {
+ Metadata xmp = new Metadata();
+ DublinCoreAdapter dc = DublinCoreSchema.getAdapter(xmp);
+ assertNull(dc.getContributors());
+
+ dc.addContributor("Contributor1");
+ assertEquals(1, dc.getContributors().length);
+ assertEquals("Contributor1", dc.getContributors()[0]);
+ dc.removeContributor("Contributor1");
+ assertNull(dc.getContributors());
+
+ dc.addContributor("Contributor1");
+ assertEquals(1, dc.getContributors().length);
+ dc.addContributor("Contributor2");
+ assertEquals(2, dc.getContributors().length);
+ assertFalse(dc.removeContributor("DoesNotExist"));
+ assertTrue(dc.removeContributor("Contributor1"));
+ assertEquals(1, dc.getContributors().length);
+ assertTrue(dc.removeContributor("Contributor2"));
+ assertFalse(dc.removeContributor("Contributor2"));
+ assertNull(dc.getContributors());
+ }
+
+ public void testPropertyRemovalLangAlt() throws Exception {
+ Metadata xmp = new Metadata();
+ DublinCoreAdapter dc = DublinCoreSchema.getAdapter(xmp);
+
+ //dc:title is a "Lang Alt"
+ dc.setTitle("en", "The title");
+ String title = dc.removeTitle("en");
+ assertEquals("The title", title);
+ dc.setTitle("en", "The title");
+ dc.setTitle("de", "Der Titel");
+ title = dc.removeTitle("en");
+ assertEquals("The title", title);
+ title = dc.removeTitle("en");
+ assertNull(title);
+
+ title = dc.removeTitle("de");
+ assertEquals("Der Titel", title);
+ title = dc.removeTitle("de");
+ assertNull(title);
+ }
+
+ public void testReplaceLangAlt() throws Exception {
+ Metadata xmp = new Metadata();
+ DublinCoreAdapter dc = DublinCoreSchema.getAdapter(xmp);
+ dc.setTitle("Default title");
+ StringWriter writer = new StringWriter();
+ XMPSerializer.writeXML(xmp, new StreamResult(writer));
+ String xmpString = writer.toString();
+ xmp = XMPParser.parseXMP(new StreamSource(new java.io.StringReader(xmpString)));
+ dc = DublinCoreSchema.getAdapter(xmp);
+ assertEquals("Default title", dc.getTitle());
+ dc.setTitle("Updated title");
+ XMPProperty prop = xmp.getProperty(new QName(DublinCoreSchema.NAMESPACE, "title"));
+ XMPArray array = prop.getArrayValue();
+ assertNotNull(array);
+ //Check that only one title is present. There used to be a bug that didn't set the
+ //non-qualified value equal to the value qualified with "x-default".
+ assertEquals(1, array.getSize());
+ assertEquals("Updated title", array.getValue(0));
+ }
+
+ public void testPropertyValues() throws Exception {
+ Metadata xmp = new Metadata();
+ DublinCoreAdapter dc = DublinCoreSchema.getAdapter(xmp);
+
+ String format = dc.getFormat();
+ assertNull(format);
+
+ dc.setFormat("application/pdf");
+ format = dc.getFormat();
+ assertEquals("application/pdf", format);
+
+ dc.setFormat("image/jpeg");
+ format = dc.getFormat();
+ assertEquals("image/jpeg", format);
+
+ dc.setFormat(null);
+ format = dc.getFormat();
+ assertNull(format);
+
+ dc.setFormat(""); //Empty string same as null value
+ format = dc.getFormat();
+ assertNull(format);
+
+ dc.setTitle("title");
+ String title = dc.getTitle();
+ assertEquals("title", title);
+
+ dc.setTitle("Titel");
+ title = dc.getTitle();
+ assertEquals("Titel", title);
+
+ dc.setTitle(null);
+ title = dc.getTitle();
+ assertNull(title);
+
+ dc.setTitle("");
+ title = dc.getTitle();
+ assertNull(title);
+ }
+
+ public void testDates() throws Exception {
+ Metadata xmp = new Metadata();
+ XMPBasicAdapter basic = XMPBasicSchema.getAdapter(xmp);
+
+ Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.ENGLISH);
+ cal.set(2008, Calendar.FEBRUARY, 07, 15, 11, 07);
+ cal.set(Calendar.MILLISECOND, 0);
+ Date dt = cal.getTime();
+
+ assertNull(basic.getCreateDate());
+ basic.setCreateDate(dt);
+ Date dt2 = basic.getCreateDate();
+ assertEquals(dt2, dt);
+ }
+
+ public void testQualifiers() throws Exception {
+ Metadata xmp = new Metadata();
+ XMPBasicAdapter basic = XMPBasicSchema.getAdapter(xmp);
+
+ basic.addIdentifier("x123");
+ basic.setIdentifier("id1", "system1");
+ basic.setIdentifier("12345", "system2");
+
+ String[] ids = basic.getIdentifiers();
+ assertEquals(3, ids.length);
+ Set set = new java.util.HashSet(Arrays.asList(ids));
+ assertTrue(set.contains("x123"));
+ assertTrue(set.contains("id1"));
+ assertTrue(set.contains("12345"));
+
+ assertEquals("id1", basic.getIdentifier("system1"));
+ basic.setIdentifier("id2", "system1");
+ assertEquals("id2", basic.getIdentifier("system1"));
+ assertEquals(3, basic.getIdentifiers().length);
+ }
+
+}