| /* |
| * 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.io.IOException; |
| import java.io.InputStream; |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| |
| import javax.xml.transform.Source; |
| import javax.xml.transform.stream.StreamSource; |
| |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| |
| import org.apache.fop.fonts.truetype.TTFFontLoader; |
| import org.apache.fop.fonts.type1.Type1FontLoader; |
| |
| /** |
| * Base class for font loaders. |
| */ |
| public abstract class FontLoader { |
| |
| /** logging instance */ |
| protected static Log log = LogFactory.getLog(FontLoader.class); |
| |
| /** URI representing the font file */ |
| protected String fontFileURI = null; |
| /** the FontResolver to use for font URI resolution */ |
| protected FontResolver resolver = null; |
| /** the loaded font */ |
| protected CustomFont returnFont = null; |
| |
| /** true if the font has been loaded */ |
| protected boolean loaded = false; |
| /** true if the font will be embedded, false if it will be referenced only. */ |
| protected boolean embedded = true; |
| /** true if kerning information shall be loaded if available. */ |
| protected boolean useKerning = true; |
| |
| /** |
| * Default constructor. |
| * @param fontFileURI the URI to the PFB file of a Type 1 font |
| * @param embedded indicates whether the font is embedded or referenced |
| * @param useKerning indicates whether kerning information shall be loaded if available |
| * @param resolver the font resolver used to resolve URIs |
| */ |
| public FontLoader(String fontFileURI, boolean embedded, boolean useKerning, |
| FontResolver resolver) { |
| this.fontFileURI = fontFileURI; |
| this.embedded = embedded; |
| this.useKerning = useKerning; |
| this.resolver = resolver; |
| } |
| |
| private static boolean isType1(String fontURI) { |
| return fontURI.toLowerCase().endsWith(".pfb"); |
| } |
| |
| /** |
| * Loads a custom font from a File. In the case of Type 1 fonts, the PFB file must be specified. |
| * @param fontFile the File representation of the font |
| * @param subFontName the sub-fontname of a font (for TrueType Collections, null otherwise) |
| * @param embedded indicates whether the font is embedded or referenced |
| * @param encodingMode the requested encoding mode |
| * @param resolver the font resolver to use when resolving URIs |
| * @return the newly loaded font |
| * @throws IOException In case of an I/O error |
| */ |
| public static CustomFont loadFont(File fontFile, String subFontName, |
| boolean embedded, EncodingMode encodingMode, FontResolver resolver) throws IOException { |
| return loadFont(fontFile.toURI().toURL(), subFontName, |
| embedded, encodingMode, resolver); |
| } |
| |
| /** |
| * Loads a custom font from an URL. In the case of Type 1 fonts, the PFB file must be specified. |
| * @param fontUrl the URL representation of the font |
| * @param subFontName the sub-fontname of a font (for TrueType Collections, null otherwise) |
| * @param embedded indicates whether the font is embedded or referenced |
| * @param encodingMode the requested encoding mode |
| * @param resolver the font resolver to use when resolving URIs |
| * @return the newly loaded font |
| * @throws IOException In case of an I/O error |
| */ |
| public static CustomFont loadFont(URL fontUrl, String subFontName, |
| boolean embedded, EncodingMode encodingMode, |
| FontResolver resolver) throws IOException { |
| return loadFont(fontUrl.toExternalForm(), subFontName, |
| embedded, encodingMode, true, |
| resolver); |
| } |
| |
| /** |
| * Loads a custom font from a URI. In the case of Type 1 fonts, the PFB file must be specified. |
| * @param fontFileURI the URI to the font |
| * @param subFontName the sub-fontname of a font (for TrueType Collections, null otherwise) |
| * @param embedded indicates whether the font is embedded or referenced |
| * @param encodingMode the requested encoding mode |
| * @param useKerning indicates whether kerning information should be loaded if available |
| * @param resolver the font resolver to use when resolving URIs |
| * @return the newly loaded font |
| * @throws IOException In case of an I/O error |
| */ |
| public static CustomFont loadFont(String fontFileURI, String subFontName, |
| boolean embedded, EncodingMode encodingMode, boolean useKerning, |
| FontResolver resolver) throws IOException { |
| fontFileURI = fontFileURI.trim(); |
| boolean type1 = isType1(fontFileURI); |
| FontLoader loader; |
| if (type1) { |
| if (encodingMode == EncodingMode.CID) { |
| throw new IllegalArgumentException( |
| "CID encoding mode not supported for Type 1 fonts"); |
| } |
| loader = new Type1FontLoader(fontFileURI, embedded, useKerning, resolver); |
| } else { |
| loader = new TTFFontLoader(fontFileURI, subFontName, |
| embedded, encodingMode, useKerning, resolver); |
| } |
| return loader.getFont(); |
| } |
| |
| /** |
| * Opens a font URI and returns an input stream. |
| * @param resolver the FontResolver to use for font URI resolution |
| * @param uri the URI representing the font |
| * @return the InputStream to read the font from. |
| * @throws IOException In case of an I/O error |
| * @throws MalformedURLException If an invalid URL is built |
| */ |
| public static InputStream openFontUri(FontResolver resolver, String uri) |
| throws IOException, MalformedURLException { |
| InputStream in = null; |
| if (resolver != null) { |
| Source source = resolver.resolve(uri); |
| if (source == null) { |
| String err = "Cannot load font: failed to create Source for font file " |
| + uri; |
| throw new IOException(err); |
| } |
| if (source instanceof StreamSource) { |
| in = ((StreamSource) source).getInputStream(); |
| } |
| if (in == null && source.getSystemId() != null) { |
| in = new java.net.URL(source.getSystemId()).openStream(); |
| } |
| if (in == null) { |
| String err = "Cannot load font: failed to create InputStream from" |
| + " Source for font file " + uri; |
| throw new IOException(err); |
| } |
| } else { |
| in = new URL(uri).openStream(); |
| } |
| return in; |
| } |
| |
| /** |
| * Reads/parses the font data. |
| * @throws IOException In case of an I/O error |
| */ |
| protected abstract void read() throws IOException; |
| |
| /** |
| * Returns the custom font that was read using this instance of FontLoader. |
| * @return the newly loaded font |
| * @throws IOException if an I/O error occurs |
| */ |
| public CustomFont getFont() throws IOException { |
| if (!loaded) { |
| read(); |
| } |
| return this.returnFont; |
| } |
| } |