| /* |
| * 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.IOException; |
| import java.util.Collections; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import javax.xml.transform.Source; |
| |
| |
| /** |
| * Abstract base class for custom fonts loaded from files, for example. |
| */ |
| public abstract class CustomFont extends Typeface |
| implements FontDescriptor, MutableFont { |
| |
| private String fontName = null; |
| private String fullName = null; |
| private Set familyNames = null; //Set<String> |
| private String fontSubName = null; |
| private String embedFileName = null; |
| private String embedResourceName = null; |
| private FontResolver resolver = null; |
| |
| private int capHeight = 0; |
| private int xHeight = 0; |
| private int ascender = 0; |
| private int descender = 0; |
| private int[] fontBBox = {0, 0, 0, 0}; |
| private int flags = 4; |
| private int weight = 0; //0 means unknown weight |
| private int stemV = 0; |
| private int italicAngle = 0; |
| private int missingWidth = 0; |
| private FontType fontType = FontType.TYPE1; |
| private int firstChar = 0; |
| private int lastChar = 255; |
| |
| private Map kerning; |
| |
| private boolean useKerning = true; |
| |
| /** {@inheritDoc} */ |
| public String getFontName() { |
| return fontName; |
| } |
| |
| /** {@inheritDoc} */ |
| public String getEmbedFontName() { |
| return getFontName(); |
| } |
| |
| /** {@inheritDoc} */ |
| public String getFullName() { |
| return fullName; |
| } |
| |
| /** |
| * Returns the font family names. |
| * @return the font family names (a Set of Strings) |
| */ |
| public Set getFamilyNames() { |
| return Collections.unmodifiableSet(this.familyNames); |
| } |
| |
| /** |
| * Returns the font family name stripped of whitespace. |
| * @return the stripped font family |
| * @see FontUtil#stripWhiteSpace(String) |
| */ |
| public String getStrippedFontName() { |
| return FontUtil.stripWhiteSpace(getFontName()); |
| } |
| |
| /** |
| * Returns font's subfamily name. |
| * @return the font's subfamily name |
| */ |
| public String getFontSubName() { |
| return fontSubName; |
| } |
| |
| /** |
| * Returns an URI representing an embeddable font file. The URI will often |
| * be a filename or an URL. |
| * @return URI to an embeddable font file or null if not available. |
| */ |
| public String getEmbedFileName() { |
| return embedFileName; |
| } |
| |
| /** |
| * Returns a Source representing an embeddable font file. |
| * @return Source for an embeddable font file |
| * @throws IOException if embedFileName is not null but Source is not found |
| */ |
| public Source getEmbedFileSource() throws IOException { |
| Source result = null; |
| if (resolver != null && embedFileName != null) { |
| result = resolver.resolve(embedFileName); |
| if (result == null) { |
| throw new IOException("Unable to resolve Source '" |
| + embedFileName + "' for embedded font"); |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Returns the lookup name to an embeddable font file available as a |
| * resource. |
| * (todo) Remove this method, this should be done using a resource: URI. |
| * @return the lookup name |
| */ |
| public String getEmbedResourceName() { |
| return embedResourceName; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public int getAscender() { |
| return ascender; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public int getDescender() { |
| return descender; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public int getCapHeight() { |
| return capHeight; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public int getAscender(int size) { |
| return size * ascender; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public int getDescender(int size) { |
| return size * descender; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public int getCapHeight(int size) { |
| return size * capHeight; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public int getXHeight(int size) { |
| return size * xHeight; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public int[] getFontBBox() { |
| return fontBBox; |
| } |
| |
| /** {@inheritDoc} */ |
| public int getFlags() { |
| return flags; |
| } |
| |
| /** {@inheritDoc} */ |
| public boolean isSymbolicFont() { |
| return ((getFlags() & 4) != 0) || "ZapfDingbatsEncoding".equals(getEncodingName()); |
| //Note: The check for ZapfDingbats is necessary as the PFM does not reliably indicate |
| //if a font is symbolic. |
| } |
| |
| /** |
| * Returns the font weight (100, 200...800, 900). This value may be different from the |
| * one that was actually used to register the font. |
| * @return the font weight (or 0 if the font weight is unknown) |
| */ |
| public int getWeight() { |
| return this.weight; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public int getStemV() { |
| return stemV; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public int getItalicAngle() { |
| return italicAngle; |
| } |
| |
| /** |
| * Returns the width to be used when no width is available. |
| * @return a character width |
| */ |
| public int getMissingWidth() { |
| return missingWidth; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public FontType getFontType() { |
| return fontType; |
| } |
| |
| /** |
| * Returns the index of the first character defined in this font. |
| * @return the index of the first character |
| */ |
| public int getFirstChar() { |
| return firstChar; |
| } |
| |
| /** |
| * Returns the index of the last character defined in this font. |
| * @return the index of the last character |
| */ |
| public int getLastChar() { |
| return lastChar; |
| } |
| |
| /** |
| * Used to determine if kerning is enabled. |
| * @return True if kerning is enabled. |
| */ |
| public boolean isKerningEnabled() { |
| return useKerning; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public final boolean hasKerningInfo() { |
| return (isKerningEnabled() && (kerning != null) && !kerning.isEmpty()); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public final Map getKerningInfo() { |
| if (hasKerningInfo()) { |
| return kerning; |
| } else { |
| return java.util.Collections.EMPTY_MAP; |
| } |
| } |
| |
| /* ---- MutableFont interface ---- */ |
| |
| /** {@inheritDoc} */ |
| public void setFontName(String name) { |
| this.fontName = name; |
| } |
| |
| /** {@inheritDoc} */ |
| public void setFullName(String name) { |
| this.fullName = name; |
| } |
| |
| /** {@inheritDoc} */ |
| public void setFamilyNames(Set names) { |
| this.familyNames = new java.util.HashSet(names); |
| } |
| |
| /** |
| * Sets the font's subfamily name. |
| * @param subFamilyName the subfamily name of the font |
| */ |
| public void setFontSubFamilyName(String subFamilyName) { |
| this.fontSubName = subFamilyName; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void setEmbedFileName(String path) { |
| this.embedFileName = path; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void setEmbedResourceName(String name) { |
| this.embedResourceName = name; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void setCapHeight(int capHeight) { |
| this.capHeight = capHeight; |
| } |
| |
| /** |
| * Returns the XHeight value of the font. |
| * @param xHeight the XHeight value |
| */ |
| public void setXHeight(int xHeight) { |
| this.xHeight = xHeight; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void setAscender(int ascender) { |
| this.ascender = ascender; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void setDescender(int descender) { |
| this.descender = descender; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void setFontBBox(int[] bbox) { |
| this.fontBBox = bbox; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void setFlags(int flags) { |
| this.flags = flags; |
| } |
| |
| /** |
| * Sets the font weight. Valid values are 100, 200...800, 900. |
| * @param weight the font weight |
| */ |
| public void setWeight(int weight) { |
| weight = (weight / 100) * 100; |
| weight = Math.max(100, weight); |
| weight = Math.min(900, weight); |
| this.weight = weight; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void setStemV(int stemV) { |
| this.stemV = stemV; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void setItalicAngle(int italicAngle) { |
| this.italicAngle = italicAngle; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void setMissingWidth(int width) { |
| this.missingWidth = width; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void setFontType(FontType fontType) { |
| this.fontType = fontType; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void setFirstChar(int index) { |
| this.firstChar = index; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void setLastChar(int index) { |
| this.lastChar = index; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void setKerningEnabled(boolean enabled) { |
| this.useKerning = enabled; |
| } |
| |
| /** |
| * Sets the font resolver. Needed for URI resolution. |
| * @param resolver the font resolver |
| */ |
| public void setResolver(FontResolver resolver) { |
| this.resolver = resolver; |
| } |
| |
| /** {@inheritDoc} */ |
| public void putKerningEntry(Integer key, Map value) { |
| if (kerning == null) { |
| kerning = new java.util.HashMap(); |
| } |
| this.kerning.put(key, value); |
| } |
| |
| /** |
| * Replaces the existing kerning map with a new one. |
| * @param kerningMap the kerning map (Map<Integer, Map<Integer, Integer>, the integers are |
| * character codes) |
| */ |
| public void replaceKerningMap(Map kerningMap) { |
| if (kerningMap == null) { |
| this.kerning = Collections.EMPTY_MAP; |
| } else { |
| this.kerning = kerningMap; |
| } |
| } |
| |
| } |