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/31 02:56:33 UTC

svn commit: r1621548 - in /pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font: ExternalFonts.java PDCIDFontType2.java PDTrueTypeFont.java PDType1CFont.java PDType1Font.java

Author: jahewson
Date: Sun Aug 31 00:56:32 2014
New Revision: 1621548

URL: http://svn.apache.org/r1621548
Log:
PDFBOX-2262: Improved font fallback for Linux

Modified:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/ExternalFonts.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/ExternalFonts.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/ExternalFonts.java?rev=1621548&r1=1621547&r2=1621548&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/ExternalFonts.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/ExternalFonts.java Sun Aug 31 00:56:32 2014
@@ -16,6 +16,8 @@
  */
 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;
@@ -28,6 +30,7 @@ import org.apache.commons.logging.LogFac
 import org.apache.fontbox.cff.CFFCIDFont;
 import org.apache.fontbox.cff.CFFFont;
 import org.apache.fontbox.cff.CFFType1Font;
+import org.apache.fontbox.ttf.TTFParser;
 import org.apache.fontbox.ttf.Type1Equivalent;
 import org.apache.fontbox.ttf.TrueTypeFont;
 import org.apache.fontbox.type1.Type1Font;
@@ -50,6 +53,27 @@ public final class ExternalFonts
     private static final Log log = LogFactory.getLog(ExternalFonts.class);
     private static FontProvider fontProvider;
 
+    /** TTF fallback font, used as as a last resort */
+    private static TrueTypeFont ttfFallbackFont;
+    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);
+            }
+            ttfFallbackFont = ttfParser.parseTTF(fontStream);
+        }
+        catch (IOException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
     /**
      * Sets the font service provider.
      */
@@ -76,34 +100,44 @@ public final class ExternalFonts
     {
         // substitutes for standard 14 fonts
         substitutes.put("Courier",
-                Arrays.asList("CourierNew", "CourierNewPSMT"));
+                Arrays.asList("CourierNew", "CourierNewPSMT", "LiberationMono", "NimbusMonL-Regu"));
         substitutes.put("Courier-Bold",
-                Arrays.asList("CourierNewPS-BoldMT", "CourierNew-Bold"));
+                Arrays.asList("CourierNewPS-BoldMT", "CourierNew-Bold", "LiberationMono-Bold",
+                              "NimbusMonL-Bold"));
         substitutes.put("Courier-Oblique",
-                Arrays.asList("CourierNewPS-ItalicMT","CourierNew-Italic"));
+                Arrays.asList("CourierNewPS-ItalicMT","CourierNew-Italic",
+                              "LiberationMono-Italic", "NimbusMonL-ReguObli"));
         substitutes.put("Courier-BoldOblique",
-                Arrays.asList("CourierNewPS-BoldItalicMT","CourierNew-BoldItalic"));
+                Arrays.asList("CourierNewPS-BoldItalicMT","CourierNew-BoldItalic",
+                              "LiberationMono-BoldItalic", "NimbusMonL-BoldObli"));
         substitutes.put("Helvetica",
-                Arrays.asList("ArialMT", "Arial"));
+                Arrays.asList("ArialMT", "Arial", "LiberationSans", "NimbusSanL-Regu"));
         substitutes.put("Helvetica-Bold",
-                Arrays.asList("Arial-BoldMT", "Arial-Bold"));
+                Arrays.asList("Arial-BoldMT", "Arial-Bold", "LiberationSans-Bold",
+                              "NimbusSanL-Bold"));
         substitutes.put("Helvetica-Oblique",
-                Arrays.asList("Arial-ItalicMT", "Arial-Italic", "Helvetica-Italic"));
+                Arrays.asList("Arial-ItalicMT", "Arial-Italic", "Helvetica-Italic",
+                              "LiberationSans-Italic", "NimbusSanL-ReguItal"));
         substitutes.put("Helvetica-BoldOblique",
-                Arrays.asList("Arial-BoldItalicMT", "Helvetica-BoldItalic"));
+                Arrays.asList("Arial-BoldItalicMT", "Helvetica-BoldItalic",
+                              "LiberationSans-BoldItalic", "NimbusSanL-BoldItal"));
         substitutes.put("Times-Roman",
-                Arrays.asList("TimesNewRomanPSMT", "TimesNewRoman", "TimesNewRomanPS"));
+                Arrays.asList("TimesNewRomanPSMT", "TimesNewRoman", "TimesNewRomanPS",
+                              "LiberationSerif", "NimbusRomNo9L-Regu"));
         substitutes.put("Times-Bold",
                 Arrays.asList("TimesNewRomanPS-BoldMT", "TimesNewRomanPS-Bold",
-                              "TimesNewRoman-Bold"));
+                              "TimesNewRoman-Bold", "LiberationSerif-Bold",
+                              "NimbusRomNo9L-Medi"));
         substitutes.put("Times-Italic",
                 Arrays.asList("TimesNewRomanPS-ItalicMT", "TimesNewRomanPS-Italic",
-                              "TimesNewRoman-Italic"));
+                              "TimesNewRoman-Italic", "LiberationSerif-Italic",
+                              "NimbusRomNo9L-ReguItal"));
         substitutes.put("Times-BoldItalic",
                 Arrays.asList("TimesNewRomanPS-BoldItalicMT", "TimesNewRomanPS-BoldItalic",
-                             "TimesNewRoman-BoldItalic"));
-        substitutes.put("Symbol",Arrays.asList("SymbolMT"));
-        substitutes.put("ZapfDingbats", Arrays.asList("ZapfDingbatsITC"));
+                             "TimesNewRoman-BoldItalic", "LiberationSerif-BoldItalic",
+                             "NimbusRomNo9L-MediItal"));
+        substitutes.put("Symbol",Arrays.asList("SymbolMT", "StandardSymL"));
+        substitutes.put("ZapfDingbats", Arrays.asList("ZapfDingbatsITC", "Dingbats"));
 
         // 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
@@ -165,7 +199,45 @@ public final class ExternalFonts
      * Returns the fallback font, used for rendering when no other fonts are available,
      * we attempt to find a good fallback based on the font descriptor.
      */
-    public static TrueTypeFont getFallbackFont(PDFontDescriptor fontDescriptor)
+    public static Type1Equivalent getType1FallbackFont(PDFontDescriptor fontDescriptor)
+    {
+        String fontName = getFallbackFontName(fontDescriptor);
+        Type1Equivalent type1Equivalent = getType1EquivalentFont(fontName);
+        if (type1Equivalent == null)
+        {
+            String message = fontProvider.toDebugString();
+            if (message != null)
+            {
+                // if we couldn't get a PFB font by now then there's no point continuing
+                log.error("No fallback font for '" + fontName + "', dumping debug information:");
+                log.error(message);
+            }
+            throw new IllegalStateException("No fonts available on the system for " + fontName);
+        }
+        return type1Equivalent;
+    }
+
+    /**
+     * Returns the fallback font, used for rendering when no other fonts are available,
+     * we attempt to find a good fallback based on the font descriptor.
+     */
+    public static TrueTypeFont getTrueTypeFallbackFont(PDFontDescriptor fontDescriptor)
+    {
+        String fontName = getFallbackFontName(fontDescriptor);
+        TrueTypeFont ttf = getTrueTypeFont(fontName);
+        if (ttf == null)
+        {
+            // we have to return something here as TTFs aren't strictly required on the system
+            log.error("No TTF fallback font for '" + fontName + "'");
+            return ttfFallbackFont;
+        }
+        return ttf;
+    }
+
+    /**
+     * Attempts to find a good fallback based on the font descriptor.
+     */
+    private static String getFallbackFontName(PDFontDescriptor fontDescriptor)
     {
         String fontName;
         if (fontDescriptor != null)
@@ -237,19 +309,7 @@ public final class ExternalFonts
             // if there is no FontDescriptor then we just fall back to Times Roman
             fontName = "Times-Roman";
         }
-
-        TrueTypeFont ttf = getTrueTypeFont(fontName);
-        if (ttf == null)
-        {
-            String message = fontProvider.toDebugString();
-            if (message != null)
-            {
-                log.error("No fallback font for '" + fontName + "', dumping debug information:");
-                log.error(message);
-            }
-            throw new IllegalStateException("No fonts available on the system for " + fontName);
-        }
-        return ttf;
+        return fontName;
     }
 
     /**

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java?rev=1621548&r1=1621547&r2=1621548&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java Sun Aug 31 00:56:32 2014
@@ -94,7 +94,7 @@ public class PDCIDFontType2 extends PDCI
             {
                 // fallback
                 LOG.warn("Using fallback font for " + getBaseFont());
-                ttf = ExternalFonts.getFallbackFont(getFontDescriptor());
+                ttf = ExternalFonts.getTrueTypeFallbackFont(getFontDescriptor());
             }
             isEmbedded = false;
         }

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java?rev=1621548&r1=1621547&r2=1621548&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java Sun Aug 31 00:56:32 2014
@@ -128,7 +128,7 @@ public class PDTrueTypeFont extends PDSi
             if (ttfFont == null)
             {
                 LOG.warn("Using fallback font for " + getBaseFont());
-                ttfFont = ExternalFonts.getFallbackFont(getFontDescriptor());
+                ttfFont = ExternalFonts.getTrueTypeFallbackFont(getFontDescriptor());
             }
         }
         ttf = ttfFont;

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java?rev=1621548&r1=1621547&r2=1621548&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java Sun Aug 31 00:56:32 2014
@@ -100,7 +100,7 @@ public class PDType1CFont extends PDSimp
             else
             {
                 LOG.warn("Using fallback font for " + getBaseFont());
-                type1Equivalent = ExternalFonts.getFallbackFont(getFontDescriptor());
+                type1Equivalent = ExternalFonts.getType1FallbackFont(getFontDescriptor());
             }
             isEmbedded = false;
         }

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java?rev=1621548&r1=1621547&r2=1621548&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java Sun Aug 31 00:56:32 2014
@@ -230,7 +230,7 @@ public class PDType1Font extends PDSimpl
             else
             {
                 LOG.warn("Using fallback font for " + getBaseFont());
-                type1Equivalent = ExternalFonts.getFallbackFont(getFontDescriptor());
+                type1Equivalent = ExternalFonts.getType1FallbackFont(getFontDescriptor());
             }
         }