diff options
Diffstat (limited to 'src/java/org/apache/fop/fonts')
21 files changed, 1605 insertions, 259 deletions
diff --git a/src/java/org/apache/fop/fonts/CustomFontCollection.java b/src/java/org/apache/fop/fonts/CustomFontCollection.java new file mode 100644 index 000000000..3c0ffbed4 --- /dev/null +++ b/src/java/org/apache/fop/fonts/CustomFontCollection.java @@ -0,0 +1,82 @@ +/* + * 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; + +import java.util.List; + +import org.apache.fop.render.PrintRenderer; + +/** + * Sets up a set of custom (embedded) fonts + */ +public class CustomFontCollection implements FontCollection { + + private PrintRenderer renderer = null; + + /** + * A print renderer to configure + * @param renderer a print renderer + */ + public CustomFontCollection(PrintRenderer renderer) { + this.renderer = renderer; + } + + /** + * {@inheritDoc} + */ + public int setup(int num, FontInfo fontInfo) { + List/*<EmbedFontInfo>*/ embedFontInfoList = renderer.getFontList(); + if (embedFontInfoList == null) { + return num; //No fonts to process + } + + FontResolver resolver = renderer.getFontResolver(); + if (resolver == null) { + //Ensure that we have minimal font resolution capabilities + resolver = FontManager.createMinimalFontResolver(); + } + + String internalName = null; + //FontReader reader = null; + + for (int i = 0; i < embedFontInfoList.size(); i++) { + EmbedFontInfo embedFontInfo = (EmbedFontInfo)embedFontInfoList.get(i); + + //String metricsFile = configFontInfo.getMetricsFile(); + internalName = "F" + num; + num++; + /* + reader = new FontReader(metricsFile); + reader.useKerning(configFontInfo.getKerning()); + reader.setFontEmbedPath(configFontInfo.getEmbedFile()); + fontInfo.addMetrics(internalName, reader.getFont()); + */ + + LazyFont font = new LazyFont(embedFontInfo, resolver); + fontInfo.addMetrics(internalName, font); + + List triplets = embedFontInfo.getFontTriplets(); + for (int tripletIndex = 0; tripletIndex < triplets.size(); tripletIndex++) { + FontTriplet triplet = (FontTriplet) triplets.get(tripletIndex); + fontInfo.addFontProperties(internalName, triplet); + } + } + return num; + } +}
\ No newline at end of file diff --git a/src/java/org/apache/fop/fonts/EmbedFontInfo.java b/src/java/org/apache/fop/fonts/EmbedFontInfo.java index 8bda40532..dc40da780 100644 --- a/src/java/org/apache/fop/fonts/EmbedFontInfo.java +++ b/src/java/org/apache/fop/fonts/EmbedFontInfo.java @@ -36,14 +36,15 @@ public class EmbedFontInfo implements Serializable { protected String embedFile; /** false, to disable kerning */ protected boolean kerning; - /** the list of associated font triplets */ - protected List fontTriplets; /** the PostScript name of the font */ protected String postScriptName = null; /** the sub-fontname of the font (used for TrueType Collections, null otherwise) */ protected String subFontName = null; + /** the list of associated font triplets */ + private List/*<FontTriplet>*/ fontTriplets = null; + /** * Main constructor * @param metricsFile Path to the xml file containing font metrics @@ -53,7 +54,7 @@ public class EmbedFontInfo implements Serializable { * @param subFontName the sub-fontname used for TrueType Collections (null otherwise) */ public EmbedFontInfo(String metricsFile, boolean kerning, - List fontTriplets, String embedFile, String subFontName) { + List/*<FontTriplet>*/ fontTriplets, String embedFile, String subFontName) { this.metricsFile = metricsFile; this.embedFile = embedFile; this.kerning = kerning; @@ -84,19 +85,11 @@ public class EmbedFontInfo implements Serializable { public boolean getKerning() { return kerning; } - - /** - * Returns the list of font triplets associated with this font. - * @return List of font triplets - */ - public List getFontTriplets() { - return fontTriplets; - } /** - * Returns the sub-fontname name of the font. This is primarily used for TrueType Collections + * Returns the sub-font name name of the font. This is primarily used for TrueType Collections * to select one of the sub-fonts. For all other fonts, this is always null. - * @return the sub-fontname (or null) + * @return the sub-font name (or null) */ public String getSubFontName() { return this.subFontName; @@ -118,10 +111,20 @@ public class EmbedFontInfo implements Serializable { this.postScriptName = postScriptName; } - /** {@inheritDoc} */ + /** + * Returns the list of font triplets associated with this font. + * @return List of font triplets + */ + public List/*<FontTriplet>*/ getFontTriplets() { + return fontTriplets; + } + + /** + * {@inheritDoc} + */ public String toString() { return "metrics-url=" + metricsFile + ",embed-url=" + embedFile - + ", kerning=" + kerning + ", font-triplet=" + fontTriplets + + ", kerning=" + kerning + ", " + "font-triplet=" + fontTriplets + (getSubFontName() != null ? ", sub-font=" + getSubFontName() : ""); } } diff --git a/src/java/org/apache/fop/fonts/Font.java b/src/java/org/apache/fop/fonts/Font.java index ff71434c6..4ce3cbfbd 100644 --- a/src/java/org/apache/fop/fonts/Font.java +++ b/src/java/org/apache/fop/fonts/Font.java @@ -48,9 +48,18 @@ public class Font { /** Italic font style */ public static final String STYLE_ITALIC = "italic"; + /** Oblique font style */ + public static final String STYLE_OBLIQUE = "oblique"; + + /** Inclined font style */ + public static final String STYLE_INCLINED = "inclined"; + + /** Default selection priority */ + public static final int PRIORITY_DEFAULT = 0; + /** Default fallback key */ public static final FontTriplet DEFAULT_FONT = new FontTriplet( - "any", STYLE_NORMAL, WEIGHT_NORMAL); + "any", STYLE_NORMAL, WEIGHT_NORMAL, PRIORITY_DEFAULT); /** logger */ private static Log log = LogFactory.getLog(Font.class); diff --git a/src/java/org/apache/fop/fonts/FontCache.java b/src/java/org/apache/fop/fonts/FontCache.java index fcf26dafb..c5b6ab9c7 100644 --- a/src/java/org/apache/fop/fonts/FontCache.java +++ b/src/java/org/apache/fop/fonts/FontCache.java @@ -59,6 +59,7 @@ public final class FontCache implements Serializable { /** font cache file path */ private static final String DEFAULT_CACHE_FILENAME = "fop-fonts.cache"; + /** has this cache been changed since it was last read? */ private transient boolean changed = false; @@ -67,10 +68,10 @@ public final class FontCache implements Serializable { /** master mapping of font url -> font info. This needs to be * a list, since a TTC file may contain more than 1 font. */ - private Map fontfileMap = new java.util.HashMap(); //Map<String, CachedFontFile> + private Map/*<String, CachedFontFile>*/ fontfileMap = null; /** mapping of font url -> file modified date (for all fonts that have failed to load) */ - private Map failedFontMap = new java.util.HashMap(); + private Map failedFontMap/*<String, Long>*/ = null; /** * Default constructor @@ -221,7 +222,7 @@ public final class FontCache implements Serializable { */ public boolean containsFont(String embedUrl) { if (embedUrl != null) { - return fontfileMap.containsKey(embedUrl); + return getFontFileMap().containsKey(embedUrl); } return false; } @@ -233,7 +234,7 @@ public final class FontCache implements Serializable { */ public boolean containsFont(EmbedFontInfo fontInfo) { if (fontInfo != null) { - return fontfileMap.containsKey(getCacheKey(fontInfo)); + return getFontFileMap().containsKey(getCacheKey(fontInfo)); } return false; } @@ -268,6 +269,13 @@ public final class FontCache implements Serializable { return null; } + private Map/*<String, CachedFontFile>*/ getFontFileMap() { + if (fontfileMap == null) { + fontfileMap = new java.util.HashMap/*<String, CachedFontFile>*/(); + } + return fontfileMap; + } + /** * Adds a font info to cache * @param fontInfo font info @@ -277,7 +285,7 @@ public final class FontCache implements Serializable { synchronized (changeLock) { CachedFontFile cachedFontFile; if (containsFont(cacheKey)) { - cachedFontFile = (CachedFontFile)fontfileMap.get(cacheKey); + cachedFontFile = (CachedFontFile)getFontFileMap().get(cacheKey); if (!cachedFontFile.containsFont(fontInfo)) { cachedFontFile.put(fontInfo); } @@ -291,7 +299,7 @@ public final class FontCache implements Serializable { log.trace("Font added to cache: " + cacheKey); } cachedFontFile.put(fontInfo); - fontfileMap.put(cacheKey, cachedFontFile); + getFontFileMap().put(cacheKey, cachedFontFile); changed = true; } } @@ -304,7 +312,7 @@ public final class FontCache implements Serializable { */ public CachedFontFile getFontFile(String embedUrl) { if (containsFont(embedUrl)) { - return (CachedFontFile)fontfileMap.get(embedUrl); + return (CachedFontFile)getFontFileMap().get(embedUrl); } return null; } @@ -336,7 +344,7 @@ public final class FontCache implements Serializable { if (log.isTraceEnabled()) { log.trace("Font removed from cache: " + embedUrl); } - fontfileMap.remove(embedUrl); + getFontFileMap().remove(embedUrl); changed = true; } } @@ -349,13 +357,13 @@ public final class FontCache implements Serializable { * @return whether this is a failed font */ public boolean isFailedFont(String embedUrl, long lastModified) { - if (failedFontMap.containsKey(embedUrl)) { + if (getFailedFontMap().containsKey(embedUrl)) { synchronized (changeLock) { - long failedLastModified = ((Long)failedFontMap.get(embedUrl)).longValue(); + long failedLastModified = ((Long)getFailedFontMap().get(embedUrl)).longValue(); if (lastModified != failedLastModified) { // this font has been changed so lets remove it // from failed font map for now - failedFontMap.remove(embedUrl); + getFailedFontMap().remove(embedUrl); changed = true; } } @@ -365,19 +373,26 @@ public final class FontCache implements Serializable { } /** - * registers a failed font with the cache + * Registers a failed font with the cache * @param embedUrl embed url * @param lastModified time last modified */ public void registerFailedFont(String embedUrl, long lastModified) { synchronized (changeLock) { - if (!failedFontMap.containsKey(embedUrl)) { - failedFontMap.put(embedUrl, new Long(lastModified)); + if (!getFailedFontMap().containsKey(embedUrl)) { + getFailedFontMap().put(embedUrl, new Long(lastModified)); changed = true; } } } + private Map/*<String, Long>*/ getFailedFontMap() { + if (failedFontMap == null) { + failedFontMap = new java.util.HashMap/*<String, Long>*/(); + } + return failedFontMap; + } + /** * Clears font cache */ @@ -386,8 +401,8 @@ public final class FontCache implements Serializable { if (log.isTraceEnabled()) { log.trace("Font cache cleared."); } - fontfileMap.clear(); - failedFontMap.clear(); + fontfileMap = null; + failedFontMap = null; changed = true; } } @@ -414,33 +429,38 @@ public final class FontCache implements Serializable { } private static class CachedFontFile implements Serializable { + private static final long serialVersionUID = 4524237324330578883L; + /** file modify date (if available) */ private long lastModified = -1; - private Map filefontsMap = new java.util.HashMap(); //Map<String, EmbedFontInfo> + private Map/*<String, EmbedFontInfo>*/ filefontsMap = null; public CachedFontFile(long lastModified) { setLastModified(lastModified); } + private Map/*<String, EmbedFontInfo>*/ getFileFontsMap() { + if (filefontsMap == null) { + filefontsMap = new java.util.HashMap/*<String, EmbedFontInfo>*/(); + } + return filefontsMap; + } + void put(EmbedFontInfo efi) { - filefontsMap.put(efi.getPostScriptName(), efi); + getFileFontsMap().put(efi.getPostScriptName(), efi); } public boolean containsFont(EmbedFontInfo efi) { if (efi.getPostScriptName() != null) { - return filefontsMap.containsKey(efi.getPostScriptName()); + return getFileFontsMap().containsKey(efi.getPostScriptName()); } return false; } - public Map getFilefontsMap() { - return filefontsMap; - } - public EmbedFontInfo[] getEmbedFontInfos() { - return (EmbedFontInfo[])this.filefontsMap.values().toArray( - new EmbedFontInfo[this.filefontsMap.size()]); + return (EmbedFontInfo[])getFileFontsMap().values().toArray( + new EmbedFontInfo[getFileFontsMap().size()]); } /** diff --git a/src/java/org/apache/fop/fonts/FontCollection.java b/src/java/org/apache/fop/fonts/FontCollection.java new file mode 100644 index 000000000..c83f2523a --- /dev/null +++ b/src/java/org/apache/fop/fonts/FontCollection.java @@ -0,0 +1,38 @@ +/* + * 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; + + +/** + * Sets up a set of fonts + */ +public interface FontCollection { + /** + * Sets up fonts in a font info object. + * + * Adds metrics for basic fonts and useful family-style-weight + * triplets for lookup. + * + * @param start the font starting number + * @param fontInfo the font info to set up + * @return the starting font number for the next font to be added + */ + int setup(int start, FontInfo fontInfo); +} diff --git a/src/java/org/apache/fop/fonts/FontDescriptor.java b/src/java/org/apache/fop/fonts/FontDescriptor.java index ffc3ea3f2..73cb235e8 100644 --- a/src/java/org/apache/fop/fonts/FontDescriptor.java +++ b/src/java/org/apache/fop/fonts/FontDescriptor.java @@ -35,7 +35,7 @@ public interface FontDescriptor extends FontMetrics { /** * Returns the capital height of the font. - * @return the capiptal height + * @return the capital height */ int getCapHeight(); diff --git a/src/java/org/apache/fop/fonts/FontInfo.java b/src/java/org/apache/fop/fonts/FontInfo.java index 950134eb6..9ac4c1e6a 100644 --- a/src/java/org/apache/fop/fonts/FontInfo.java +++ b/src/java/org/apache/fop/fonts/FontInfo.java @@ -19,19 +19,18 @@ package org.apache.fop.fonts; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - /** - * The FontInfo for the layout and rendering of a fo document. + * The FontInfo holds font information for the layout and rendering of a fo document. * This stores the list of available fonts that are setup by * the renderer. The font name can be retrieved for the * family style and weight. @@ -47,38 +46,40 @@ public class FontInfo { protected static Log log = LogFactory.getLog(FontInfo.class); /** Map containing fonts that have been used */ - private Map usedFonts; //Map<String,FontMetrics> (String = font key) + private Map/*<String,FontMetrics>*/ usedFonts = null; //(String = font key) /** look up a font-triplet to find a font-name */ - private Map triplets; //Map<FontTriplet,String> (String = font key) + private Map/*<FontTriplet,String>*/ triplets = null; //(String = font key) /** look up a font-triplet to find its priority * (only used inside addFontProperties()) */ - private Map tripletPriorities; //Map<FontTriplet,Integer> + private Map/*<FontTriplet,Integer>*/ tripletPriorities = null; //Map<FontTriplet,Integer> /** look up a font-name to get a font (that implements FontMetrics at least) */ - private Map fonts; //Map<String,FontMetrics> (String = font key) + private Map/*<String,FontMetrics>*/ fonts = null; //(String = font key) - /** collection of missing fonts; used to make sure the user gets + /** + * a collection of missing fonts; used to make sure the user gets * a warning for a missing font only once (not every time the font is used) */ - private Collection loggedFontKeys; + private Set/*<FontTriplet>*/ loggedFontKeys = null; /** Cache for Font instances. */ - private Map fontInstanceCache = new java.util.HashMap(); - - private FontEventListener eventListener; + private Map/*<FontTriplet, Map>*/ fontInstanceCache = null; + /** Event listener for font events */ + private FontEventListener eventListener = null; + /** * Main constructor */ public FontInfo() { - this.triplets = new java.util.HashMap(); - this.tripletPriorities = new java.util.HashMap(); - this.fonts = new java.util.HashMap(); - this.usedFonts = new java.util.HashMap(); + this.triplets = new java.util.HashMap/*<FontTriplet, String>*/(); + this.tripletPriorities = new java.util.HashMap/*<FontTriplet, Integer>*/(); + this.fonts = new java.util.HashMap/*<String, FontMetrics>*/(); + this.usedFonts = new java.util.HashMap/*<String,FontMetrics>*/(); } - + /** * Sets the font event listener that can be used to receive events about particular events * in this class. @@ -112,16 +113,16 @@ public class FontInfo { /** * Adds a new font triplet. - * @param name internal key + * @param internalFontKey internal font key * @param triplet the font triplet to associate with the internal key */ - public void addFontProperties(String name, FontTriplet triplet) { + public void addFontProperties(String internalFontKey, FontTriplet triplet) { /* * add the given family, style and weight as a lookup for the font * with the given name */ if (log.isDebugEnabled()) { - log.debug("Registering: " + triplet + " under " + name); + log.debug("Registering: " + triplet + " under " + internalFontKey); } String oldName = (String)triplets.get(triplet); int newPriority = triplet.getPriority(); @@ -129,18 +130,20 @@ public class FontInfo { int oldPriority = ((Integer)tripletPriorities.get(triplet)).intValue(); if (oldPriority < newPriority) { logDuplicateFont(triplet, false, oldName, oldPriority, - name, newPriority); + internalFontKey, newPriority); return; } else { logDuplicateFont(triplet, true, oldName, oldPriority, - name, newPriority); + internalFontKey, newPriority); } } - this.triplets.put(triplet, name); + this.triplets.put(triplet, internalFontKey); this.tripletPriorities.put(triplet, new Integer(newPriority)); } - /** Log warning about duplicate font triplets. + /** + * Log warning about duplicate font triplets. + * * @param triplet the duplicate font triplet * @param replacing true iff the new font will replace the old one * @param oldKey the old internal font name @@ -155,24 +158,24 @@ public class FontInfo { log.debug(triplet + (replacing ? ": Replacing " : ": Not replacing ") + ((FontMetrics)fonts.get(triplets.get(triplet))).getFullName() - + " (" + oldPriority + ") by " + + " (priority=" + oldPriority + ") by " + ((FontMetrics)fonts.get(newKey)).getFullName() - + " (" + newPriority + ")"); + + " (priority=" + newPriority + ")"); } } /** * Adds font metrics for a specific font. - * @param name internal key + * @param internalFontKey internal key * @param metrics metrics to register */ - public void addMetrics(String name, FontMetrics metrics) { + public void addMetrics(String internalFontKey, FontMetrics metrics) { // add the given metrics as a font with the given name if (metrics instanceof Typeface) { ((Typeface)metrics).setEventListener(this.eventListener); } - this.fonts.put(name, metrics); + this.fonts.put(internalFontKey, metrics); } /** @@ -187,71 +190,72 @@ public class FontInfo { * @param weight font weight * @param substFont true if the font may be substituted with the * default font if not found - * @return internal key + * @return internal font triplet key */ private FontTriplet fontLookup(String family, String style, int weight, boolean substFont) { if (log.isTraceEnabled()) { log.trace("Font lookup: " + family + " " + style + " " + weight); - } + } + FontTriplet startKey = createFontKey(family, style, weight); - FontTriplet key = startKey; + FontTriplet fontTriplet = startKey; // first try given parameters - String f = getInternalFontKey(key); - if (f == null) { - key = doAdjustedLookup(family, style, weight, startKey, substFont); + String internalFontKey = getInternalFontKey(fontTriplet); + if (internalFontKey == null) { + fontTriplet = fuzzyFontLookup(family, style, weight, startKey, substFont); } - if (key != null) { - if (key != startKey) { - notifyFontReplacement(startKey, key); + if (fontTriplet != null) { + if (fontTriplet != startKey) { + notifyFontReplacement(startKey, fontTriplet); } - return key; + return fontTriplet; } else { return null; } } - private FontTriplet doAdjustedLookup(String family, String style, + private FontTriplet fuzzyFontLookup(String family, String style, int weight, FontTriplet startKey, boolean substFont) { FontTriplet key; - String f; + String internalFontKey; if (!family.equals(startKey.getName())) { key = createFontKey(family, style, weight); - f = getInternalFontKey(key); - if (f != null) { + internalFontKey = getInternalFontKey(key); + if (internalFontKey != null) { return key; } } // adjust weight, favouring normal or bold key = findAdjustWeight(family, style, weight); - f = getInternalFontKey(key); + internalFontKey = getInternalFontKey(key); - if (!substFont && f == null) { + if (!substFont && internalFontKey == null) { return null; } // only if the font may be substituted // fallback 1: try the same font-family and weight with default style - if (f == null && style != Font.STYLE_NORMAL) { + if (internalFontKey == null && style != Font.STYLE_NORMAL) { key = createFontKey(family, Font.STYLE_NORMAL, weight); - f = getInternalFontKey(key); + internalFontKey = getInternalFontKey(key); } - if (f == null && weight != Font.WEIGHT_NORMAL) { + if (internalFontKey == null && weight != Font.WEIGHT_NORMAL) { int diffWeight = (Font.WEIGHT_NORMAL - weight) / 100; int direction = diffWeight > 0 ? 1 : -1; int tryWeight = weight; while (tryWeight != Font.WEIGHT_NORMAL) { tryWeight += 100 * direction; key = createFontKey(family, style, weight); - f = getInternalFontKey(key); - if (f == null) { + internalFontKey = getInternalFontKey(key); + if (internalFontKey == null) { key = createFontKey(family, Font.STYLE_NORMAL, weight); - f = getInternalFontKey(key); + internalFontKey = getInternalFontKey(key); } - if (f != null) { + if (internalFontKey != null) { break; } } @@ -265,17 +269,17 @@ public class FontInfo { }*/ // fallback 3: try any family with orig style/weight - if (f == null) { - return doAdjustedLookup("any", style, weight, startKey, false); + if (internalFontKey == null) { + return fuzzyFontLookup("any", style, weight, startKey, false); } // last resort: use default - if (f == null) { + if (internalFontKey == null) { key = Font.DEFAULT_FONT; - f = getInternalFontKey(key); + internalFontKey = getInternalFontKey(key); } - if (f != null) { + if (internalFontKey != null) { return key; } else { return null; @@ -290,6 +294,13 @@ public class FontInfo { usedFonts.put(internalName, fonts.get(internalName)); } + private Map/*<FontTriplet,Map<Integer,Font>>*/ getFontInstanceCache() { + if (fontInstanceCache == null) { + fontInstanceCache = new java.util.HashMap/*<FontTriplet, Map<Integer,Font>>*/(); + } + return fontInstanceCache; + } + /** * Retrieves a (possibly cached) Font instance based on a FontTriplet and a font size. * @param triplet the font triplet designating the requested font @@ -297,10 +308,11 @@ public class FontInfo { * @return the requested Font instance */ public Font getFontInstance(FontTriplet triplet, int fontSize) { - Map sizes = (Map)fontInstanceCache.get(triplet); + Map/*<Integer,Font>*/ sizes + = (Map/*<Integer,Font>*/)getFontInstanceCache().get(triplet); if (sizes == null) { - sizes = new java.util.HashMap(); - fontInstanceCache.put(triplet, sizes); + sizes = new java.util.HashMap/*<Integer,Font>*/(); + getFontInstanceCache().put(triplet, sizes); } Integer size = new Integer(fontSize); Font font = (Font)sizes.get(size); @@ -350,7 +362,7 @@ public class FontInfo { throw new IllegalArgumentException("Specify at least one font family"); } FontTriplet triplet; - List tmpTriplets = new ArrayList(); + List tmpTriplets = new java.util.ArrayList(); for (int i = 0, c = families.length; i < c; i++) { triplet = fontLookup(families[i], style, weight, (i >= families.length - 1)); if (triplet != null) { @@ -372,12 +384,16 @@ public class FontInfo { + "FontTriplet on the last call. Lookup: " + sb.toString()); } - private void notifyFontReplacement(FontTriplet replacedKey, FontTriplet newKey) { + private Set/*<FontTriplet>*/ getLoggedFontKeys() { if (loggedFontKeys == null) { - loggedFontKeys = new java.util.HashSet(); + loggedFontKeys = new java.util.HashSet/*<FontTriplet>*/(); } - if (!loggedFontKeys.contains(replacedKey)) { - loggedFontKeys.add(replacedKey); + return loggedFontKeys; + } + + private void notifyFontReplacement(FontTriplet replacedKey, FontTriplet newKey) { + if (!getLoggedFontKeys().contains(replacedKey)) { + getLoggedFontKeys().add(replacedKey); if (this.eventListener != null) { this.eventListener.fontSubstituted(this, replacedKey, newKey); } else { @@ -477,16 +493,16 @@ public class FontInfo { * Gets a Map of all registered fonts. * @return a read-only Map with font key/FontMetrics pairs */ - public Map getFonts() { + public Map/*<String,FontMetrics>*/ getFonts() { return java.util.Collections.unmodifiableMap(this.fonts); } /** * Gets a Map of all registered font triplets. - * @return a read-only Map with FontTriplet/font key pairs + * @return a Map with FontTriplet/font key pairs */ - public Map getFontTriplets() { - return java.util.Collections.unmodifiableMap(this.triplets); + public Map/*<FontTriplet,String>*/ getFontTriplets() { + return this.triplets; } /** @@ -495,7 +511,7 @@ public class FontInfo { * This is for embedded font or creating a list of used fonts. * @return a read-only Map with font key/FontMetrics pairs */ - public Map getUsedFonts() { + public Map/*<String,FontMetrics>*/ getUsedFonts() { return this.usedFonts; } @@ -511,20 +527,30 @@ public class FontInfo { } /** - * Returns the first triplet matching the given font name. - * As there may be multiple triplets matching the font name - * the result set is sorted first to guarantee consistent results. + * Returns all font triplet matching the given font name. * @param fontName The font name we are looking for - * @return The first triplet for the given font name + * @return A list of matching font triplets */ - public FontTriplet getTripletFor(String fontName) { - List foundTriplets = new ArrayList(); + public List/*<FontTriplet>*/ getTripletsFor(String fontName) { + List/*<FontTriplet>*/ foundTriplets = new java.util.ArrayList(); for (Iterator iter = triplets.entrySet().iterator(); iter.hasNext();) { Map.Entry tripletEntry = (Map.Entry) iter.next(); if (fontName.equals(((String)tripletEntry.getValue()))) { foundTriplets.add(tripletEntry.getKey()); } } + return foundTriplets; + } + + /** + * Returns the first triplet matching the given font name. + * As there may be multiple triplets matching the font name + * the result set is sorted first to guarantee consistent results. + * @param fontName The font name we are looking for + * @return The first triplet for the given font name + */ + public FontTriplet getTripletFor(String fontName) { + List/*<FontTriplet>*/ foundTriplets = getTripletsFor(fontName); if (foundTriplets.size() > 0) { Collections.sort(foundTriplets); return (FontTriplet)foundTriplets.get(0); @@ -570,17 +596,25 @@ public class FontInfo { * Diagnostic method for logging all registered fonts to System.out. */ public void dumpAllTripletsToSystemOut() { + System.out.print(toString()); + } + + /** + * {@inheritDoc} + */ + public String toString() { Collection entries = new java.util.TreeSet(); Iterator iter = this.triplets.keySet().iterator(); while (iter.hasNext()) { FontTriplet triplet = (FontTriplet)iter.next(); String key = getInternalFontKey(triplet); FontMetrics metrics = getMetricsFor(key); - entries.add(triplet.toString() + " -> " + key + " -> " + metrics.getFontName()); + entries.add(triplet.toString() + " -> " + key + " -> " + metrics.getFontName() + "\n"); } - iter = entries.iterator(); - while (iter.hasNext()) { - System.out.println(iter.next()); + StringBuffer stringBuffer = new StringBuffer(); + for (iter = entries.iterator(); iter.hasNext();) { + stringBuffer.append(iter.next()); } + return stringBuffer.toString(); } } diff --git a/src/java/org/apache/fop/fonts/FontManager.java b/src/java/org/apache/fop/fonts/FontManager.java new file mode 100644 index 000000000..8ff85afb4 --- /dev/null +++ b/src/java/org/apache/fop/fonts/FontManager.java @@ -0,0 +1,221 @@ +/* + * 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; + +import java.awt.Graphics2D; +import java.net.MalformedURLException; + +import javax.xml.transform.Source; +import javax.xml.transform.stream.StreamSource; + +import org.apache.fop.apps.FopFactory; +import org.apache.fop.fonts.substitute.FontSubstitutions; +import org.apache.fop.render.PrintRenderer; + +// TODO: Refactor fonts package so major font activities (autodetection etc) +// are all centrally managed and delegated from this class, also remove dependency on FopFactory +// and start using POJO config/properties type classes + +/** + * The manager of fonts + */ +public class FontManager { + /** Use cache (record previously detected font triplet info) */ + public static final boolean DEFAULT_USE_CACHE = true; + + /** The base URL for all font URL resolutions. */ + private String fontBase = null; + + /** Font cache to speed up auto-font configuration (null if disabled) */ + private FontCache fontCache = null; + + /** Font substitutions */ + private FontSubstitutions fontSubstitutions = null; + + private FopFactory fopFactory = null; + + /** Allows enabling kerning on the base 14 fonts, default is false */ + private boolean enableBase14Kerning = false; + + /** + * Main constructor + * + * @param fopFactory the fo URI resolver + */ + public FontManager(FopFactory fopFactory) { + this(fopFactory, DEFAULT_USE_CACHE); + } + + /** + * Constructor + * + * @param fopFactory the fo URI resolver + * @param useCache true if the FontCache should be used + */ + public FontManager(FopFactory fopFactory, boolean useCache) { + this.fopFactory = fopFactory; + setUseCache(useCache); + } + + /** + * Sets the font base URL. + * @param fontBase font base URL + * @throws MalformedURLException if there's a problem with a file URL + */ + public void setFontBaseURL(String fontBase) throws MalformedURLException { + this.fontBase = fopFactory.getFOURIResolver().checkBaseURL(fontBase); + } + + /** + * @return the font base URL + */ + public String getFontBaseURL() { + return this.fontBase; + } + + /** @return true if kerning on base 14 fonts is enabled */ + public boolean isBase14KerningEnabled() { + return this.enableBase14Kerning; + } + + /** + * Controls whether kerning is activated on base 14 fonts. + * @param value true if kerning should be activated + */ + public void setBase14KerningEnabled(boolean value) { + this.enableBase14Kerning = value; + } + + /** + * Sets the font substitutions + * @param substitutions font substitutions + */ + public void setFontSubstitutions(FontSubstitutions substitutions) { + this.fontSubstitutions = substitutions; + } + + /** + * Returns the font substitution catalog + * @return the font substitution catalog + */ + protected FontSubstitutions getFontSubstitutions() { + if (fontSubstitutions == null) { + this.fontSubstitutions = new FontSubstitutions(); + } + return fontSubstitutions; + } + + /** + * Whether or not to cache results of font triplet detection/auto-config + * @param useCache use cache or not + */ + public void setUseCache(boolean useCache) { + if (useCache) { + this.fontCache = FontCache.load(); + if (this.fontCache == null) { + this.fontCache = new FontCache(); + } + } else { + this.fontCache = null; + } + } + + /** + * Cache results of font triplet detection/auto-config? + * @return true if this font manager uses the cache + */ + public boolean useCache() { + return (this.fontCache != null); + } + + /** + * Returns the font cache instance used by this font manager. + * @return the font cache + */ + public FontCache getFontCache() { + return this.fontCache; + } + + /** + * Sets up the fonts on a given PrintRenderer + * @param renderer a print renderer + */ + public void setupRenderer(PrintRenderer renderer) { + FontInfo fontInfo = renderer.getFontInfo(); + + int startNum = 1; + + // Configure base 14 fonts + org.apache.fop.fonts.base14.Base14FontCollection base14FontCollection + = new org.apache.fop.fonts.base14.Base14FontCollection(this.enableBase14Kerning); + startNum = base14FontCollection.setup(startNum, fontInfo); + + // Configure any custom font collection + org.apache.fop.fonts.CustomFontCollection customFontCollection + = new org.apache.fop.fonts.CustomFontCollection(renderer); + startNum = customFontCollection.setup(startNum, fontInfo); + + // Make any defined substitutions in the font info + getFontSubstitutions().adjustFontInfo(fontInfo); + } + + /** + * Sets up the fonts on a given PrintRenderer with Graphics2D + * @param renderer a print renderer + * @param graphics2D a graphics 2D + */ + public void setupRenderer(PrintRenderer renderer, Graphics2D graphics2D) { + FontInfo fontInfo = renderer.getFontInfo(); + + int startNum = 1; + + // setup base 14 fonts + org.apache.fop.render.java2d.Base14FontCollection base14FontCollection + = new org.apache.fop.render.java2d.Base14FontCollection(graphics2D); + + // setup any custom font collection + startNum = base14FontCollection.setup(startNum, fontInfo); + + // setup any installed fonts + org.apache.fop.render.java2d.InstalledFontCollection installedFontCollection + = new org.apache.fop.render.java2d.InstalledFontCollection(graphics2D); + startNum = installedFontCollection.setup(startNum, fontInfo); + + // setup any configured fonts + org.apache.fop.render.java2d.ConfiguredFontCollection configuredFontCollection + = new org.apache.fop.render.java2d.ConfiguredFontCollection(renderer); + startNum = configuredFontCollection.setup(startNum, fontInfo); + + // Make any defined substitutions in the font info + getFontSubstitutions().adjustFontInfo(fontInfo); + } + + /** @return a new FontResolver to be used by the font subsystem */ + public static FontResolver createMinimalFontResolver() { + return new FontResolver() { + + /** {@inheritDoc} */ + public Source resolve(String href) { + //Minimal functionality here + return new StreamSource(href); + } + }; + } +} diff --git a/src/java/org/apache/fop/fonts/FontManagerConfigurator.java b/src/java/org/apache/fop/fonts/FontManagerConfigurator.java new file mode 100644 index 000000000..edee46a0f --- /dev/null +++ b/src/java/org/apache/fop/fonts/FontManagerConfigurator.java @@ -0,0 +1,89 @@ +/* + * 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; + +import java.net.MalformedURLException; + +import org.apache.avalon.framework.configuration.Configuration; +import org.apache.avalon.framework.configuration.ConfigurationException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.fop.apps.FOPException; +import org.apache.fop.fonts.substitute.FontSubstitutions; +import org.apache.fop.fonts.substitute.FontSubstitutionsConfigurator; +import org.apache.fop.util.LogUtil; + +/** + * Configurator of the FontManager + */ +public class FontManagerConfigurator { + + /** logger instance */ + private static Log log = LogFactory.getLog(FontManagerConfigurator.class); + + private Configuration cfg; + + /** + * Main constructor + * @param cfg the font manager configuration object + */ + public FontManagerConfigurator(Configuration cfg) { + this.cfg = cfg; + } + + /** + * Initializes font settings from the user configuration + * @param fontManager a font manager + * @throws FOPException fop exception + */ + public void configure(FontManager fontManager) throws FOPException { + // caching (fonts) + if (cfg.getChild("use-cache", false) != null) { + try { + fontManager.setUseCache( + cfg.getChild("use-cache").getValueAsBoolean()); + } catch (ConfigurationException mfue) { + LogUtil.handleException(log, mfue, true); + } + } + if (cfg.getChild("font-base", false) != null) { + try { + fontManager.setFontBaseURL( + cfg.getChild("font-base").getValue(null)); + } catch (MalformedURLException mfue) { + LogUtil.handleException(log, mfue, true); + } + } + + // global font configuration + Configuration fontsCfg = cfg.getChild("fonts", false); + if (fontsCfg != null) { + // font substitution + Configuration substitutionsCfg = fontsCfg.getChild("substitutions", false); + if (substitutionsCfg != null) { + FontSubstitutionsConfigurator fontSubstitutionsConfigurator + = new FontSubstitutionsConfigurator(substitutionsCfg); + FontSubstitutions substitutions = new FontSubstitutions(); + fontSubstitutionsConfigurator.configure(substitutions); + fontManager.setFontSubstitutions(substitutions); + } + } + } +} diff --git a/src/java/org/apache/fop/fonts/FontSetup.java b/src/java/org/apache/fop/fonts/FontSetup.java index 8734856f6..ab893d385 100644 --- a/src/java/org/apache/fop/fonts/FontSetup.java +++ b/src/java/org/apache/fop/fonts/FontSetup.java @@ -42,6 +42,8 @@ import org.apache.fop.fonts.base14.TimesItalic; import org.apache.fop.fonts.base14.TimesRoman; import org.apache.fop.fonts.base14.ZapfDingbats; +//TODO remove small dependency on and refactor this + /** * Default fonts for FOP application; currently this uses PDF's fonts * by default. @@ -57,17 +59,11 @@ public class FontSetup { protected static Log log = LogFactory.getLog(FontSetup.class); /** - * Sets up the font info object. - * - * Adds metrics for basic fonts and useful family-style-weight - * triplets for lookup. - * - * @param fontInfo the font info object to set up - * @param embedList a list of EmbedFontInfo objects - * @param resolver the font resolver + * Sets up a font info + * @param fontInfo font info */ - public static void setup(FontInfo fontInfo, List embedList, FontResolver resolver) { - setup(fontInfo, embedList, resolver, false); + public static void setup(FontInfo fontInfo) { + setup(fontInfo, null, null); } /** @@ -77,25 +73,23 @@ public class FontSetup { * triplets for lookup. * * @param fontInfo the font info object to set up - * @param embedList a list of EmbedFontInfo objects + * @param embedFontInfoList a list of EmbedFontInfo objects * @param resolver the font resolver - * @param enableBase14Kerning true if kerning should be enabled for base 14 fonts */ - public static void setup(FontInfo fontInfo, List embedList, FontResolver resolver, - boolean enableBase14Kerning) { - - fontInfo.addMetrics("F1", new Helvetica(enableBase14Kerning)); - fontInfo.addMetrics("F2", new HelveticaOblique(enableBase14Kerning)); - fontInfo.addMetrics("F3", new HelveticaBold(enableBase14Kerning)); - fontInfo.addMetrics("F4", new HelveticaBoldOblique(enableBase14Kerning)); - fontInfo.addMetrics("F5", new TimesRoman(enableBase14Kerning)); - fontInfo.addMetrics("F6", new TimesItalic(enableBase14Kerning)); - fontInfo.addMetrics("F7", new TimesBold(enableBase14Kerning)); - fontInfo.addMetrics("F8", new TimesBoldItalic(enableBase14Kerning)); - fontInfo.addMetrics("F9", new Courier(enableBase14Kerning)); - fontInfo.addMetrics("F10", new CourierOblique(enableBase14Kerning)); - fontInfo.addMetrics("F11", new CourierBold(enableBase14Kerning)); - fontInfo.addMetrics("F12", new CourierBoldOblique(enableBase14Kerning)); + public static void setup(FontInfo fontInfo, List embedFontInfoList, FontResolver resolver) { + final boolean base14Kerning = false; + fontInfo.addMetrics("F1", new Helvetica(base14Kerning)); + fontInfo.addMetrics("F2", new HelveticaOblique(base14Kerning)); + fontInfo.addMetrics("F3", new HelveticaBold(base14Kerning)); + fontInfo.addMetrics("F4", new HelveticaBoldOblique(base14Kerning)); + fontInfo.addMetrics("F5", new TimesRoman(base14Kerning)); + fontInfo.addMetrics("F6", new TimesItalic(base14Kerning)); + fontInfo.addMetrics("F7", new TimesBold(base14Kerning)); + fontInfo.addMetrics("F8", new TimesBoldItalic(base14Kerning)); + fontInfo.addMetrics("F9", new Courier(base14Kerning)); + fontInfo.addMetrics("F10", new CourierOblique(base14Kerning)); + fontInfo.addMetrics("F11", new CourierBold(base14Kerning)); + fontInfo.addMetrics("F12", new CourierBoldOblique(base14Kerning)); fontInfo.addMetrics("F13", new Symbol()); fontInfo.addMetrics("F14", new ZapfDingbats()); @@ -105,64 +99,64 @@ public class FontSetup { // fontInfo.addMetrics("F17", new BauerBodoniBoldItalic()); /* any is treated as serif */ - fontInfo.addFontProperties("F5", "any", "normal", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F6", "any", "italic", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F6", "any", "oblique", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F7", "any", "normal", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F8", "any", "italic", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F8", "any", "oblique", Font.WEIGHT_BOLD); - - fontInfo.addFontProperties("F1", "sans-serif", "normal", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F2", "sans-serif", "oblique", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F2", "sans-serif", "italic", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F3", "sans-serif", "normal", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F4", "sans-serif", "oblique", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F4", "sans-serif", "italic", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F1", "SansSerif", "normal", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F2", "SansSerif", "oblique", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F2", "SansSerif", "italic", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F3", "SansSerif", "normal", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F4", "SansSerif", "oblique", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F4", "SansSerif", "italic", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F5", "serif", "normal", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F6", "serif", "oblique", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F6", "serif", "italic", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F7", "serif", "normal", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F8", "serif", "oblique", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F8", "serif", "italic", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F9", "monospace", "normal", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F10", "monospace", "oblique", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F10", "monospace", "italic", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F11", "monospace", "normal", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F12", "monospace", "oblique", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F12", "monospace", "italic", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F9", "Monospaced", "normal", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F10", "Monospaced", "oblique", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F10", "Monospaced", "italic", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F11", "Monospaced", "normal", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F12", "Monospaced", "oblique", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F12", "Monospaced", "italic", Font.WEIGHT_BOLD); - - fontInfo.addFontProperties("F1", "Helvetica", "normal", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F2", "Helvetica", "oblique", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F2", "Helvetica", "italic", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F3", "Helvetica", "normal", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F4", "Helvetica", "oblique", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F4", "Helvetica", "italic", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F5", "Times", "normal", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F6", "Times", "oblique", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F6", "Times", "italic", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F7", "Times", "normal", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F8", "Times", "oblique", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F8", "Times", "italic", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F9", "Courier", "normal", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F10", "Courier", "oblique", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F10", "Courier", "italic", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F11", "Courier", "normal", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F12", "Courier", "oblique", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F12", "Courier", "italic", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F13", "Symbol", "normal", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F14", "ZapfDingbats", "normal", Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F5", "any", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F6", "any", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F6", "any", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F7", "any", Font.STYLE_NORMAL, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F8", "any", Font.STYLE_ITALIC, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F8", "any", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD); + + fontInfo.addFontProperties("F1", "sans-serif", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F2", "sans-serif", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F2", "sans-serif", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F3", "sans-serif", Font.STYLE_NORMAL, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F4", "sans-serif", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F4", "sans-serif", Font.STYLE_ITALIC, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F1", "SansSerif", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F2", "SansSerif", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F2", "SansSerif", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F3", "SansSerif", Font.STYLE_NORMAL, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F4", "SansSerif", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F4", "SansSerif", Font.STYLE_ITALIC, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F5", "serif", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F6", "serif", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F6", "serif", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F7", "serif", Font.STYLE_NORMAL, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F8", "serif", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F8", "serif", Font.STYLE_ITALIC, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F9", "monospace", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F10", "monospace", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F10", "monospace", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F11", "monospace", Font.STYLE_NORMAL, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F12", "monospace", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F12", "monospace", Font.STYLE_ITALIC, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F9", "Monospaced", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F10", "Monospaced", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F10", "Monospaced", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F11", "Monospaced", Font.STYLE_NORMAL, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F12", "Monospaced", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F12", "Monospaced", Font.STYLE_ITALIC, Font.WEIGHT_BOLD); + + fontInfo.addFontProperties("F1", "Helvetica", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F2", "Helvetica", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F2", "Helvetica", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F3", "Helvetica", Font.STYLE_NORMAL, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F4", "Helvetica", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F4", "Helvetica", Font.STYLE_ITALIC, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F5", "Times", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F6", "Times", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F6", "Times", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F7", "Times", Font.STYLE_NORMAL, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F8", "Times", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F8", "Times", Font.STYLE_ITALIC, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F9", "Courier", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F10", "Courier", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F10", "Courier", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F11", "Courier", Font.STYLE_NORMAL, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F12", "Courier", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F12", "Courier", Font.STYLE_ITALIC, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F13", "Symbol", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F14", "ZapfDingbats", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); // Custom type 1 fonts step 2/2 // fontInfo.addFontProperties("F15", "OMEP", "normal", FontInfo.NORMAL); @@ -170,50 +164,53 @@ public class FontSetup { // fontInfo.addFontProperties("F17", "BauerBodoni", "italic", FontInfo.BOLD); /* for compatibility with PassiveTex */ - fontInfo.addFontProperties("F5", "Times-Roman", "normal", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F6", "Times-Roman", "oblique", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F6", "Times-Roman", "italic", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F7", "Times-Roman", "normal", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F8", "Times-Roman", "oblique", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F8", "Times-Roman", "italic", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F5", "Times Roman", "normal", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F6", "Times Roman", "oblique", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F6", "Times Roman", "italic", Font.WEIGHT_NORMAL); - fontInfo.addFontProperties("F7", "Times Roman", "normal", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F8", "Times Roman", "oblique", Font.WEIGHT_BOLD); - fontInfo.addFontProperties("F8", "Times Roman", "italic", Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F5", "Times-Roman", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F6", "Times-Roman", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F6", "Times-Roman", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F7", "Times-Roman", Font.STYLE_NORMAL, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F8", "Times-Roman", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F8", "Times-Roman", Font.STYLE_ITALIC, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F5", "Times Roman", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F6", "Times Roman", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F6", "Times Roman", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F7", "Times Roman", Font.STYLE_NORMAL, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F8", "Times Roman", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F8", "Times Roman", Font.STYLE_ITALIC, Font.WEIGHT_BOLD); fontInfo.addFontProperties("F9", "Computer-Modern-Typewriter", - "normal", Font.WEIGHT_NORMAL); + Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + // All base 14 configured now, so any custom embedded fonts start from 15 + final int startNum = 15; + /* Add configured fonts */ - addConfiguredFonts(fontInfo, embedList, 15, resolver); + addConfiguredFonts(fontInfo, embedFontInfoList, startNum, resolver); } /** * Add fonts from configuration file starting with internal name F<num>. - * @param fontInfo the font info object to set up - * @param fontInfoList a list of EmbedFontInfo objects + * @param fontInfo the font info to set up + * @param embedFontInfoList a list of EmbedFontInfo objects * @param num starting index for internal font numbering * @param resolver the font resolver */ - public static void addConfiguredFonts(FontInfo fontInfo, List fontInfoList - , int num, FontResolver resolver) { - if (fontInfoList == null) { + private static void addConfiguredFonts(FontInfo fontInfo, + List/*<EmbedFontInfo>*/ embedFontInfoList, int num, FontResolver resolver) { + if (embedFontInfoList == null) { return; //No fonts to process } if (resolver == null) { //Ensure that we have minimal font resolution capabilities - resolver = createMinimalFontResolver(); + resolver = createMinimalFontResolver1(); } String internalName = null; //FontReader reader = null; - for (int i = 0; i < fontInfoList.size(); i++) { - EmbedFontInfo configFontInfo = (EmbedFontInfo) fontInfoList.get(i); + for (int i = 0; i < embedFontInfoList.size(); i++) { + EmbedFontInfo embedFontInfo = (EmbedFontInfo)embedFontInfoList.get(i); - String metricsFile = configFontInfo.getMetricsFile(); + //String metricsFile = configFontInfo.getMetricsFile(); internalName = "F" + num; num++; /* @@ -222,20 +219,20 @@ public class FontSetup { reader.setFontEmbedPath(configFontInfo.getEmbedFile()); fontInfo.addMetrics(internalName, reader.getFont()); */ - LazyFont font = new LazyFont(configFontInfo, resolver); + + LazyFont font = new LazyFont(embedFontInfo, resolver); fontInfo.addMetrics(internalName, font); - List triplets = configFontInfo.getFontTriplets(); - for (int c = 0; c < triplets.size(); c++) { - FontTriplet triplet = (FontTriplet) triplets.get(c); - + List triplets = embedFontInfo.getFontTriplets(); + for (int tripletIndex = 0; tripletIndex < triplets.size(); tripletIndex++) { + FontTriplet triplet = (FontTriplet) triplets.get(tripletIndex); fontInfo.addFontProperties(internalName, triplet); } } } /** @return a new FontResolver to be used by the font subsystem */ - public static FontResolver createMinimalFontResolver() { + public static FontResolver createMinimalFontResolver1() { return new FontResolver() { /** {@inheritDoc} */ diff --git a/src/java/org/apache/fop/fonts/FontTriplet.java b/src/java/org/apache/fop/fonts/FontTriplet.java index a7890ecbd..9091219f5 100644 --- a/src/java/org/apache/fop/fonts/FontTriplet.java +++ b/src/java/org/apache/fop/fonts/FontTriplet.java @@ -38,13 +38,21 @@ public class FontTriplet implements Comparable, Serializable { private transient String key; /** + * Creates a new font triplet (for base14 use). + * @param name font name + */ + public FontTriplet(String name) { + this.name = name; + } + + /** * Creates a new font triplet. * @param name font name * @param style font style (normal, italic etc.) * @param weight font weight (100, 200, 300...800, 900) */ public FontTriplet(String name, String style, int weight) { - this(name, style, weight, 0); + this(name, style, weight, Font.PRIORITY_DEFAULT); } /** @@ -55,7 +63,7 @@ public class FontTriplet implements Comparable, Serializable { * @param priority priority of this triplet/font mapping */ public FontTriplet(String name, String style, int weight, int priority) { - this.name = name; + this(name); this.style = style; this.weight = weight; this.priority = priority; @@ -120,6 +128,5 @@ public class FontTriplet implements Comparable, Serializable { public String toString() { return getKey(); } - } diff --git a/src/java/org/apache/fop/fonts/FontUtil.java b/src/java/org/apache/fop/fonts/FontUtil.java index 89ea132c0..d72e283cf 100644 --- a/src/java/org/apache/fop/fonts/FontUtil.java +++ b/src/java/org/apache/fop/fonts/FontUtil.java @@ -59,25 +59,27 @@ public class FontUtil { /** * Removes all white space from a string (used primarily for font names) - * @param s the string + * @param str the string * @return the processed result */ - public static String stripWhiteSpace(String s) { - StringBuffer sb = new StringBuffer(s.length()); - for (int i = 0, c = s.length(); i < c; i++) { - final char ch = s.charAt(i); - if (ch != ' ' - && ch != '\r' - && ch != '\n' - && ch != '\t') { - sb.append(ch); + public static String stripWhiteSpace(String str) { + if (str != null) { + StringBuffer stringBuffer = new StringBuffer(str.length()); + for (int i = 0, strLen = str.length(); i < strLen; i++) { + final char ch = str.charAt(i); + if (ch != ' ' && ch != '\r' && ch != '\n' && ch != '\t') { + stringBuffer.append(ch); + } } + return stringBuffer.toString(); } - return sb.toString(); + return str; } /** font constituent names which identify a font as being of "italic" style */ - private static final String[] ITALIC_WORDS = {"italic", "oblique", "inclined"}; + private static final String[] ITALIC_WORDS = { + Font.STYLE_ITALIC, Font.STYLE_OBLIQUE, Font.STYLE_INCLINED + }; /** font constituent names which identify a font as being of "light" weight */ private static final String[] LIGHT_WORDS = {"light"}; @@ -97,9 +99,11 @@ public class FontUtil { * @return "normal" or "italic" */ public static String guessStyle(String fontName) { - for (int i = 0; i < ITALIC_WORDS.length; i++) { - if (fontName.indexOf(ITALIC_WORDS[i]) != -1) { - return Font.STYLE_ITALIC; + if (fontName != null) { + for (int i = 0; i < ITALIC_WORDS.length; i++) { + if (fontName.indexOf(ITALIC_WORDS[i]) != -1) { + return Font.STYLE_ITALIC; + } } } return Font.STYLE_NORMAL; @@ -148,6 +152,4 @@ public class FontUtil { } return weight; } - - } diff --git a/src/java/org/apache/fop/fonts/autodetect/FontFileFinder.java b/src/java/org/apache/fop/fonts/autodetect/FontFileFinder.java index d0f7b4f14..11b52f916 100644 --- a/src/java/org/apache/fop/fonts/autodetect/FontFileFinder.java +++ b/src/java/org/apache/fop/fonts/autodetect/FontFileFinder.java @@ -156,7 +156,7 @@ public class FontFileFinder extends DirectoryWalker implements FontFinder { * * @param dir directory to search * @return list of font files - * @throws IOException io exception + * @throws IOException thrown if an I/O exception of some sort has occurred */ public List find(String dir) throws IOException { List results = new java.util.ArrayList(); diff --git a/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java b/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java index 484710d1a..b2ee4a274 100644 --- a/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java +++ b/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java @@ -94,9 +94,9 @@ public class FontInfoFinder { //Full Name usually includes style/weight info so don't use these traits //If we still want to use these traits, we have to make FontInfo.fontLookup() smarter - triplets.add(new FontTriplet(fullName, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL, 0)); + triplets.add(new FontTriplet(fullName, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL)); if (!fullName.equals(strippedName)) { - triplets.add(new FontTriplet(strippedName, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL, 0)); + triplets.add(new FontTriplet(strippedName, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL)); } Set familyNames = customFont.getFamilyNames(); Iterator iter = familyNames.iterator(); diff --git a/src/java/org/apache/fop/fonts/base14/Base14FontCollection.java b/src/java/org/apache/fop/fonts/base14/Base14FontCollection.java new file mode 100644 index 000000000..68324f13a --- /dev/null +++ b/src/java/org/apache/fop/fonts/base14/Base14FontCollection.java @@ -0,0 +1,149 @@ +/* + * 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.base14; + +import org.apache.fop.fonts.Font; +import org.apache.fop.fonts.FontCollection; +import org.apache.fop.fonts.FontInfo; + +/** + * Sets up Base 14 fonts + */ +public class Base14FontCollection implements FontCollection { + + private boolean kerning = false; + + /** + * Main constructor + * + * @param kerning set to true when font kerning is enabled + */ + public Base14FontCollection(boolean kerning) { + this.kerning = kerning; + } + + /** + * {@inheritDoc} + */ + public int setup(int start, FontInfo fontInfo) { + fontInfo.addMetrics("F1", new Helvetica(kerning)); + fontInfo.addMetrics("F2", new HelveticaOblique(kerning)); + fontInfo.addMetrics("F3", new HelveticaBold(kerning)); + fontInfo.addMetrics("F4", new HelveticaBoldOblique(kerning)); + fontInfo.addMetrics("F5", new TimesRoman(kerning)); + fontInfo.addMetrics("F6", new TimesItalic(kerning)); + fontInfo.addMetrics("F7", new TimesBold(kerning)); + fontInfo.addMetrics("F8", new TimesBoldItalic(kerning)); + fontInfo.addMetrics("F9", new Courier(kerning)); + fontInfo.addMetrics("F10", new CourierOblique(kerning)); + fontInfo.addMetrics("F11", new CourierBold(kerning)); + fontInfo.addMetrics("F12", new CourierBoldOblique(kerning)); + fontInfo.addMetrics("F13", new Symbol()); + fontInfo.addMetrics("F14", new ZapfDingbats()); + + // Custom type 1 fonts step 1/2 + // fontInfo.addMetrics("F15", new OMEP()); + // fontInfo.addMetrics("F16", new GaramondLightCondensed()); + // fontInfo.addMetrics("F17", new BauerBodoniBoldItalic()); + + /* any is treated as serif */ + fontInfo.addFontProperties("F5", "any", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F6", "any", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F6", "any", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F7", "any", Font.STYLE_NORMAL, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F8", "any", Font.STYLE_ITALIC, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F8", "any", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD); + + fontInfo.addFontProperties("F1", "sans-serif", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F2", "sans-serif", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F2", "sans-serif", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F3", "sans-serif", Font.STYLE_NORMAL, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F4", "sans-serif", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F4", "sans-serif", Font.STYLE_ITALIC, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F1", "SansSerif", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F2", "SansSerif", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F2", "SansSerif", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F3", "SansSerif", Font.STYLE_NORMAL, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F4", "SansSerif", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F4", "SansSerif", Font.STYLE_ITALIC, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F5", "serif", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F6", "serif", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F6", "serif", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F7", "serif", Font.STYLE_NORMAL, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F8", "serif", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F8", "serif", Font.STYLE_ITALIC, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F9", "monospace", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F10", "monospace", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F10", "monospace", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F11", "monospace", Font.STYLE_NORMAL, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F12", "monospace", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F12", "monospace", Font.STYLE_ITALIC, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F9", "Monospaced", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F10", "Monospaced", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F10", "Monospaced", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F11", "Monospaced", Font.STYLE_NORMAL, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F12", "Monospaced", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F12", "Monospaced", Font.STYLE_ITALIC, Font.WEIGHT_BOLD); + + fontInfo.addFontProperties("F1", "Helvetica", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F2", "Helvetica", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F2", "Helvetica", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F3", "Helvetica", Font.STYLE_NORMAL, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F4", "Helvetica", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F4", "Helvetica", Font.STYLE_ITALIC, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F5", "Times", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F6", "Times", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F6", "Times", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F7", "Times", Font.STYLE_NORMAL, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F8", "Times", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F8", "Times", Font.STYLE_ITALIC, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F9", "Courier", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F10", "Courier", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F10", "Courier", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F11", "Courier", Font.STYLE_NORMAL, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F12", "Courier", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F12", "Courier", Font.STYLE_ITALIC, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F13", "Symbol", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F14", "ZapfDingbats", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + + // Custom type 1 fonts step 2/2 + // fontInfo.addFontProperties("F15", "OMEP", "normal", FontInfo.NORMAL); + // fontInfo.addFontProperties("F16", "Garamond-LightCondensed", "normal", FontInfo.NORMAL); + // fontInfo.addFontProperties("F17", "BauerBodoni", "italic", FontInfo.BOLD); + + /* for compatibility with PassiveTex */ + fontInfo.addFontProperties("F5", "Times-Roman", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F6", "Times-Roman", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F6", "Times-Roman", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F7", "Times-Roman", Font.STYLE_NORMAL, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F8", "Times-Roman", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F8", "Times-Roman", Font.STYLE_ITALIC, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F5", "Times Roman", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F6", "Times Roman", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F6", "Times Roman", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL); + fontInfo.addFontProperties("F7", "Times Roman", Font.STYLE_NORMAL, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F8", "Times Roman", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F8", "Times Roman", Font.STYLE_ITALIC, Font.WEIGHT_BOLD); + fontInfo.addFontProperties("F9", "Computer-Modern-Typewriter", + Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); + + return 15; + } +} diff --git a/src/java/org/apache/fop/fonts/substitute/AttributeValue.java b/src/java/org/apache/fop/fonts/substitute/AttributeValue.java new file mode 100644 index 000000000..1c697dc02 --- /dev/null +++ b/src/java/org/apache/fop/fonts/substitute/AttributeValue.java @@ -0,0 +1,65 @@ +/* + * 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.StringTokenizer; + +/** + * Encapsulates a font attribute value + */ +public class AttributeValue extends java.util.ArrayList { + + private static final long serialVersionUID = 748610847500940557L; + + /** + * Returns an <code>AttributeValue</code> object holding the + * value of the specified <code>String</code>. + * + * @param valuesString the value to be parsed + * @return an <code>AttributeValue</code> object holding the value + * represented by the string argument. + */ + public static AttributeValue valueOf(String valuesString) { + AttributeValue attribute = new AttributeValue(); + StringTokenizer stringTokenzier = new StringTokenizer(valuesString, ","); + if (stringTokenzier.countTokens() > 1) { + while (stringTokenzier.hasMoreTokens()) { + String token = stringTokenzier.nextToken().trim(); + AttributeValue tokenAttribute = AttributeValue.valueOf(token); + attribute.addAll(tokenAttribute); + } + } else { + String token = stringTokenzier.nextToken().trim(); + Object value = null; + try { + value = Integer.valueOf(token); + } catch (NumberFormatException ex) { + value = FontWeightRange.valueOf(token); + if (value == null) { + value = token; + } + } + if (value != null) { + attribute.add(value); + } + } + return attribute; + } +} diff --git a/src/java/org/apache/fop/fonts/substitute/FontQualifier.java b/src/java/org/apache/fop/fonts/substitute/FontQualifier.java new file mode 100644 index 000000000..a68bb2ccd --- /dev/null +++ b/src/java/org/apache/fop/fonts/substitute/FontQualifier.java @@ -0,0 +1,305 @@ +/* + * 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.Iterator; +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 = null; + + /** font style attribute value */ + private AttributeValue fontStyleAttributeValue = null; + + /** font weight attribute value */ + private AttributeValue fontWeightAttributeValue = null; + + /** + * 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 (Iterator it = fontWeightAttribute.iterator(); it.hasNext();) { + Object weightObj = it.next(); + 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 (Iterator attrIt = fontFamilyValue.iterator(); attrIt.hasNext();) { + String fontFamilyString = (String)attrIt.next(); + Map/*<FontTriplet>*/ triplets = (Map/*<FontTriplet>*/)fontInfo.getFontTriplets(); + if (triplets != null) { + Set/*<FontTriplet>*/ tripletSet = triplets.keySet(); + for (Iterator/*<FontTriplet>*/ tripletIt = tripletSet.iterator(); + tripletIt.hasNext();) { + FontTriplet triplet = (FontTriplet)tripletIt.next(); + 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 (Iterator weightIt = weightValue.iterator(); weightIt.hasNext();) { + Object weightObj = weightIt.next(); + 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.intValue(); + if (fontWeightValue == fontWeight) { + weightMatched = true; + } + } + } + + // try and match font style + boolean styleMatched = false; + String fontStyleString = triplet.getStyle(); + for (Iterator styleIt = styleValue.iterator(); styleIt.hasNext();) { + String style = (String)styleIt.next(); + 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 = (FontTriplet)matchingTriplets.get(0); + } else { + for (Iterator iterator = matchingTriplets.iterator(); iterator.hasNext();) { + FontTriplet triplet = (FontTriplet)iterator.next(); + 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 (Iterator fontFamilyIt = fontFamilyValue.iterator(); fontFamilyIt.hasNext();) { + String name = (String)fontFamilyIt.next(); + + AttributeValue styleValue = getFontStyle(); + for (Iterator styleIt = styleValue.iterator(); styleIt.hasNext();) { + String style = (String)styleIt.next(); + + AttributeValue weightValue = getFontWeight(); + for (Iterator weightIt = weightValue.iterator(); weightIt.hasNext();) { + Object weightObj = weightIt.next(); + + if (weightObj instanceof FontWeightRange) { + FontWeightRange fontWeightRange = (FontWeightRange)weightObj; + int[] weightRange = fontWeightRange.toArray(); + for (int i = 0; i < weightRange.length; i++) { + triplets.add(new FontTriplet(name, style, weightRange[i])); + } + } 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.intValue(); + triplets.add(new FontTriplet(name, style, weight)); + } + } + } + } + return triplets; + } + + /** + * {@inheritDoc} + */ + public String toString() { + String str = new String(); + 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; + } +}
\ No newline at end of file diff --git a/src/java/org/apache/fop/fonts/substitute/FontSubstitution.java b/src/java/org/apache/fop/fonts/substitute/FontSubstitution.java new file mode 100644 index 000000000..5f71e7b7c --- /dev/null +++ b/src/java/org/apache/fop/fonts/substitute/FontSubstitution.java @@ -0,0 +1,61 @@ +/* + * 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; + +/** + * Encapsulates a pair of substitution qualifiers + */ +public class FontSubstitution { + + private FontQualifier fromQualifier; + private FontQualifier toQualifier; + + /** + * Main constructor + * + * @param fromQualifier the substitution from qualifier + * @param toQualifier the substitution to qualifier + */ + public FontSubstitution(FontQualifier fromQualifier, FontQualifier toQualifier) { + this.fromQualifier = fromQualifier; + this.toQualifier = toQualifier; + } + + /** + * @return the substitution from qualifier + */ + public FontQualifier getFromQualifier() { + return fromQualifier; + } + + /** + * @return the substitution to qualifier + */ + public FontQualifier getToQualifier() { + return toQualifier; + } + + /** + * {@inheritDoc} + */ + public String toString() { + return "from=" + fromQualifier + ", to=" + toQualifier; + } +}
\ No newline at end of file diff --git a/src/java/org/apache/fop/fonts/substitute/FontSubstitutions.java b/src/java/org/apache/fop/fonts/substitute/FontSubstitutions.java new file mode 100644 index 000000000..346b967e2 --- /dev/null +++ b/src/java/org/apache/fop/fonts/substitute/FontSubstitutions.java @@ -0,0 +1,66 @@ +/* + * 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.Iterator; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.fop.fonts.FontInfo; +import org.apache.fop.fonts.FontTriplet; + +/** + * Font substitutions + */ +public class FontSubstitutions extends java.util.ArrayList/*<Substitutions>*/ { + + private static final long serialVersionUID = -9173104935431899722L; + + /** logging instance */ + protected static Log log = LogFactory.getLog(FontSubstitutions.class); + + /** + * Adjusts a given fontInfo using this font substitution catalog + * @param fontInfo font info + */ + public void adjustFontInfo(FontInfo fontInfo) { + for (Iterator/*<FontSubstitution>*/ subsIt = super.iterator(); subsIt.hasNext();) { + FontSubstitution substitution = (FontSubstitution)subsIt.next(); + + // find the best matching font triplet + FontQualifier toQualifier = substitution.getToQualifier(); + FontTriplet fontTriplet = toQualifier.bestMatch(fontInfo); + if (fontTriplet == null) { + log.error("Unable to match font substitution for destination qualifier " + + toQualifier); + continue; + } + String internalFontKey = fontInfo.getInternalFontKey(fontTriplet); + + FontQualifier fromQualifier = substitution.getFromQualifier(); + List/*<FontTriplet>*/ tripletList = fromQualifier.getTriplets(); + for (Iterator tripletit = tripletList.iterator(); tripletit.hasNext();) { + FontTriplet triplet = (FontTriplet) tripletit.next(); + fontInfo.addFontProperties(internalFontKey, triplet); + } + } + } +} diff --git a/src/java/org/apache/fop/fonts/substitute/FontSubstitutionsConfigurator.java b/src/java/org/apache/fop/fonts/substitute/FontSubstitutionsConfigurator.java new file mode 100644 index 000000000..53045c601 --- /dev/null +++ b/src/java/org/apache/fop/fonts/substitute/FontSubstitutionsConfigurator.java @@ -0,0 +1,83 @@ +/* + * 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 org.apache.avalon.framework.configuration.Configuration; +import org.apache.fop.apps.FOPException; + +/** + * Configures a font substitution catalog + */ +public class FontSubstitutionsConfigurator { + + private Configuration cfg = null; + + /** + * Main constructor + * + * @param cfg a configuration + */ + public FontSubstitutionsConfigurator(Configuration cfg) { + this.cfg = cfg; + } + + private static FontQualifier getQualfierFromConfiguration(Configuration cfg) + throws FOPException { + String fontFamily = cfg.getAttribute("font-family", null); + if (fontFamily == null) { + throw new FOPException("substitution qualifier must have a font-family"); + } + FontQualifier qualifier = new FontQualifier(); + qualifier.setFontFamily(fontFamily); + String fontWeight = cfg.getAttribute("font-weight", null); + if (fontWeight != null) { + qualifier.setFontWeight(fontWeight); + } + String fontStyle = cfg.getAttribute("font-style", null); + if (fontStyle != null) { + qualifier.setFontStyle(fontStyle); + } + return qualifier; + } + + /** + * Configures a font substitution catalog + * + * @param substitutions font substitutions + * @throws FOPException if something's wrong with the config data + */ + public void configure(FontSubstitutions substitutions) throws FOPException { + Configuration[] substitutionCfgs = cfg.getChildren("substitution"); + for (int i = 0; i < substitutionCfgs.length; i++) { + Configuration fromCfg = substitutionCfgs[i].getChild("from", false); + if (fromCfg == null) { + throw new FOPException("'substitution' element without child 'from' element"); + } + Configuration toCfg = substitutionCfgs[i].getChild("to", false); + if (fromCfg == null) { + throw new FOPException("'substitution' element without child 'to' element"); + } + FontQualifier fromQualifier = getQualfierFromConfiguration(fromCfg); + FontQualifier toQualifier = getQualfierFromConfiguration(toCfg); + FontSubstitution substitution = new FontSubstitution(fromQualifier, toQualifier); + substitutions.add(substitution); + } + } +} diff --git a/src/java/org/apache/fop/fonts/substitute/FontWeightRange.java b/src/java/org/apache/fop/fonts/substitute/FontWeightRange.java new file mode 100644 index 000000000..630bc1895 --- /dev/null +++ b/src/java/org/apache/fop/fonts/substitute/FontWeightRange.java @@ -0,0 +1,115 @@ +/* + * 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.StringTokenizer; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.fop.fonts.FontUtil; + +/** + * Encapsulates a range of font weight values + */ +public class FontWeightRange { + + /** logging instance */ + protected static Log log = LogFactory.getLog("org.apache.fop.render.fonts"); + + /** + * Returns an <code>FontWeightRange</code> object holding the + * range values of the specified <code>String</code>. + * + * @param weightRangeString the value range string + * @return an <code>FontWeightRange</code> object holding the value ranges + */ + public static FontWeightRange valueOf(String weightRangeString) { + StringTokenizer rangeToken = new StringTokenizer(weightRangeString, ".."); + FontWeightRange weightRange = null; + if (rangeToken.countTokens() == 2) { + String weightString = rangeToken.nextToken().trim(); + try { + int start = Integer.parseInt(weightString); + if (start % 100 != 0) { + log.error("font-weight start range is not a multiple of 100"); + } + int end = Integer.parseInt(rangeToken.nextToken()); + if (end % 100 != 0) { + log.error("font-weight end range is not a multiple of 100"); + } + if (start <= end) { + weightRange = new FontWeightRange(start, end); + } else { + log.error("font-weight start range is greater than end range"); + } + } catch (NumberFormatException e) { + log.error("invalid font-weight value " + weightString); + } + } + return weightRange; + } + + /** the start range */ + private int start; + + /** the end range */ + private int end; + + /** + * Main constructor + * @param start the start value range + * @param end the end value range + */ + public FontWeightRange(int start, int end) { + this.start = start; + this.end = end; + } + + /** + * Returns true if the given integer value is within this integer range + * @param value the integer value + * @return true if the given integer value is within this integer range + */ + public boolean isWithinRange(int value) { + return (value >= start && value <= end); + } + + /** + * {@inheritDoc} + */ + public String toString() { + return start + ".." + end; + } + + /** + * @return an integer array containing the weight ranges + */ + public int[] toArray() { + int cnt = 0; + for (int i = start; i <= end; i += 100) { + cnt++; + } + int[] range = new int[cnt]; + for (int i = 0; i < cnt; i++) { + range[i] = start + (i * 100); + } + return range; + } +} |