/* * ShadowEffect.java * $Id$ * * * Copyright 1999-2003 The Apache Software Foundation. * * Licensed 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. * * * @author Peter B. West * @version $Revision$ $Name$ */ package org.apache.fop.datatypes; import java.util.Iterator; import org.apache.fop.fo.PropNames; import org.apache.fop.fo.expr.PropertyException; /** * Class to represent ShadowEffect values. This class is a holder for a * set of PropertyValue objects, and will be placed in a PropertyValueList, * as text shadow effects are specified in a list. See 7.16.5. */ public class ShadowEffect extends AbstractPropertyValue { private static final String tag = "$Name$"; private static final String revision = "$Revision$"; /** * The shadow's "horizontal distance to the right of the text" (mandatory). */ private Numeric inlineOffset; /** * The shadow's "vertical distance below the text" (mandatory). */ private Numeric blockOffset; /** * The shadow's blur radius (optional) */ private Numeric blurRadius; /** * The shadow's color (optional) */ private ColorType color; /** * Construct a ShadowEffect from a given PropertyValueList. * An individual shadow effect is specified as a list comprising a * mandatory pair of Lengths, the inline-progression offset and * the block-progression offset, with an otpional third Length * for the blur radius. The shadow effect may optionally include a * color value, specified as a ColorType. The ColorType * may precede or follow the Length specifiers. * @param property the index of the property with which this value * is associated. * @param list the PropertyValueList containing details of one * shadow effect */ public ShadowEffect(int property, PropertyValueList list) throws PropertyException { super(property, PropertyValue.SHADOW_EFFECT); Object entry; Iterator entries = list.iterator(); switch (list.size()) { case 2: // Must be the inline and block offsets setInlineAndBlock(entries); break; case 3: // Must have inline and block offsets; may have blur radius or // a colour specifier if (list.getFirst() instanceof Numeric) { if (list.getLast() instanceof Numeric) { setInlineBlockAndBlur(entries); } else { // last element must be a color setInlineAndBlock(entries); setColor(entries); } } else { // First entry is not Numeric; has to be color setColor(entries); setInlineAndBlock(entries); } break; case 4: // Must have inline and block offsets, blur radius and colour // specifier if (list.getFirst() instanceof Numeric) { setInlineBlockAndBlur(entries); setColor(entries); } else { // First entry is not Numeric; has to be color setColor(entries); setInlineBlockAndBlur(entries); } break; default: throw new PropertyException ("Invalid number of elements in ShadowEffect: " + list.size()); } } /** * Construct a ShadowEffect from a given PropertyValueList. * @param propertyName the name of the property with which this value * is associated. * @param list the PropertyValueList containing details of one * shadow effect */ public ShadowEffect(String propertyName, PropertyValueList list) throws PropertyException { this(PropNames.getPropertyIndex(propertyName), list); } /** * Pick up two Numeric entries through the Iterator * and assign them to the inlineOffset and blockOffset * @param entries an Iterator already initialised elsewhere */ private void setInlineAndBlock(Iterator entries) throws PropertyException { Object entry; entry = entries.next(); if (! (entry instanceof Numeric)) throw new PropertyException ("Numeric value expected for text-shadow"); inlineOffset = (Numeric)entry; entry = entries.next(); if (! (entry instanceof Numeric)) throw new PropertyException ("Numeric value expected for text-shadow"); blockOffset = (Numeric)entry; } /** * Pick up three Numeric entries through the Iterator * and assign them to the inlineOffset, blockOffset and blurRadius * @param entries an Iterator already initialised elsewhere */ private void setInlineBlockAndBlur(Iterator entries) throws PropertyException { Object entry; setInlineAndBlock(entries); entry = entries.next(); if (! (entry instanceof Numeric)) throw new PropertyException ("Numeric blur radius value expected for text-shadow"); blurRadius = (Numeric)entry; } /** * Set the shadow color from the next entry returned by the entries * iterator. A color entry must be either a ColorType already, * or an NCName containing one of the standard XSL color * keywords. * @param entries an Iterator. */ private void setColor(Iterator entries) throws PropertyException { Object entry; entry = entries.next(); if (entry instanceof ColorType) { color = (ColorType)entry; } else if (entry instanceof NCName) { color = new ColorType (property, propertyConsts.getEnumIndex (PropNames.TEXT_SHADOW, ((NCName)entry).getNCName())); } } /** * Validate this ShadowEffect. Check that it is allowed on the * associated property. A ShadowEffect may also encode a single * character; i.e. a <character> type. If the * validation against LITERAL fails, try CHARACTER_T. */ public void validate() throws PropertyException { if (property != PropNames.TEXT_SHADOW) throw new PropertyException ("ShadowEffects only valid for text-shadow'"); } }