* Added java 1.5 generics comments to many methods. * Performed some preparatory cleanup and refactoring which includes (but is not limited to..) - Creating a FontManager delegating class that is called upon when renderers are setting up fonts - A new FontCollection interface and concrete implementing classes to supercede the static FontSetup mechanism. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@653826 13f79535-47bb-0310-9956-ffa450edef68tags/fop-1_0
support fonts. These fonts will then automatically be registered. | support fonts. These fonts will then automatically be registered. | ||||
</p> | </p> | ||||
<source><![CDATA[ | <source><![CDATA[ | ||||
<fonts> | |||||
<!-- register all the fonts found in a directory --> | |||||
<directory>C:\MyFonts1</directory> | |||||
<renderers> | |||||
<renderer mime="application/pdf"> | |||||
<fonts> | |||||
<!-- register all the fonts found in a directory --> | |||||
<directory>C:\MyFonts1</directory> | |||||
<!-- register all the fonts found in a directory | |||||
and all of its sub directories (use with care) --> | |||||
<directory recursive="true">C:\MyFonts2</directory> | |||||
<!-- register all the fonts found in a directory and all of its sub directories (use with care) --> | |||||
<directory recursive="true">C:\MyFonts2</directory> | |||||
<!-- automatically detect operating system installed fonts --> | |||||
<auto-detect/> | |||||
</fonts>]]></source> | |||||
<!-- automatically detect operating system installed fonts --> | |||||
<auto-detect/> | |||||
</fonts> | |||||
</renderer> | |||||
</renderers>]]></source> | |||||
<note> | <note> | ||||
Review the documentation for <a href="configuration.html">FOP Configuration</a> | Review the documentation for <a href="configuration.html">FOP Configuration</a> | ||||
for instructions on making the FOP configuration available to FOP when it runs. | for instructions on making the FOP configuration available to FOP when it runs. | ||||
<title>Register Fonts with FOP</title> | <title>Register Fonts with FOP</title> | ||||
<p>You must tell FOP how to find and use the font metrics files by registering them in the <a href="configuration.html">FOP Configuration</a>. Add entries for your custom fonts, regardless of font type, to the configuration file in a manner similar to the following:</p> | <p>You must tell FOP how to find and use the font metrics files by registering them in the <a href="configuration.html">FOP Configuration</a>. Add entries for your custom fonts, regardless of font type, to the configuration file in a manner similar to the following:</p> | ||||
<source><![CDATA[ | <source><![CDATA[ | ||||
<fonts> | |||||
<!-- register a particular font --> | |||||
<font metrics-url="file:///C:/myfonts/FTL_____.xml" kerning="yes" | |||||
embed-url="file:///C:/myfonts/FTL_____.pfb"> | |||||
<font-triplet name="FrutigerLight" style="normal" weight="normal"/> | |||||
</font> | |||||
<renderers> | |||||
<renderer mime="application/pdf"> | |||||
<fonts> | |||||
<!-- register a particular font --> | |||||
<font metrics-url="file:///C:/myfonts/FTL_____.xml" kerning="yes" embed-url="file:///C:/myfonts/FTL_____.pfb"> | |||||
<font-triplet name="FrutigerLight" style="normal" weight="normal"/> | |||||
</font> | |||||
<!-- register all the fonts found in a directory --> | |||||
<directory>C:\MyFonts1</directory> | |||||
<!-- register all the fonts found in a directory --> | |||||
<directory>C:\MyFonts1</directory> | |||||
<!-- register all the fonts found in a directory | |||||
and all of its sub directories (use with care) --> | |||||
<directory recursive="true">C:\MyFonts2</directory> | |||||
<!-- register all the fonts found in a directory and all of its sub directories (use with care) --> | |||||
<directory recursive="true">C:\MyFonts2</directory> | |||||
<!-- automatically detect operating system installed fonts --> | |||||
<auto-detect/> | |||||
</fonts>]]></source> | |||||
<!-- automatically detect operating system installed fonts --> | |||||
<auto-detect/> | |||||
</fonts> | |||||
</renderer> | |||||
</renderers>]]></source> | |||||
<ul> | <ul> | ||||
<li> | <li> | ||||
URLs are used to access the font metric and font files. | URLs are used to access the font metric and font files. | ||||
<!--note>Cocoon users will need to setup the config, see FOPSerializer for more information.</note--> | <!--note>Cocoon users will need to setup the config, see FOPSerializer for more information.</note--> | ||||
</section> | </section> | ||||
<section id="autodetect"> | <section id="autodetect"> | ||||
<title>Auto-Detect and auto-embedd feature</title> | |||||
<title>Auto-Detect and auto-embed feature</title> | |||||
<p>When the "auto-detect" flag is set in the configuration, FOP will automatically search for fonts in the default paths for your operating system.</p> | <p>When the "auto-detect" flag is set in the configuration, FOP will automatically search for fonts in the default paths for your operating system.</p> | ||||
<p>FOP will also auto-detect fonts which are available in the classpath, if they are described as "application/x-font" in the MANIFEST.MF file. For example, if your .jar file contains font/myfont.ttf:</p> | <p>FOP will also auto-detect fonts which are available in the classpath, if they are described as "application/x-font" in the MANIFEST.MF file. For example, if your .jar file contains font/myfont.ttf:</p> | ||||
<source>Manifest-Version: 1.0 | <source>Manifest-Version: 1.0 | ||||
<p>When embedding TrueType fonts (ttf) or TrueType Collections (ttc), a subset of the | <p>When embedding TrueType fonts (ttf) or TrueType Collections (ttc), a subset of the | ||||
original font, containing only the glyphs used, is embedded in the output document.</p> | original font, containing only the glyphs used, is embedded in the output document.</p> | ||||
</section> | </section> | ||||
<section id="substitution"> | |||||
<title>Substitution</title> | |||||
<p>When a <substitutions/> section is defined in the configuration, FOP will re-map any font-family references found in your FO input to a given substitution font.</p> | |||||
<ul> | |||||
<li>If a <substitution/> is declared, it is mandatory that both a <from/> and <to/> child element is declared with a font-family attribute.</li> | |||||
<li>Both font-weight and font-style are optional attributes, if they are provided then a value of 'normal' is assumed.</li> | |||||
</ul> | |||||
<p>For example you could make all FO font-family references to 'Arial' with weights between 700 and 900 reference the normal 'Arial Black' font.</p> | |||||
<source><![CDATA[ | |||||
<fop version="1.0"> | |||||
<fonts> | |||||
<substitutions> | |||||
<substitution> | |||||
<from font-family="Arial" font-weight="700..900"/> | |||||
<to font-family="Arial Black"/> | |||||
</substitution> | |||||
<substitution> | |||||
<from font-family="FrutigerLight"/> | |||||
<to font-family="Times" font-weight="bold" font-style="italic"/> | |||||
</substitution> | |||||
</substitutions> | |||||
</fonts> | |||||
</fop>]]></source> | |||||
</section> | |||||
<!-- The following section should no longer be required | <!-- The following section should no longer be required | ||||
<section id="embedding-base14"> | <section id="embedding-base14"> | ||||
<title>Explicitly embedding the base 14 fonts</title> | <title>Explicitly embedding the base 14 fonts</title> |
/** true if exceptions are to be thrown if the URIs cannot be resolved. */ | /** true if exceptions are to be thrown if the URIs cannot be resolved. */ | ||||
private boolean throwExceptions = false; | 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 | * Default constructor | ||||
*/ | */ |
} | } | ||||
this.factory = factory; | this.factory = factory; | ||||
setBaseURL(factory.getBaseURL()); | setBaseURL(factory.getBaseURL()); | ||||
setFontBaseURL(factory.getFontBaseURL()); | |||||
setFontBaseURL(factory.getFontManager().getFontBaseURL()); | |||||
setTargetResolution(factory.getTargetResolution()); | setTargetResolution(factory.getTargetResolution()); | ||||
} | } | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.io.OutputStream; | import java.io.OutputStream; | ||||
import java.net.MalformedURLException; | import java.net.MalformedURLException; | ||||
import java.net.URL; | |||||
import java.util.Collection; | import java.util.Collection; | ||||
import java.util.Collections; | import java.util.Collections; | ||||
import java.util.Set; | import java.util.Set; | ||||
import org.apache.fop.fo.ElementMapping; | import org.apache.fop.fo.ElementMapping; | ||||
import org.apache.fop.fo.ElementMappingRegistry; | import org.apache.fop.fo.ElementMappingRegistry; | ||||
import org.apache.fop.fonts.FontCache; | import org.apache.fop.fonts.FontCache; | ||||
import org.apache.fop.fonts.FontManager; | |||||
import org.apache.fop.hyphenation.HyphenationTreeResolver; | import org.apache.fop.hyphenation.HyphenationTreeResolver; | ||||
import org.apache.fop.layoutmgr.LayoutManagerMaker; | import org.apache.fop.layoutmgr.LayoutManagerMaker; | ||||
import org.apache.fop.render.RendererFactory; | import org.apache.fop.render.RendererFactory; | ||||
/** Image manager for loading and caching image objects */ | /** Image manager for loading and caching image objects */ | ||||
private ImageManager imageManager; | private ImageManager imageManager; | ||||
/** Font manager for font substitution, autodetection and caching **/ | |||||
private FontManager fontManager; | |||||
/** Configuration layer used to configure fop */ | /** Configuration layer used to configure fop */ | ||||
private FopFactoryConfigurator config = null; | private FopFactoryConfigurator config = null; | ||||
*/ | */ | ||||
private String base = null; | private String base = null; | ||||
/** The base URL for all font URL resolutions. */ | |||||
private String fontBase = null; | |||||
/** The base URL for all hyphen URL resolutions. */ | /** The base URL for all hyphen URL resolutions. */ | ||||
private String hyphenBase = null; | private String hyphenBase = null; | ||||
*/ | */ | ||||
private boolean strictUserConfigValidation | private boolean strictUserConfigValidation | ||||
= FopFactoryConfigurator.DEFAULT_STRICT_USERCONFIG_VALIDATION; | = 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 */ | /** Source resolution in dpi */ | ||||
private float sourceResolution = FopFactoryConfigurator.DEFAULT_SOURCE_RESOLUTION; | private float sourceResolution = FopFactoryConfigurator.DEFAULT_SOURCE_RESOLUTION; | ||||
this.rendererFactory = new RendererFactory(); | this.rendererFactory = new RendererFactory(); | ||||
this.xmlHandlers = new XMLHandlerRegistry(); | this.xmlHandlers = new XMLHandlerRegistry(); | ||||
this.ignoredNamespaces = new java.util.HashSet(); | this.ignoredNamespaces = new java.util.HashSet(); | ||||
setUseCache(FopFactoryConfigurator.DEFAULT_USE_CACHE); | |||||
} | } | ||||
/** | /** | ||||
public LayoutManagerMaker getLayoutManagerMakerOverride() { | public LayoutManagerMaker getLayoutManagerMakerOverride() { | ||||
return this.lmMakerOverride; | 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. | * Sets the base URL. | ||||
* @param base base URL | |||||
* @param base the base URL | |||||
* @throws MalformedURLException if there's a problem with a file URL | * @throws MalformedURLException if there's a problem with a file URL | ||||
*/ | */ | ||||
public void setBaseURL(String base) throws MalformedURLException { | public void setBaseURL(String base) throws MalformedURLException { | ||||
this.base = checkBaseURL(base); | |||||
this.base = foURIResolver.checkBaseURL(base); | |||||
} | } | ||||
/** | /** | ||||
* Sets the font base URL. | * Sets the font base URL. | ||||
* @param fontBase font base URL | * @param fontBase font base URL | ||||
* @throws MalformedURLException if there's a problem with a file 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 { | 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() { | public String getFontBaseURL() { | ||||
return this.fontBase; | |||||
return getFontManager().getFontBaseURL(); | |||||
} | } | ||||
/** @return the hyphen base URL */ | /** @return the hyphen base URL */ | ||||
} | } | ||||
}); | }); | ||||
} | } | ||||
this.hyphenBase = checkBaseURL(hyphenBase); | |||||
this.hyphenBase = foURIResolver.checkBaseURL(hyphenBase); | |||||
} | } | ||||
/** | /** | ||||
return foURIResolver; | 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. */ | /** @return the HyphenationTreeResolver for resolving user-supplied hyphenation patterns. */ | ||||
public HyphenationTreeResolver getHyphenationTreeResolver() { | public HyphenationTreeResolver getHyphenationTreeResolver() { | ||||
return this.hyphResolver; | return this.hyphResolver; | ||||
this.breakIndentInheritanceOnReferenceAreaBoundary = value; | 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() { | public boolean isBase14KerningEnabled() { | ||||
return this.enableBase14Kerning; | |||||
return getFontManager().isBase14KerningEnabled(); | |||||
} | } | ||||
/** | /** | ||||
* Controls whether kerning is activated on base 14 fonts. | * Controls whether kerning is activated on base 14 fonts. | ||||
* @param value true if kerning should be activated | * @param value true if kerning should be activated | ||||
* @deprecated use getFontManager().setBase14KerningEnabled(boolean) instead | |||||
*/ | */ | ||||
public void setBase14KerningEnabled(boolean value) { | public void setBase14KerningEnabled(boolean value) { | ||||
this.enableBase14Kerning = value; | |||||
getFontManager().setBase14KerningEnabled(value); | |||||
} | } | ||||
/** @return the resolution for resolution-dependant input */ | /** @return the resolution for resolution-dependant input */ | ||||
return this.strictUserConfigValidation; | return this.strictUserConfigValidation; | ||||
} | } | ||||
//------------------------------------------- Cache related stuff | |||||
//------------------------------------------- Font related stuff | |||||
/** | /** | ||||
* Whether or not to cache results of font triplet detection/auto-config | * Whether or not to cache results of font triplet detection/auto-config | ||||
* @param useCache use cache or not | * @param useCache use cache or not | ||||
* @deprecated use getFontManager().setUseCache(boolean) instead | |||||
*/ | */ | ||||
public void setUseCache(boolean useCache) { | 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? | * Cache results of font triplet detection/auto-config? | ||||
* @return whether this factory is uses the cache | * @return whether this factory is uses the cache | ||||
* @deprecated use getFontManager().useCache() instead | |||||
*/ | */ | ||||
public boolean useCache() { | public boolean useCache() { | ||||
return (this.fontCache != null); | |||||
return getFontManager().useCache(); | |||||
} | } | ||||
/** | /** | ||||
* Returns the font cache instance used by this factory. | * Returns the font cache instance used by this factory. | ||||
* @return the font cache | * @return the font cache | ||||
* @deprecated use getFontManager().getFontCache() instead | |||||
*/ | */ | ||||
public FontCache getFontCache() { | 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; | |||||
} | } | ||||
/** | /** |
import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; | import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; | ||||
import org.apache.commons.logging.Log; | import org.apache.commons.logging.Log; | ||||
import org.apache.commons.logging.LogFactory; | 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.apache.fop.util.LogUtil; | ||||
import org.xml.sax.SAXException; | import org.xml.sax.SAXException; | ||||
/** Defines the default target resolution (72dpi) for FOP */ | /** Defines the default target resolution (72dpi) for FOP */ | ||||
public static final float DEFAULT_TARGET_RESOLUTION = 72.0f; //dpi | 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 */ | /** logger instance */ | ||||
private final Log log = LogFactory.getLog(FopFactoryConfigurator.class); | private final Log log = LogFactory.getLog(FopFactoryConfigurator.class); | ||||
LogUtil.handleException(log, mfue, strict); | 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) { | if (cfg.getChild("hyphenation-base", false) != null) { | ||||
try { | try { | ||||
factory.setHyphenBaseURL( | factory.setHyphenBaseURL( | ||||
} | } | ||||
} | } | ||||
// 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); | |||||
} | } | ||||
/** | /** |
/* | |||||
* 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; | |||||
} | |||||
} |
protected String embedFile; | protected String embedFile; | ||||
/** false, to disable kerning */ | /** false, to disable kerning */ | ||||
protected boolean kerning; | protected boolean kerning; | ||||
/** the list of associated font triplets */ | |||||
protected List fontTriplets; | |||||
/** the PostScript name of the font */ | /** the PostScript name of the font */ | ||||
protected String postScriptName = null; | protected String postScriptName = null; | ||||
/** the sub-fontname of the font (used for TrueType Collections, null otherwise) */ | /** the sub-fontname of the font (used for TrueType Collections, null otherwise) */ | ||||
protected String subFontName = null; | protected String subFontName = null; | ||||
/** the list of associated font triplets */ | |||||
private List/*<FontTriplet>*/ fontTriplets = null; | |||||
/** | /** | ||||
* Main constructor | * Main constructor | ||||
* @param metricsFile Path to the xml file containing font metrics | * @param metricsFile Path to the xml file containing font metrics | ||||
* @param subFontName the sub-fontname used for TrueType Collections (null otherwise) | * @param subFontName the sub-fontname used for TrueType Collections (null otherwise) | ||||
*/ | */ | ||||
public EmbedFontInfo(String metricsFile, boolean kerning, | public EmbedFontInfo(String metricsFile, boolean kerning, | ||||
List fontTriplets, String embedFile, String subFontName) { | |||||
List/*<FontTriplet>*/ fontTriplets, String embedFile, String subFontName) { | |||||
this.metricsFile = metricsFile; | this.metricsFile = metricsFile; | ||||
this.embedFile = embedFile; | this.embedFile = embedFile; | ||||
this.kerning = kerning; | this.kerning = kerning; | ||||
public boolean getKerning() { | public boolean getKerning() { | ||||
return kerning; | 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. | * 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() { | public String getSubFontName() { | ||||
return this.subFontName; | return this.subFontName; | ||||
this.postScriptName = postScriptName; | 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() { | public String toString() { | ||||
return "metrics-url=" + metricsFile + ",embed-url=" + embedFile | return "metrics-url=" + metricsFile + ",embed-url=" + embedFile | ||||
+ ", kerning=" + kerning + ", font-triplet=" + fontTriplets | |||||
+ ", kerning=" + kerning + ", " + "font-triplet=" + fontTriplets | |||||
+ (getSubFontName() != null ? ", sub-font=" + getSubFontName() : ""); | + (getSubFontName() != null ? ", sub-font=" + getSubFontName() : ""); | ||||
} | } | ||||
} | } |
/** Italic font style */ | /** Italic font style */ | ||||
public static final String STYLE_ITALIC = "italic"; | 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 */ | /** Default fallback key */ | ||||
public static final FontTriplet DEFAULT_FONT = new FontTriplet( | public static final FontTriplet DEFAULT_FONT = new FontTriplet( | ||||
"any", STYLE_NORMAL, WEIGHT_NORMAL); | |||||
"any", STYLE_NORMAL, WEIGHT_NORMAL, PRIORITY_DEFAULT); | |||||
/** logger */ | /** logger */ | ||||
private static Log log = LogFactory.getLog(Font.class); | private static Log log = LogFactory.getLog(Font.class); |
/** font cache file path */ | /** font cache file path */ | ||||
private static final String DEFAULT_CACHE_FILENAME = "fop-fonts.cache"; | private static final String DEFAULT_CACHE_FILENAME = "fop-fonts.cache"; | ||||
/** has this cache been changed since it was last read? */ | /** has this cache been changed since it was last read? */ | ||||
private transient boolean changed = false; | private transient boolean changed = false; | ||||
/** master mapping of font url -> font info. This needs to be | /** master mapping of font url -> font info. This needs to be | ||||
* a list, since a TTC file may contain more than 1 font. */ | * 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) */ | /** 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 | * Default constructor | ||||
*/ | */ | ||||
public boolean containsFont(String embedUrl) { | public boolean containsFont(String embedUrl) { | ||||
if (embedUrl != null) { | if (embedUrl != null) { | ||||
return fontfileMap.containsKey(embedUrl); | |||||
return getFontFileMap().containsKey(embedUrl); | |||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
*/ | */ | ||||
public boolean containsFont(EmbedFontInfo fontInfo) { | public boolean containsFont(EmbedFontInfo fontInfo) { | ||||
if (fontInfo != null) { | if (fontInfo != null) { | ||||
return fontfileMap.containsKey(getCacheKey(fontInfo)); | |||||
return getFontFileMap().containsKey(getCacheKey(fontInfo)); | |||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
return null; | 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 | * Adds a font info to cache | ||||
* @param fontInfo font info | * @param fontInfo font info | ||||
synchronized (changeLock) { | synchronized (changeLock) { | ||||
CachedFontFile cachedFontFile; | CachedFontFile cachedFontFile; | ||||
if (containsFont(cacheKey)) { | if (containsFont(cacheKey)) { | ||||
cachedFontFile = (CachedFontFile)fontfileMap.get(cacheKey); | |||||
cachedFontFile = (CachedFontFile)getFontFileMap().get(cacheKey); | |||||
if (!cachedFontFile.containsFont(fontInfo)) { | if (!cachedFontFile.containsFont(fontInfo)) { | ||||
cachedFontFile.put(fontInfo); | cachedFontFile.put(fontInfo); | ||||
} | } | ||||
log.trace("Font added to cache: " + cacheKey); | log.trace("Font added to cache: " + cacheKey); | ||||
} | } | ||||
cachedFontFile.put(fontInfo); | cachedFontFile.put(fontInfo); | ||||
fontfileMap.put(cacheKey, cachedFontFile); | |||||
getFontFileMap().put(cacheKey, cachedFontFile); | |||||
changed = true; | changed = true; | ||||
} | } | ||||
} | } | ||||
*/ | */ | ||||
public CachedFontFile getFontFile(String embedUrl) { | public CachedFontFile getFontFile(String embedUrl) { | ||||
if (containsFont(embedUrl)) { | if (containsFont(embedUrl)) { | ||||
return (CachedFontFile)fontfileMap.get(embedUrl); | |||||
return (CachedFontFile)getFontFileMap().get(embedUrl); | |||||
} | } | ||||
return null; | return null; | ||||
} | } | ||||
if (log.isTraceEnabled()) { | if (log.isTraceEnabled()) { | ||||
log.trace("Font removed from cache: " + embedUrl); | log.trace("Font removed from cache: " + embedUrl); | ||||
} | } | ||||
fontfileMap.remove(embedUrl); | |||||
getFontFileMap().remove(embedUrl); | |||||
changed = true; | changed = true; | ||||
} | } | ||||
} | } | ||||
* @return whether this is a failed font | * @return whether this is a failed font | ||||
*/ | */ | ||||
public boolean isFailedFont(String embedUrl, long lastModified) { | public boolean isFailedFont(String embedUrl, long lastModified) { | ||||
if (failedFontMap.containsKey(embedUrl)) { | |||||
if (getFailedFontMap().containsKey(embedUrl)) { | |||||
synchronized (changeLock) { | synchronized (changeLock) { | ||||
long failedLastModified = ((Long)failedFontMap.get(embedUrl)).longValue(); | |||||
long failedLastModified = ((Long)getFailedFontMap().get(embedUrl)).longValue(); | |||||
if (lastModified != failedLastModified) { | if (lastModified != failedLastModified) { | ||||
// this font has been changed so lets remove it | // this font has been changed so lets remove it | ||||
// from failed font map for now | // from failed font map for now | ||||
failedFontMap.remove(embedUrl); | |||||
getFailedFontMap().remove(embedUrl); | |||||
changed = true; | changed = true; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* registers a failed font with the cache | |||||
* Registers a failed font with the cache | |||||
* @param embedUrl embed url | * @param embedUrl embed url | ||||
* @param lastModified time last modified | * @param lastModified time last modified | ||||
*/ | */ | ||||
public void registerFailedFont(String embedUrl, long lastModified) { | public void registerFailedFont(String embedUrl, long lastModified) { | ||||
synchronized (changeLock) { | synchronized (changeLock) { | ||||
if (!failedFontMap.containsKey(embedUrl)) { | |||||
failedFontMap.put(embedUrl, new Long(lastModified)); | |||||
if (!getFailedFontMap().containsKey(embedUrl)) { | |||||
getFailedFontMap().put(embedUrl, new Long(lastModified)); | |||||
changed = true; | changed = true; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
private Map/*<String, Long>*/ getFailedFontMap() { | |||||
if (failedFontMap == null) { | |||||
failedFontMap = new java.util.HashMap/*<String, Long>*/(); | |||||
} | |||||
return failedFontMap; | |||||
} | |||||
/** | /** | ||||
* Clears font cache | * Clears font cache | ||||
*/ | */ | ||||
if (log.isTraceEnabled()) { | if (log.isTraceEnabled()) { | ||||
log.trace("Font cache cleared."); | log.trace("Font cache cleared."); | ||||
} | } | ||||
fontfileMap.clear(); | |||||
failedFontMap.clear(); | |||||
fontfileMap = null; | |||||
failedFontMap = null; | |||||
changed = true; | changed = true; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
private static class CachedFontFile implements Serializable { | private static class CachedFontFile implements Serializable { | ||||
private static final long serialVersionUID = 4524237324330578883L; | |||||
/** file modify date (if available) */ | /** file modify date (if available) */ | ||||
private long lastModified = -1; | private long lastModified = -1; | ||||
private Map filefontsMap = new java.util.HashMap(); //Map<String, EmbedFontInfo> | |||||
private Map/*<String, EmbedFontInfo>*/ filefontsMap = null; | |||||
public CachedFontFile(long lastModified) { | public CachedFontFile(long lastModified) { | ||||
setLastModified(lastModified); | setLastModified(lastModified); | ||||
} | } | ||||
private Map/*<String, EmbedFontInfo>*/ getFileFontsMap() { | |||||
if (filefontsMap == null) { | |||||
filefontsMap = new java.util.HashMap/*<String, EmbedFontInfo>*/(); | |||||
} | |||||
return filefontsMap; | |||||
} | |||||
void put(EmbedFontInfo efi) { | void put(EmbedFontInfo efi) { | ||||
filefontsMap.put(efi.getPostScriptName(), efi); | |||||
getFileFontsMap().put(efi.getPostScriptName(), efi); | |||||
} | } | ||||
public boolean containsFont(EmbedFontInfo efi) { | public boolean containsFont(EmbedFontInfo efi) { | ||||
if (efi.getPostScriptName() != null) { | if (efi.getPostScriptName() != null) { | ||||
return filefontsMap.containsKey(efi.getPostScriptName()); | |||||
return getFileFontsMap().containsKey(efi.getPostScriptName()); | |||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
public Map getFilefontsMap() { | |||||
return filefontsMap; | |||||
} | |||||
public EmbedFontInfo[] getEmbedFontInfos() { | public EmbedFontInfo[] getEmbedFontInfos() { | ||||
return (EmbedFontInfo[])this.filefontsMap.values().toArray( | |||||
new EmbedFontInfo[this.filefontsMap.size()]); | |||||
return (EmbedFontInfo[])getFileFontsMap().values().toArray( | |||||
new EmbedFontInfo[getFileFontsMap().size()]); | |||||
} | } | ||||
/** | /** |
/* | |||||
* 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); | |||||
} |
/** | /** | ||||
* Returns the capital height of the font. | * Returns the capital height of the font. | ||||
* @return the capiptal height | |||||
* @return the capital height | |||||
*/ | */ | ||||
int getCapHeight(); | int getCapHeight(); | ||||
package org.apache.fop.fonts; | package org.apache.fop.fonts; | ||||
import java.util.ArrayList; | |||||
import java.util.Collection; | import java.util.Collection; | ||||
import java.util.Collections; | import java.util.Collections; | ||||
import java.util.Iterator; | import java.util.Iterator; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.Set; | |||||
import org.apache.commons.logging.Log; | import org.apache.commons.logging.Log; | ||||
import org.apache.commons.logging.LogFactory; | 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 | * This stores the list of available fonts that are setup by | ||||
* the renderer. The font name can be retrieved for the | * the renderer. The font name can be retrieved for the | ||||
* family style and weight. | * family style and weight. | ||||
protected static Log log = LogFactory.getLog(FontInfo.class); | protected static Log log = LogFactory.getLog(FontInfo.class); | ||||
/** Map containing fonts that have been used */ | /** 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 */ | /** 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 | /** look up a font-triplet to find its priority | ||||
* (only used inside addFontProperties()) */ | * (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) */ | /** 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) | * 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. */ | /** 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 | * Main constructor | ||||
*/ | */ | ||||
public FontInfo() { | 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 | * Sets the font event listener that can be used to receive events about particular events | ||||
* in this class. | * in this class. | ||||
/** | /** | ||||
* Adds a new font triplet. | * 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 | * @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 | * add the given family, style and weight as a lookup for the font | ||||
* with the given name | * with the given name | ||||
*/ | */ | ||||
if (log.isDebugEnabled()) { | if (log.isDebugEnabled()) { | ||||
log.debug("Registering: " + triplet + " under " + name); | |||||
log.debug("Registering: " + triplet + " under " + internalFontKey); | |||||
} | } | ||||
String oldName = (String)triplets.get(triplet); | String oldName = (String)triplets.get(triplet); | ||||
int newPriority = triplet.getPriority(); | int newPriority = triplet.getPriority(); | ||||
int oldPriority = ((Integer)tripletPriorities.get(triplet)).intValue(); | int oldPriority = ((Integer)tripletPriorities.get(triplet)).intValue(); | ||||
if (oldPriority < newPriority) { | if (oldPriority < newPriority) { | ||||
logDuplicateFont(triplet, false, oldName, oldPriority, | logDuplicateFont(triplet, false, oldName, oldPriority, | ||||
name, newPriority); | |||||
internalFontKey, newPriority); | |||||
return; | return; | ||||
} else { | } else { | ||||
logDuplicateFont(triplet, true, oldName, oldPriority, | 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)); | 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 triplet the duplicate font triplet | ||||
* @param replacing true iff the new font will replace the old one | * @param replacing true iff the new font will replace the old one | ||||
* @param oldKey the old internal font name | * @param oldKey the old internal font name | ||||
log.debug(triplet | log.debug(triplet | ||||
+ (replacing ? ": Replacing " : ": Not replacing ") | + (replacing ? ": Replacing " : ": Not replacing ") | ||||
+ ((FontMetrics)fonts.get(triplets.get(triplet))).getFullName() | + ((FontMetrics)fonts.get(triplets.get(triplet))).getFullName() | ||||
+ " (" + oldPriority + ") by " | |||||
+ " (priority=" + oldPriority + ") by " | |||||
+ ((FontMetrics)fonts.get(newKey)).getFullName() | + ((FontMetrics)fonts.get(newKey)).getFullName() | ||||
+ " (" + newPriority + ")"); | |||||
+ " (priority=" + newPriority + ")"); | |||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Adds font metrics for a specific font. | * Adds font metrics for a specific font. | ||||
* @param name internal key | |||||
* @param internalFontKey internal key | |||||
* @param metrics metrics to register | * @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 | // add the given metrics as a font with the given name | ||||
if (metrics instanceof Typeface) { | if (metrics instanceof Typeface) { | ||||
((Typeface)metrics).setEventListener(this.eventListener); | ((Typeface)metrics).setEventListener(this.eventListener); | ||||
} | } | ||||
this.fonts.put(name, metrics); | |||||
this.fonts.put(internalFontKey, metrics); | |||||
} | } | ||||
/** | /** | ||||
* @param weight font weight | * @param weight font weight | ||||
* @param substFont true if the font may be substituted with the | * @param substFont true if the font may be substituted with the | ||||
* default font if not found | * default font if not found | ||||
* @return internal key | |||||
* @return internal font triplet key | |||||
*/ | */ | ||||
private FontTriplet fontLookup(String family, String style, | private FontTriplet fontLookup(String family, String style, | ||||
int weight, boolean substFont) { | int weight, boolean substFont) { | ||||
if (log.isTraceEnabled()) { | if (log.isTraceEnabled()) { | ||||
log.trace("Font lookup: " + family + " " + style + " " + weight); | log.trace("Font lookup: " + family + " " + style + " " + weight); | ||||
} | |||||
} | |||||
FontTriplet startKey = createFontKey(family, style, weight); | FontTriplet startKey = createFontKey(family, style, weight); | ||||
FontTriplet key = startKey; | |||||
FontTriplet fontTriplet = startKey; | |||||
// first try given parameters | // 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 { | } else { | ||||
return null; | return null; | ||||
} | } | ||||
} | } | ||||
private FontTriplet doAdjustedLookup(String family, String style, | |||||
private FontTriplet fuzzyFontLookup(String family, String style, | |||||
int weight, FontTriplet startKey, boolean substFont) { | int weight, FontTriplet startKey, boolean substFont) { | ||||
FontTriplet key; | FontTriplet key; | ||||
String f; | |||||
String internalFontKey; | |||||
if (!family.equals(startKey.getName())) { | if (!family.equals(startKey.getName())) { | ||||
key = createFontKey(family, style, weight); | key = createFontKey(family, style, weight); | ||||
f = getInternalFontKey(key); | |||||
if (f != null) { | |||||
internalFontKey = getInternalFontKey(key); | |||||
if (internalFontKey != null) { | |||||
return key; | return key; | ||||
} | } | ||||
} | } | ||||
// adjust weight, favouring normal or bold | // adjust weight, favouring normal or bold | ||||
key = findAdjustWeight(family, style, weight); | key = findAdjustWeight(family, style, weight); | ||||
f = getInternalFontKey(key); | |||||
internalFontKey = getInternalFontKey(key); | |||||
if (!substFont && f == null) { | |||||
if (!substFont && internalFontKey == null) { | |||||
return null; | return null; | ||||
} | } | ||||
// only if the font may be substituted | // only if the font may be substituted | ||||
// fallback 1: try the same font-family and weight with default style | // 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); | 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 diffWeight = (Font.WEIGHT_NORMAL - weight) / 100; | ||||
int direction = diffWeight > 0 ? 1 : -1; | int direction = diffWeight > 0 ? 1 : -1; | ||||
int tryWeight = weight; | int tryWeight = weight; | ||||
while (tryWeight != Font.WEIGHT_NORMAL) { | while (tryWeight != Font.WEIGHT_NORMAL) { | ||||
tryWeight += 100 * direction; | tryWeight += 100 * direction; | ||||
key = createFontKey(family, style, weight); | key = createFontKey(family, style, weight); | ||||
f = getInternalFontKey(key); | |||||
if (f == null) { | |||||
internalFontKey = getInternalFontKey(key); | |||||
if (internalFontKey == null) { | |||||
key = createFontKey(family, Font.STYLE_NORMAL, weight); | key = createFontKey(family, Font.STYLE_NORMAL, weight); | ||||
f = getInternalFontKey(key); | |||||
internalFontKey = getInternalFontKey(key); | |||||
} | } | ||||
if (f != null) { | |||||
if (internalFontKey != null) { | |||||
break; | break; | ||||
} | } | ||||
} | } | ||||
}*/ | }*/ | ||||
// fallback 3: try any family with orig style/weight | // 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 | // last resort: use default | ||||
if (f == null) { | |||||
if (internalFontKey == null) { | |||||
key = Font.DEFAULT_FONT; | key = Font.DEFAULT_FONT; | ||||
f = getInternalFontKey(key); | |||||
internalFontKey = getInternalFontKey(key); | |||||
} | } | ||||
if (f != null) { | |||||
if (internalFontKey != null) { | |||||
return key; | return key; | ||||
} else { | } else { | ||||
return null; | return null; | ||||
usedFonts.put(internalName, fonts.get(internalName)); | 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. | * Retrieves a (possibly cached) Font instance based on a FontTriplet and a font size. | ||||
* @param triplet the font triplet designating the requested font | * @param triplet the font triplet designating the requested font | ||||
* @return the requested Font instance | * @return the requested Font instance | ||||
*/ | */ | ||||
public Font getFontInstance(FontTriplet triplet, int fontSize) { | 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) { | 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); | Integer size = new Integer(fontSize); | ||||
Font font = (Font)sizes.get(size); | Font font = (Font)sizes.get(size); | ||||
throw new IllegalArgumentException("Specify at least one font family"); | throw new IllegalArgumentException("Specify at least one font family"); | ||||
} | } | ||||
FontTriplet triplet; | FontTriplet triplet; | ||||
List tmpTriplets = new ArrayList(); | |||||
List tmpTriplets = new java.util.ArrayList(); | |||||
for (int i = 0, c = families.length; i < c; i++) { | for (int i = 0, c = families.length; i < c; i++) { | ||||
triplet = fontLookup(families[i], style, weight, (i >= families.length - 1)); | triplet = fontLookup(families[i], style, weight, (i >= families.length - 1)); | ||||
if (triplet != null) { | if (triplet != null) { | ||||
+ "FontTriplet on the last call. Lookup: " + sb.toString()); | + "FontTriplet on the last call. Lookup: " + sb.toString()); | ||||
} | } | ||||
private void notifyFontReplacement(FontTriplet replacedKey, FontTriplet newKey) { | |||||
private Set/*<FontTriplet>*/ getLoggedFontKeys() { | |||||
if (loggedFontKeys == null) { | 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) { | if (this.eventListener != null) { | ||||
this.eventListener.fontSubstituted(this, replacedKey, newKey); | this.eventListener.fontSubstituted(this, replacedKey, newKey); | ||||
} else { | } else { | ||||
* Gets a Map of all registered fonts. | * Gets a Map of all registered fonts. | ||||
* @return a read-only Map with font key/FontMetrics pairs | * @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); | return java.util.Collections.unmodifiableMap(this.fonts); | ||||
} | } | ||||
/** | /** | ||||
* Gets a Map of all registered font triplets. | * 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; | |||||
} | } | ||||
/** | /** | ||||
* This is for embedded font or creating a list of used fonts. | * This is for embedded font or creating a list of used fonts. | ||||
* @return a read-only Map with font key/FontMetrics pairs | * @return a read-only Map with font key/FontMetrics pairs | ||||
*/ | */ | ||||
public Map getUsedFonts() { | |||||
public Map/*<String,FontMetrics>*/ getUsedFonts() { | |||||
return this.usedFonts; | return this.usedFonts; | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* 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 | * @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();) { | for (Iterator iter = triplets.entrySet().iterator(); iter.hasNext();) { | ||||
Map.Entry tripletEntry = (Map.Entry) iter.next(); | Map.Entry tripletEntry = (Map.Entry) iter.next(); | ||||
if (fontName.equals(((String)tripletEntry.getValue()))) { | if (fontName.equals(((String)tripletEntry.getValue()))) { | ||||
foundTriplets.add(tripletEntry.getKey()); | 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) { | if (foundTriplets.size() > 0) { | ||||
Collections.sort(foundTriplets); | Collections.sort(foundTriplets); | ||||
return (FontTriplet)foundTriplets.get(0); | return (FontTriplet)foundTriplets.get(0); | ||||
* Diagnostic method for logging all registered fonts to System.out. | * Diagnostic method for logging all registered fonts to System.out. | ||||
*/ | */ | ||||
public void dumpAllTripletsToSystemOut() { | public void dumpAllTripletsToSystemOut() { | ||||
System.out.print(toString()); | |||||
} | |||||
/** | |||||
* {@inheritDoc} | |||||
*/ | |||||
public String toString() { | |||||
Collection entries = new java.util.TreeSet(); | Collection entries = new java.util.TreeSet(); | ||||
Iterator iter = this.triplets.keySet().iterator(); | Iterator iter = this.triplets.keySet().iterator(); | ||||
while (iter.hasNext()) { | while (iter.hasNext()) { | ||||
FontTriplet triplet = (FontTriplet)iter.next(); | FontTriplet triplet = (FontTriplet)iter.next(); | ||||
String key = getInternalFontKey(triplet); | String key = getInternalFontKey(triplet); | ||||
FontMetrics metrics = getMetricsFor(key); | 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(); | |||||
} | } | ||||
} | } |
/* | |||||
* 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); | |||||
} | |||||
}; | |||||
} | |||||
} |
/* | |||||
* 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); | |||||
} | |||||
} | |||||
} | |||||
} |
import org.apache.fop.fonts.base14.TimesRoman; | import org.apache.fop.fonts.base14.TimesRoman; | ||||
import org.apache.fop.fonts.base14.ZapfDingbats; | 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 | * Default fonts for FOP application; currently this uses PDF's fonts | ||||
* by default. | * by default. | ||||
protected static Log log = LogFactory.getLog(FontSetup.class); | 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); | |||||
} | } | ||||
/** | /** | ||||
* triplets for lookup. | * triplets for lookup. | ||||
* | * | ||||
* @param fontInfo the font info object to set up | * @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 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("F13", new Symbol()); | ||||
fontInfo.addMetrics("F14", new ZapfDingbats()); | fontInfo.addMetrics("F14", new ZapfDingbats()); | ||||
// fontInfo.addMetrics("F17", new BauerBodoniBoldItalic()); | // fontInfo.addMetrics("F17", new BauerBodoniBoldItalic()); | ||||
/* any is treated as serif */ | /* 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 | // Custom type 1 fonts step 2/2 | ||||
// fontInfo.addFontProperties("F15", "OMEP", "normal", FontInfo.NORMAL); | // fontInfo.addFontProperties("F15", "OMEP", "normal", FontInfo.NORMAL); | ||||
// fontInfo.addFontProperties("F17", "BauerBodoni", "italic", FontInfo.BOLD); | // fontInfo.addFontProperties("F17", "BauerBodoni", "italic", FontInfo.BOLD); | ||||
/* for compatibility with PassiveTex */ | /* 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", | 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 */ | /* Add configured fonts */ | ||||
addConfiguredFonts(fontInfo, embedList, 15, resolver); | |||||
addConfiguredFonts(fontInfo, embedFontInfoList, startNum, resolver); | |||||
} | } | ||||
/** | /** | ||||
* Add fonts from configuration file starting with internal name F<num>. | * 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 num starting index for internal font numbering | ||||
* @param resolver the font resolver | * @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 | return; //No fonts to process | ||||
} | } | ||||
if (resolver == null) { | if (resolver == null) { | ||||
//Ensure that we have minimal font resolution capabilities | //Ensure that we have minimal font resolution capabilities | ||||
resolver = createMinimalFontResolver(); | |||||
resolver = createMinimalFontResolver1(); | |||||
} | } | ||||
String internalName = null; | String internalName = null; | ||||
//FontReader reader = 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; | internalName = "F" + num; | ||||
num++; | num++; | ||||
/* | /* | ||||
reader.setFontEmbedPath(configFontInfo.getEmbedFile()); | reader.setFontEmbedPath(configFontInfo.getEmbedFile()); | ||||
fontInfo.addMetrics(internalName, reader.getFont()); | fontInfo.addMetrics(internalName, reader.getFont()); | ||||
*/ | */ | ||||
LazyFont font = new LazyFont(configFontInfo, resolver); | |||||
LazyFont font = new LazyFont(embedFontInfo, resolver); | |||||
fontInfo.addMetrics(internalName, font); | 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); | fontInfo.addFontProperties(internalName, triplet); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
/** @return a new FontResolver to be used by the font subsystem */ | /** @return a new FontResolver to be used by the font subsystem */ | ||||
public static FontResolver createMinimalFontResolver() { | |||||
public static FontResolver createMinimalFontResolver1() { | |||||
return new FontResolver() { | return new FontResolver() { | ||||
/** {@inheritDoc} */ | /** {@inheritDoc} */ |
//This is only a cache | //This is only a cache | ||||
private transient String key; | 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. | * Creates a new font triplet. | ||||
* @param name font name | * @param name font name | ||||
* @param weight font weight (100, 200, 300...800, 900) | * @param weight font weight (100, 200, 300...800, 900) | ||||
*/ | */ | ||||
public FontTriplet(String name, String style, int weight) { | public FontTriplet(String name, String style, int weight) { | ||||
this(name, style, weight, 0); | |||||
this(name, style, weight, Font.PRIORITY_DEFAULT); | |||||
} | } | ||||
/** | /** | ||||
* @param priority priority of this triplet/font mapping | * @param priority priority of this triplet/font mapping | ||||
*/ | */ | ||||
public FontTriplet(String name, String style, int weight, int priority) { | public FontTriplet(String name, String style, int weight, int priority) { | ||||
this.name = name; | |||||
this(name); | |||||
this.style = style; | this.style = style; | ||||
this.weight = weight; | this.weight = weight; | ||||
this.priority = priority; | this.priority = priority; | ||||
public String toString() { | public String toString() { | ||||
return getKey(); | return getKey(); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Removes all white space from a string (used primarily for font names) | * Removes all white space from a string (used primarily for font names) | ||||
* @param s the string | |||||
* @param str the string | |||||
* @return the processed result | * @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 */ | /** 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 */ | /** font constituent names which identify a font as being of "light" weight */ | ||||
private static final String[] LIGHT_WORDS = {"light"}; | private static final String[] LIGHT_WORDS = {"light"}; | ||||
* @return "normal" or "italic" | * @return "normal" or "italic" | ||||
*/ | */ | ||||
public static String guessStyle(String fontName) { | 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; | return Font.STYLE_NORMAL; | ||||
} | } | ||||
return weight; | return weight; | ||||
} | } | ||||
} | } |
* | * | ||||
* @param dir directory to search | * @param dir directory to search | ||||
* @return list of font files | * @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 { | public List find(String dir) throws IOException { | ||||
List results = new java.util.ArrayList(); | List results = new java.util.ArrayList(); |
//Full Name usually includes style/weight info so don't use these traits | //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 | //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)) { | 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(); | Set familyNames = customFont.getFamilyNames(); | ||||
Iterator iter = familyNames.iterator(); | Iterator iter = familyNames.iterator(); |
/* | |||||
* 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; | |||||
} | |||||
} |
/* | |||||
* 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; | |||||
} | |||||
} |
/* | |||||
* 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; | |||||
} | |||||
} |
/* | |||||
* 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; | |||||
} | |||||
} |
/* | |||||
* 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); | |||||
} | |||||
} | |||||
} | |||||
} |
/* | |||||
* 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); | |||||
} | |||||
} | |||||
} |
/* | |||||
* 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; | |||||
} | |||||
} |
/** True if this LayoutManager has handled all of its content. */ | /** True if this LayoutManager has handled all of its content. */ | ||||
private boolean bFinished = false; | private boolean bFinished = false; | ||||
/** child LM and child LM iterator during getNextKnuthElement phase */ | |||||
/** child LM during getNextKnuthElement phase */ | |||||
protected LayoutManager curChildLM = null; | protected LayoutManager curChildLM = null; | ||||
/** child LM iterator during getNextKnuthElement phase */ | |||||
protected ListIterator childLMiter = null; | protected ListIterator childLMiter = null; | ||||
private int lastGeneratedPosition = -1; | private int lastGeneratedPosition = -1; |
super(); | super(); | ||||
this.userAgent = userAgent; | this.userAgent = userAgent; | ||||
} | } | ||||
/** | /** | ||||
* Returns the configuration subtree for a specific renderer. | * Returns the configuration subtree for a specific renderer. | ||||
return null; | return null; | ||||
} | } | ||||
return getRendererConfig(userAgent, mimeType); | |||||
return getRendererConfig(mimeType); | |||||
} | } | ||||
/** | /** | ||||
* Returns the configuration subtree for a specific renderer. | * 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 | * @param mimeType the MIME type of the renderer | ||||
* @return the requested configuration subtree, null if there's no configuration | * @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(); | Configuration cfg = userAgent.getFactory().getUserConfig(); | ||||
if (cfg == null) { | if (cfg == null) { | ||||
if (log.isDebugEnabled()) { | if (log.isDebugEnabled()) { |
import org.apache.fop.fonts.Font; | import org.apache.fop.fonts.Font; | ||||
import org.apache.fop.fonts.FontInfo; | import org.apache.fop.fonts.FontInfo; | ||||
import org.apache.fop.fonts.FontResolver; | import org.apache.fop.fonts.FontResolver; | ||||
import org.apache.fop.fonts.FontSetup; | |||||
import org.apache.fop.fonts.FontTriplet; | import org.apache.fop.fonts.FontTriplet; | ||||
import org.w3c.dom.Document; | import org.w3c.dom.Document; | ||||
protected FontResolver fontResolver = null; | protected FontResolver fontResolver = null; | ||||
/** list of fonts */ | /** 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 { | } 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; | |||||
} | } | ||||
/** | /** | ||||
*/ | */ | ||||
public void setupFontInfo(FontInfo inFontInfo) { | public void setupFontInfo(FontInfo inFontInfo) { | ||||
this.fontInfo = inFontInfo; | this.fontInfo = inFontInfo; | ||||
FontSetup.setup(fontInfo, fontList, fontResolver, | |||||
userAgent.getFactory().isBase14KerningEnabled()); | |||||
userAgent.getFactory().getFontManager().setupRenderer(this); | |||||
} | } | ||||
/** | /** | ||||
} | } | ||||
return this.fontResolver; | return this.fontResolver; | ||||
} | } | ||||
/** | |||||
* @return the font info | |||||
*/ | |||||
public FontInfo getFontInfo() { | |||||
return this.fontInfo; | |||||
} | |||||
} | } |
import org.apache.fop.fonts.EmbedFontInfo; | import org.apache.fop.fonts.EmbedFontInfo; | ||||
import org.apache.fop.fonts.FontCache; | import org.apache.fop.fonts.FontCache; | ||||
import org.apache.fop.fonts.FontInfo; | import org.apache.fop.fonts.FontInfo; | ||||
import org.apache.fop.fonts.FontManager; | |||||
import org.apache.fop.fonts.FontResolver; | import org.apache.fop.fonts.FontResolver; | ||||
import org.apache.fop.fonts.FontSetup; | |||||
import org.apache.fop.fonts.FontTriplet; | import org.apache.fop.fonts.FontTriplet; | ||||
import org.apache.fop.fonts.FontUtil; | import org.apache.fop.fonts.FontUtil; | ||||
import org.apache.fop.fonts.autodetect.FontFileFinder; | import org.apache.fop.fonts.autodetect.FontFileFinder; | ||||
public void configure(Renderer renderer) throws FOPException { | public void configure(Renderer renderer) throws FOPException { | ||||
Configuration cfg = getRendererConfig(renderer); | Configuration cfg = getRendererConfig(renderer); | ||||
if (cfg == null) { | if (cfg == null) { | ||||
log.trace("no configuration found for " + renderer); | |||||
return; | return; | ||||
} | } | ||||
PrintRenderer printRenderer = (PrintRenderer)renderer; | PrintRenderer printRenderer = (PrintRenderer)renderer; | ||||
FontResolver fontResolver = printRenderer.getFontResolver(); | FontResolver fontResolver = printRenderer.getFontResolver(); | ||||
FopFactory factory = userAgent.getFactory(); | |||||
FontManager fontManager = factory.getFontManager(); | |||||
if (fontResolver == null) { | if (fontResolver == null) { | ||||
//Ensure that we have minimal font resolution capabilities | //Ensure that we have minimal font resolution capabilities | ||||
fontResolver = FontSetup.createMinimalFontResolver(); | |||||
fontResolver = FontManager.createMinimalFontResolver(); | |||||
} | } | ||||
FopFactory factory = userAgent.getFactory(); | |||||
boolean strict = factory.validateUserConfigStrictly(); | 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, | userAgent.getFontBaseURL(), fontResolver, strict, | ||||
fontCache); | fontCache); | ||||
if (fontCache != null && fontCache.hasChanged()) { | if (fontCache != null && fontCache.hasChanged()) { | ||||
fontCache.save(); | fontCache.save(); | ||||
} | } | ||||
printRenderer.addFontList(fontInfoList); | |||||
printRenderer.addFontList(embedFontInfoList); | |||||
} | } | ||||
/** | /** | ||||
* @return a List of EmbedFontInfo objects. | * @return a List of EmbedFontInfo objects. | ||||
* @throws FOPException If an error occurs while processing the configuration | * @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, | String fontBaseURL, FontResolver fontResolver, | ||||
boolean strict, FontCache fontCache) throws FOPException { | 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); | Configuration fonts = cfg.getChild("fonts", false); | ||||
if (fonts != null) { | if (fonts != null) { | ||||
// font file (singular) configuration | // font file (singular) configuration | ||||
Configuration[] font = fonts.getChildren("font"); | Configuration[] font = fonts.getChildren("font"); | ||||
for (int i = 0; i < font.length; i++) { | for (int i = 0; i < font.length; i++) { | ||||
EmbedFontInfo fontInfo = getFontInfoFromConfiguration( | |||||
EmbedFontInfo embedFontInfo = getFontInfoFromConfiguration( | |||||
font[i], fontResolver, strict, fontCache); | font[i], fontResolver, strict, fontCache); | ||||
if (fontInfo != null) { | |||||
fontInfoList.add(fontInfo); | |||||
if (embedFontInfo != null) { | |||||
fontInfoList.add(embedFontInfo); | |||||
} | } | ||||
} | } | ||||
if (log.isDebugEnabled()) { | if (log.isDebugEnabled()) { | ||||
log.debug("Finished font configuration in " | log.debug("Finished font configuration in " | ||||
+ (System.currentTimeMillis() - start) + "ms"); | + (System.currentTimeMillis() - start) + "ms"); | ||||
/** | /** | ||||
* Iterates over font file list adding font info to list | * Iterates over font file list adding font info to list | ||||
* @param fontFileList font file list | * @param fontFileList font file list | ||||
* @param fontInfoList font info list | |||||
* @param embedFontInfoList a configured font info list | |||||
* @param resolver font resolver | * @param resolver font resolver | ||||
*/ | */ | ||||
private static void addFontInfoListFromFileList( | 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();) { | for (Iterator iter = fontFileList.iterator(); iter.hasNext();) { | ||||
URL fontUrl = (URL)iter.next(); | URL fontUrl = (URL)iter.next(); | ||||
// parse font to ascertain font info | // parse font to ascertain font info | ||||
for (int i = 0, c = embedFontInfos.length; i < c; i++) { | for (int i = 0, c = embedFontInfos.length; i < c; i++) { | ||||
EmbedFontInfo fontInfo = embedFontInfos[i]; | EmbedFontInfo fontInfo = embedFontInfos[i]; | ||||
if (fontInfo != null) { | if (fontInfo != null) { | ||||
fontInfoList.add(fontInfo); | |||||
embedFontInfoList.add(fontInfo); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
/** | |||||
* 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 | * Returns a font info from a font node Configuration definition | ||||
* | * | ||||
* @param fontResolver font resolver used to resolve font | * @param fontResolver font resolver used to resolve font | ||||
* @param strict validate configuration strictly | * @param strict validate configuration strictly | ||||
* @param fontCache the font cache (or null if it is disabled) | * @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 | * @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) | Configuration fontCfg, FontResolver fontResolver, boolean strict, FontCache fontCache) | ||||
throws FOPException { | throws FOPException { | ||||
String metricsUrl = fontCfg.getAttribute("metrics-url", null); | String metricsUrl = fontCfg.getAttribute("metrics-url", null); | ||||
String embedUrl = fontCfg.getAttribute("embed-url", null); | String embedUrl = fontCfg.getAttribute("embed-url", null); | ||||
String subFont = fontCfg.getAttribute("sub-font", null); | String subFont = fontCfg.getAttribute("sub-font", null); | ||||
if (metricsUrl == null && embedUrl == 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; | return null; | ||||
} | } | ||||
if (strict) { | if (strict) { | ||||
} | } | ||||
} | } | ||||
} | } | ||||
boolean useKerning = fontCfg.getAttributeAsBoolean("kerning", true); | |||||
EmbedFontInfo fontInfo = null; | |||||
Configuration[] tripletCfg = fontCfg.getChildren("font-triplet"); | Configuration[] tripletCfg = fontCfg.getChildren("font-triplet"); | ||||
// no font triplet info | // no font triplet info | ||||
if (tripletCfg.length == 0) { | if (tripletCfg.length == 0) { | ||||
LogUtil.handleError(log, "font without font-triplet", strict); | 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}); | File fontFile = FontCache.getFileFromUrls(new String[] {embedUrl, metricsUrl}); | ||||
URL fontUrl; | URL fontUrl; | ||||
try { | try { | ||||
} else { | } else { | ||||
return null; | 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; | |||||
} | } | ||||
} | } |
public void setupFontInfo(FontInfo inFontInfo) { | public void setupFontInfo(FontInfo inFontInfo) { | ||||
this.fontInfo = inFontInfo; | this.fontInfo = inFontInfo; | ||||
int num = 1; | 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(); | AFPFontInfo afi = (AFPFontInfo)it.next(); | ||||
AFPFont bf = (AFPFont)afi.getAFPFont(); | AFPFont bf = (AFPFont)afi.getAFPFont(); | ||||
for (Iterator it2 = afi.getFontTriplets().iterator(); it2.hasNext();) { | for (Iterator it2 = afi.getFontTriplets().iterator(); it2.hasNext();) { |
/* | |||||
* 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; | |||||
} | |||||
} |
/* | |||||
* 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; | |||||
} | |||||
} |
/* | |||||
* 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; | |||||
} | |||||
} | |||||
/* | |||||
* 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; | |||||
} | |||||
} |
public void setupFontInfo(FontInfo inFontInfo) { | public void setupFontInfo(FontInfo inFontInfo) { | ||||
//Don't call super.setupFontInfo() here! Java2D needs a special font setup | //Don't call super.setupFontInfo() here! Java2D needs a special font setup | ||||
// create a temp Image to test font metrics on | // create a temp Image to test font metrics on | ||||
fontInfo = inFontInfo; | |||||
this.fontInfo = inFontInfo; | |||||
BufferedImage fontImage = new BufferedImage(100, 100, | BufferedImage fontImage = new BufferedImage(100, 100, | ||||
BufferedImage.TYPE_INT_RGB); | BufferedImage.TYPE_INT_RGB); | ||||
Graphics2D g = fontImage.createGraphics(); | |||||
Graphics2D graphics2D = fontImage.createGraphics(); | |||||
//The next line is important to get accurate font metrics! | //The next line is important to get accurate font metrics! | ||||
g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, | |||||
graphics2D.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, | |||||
RenderingHints.VALUE_FRACTIONALMETRICS_ON); | RenderingHints.VALUE_FRACTIONALMETRICS_ON); | ||||
FontSetup.setup(fontInfo, fontList, fontResolver, g); | |||||
userAgent.getFactory().getFontManager().setupRenderer(this, graphics2D); | |||||
} | } | ||||
/** {@inheritDoc} */ | /** {@inheritDoc} */ |
import org.apache.fop.render.RendererContextConstants; | import org.apache.fop.render.RendererContextConstants; | ||||
import org.apache.fop.render.RendererEventProducer; | import org.apache.fop.render.RendererEventProducer; | ||||
import org.apache.fop.render.java2d.FontMetricsMapper; | 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.java2d.Java2DRenderer; | ||||
import org.apache.fop.render.pcl.extensions.PCLElementMapping; | import org.apache.fop.render.pcl.extensions.PCLElementMapping; | ||||
import org.apache.fop.traits.BorderProps; | import org.apache.fop.traits.BorderProps; | ||||
fontInfo = inFontInfo; | fontInfo = inFontInfo; | ||||
BufferedImage fontImage = new BufferedImage(100, 100, | BufferedImage fontImage = new BufferedImage(100, 100, | ||||
BufferedImage.TYPE_INT_RGB); | BufferedImage.TYPE_INT_RGB); | ||||
Graphics2D g = fontImage.createGraphics(); | |||||
Graphics2D graphics2D = fontImage.createGraphics(); | |||||
//The next line is important to get accurate font metrics! | //The next line is important to get accurate font metrics! | ||||
g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, | |||||
graphics2D.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, | |||||
RenderingHints.VALUE_FRACTIONALMETRICS_ON); | RenderingHints.VALUE_FRACTIONALMETRICS_ON); | ||||
FontSetup.setup(fontInfo, fontList, fontResolver, g); | |||||
userAgent.getFactory().getFontManager().setupRenderer(this, graphics2D); | |||||
} | } | ||||
/** | /** |
if (!isTextStroked()) { | if (!isTextStroked()) { | ||||
FontInfo fontInfo = new FontInfo(); | FontInfo fontInfo = new FontInfo(); | ||||
//TODO Do custom font configuration here somewhere/somehow | //TODO Do custom font configuration here somewhere/somehow | ||||
FontSetup.setup(fontInfo, null, null); | |||||
FontSetup.setup(fontInfo); | |||||
graphics.setCustomTextHandler(new NativeTextHandler(graphics, fontInfo)); | graphics.setCustomTextHandler(new NativeTextHandler(graphics, fontInfo)); | ||||
} | } | ||||
private void setupFontInfo() { | private void setupFontInfo() { | ||||
//Sets up a FontInfo with default fonts | //Sets up a FontInfo with default fonts | ||||
fontInfo = new FontInfo(); | fontInfo = new FontInfo(); | ||||
FontSetup.setup(fontInfo, null, null); | |||||
FontSetup.setup(fontInfo); | |||||
} | } | ||||
/** | /** |
if (fontInfo == null) { | if (fontInfo == null) { | ||||
//Default minimal fonts | //Default minimal fonts | ||||
FontInfo fontInfo = new FontInfo(); | FontInfo fontInfo = new FontInfo(); | ||||
FontSetup.setup(fontInfo, null, null); | |||||
FontSetup.setup(fontInfo); | |||||
setFontInfo(fontInfo); | setFontInfo(fontInfo); | ||||
} | } | ||||
} | } |
import org.apache.fop.apps.FOPException; | import org.apache.fop.apps.FOPException; | ||||
import org.apache.fop.fonts.FontCache; | import org.apache.fop.fonts.FontCache; | ||||
import org.apache.fop.fonts.FontInfo; | import org.apache.fop.fonts.FontInfo; | ||||
import org.apache.fop.fonts.FontManager; | |||||
import org.apache.fop.fonts.FontResolver; | import org.apache.fop.fonts.FontResolver; | ||||
import org.apache.fop.fonts.FontSetup; | import org.apache.fop.fonts.FontSetup; | ||||
import org.apache.fop.pdf.PDFDocument; | import org.apache.fop.pdf.PDFDocument; | ||||
//Fonts | //Fonts | ||||
try { | try { | ||||
FontResolver fontResolver = FontSetup.createMinimalFontResolver(); | |||||
FontResolver fontResolver = FontManager.createMinimalFontResolver(); | |||||
//TODO The following could be optimized by retaining the FontCache somewhere | //TODO The following could be optimized by retaining the FontCache somewhere | ||||
FontCache fontCache = FontCache.load(); | FontCache fontCache = FontCache.load(); | ||||
if (fontCache == null) { | if (fontCache == null) { | ||||
fontCache = new FontCache(); | 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(); | fontCache.save(); | ||||
FontInfo fontInfo = new FontInfo(); | FontInfo fontInfo = new FontInfo(); | ||||
FontSetup.setup(fontInfo, fontList, fontResolver); | |||||
FontSetup.setup(fontInfo, embedFontInfoList, fontResolver); | |||||
graphics.setFontInfo(fontInfo); | graphics.setFontInfo(fontInfo); | ||||
} catch (FOPException e) { | } catch (FOPException e) { | ||||
throw new ConfigurationException("Error while setting up fonts", e); | throw new ConfigurationException("Error while setting up fonts", e); |
preparePainting(); | preparePainting(); | ||||
FontInfo specialFontInfo = new FontInfo(); | FontInfo specialFontInfo = new FontInfo(); | ||||
FontSetup.setup(specialFontInfo, null, null); | |||||
FontSetup.setup(specialFontInfo); | |||||
PDFResources res = pdfDoc.getFactory().makeResources(); | PDFResources res = pdfDoc.getFactory().makeResources(); | ||||
PDFResourceContext context = new PDFResourceContext(res); | PDFResourceContext context = new PDFResourceContext(res); |
<action context="Renderers" dev="AC" importance="high" type="add"> | <action context="Renderers" dev="AC" importance="high" type="add"> | ||||
Added SVG support for AFP (GOCA). | Added SVG support for AFP (GOCA). | ||||
</action --> | </action --> | ||||
<action context="Fonts" dev="AC" type="add"> | |||||
Add support for font substitution. | |||||
</action> | |||||
<action context="Code" dev="AD" type="fix" fixed-bug="44203"> | |||||
<action context="Renderers" dev="JM" type="fix" fixes-bug="43650"> | <action context="Renderers" dev="JM" type="fix" fixes-bug="43650"> | ||||
PCL Renderer: Improved page format selection so it doesn't interfere with | PCL Renderer: Improved page format selection so it doesn't interfere with | ||||
duplex printing. | duplex printing. |
<?xml version="1.0"?> | |||||
<fop version="1.0"> | |||||
<!-- Strict configuration On --> | |||||
<strict-configuration>true</strict-configuration> | |||||
<!-- Switch off font caching for the purposes of the unit test --> | |||||
<use-cache>false</use-cache> | |||||
<!-- Base URL for resolving relative URLs --> | |||||
<base>./</base> | |||||
<!-- Font Base URL for resolving relative font URLs --> | |||||
<font-base>./</font-base> | |||||
<fonts> | |||||
<substitutions> | |||||
<substitution> | |||||
<from font-family="Times" font-style="italic"/> | |||||
<to font-family="Gladiator" font-style="normal" font-weight="bold"/> | |||||
</substitution> | |||||
</substitutions> | |||||
</fonts> | |||||
<renderers> | |||||
<renderer mime="application/pdf"> | |||||
<fonts> | |||||
<font metrics-url="test/resources/fonts/glb12.ttf.xml" embed-url="test/resources/fonts/glb12.ttf"> | |||||
<font-triplet name="Gladiator" style="normal" weight="bold"/> | |||||
</font> | |||||
</fonts> | |||||
</renderer> | |||||
</renderers> | |||||
</fop> |
final File baseDir = getBaseDir(); | final File baseDir = getBaseDir(); | ||||
final String fontFOFilePath = getFontFOFilePath(); | final String fontFOFilePath = getFontFOFilePath(); | ||||
File foFile = new File(baseDir, fontFOFilePath); | File foFile = new File(baseDir, fontFOFilePath); | ||||
final boolean dumpOutput = false; | |||||
final boolean dumpOutput = true; | |||||
FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); | FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); | ||||
convertFO(foFile, foUserAgent, dumpOutput); | convertFO(foFile, foUserAgent, dumpOutput); | ||||
} | } |
/* | |||||
* 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.config; | |||||
import java.io.File; | |||||
import org.apache.fop.apps.FOUserAgent; | |||||
import org.apache.fop.apps.MimeConstants; | |||||
import org.apache.fop.fonts.Font; | |||||
import org.apache.fop.fonts.FontInfo; | |||||
import org.apache.fop.fonts.FontManager; | |||||
import org.apache.fop.fonts.FontTriplet; | |||||
import org.apache.fop.render.PrintRenderer; | |||||
public class FontsSubstitutionTestCase extends BaseConstructiveUserConfigTestCase { | |||||
public FontsSubstitutionTestCase(String name) { | |||||
super(name); | |||||
} | |||||
/** | |||||
* {@inheritDoc} | |||||
*/ | |||||
protected byte[] convertFO(File foFile, FOUserAgent ua, boolean dumpPdfFile) throws Exception { | |||||
PrintRenderer renderer = (PrintRenderer)ua.getRendererFactory().createRenderer(ua, MimeConstants.MIME_PDF); | |||||
FontInfo fontInfo = new FontInfo(); | |||||
renderer.setupFontInfo(fontInfo); | |||||
FontManager fontManager = ua.getFactory().getFontManager(); | |||||
fontManager.setupRenderer(renderer); | |||||
FontTriplet triplet = new FontTriplet("Times", "italic", Font.WEIGHT_NORMAL); | |||||
String internalFontKey = fontInfo.getInternalFontKey(triplet); | |||||
// Times italic should now be mapped to the 15th font (custom font) | |||||
// not the original base 14 (F6) | |||||
if (!"F15".equals(internalFontKey)) { | |||||
throw new Exception("font substitution failed :" + triplet); | |||||
} | |||||
return null; | |||||
} | |||||
/** | |||||
* {@inheritDoc} | |||||
*/ | |||||
public String getUserConfigFilename() { | |||||
return "test_fonts_substitution.xconf"; | |||||
} | |||||
} |
suite.addTest(new TestSuite(FontEmbedUrlMalformedTestCase.class)); | suite.addTest(new TestSuite(FontEmbedUrlMalformedTestCase.class)); | ||||
suite.addTest(new TestSuite(FontsDirectoryRecursiveTestCase.class)); | suite.addTest(new TestSuite(FontsDirectoryRecursiveTestCase.class)); | ||||
suite.addTest(new TestSuite(FontsAutoDetectTestCase.class)); | suite.addTest(new TestSuite(FontsAutoDetectTestCase.class)); | ||||
suite.addTest(new TestSuite(FontsSubstitutionTestCase.class)); | |||||
//$JUnit-END$ | //$JUnit-END$ | ||||
return suite; | return suite; | ||||
} | } |
*/ | */ | ||||
public LayoutEngineTester(File areaTreeBackupDir) { | public LayoutEngineTester(File areaTreeBackupDir) { | ||||
this.areaTreeBackupDir = areaTreeBackupDir; | this.areaTreeBackupDir = areaTreeBackupDir; | ||||
fopFactory.setBase14KerningEnabled(false); | |||||
fopFactoryWithBase14Kerning.setBase14KerningEnabled(true); | |||||
fopFactory.getFontManager().setBase14KerningEnabled(false); | |||||
fopFactoryWithBase14Kerning.getFontManager().setBase14KerningEnabled(true); | |||||
} | } | ||||
private Templates getTestcase2FOStylesheet() throws TransformerConfigurationException { | private Templates getTestcase2FOStylesheet() throws TransformerConfigurationException { |
} | } | ||||
} | } | ||||
private static Exception extractOriginalException(Exception e) { | |||||
protected static Exception extractOriginalException(Exception e) { | |||||
if (e.getCause() != null) { | if (e.getCause() != null) { | ||||
return extractOriginalException((Exception)e.getCause()); | return extractOriginalException((Exception)e.getCause()); | ||||
} else if (e instanceof SAXException) { | } else if (e instanceof SAXException) { |
* @return an initialized FOUserAgent | * @return an initialized FOUserAgent | ||||
* */ | * */ | ||||
protected FOUserAgent getUserAgent() { | protected FOUserAgent getUserAgent() { | ||||
final FOUserAgent a = fopFactory.newFOUserAgent(); | |||||
a.getRendererOptions().put("pdf-a-mode", "PDF/A-1b"); | |||||
return a; | |||||
final FOUserAgent userAgent = fopFactory.newFOUserAgent(); | |||||
userAgent.getRendererOptions().put("pdf-a-mode", "PDF/A-1b"); | |||||
return userAgent; | |||||
} | } | ||||
/** | /** | ||||
//Good! | //Good! | ||||
} | } | ||||
} | } | ||||
} | } |