/*
 * 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: FontShorthandProperty.java 679326 2008-07-24 09:35:34Z vhennebert $ */

package org.apache.fop.fo.properties;

import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.expr.PropertyException;

Property subclass for the font shorthand
/** * Property subclass for the font shorthand */
public class FontShorthandProperty extends ListProperty {
Inner class for creating instances of FontShorthandProperty
/** * Inner class for creating instances of FontShorthandProperty */
public static class Maker extends PropertyMaker { private static final int[] PROP_IDS = { Constants.PR_FONT_SIZE, Constants.PR_FONT_FAMILY, Constants.PR_LINE_HEIGHT, Constants.PR_FONT_STYLE, Constants.PR_FONT_VARIANT, Constants.PR_FONT_WEIGHT };
Params:
  • propId – ID of the property for which Maker should be created
/** * @param propId ID of the property for which Maker should be created */
public Maker(int propId) { super(propId); }
{@inheritDoc}
/** * {@inheritDoc} */
public Property make(PropertyList propertyList, String value, FObj fo) throws PropertyException { try { FontShorthandProperty newProp = new FontShorthandProperty(); newProp.setSpecifiedValue(value); String specVal = value; Property prop = null; if ("inherit".equals(specVal)) { /* fill the list with the individual properties from the parent */ for (int i = PROP_IDS.length; --i >= 0;) { prop = propertyList.getFromParent(PROP_IDS[i]); newProp.addProperty(prop, i); } } else { /* initialize list with nulls */ for (int pos = PROP_IDS.length; --pos >= 0;) { newProp.addProperty(null, pos); } prop = checkEnumValues(specVal); if (prop == null) { /* not an enum: * value should consist at least of font-size and font-family * separated by a space * mind the possible spaces from quoted font-family names */ int spaceIndex = value.indexOf(' '); int quoteIndex = (value.indexOf('\'') == -1) ? value.indexOf('\"') : value.indexOf('\''); if (spaceIndex == -1 || (quoteIndex != -1 && spaceIndex > quoteIndex)) { /* no spaces or first space appears after the first * single/double quote, so malformed value string */ throw new PropertyException("Invalid property value: " + "font=\"" + value + "\""); } PropertyMaker m = null; int fromIndex = spaceIndex + 1; int toIndex = specVal.length(); /* at least one space that appears before the first * single/double quote, so extract the individual properties */ boolean fontFamilyParsed = false; int commaIndex = value.indexOf(','); while (!fontFamilyParsed) { /* value contains a (list of) possibly quoted * font-family name(s) */ if (commaIndex == -1) { /* no list, just a single name * (or first name in the list) */ if (quoteIndex != -1) { /* a single name, quoted */ fromIndex = quoteIndex; } m = FObj.getPropertyMakerFor(PROP_IDS[1]); prop = m.make(propertyList, specVal.substring(fromIndex), fo); newProp.addProperty(prop, 1); fontFamilyParsed = true; } else { if (quoteIndex != -1 && quoteIndex < commaIndex) { /* a quoted font-family name as first name * in the comma-separated list * fromIndex = index of the first quote */ fromIndex = quoteIndex; quoteIndex = -1; } else { fromIndex = value.lastIndexOf(' ', commaIndex) + 1; } commaIndex = -1; } } toIndex = fromIndex - 1; fromIndex = value.lastIndexOf(' ', toIndex - 1) + 1; value = specVal.substring(fromIndex, toIndex); int slashIndex = value.indexOf('/'); String fontSize = value.substring(0, (slashIndex == -1) ? value.length() : slashIndex); m = FObj.getPropertyMakerFor(PROP_IDS[0]); prop = m.make(propertyList, fontSize, fo); /* need to make sure subsequent call to LineHeightPropertyMaker.make() * doesn't generate the default font-size property... */ propertyList.putExplicit(PROP_IDS[0], prop); newProp.addProperty(prop, 0); if (slashIndex != -1) { /* line-height */ String lineHeight = value.substring(slashIndex + 1); m = FObj.getPropertyMakerFor(PROP_IDS[2]); prop = m.make(propertyList, lineHeight, fo); newProp.addProperty(prop, 2); } if (fromIndex != 0) { toIndex = fromIndex - 1; value = specVal.substring(0, toIndex); fromIndex = 0; spaceIndex = value.indexOf(' '); do { toIndex = (spaceIndex == -1) ? value.length() : spaceIndex; String val = value.substring(fromIndex, toIndex); for (int i = 6; --i >= 3;) { if (newProp.list.get(i) == null) { /* not set */ m = FObj.getPropertyMakerFor(PROP_IDS[i]); val = m.checkValueKeywords(val); prop = m.checkEnumValues(val); if (prop != null) { newProp.addProperty(prop, i); } } } fromIndex = toIndex + 1; spaceIndex = value.indexOf(' ', fromIndex); } while (toIndex != value.length()); } } else { //TODO: implement enum values log.warn("Enum values other than \"inherit\"" + " not yet supported for the font shorthand."); return null; } } if (newProp.list.get(0) == null || newProp.list.get(1) == null) { throw new PropertyException("Invalid property value: " + "font-size and font-family are required for the font shorthand" + "\nfont=\"" + value + "\""); } return newProp; } catch (PropertyException pe) { pe.setLocator(propertyList.getFObj().getLocator()); pe.setPropertyName(getName()); throw pe; } } } private void addProperty(Property prop, int pos) { while (list.size() < (pos + 1)) { list.add(null); } list.set(pos, prop); } }