blob: 9285c94be4ab091f5d4d70fb8912ce7f9d13fdce [file] [log] [blame]
/*
* 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.io.File;
import java.net.MalformedURLException;
import java.util.List;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import org.apache.fop.apps.FOPException;
import org.apache.fop.fonts.FontTriplet.Matcher;
import org.apache.fop.fonts.substitute.FontSubstitutions;
// TODO: Refactor fonts package so major font activities (autodetection etc)
// are all centrally managed and delegated from this class
/**
* The manager of fonts. The class holds a reference to the font cache and information about
* font substitution, referenced fonts and similar.
*/
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;
/** Allows enabling kerning on the base 14 fonts, default is false */
private boolean enableBase14Kerning = false;
/** FontTriplet matcher for fonts that shall be referenced rather than embedded. */
private FontTriplet.Matcher referencedFontsMatcher;
/** Enables/disables the use of font caching */
private boolean useCache = DEFAULT_USE_CACHE;
/** Provides a font cache file path **/
private File cacheFile;
/**
* Main constructor
*/
public FontManager() {
}
/**
* Sets the font base URL.
* @param fontBase font base URL
* @throws MalformedURLException if there's a problem with a URL
*/
public void setFontBaseURL(String fontBase) throws MalformedURLException {
this.fontBase = fontBase;
}
/**
* Returns the font base URL.
* @return the font base URL (or null if none was set)
*/
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;
}
/**
* Sets the font cache file
* @param cacheFile the font cache file
*/
public void setCacheFile(File cacheFile) {
this.cacheFile = cacheFile;
}
/**
* Returns the font cache file
* @return the font cache file
*/
public File getCacheFile() {
if (cacheFile != null) {
return this.cacheFile;
}
return FontCache.getDefaultCacheFile(false);
}
/**
* Whether or not to cache results of font triplet detection/auto-config
* @param useCache use cache or not
*/
public void setUseCache(boolean useCache) {
this.useCache = useCache;
if (!useCache) {
this.fontCache = null;
}
}
/**
* Cache results of font triplet detection/auto-config?
* @return true if this font manager uses the cache
*/
public boolean useCache() {
return useCache;
}
/**
* Returns the font cache instance used by this font manager.
* @return the font cache
*/
public FontCache getFontCache() {
if (fontCache == null) {
if (useCache) {
if (cacheFile != null) {
fontCache = FontCache.loadFrom(cacheFile);
} else {
fontCache = FontCache.load();
}
if (fontCache == null) {
fontCache = new FontCache();
}
}
}
return fontCache;
}
/**
* Saves the FontCache as necessary
*
* @throws FOPException fop exception
*/
public void saveCache() throws FOPException {
if (useCache) {
if (fontCache != null && fontCache.hasChanged()) {
if (cacheFile != null) {
fontCache.saveTo(cacheFile);
} else {
fontCache.save();
}
}
}
}
/**
* Deletes the current FontCache file
* @return Returns true if the font cache file was successfully deleted.
*/
public boolean deleteCache() {
boolean deleted = false;
if (useCache) {
if (cacheFile != null) {
deleted = cacheFile.delete();
} else {
deleted = FontCache.getDefaultCacheFile(true).delete();
}
}
return deleted;
}
/**
* Sets up the fonts on a given FontInfo object. The fonts to setup are defined by an
* array of {@link FontCollection} objects.
* @param fontInfo the FontInfo object to set up
* @param fontCollections the array of font collections/sources
*/
public void setup(FontInfo fontInfo, FontCollection[] fontCollections) {
int startNum = 1;
for (int i = 0, c = fontCollections.length; i < c; i++) {
startNum = fontCollections[i].setup(startNum, fontInfo);
}
// Make any defined substitutions in the font info
getFontSubstitutions().adjustFontInfo(fontInfo);
}
/**
* Minimum implemenation of FontResolver.
*/
public static class MinimalFontResolver implements FontResolver {
private boolean useComplexScriptFeatures;
MinimalFontResolver(boolean useComplexScriptFeatures) {
this.useComplexScriptFeatures = useComplexScriptFeatures;
}
/** {@inheritDoc} */
public Source resolve(String href) {
//Minimal functionality here
return new StreamSource(href);
}
/** {@inheritDoc} */
public boolean isComplexScriptFeaturesEnabled() {
return useComplexScriptFeatures;
}
}
/**
* Create minimal font resolver.
* @param useComplexScriptFeatures true if complex script features enabled
* @return a new FontResolver to be used by the font subsystem
*/
public static FontResolver createMinimalFontResolver(boolean useComplexScriptFeatures) {
return new MinimalFontResolver ( useComplexScriptFeatures );
}
/**
* Sets the {@link FontTriplet.Matcher} that can be used to identify the fonts that shall
* be referenced rather than embedded.
* @param matcher the font triplet matcher
*/
public void setReferencedFontsMatcher(FontTriplet.Matcher matcher) {
this.referencedFontsMatcher = matcher;
}
/**
* Gets the {@link FontTriplet.Matcher} that can be used to identify the fonts that shall
* be referenced rather than embedded.
* @return the font triplet matcher (or null if none is set)
*/
public Matcher getReferencedFontsMatcher() {
return this.referencedFontsMatcher;
}
/**
* Updates the referenced font list using the FontManager's referenced fonts matcher
* ({@link #getReferencedFontsMatcher()}).
* @param fontInfoList a font info list
*/
public void updateReferencedFonts(List<EmbedFontInfo> fontInfoList) {
Matcher matcher = getReferencedFontsMatcher();
updateReferencedFonts(fontInfoList, matcher);
}
/**
* Updates the referenced font list.
* @param fontInfoList a font info list
* @param matcher the font triplet matcher to use
*/
public void updateReferencedFonts(List<EmbedFontInfo> fontInfoList, Matcher matcher) {
if (matcher == null) {
return; //No referenced fonts
}
for (EmbedFontInfo fontInfo : fontInfoList) {
for (FontTriplet triplet : fontInfo.getFontTriplets()) {
if (matcher.matches(triplet)) {
fontInfo.setEmbedded(false);
break;
}
}
}
}
}