| /* |
| * 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.fonts.substitute; |
| |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| |
| import org.apache.fop.fonts.Font; |
| import org.apache.fop.fonts.FontInfo; |
| import org.apache.fop.fonts.FontTriplet; |
| import org.apache.fop.fonts.FontUtil; |
| |
| /** |
| * Encapsulates a font substitution qualifier |
| */ |
| public class FontQualifier { |
| |
| /** logger instance */ |
| private static Log log = LogFactory.getLog(FontQualifier.class); |
| |
| /** font family attribute value */ |
| private AttributeValue fontFamilyAttributeValue; |
| |
| /** font style attribute value */ |
| private AttributeValue fontStyleAttributeValue; |
| |
| /** font weight attribute value */ |
| private AttributeValue fontWeightAttributeValue; |
| |
| /** |
| * Default constructor |
| */ |
| public FontQualifier() { |
| } |
| |
| /** |
| * Sets the font family |
| * @param fontFamily the font family |
| */ |
| public void setFontFamily(String fontFamily) { |
| AttributeValue fontFamilyAttribute = AttributeValue.valueOf(fontFamily); |
| if (fontFamilyAttribute == null) { |
| log.error("Invalid font-family value '" + fontFamily + "'"); |
| return; |
| } |
| this.fontFamilyAttributeValue = fontFamilyAttribute; |
| } |
| |
| /** |
| * Sets the font style |
| * @param fontStyle the font style |
| */ |
| public void setFontStyle(String fontStyle) { |
| AttributeValue fontStyleAttribute = AttributeValue.valueOf(fontStyle); |
| if (fontStyleAttribute != null) { |
| this.fontStyleAttributeValue = fontStyleAttribute; |
| } |
| } |
| |
| /** |
| * Sets the font weight |
| * @param fontWeight the font weight |
| */ |
| public void setFontWeight(String fontWeight) { |
| AttributeValue fontWeightAttribute = AttributeValue.valueOf(fontWeight); |
| if (fontWeightAttribute != null) { |
| for (Object weightObj : fontWeightAttribute) { |
| if (weightObj instanceof String) { |
| String weightString = ((String) weightObj).trim(); |
| try { |
| FontUtil.parseCSS2FontWeight(weightString); |
| } catch (IllegalArgumentException ex) { |
| log.error("Invalid font-weight value '" + weightString + "'"); |
| return; |
| } |
| } |
| } |
| this.fontWeightAttributeValue = fontWeightAttribute; |
| } |
| } |
| |
| /** |
| * @return the font family attribute |
| */ |
| public AttributeValue getFontFamily() { |
| return this.fontFamilyAttributeValue; |
| } |
| |
| /** |
| * @return the font style attribute |
| */ |
| public AttributeValue getFontStyle() { |
| if (fontStyleAttributeValue == null) { |
| return AttributeValue.valueOf(Font.STYLE_NORMAL); |
| } |
| return this.fontStyleAttributeValue; |
| } |
| |
| /** |
| * @return the font weight attribute |
| */ |
| public AttributeValue getFontWeight() { |
| if (fontWeightAttributeValue == null) { |
| return AttributeValue.valueOf(Integer.toString(Font.WEIGHT_NORMAL)); |
| } |
| return this.fontWeightAttributeValue; |
| } |
| |
| /** |
| * @return true if this rule has a font weight |
| */ |
| public boolean hasFontWeight() { |
| return this.fontWeightAttributeValue != null; |
| } |
| |
| /** |
| * @return true if this rule has a font style |
| */ |
| public boolean hasFontStyle() { |
| return this.fontStyleAttributeValue != null; |
| } |
| |
| /** |
| * Returns a list of matching font triplet found in a given font info |
| * |
| * @param fontInfo the font info |
| * @return a list of matching font triplets |
| */ |
| protected List<FontTriplet> match(FontInfo fontInfo) { |
| AttributeValue fontFamilyValue = getFontFamily(); |
| AttributeValue weightValue = getFontWeight(); |
| AttributeValue styleValue = getFontStyle(); |
| |
| List<FontTriplet> matchingTriplets = new java.util.ArrayList<FontTriplet>(); |
| |
| // try to find matching destination font triplet |
| for (Object aFontFamilyValue : fontFamilyValue) { |
| String fontFamilyString = (String) aFontFamilyValue; |
| Map<FontTriplet, String> triplets = fontInfo.getFontTriplets(); |
| if (triplets != null) { |
| Set<FontTriplet> tripletSet = triplets.keySet(); |
| for (Object aTripletSet : tripletSet) { |
| FontTriplet triplet = (FontTriplet) aTripletSet; |
| String fontName = triplet.getName(); |
| |
| // matched font family name |
| if (fontFamilyString.toLowerCase().equals(fontName.toLowerCase())) { |
| |
| // try and match font weight |
| boolean weightMatched = false; |
| int fontWeight = triplet.getWeight(); |
| for (Object weightObj : weightValue) { |
| if (weightObj instanceof FontWeightRange) { |
| FontWeightRange intRange = (FontWeightRange) weightObj; |
| if (intRange.isWithinRange(fontWeight)) { |
| weightMatched = true; |
| } |
| } else if (weightObj instanceof String) { |
| String fontWeightString = (String) weightObj; |
| int fontWeightValue = FontUtil.parseCSS2FontWeight( |
| fontWeightString); |
| if (fontWeightValue == fontWeight) { |
| weightMatched = true; |
| } |
| } else if (weightObj instanceof Integer) { |
| Integer fontWeightInteger = (Integer) weightObj; |
| int fontWeightValue = fontWeightInteger; |
| if (fontWeightValue == fontWeight) { |
| weightMatched = true; |
| } |
| } |
| } |
| |
| // try and match font style |
| boolean styleMatched = false; |
| String fontStyleString = triplet.getStyle(); |
| for (Object aStyleValue : styleValue) { |
| String style = (String) aStyleValue; |
| if (fontStyleString.equals(style)) { |
| styleMatched = true; |
| } |
| } |
| |
| if (weightMatched && styleMatched) { |
| matchingTriplets.add(triplet); |
| } |
| } |
| } |
| } |
| } |
| return matchingTriplets; |
| } |
| |
| /** |
| * Returns the highest priority matching font triplet found in a given font info |
| * @param fontInfo the font info |
| * @return the highest priority matching font triplet |
| */ |
| protected FontTriplet bestMatch(FontInfo fontInfo) { |
| List<FontTriplet> matchingTriplets = match(fontInfo); |
| FontTriplet bestTriplet = null; |
| if (matchingTriplets.size() == 1) { |
| bestTriplet = matchingTriplets.get(0); |
| } else { |
| for (Object matchingTriplet : matchingTriplets) { |
| FontTriplet triplet = (FontTriplet) matchingTriplet; |
| if (bestTriplet == null) { |
| bestTriplet = triplet; |
| } else { |
| int priority = triplet.getPriority(); |
| if (priority < bestTriplet.getPriority()) { |
| bestTriplet = triplet; |
| } |
| } |
| } |
| } |
| return bestTriplet; |
| } |
| |
| /** |
| * @return a list of font triplets matching this qualifier |
| */ |
| public List<FontTriplet> getTriplets() { |
| List<FontTriplet> triplets = new java.util.ArrayList<FontTriplet>(); |
| |
| AttributeValue fontFamilyValue = getFontFamily(); |
| for (Object aFontFamilyValue : fontFamilyValue) { |
| String name = (String) aFontFamilyValue; |
| |
| AttributeValue styleValue = getFontStyle(); |
| for (Object aStyleValue : styleValue) { |
| String style = (String) aStyleValue; |
| |
| AttributeValue weightValue = getFontWeight(); |
| for (Object weightObj : weightValue) { |
| if (weightObj instanceof FontWeightRange) { |
| FontWeightRange fontWeightRange = (FontWeightRange) weightObj; |
| int[] weightRange = fontWeightRange.toArray(); |
| for (int aWeightRange : weightRange) { |
| triplets.add(new FontTriplet(name, style, aWeightRange)); |
| } |
| } else if (weightObj instanceof String) { |
| String weightString = (String) weightObj; |
| int weight = FontUtil.parseCSS2FontWeight(weightString); |
| triplets.add(new FontTriplet(name, style, weight)); |
| } else if (weightObj instanceof Integer) { |
| Integer weightInteger = (Integer) weightObj; |
| int weight = weightInteger; |
| triplets.add(new FontTriplet(name, style, weight)); |
| } |
| } |
| } |
| } |
| return triplets; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public String toString() { |
| String str = ""; |
| if (fontFamilyAttributeValue != null) { |
| str += "font-family=" + fontFamilyAttributeValue; |
| } |
| if (fontStyleAttributeValue != null) { |
| if (str.length() > 0) { |
| str += ", "; |
| } |
| str += "font-style=" + fontStyleAttributeValue; |
| } |
| if (fontWeightAttributeValue != null) { |
| if (str.length() > 0) { |
| str += ", "; |
| } |
| str += "font-weight=" + fontWeightAttributeValue; |
| } |
| return str; |
| } |
| } |