You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2014/05/19 21:08:42 UTC

svn commit: r1595992 - in /pdfbox/trunk: fontbox/ fontbox/src/main/java/org/apache/fontbox/util/ fontbox/src/main/java/org/apache/fontbox/util/autodetect/ pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/ pdfbox/src/main/resources/org/apache/pdfbox/...

Author: lehmi
Date: Mon May 19 19:08:41 2014
New Revision: 1595992

URL: http://svn.apache.org/r1595992
Log:
PDFBOX-1689: added a font manager to find and deal with local fonts

Added:
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/FontManager.java   (with props)
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/FontDirFinder.java   (with props)
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/FontFileFinder.java   (with props)
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/MacFontDirFinder.java   (with props)
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/NativeFontDirFinder.java   (with props)
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/UnixFontDirFinder.java   (with props)
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/WindowsFontDirFinder.java   (with props)
Removed:
    pdfbox/trunk/pdfbox/src/main/resources/org/apache/pdfbox/resources/PDFBox_External_Fonts.properties
    pdfbox/trunk/pdfbox/src/main/resources/org/apache/pdfbox/resources/ttf/
Modified:
    pdfbox/trunk/fontbox/pom.xml
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java

Modified: pdfbox/trunk/fontbox/pom.xml
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/pom.xml?rev=1595992&r1=1595991&r2=1595992&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/pom.xml (original)
+++ pdfbox/trunk/fontbox/pom.xml Mon May 19 19:08:41 2014
@@ -43,6 +43,10 @@
       <artifactId>commons-logging</artifactId>
     </dependency>
     <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+    </dependency>
+    <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
     </dependency>

Added: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/FontManager.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/FontManager.java?rev=1595992&view=auto
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/FontManager.java (added)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/FontManager.java Mon May 19 19:08:41 2014
@@ -0,0 +1,291 @@
+/*
+ * 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.fontbox.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+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.ttf.NamingTable;
+import org.apache.fontbox.ttf.TTFParser;
+import org.apache.fontbox.ttf.TrueTypeFont;
+import org.apache.fontbox.util.autodetect.FontFileFinder;
+
+/**
+ * This class is used as manager for local fonts. It's based on the font manager provided by Apache FOP. see
+ * org.apache.fop.fonts.FontManager.java
+ */
+
+public class FontManager
+{
+    /**
+     * Log instance.
+     */
+    private static final Log LOG = LogFactory.getLog(FontManager.class);
+
+    private static HashMap<String, String> ttfFontfiles = new HashMap<String, String>();
+
+    private static boolean fontsLoaded = false;
+
+    // HashMap with all known true type fonts
+    private static HashMap<String, String> fontMappingTTF = new HashMap<String, String>();
+
+    private FontManager()
+    {
+    }
+
+    /**
+     * Load all available fonts from the environment.
+     */
+    private static void loadFonts()
+    {
+        try
+        {
+            FontFileFinder fontfinder = new FontFileFinder();
+            List<URL> fonts = fontfinder.find();
+            for (URL font : fonts)
+            {
+                String fontfilename = font.getPath();
+                if (fontfilename.toLowerCase().endsWith(".ttf"))
+                {
+                    try
+                    {
+                        analyzeTTF(fontfilename);
+                    }
+                    catch (IOException exception)
+                    {
+                        LOG.debug("Can't read external font: " + fontfilename, exception);
+                    }
+                }
+                else
+                {
+                    LOG.debug("Unsupported font format for external font: " + fontfilename);
+                }
+            }
+            addFontMapping(fontfinder.getCommonTTFMapping(), fontMappingTTF);
+            createFontmapping();
+        }
+        catch (IOException exception)
+        {
+            LOG.error("An error occured when collecting external fonts.", exception);
+        }
+        finally
+        {
+            fontsLoaded = true;
+        }
+    }
+
+    /**
+     * Analyze the given true type font.
+     * 
+     * @param ttfFilename the filename of the true type type
+     * @throws IOException if something went wrong
+     */
+    private static void analyzeTTF(String ttfFilename) throws IOException
+    {
+        TTFParser ttfParser = new TTFParser();
+        TrueTypeFont ttfFont = ttfParser.parseTTF(ttfFilename);
+        if (ttfFont != null)
+        {
+            NamingTable namingTable = ttfFont.getNaming();
+            String normalizedName = normalizeFontname(namingTable.getPSName());
+            ttfFontfiles.put(normalizedName, ttfFilename);
+        }
+    }
+
+    /**
+     * Normalize the fontname.
+     * 
+     * @param fontname The name of the font.
+     * 
+     * @return The normalized name of the font.
+     */
+    private static String normalizeFontname(String fontname)
+    {
+        // Terminate all whitespaces, commas and hyphens
+        String normalizedFontname = fontname.toLowerCase().replaceAll(" ", "").replaceAll(",", "")
+                .replaceAll("-", "");
+        // Terminate trailing characters up to the "+".
+        // As far as I know, these characters are used in names of embedded fonts
+        // If the embedded font can't be read, we'll try to find it here
+        if (normalizedFontname.indexOf("+") > -1)
+        {
+            normalizedFontname = normalizedFontname.substring(normalizedFontname.indexOf("+") + 1);
+        }
+        // normalize all kinds of fonttypes. There are several possible version which have to be normalized
+        // e.g. Arial,Bold Arial-BoldMT Helevtica-oblique ...
+        boolean isBold = normalizedFontname.indexOf("bold") > -1;
+        boolean isItalic = normalizedFontname.indexOf("italic") > -1
+                || normalizedFontname.indexOf("oblique") > -1;
+        normalizedFontname = normalizedFontname.toLowerCase().replaceAll("bold", "")
+                .replaceAll("italic", "").replaceAll("oblique", "");
+        if (isBold)
+        {
+            normalizedFontname += "bold";
+        }
+        if (isItalic)
+        {
+            normalizedFontname += "italic";
+        }
+        return normalizedFontname;
+    }
+
+    /**
+     * Add a font-mapping.
+     * 
+     * @param font The name of the font.
+     * 
+     * @param mappedName The name of the mapped font.
+     */
+    private static void addFontMapping(String font, String mappedName, Map<String, String> mapping)
+    {
+        String fontname = normalizeFontname(font);
+        // is there already a font mapping ?
+        if (mapping.containsKey(fontname))
+        {
+            return;
+        }
+        String mappedFontname = normalizeFontname(mappedName);
+        // is there any font with the mapped name ?
+        if (ttfFontfiles.containsKey(mappedFontname))
+        {
+            mapping.put(fontname, mappedFontname);
+        }
+        else
+        {
+            // is there any recursive mapping ?
+            if (mapping.containsKey(mappedFontname))
+            {
+                mapping.put(fontname, mapping.get(mappedFontname));
+            }
+        }
+    }
+
+    /**
+     * Add the given mappings to the font mapping.
+     * 
+     * @param fontMappingSrc the given mapping
+     */
+    private static void addFontMapping(Map<String, String> fontMappingSrc,
+            Map<String, String> fontMappingDest)
+    {
+        for (String fontname : fontMappingSrc.keySet())
+        {
+            addFontMapping(fontname, fontMappingSrc.get(fontname), fontMappingDest);
+        }
+    }
+
+    /**
+     * Search for a mapped true type font name.
+     * 
+     * @param fontname the given font name
+     * @return the mapped font name
+     */
+    private static String getMappedTTFName(String fontname)
+    {
+        String normalizedFontname = normalizeFontname(fontname);
+        if (fontMappingTTF.containsKey(normalizedFontname))
+        {
+            return fontMappingTTF.get(normalizedFontname);
+        }
+        return null;
+    }
+
+    /**
+     * Create a mapping for the some font families.
+     */
+    private static void createFontmapping()
+    {
+        addFontFamilyMapping("ArialNarrow", "Arial", fontMappingTTF);
+    }
+
+    /**
+     * Create a mapping for the given font family.
+     * 
+     * @param fontfamily the font family to be mapped
+     * @param mappedFontfamily the mapped font family
+     */
+    private static void addFontFamilyMapping(String fontfamily, String mappedFontfamily,
+            Map<String, String> mapping)
+    {
+        addFontMapping(fontfamily + ",BoldItalic", mappedFontfamily + ",BoldItalic", mapping);
+        addFontMapping(fontfamily + ",Bold", mappedFontfamily + ",Bold", mapping);
+        addFontMapping(fontfamily + ",Italic", mappedFontfamily + ",Italic", mapping);
+        addFontMapping(fontfamily, mappedFontfamily, mapping);
+    }
+
+    /**
+     * Search for a font for the given font name.
+     * 
+     * @param fontname the given font name
+     * @return the name of the mapped font
+     */
+    public static String findTTFontname(String fontname)
+    {
+        if (!fontsLoaded)
+        {
+            loadFonts();
+        }
+        String fontfile = null;
+        if (ttfFontfiles.containsKey(fontname))
+        {
+            fontfile = ttfFontfiles.get(fontname);
+        }
+        if (fontfile == null)
+        {
+            String mappedFontname = getMappedTTFName(fontname);
+            if (mappedFontname != null && ttfFontfiles.containsKey(mappedFontname))
+            {
+                fontfile = ttfFontfiles.get(mappedFontname);
+            }
+        }
+        if (fontfile == null)
+        {
+            LOG.warn("Font not found: " + fontname);
+        }
+        return fontfile;
+    }
+
+    /**
+     * Search for a true type font for the given font name.
+     * 
+     * @param fontname the given font name
+     * @return the mapped true type font
+     * @throws IOException if something went wrong
+     */
+    public static TrueTypeFont findTTFont(String fontname) throws IOException
+    {
+        String ttffontname = findTTFontname(fontname);
+        TrueTypeFont ttfFont = null;
+        if (ttffontname != null)
+        {
+            TTFParser ttfParser = new TTFParser();
+            InputStream fontStream = ResourceLoader.loadResource(ttffontname);
+            if (fontStream == null)
+            {
+                throw new IOException("Can't load external font: " + ttffontname);
+            }
+            ttfFont = ttfParser.parseTTF(fontStream);
+        }
+        return ttfFont;
+    }
+}

Propchange: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/FontManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/FontDirFinder.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/FontDirFinder.java?rev=1595992&view=auto
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/FontDirFinder.java (added)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/FontDirFinder.java Mon May 19 19:08:41 2014
@@ -0,0 +1,47 @@
+/*
+ * 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.fontbox.util.autodetect;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Implementers provide find method for searching native operating system for available fonts. This class is based on a
+ * class provided by Apache FOP. see org.apache.fop.fonts.autodetect.FontDirFinder
+ */
+public interface FontDirFinder
+{
+
+    /**
+     * Finds a list of font files.
+     * 
+     * @return list of font files.
+     * @throws IOException In case of an I/O problem
+     */
+    List<File> find() throws IOException;
+
+    /**
+     * Provides a list of platform specific ttf name mappings.
+     * 
+     * @return a fontname mapping
+     */
+    Map<String, String> getCommonTTFMapping();
+
+}

Propchange: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/FontDirFinder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/FontFileFinder.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/FontFileFinder.java?rev=1595992&view=auto
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/FontFileFinder.java (added)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/FontFileFinder.java Mon May 19 19:08:41 2014
@@ -0,0 +1,214 @@
+/*
+ * 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.fontbox.util.autodetect;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.io.DirectoryWalker;
+import org.apache.commons.io.IOCase;
+import org.apache.commons.io.filefilter.FileFilterUtils;
+import org.apache.commons.io.filefilter.IOFileFilter;
+import org.apache.commons.io.filefilter.WildcardFileFilter;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Helps to autodetect/locate available operating system fonts. This class is based on a class provided by Apache FOP.
+ * see org.apache.fop.fonts.autodetect.FontFileFinder
+ */
+public class FontFileFinder extends DirectoryWalker<URL>
+{
+
+    /**
+     * logging instance.
+     */
+    private final Log log = LogFactory.getLog(FontFileFinder.class);
+
+    private FontDirFinder fontDirFinder = null;
+
+    /**
+     * default depth limit of recursion when searching for font files.
+     */
+    public static final int DEFAULT_DEPTH_LIMIT = -1;
+
+    /**
+     * Default constructor.
+     */
+    public FontFileFinder()
+    {
+        this(DEFAULT_DEPTH_LIMIT);
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param depthLimit recursion depth limit
+     * 
+     */
+    public FontFileFinder(int depthLimit)
+    {
+        super(getDirectoryFilter(), getFileFilter(), depthLimit);
+    }
+
+    private FontDirFinder determineDirFinder()
+    {
+        final String osName = System.getProperty("os.name");
+        if (osName.startsWith("Windows"))
+        {
+            return new WindowsFontDirFinder();
+        }
+        else
+        {
+            if (osName.startsWith("Mac"))
+            {
+                return new MacFontDirFinder();
+            }
+            else
+            {
+                return new UnixFontDirFinder();
+            }
+        }
+    }
+
+    /**
+     * Font directory filter. Currently ignores hidden directories.
+     * 
+     * @return IOFileFilter font directory filter
+     */
+    protected static IOFileFilter getDirectoryFilter()
+    {
+        return FileFilterUtils.and(FileFilterUtils.directoryFileFilter(),
+                FileFilterUtils.notFileFilter(FileFilterUtils.prefixFileFilter(".")));
+    }
+
+    /**
+     * Font file filter. Currently searches for files with .ttf, .ttc, .otf, and .pfb extensions.
+     * 
+     * @return IOFileFilter font file filter
+     */
+    protected static IOFileFilter getFileFilter()
+    {
+        return FileFilterUtils.and(FileFilterUtils.fileFileFilter(), new WildcardFileFilter(
+                new String[] { "*.ttf", "*.otf", "*.pfb", "*.ttc" }, IOCase.INSENSITIVE));
+    }
+
+    /**
+     * @param directory directory to handle
+     * @param depth recursion depth
+     * @param results collection
+     * @return whether directory should be handled {@inheritDoc}
+     */
+    @Override
+    protected boolean handleDirectory(File directory, int depth, Collection<URL> results)
+    {
+        return true;
+    }
+
+    /**
+     * @param file file to handle
+     * @param depth recursion depth
+     * @param results collection {@inheritDoc}
+     */
+    @Override
+    protected void handleFile(File file, int depth, Collection<URL> results)
+    {
+        try
+        {
+            // Looks Strange, but is actually recommended over just .URL()
+            results.add(file.toURI().toURL());
+        }
+        catch (MalformedURLException e)
+        {
+            log.debug("MalformedURLException" + e.getMessage());
+        }
+    }
+
+    /**
+     * @param directory the directory being processed
+     * @param depth the current directory level
+     * @param results the collection of results objects {@inheritDoc}
+     */
+    @Override
+    protected void handleDirectoryEnd(File directory, int depth, Collection<URL> results)
+    {
+        if (log.isDebugEnabled())
+        {
+            log.debug(directory + ": found " + results.size() + " font"
+                    + ((results.size() == 1) ? "" : "s"));
+        }
+    }
+
+    /**
+     * Automagically finds a list of font files on local system.
+     * 
+     * @return List&lt;URL&gt; of font files
+     * @throws IOException io exception {@inheritDoc}
+     */
+    public List<URL> find() throws IOException
+    {
+        if (fontDirFinder == null)
+        {
+            fontDirFinder = determineDirFinder();
+        }
+        List<File> fontDirs = fontDirFinder.find();
+        List<URL> results = new java.util.ArrayList<URL>();
+        for (File dir : fontDirs)
+        {
+            super.walk(dir, results);
+        }
+        return results;
+    }
+
+    /**
+     * Searches a given directory for font files.
+     * 
+     * @param dir directory to search
+     * @return list of font files
+     * @throws IOException thrown if an I/O exception of some sort has occurred
+     */
+    public List<URL> find(String dir) throws IOException
+    {
+        List<URL> results = new java.util.ArrayList<URL>();
+        File directory = new File(dir);
+        if (directory.isDirectory())
+        {
+            super.walk(directory, results);
+        }
+        return results;
+    }
+
+    /**
+     * Provides a list of platform specific ttf name mappings.
+     * 
+     * @return a font name mapping
+     */
+    public Map<String, String> getCommonTTFMapping()
+    {
+        if (fontDirFinder == null)
+        {
+            fontDirFinder = determineDirFinder();
+        }
+        return fontDirFinder.getCommonTTFMapping();
+    }
+}

Propchange: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/FontFileFinder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/MacFontDirFinder.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/MacFontDirFinder.java?rev=1595992&view=auto
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/MacFontDirFinder.java (added)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/MacFontDirFinder.java Mon May 19 19:08:41 2014
@@ -0,0 +1,52 @@
+/*
+ * 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.fontbox.util.autodetect;
+
+import java.util.Map;
+
+/**
+ * Mac font directory finder. This class is based on a class provided by Apache FOP. see
+ * org.apache.fop.fonts.autodetect.MacFontDirFinder
+ */
+public class MacFontDirFinder extends NativeFontDirFinder
+{
+
+    /**
+     * Some guesses at possible unix font directory locations.
+     * 
+     * @return a array of possible font directory locations
+     */
+    protected String[] getSearchableDirectories()
+    {
+        return new String[] { System.getProperty("user.home") + "/Library/Fonts/", // user
+                "/Library/Fonts/", // local
+                "/System/Library/Fonts/", // system
+                "/Network/Library/Fonts/" // network
+        };
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Map<String, String> getCommonTTFMapping()
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+}

Propchange: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/MacFontDirFinder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/NativeFontDirFinder.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/NativeFontDirFinder.java?rev=1595992&view=auto
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/NativeFontDirFinder.java (added)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/NativeFontDirFinder.java Mon May 19 19:08:41 2014
@@ -0,0 +1,60 @@
+/*
+ * 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.fontbox.util.autodetect;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * Native font finder base class. This class is based on a class provided by Apache FOP. see
+ * org.apache.fop.fonts.autodetect.NativeFontDirFinder
+ */
+public abstract class NativeFontDirFinder implements FontDirFinder
+{
+
+    /**
+     * Generic method used by Mac and Unix font finders.
+     * 
+     * @return list of natively existing font directories {@inheritDoc}
+     */
+    public List<File> find()
+    {
+        List<File> fontDirList = new java.util.ArrayList<File>();
+        String[] searchableDirectories = getSearchableDirectories();
+        if (searchableDirectories != null)
+        {
+            for (int i = 0; i < searchableDirectories.length; i++)
+            {
+                File fontDir = new File(searchableDirectories[i]);
+                if (fontDir.exists() && fontDir.canRead())
+                {
+                    fontDirList.add(fontDir);
+                }
+            }
+        }
+        return fontDirList;
+    }
+
+    /**
+     * Returns an array of directories to search for fonts in.
+     * 
+     * @return an array of directories
+     */
+    protected abstract String[] getSearchableDirectories();
+
+}

Propchange: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/NativeFontDirFinder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/UnixFontDirFinder.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/UnixFontDirFinder.java?rev=1595992&view=auto
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/UnixFontDirFinder.java (added)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/UnixFontDirFinder.java Mon May 19 19:08:41 2014
@@ -0,0 +1,65 @@
+/*
+ * 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.fontbox.util.autodetect;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Unix font directory finder. This class is based on a class provided by Apache FOP. see
+ * org.apache.fop.fonts.autodetect.UnixFontDirFinder
+ */
+public class UnixFontDirFinder extends NativeFontDirFinder
+{
+
+    /**
+     * Some guesses at possible unix font directory locations.
+     * 
+     * @return a list of possible font locations
+     */
+    protected String[] getSearchableDirectories()
+    {
+        return new String[] { System.getProperty("user.home") + "/.fonts", // user
+                "/usr/local/fonts", // local
+                "/usr/local/share/fonts", // local shared
+                "/usr/share/fonts", // system
+                "/usr/X11R6/lib/X11/fonts" // X
+        };
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Map<String, String> getCommonTTFMapping()
+    {
+        HashMap<String,String> map = new HashMap<String,String>();
+        map.put("TimesNewRoman,BoldItalic","LiberationSerif-BoldItalic");
+        map.put("TimesNewRoman,Bold","LiberationSerif-Bold");
+        map.put("TimesNewRoman,Italic","LiberationSerif-Italic");
+        map.put("TimesNewRoman","LiberationSerif");
+        map.put("ArialNarrow,BoldItalic","LiberationSans-BoldItalic");
+        map.put("ArialNarrow,Italic","LiberationSans-Italic");
+        map.put("ArialNarrow,Bold","LiberationSans-Bold");
+        map.put("Arial","LiberationSans");
+        map.put("Symbol", "OpenSymbol");
+        map.put("ZapfDingbats", "Dingbats");
+        return Collections.unmodifiableMap(map);
+    }
+    
+}

Propchange: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/UnixFontDirFinder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/WindowsFontDirFinder.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/WindowsFontDirFinder.java?rev=1595992&view=auto
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/WindowsFontDirFinder.java (added)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/WindowsFontDirFinder.java Mon May 19 19:08:41 2014
@@ -0,0 +1,141 @@
+/*
+ * 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.fontbox.util.autodetect;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * FontFinder for native Windows platforms. This class is based on a class provided by Apache FOP. see
+ * org.apache.fop.fonts.autodetect.WindowsFontDirFinder
+ */
+public class WindowsFontDirFinder implements FontDirFinder
+{
+
+    /**
+     * Attempts to read windir environment variable on windows (disclaimer: This is a bit dirty but seems to work
+     * nicely).
+     */
+    private String getWinDir(String osName) throws IOException
+    {
+        Process process = null;
+        Runtime runtime = Runtime.getRuntime();
+        if (osName.startsWith("Windows 9"))
+        {
+            process = runtime.exec("command.com /c echo %windir%");
+        }
+        else
+        {
+            process = runtime.exec("cmd.exe /c echo %windir%");
+        }
+        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(
+                process.getInputStream()));
+        return bufferedReader.readLine();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @return a list of detected font files
+     */
+    public List<File> find()
+    {
+        List<File> fontDirList = new java.util.ArrayList<File>();
+        String windir = null;
+        try
+        {
+            windir = System.getProperty("env.windir");
+        }
+        catch (SecurityException e)
+        {
+            // should continue if this fails
+        }
+        String osName = System.getProperty("os.name");
+        if (windir == null)
+        {
+            try
+            {
+                windir = getWinDir(osName);
+            }
+            catch (IOException e)
+            {
+                // should continue if this fails
+            }
+        }
+        File osFontsDir = null;
+        File psFontsDir = null;
+        if (windir != null)
+        {
+            // remove any trailing '/'
+            if (windir.endsWith("/"))
+            {
+                windir = windir.substring(0, windir.length() - 1);
+            }
+            osFontsDir = new File(windir + File.separator + "FONTS");
+            if (osFontsDir.exists() && osFontsDir.canRead())
+            {
+                fontDirList.add(osFontsDir);
+            }
+            psFontsDir = new File(windir.substring(0, 2) + File.separator + "PSFONTS");
+            if (psFontsDir.exists() && psFontsDir.canRead())
+            {
+                fontDirList.add(psFontsDir);
+            }
+        }
+        else
+        {
+            String windowsDirName = osName.endsWith("NT") ? "WINNT" : "WINDOWS";
+            // look for true type font folder
+            for (char driveLetter = 'C'; driveLetter <= 'E'; driveLetter++)
+            {
+                osFontsDir = new File(driveLetter + ":" + File.separator + windowsDirName
+                        + File.separator + "FONTS");
+                if (osFontsDir.exists() && osFontsDir.canRead())
+                {
+                    fontDirList.add(osFontsDir);
+                    break;
+                }
+            }
+            // look for type 1 font folder
+            for (char driveLetter = 'C'; driveLetter <= 'E'; driveLetter++)
+            {
+                psFontsDir = new File(driveLetter + ":" + File.separator + "PSFONTS");
+                if (psFontsDir.exists() && psFontsDir.canRead())
+                {
+                    fontDirList.add(psFontsDir);
+                    break;
+                }
+            }
+        }
+        return fontDirList;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Map<String, String> getCommonTTFMapping()
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+}

Propchange: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/autodetect/WindowsFontDirFinder.java
------------------------------------------------------------------------------
    svn:eol-style = native

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=1595992&r1=1595991&r2=1595992&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 Mon May 19 19:08:41 2014
@@ -48,7 +48,6 @@ import org.apache.pdfbox.encoding.WinAns
 import org.apache.pdfbox.pdmodel.PDDocument;
 import org.apache.pdfbox.pdmodel.common.PDRectangle;
 import org.apache.pdfbox.pdmodel.common.PDStream;
-import org.apache.pdfbox.util.ResourceLoader;
 
 /**
  * This is the TrueType implementation of fonts.
@@ -60,28 +59,6 @@ public class PDTrueTypeFont extends PDSi
 {
 
     /**
-     * This is the key to a property in the PDFBox_External_Fonts.properties file to load a Font when a mapping does not
-     * exist for the current font.
-     */
-    private static final String UNKNOWN_FONT = "UNKNOWN_FONT";
-
-    private static Properties externalFonts = new Properties();
-    private static Map<String, TrueTypeFont> loadedExternalFonts = new HashMap<String, TrueTypeFont>();
-
-    static
-    {
-        try
-        {
-            ResourceLoader
-                    .loadProperties("org/apache/pdfbox/resources/PDFBox_External_Fonts.properties", externalFonts);
-        }
-        catch (IOException io)
-        {
-            throw new RuntimeException("Error loading font resources", io);
-        }
-    }
-
-    /**
      * Constructor.
      */
     public PDTrueTypeFont()
@@ -394,41 +371,6 @@ public class PDTrueTypeFont extends PDSi
     }
 
     /**
-     * Permit to load an external TTF Font program file
-     * 
-     * Created by Pascal Allain Vertical7 Inc.
-     * 
-     * @return A PDStream with the Font File program, null if fd is null
-     * @throws IOException If the font is not found
-     */
-    private TrueTypeFont getExternalFontFile2() throws IOException
-    {
-        TrueTypeFont retval = null;
-        String baseFont = getBaseFont();
-        String fontResource = externalFonts.getProperty(UNKNOWN_FONT);
-        if ((baseFont != null) && (externalFonts.containsKey(baseFont)))
-        {
-            fontResource = externalFonts.getProperty(baseFont);
-        }
-        if (fontResource != null)
-        {
-            retval = (TrueTypeFont) loadedExternalFonts.get(baseFont);
-            if (retval == null)
-            {
-                TTFParser ttfParser = new TTFParser();
-                InputStream fontStream = ResourceLoader.loadResource(fontResource);
-                if (fontStream == null)
-                {
-                    throw new IOException("Error missing font resource '" + externalFonts.get(baseFont) + "'");
-                }
-                retval = ttfParser.parseTTF(fontStream);
-                loadedExternalFonts.put(baseFont, retval);
-            }
-        }
-        return retval;
-    }
-
-    /**
      * Return the TTF font as TrueTypeFont.
      * 
      * @return the TTF font
@@ -450,7 +392,7 @@ public class PDTrueTypeFont extends PDSi
         if (trueTypeFont == null)
         {
             // check if there is a font mapping for an external font file
-            trueTypeFont = getExternalFontFile2();
+            trueTypeFont = org.apache.fontbox.util.FontManager.findTTFont(getBaseFont());
         }
         return trueTypeFont;
     }