You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ja...@apache.org on 2014/08/17 22:02:20 UTC
svn commit: r1618516 [4/6] - in /pdfbox/no-awt:
examples/src/main/java/org/apache/pdfbox/examples/pdmodel/
fontbox/src/main/java/org/apache/fontbox/afm/
fontbox/src/main/java/org/apache/fontbox/cff/
fontbox/src/main/java/org/apache/fontbox/cff/charset/...
Modified: pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/encoding/Type1Encoding.java
URL: http://svn.apache.org/viewvc/pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/encoding/Type1Encoding.java?rev=1618516&r1=1618515&r2=1618516&view=diff
==============================================================================
--- pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/encoding/Type1Encoding.java (original)
+++ pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/encoding/Type1Encoding.java Sun Aug 17 20:02:18 2014
@@ -16,28 +16,57 @@
*/
package org.apache.pdfbox.encoding;
+import org.apache.fontbox.afm.CharMetric;
+import org.apache.fontbox.afm.FontMetrics;
import org.apache.pdfbox.cos.COSBase;
+import java.util.Map;
+
/**
- * This class represents an encoding which was read from a type1 font.
- *
+ * An encoding for a Type 1 font.
*/
public class Type1Encoding extends Encoding
{
+ /**
+ * Creates an empty encoding of the given size (all elements map to .notdef).
+ */
public Type1Encoding(int size)
{
- for (int i=1;i<size;i++)
+ for (int i = 1; i < size; i++)
{
addCharacterEncoding(i, NOTDEF);
}
}
/**
- * {@inheritDoc}
+ * Creates an encoding from the given AFM font metrics.
+ *
+ * @param fontMetrics AFM font metrics.
+ */
+ public Type1Encoding(FontMetrics fontMetrics)
+ {
+ for (CharMetric nextMetric : fontMetrics.getCharMetrics())
+ {
+ addCharacterEncoding(nextMetric.getCharacterCode(), nextMetric.getName());
+ }
+ }
+
+ /**
+ * Creates an encoding from the given FontBox encoding.
+ *
+ * @param encoding FontBox encoding
*/
+ public Type1Encoding(org.apache.fontbox.encoding.Encoding encoding)
+ {
+ for (Map.Entry<Integer, String> entry : encoding.getCodeToNameMap().entrySet())
+ {
+ addCharacterEncoding(entry.getKey(), entry.getValue());
+ }
+ }
+
+ @Override
public COSBase getCOSObject()
{
return null;
}
-
}
Added: pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/ExternalFonts.java
URL: http://svn.apache.org/viewvc/pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/ExternalFonts.java?rev=1618516&view=auto
==============================================================================
--- pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/ExternalFonts.java (added)
+++ pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/ExternalFonts.java Sun Aug 17 20:02:18 2014
@@ -0,0 +1,309 @@
+/*
+ * 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.
+ */
+package org.apache.pdfbox.pdmodel.font;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.fontbox.cff.CFFCIDFont;
+import org.apache.fontbox.cff.CFFFont;
+import org.apache.fontbox.cff.CFFType1Font;
+import org.apache.fontbox.ttf.Type1Equivalent;
+import org.apache.fontbox.ttf.TTFParser;
+import org.apache.fontbox.ttf.TrueTypeFont;
+import org.apache.fontbox.type1.Type1Font;
+
+/**
+ * External font service, locates non-embedded fonts via a pluggable FontProvider.
+ *
+ * @author John Hewson
+ */
+public final class ExternalFonts
+{
+ private ExternalFonts() {}
+
+ private static FontProvider fontProvider;
+
+ /**
+ * Sets the font service provider.
+ */
+ public static void setProvider(FontProvider fontProvider)
+ {
+ ExternalFonts.fontProvider = fontProvider;
+ }
+
+ /**
+ * Gets the font service provider. Defaults to using FileSystemFontProvider.
+ */
+ private static FontProvider getProvider()
+ {
+ if (fontProvider == null)
+ {
+ fontProvider = new FileSystemFontProvider();
+ }
+ return fontProvider;
+ }
+
+ // todo: we could just rely on the system to provide Times rather than ship our own
+ /** Fallback font, used as as a last resort */
+ private static TrueTypeFont fallbackFont;
+ static
+ {
+ try
+ {
+ String name = "org/apache/pdfbox/resources/ttf/LiberationSans-Regular.ttf";
+ TTFParser ttfParser = new TTFParser();
+ InputStream fontStream = org.apache.fontbox.util.ResourceLoader.loadResource(name);
+ if (fontStream == null)
+ {
+ throw new IOException("Error loading resource: " + name);
+ }
+ fallbackFont = ttfParser.parseTTF(fontStream);
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /** Map of PostScript name substitutes, in priority order. */
+ private final static Map<String, List<String>> substitutes = new HashMap<String, List<String>>();
+ static
+ {
+ // well-known substitutes commonly found on end-user systems
+ substitutes.put("Courier",
+ Arrays.asList("CourierNew", "CourierNewPSMT"));
+ substitutes.put("Courier-Bold",
+ Arrays.asList("CourierNewPS-BoldMT", "CourierNew-Bold"));
+ substitutes.put("Courier-Oblique",
+ Arrays.asList("CourierNewPS-ItalicMT","CourierNew-Italic"));
+ substitutes.put("Helvetica",
+ Arrays.asList("ArialMT", "Arial"));
+ substitutes.put("Helvetica-Bold",
+ Arrays.asList("Arial-BoldMT", "Arial-Bold"));
+ substitutes.put("Helvetica-Oblique",
+ Arrays.asList("Arial-ItalicMT", "Arial-Italic", "Helvetica-Italic"));
+ substitutes.put("Helvetica-BoldOblique",
+ Arrays.asList("Helvetica-BoldItalic"));
+ substitutes.put("Times-Roman",
+ Arrays.asList("TimesNewRomanPSMT", "TimesNewRoman", "TimesNewRomanPS"));
+ substitutes.put("Times-Bold",
+ Arrays.asList("TimesNewRomanPS-BoldMT", "TimesNewRomanPS-Bold",
+ "TimesNewRoman-Bold"));
+ substitutes.put("Times-Italic",
+ Arrays.asList("TimesNewRomanPS-ItalicMT", "TimesNewRomanPS-Italic",
+ "TimesNewRoman-Italic"));
+ substitutes.put("Times-BoldItalic",
+ Arrays.asList("TimesNewRomanPS-BoldItalicMT", "TimesNewRomanPS-BoldItalic",
+ "TimesNewRoman-BoldItalic"));
+ substitutes.put("Symbol",Arrays.asList("SymbolMT"));
+ substitutes.put("ZapfDingbats", Arrays.asList("ZapfDingbatsITC"));
+
+ // the Adobe Supplement to the ISO 32000 specifies some alternative names for some
+ // of the standard 14 fonts, so we map these to our fallbacks above
+ substitutes.put("CourierCourierNew", substitutes.get("Courier"));
+ substitutes.put("CourierNew,Italic", substitutes.get("Courier-Oblique"));
+ substitutes.put("CourierNew,Bold", substitutes.get("Courier-Bold"));
+ substitutes.put("CourierNew,BoldItalic", substitutes.get("Courier-BoldOblique"));
+ substitutes.put("Arial", substitutes.get("Helvetica"));
+ substitutes.put("Arial,Italic", substitutes.get("Helvetica-Oblique"));
+ substitutes.put("Arial,Bold", substitutes.get("Helvetica-Bold"));
+ substitutes.put("Arial,BoldItalic", substitutes.get("Helvetica-BoldOblique"));
+ substitutes.put("TimesNewRoman", substitutes.get("Times-Roman"));
+ substitutes.put("TimesNewRoman,Italic", substitutes.get("Times-Italic"));
+ substitutes.put("TimesNewRoman,Bold", substitutes.get("Times-Bold"));
+ substitutes.put("TimesNewRoman,BoldItalic", substitutes.get("Times-BoldItalic"));
+ }
+
+ /**
+ * Adds a top-priority substitute for the given font.
+ *
+ * @param match PostScript name of the font to match
+ * @param replace PostScript name of the font to use as a replacement
+ */
+ public static void addSubstitute(String match, String replace)
+ {
+ if (!substitutes.containsKey(match))
+ {
+ substitutes.put(match, new ArrayList<String>());
+ }
+ substitutes.get(match).add(replace);
+ }
+
+ /**
+ * Returns the substitutes for a given font.
+ */
+ private static List<String> getSubstitutes(String postScriptName)
+ {
+ List<String> subs = substitutes.get(postScriptName);
+ if (subs != null)
+ {
+ return subs;
+ }
+ else
+ {
+ return Collections.emptyList();
+ }
+ }
+
+ /**
+ * Returns the fallback font, used for rendering when no other fonts are available.
+ */
+ public static TrueTypeFont getFallbackFont()
+ {
+ // todo: add FontDescriptor to the parameters for this method for "smart fallback" to
+ // standard 14 fonts via the FontProvider
+ return fallbackFont;
+ }
+
+ /**
+ * Finds a TrueType font with the given PostScript name, or a suitable substitute, or null.
+ *
+ * @param postScriptName PostScript font name
+ */
+ public static TrueTypeFont getTrueTypeFont(String postScriptName)
+ {
+ // first ask the font provider for the font
+ TrueTypeFont ttf = getProvider().getTrueTypeFont(postScriptName);
+ if (ttf == null)
+ {
+ // then try substitutes
+ for (String substituteName : getSubstitutes(postScriptName))
+ {
+ ttf = getProvider().getTrueTypeFont(substituteName);
+ if (ttf != null)
+ {
+ break;
+ }
+ }
+ }
+ return ttf;
+ }
+
+ /**
+ * Finds a TrueType font with the given PostScript name, or a suitable substitute, or null.
+ *
+ * @param postScriptName PostScript font name
+ */
+ public static Type1Font getType1Font(String postScriptName)
+ {
+ // first ask the font provider for the font
+ Type1Font t1 = getProvider().getType1Font(postScriptName);
+ if (t1 == null)
+ {
+ // then try substitutes
+ for (String substituteName : getSubstitutes(postScriptName))
+ {
+ t1 = getProvider().getType1Font(substituteName);
+ if (t1 != null)
+ {
+ break;
+ }
+ }
+ }
+ return t1;
+ }
+
+ /**
+ * Finds a CFF Type 1 font with the given PostScript name, or a suitable substitute, or null.
+ *
+ * @param postScriptName PostScript font name
+ */
+ public static CFFType1Font getCFFType1Font(String postScriptName)
+ {
+ CFFFont cff = getCFFFont(postScriptName);
+ if (cff instanceof CFFType1Font)
+ {
+ return (CFFType1Font)cff;
+ }
+ return null;
+ }
+
+ /**
+ * Finds a CFF CID-Keyed font with the given PostScript name, or a suitable substitute, or null.
+ *
+ * @param postScriptName PostScript font name
+ */
+ public static CFFCIDFont getCFFCIDFont(String postScriptName)
+ {
+ CFFFont cff = getCFFFont(postScriptName);
+ if (cff instanceof CFFCIDFont)
+ {
+ return (CFFCIDFont)cff;
+ }
+ return null;
+ }
+
+ /**
+ * Finds a CFF font with the given PostScript name, or a suitable substitute, or null.
+ *
+ * @param postScriptName PostScript font name
+ */
+ private static CFFFont getCFFFont(String postScriptName)
+ {
+ // first ask the font provider for the font
+ CFFFont cff = getProvider().getCFFFont(postScriptName);
+ if (cff == null)
+ {
+ // then try substitutes
+ for (String substituteName : getSubstitutes(postScriptName))
+ {
+ cff = getProvider().getCFFFont(substituteName);
+ if (cff != null)
+ {
+ break;
+ }
+ }
+ }
+ return cff;
+ }
+
+ /**
+ * Finds a Type 1-equivalent font with the given PostScript name, or a suitable substitute,
+ * or null. This allows a Type 1 font to be substituted with a PFB, TTF or OTF.
+ *
+ * @param postScriptName PostScript font name
+ */
+ public static Type1Equivalent getType1EquivalentFont(String postScriptName)
+ {
+ Type1Font t1 = getType1Font(postScriptName);
+ if (t1 != null)
+ {
+ return t1;
+ }
+
+ CFFType1Font cff = getCFFType1Font(postScriptName);
+ if (cff != null)
+ {
+ return cff;
+ }
+
+ TrueTypeFont ttf = getTrueTypeFont(postScriptName);
+ if (ttf != null)
+ {
+ return ttf;
+ }
+
+ return null;
+ }
+}
Added: pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/FileSystemFontProvider.java
URL: http://svn.apache.org/viewvc/pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/FileSystemFontProvider.java?rev=1618516&view=auto
==============================================================================
--- pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/FileSystemFontProvider.java (added)
+++ pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/FileSystemFontProvider.java Sun Aug 17 20:02:18 2014
@@ -0,0 +1,264 @@
+/*
+ * 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.
+ */
+package org.apache.pdfbox.pdmodel.font;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fontbox.cff.CFFFont;
+import org.apache.fontbox.cff.CFFParser;
+import org.apache.fontbox.ttf.NamingTable;
+import org.apache.fontbox.ttf.TTFParser;
+import org.apache.fontbox.ttf.TrueTypeFont;
+import org.apache.fontbox.type1.Type1Font;
+import org.apache.fontbox.util.autodetect.FontFileFinder;
+import org.apache.pdfbox.io.IOUtils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * External font provider which searches for fonts on the local filesystem.
+ *
+ * @author John Hewson
+ */
+final class FileSystemFontProvider implements FontProvider
+{
+ private static final Log LOG = LogFactory.getLog(FileSystemFontProvider.class);
+
+ // cache of font files on the system
+ private final Map<String, File> ttfFontFiles = new HashMap<String, File>();
+ private final Map<String, File> cffFontFiles = new HashMap<String, File>();
+ private final Map<String, File> type1FontFiles = new HashMap<String, File>();
+
+ // cache of loaded fonts which are in use
+ private final Map<String, TrueTypeFont> ttfFonts = new HashMap<String, TrueTypeFont>();
+ private final Map<String, CFFFont> cffFonts = new HashMap<String, CFFFont>();
+ private final Map<String, Type1Font> type1Fonts = new HashMap<String, Type1Font>();
+
+ /**
+ * Constructor.
+ */
+ FileSystemFontProvider()
+ {
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("Will search the local system for fonts");
+ }
+
+ int count = 0;
+ FontFileFinder fontFileFinder = new FontFileFinder();
+ List<URI> fonts = fontFileFinder.find();
+ for (URI font : fonts)
+ {
+ count++;
+ File fontFile = new File(font);
+ try
+ {
+ if (fontFile.getPath().toLowerCase().endsWith(".ttf") ||
+ fontFile.getPath().toLowerCase().endsWith(".otf"))
+ {
+ addOpenTypeFont(fontFile);
+ }
+ else if (fontFile.getPath().toLowerCase().endsWith(".pfb"))
+ {
+ addType1Font(fontFile);
+ }
+ }
+ catch (IOException e)
+ {
+ LOG.error("Error parsing font " + fontFile.getPath(), e);
+ }
+ }
+
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("Found " + count + " fonts on the local system");
+ }
+ }
+
+ /**
+ * Adds an OTF or TTF font to the file cache. To reduce memory, the parsed font is not cached.
+ */
+ private void addOpenTypeFont(File otfFile) throws IOException
+ {
+ TTFParser ttfParser = new TTFParser(false, true);
+ TrueTypeFont ttf = ttfParser.parseTTF(otfFile);
+ try
+ {
+ // check for 'name' table
+ NamingTable nameTable = ttf.getNaming();
+ if (nameTable == null)
+ {
+ throw new IOException("Missing 'name' table");
+ }
+
+ // read PostScript name, if any
+ if (nameTable.getPostScriptName() != null)
+ {
+ String psName = nameTable.getPostScriptName();
+
+ String format;
+ if (ttf.getTableMap().get("CFF ") != null)
+ {
+ format = "OTF";
+ cffFontFiles.put(psName, otfFile);
+ }
+ else
+ {
+ format = "TTF";
+ ttfFontFiles.put(psName, otfFile);
+ }
+
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug(format +": '" + psName + "' / '" + nameTable.getFontFamily() +
+ "' / '" + nameTable.getFontSubFamily() + "'");
+ }
+ }
+ else
+ {
+ throw new IOException("Missing 'name' entry for PostScript name");
+ }
+ }
+ finally
+ {
+ ttf.close();
+ }
+ }
+
+ /**
+ * Adds a Type 1 font to the file cache. To reduce memory, the parsed font is not cached.
+ */
+ private void addType1Font(File pfbFile) throws IOException
+ {
+ InputStream input = new FileInputStream(pfbFile);
+ try
+ {
+ Type1Font type1 = Type1Font.createWithPFB(input);
+
+ String psName = type1.getFontName();
+ type1FontFiles.put(psName, pfbFile);
+
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("PFB: '" + psName + "' / '" + type1.getFamilyName() + "' / '" +
+ type1.getWeight() + "'");
+ }
+ }
+ finally
+ {
+ input.close();
+ }
+ }
+
+ @Override
+ public TrueTypeFont getTrueTypeFont(String postScriptName)
+ {
+ TrueTypeFont ttf = ttfFonts.get(postScriptName);
+ if (ttf != null)
+ {
+ return ttf;
+ }
+
+ File file = ttfFontFiles.get(postScriptName);
+ if (file != null)
+ {
+ TTFParser ttfParser = new TTFParser(false, true);
+ try
+ {
+ ttf = ttfParser.parseTTF(file);
+ ttfFonts.put(postScriptName, ttf);
+ return ttf;
+ }
+ catch (IOException e)
+ {
+ LOG.error("Could not load font file: " + file);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public CFFFont getCFFFont(String postScriptName)
+ {
+ CFFFont cff = cffFonts.get(postScriptName);
+ if (cff != null)
+ {
+ return cff;
+ }
+
+ File file = cffFontFiles.get(postScriptName);
+ if (file != null)
+ {
+ InputStream input = null;
+ try
+ {
+ input = new FileInputStream(file);
+ byte[] bytes = IOUtils.toByteArray(input);
+ CFFParser cffParser = new CFFParser();
+ cff = cffParser.parse(bytes).get(0);
+ cffFonts.put(postScriptName, cff);
+ }
+ catch (IOException e)
+ {
+ LOG.error("Could not load font file: " + file);
+ }
+ finally
+ {
+ IOUtils.closeQuietly(input);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Type1Font getType1Font(String postScriptName)
+ {
+ Type1Font type1 = type1Fonts.get(postScriptName);
+ if (type1 != null)
+ {
+ return type1;
+ }
+
+ File file = type1FontFiles.get(postScriptName);
+ if (file != null)
+ {
+ InputStream input = null;
+ try
+ {
+ input = new FileInputStream(file);
+ type1 = Type1Font.createWithPFB(input);
+ type1Fonts.put(postScriptName, type1);
+ }
+ catch (IOException e)
+ {
+ LOG.error("Could not load font file: " + file);
+ }
+ finally
+ {
+ IOUtils.closeQuietly(input);
+ }
+ }
+ return null;
+ }
+}
Added: pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/FontProvider.java
URL: http://svn.apache.org/viewvc/pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/FontProvider.java?rev=1618516&view=auto
==============================================================================
--- pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/FontProvider.java (added)
+++ pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/FontProvider.java Sun Aug 17 20:02:18 2014
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+package org.apache.pdfbox.pdmodel.font;
+
+import org.apache.fontbox.cff.CFFFont;
+import org.apache.fontbox.ttf.TrueTypeFont;
+import org.apache.fontbox.type1.Type1Font;
+
+/**
+ * External font service provider interface.
+ *
+ * @author John Hewson
+ */
+public interface FontProvider
+{
+ /**
+ * Returns a TrueType which corresponds to the given PostScript name. If there is no
+ * suitable font, then this method will return null.
+ *
+ * @param postScriptName PostScript font name
+ */
+ public TrueTypeFont getTrueTypeFont(String postScriptName);
+
+ /**
+ * Returns a CFF font which corresponds to the given PostScript name. If there is no
+ * suitable font, then this method will return null.
+ *
+ * @param postScriptName PostScript font name
+ */
+ public CFFFont getCFFFont(String postScriptName);
+
+ /**
+ * Returns a Type 1 which corresponds to the given PostScript name. If there is no
+ * suitable font, then this method will return null.
+ *
+ * @param postScriptName PostScript font name
+ */
+ public Type1Font getType1Font(String postScriptName);
+}
Modified: pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java
URL: http://svn.apache.org/viewvc/pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java?rev=1618516&r1=1618515&r2=1618516&view=diff
==============================================================================
--- pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java (original)
+++ pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java Sun Aug 17 20:02:18 2014
@@ -55,6 +55,7 @@ public abstract class PDCIDFont extends
super(fontDictionary);
this.parent = parent;
extractWidths();
+ determineEncoding();
}
/**
@@ -108,10 +109,9 @@ public abstract class PDCIDFont extends
* @param offset The offset into the array.
* @param length The length of the data.
* @return The width is in 1000 unit of text space, ie 333 or 777
- * @throws IOException If an error occurs while parsing.
*/
@Override
- public float getFontWidth(byte[] c, int offset, int length) throws IOException
+ public float getFontWidth(byte[] c, int offset, int length)
{
float retval = getDefaultWidth();
int code = getCodeFromArray(c, offset, length);
@@ -174,11 +174,9 @@ public abstract class PDCIDFont extends
* @param length The length of the data.
*
* @return The width is in 1000 unit of text space, ie 333 or 777
- *
- * @throws IOException If an error occurs while parsing.
*/
@Override
- public float getFontHeight(byte[] c, int offset, int length) throws IOException
+ public float getFontHeight(byte[] c, int offset, int length)
{
float retval = 0;
PDFontDescriptor desc = getFontDescriptor();
@@ -212,11 +210,9 @@ public abstract class PDCIDFont extends
* This will get the average font width for all characters.
*
* @return The width is in 1000 unit of text space, ie 333 or 777
- *
- * @throws IOException If an error occurs while parsing.
*/
@Override
- public float getAverageFontWidth() throws IOException
+ public float getAverageFontWidth()
{
float totalWidths = 0.0f;
float characterCount = 0.0f;
@@ -331,7 +327,7 @@ public abstract class PDCIDFont extends
}
else
{
- LOG.debug("'" + cidSystemInfo + "' isn't a predefined CMap, most " +
+ LOG.warn("'" + cidSystemInfo + "' isn't a predefined CMap, most " +
"likely it's embedded in the pdf itself.");
}
}
Copied: pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java (from r1615712, pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0Font.java)
URL: http://svn.apache.org/viewvc/pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java?p2=pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java&p1=pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0Font.java&r1=1615712&r2=1618516&rev=1618516&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0Font.java (original)
+++ pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java Sun Aug 17 20:02:18 2014
@@ -17,66 +17,287 @@
package org.apache.pdfbox.pdmodel.font;
import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.fontbox.cff.CFFCIDFont;
+import org.apache.fontbox.cff.CFFParser;
+import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSFloat;
+import org.apache.pdfbox.io.IOUtils;
+import org.apache.pdfbox.pdmodel.common.PDMatrix;
+import org.apache.pdfbox.pdmodel.common.PDRectangle;
+import org.apache.pdfbox.pdmodel.common.PDStream;
/**
- * A Type0 CIDFont (CFF).
+ * Type 0 CIDFont (CFF).
*
* @author Ben Litchfield
+ * @author John Hewson
*/
-public class PDCIDFontType0Font extends PDCIDFont
+public class PDCIDFontType0 extends PDCIDFont
{
- private static final Log LOG = LogFactory.getLog(PDCIDFontType0Font.class);
+ private static final Log LOG = LogFactory.getLog(PDCIDFontType0.class);
+ private static final byte[] SPACE_BYTES = { (byte) 32 };
- private PDType1CFont type1CFont;
+ private CFFCIDFont cffFont = null;
+ private String fontname = null;
+ private final Map<Integer, Float> glyphWidths = new HashMap<Integer, Float>();
+ private final Map<Integer, Float> glyphHeights = new HashMap<Integer, Float>();
+ private Float avgWidth = null;
+ private PDRectangle fontBBox = null;
/**
* Constructor.
*
* @param fontDictionary The font dictionary according to the PDF specification.
*/
- public PDCIDFontType0Font(COSDictionary fontDictionary, PDType0Font parent)
+ public PDCIDFontType0(COSDictionary fontDictionary, PDType0Font parent) throws IOException
{
super(fontDictionary, parent);
+
PDFontDescriptor fd = getFontDescriptor();
- if (fd instanceof PDFontDescriptorDictionary)
+ byte[] bytes = null;
+ if (fd != null && fd instanceof PDFontDescriptorDictionary) // <-- todo: must be true
{
- PDFontDescriptorDictionary fdd = (PDFontDescriptorDictionary) fd;
- if (fdd.getFontFile3() != null)
+ PDStream ff3Stream = ((PDFontDescriptorDictionary) fd).getFontFile3();
+ if (ff3Stream != null)
{
- try
- {
- type1CFont = new PDType1CFont(dict);
- }
- catch (IOException exception)
- {
- LOG.error("Can't create the embedded CFF-font", exception);
- }
+ bytes = IOUtils.toByteArray(ff3Stream.createInputStream());
+ }
+ }
+
+ if (bytes != null)
+ {
+ // embedded
+ CFFParser cffParser = new CFFParser();
+ cffFont = (CFFCIDFont)cffParser.parse(bytes).get(0);
+ }
+ else
+ {
+ // substitute
+ cffFont = ExternalFonts.getCFFCIDFont(getBaseFont());
+
+ if (cffFont == null)
+ {
+ // todo: log message + substitute? But what would we substitute with?
+ throw new UnsupportedOperationException("not implemented: missing CFF");
}
}
+
+ // cache the font name
+ fontname = cffFont.getName();
}
/**
- * Returns the embedded Type1CFont.
- *
- * @return the Type1C font
+ * Returns the embedded CFF CIDFont.
+ */
+ public CFFCIDFont getCFFCIDFont()
+ {
+ return cffFont;
+ }
+
+ @Override
+ public String encode(byte[] bytes, int offset, int length) throws IOException
+ {
+ // a CIDFont does not contain an encoding, instead the CMap defines this mapping
+ int code = getCodeFromArray(bytes, offset, length);
+ String character = getCMap().lookupCID(code);
+
+ if (character == null)
+ {
+ LOG.error("No character for code " + (bytes[offset] & 0xff) + " in " + fontname);
+ return null;
+ }
+ return character;
+ }
+
+ @Override
+ public int encodeToCID(byte[] bytes, int offset, int length)
+ {
+ if (length > 2)
+ {
+ return -1;
+ }
+ int code = bytes[offset] & 0xff;
+ if (length == 2)
+ {
+ code = code * 256 + bytes[offset + 1] & 0xff;
+ }
+ return code;
+ }
+
+ @Override
+ public float getFontWidth(byte[] bytes, int offset, int length)
+ {
+ int cid = codeToCID(bytes, offset, length);
+ if (cid == 0 && !Arrays.equals(SPACE_BYTES, bytes))
+ {
+ LOG.error("No name for code " + (bytes[offset] & 0xff) + " in " + fontname);
+ return 0;
+ }
+
+ Float width = glyphWidths.get(cid);
+ if (width == null)
+ {
+ width = getCharacterWidth(cid);
+ glyphWidths.put(cid, width);
+ }
+
+ return width;
+ }
+
+ @Override
+ public float getFontHeight(byte[] bytes, int offset, int length)
+ {
+ int cid = codeToCID(bytes, offset, length);
+ if (cid == 0)
+ {
+ LOG.error("No CID for code " + (bytes[offset] & 0xff) + " in " + fontname);
+ return 0;
+ }
+
+ float height = 0;
+ if (!glyphHeights.containsKey(cid))
+ {
+ height = getCharacterHeight(cid);
+ glyphHeights.put(cid, height);
+ }
+ return height;
+ }
+
+ // helper
+ private int codeToCID(byte[] bytes, int offset, int length)
+ {
+ return getCMap().lookupCID(bytes, offset, length);
+ }
+
+ /**
+ * Returns the CID for the given character code. If not found then CID 0 is returned.
+ *
+ * @param code character code
+ * @return CID
*/
- public PDType1CFont getType1CFont()
+ public int codeToCID(int code)
+ {
+ //int length = getCMap().hasTwoByteMappings() ? 2 : 1; // todo: HACK: see PDFStreamEngine
+ int length = 2; // todo: HACK always use 2-byte mappings
+
+ byte[] bytes;
+ // todo: actually codes may be variable length (1 to 4 bytes)
+ if (length == 1)
+ {
+ bytes = new byte[] { (byte)(code & 0xff) };
+ }
+ else
+ {
+ bytes = new byte[] { (byte)(code >> 8 & 0xff), (byte)(code & 0xff) };
+ }
+ return getCMap().lookupCID(bytes, 0, length);
+ }
+
+ @Override
+ public float getStringWidth(String string) throws IOException
+ {
+ // todo: CMap currently has no methods which can do this correctly
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ public float getAverageFontWidth()
+ {
+ if (avgWidth == null)
+ {
+ avgWidth = getAverageCharacterWidth();
+ }
+ return avgWidth;
+ }
+
+ @Override
+ public PDRectangle getFontBoundingBox() throws IOException
+ {
+ if (fontBBox == null)
+ {
+ fontBBox = new PDRectangle(cffFont.getFontBBox());
+ }
+ return fontBBox;
+ }
+
+ @Override
+ public PDMatrix getFontMatrix()
{
- return type1CFont;
+ if (fontMatrix == null)
+ {
+ List<Number> numbers = cffFont.getFontMatrix();
+ if (numbers != null && numbers.size() == 6)
+ {
+ COSArray array = new COSArray();
+ for (Number number : numbers)
+ {
+ array.add(new COSFloat(number.floatValue()));
+ }
+ fontMatrix = new PDMatrix(array);
+ }
+ else
+ {
+ // todo: the font should always have a Matrix, so why fallback?
+ super.getFontMatrix();
+ }
+ }
+ return fontMatrix;
}
-
+
+ // todo: this is a replacement for FontMetrics method
+ private float getCharacterWidth(int cid)
+ {
+ try
+ {
+ return cffFont.getType2CharString(cid).getWidth();
+ }
+ catch (IOException e)
+ {
+ // todo: HACK
+ LOG.error(e);
+ return 0;
+ }
+ }
+
+ // todo: this is a replacement for FontMetrics method
+ // todo: but in FontMetrics this method actually gets the advance-y for vertical mode
+ private float getCharacterHeight(int cid)
+ {
+ try
+ {
+ return (float)cffFont.getType2CharString(cid).getBounds().getHeight();
+ }
+ catch (IOException e)
+ {
+ // todo: HACK
+ LOG.error(e);
+ return 0;
+ }
+ }
+
+ // todo: this is a replacement for FontMetrics method
+ private float getAverageCharacterWidth()
+ {
+ // todo: not implemented, highly suspect
+ return 500;
+ }
+
@Override
public void clear()
{
super.clear();
- if (type1CFont != null)
+ if (cffFont != null)
{
- type1CFont.clear();
- type1CFont = null;
+ //cffFont.clear();
+ cffFont = null;
}
}
}
Copied: pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java (from r1615712, pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Font.java)
URL: http://svn.apache.org/viewvc/pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java?p2=pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java&p1=pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Font.java&r1=1615712&r2=1618516&rev=1618516&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Font.java (original)
+++ pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java Sun Aug 17 20:02:18 2014
@@ -31,14 +31,15 @@ import org.apache.pdfbox.io.IOUtils;
import org.apache.pdfbox.pdmodel.common.PDStream;
/**
- * A Type2 CIDFont (TrueType).
+ * Type 2 CIDFont (TrueType).
*
* @author Ben Litchfield
*/
-public class PDCIDFontType2Font extends PDCIDFont
+public class PDCIDFontType2 extends PDCIDFont
{
- private static final Log LOG = LogFactory.getLog(PDCIDFontType2Font.class);
+ private static final Log LOG = LogFactory.getLog(PDCIDFontType2.class);
+ private final TrueTypeFont ttf;
private Boolean hasCIDToGIDMap = null;
private Boolean hasIdentityCIDToGIDMap = null;
private int[] cid2gid = null;
@@ -48,9 +49,34 @@ public class PDCIDFontType2Font extends
*
* @param fontDictionary The font dictionary according to the PDF specification.
*/
- public PDCIDFontType2Font(COSDictionary fontDictionary, PDType0Font parent)
+ public PDCIDFontType2(COSDictionary fontDictionary, PDType0Font parent) throws IOException
{
super(fontDictionary, parent);
+
+ PDFontDescriptorDictionary fd = (PDFontDescriptorDictionary) getFontDescriptor();
+ PDStream ff2Stream = fd.getFontFile2();
+
+ if (ff2Stream != null)
+ {
+ // embedded
+ TTFParser ttfParser = new TTFParser(true);
+ ttf = ttfParser.parseTTF(ff2Stream.createInputStream());
+ }
+ else
+ {
+ // substitute
+ TrueTypeFont ttfSubstitute = ExternalFonts.getTrueTypeFont(getBaseFont());
+ if (ttfSubstitute != null)
+ {
+ ttf = ttfSubstitute;
+ }
+ else
+ {
+ // fallback
+ LOG.warn("Using fallback font for " + getBaseFont());
+ ttf = ExternalFonts.getFallbackFont();
+ }
+ }
}
/**
@@ -124,23 +150,6 @@ public class PDCIDFontType2Font extends
}
}
- /**
- * Returns the CID2GID mapping if present.
- *
- * @return the CID2GID mapping
- */
- public int[] getCID2GID()
- {
- if (hasCIDToGIDMap())
- {
- if (cid2gid == null)
- {
- readCIDToGIDMapping();
- }
- }
- return cid2gid;
- }
-
private void readCIDToGIDMapping()
{
COSBase map = dict.getDictionaryObject(COSName.CID_TO_GID_MAP);
@@ -169,26 +178,15 @@ public class PDCIDFontType2Font extends
}
/**
- * Returns the embedded true type font.
- *
- * @return the true type font
- * @throws IOException exception if something went wrong
+ * Returns the embedded or substituted TrueType font.
*/
- public TrueTypeFont getTTFFont() throws IOException
+ public TrueTypeFont getTrueTypeFont()
{
- PDFontDescriptorDictionary fd = (PDFontDescriptorDictionary) getFontDescriptor();
- PDStream ff2Stream = fd.getFontFile2();
- TrueTypeFont trueTypeFont = null;
- if (ff2Stream != null)
- {
- TTFParser ttfParser = new TTFParser(true);
- trueTypeFont = ttfParser.parseTTF(ff2Stream.createInputStream());
- }
- return trueTypeFont;
+ return ttf;
}
@Override
- public float getFontWidth(byte[] c, int offset, int length) throws IOException
+ public float getFontWidth(byte[] c, int offset, int length)
{
// a suitable mapping is needed to address the correct width value
int code = getCodeFromArray(c, offset, length);
Modified: pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java
URL: http://svn.apache.org/viewvc/pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java?rev=1618516&r1=1618515&r2=1618516&view=diff
==============================================================================
--- pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java (original)
+++ pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java Sun Aug 17 20:02:18 2014
@@ -26,7 +26,6 @@ import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.fontbox.afm.FontMetric;
import org.apache.fontbox.cmap.CMap;
import org.apache.fontbox.cmap.CMapParser;
import org.apache.pdfbox.cos.COSArray;
@@ -172,7 +171,6 @@ public abstract class PDFont implements
protected PDFont(COSDictionary fontDictionary)
{
dict = fontDictionary;
- determineEncoding();
}
/**
@@ -189,14 +187,7 @@ public abstract class PDFont implements
{
fontDescriptor = new PDFontDescriptorDictionary(fd);
}
- else
- {
- FontMetric afm = getAFM();
- if (afm != null)
- {
- fontDescriptor = new PDFontDescriptorAFM(afm);
- }
- }
+ // todo: NOTE: null return value here if fine, because we override this method
}
return fontDescriptor;
}
@@ -220,7 +211,7 @@ public abstract class PDFont implements
}
catch (IOException exception)
{
- LOG.debug("Debug: Could not find encoding for " + encodingName);
+ LOG.warn("Debug: Could not find encoding for " + encodingName);
}
}
else if (encoding instanceof COSDictionary)
@@ -301,20 +292,14 @@ public abstract class PDFont implements
* @param offset The offset into the array.
* @param length The length of the data.
* @return The width is in 1000 unit of text space, ie 333 or 777
- * @throws IOException If an error occurs while parsing.
*/
- public float getFontWidth(byte[] c, int offset, int length) throws IOException
+ public float getFontWidth(byte[] c, int offset, int length)
{
int code = getCodeFromArray(c, offset, length);
Float fontWidth = fontSizes.get(code);
if (fontWidth == null)
{
fontWidth = getFontWidth(code);
- if (fontWidth <= 0)
- {
- // TODO should this be in PDType1Font??
- fontWidth = getFontWidthFromAFMFile(code);
- }
fontSizes.put(code, fontWidth);
}
return fontWidth;
@@ -327,61 +312,46 @@ public abstract class PDFont implements
* @param offset The offset into the array.
* @param length The length of the data.
* @return The height is in 1000 unit of text space, ie 333 or 777
- * @throws IOException If an error occurs while parsing.
*/
- public float getFontHeight(byte[] c, int offset, int length) throws IOException
+ public float getFontHeight(byte[] c, int offset, int length)
{
// maybe there is already a precalculated value
- if (avgFontHeight > 0)
+ PDFontDescriptor desc = getFontDescriptor();
+ if (desc != null)
{
- return avgFontHeight;
- }
- float retval = 0;
- FontMetric metric = getAFM();
- if (metric != null)
- {
- int code = getCodeFromArray(c, offset, length);
- Encoding encoding = getFontEncoding();
- String characterName = encoding.getName(code);
- retval = metric.getCharacterHeight(characterName);
- }
- else
- {
- PDFontDescriptor desc = getFontDescriptor();
- if (desc != null)
+ // the following values are all more or less accurate at least all are average
+ // values. Maybe we'll find another way to get those value for every single glyph
+ // in the future if needed
+ PDRectangle fontBBox = desc.getFontBoundingBox();
+ float retval = 0;
+ if (fontBBox != null)
{
- // the following values are all more or less accurate at least all are average
- // values. Maybe we'll find another way to get those value for every single glyph
- // in the future if needed
- PDRectangle fontBBox = desc.getFontBoundingBox();
- if (fontBBox != null)
- {
- retval = fontBBox.getHeight() / 2;
- }
- if (retval == 0)
- {
- retval = desc.getCapHeight();
- }
- if (retval == 0)
- {
- retval = desc.getAscent();
- }
- if (retval == 0)
+ retval = fontBBox.getHeight() / 2;
+ }
+ if (retval == 0)
+ {
+ retval = desc.getCapHeight();
+ }
+ if (retval == 0)
+ {
+ retval = desc.getAscent();
+ }
+ if (retval == 0)
+ {
+ retval = desc.getXHeight();
+ if (retval > 0)
{
- retval = desc.getXHeight();
- if (retval > 0)
- {
- retval -= desc.getDescent();
- }
+ retval -= desc.getDescent();
}
- avgFontHeight = retval;
}
+ avgFontHeight = retval;
+ return retval;
}
- return retval;
+ return 0;
}
/**
- * This will get the width of this string for this font.
+ * Returns the width of the given Unicode string.
*
* @param string The string to get the width of.
* @return The width of the string in 1000 units of text space, ie 333 567...
@@ -402,9 +372,9 @@ public abstract class PDFont implements
* This will get the average font width for all characters.
*
* @return The width is in 1000 unit of text space, ie 333 or 777
- * @throws IOException If an error occurs while parsing.
*/
- public float getAverageFontWidth() throws IOException
+ // todo: this method is highly suspicious, the average glyph width is not usually a good metric
+ public float getAverageFontWidth()
{
float average;
if (avgFontWidth != 0.0f)
@@ -435,7 +405,7 @@ public abstract class PDFont implements
}
else
{
- average = getAverageFontWidthFromAFMFile();
+ average = 0;
}
avgFontWidth = average;
}
@@ -462,52 +432,6 @@ public abstract class PDFont implements
}
/**
- * This will attempt to get the font width from an AFM file.
- *
- * @param code The character code we are trying to get.
- * @return The font width from the AFM file.
- * @throws IOException if we cannot find the width.
- */
- private float getFontWidthFromAFMFile(int code) throws IOException
- {
- float retval = 0;
- FontMetric metric = getAFM();
- if (metric != null)
- {
- String characterName = fontEncoding.getName(code);
- retval = metric.getCharacterWidth(characterName);
- }
- return retval;
- }
-
- /**
- * This will attempt to get the average font width from an AFM file.
- *
- * @return The average font width from the AFM file.
- * @throws IOException if we cannot find the width.
- */
- private float getAverageFontWidthFromAFMFile() throws IOException
- {
- float retval = 0;
- FontMetric metric = getAFM();
- if (metric != null)
- {
- retval = metric.getAverageCharacterWidth();
- }
- return retval;
- }
-
- /**
- * This will get an AFM object if one exists.
- *
- * @return The afm object from the name.
- */
- protected FontMetric getAFM()
- {
- return null;
- }
-
- /**
* Encode the given value using the CMap of the font.
*
* @param code the code to encode.
@@ -538,7 +462,7 @@ public abstract class PDFont implements
}
/**
- * This will perform the encoding of a character if needed.
+ * Returns the Unicode character(s) for a given character code.
*
* @param c The character to encode.
* @param offset The offset into the array to get the data
@@ -871,7 +795,7 @@ public abstract class PDFont implements
/**
* Returns the toUnicode mapping if present.
- *
+ *
* @return the CMap representing the toUnicode mapping
*/
public CMap getToUnicodeCMap()
@@ -881,7 +805,7 @@ public abstract class PDFont implements
/**
* Returns the CMap if present.
- *
+ *
* @return the CMap representing the character encoding
*/
public CMap getCMap()
@@ -907,4 +831,10 @@ public abstract class PDFont implements
{
return this.getCOSObject().hashCode();
}
+
+ @Override
+ public String toString()
+ {
+ return getClass().getSimpleName() + " " + getBaseFont();
+ }
}
Modified: pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontDescriptorAFM.java
URL: http://svn.apache.org/viewvc/pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontDescriptorAFM.java?rev=1618516&r1=1618515&r2=1618516&view=diff
==============================================================================
--- pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontDescriptorAFM.java (original)
+++ pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontDescriptorAFM.java Sun Aug 17 20:02:18 2014
@@ -17,30 +17,26 @@
package org.apache.pdfbox.pdmodel.font;
import java.io.IOException;
-
-import org.apache.fontbox.afm.FontMetric;
-
+import org.apache.fontbox.afm.FontMetrics;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
-
import org.apache.fontbox.util.BoundingBox;
/**
* This class represents the font descriptor when the font information
* is coming from an AFM file.
*
- * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
- * @version $Revision: 1.3 $
+ * @author Ben Litchfield
*/
public class PDFontDescriptorAFM extends PDFontDescriptor
{
- private FontMetric afm;
+ private FontMetrics afm;
/**
* Constructor.
*
* @param afmFile The AFM file.
*/
- public PDFontDescriptorAFM( FontMetric afmFile )
+ public PDFontDescriptorAFM( FontMetrics afmFile )
{
afm = afmFile;
}
Modified: pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontDescriptorDictionary.java
URL: http://svn.apache.org/viewvc/pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontDescriptorDictionary.java?rev=1618516&r1=1618515&r2=1618516&view=diff
==============================================================================
--- pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontDescriptorDictionary.java (original)
+++ pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontDescriptorDictionary.java Sun Aug 17 20:02:18 2014
@@ -42,16 +42,16 @@ public class PDFontDescriptorDictionary
private int flags = -1;
/**
- * Constructor.
+ * Package-private constructor, for internal PDFBox use only.
*/
- public PDFontDescriptorDictionary()
+ PDFontDescriptorDictionary()
{
dic = new COSDictionary();
dic.setItem( COSName.TYPE, COSName.FONT_DESC );
}
/**
- * Constructor.
+ * Creates a PDFontDescriptor from a COS dictionary.
*
* @param desc The wrapped COS Dictionary.
*/
Modified: pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontFactory.java
URL: http://svn.apache.org/viewvc/pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontFactory.java?rev=1618516&r1=1618515&r2=1618516&view=diff
==============================================================================
--- pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontFactory.java (original)
+++ pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontFactory.java Sun Aug 17 20:02:18 2014
@@ -18,6 +18,7 @@ package org.apache.pdfbox.pdmodel.font;
import java.io.IOException;
+import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.commons.logging.Log;
@@ -53,6 +54,14 @@ public class PDFontFactory
COSName subType = dictionary.getCOSName(COSName.SUBTYPE);
if (COSName.TYPE1.equals(subType))
{
+ COSBase fd = dictionary.getDictionaryObject(COSName.FONT_DESC);
+ if (fd != null && fd instanceof COSDictionary)
+ {
+ if (((COSDictionary)fd).containsKey(COSName.FONT_FILE3))
+ {
+ return new PDType1CFont(dictionary);
+ }
+ }
return new PDType1Font(dictionary);
}
else if (COSName.MM_TYPE1.equals(subType))
@@ -101,17 +110,17 @@ public class PDFontFactory
COSName type = dictionary.getCOSName(COSName.TYPE, COSName.FONT);
if (!COSName.FONT.equals(type))
{
- throw new IOException("Expected 'Font' dictionary but found '" + type.getName() + "'");
+ throw new IllegalArgumentException("Expected 'Font' dictionary but found '" + type.getName() + "'");
}
COSName subType = dictionary.getCOSName(COSName.SUBTYPE);
if (COSName.CID_FONT_TYPE0.equals(subType))
{
- return new PDCIDFontType0Font(dictionary, parent);
+ return new PDCIDFontType0(dictionary, parent);
}
else if (COSName.CID_FONT_TYPE2.equals(subType))
{
- return new PDCIDFontType2Font(dictionary, parent);
+ return new PDCIDFontType2(dictionary, parent);
}
else
{
Modified: pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDMMType1Font.java
URL: http://svn.apache.org/viewvc/pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDMMType1Font.java?rev=1618516&r1=1618515&r2=1618516&view=diff
==============================================================================
--- pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDMMType1Font.java (original)
+++ pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDMMType1Font.java Sun Aug 17 20:02:18 2014
@@ -17,7 +17,8 @@
package org.apache.pdfbox.pdmodel.font;
import org.apache.pdfbox.cos.COSDictionary;
-import org.apache.pdfbox.cos.COSName;
+
+import java.io.IOException;
/**
* Type 1 Multiple Master Font.
@@ -27,19 +28,11 @@ import org.apache.pdfbox.cos.COSName;
public class PDMMType1Font extends PDType1Font
{
/**
- * Constructor.
- */
- public PDMMType1Font()
- {
- dict.setItem(COSName.SUBTYPE, COSName.MM_TYPE1);
- }
-
- /**
- * Constructor.
+ * Creates an MMType1Font from a Font dictionary in a PDF.
*
- * @param fontDictionary The font dictionary according to the PDF specification.
+ * @param fontDictionary font dictionary
*/
- public PDMMType1Font(COSDictionary fontDictionary)
+ public PDMMType1Font(COSDictionary fontDictionary) throws IOException
{
super(fontDictionary);
}
Modified: pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java
URL: http://svn.apache.org/viewvc/pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java?rev=1618516&r1=1618515&r2=1618516&view=diff
==============================================================================
--- pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java (original)
+++ pdfbox/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java Sun Aug 17 20:02:18 2014
@@ -20,39 +20,18 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fontbox.ttf.CMAPEncodingEntry;
import org.apache.fontbox.ttf.CMAPTable;
-import org.apache.fontbox.ttf.GlyphData;
-import org.apache.fontbox.ttf.GlyphTable;
-import org.apache.fontbox.ttf.HeaderTable;
-import org.apache.fontbox.ttf.HorizontalHeaderTable;
-import org.apache.fontbox.ttf.HorizontalMetricsTable;
-import org.apache.fontbox.ttf.NameRecord;
-import org.apache.fontbox.ttf.NamingTable;
-import org.apache.fontbox.ttf.OS2WindowsMetricsTable;
-import org.apache.fontbox.ttf.PostScriptTable;
import org.apache.fontbox.ttf.TTFParser;
import org.apache.fontbox.ttf.TrueTypeFont;
-import org.apache.fontbox.util.SystemFontManager;
import org.apache.pdfbox.cos.COSDictionary;
-import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.encoding.Encoding;
import org.apache.pdfbox.encoding.MacOSRomanEncoding;
-import org.apache.pdfbox.encoding.WinAnsiEncoding;
-import org.apache.pdfbox.io.IOUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
-import org.apache.pdfbox.pdmodel.common.COSArrayList;
-import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.common.PDStream;
/**
@@ -94,331 +73,58 @@ public class PDTrueTypeFont extends PDFo
*
* @param fontDictionary The font dictionary according to the PDF specification.
*/
- public PDTrueTypeFont(COSDictionary fontDictionary) throws IOException
+ public PDTrueTypeFont(COSDictionary fontDictionary) throws IOException
{
super(fontDictionary);
- getTTFFont(); // load the font file
- }
-
- /**
- * Creates a new TrueType font for embedding.
- */
- private PDTrueTypeFont(PDDocument document, InputStream ttfStream) throws IOException
- {
- dict.setItem(COSName.SUBTYPE, COSName.TRUE_TYPE);
-
- PDStream stream = new PDStream(document, ttfStream, false);
- stream.getStream().setInt(COSName.LENGTH1, stream.getByteArray().length); // todo: wrong?
- stream.addCompression();
-
- // only support winansi encoding right now, should really
- // just use Identity-H with unicode mapping
- Encoding encoding = new WinAnsiEncoding(); // fixme: read encoding from TTF
-
- this.fontEncoding = encoding;
- dict.setItem(COSName.ENCODING, encoding.getCOSObject());
-
- // as the stream was close within the PDStream constructor, we have to recreate it
- InputStream stream2 = null;
- PDFontDescriptorDictionary fd;
- try
- {
- stream2 = stream.createInputStream();
- ttf = new TTFParser().parseTTF(stream2);
- fd = makeFontDescriptor(ttf);
- }
- finally
- {
- IOUtils.closeQuietly(stream2);
- }
-
- fd.setFontFile2(stream);
- dict.setItem(COSName.FONT_DESC, fd);
- }
- @Override
- public PDFontDescriptor getFontDescriptor()
- {
- if (fontDescriptor == null)
+ PDFontDescriptorDictionary fd = (PDFontDescriptorDictionary) super.getFontDescriptor();
+ if (fd != null)
{
- COSDictionary fd = (COSDictionary) dict.getDictionaryObject(COSName.FONT_DESC);
- if (fd != null)
+ PDStream ff2Stream = fd.getFontFile2();
+ if (ff2Stream != null)
{
- fontDescriptor = new PDFontDescriptorDictionary(fd);
- }
- else
- {
- fontDescriptor = makeFontDescriptor(ttf);
+ // embedded
+ TTFParser ttfParser = new TTFParser(true);
+ ttf = ttfParser.parseTTF(ff2Stream.createInputStream());
}
}
- return fontDescriptor;
- }
-
- // creates a new font descriptor dictionary for the given TTF
- private PDFontDescriptorDictionary makeFontDescriptor(TrueTypeFont ttf)
- {
- PDFontDescriptorDictionary fd = new PDFontDescriptorDictionary();
- NamingTable naming = ttf.getNaming();
- List<NameRecord> records = naming.getNameRecords();
- for (NameRecord nr : records)
- {
- if (nr.getNameId() == NameRecord.NAME_POSTSCRIPT_NAME)
- {
- dict.setName(COSName.BASE_FONT, nr.getString());
- fd.setFontName(nr.getString());
- }
- else if (nr.getNameId() == NameRecord.NAME_FONT_FAMILY_NAME)
- {
- fd.setFontFamily(nr.getString());
- }
- }
-
- OS2WindowsMetricsTable os2 = ttf.getOS2Windows();
- boolean isSymbolic = false;
- switch (os2.getFamilyClass())
- {
- case OS2WindowsMetricsTable.FAMILY_CLASS_SYMBOLIC:
- isSymbolic = true;
- break;
- case OS2WindowsMetricsTable.FAMILY_CLASS_SCRIPTS:
- fd.setScript(true);
- break;
- case OS2WindowsMetricsTable.FAMILY_CLASS_CLAREDON_SERIFS:
- case OS2WindowsMetricsTable.FAMILY_CLASS_FREEFORM_SERIFS:
- case OS2WindowsMetricsTable.FAMILY_CLASS_MODERN_SERIFS:
- case OS2WindowsMetricsTable.FAMILY_CLASS_OLDSTYLE_SERIFS:
- case OS2WindowsMetricsTable.FAMILY_CLASS_SLAB_SERIFS:
- fd.setSerif(true);
- break;
- }
-
- switch (os2.getWidthClass())
- {
- case OS2WindowsMetricsTable.WIDTH_CLASS_ULTRA_CONDENSED:
- fd.setFontStretch("UltraCondensed");
- break;
- case OS2WindowsMetricsTable.WIDTH_CLASS_EXTRA_CONDENSED:
- fd.setFontStretch("ExtraCondensed");
- break;
- case OS2WindowsMetricsTable.WIDTH_CLASS_CONDENSED:
- fd.setFontStretch("Condensed");
- break;
- case OS2WindowsMetricsTable.WIDTH_CLASS_SEMI_CONDENSED:
- fd.setFontStretch("SemiCondensed");
- break;
- case OS2WindowsMetricsTable.WIDTH_CLASS_MEDIUM:
- fd.setFontStretch("Normal");
- break;
- case OS2WindowsMetricsTable.WIDTH_CLASS_SEMI_EXPANDED:
- fd.setFontStretch("SemiExpanded");
- break;
- case OS2WindowsMetricsTable.WIDTH_CLASS_EXPANDED:
- fd.setFontStretch("Expanded");
- break;
- case OS2WindowsMetricsTable.WIDTH_CLASS_EXTRA_EXPANDED:
- fd.setFontStretch("ExtraExpanded");
- break;
- case OS2WindowsMetricsTable.WIDTH_CLASS_ULTRA_EXPANDED:
- fd.setFontStretch("UltraExpanded");
- break;
- }
- fd.setFontWeight(os2.getWeightClass());
- fd.setSymbolic(isSymbolic);
- fd.setNonSymbolic(!isSymbolic);
-
- // todo retval.setItalic
- // todo retval.setAllCap
- // todo retval.setSmallCap
- // todo retval.setForceBold
-
- HeaderTable header = ttf.getHeader();
- PDRectangle rect = new PDRectangle();
- float scaling = 1000f / header.getUnitsPerEm();
- rect.setLowerLeftX(header.getXMin() * scaling);
- rect.setLowerLeftY(header.getYMin() * scaling);
- rect.setUpperRightX(header.getXMax() * scaling);
- rect.setUpperRightY(header.getYMax() * scaling);
- fd.setFontBoundingBox(rect);
-
- HorizontalHeaderTable hHeader = ttf.getHorizontalHeader();
- fd.setAscent(hHeader.getAscender() * scaling);
- fd.setDescent(hHeader.getDescender() * scaling);
-
- GlyphTable glyphTable = ttf.getGlyph();
- GlyphData[] glyphs = glyphTable.getGlyphs();
-
- PostScriptTable ps = ttf.getPostScript();
- fd.setFixedPitch(ps.getIsFixedPitch() > 0);
- fd.setItalicAngle(ps.getItalicAngle());
-
- String[] names = ps.getGlyphNames();
-
- if (names != null)
- {
- for (int i = 0; i < names.length; i++)
- {
- // if we have a capital H then use that, otherwise use the tallest letter
- if (names[i].equals("H"))
- {
- fd.setCapHeight(glyphs[i].getBoundingBox().getUpperRightY() / scaling);
- }
- if (names[i].equals("x"))
- {
- fd.setXHeight(glyphs[i].getBoundingBox().getUpperRightY() / scaling);
- }
- }
- }
-
- // hmm there does not seem to be a clear definition for StemV,
- // this is close enough and I am told it doesn't usually get used.
- fd.setStemV(fd.getFontBoundingBox().getWidth() * .13f);
-
- CMAPTable cmapTable = ttf.getCMAP();
- CMAPEncodingEntry[] cmaps = cmapTable.getCmaps();
-
- CMAPEncodingEntry uniMap = getCmapSubtable(cmaps, CMAPTable.PLATFORM_UNICODE,
- CMAPTable.ENCODING_UNICODE_2_0_FULL);
- if (uniMap == null)
- {
- uniMap = getCmapSubtable(cmaps, CMAPTable.PLATFORM_UNICODE,
- CMAPTable.ENCODING_UNICODE_2_0_BMP);
- }
- if (uniMap == null)
- {
- uniMap = getCmapSubtable(cmaps, CMAPTable.PLATFORM_WINDOWS,
- CMAPTable.ENCODING_WIN_UNICODE);
- }
- if (uniMap == null)
- {
- // Microsoft's "Recommendations for OpenType Fonts" says that "Symbol" encoding
- // actually means "Unicode, non-standard character set"
- uniMap = getCmapSubtable(cmaps, CMAPTable.PLATFORM_WINDOWS,
- CMAPTable.ENCODING_WIN_SYMBOL);
- }
- if (uniMap == null)
- {
- // there should always be a usable cmap, if this happens we haven't tried hard enough
- // to find one. Furthermore, if we loaded the font from disk then we should've checked
- // first to see that it had a suitable cmap before calling makeFontDescriptor
- throw new IllegalArgumentException("ttf: no suitable cmap for font '" +
- ttf.getNaming().getFontFamily() + "', found: " + Arrays.toString(cmaps));
- }
-
- if (this.getFontEncoding() == null)
+ // substitute
+ if (ttf == null)
{
- // todo: calling this.getFontEncoding() doesn't work if the font is loaded
- // from the local system, because it relies on the FontDescriptor!
- // We make do for now by returning an incomplete descriptor pending further
- // refactoring of PDFont#determineEncoding().
- return fd;
+ ttf = ExternalFonts.getTrueTypeFont(getBaseFont());
}
+ // todo: put the fallback here? (i.e. make this class fallback-aware - cleaner)
- Map<Integer, String> codeToName = this.getFontEncoding().getCodeToNameMap();
-
- int firstChar = Collections.min(codeToName.keySet());
- int lastChar = Collections.max(codeToName.keySet());
-
- HorizontalMetricsTable hMet = ttf.getHorizontalMetrics();
- int[] widthValues = hMet.getAdvanceWidth();
- // some monospaced fonts provide only one value for the width
- // instead of an array containing the same value for every glyphid
- boolean isMonospaced = fd.isFixedPitch() || widthValues.length == 1;
- int nWidths = lastChar - firstChar + 1;
- List<Integer> widths = new ArrayList<Integer>(nWidths);
- // use the first width as default
- // proportional fonts -> width of the .notdef character
- // monospaced-fonts -> the first width
- int defaultWidth = Math.round(widthValues[0] * scaling);
- for (int i = 0; i < nWidths; i++)
- {
- widths.add(defaultWidth);
- }
- // Encoding singleton to have acces to the chglyph name to
- // unicode cpoint point mapping of Adobe's glyphlist.txt
- Encoding glyphlist = WinAnsiEncoding.INSTANCE;
-
- // A character code is mapped to a glyph name via the provided font encoding
- // Afterwards, the glyph name is translated to a glyph ID.
- // For details, see PDFReference16.pdf, Section 5.5.5, p.401
- //
- for (Entry<Integer, String> e : codeToName.entrySet())
- {
- String name = e.getValue();
- // pdf code to unicode by glyph list.
- if (!name.equals(".notdef"))
- {
- String c = glyphlist.getCharacter(name);
- int charCode = c.codePointAt(0);
- int gid = uniMap.getGlyphId(charCode);
- if (gid != 0)
- {
- if (isMonospaced)
- {
- widths.set(e.getKey() - firstChar, defaultWidth);
- }
- else
- {
- widths.set(e.getKey() - firstChar,
- Math.round(widthValues[gid] * scaling));
- }
- }
- }
- }
- dict.setItem(COSName.WIDTHS, COSArrayList.converterToCOSArray(widths));
- dict.setInt(COSName.FIRST_CHAR, firstChar);
- dict.setInt(COSName.LAST_CHAR, lastChar);
-
- return fd;
+ determineEncoding();
}
/**
- * Returns the "cmap" subtable for the given platform and encoding, or null.
+ * Creates a new TrueType font for embedding.
*/
- private CMAPEncodingEntry getCmapSubtable(CMAPEncodingEntry[] cmaps,
- int platformId, int platformEncodingId)
+ private PDTrueTypeFont(PDDocument document, InputStream ttfStream) throws IOException
+ {
+ PDTrueTypeFontEmbedder embedder = new PDTrueTypeFontEmbedder(document, dict, ttfStream);
+ fontEncoding = embedder.getFontEncoding();
+ ttf = embedder.getTrueTypeFont();
+ }
+
+ @Override
+ public PDFontDescriptor getFontDescriptor()
{
- for (CMAPEncodingEntry cmap : cmaps)
+ if (super.getFontDescriptor() == null)
{
- if (cmap.getPlatformId() == platformId &&
- cmap.getPlatformEncodingId() == platformEncodingId)
- {
- return cmap;
- }
+ // todo: this is an experiment: we now allow this to be null (i.e. we no longer synthesise)
+ //fontDescriptor = makeFontDescriptor(ttf);
}
- return null;
+ return fontDescriptor;
}
/**
- * Return the TTF font as TrueTypeFont.
- *
- * @return the TTF font
- * @throws IOException If there is an error loading the data
+ * Returns the embedded or substituted TrueType font.
*/
- public TrueTypeFont getTTFFont() throws IOException
+ public TrueTypeFont getTrueTypeFont()
{
- if (ttf == null)
- {
- PDFontDescriptorDictionary fd = (PDFontDescriptorDictionary) super.getFontDescriptor();
- if (fd != null)
- {
- PDStream ff2Stream = fd.getFontFile2();
- if (ff2Stream != null)
- {
- TTFParser ttfParser = new TTFParser(true);
- ttf = ttfParser.parseTTF(ff2Stream.createInputStream());
- }
- }
- if (ttf == null)
- {
- // check if there is a font mapping for an external font file
- ttf = SystemFontManager.findTTFont(getBaseFont());
- }
- if (ttf == null)
- {
- ttf = PDFFontManager.getTrueTypeFallbackFont();
- }
- }
return ttf;
}
@@ -434,25 +140,13 @@ public class PDTrueTypeFont extends PDFo
}
else
{
- TrueTypeFont ttf;
- try
+ int code = getGIDForCharacterCode(charCode);
+ width = ttf.getAdvanceWidth(code);
+ int unitsPerEM = ttf.getUnitsPerEm();
+ // do we have to scale the width
+ if (unitsPerEM != 1000)
{
- ttf = getTTFFont();
- if (ttf != null)
- {
- int code = getGIDForCharacterCode(charCode);
- width = ttf.getAdvanceWidth(code);
- int unitsPerEM = ttf.getUnitsPerEm();
- // do we have to scale the width
- if (unitsPerEM != 1000)
- {
- width *= 1000f / unitsPerEM;
- }
- }
- }
- catch (IOException exception)
- {
- width = 250;
+ width *= 1000f / unitsPerEM;
}
advanceWidths.put(charCode, width);
}
@@ -567,15 +261,6 @@ public class PDTrueTypeFont extends PDFo
return;
}
- try
- {
- getTTFFont();
- }
- catch(IOException exception)
- {
- LOG.error("Can't read the true type font", exception);
- }
-
CMAPTable cmapTable = ttf.getCMAP();
if (cmapTable != null)
{
@@ -615,9 +300,6 @@ public class PDTrueTypeFont extends PDFo
cmapMacintoshSymbol = null;
cmapInitialized = false;
ttf = null;
- if (advanceWidths != null)
- {
- advanceWidths.clear();
- }
+ advanceWidths.clear();
}
}