diff options
Diffstat (limited to 'src/java/org')
41 files changed, 2263 insertions, 795 deletions
diff --git a/src/java/org/apache/fop/apps/FOURIResolver.java b/src/java/org/apache/fop/apps/FOURIResolver.java index f38be542a..bc0ca25b5 100644 --- a/src/java/org/apache/fop/apps/FOURIResolver.java +++ b/src/java/org/apache/fop/apps/FOURIResolver.java @@ -60,6 +60,34 @@ public class FOURIResolver implements javax.xml.transform.URIResolver { private boolean throwExceptions = false; /** + * Checks if the given base URL is acceptable. It also normalizes the URL. + * @param base the base URL to check + * @return the normalized URL + * @throws MalformedURLException if there's a problem with a file URL + */ + public String checkBaseURL(String base) throws MalformedURLException { + if (!base.endsWith("/")) { + // The behavior described by RFC 3986 regarding resolution of relative + // references may be misleading for normal users: + // file://path/to/resources + myResource.res -> file://path/to/myResource.res + // file://path/to/resources/ + myResource.res -> file://path/to/resources/myResource.res + // We assume that even when the ending slash is missing, users have the second + // example in mind + base += "/"; + } + File dir = new File(base); + try { + base = (dir.isDirectory() ? dir.toURL() : new URL(base)).toExternalForm(); + } catch (MalformedURLException mfue) { + if (throwExceptions) { + throw mfue; + } + log.error(mfue.getMessage()); + } + return base; + } + + /** * Default constructor */ public FOURIResolver() { diff --git a/src/java/org/apache/fop/apps/FOUserAgent.java b/src/java/org/apache/fop/apps/FOUserAgent.java index eea7f3926..f4c68933e 100644 --- a/src/java/org/apache/fop/apps/FOUserAgent.java +++ b/src/java/org/apache/fop/apps/FOUserAgent.java @@ -147,7 +147,7 @@ public class FOUserAgent { } this.factory = factory; setBaseURL(factory.getBaseURL()); - setFontBaseURL(factory.getFontBaseURL()); + setFontBaseURL(factory.getFontManager().getFontBaseURL()); setTargetResolution(factory.getTargetResolution()); } diff --git a/src/java/org/apache/fop/apps/FopFactory.java b/src/java/org/apache/fop/apps/FopFactory.java index ce77d9040..bd54ffb2f 100644 --- a/src/java/org/apache/fop/apps/FopFactory.java +++ b/src/java/org/apache/fop/apps/FopFactory.java @@ -24,7 +24,6 @@ import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.net.MalformedURLException; -import java.net.URL; import java.util.Collection; import java.util.Collections; import java.util.Set; @@ -45,6 +44,7 @@ import org.apache.xmlgraphics.image.loader.ImageManager; import org.apache.fop.fo.ElementMapping; import org.apache.fop.fo.ElementMappingRegistry; import org.apache.fop.fonts.FontCache; +import org.apache.fop.fonts.FontManager; import org.apache.fop.hyphenation.HyphenationTreeResolver; import org.apache.fop.layoutmgr.LayoutManagerMaker; import org.apache.fop.render.RendererFactory; @@ -84,6 +84,9 @@ public class FopFactory implements ImageContext { /** Image manager for loading and caching image objects */ private ImageManager imageManager; + /** Font manager for font substitution, autodetection and caching **/ + private FontManager fontManager; + /** Configuration layer used to configure fop */ private FopFactoryConfigurator config = null; @@ -93,9 +96,6 @@ public class FopFactory implements ImageContext { */ private String base = null; - /** The base URL for all font URL resolutions. */ - private String fontBase = null; - /** The base URL for all hyphen URL resolutions. */ private String hyphenBase = null; @@ -113,12 +113,6 @@ public class FopFactory implements ImageContext { */ private boolean strictUserConfigValidation = FopFactoryConfigurator.DEFAULT_STRICT_USERCONFIG_VALIDATION; - - /** Font cache to speed up auto-font configuration (null if disabled) */ - private FontCache fontCache = null; - - /** Allows enabling kerning on the base 14 fonts, default is false */ - private boolean enableBase14Kerning = false; /** Source resolution in dpi */ private float sourceResolution = FopFactoryConfigurator.DEFAULT_SOURCE_RESOLUTION; @@ -155,7 +149,6 @@ public class FopFactory implements ImageContext { this.rendererFactory = new RendererFactory(); this.xmlHandlers = new XMLHandlerRegistry(); this.ignoredNamespaces = new java.util.HashSet(); - setUseCache(FopFactoryConfigurator.DEFAULT_USE_CACHE); } /** @@ -317,42 +310,14 @@ public class FopFactory implements ImageContext { public LayoutManagerMaker getLayoutManagerMakerOverride() { return this.lmMakerOverride; } - - /** - * Checks if the given base URL is acceptable. It also normalizes the URL. - * @param base the base URL to check - * @return the normalized URL - * @throws MalformedURLException if there's a problem with a file URL - */ - private String checkBaseURL(String base) throws MalformedURLException { - if (!base.endsWith("/")) { - // The behavior described by RFC 3986 regarding resolution of relative - // references may be misleading for normal users: - // file://path/to/resources + myResource.res -> file://path/to/myResource.res - // file://path/to/resources/ + myResource.res -> file://path/to/resources/myResource.res - // We assume that even when the ending slash is missing, users have the second - // example in mind - base += "/"; - } - File dir = new File(base); - try { - base = (dir.isDirectory() ? dir.toURL() : new URL(base)).toExternalForm(); - } catch (MalformedURLException mfue) { - if (strictUserConfigValidation) { - throw mfue; - } - log.error(mfue.getMessage()); - } - return base; - } /** * Sets the base URL. - * @param base base URL + * @param base the base URL * @throws MalformedURLException if there's a problem with a file URL */ public void setBaseURL(String base) throws MalformedURLException { - this.base = checkBaseURL(base); + this.base = foURIResolver.checkBaseURL(base); } /** @@ -367,14 +332,18 @@ public class FopFactory implements ImageContext { * Sets the font base URL. * @param fontBase font base URL * @throws MalformedURLException if there's a problem with a file URL + * @deprecated use getFontManager().setFontBaseURL(fontBase) instead */ public void setFontBaseURL(String fontBase) throws MalformedURLException { - this.fontBase = checkBaseURL(fontBase); + getFontManager().setFontBaseURL(fontBase); } - /** @return the font base URL */ + /** + * @return the font base URL + * @deprecated use getFontManager().setFontBaseURL(fontBase) instead + */ public String getFontBaseURL() { - return this.fontBase; + return getFontManager().getFontBaseURL(); } /** @return the hyphen base URL */ @@ -396,7 +365,7 @@ public class FopFactory implements ImageContext { } }); } - this.hyphenBase = checkBaseURL(hyphenBase); + this.hyphenBase = foURIResolver.checkBaseURL(hyphenBase); } /** @@ -416,6 +385,14 @@ public class FopFactory implements ImageContext { return foURIResolver; } + /** + * Returns the FO URI Resolver. + * @return the FO URI Resolver + */ + public FOURIResolver getFOURIResolver() { + return foURIResolver; + } + /** @return the HyphenationTreeResolver for resolving user-supplied hyphenation patterns. */ public HyphenationTreeResolver getHyphenationTreeResolver() { return this.hyphResolver; @@ -471,17 +448,21 @@ public class FopFactory implements ImageContext { this.breakIndentInheritanceOnReferenceAreaBoundary = value; } - /** @return true if kerning on base 14 fonts is enabled */ + /** + * @return true if kerning on base 14 fonts is enabled + * @deprecated use getFontManager().isBase14KerningEnabled() instead + */ public boolean isBase14KerningEnabled() { - return this.enableBase14Kerning; + return getFontManager().isBase14KerningEnabled(); } /** * Controls whether kerning is activated on base 14 fonts. * @param value true if kerning should be activated + * @deprecated use getFontManager().setBase14KerningEnabled(boolean) instead */ public void setBase14KerningEnabled(boolean value) { - this.enableBase14Kerning = value; + getFontManager().setBase14KerningEnabled(value); } /** @return the resolution for resolution-dependant input */ @@ -681,37 +662,44 @@ public class FopFactory implements ImageContext { return this.strictUserConfigValidation; } - //------------------------------------------- Cache related stuff + //------------------------------------------- Font related stuff /** * Whether or not to cache results of font triplet detection/auto-config * @param useCache use cache or not + * @deprecated use getFontManager().setUseCache(boolean) instead */ public void setUseCache(boolean useCache) { - if (useCache) { - this.fontCache = FontCache.load(); - if (this.fontCache == null) { - this.fontCache = new FontCache(); - } - } else { - this.fontCache = null; - } + getFontManager().setUseCache(useCache); } /** * Cache results of font triplet detection/auto-config? * @return whether this factory is uses the cache + * @deprecated use getFontManager().useCache() instead */ public boolean useCache() { - return (this.fontCache != null); + return getFontManager().useCache(); } /** * Returns the font cache instance used by this factory. * @return the font cache + * @deprecated use getFontManager().getFontCache() instead */ public FontCache getFontCache() { - return this.fontCache; + return getFontManager().getFontCache(); + } + + /** + * Returns the font manager + * @return the font manager + */ + public FontManager getFontManager() { + if (fontManager == null) { + this.fontManager = new FontManager(this); + } + return this.fontManager; } /** diff --git a/src/java/org/apache/fop/apps/FopFactoryConfigurator.java b/src/java/org/apache/fop/apps/FopFactoryConfigurator.java index 4d4f8d3eb..89388ae77 100644 --- a/src/java/org/apache/fop/apps/FopFactoryConfigurator.java +++ b/src/java/org/apache/fop/apps/FopFactoryConfigurator.java @@ -28,6 +28,8 @@ import org.apache.avalon.framework.configuration.ConfigurationException; import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.fop.fonts.FontManager; +import org.apache.fop.fonts.FontManagerConfigurator; import org.apache.fop.util.LogUtil; import org.xml.sax.SAXException; @@ -57,9 +59,6 @@ public class FopFactoryConfigurator { /** Defines the default target resolution (72dpi) for FOP */ public static final float DEFAULT_TARGET_RESOLUTION = 72.0f; //dpi - /** Use cache (record previously detected font triplet info) */ - public static final boolean DEFAULT_USE_CACHE = true; - /** logger instance */ private final Log log = LogFactory.getLog(FopFactoryConfigurator.class); @@ -119,14 +118,6 @@ public class FopFactoryConfigurator { LogUtil.handleException(log, mfue, strict); } } - if (cfg.getChild("font-base", false) != null) { - try { - factory.setFontBaseURL( - cfg.getChild("font-base").getValue(null)); - } catch (MalformedURLException mfue) { - LogUtil.handleException(log, mfue, strict); - } - } if (cfg.getChild("hyphenation-base", false) != null) { try { factory.setHyphenBaseURL( @@ -180,15 +171,10 @@ public class FopFactoryConfigurator { } } - // caching (fonts) - if (cfg.getChild("use-cache", false) != null) { - try { - factory.setUseCache( - cfg.getChild("use-cache").getValueAsBoolean()); - } catch (ConfigurationException mfue) { - LogUtil.handleException(log, mfue, strict); - } - } + // configure font manager + FontManager fontManager = factory.getFontManager(); + FontManagerConfigurator fontManagerConfigurator = new FontManagerConfigurator(cfg); + fontManagerConfigurator.configure(fontManager); } /** 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; + } +} diff --git a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java index 76c5ad4da..f83434f47 100644 --- a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java @@ -58,8 +58,10 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager /** True if this LayoutManager has handled all of its content. */ private boolean bFinished = false; - /** child LM and child LM iterator during getNextKnuthElement phase */ + /** child LM during getNextKnuthElement phase */ protected LayoutManager curChildLM = null; + + /** child LM iterator during getNextKnuthElement phase */ protected ListIterator childLMiter = null; private int lastGeneratedPosition = -1; diff --git a/src/java/org/apache/fop/render/AbstractRendererConfigurator.java b/src/java/org/apache/fop/render/AbstractRendererConfigurator.java index d6851c3c5..bce5abfbd 100644 --- a/src/java/org/apache/fop/render/AbstractRendererConfigurator.java +++ b/src/java/org/apache/fop/render/AbstractRendererConfigurator.java @@ -45,7 +45,6 @@ public abstract class AbstractRendererConfigurator { super(); this.userAgent = userAgent; } - /** * Returns the configuration subtree for a specific renderer. @@ -61,16 +60,15 @@ public abstract class AbstractRendererConfigurator { return null; } - return getRendererConfig(userAgent, mimeType); + return getRendererConfig(mimeType); } /** * Returns the configuration subtree for a specific renderer. - * @param userAgent the user agent containing the user configuration * @param mimeType the MIME type of the renderer * @return the requested configuration subtree, null if there's no configuration */ - public static Configuration getRendererConfig(FOUserAgent userAgent, String mimeType) { + private Configuration getRendererConfig(String mimeType) { Configuration cfg = userAgent.getFactory().getUserConfig(); if (cfg == null) { if (log.isDebugEnabled()) { diff --git a/src/java/org/apache/fop/render/PrintRenderer.java b/src/java/org/apache/fop/render/PrintRenderer.java index 6f1bfeea6..23f8a1f62 100644 --- a/src/java/org/apache/fop/render/PrintRenderer.java +++ b/src/java/org/apache/fop/render/PrintRenderer.java @@ -25,7 +25,6 @@ import org.apache.fop.area.Trait; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontInfo; import org.apache.fop.fonts.FontResolver; -import org.apache.fop.fonts.FontSetup; import org.apache.fop.fonts.FontTriplet; import org.w3c.dom.Document; @@ -45,25 +44,32 @@ public abstract class PrintRenderer extends AbstractRenderer { protected FontResolver fontResolver = null; /** list of fonts */ - protected List fontList = null; + protected List/*<EmbedFontInfo>*/ embedFontInfoList = null; /** - * adds a font list to current list of fonts - * @param fontInfoList font list + * Adds a font list to current list of fonts + * @param fontList a font info list */ - public void addFontList(List fontInfoList) { - if (this.fontList == null) { - setFontList(fontInfoList); + public void addFontList(List/*<EmbedFontInfo>*/ fontList) { + if (embedFontInfoList == null) { + setFontList(fontList); } else { - this.fontList.addAll(fontInfoList); + fontList.addAll(fontList); } } /** - * @param fontList list of available fonts + * @param embedFontInfoList list of available fonts */ - public void setFontList(List fontList) { - this.fontList = fontList; + public void setFontList(List/*<EmbedFontInfo>*/ embedFontInfoList) { + this.embedFontInfoList = embedFontInfoList; + } + + /** + * @return list of available embedded fonts + */ + public List/*<EmbedFontInfo>*/ getFontList() { + return this.embedFontInfoList; } /** @@ -73,8 +79,7 @@ public abstract class PrintRenderer extends AbstractRenderer { */ public void setupFontInfo(FontInfo inFontInfo) { this.fontInfo = inFontInfo; - FontSetup.setup(fontInfo, fontList, fontResolver, - userAgent.getFactory().isBase14KerningEnabled()); + userAgent.getFactory().getFontManager().setupRenderer(this); } /** @@ -180,4 +185,11 @@ public abstract class PrintRenderer extends AbstractRenderer { } return this.fontResolver; } + + /** + * @return the font info + */ + public FontInfo getFontInfo() { + return this.fontInfo; + } } diff --git a/src/java/org/apache/fop/render/PrintRendererConfigurator.java b/src/java/org/apache/fop/render/PrintRendererConfigurator.java index 674c357df..6273b7050 100644 --- a/src/java/org/apache/fop/render/PrintRendererConfigurator.java +++ b/src/java/org/apache/fop/render/PrintRendererConfigurator.java @@ -44,8 +44,8 @@ import org.apache.fop.apps.FopFactory; import org.apache.fop.fonts.EmbedFontInfo; import org.apache.fop.fonts.FontCache; import org.apache.fop.fonts.FontInfo; +import org.apache.fop.fonts.FontManager; import org.apache.fop.fonts.FontResolver; -import org.apache.fop.fonts.FontSetup; import org.apache.fop.fonts.FontTriplet; import org.apache.fop.fonts.FontUtil; import org.apache.fop.fonts.autodetect.FontFileFinder; @@ -78,28 +78,30 @@ public class PrintRendererConfigurator extends AbstractRendererConfigurator public void configure(Renderer renderer) throws FOPException { Configuration cfg = getRendererConfig(renderer); if (cfg == null) { + log.trace("no configuration found for " + renderer); return; } PrintRenderer printRenderer = (PrintRenderer)renderer; FontResolver fontResolver = printRenderer.getFontResolver(); + FopFactory factory = userAgent.getFactory(); + FontManager fontManager = factory.getFontManager(); if (fontResolver == null) { //Ensure that we have minimal font resolution capabilities - fontResolver = FontSetup.createMinimalFontResolver(); + fontResolver = FontManager.createMinimalFontResolver(); } - FopFactory factory = userAgent.getFactory(); boolean strict = factory.validateUserConfigStrictly(); - FontCache fontCache = factory.getFontCache(); + FontCache fontCache = fontManager.getFontCache(); - List fontInfoList = buildFontListFromConfiguration(cfg, + List/*<EmbedFontInfo>*/ embedFontInfoList = buildFontListFromConfiguration(cfg, userAgent.getFontBaseURL(), fontResolver, strict, fontCache); if (fontCache != null && fontCache.hasChanged()) { fontCache.save(); } - printRenderer.addFontList(fontInfoList); + printRenderer.addFontList(embedFontInfoList); } /** @@ -113,10 +115,11 @@ public class PrintRendererConfigurator extends AbstractRendererConfigurator * @return a List of EmbedFontInfo objects. * @throws FOPException If an error occurs while processing the configuration */ - public static List buildFontListFromConfiguration(Configuration cfg, + public static List/*<EmbedFontInfo>*/ buildFontListFromConfiguration(Configuration cfg, String fontBaseURL, FontResolver fontResolver, boolean strict, FontCache fontCache) throws FOPException { - List fontInfoList = new java.util.ArrayList(); + List/*<EmbedFontInfo>*/ fontInfoList + = new java.util.ArrayList/*<EmbedFontInfo>*/(); Configuration fonts = cfg.getChild("fonts", false); if (fonts != null) { @@ -204,12 +207,13 @@ public class PrintRendererConfigurator extends AbstractRendererConfigurator // font file (singular) configuration Configuration[] font = fonts.getChildren("font"); for (int i = 0; i < font.length; i++) { - EmbedFontInfo fontInfo = getFontInfoFromConfiguration( + EmbedFontInfo embedFontInfo = getFontInfoFromConfiguration( font[i], fontResolver, strict, fontCache); - if (fontInfo != null) { - fontInfoList.add(fontInfo); + if (embedFontInfo != null) { + fontInfoList.add(embedFontInfo); } } + if (log.isDebugEnabled()) { log.debug("Finished font configuration in " + (System.currentTimeMillis() - start) + "ms"); @@ -221,11 +225,12 @@ public class PrintRendererConfigurator extends AbstractRendererConfigurator /** * Iterates over font file list adding font info to list * @param fontFileList font file list - * @param fontInfoList font info list + * @param embedFontInfoList a configured font info list * @param resolver font resolver */ private static void addFontInfoListFromFileList( - List fontFileList, List fontInfoList, FontResolver resolver, FontCache fontCache) { + List fontFileList, List/*<EmbedFontInfo>*/ embedFontInfoList, + FontResolver resolver, FontCache fontCache) { for (Iterator iter = fontFileList.iterator(); iter.hasNext();) { URL fontUrl = (URL)iter.next(); // parse font to ascertain font info @@ -242,7 +247,7 @@ public class PrintRendererConfigurator extends AbstractRendererConfigurator for (int i = 0, c = embedFontInfos.length; i < c; i++) { EmbedFontInfo fontInfo = embedFontInfos[i]; if (fontInfo != null) { - fontInfoList.add(fontInfo); + embedFontInfoList.add(fontInfo); } } } @@ -257,24 +262,64 @@ public class PrintRendererConfigurator extends AbstractRendererConfigurator } /** + * Creates a new FontTriplet given a triple Configuration + * + * @param tripletCfg a triplet configuration + * @param strict use strict validation + * @return a font triplet font key + * @throws FOPException thrown if a FOP exception occurs + */ + private static FontTriplet getFontTripletFromConfiguration( + Configuration tripletCfg, boolean strict) throws FOPException { + try { + String name = tripletCfg.getAttribute("name"); + if (name == null) { + LogUtil.handleError(log, "font-triplet without name", strict); + return null; + } + + String weightStr = tripletCfg.getAttribute("weight"); + if (weightStr == null) { + LogUtil.handleError(log, "font-triplet without weight", strict); + return null; + } + int weight = FontUtil.parseCSS2FontWeight(FontUtil.stripWhiteSpace(weightStr)); + + String style = tripletCfg.getAttribute("style"); + if (style == null) { + LogUtil.handleError(log, "font-triplet without style", strict); + return null; + } else { + style = FontUtil.stripWhiteSpace(style); + } + return FontInfo.createFontKey(name, style, weight); + } catch (ConfigurationException e) { + LogUtil.handleException(log, e, strict); + } + return null; + } + + /** * Returns a font info from a font node Configuration definition * * @param fontCfg Configuration object (font node) * @param fontResolver font resolver used to resolve font * @param strict validate configuration strictly * @param fontCache the font cache (or null if it is disabled) - * @return font info + * @return the embedded font info * @throws FOPException if something's wrong with the config data */ - public static EmbedFontInfo getFontInfoFromConfiguration( + private static EmbedFontInfo getFontInfoFromConfiguration( Configuration fontCfg, FontResolver fontResolver, boolean strict, FontCache fontCache) throws FOPException { String metricsUrl = fontCfg.getAttribute("metrics-url", null); String embedUrl = fontCfg.getAttribute("embed-url", null); String subFont = fontCfg.getAttribute("sub-font", null); - + if (metricsUrl == null && embedUrl == null) { - LogUtil.handleError(log, "Font configuration without metric-url or embed-url", strict); + LogUtil.handleError(log, + "Font configuration without metric-url or embed-url attribute", + strict); return null; } if (strict) { @@ -299,15 +344,13 @@ public class PrintRendererConfigurator extends AbstractRendererConfigurator } } } - boolean useKerning = fontCfg.getAttributeAsBoolean("kerning", true); - EmbedFontInfo fontInfo = null; Configuration[] tripletCfg = fontCfg.getChildren("font-triplet"); + // no font triplet info if (tripletCfg.length == 0) { LogUtil.handleError(log, "font without font-triplet", strict); - - // if not strict try to determine font info from the embed/metrics url + File fontFile = FontCache.getFileFromUrls(new String[] {embedUrl, metricsUrl}); URL fontUrl; try { @@ -324,53 +367,36 @@ public class PrintRendererConfigurator extends AbstractRendererConfigurator } else { return null; } - } else { - List tripleList = new java.util.ArrayList(); - for (int j = 0; j < tripletCfg.length; j++) { - try { - String name = tripletCfg[j].getAttribute("name"); - if (name == null) { - LogUtil.handleError(log, "font-triplet without name", strict); - continue; - } - String weightStr = tripletCfg[j].getAttribute("weight"); - if (weightStr == null) { - LogUtil.handleError(log, "font-triplet without weight", strict); - continue; - } - int weight = FontUtil.parseCSS2FontWeight(weightStr); - String style = tripletCfg[j].getAttribute("style"); - if (style == null) { - LogUtil.handleError(log, "font-triplet without style", strict); - continue; - } - tripleList.add(FontInfo.createFontKey(name, style, weight)); - } catch (ConfigurationException e) { - LogUtil.handleException(log, e, strict); - } - } - - fontInfo = new EmbedFontInfo(metricsUrl, useKerning, tripleList, embedUrl, subFont); - - if (fontCache != null) { - if (!fontCache.containsFont(fontInfo)) { - fontCache.addFont(fontInfo); - } + } + + List/*<FontTriplet>*/ tripletList = new java.util.ArrayList/*<FontTriplet>*/(); + for (int j = 0; j < tripletCfg.length; j++) { + FontTriplet fontTriplet = getFontTripletFromConfiguration(tripletCfg[j], strict); + tripletList.add(fontTriplet); + } + + boolean useKerning = fontCfg.getAttributeAsBoolean("kerning", true); + EmbedFontInfo embedFontInfo + = new EmbedFontInfo(metricsUrl, useKerning, tripletList, embedUrl, subFont); + if (fontCache != null) { + if (!fontCache.containsFont(embedFontInfo)) { + fontCache.addFont(embedFontInfo); } - - if (log.isDebugEnabled()) { - log.debug("Adding font " + fontInfo.getEmbedFile() - + ", metric file " + fontInfo.getMetricsFile()); - for (int j = 0; j < tripleList.size(); ++j) { - FontTriplet triplet = (FontTriplet) tripleList.get(j); - log.debug(" Font triplet " - + triplet.getName() + ", " - + triplet.getStyle() + ", " - + triplet.getWeight()); - } - } } - return fontInfo; + + if (log.isDebugEnabled()) { + String embedFile = embedFontInfo.getEmbedFile(); + log.debug("Adding font " + (embedFile != null ? embedFile + ", " : "") + + "metric file " + embedFontInfo.getMetricsFile()); + for (int j = 0; j < tripletList.size(); ++j) { + FontTriplet triplet = (FontTriplet) tripletList.get(j); + log.debug(" Font triplet " + + triplet.getName() + ", " + + triplet.getStyle() + ", " + + triplet.getWeight()); + } + } + return embedFontInfo; } } diff --git a/src/java/org/apache/fop/render/afp/AFPRenderer.java b/src/java/org/apache/fop/render/afp/AFPRenderer.java index 526fc43f3..14eb33510 100644 --- a/src/java/org/apache/fop/render/afp/AFPRenderer.java +++ b/src/java/org/apache/fop/render/afp/AFPRenderer.java @@ -283,8 +283,8 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { public void setupFontInfo(FontInfo inFontInfo) { this.fontInfo = inFontInfo; int num = 1; - if (this.fontList != null && this.fontList.size() > 0) { - for (Iterator it = this.fontList.iterator(); it.hasNext();) { + if (super.embedFontInfoList != null && super.embedFontInfoList.size() > 0) { + for (Iterator it = super.embedFontInfoList.iterator(); it.hasNext();) { AFPFontInfo afi = (AFPFontInfo)it.next(); AFPFont bf = (AFPFont)afi.getAFPFont(); for (Iterator it2 = afi.getFontTriplets().iterator(); it2.hasNext();) { diff --git a/src/java/org/apache/fop/render/java2d/Base14FontCollection.java b/src/java/org/apache/fop/render/java2d/Base14FontCollection.java new file mode 100644 index 000000000..f97a68191 --- /dev/null +++ b/src/java/org/apache/fop/render/java2d/Base14FontCollection.java @@ -0,0 +1,181 @@ +/* + * 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.render.java2d; + +import java.awt.Graphics2D; + +import org.apache.fop.fonts.Font; +import org.apache.fop.fonts.FontCollection; +import org.apache.fop.fonts.FontInfo; + +/** + * A base 14 font collection for graphics 2D + */ +public class Base14FontCollection implements FontCollection { + + private Graphics2D graphics2d = null; + + /** + * Main constructor + * @param graphics2d a graphics 2D + */ + public Base14FontCollection(Graphics2D graphics2d) { + this.graphics2d = graphics2d; + } + + /** + * {@inheritDoc} + */ + public int setup(int start, FontInfo fontInfo) { + /* + * available java fonts are: + * Serif - bold, normal, italic, bold-italic + * SansSerif - bold, normal, italic, bold-italic + * MonoSpaced - bold, normal, italic, bold-italic + */ + final int normal = java.awt.Font.PLAIN; + final int bold = java.awt.Font.BOLD; + final int italic = java.awt.Font.ITALIC; + final int bolditalic = java.awt.Font.BOLD + java.awt.Font.ITALIC; + + FontMetricsMapper metric; + metric = new SystemFontMetricsMapper("SansSerif", normal, graphics2d); + // --> goes to F1 + fontInfo.addMetrics("F1", metric); + metric = new SystemFontMetricsMapper("SansSerif", italic, graphics2d); + // --> goes to F2 + fontInfo.addMetrics("F2", metric); + metric = new SystemFontMetricsMapper("SansSerif", bold, graphics2d); + // --> goes to F3 + fontInfo.addMetrics("F3", metric); + metric = new SystemFontMetricsMapper("SansSerif", bolditalic, graphics2d); + // --> goes to F4 + fontInfo.addMetrics("F4", metric); + + + metric = new SystemFontMetricsMapper("Serif", normal, graphics2d); + // --> goes to F5 + fontInfo.addMetrics("F5", metric); + metric = new SystemFontMetricsMapper("Serif", italic, graphics2d); + // --> goes to F6 + fontInfo.addMetrics("F6", metric); + metric = new SystemFontMetricsMapper("Serif", bold, graphics2d); + // --> goes to F7 + fontInfo.addMetrics("F7", metric); + metric = new SystemFontMetricsMapper("Serif", bolditalic, graphics2d); + // --> goes to F8 + fontInfo.addMetrics("F8", metric); + + metric = new SystemFontMetricsMapper("MonoSpaced", normal, graphics2d); + // --> goes to F9 + fontInfo.addMetrics("F9", metric); + metric = new SystemFontMetricsMapper("MonoSpaced", italic, graphics2d); + // --> goes to F10 + fontInfo.addMetrics("F10", metric); + metric = new SystemFontMetricsMapper("MonoSpaced", bold, graphics2d); + // --> goes to F11 + fontInfo.addMetrics("F11", metric); + metric = new SystemFontMetricsMapper("MonoSpaced", bolditalic, graphics2d); + // --> goes to F12 + fontInfo.addMetrics("F12", metric); + + metric = new SystemFontMetricsMapper("Serif", normal, graphics2d); + //"Symbol" doesn't seem to work here, but "Serif" does the job just fine. *shrug* + // --> goes to F13 and F14 + fontInfo.addMetrics("F13", metric); + fontInfo.addMetrics("F14", metric); + + // 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("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("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", + "normal", Font.WEIGHT_NORMAL); + + return 15; + } +} diff --git a/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java b/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java new file mode 100644 index 000000000..771d3f2d7 --- /dev/null +++ b/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java @@ -0,0 +1,111 @@ +/* + * 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.render.java2d; + +import java.util.List; + +import javax.xml.transform.Source; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.fop.fonts.CustomFont; +import org.apache.fop.fonts.EmbedFontInfo; +import org.apache.fop.fonts.FontCollection; +import org.apache.fop.fonts.FontInfo; +import org.apache.fop.fonts.FontLoader; +import org.apache.fop.fonts.FontManager; +import org.apache.fop.fonts.FontResolver; +import org.apache.fop.fonts.FontTriplet; +import org.apache.fop.fonts.LazyFont; +import org.apache.fop.render.PrintRenderer; + +/** + * A java2d configured font collection + */ +public class ConfiguredFontCollection implements FontCollection { + + private static Log log = LogFactory.getLog(ConfiguredFontCollection.class); + + private PrintRenderer renderer = null; + + /** + * Main constructor + * + * @param renderer a print renderer + */ + public ConfiguredFontCollection(PrintRenderer renderer) { + this.renderer = renderer; + } + + /** + * {@inheritDoc} + */ + public int setup(int start, FontInfo fontInfo) { + List/*<EmbedFontInfo>*/ fontList = renderer.getFontList(); + FontResolver resolver = renderer.getFontResolver(); + int num = start; + if (fontList == null || fontList.size() < 1) { + log.debug("No user configured fonts found."); + return num; + } + if (resolver == null) { + // Ensure that we have minimal font resolution capabilities + resolver = FontManager.createMinimalFontResolver(); + } + String internalName = null; + + for (int i = 0; i < fontList.size(); i++) { + + EmbedFontInfo configFontInfo = (EmbedFontInfo) fontList.get(i); + String fontFile = configFontInfo.getEmbedFile(); + internalName = "F" + num; + num++; + try { + FontMetricsMapper font = null; + String metricsUrl = configFontInfo.getMetricsFile(); + // If the user specified an XML-based metrics file, we'll use it + // Otherwise, calculate metrics directly from the font file. + if (metricsUrl != null) { + LazyFont fontMetrics = new LazyFont(configFontInfo, resolver); + Source fontSource = resolver.resolve(configFontInfo.getEmbedFile()); + font = new CustomFontMetricsMapper(fontMetrics, fontSource); + } else { + CustomFont fontMetrics = FontLoader.loadFont(fontFile, null, resolver); + font = new CustomFontMetricsMapper(fontMetrics); + } + + fontInfo.addMetrics(internalName, font); + + List triplets = configFontInfo.getFontTriplets(); + for (int c = 0; c < triplets.size(); c++) { + FontTriplet triplet = (FontTriplet) triplets.get(c); + + if (log.isDebugEnabled()) { + log.debug("Registering: " + triplet + " under " + internalName); + } + fontInfo.addFontProperties(internalName, triplet); + } + } catch (Exception e) { + log.warn("Unable to load custom font from file '" + fontFile + "'", e); + } + } + return num; + } +} diff --git a/src/java/org/apache/fop/render/java2d/FontSetup.java b/src/java/org/apache/fop/render/java2d/FontSetup.java deleted file mode 100644 index ade457d95..000000000 --- a/src/java/org/apache/fop/render/java2d/FontSetup.java +++ /dev/null @@ -1,353 +0,0 @@ -/* - * 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.render.java2d; - -// FOP -import java.awt.Graphics2D; -import java.awt.GraphicsEnvironment; -import java.util.List; -import java.util.Set; - -import javax.xml.transform.Source; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.apache.fop.fonts.CustomFont; -import org.apache.fop.fonts.EmbedFontInfo; -import org.apache.fop.fonts.Font; -import org.apache.fop.fonts.FontInfo; -import org.apache.fop.fonts.FontLoader; -import org.apache.fop.fonts.FontResolver; -import org.apache.fop.fonts.FontTriplet; -import org.apache.fop.fonts.FontUtil; -import org.apache.fop.fonts.LazyFont; - -/** - * Sets up the Java2D/AWT fonts. It is similar to - * org.apache.fop.render.fonts.FontSetup. - * Assigns the font (with metrics) to internal names like "F1" and - * assigns family-style-weight triplets to the fonts. - */ -public class FontSetup { - - /** logging instance */ - protected static Log log = LogFactory.getLog(FontSetup.class); - - private static final int LAST_PREDEFINED_FONT_NUMBER = 14; - - private static final Set HARDCODED_FONT_NAMES; - - static { - HARDCODED_FONT_NAMES = new java.util.HashSet(); - HARDCODED_FONT_NAMES.add("any"); - HARDCODED_FONT_NAMES.add("sans-serif"); - HARDCODED_FONT_NAMES.add("serif"); - HARDCODED_FONT_NAMES.add("monospace"); - - HARDCODED_FONT_NAMES.add("Helvetica"); - HARDCODED_FONT_NAMES.add("Times"); - HARDCODED_FONT_NAMES.add("Courier"); - HARDCODED_FONT_NAMES.add("Symbol"); - HARDCODED_FONT_NAMES.add("ZapfDingbats"); - HARDCODED_FONT_NAMES.add("Times Roman"); - HARDCODED_FONT_NAMES.add("Times-Roman"); - HARDCODED_FONT_NAMES.add("Computer-Modern-Typewriter"); - } - - /** - * 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 configuredFontList of fop config fonts - * @param resolver for resolving the font file URI - * @param graphics needed for access to font metrics - */ - public static void setup(FontInfo fontInfo, List configuredFontList, - FontResolver resolver, Graphics2D graphics) { - FontMetricsMapper metric; - int normal, bold, bolditalic, italic; - - /* - * available java fonts are: - * Serif - bold, normal, italic, bold-italic - * SansSerif - bold, normal, italic, bold-italic - * MonoSpaced - bold, normal, italic, bold-italic - */ - normal = java.awt.Font.PLAIN; - bold = java.awt.Font.BOLD; - italic = java.awt.Font.ITALIC; - bolditalic = java.awt.Font.BOLD + java.awt.Font.ITALIC; - - metric = new SystemFontMetricsMapper("SansSerif", normal, graphics); - // --> goes to F1 - fontInfo.addMetrics("F1", metric); - metric = new SystemFontMetricsMapper("SansSerif", italic, graphics); - // --> goes to F2 - fontInfo.addMetrics("F2", metric); - metric = new SystemFontMetricsMapper("SansSerif", bold, graphics); - // --> goes to F3 - fontInfo.addMetrics("F3", metric); - metric = new SystemFontMetricsMapper("SansSerif", bolditalic, graphics); - // --> goes to F4 - fontInfo.addMetrics("F4", metric); - - - metric = new SystemFontMetricsMapper("Serif", normal, graphics); - // --> goes to F5 - fontInfo.addMetrics("F5", metric); - metric = new SystemFontMetricsMapper("Serif", italic, graphics); - // --> goes to F6 - fontInfo.addMetrics("F6", metric); - metric = new SystemFontMetricsMapper("Serif", bold, graphics); - // --> goes to F7 - fontInfo.addMetrics("F7", metric); - metric = new SystemFontMetricsMapper("Serif", bolditalic, graphics); - // --> goes to F8 - fontInfo.addMetrics("F8", metric); - - metric = new SystemFontMetricsMapper("MonoSpaced", normal, graphics); - // --> goes to F9 - fontInfo.addMetrics("F9", metric); - metric = new SystemFontMetricsMapper("MonoSpaced", italic, graphics); - // --> goes to F10 - fontInfo.addMetrics("F10", metric); - metric = new SystemFontMetricsMapper("MonoSpaced", bold, graphics); - // --> goes to F11 - fontInfo.addMetrics("F11", metric); - metric = new SystemFontMetricsMapper("MonoSpaced", bolditalic, graphics); - // --> goes to F12 - fontInfo.addMetrics("F12", metric); - - metric = new SystemFontMetricsMapper("Serif", normal, graphics); - //"Symbol" doesn't seem to work here, but "Serif" does the job just fine. *shrug* - // --> goes to F13 and F14 - fontInfo.addMetrics("F13", metric); - fontInfo.addMetrics("F14", metric); - - // 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", "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("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("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); - - // 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", "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("F9", "Computer-Modern-Typewriter", - "normal", Font.WEIGHT_NORMAL); - - int lastNum = configureInstalledAWTFonts(fontInfo, graphics, LAST_PREDEFINED_FONT_NUMBER + 1); - addConfiguredFonts(fontInfo, configuredFontList, resolver, lastNum++); - } - - private static int configureInstalledAWTFonts(FontInfo fontInfo, Graphics2D graphics, - int startNumber) { - int num = startNumber; - GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); - - java.awt.Font[] fonts = env.getAllFonts(); - for (int i = 0; i < fonts.length; i++) { - java.awt.Font f = fonts[i]; - if (HARDCODED_FONT_NAMES.contains(f.getName())) { - continue; //skip - } - - if (log.isTraceEnabled()) { - log.trace("AWT Font: " + f.getFontName() - + ", family: " + f.getFamily() - + ", PS: " + f.getPSName() - + ", Name: " + f.getName() - + ", Angle: " + f.getItalicAngle() - + ", Style: " + f.getStyle()); - } - - String searchName = FontUtil.stripWhiteSpace(f.getName()).toLowerCase(); - String guessedStyle = FontUtil.guessStyle(searchName); - int guessedWeight = FontUtil.guessWeight(searchName); - - num++; - String fontKey = "F" + num; - int style = convertToAWTFontStyle(guessedStyle, guessedWeight); - addFontMetricsMapper(fontInfo, f.getName(), fontKey, graphics, style); - - //Register appropriate font triplets matching the font. Two different strategies: - //Example: "Arial Bold", normal, normal - addFontTriplet(fontInfo, f.getName(), - Font.STYLE_NORMAL, Font.WEIGHT_NORMAL, fontKey); - if (!f.getName().equals(f.getFamily())) { - //Example: "Arial", bold, normal - addFontTriplet(fontInfo, f.getFamily(), - guessedStyle, guessedWeight, fontKey); - } - } - return num; - - } - - /** - * Add fonts from configuration file starting with internal name F<num>. - * - * @param fontInfo the font info object to set up - * @param fontList a list of EmbedFontInfo objects - * @param num starting index for internal font numbering - * @param resolver the font resolver - */ - private static void addConfiguredFonts(FontInfo fontInfo, List fontList, FontResolver resolver, int num) { - - if (fontList == null || fontList.size() < 1) { - log.debug("No user configured fonts found."); - return; - } - if (resolver == null) { - // Ensure that we have minimal font resolution capabilities - resolver = org.apache.fop.fonts.FontSetup - .createMinimalFontResolver(); - } - String internalName = null; - - for (int i = 0; i < fontList.size(); i++) { - - EmbedFontInfo configFontInfo = (EmbedFontInfo) fontList.get(i); - String fontFile = configFontInfo.getEmbedFile(); - internalName = "F" + num; - num++; - try { - FontMetricsMapper font = null; - String metricsUrl = configFontInfo.getMetricsFile(); - // If the user specified an XML-based metrics file, we'll use it - // Otherwise, calculate metrics directly from the font file. - if (metricsUrl != null) { - LazyFont fontMetrics = new LazyFont(configFontInfo, resolver); - Source fontSource = resolver.resolve(configFontInfo.getEmbedFile()); - font = new CustomFontMetricsMapper(fontMetrics, fontSource); - } else { - CustomFont fontMetrics = FontLoader.loadFont(fontFile, null, resolver); - font = new CustomFontMetricsMapper(fontMetrics); - } - - fontInfo.addMetrics(internalName, font); - - List triplets = configFontInfo.getFontTriplets(); - for (int c = 0; c < triplets.size(); c++) { - FontTriplet triplet = (FontTriplet) triplets.get(c); - - if (log.isDebugEnabled()) { - log.debug("Registering: " + triplet + " under " + internalName); - } - fontInfo.addFontProperties(internalName, triplet); - } - } catch (Exception e) { - log.warn("Unable to load custom font from file '" + fontFile + "'", e); - } - } - } - - - private static void addFontTriplet(FontInfo fontInfo, String fontName, String fontStyle, - int fontWeight, String fontKey) { - FontTriplet triplet = FontInfo.createFontKey(fontName, fontStyle, fontWeight); - fontInfo.addFontProperties(fontKey, triplet); - } - - private static void addFontMetricsMapper(FontInfo fontInfo, String family, String fontKey, - Graphics2D graphics, int style) { - FontMetricsMapper metric = new SystemFontMetricsMapper(family, style, graphics); - fontInfo.addMetrics(fontKey, metric); - } - - private static int convertToAWTFontStyle(String fontStyle, int fontWeight) { - int style = java.awt.Font.PLAIN; - if (fontWeight >= Font.WEIGHT_BOLD) { - style |= java.awt.Font.BOLD; - } - if (!"normal".equals(fontStyle)) { - style |= java.awt.Font.ITALIC; - } - return style; - } - -} - diff --git a/src/java/org/apache/fop/render/java2d/InstalledFontCollection.java b/src/java/org/apache/fop/render/java2d/InstalledFontCollection.java new file mode 100644 index 000000000..4cdd30c41 --- /dev/null +++ b/src/java/org/apache/fop/render/java2d/InstalledFontCollection.java @@ -0,0 +1,138 @@ +/* + * 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.render.java2d; + +import java.awt.Graphics2D; +import java.awt.GraphicsEnvironment; +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.FontCollection; +import org.apache.fop.fonts.FontInfo; +import org.apache.fop.fonts.FontTriplet; +import org.apache.fop.fonts.FontUtil; + +/** + * A custom AWT font collection + */ +public class InstalledFontCollection implements FontCollection { + + private static Log log = LogFactory.getLog(InstalledFontCollection.class); + + private static final Set HARDCODED_FONT_NAMES; + + static { + HARDCODED_FONT_NAMES = new java.util.HashSet(); + HARDCODED_FONT_NAMES.add("any"); + HARDCODED_FONT_NAMES.add("sans-serif"); + HARDCODED_FONT_NAMES.add("serif"); + HARDCODED_FONT_NAMES.add("monospace"); + + HARDCODED_FONT_NAMES.add("Helvetica"); + HARDCODED_FONT_NAMES.add("Times"); + HARDCODED_FONT_NAMES.add("Courier"); + HARDCODED_FONT_NAMES.add("Symbol"); + HARDCODED_FONT_NAMES.add("ZapfDingbats"); + HARDCODED_FONT_NAMES.add("Times Roman"); + HARDCODED_FONT_NAMES.add("Times-Roman"); + HARDCODED_FONT_NAMES.add("Computer-Modern-Typewriter"); + } + + private Graphics2D graphics2D = null; + + /** + * Main constructor + * + * @param graphics2D a graphics 2D + */ + public InstalledFontCollection(Graphics2D graphics2D) { + this.graphics2D = graphics2D; + } + + /** + * {@inheritDoc} + */ + public int setup(int start, FontInfo fontInfo) { + int num = start; + GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); + + java.awt.Font[] fonts = env.getAllFonts(); + for (int i = 0; i < fonts.length; i++) { + java.awt.Font f = fonts[i]; + if (HARDCODED_FONT_NAMES.contains(f.getName())) { + continue; //skip + } + + if (log.isTraceEnabled()) { + log.trace("AWT Font: " + f.getFontName() + + ", family: " + f.getFamily() + + ", PS: " + f.getPSName() + + ", Name: " + f.getName() + + ", Angle: " + f.getItalicAngle() + + ", Style: " + f.getStyle()); + } + + String searchName = FontUtil.stripWhiteSpace(f.getName()).toLowerCase(); + String guessedStyle = FontUtil.guessStyle(searchName); + int guessedWeight = FontUtil.guessWeight(searchName); + + num++; + String fontKey = "F" + num; + int style = convertToAWTFontStyle(guessedStyle, guessedWeight); + addFontMetricsMapper(fontInfo, f.getName(), fontKey, graphics2D, style); + + //Register appropriate font triplets matching the font. Two different strategies: + //Example: "Arial Bold", normal, normal + addFontTriplet(fontInfo, f.getName(), + Font.STYLE_NORMAL, Font.WEIGHT_NORMAL, fontKey); + if (!f.getName().equals(f.getFamily())) { + //Example: "Arial", bold, normal + addFontTriplet(fontInfo, f.getFamily(), + guessedStyle, guessedWeight, fontKey); + } + } + return num; + } + + private static void addFontTriplet(FontInfo fontInfo, String fontName, String fontStyle, + int fontWeight, String fontKey) { + FontTriplet triplet = FontInfo.createFontKey(fontName, fontStyle, fontWeight); + fontInfo.addFontProperties(fontKey, triplet); + } + + private static void addFontMetricsMapper(FontInfo fontInfo, String family, String fontKey, + Graphics2D graphics, int style) { + FontMetricsMapper metric = new SystemFontMetricsMapper(family, style, graphics); + fontInfo.addMetrics(fontKey, metric); + } + + private static int convertToAWTFontStyle(String fontStyle, int fontWeight) { + int style = java.awt.Font.PLAIN; + if (fontWeight >= Font.WEIGHT_BOLD) { + style |= java.awt.Font.BOLD; + } + if (!"normal".equals(fontStyle)) { + style |= java.awt.Font.ITALIC; + } + return style; + } +} diff --git a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java index db8ed6250..eea165525 100644 --- a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java +++ b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java @@ -168,14 +168,15 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem public void setupFontInfo(FontInfo inFontInfo) { //Don't call super.setupFontInfo() here! Java2D needs a special font setup // create a temp Image to test font metrics on - fontInfo = inFontInfo; + this.fontInfo = inFontInfo; BufferedImage fontImage = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); - Graphics2D g = fontImage.createGraphics(); + Graphics2D graphics2D = fontImage.createGraphics(); //The next line is important to get accurate font metrics! - g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, + graphics2D.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); - FontSetup.setup(fontInfo, fontList, fontResolver, g); + + userAgent.getFactory().getFontManager().setupRenderer(this, graphics2D); } /** {@inheritDoc} */ diff --git a/src/java/org/apache/fop/render/pcl/PCLRenderer.java b/src/java/org/apache/fop/render/pcl/PCLRenderer.java index 921856b07..5ffef15ba 100644 --- a/src/java/org/apache/fop/render/pcl/PCLRenderer.java +++ b/src/java/org/apache/fop/render/pcl/PCLRenderer.java @@ -89,7 +89,6 @@ import org.apache.fop.render.RendererContext; import org.apache.fop.render.RendererContextConstants; import org.apache.fop.render.RendererEventProducer; import org.apache.fop.render.java2d.FontMetricsMapper; -import org.apache.fop.render.java2d.FontSetup; import org.apache.fop.render.java2d.Java2DRenderer; import org.apache.fop.render.pcl.extensions.PCLElementMapping; import org.apache.fop.traits.BorderProps; @@ -202,11 +201,12 @@ public class PCLRenderer extends PrintRenderer { fontInfo = inFontInfo; BufferedImage fontImage = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); - Graphics2D g = fontImage.createGraphics(); + Graphics2D graphics2D = fontImage.createGraphics(); //The next line is important to get accurate font metrics! - g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, + graphics2D.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); - FontSetup.setup(fontInfo, fontList, fontResolver, g); + + userAgent.getFactory().getFontManager().setupRenderer(this, graphics2D); } /** diff --git a/src/java/org/apache/fop/render/ps/AbstractPSTranscoder.java b/src/java/org/apache/fop/render/ps/AbstractPSTranscoder.java index 75ed0de52..ea4cc50bb 100644 --- a/src/java/org/apache/fop/render/ps/AbstractPSTranscoder.java +++ b/src/java/org/apache/fop/render/ps/AbstractPSTranscoder.java @@ -98,7 +98,7 @@ public abstract class AbstractPSTranscoder extends AbstractFOPTranscoder { if (!isTextStroked()) { FontInfo fontInfo = new FontInfo(); //TODO Do custom font configuration here somewhere/somehow - FontSetup.setup(fontInfo, null, null); + FontSetup.setup(fontInfo); graphics.setCustomTextHandler(new NativeTextHandler(graphics, fontInfo)); } diff --git a/src/java/org/apache/fop/render/ps/NativeTextHandler.java b/src/java/org/apache/fop/render/ps/NativeTextHandler.java index 5b840484d..174fe8077 100644 --- a/src/java/org/apache/fop/render/ps/NativeTextHandler.java +++ b/src/java/org/apache/fop/render/ps/NativeTextHandler.java @@ -71,7 +71,7 @@ public class NativeTextHandler implements PSTextHandler { private void setupFontInfo() { //Sets up a FontInfo with default fonts fontInfo = new FontInfo(); - FontSetup.setup(fontInfo, null, null); + FontSetup.setup(fontInfo); } /** diff --git a/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java b/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java index 420e46cb8..513ba4587 100644 --- a/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java +++ b/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java @@ -156,7 +156,7 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D { if (fontInfo == null) { //Default minimal fonts FontInfo fontInfo = new FontInfo(); - FontSetup.setup(fontInfo, null, null); + FontSetup.setup(fontInfo); setFontInfo(fontInfo); } } diff --git a/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java b/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java index f57e8cc58..02e9d6da4 100644 --- a/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java +++ b/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java @@ -26,6 +26,7 @@ import org.apache.avalon.framework.configuration.ConfigurationException; import org.apache.fop.apps.FOPException; import org.apache.fop.fonts.FontCache; import org.apache.fop.fonts.FontInfo; +import org.apache.fop.fonts.FontManager; import org.apache.fop.fonts.FontResolver; import org.apache.fop.fonts.FontSetup; import org.apache.fop.pdf.PDFDocument; @@ -53,17 +54,20 @@ public class PDFDocumentGraphics2DConfigurator { //Fonts try { - FontResolver fontResolver = FontSetup.createMinimalFontResolver(); + FontResolver fontResolver = FontManager.createMinimalFontResolver(); //TODO The following could be optimized by retaining the FontCache somewhere FontCache fontCache = FontCache.load(); if (fontCache == null) { fontCache = new FontCache(); } - List fontList = PrintRendererConfigurator.buildFontListFromConfiguration( - cfg, null, fontResolver, false, fontCache); + //TODO Provide fontBaseURL to this method call + final String fontBaseURL = null; + List/*<EmbedFontInfo>*/ embedFontInfoList + = PrintRendererConfigurator.buildFontListFromConfiguration( + cfg, fontBaseURL, fontResolver, false, fontCache); fontCache.save(); FontInfo fontInfo = new FontInfo(); - FontSetup.setup(fontInfo, fontList, fontResolver); + FontSetup.setup(fontInfo, embedFontInfoList, fontResolver); graphics.setFontInfo(fontInfo); } catch (FOPException e) { throw new ConfigurationException("Error while setting up fonts", e); diff --git a/src/java/org/apache/fop/svg/PDFGraphics2D.java b/src/java/org/apache/fop/svg/PDFGraphics2D.java index 05c30ef50..5a147f3be 100644 --- a/src/java/org/apache/fop/svg/PDFGraphics2D.java +++ b/src/java/org/apache/fop/svg/PDFGraphics2D.java @@ -959,7 +959,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { preparePainting(); FontInfo specialFontInfo = new FontInfo(); - FontSetup.setup(specialFontInfo, null, null); + FontSetup.setup(specialFontInfo); PDFResources res = pdfDoc.getFactory().makeResources(); PDFResourceContext context = new PDFResourceContext(res); |