/*
* 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'");
}
}