/******************************************************************************* * Copyright (c) 2004, 2008 John Krasnay and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * John Krasnay - initial API and implementation *******************************************************************************/ package net.sf.vex.css; import java.util.HashMap; import java.util.Map; import net.sf.vex.core.Color; import org.w3c.css.sac.LexicalUnit; /** * Color-valued properties. */ public class ColorProperty extends AbstractProperty { private static Map colorNames = new HashMap(); static { colorNames.put(CSS.AQUA, new Color(0, 255, 255)); colorNames.put(CSS.BLACK, new Color(0, 0, 0)); colorNames.put(CSS.BLUE, new Color(0, 0, 255)); colorNames.put(CSS.FUCHSIA, new Color(255, 0, 255)); colorNames.put(CSS.GRAY, new Color(128, 128, 128)); colorNames.put(CSS.GREEN, new Color(0, 128, 0)); colorNames.put(CSS.LIME, new Color(0, 255, 0)); colorNames.put(CSS.MAROON, new Color(128, 0, 0)); colorNames.put(CSS.NAVY, new Color(0, 0, 128)); colorNames.put(CSS.OLIVE, new Color(128, 128, 0)); colorNames.put(CSS.ORANGE, new Color( 255, 165, 0)); colorNames.put(CSS.PURPLE, new Color(128, 0, 128)); colorNames.put(CSS.RED, new Color(255, 0, 0)); colorNames.put(CSS.SILVER, new Color(192, 192, 192)); colorNames.put(CSS.TEAL, new Color(0, 128, 128)); colorNames.put(CSS.WHITE, new Color(255, 255, 255)); colorNames.put(CSS.YELLOW, new Color(255, 255, 0)); } /** * Class constructor. The names CSS.COLOR and * CSS.BACKGROUND_COLOR are treated specially, as follows. * * <ul> * <li>If name is CSS.COLOR, it is inherited and defaults to black.</li> * <li>If name is CSS.BACKGROUND_COLOR, it is not inherited and defaults * to transparent (null).</li> * <li>Otherwise, it is not inherited and defaults to the current color.</li> * </ul> * * <p>Because of the default in the third case, the ColorProperty * for CSS.COLOR must be processed before any others.</p> * @param name Name of the element. */ public ColorProperty(String name) { super(name); } public Object calculate(LexicalUnit lu, Styles parentStyles, Styles styles) { boolean inherit = isInherit(lu) || this.getName().equals(CSS.COLOR); if (isColor(lu)) { return getColor(lu); } else if (inherit && parentStyles != null) { return parentStyles.get(this.getName()); } else { if (this.getName().equals(CSS.COLOR)) { return Color.BLACK; } else if (this.getName().equals(CSS.BACKGROUND_COLOR)) { return null; // transparent } else { return styles.getColor(); } } } /** * Returns true if the given lexical unit represents a color. * * @param lu LexicalUnit to check. */ public static boolean isColor(LexicalUnit lu) { if (lu == null) { return false; } else if (lu.getLexicalUnitType() == LexicalUnit.SAC_IDENT && colorNames.containsKey(lu.getStringValue())) { return true; } else if (lu.getLexicalUnitType() == LexicalUnit.SAC_RGBCOLOR) { return true; } else { return false; } } //========================================================== PRIVATE private static Color getColor(LexicalUnit lu) { if (lu.getLexicalUnitType() == LexicalUnit.SAC_IDENT) { String s = lu.getStringValue(); if (colorNames.containsKey(s)) { return (Color) colorNames.get(s); } else { return null; } } else if (lu.getLexicalUnitType() == LexicalUnit.SAC_RGBCOLOR) { lu = lu.getParameters(); int red = getColorPart(lu); lu = lu.getNextLexicalUnit(); // gobble comma lu = lu.getNextLexicalUnit(); int green = getColorPart(lu); lu = lu.getNextLexicalUnit(); // gobble comma lu = lu.getNextLexicalUnit(); int blue = getColorPart(lu); if (red == -1 || green == -1 || blue == -1) { return null; } else { return new Color(red, green, blue); } } else { System.out.println("WARNING: unsupported color type: " + lu); return null; } } /** * Converts one of the color channels into an int from 0-255, or -1 * if there's an error. */ private static int getColorPart(LexicalUnit lu) { int value; if (lu.getLexicalUnitType() == LexicalUnit.SAC_INTEGER) { value = lu.getIntegerValue(); } else if (lu.getLexicalUnitType() == LexicalUnit.SAC_PERCENTAGE) { value = Math.round(lu.getFloatValue() * 255); } else { System.out.println("WARNING: unsupported color part: " + lu); return -1; } return Math.max(0, Math.min(255, value)); } }