/* * 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.fop.fo.properties; // FOP import java.util.List; import org.apache.fop.datatypes.Length; import org.apache.fop.datatypes.Numeric; import org.apache.fop.fo.Constants; import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.expr.PropertyException; import org.apache.fop.fonts.FontInfo; import org.apache.fop.fonts.FontTriplet; import org.apache.fop.util.CompareUtil; /** * Collection of CommonFont properties */ public final class CommonFont { /** cache holding canonical CommonFont instances (only those with * absolute font-size and font-size-adjust) */ private static final PropertyCache<CommonFont> CACHE = new PropertyCache<CommonFont>(); /** hashcode of this instance */ private int hash = -1; /** The "font-family" property. */ private final FontFamilyProperty fontFamily; /** The "font-selection-strategy" property. */ private final EnumProperty fontSelectionStrategy; /** The "font-stretch" property. */ private final EnumProperty fontStretch; /** The "font-style" property. */ private final EnumProperty fontStyle; /** The "font-variant" property. */ private final EnumProperty fontVariant; /** The "font-weight" property. */ private final EnumProperty fontWeight; /** The "font-size" property. */ public final Length fontSize; /** The "font-size-adjust" property. */ public final Numeric fontSizeAdjust; /** * Construct a CommonFont instance * * @param fontFamily the font-family property * @param fontSelectionStrategy the font-selection-strategy property * @param fontStretch the font-stretch property * @param fontStyle the font-style property * @param fontVariant the font-variant property * @param fontWeight the font-weight property * @param fontSize the font-size (possibly non-cached) * @param fontSizeAdjust the font-size-adjust (possibly non-cached) */ private CommonFont(FontFamilyProperty fontFamily, EnumProperty fontSelectionStrategy, EnumProperty fontStretch, EnumProperty fontStyle, EnumProperty fontVariant, EnumProperty fontWeight, Length fontSize, Numeric fontSizeAdjust) { this.fontFamily = fontFamily; this.fontSelectionStrategy = fontSelectionStrategy; this.fontStretch = fontStretch; this.fontStyle = fontStyle; this.fontVariant = fontVariant; this.fontWeight = fontWeight; this.fontSize = fontSize; this.fontSizeAdjust = fontSizeAdjust; } /** * Returns a CommonFont instance for the given PropertyList * If the font-size and font-size-adjust properties are absolute * the entire instance will be cached. * If not, then a distinct instance will be returned, with * as much cached information as possible. * * @param pList the PropertyList to get the properties from * @return a CommonFont instance corresponding to the properties * @throws PropertyException if there was a problem getting the properties */ public static CommonFont getInstance(PropertyList pList) throws PropertyException { FontFamilyProperty fontFamily = (FontFamilyProperty) pList.get(Constants.PR_FONT_FAMILY); EnumProperty fontSelectionStrategy = (EnumProperty) pList.get(Constants.PR_FONT_SELECTION_STRATEGY); EnumProperty fontStretch = (EnumProperty) pList.get(Constants.PR_FONT_STRETCH); EnumProperty fontStyle = (EnumProperty) pList.get(Constants.PR_FONT_STYLE); EnumProperty fontVariant = (EnumProperty) pList.get(Constants.PR_FONT_VARIANT); EnumProperty fontWeight = (EnumProperty) pList.get(Constants.PR_FONT_WEIGHT); Numeric fontSizeAdjust = pList.get(Constants.PR_FONT_SIZE_ADJUST).getNumeric(); Length fontSize = pList.get(Constants.PR_FONT_SIZE).getLength(); CommonFont commonFont = new CommonFont(fontFamily, fontSelectionStrategy, fontStretch, fontStyle, fontVariant, fontWeight, fontSize, fontSizeAdjust); return CACHE.fetch(commonFont); } /** @return an array with the font-family names */ private String[] getFontFamily() { List<Property> lst = fontFamily.getList(); String[] fontFamily = new String[lst.size()]; for (int i = 0, c = lst.size(); i < c; i++) { fontFamily[i] = lst.get(i).getString(); } return fontFamily; } /** @return the first font-family name in the list */ public String getFirstFontFamily() { return fontFamily.list.get(0).getString(); } /** @return the "font-selection-strategy" property */ public int getFontSelectionStrategy() { return fontSelectionStrategy.getEnum(); } /** @return the "font-stretch" property */ public int getFontStretch() { return fontStretch.getEnum(); } /** @return the "font-style" property */ public int getFontStyle() { return fontStyle.getEnum(); } /** @return the "font-variant" property */ public int getFontVariant() { return fontVariant.getEnum(); } /** @return the "font-weight" property */ public int getFontWeight() { return fontWeight.getEnum(); } /** @return the "font-size" property. */ public Length getFontSize() { return fontSize; } /** @return the "font-size-adjust" property. */ public Numeric getFontSizeAdjust() { return fontSizeAdjust; } /** * Create and return an array of <code>FontTriplets</code> based on * the properties stored in the instance variables. * @param fontInfo a font info object * @return a font triplet */ public FontTriplet[] getFontState(FontInfo fontInfo) { int fw; switch (fontWeight.getEnum()) { case Constants.EN_100: fw = 100; break; case Constants.EN_200: fw = 200; break; case Constants.EN_300: fw = 300; break; case Constants.EN_400: fw = 400; break; case Constants.EN_500: fw = 500; break; case Constants.EN_600: fw = 600; break; case Constants.EN_700: fw = 700; break; case Constants.EN_800: fw = 800; break; case Constants.EN_900: fw = 900; break; default: fw = 400; } String style; switch (fontStyle.getEnum()) { case Constants.EN_ITALIC: style = "italic"; break; case Constants.EN_OBLIQUE: style = "oblique"; break; case Constants.EN_BACKSLANT: style = "backslant"; break; default: style = "normal"; } // NOTE: this is incomplete. font-size may be specified with // various kinds of keywords too //int fontVariant = propertyList.get("font-variant").getEnum(); FontTriplet[] triplets = fontInfo.fontLookup( getFontFamily(), style, fw); return triplets; } /** {@inheritDoc} */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!(obj instanceof CommonFont)) { return false; } CommonFont other = (CommonFont) obj; return CompareUtil.equal(fontFamily, other.fontFamily) && CompareUtil.equal(fontSelectionStrategy, other.fontSelectionStrategy) && CompareUtil.equal(fontSize, other.fontSize) && CompareUtil.equal(fontSizeAdjust, other.fontSizeAdjust) && CompareUtil.equal(fontStretch, other.fontStretch) && CompareUtil.equal(fontStyle, other.fontStyle) && CompareUtil.equal(fontVariant, other.fontVariant) && CompareUtil.equal(fontWeight, other.fontWeight); } /** {@inheritDoc} */ public int hashCode() { if (this.hash == -1) { int hash = 17; hash = 37 * hash + CompareUtil.getHashCode(fontSize); hash = 37 * hash + CompareUtil.getHashCode(fontSizeAdjust); hash = 37 * hash + CompareUtil.getHashCode(fontFamily); hash = 37 * hash + CompareUtil.getHashCode(fontSelectionStrategy); hash = 37 * hash + CompareUtil.getHashCode(fontStretch); hash = 37 * hash + CompareUtil.getHashCode(fontStyle); hash = 37 * hash + CompareUtil.getHashCode(fontVariant); hash = 37 * hash + CompareUtil.getHashCode(fontWeight); this.hash = hash; } return hash; } }