Save This Page
Home » pdfbox-1.1.0-src » org.apache.pdfbox.pdmodel.font » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   package org.apache.pdfbox.pdmodel.font;
   18   
   19   import java.io.IOException;
   20   import java.util.Enumeration;
   21   import java.util.HashMap;
   22   import java.util.Properties;
   23   
   24   import org.apache.pdfbox.util.ResourceLoader;
   25   
   26   /**
   27    *  This class is used as font manager.
   28    *  @author <a href="mailto:andreas@lehmi.de">Andreas Lehmkühler</a>
   29    *  @version $Revision: 1.0 $
   30    */
   31   
   32   public class FontManager 
   33   {
   34   
   35       // HashMap with all known fonts
   36       private static HashMap envFonts = new HashMap();
   37       // the standard font
   38       private static String standardFont = null;
   39       private static Properties fontMapping = new Properties(); 
   40       
   41       static {
   42           try
   43           {
   44               ResourceLoader.loadProperties( "Resources/FontMapping.properties", fontMapping );
   45           }
   46           catch( IOException io )
   47           {
   48               io.printStackTrace();
   49               throw new RuntimeException( "Error loading font mapping" );
   50           }
   51           loadFonts();
   52           loadFontMapping();
   53           loadBasefontMapping();
   54           setStandardFont();
   55       }
   56       
   57       private FontManager() 
   58       {
   59       }
   60       /**
   61        * Get the standard font from the environment, usually Arial or Times New Roman. 
   62        *
   63        * @return The standard font 
   64        * 
   65        */
   66       public static java.awt.Font getStandardFont() 
   67       {
   68           if (standardFont != null)
   69           {
   70               return getAwtFont(standardFont);
   71           }
   72           return null;
   73       }
   74       
   75       /**
   76        * Get the font for the given fontname.
   77        *
   78        * @param font The name of the font.
   79        *
   80        * @return The font we are looking for or a similar font or null if nothing is found.
   81        * 
   82        */
   83       public static java.awt.Font getAwtFont(String font) 
   84       {
   85           String fontname = normalizeFontname(font);
   86           if (envFonts.containsKey(fontname))
   87           {
   88               return (java.awt.Font)envFonts.get(fontname);
   89           }
   90           return null;
   91       }
   92   
   93       /**
   94        * Load all available fonts from the environment.
   95        */
   96       private static void loadFonts() 
   97       {
   98           java.awt.Font[] allFonts = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
   99           int numberOfFonts = allFonts.length;
  100           for (int i=0;i<numberOfFonts;i++) 
  101           {
  102               java.awt.Font font = allFonts[i];
  103               String family = normalizeFontname(font.getFamily());
  104               String psname = normalizeFontname(font.getPSName());
  105               if (isBoldItalic(font)) 
  106               {
  107                   envFonts.put(family+"bolditalic", font);
  108               }
  109               else if (isBold(font)) 
  110               {
  111                   envFonts.put(family+"bold", font);
  112               }
  113               else if (isItalic(font)) 
  114               {
  115                   envFonts.put(family+"italic", font);
  116               }
  117               else 
  118               { 
  119                   envFonts.put(family, font);
  120               }
  121               if (!family.equals(psname)) 
  122               {
  123                   envFonts.put(normalizeFontname(font.getPSName()),font);
  124               }
  125           }
  126       }
  127   
  128       private static void setStandardFont() 
  129       {
  130           // One of the following fonts will be the standard-font 
  131           if (envFonts.containsKey("arial"))
  132           {
  133               standardFont = "arial";
  134           }
  135           else if (envFonts.containsKey("timesnewroman"))
  136           {
  137               standardFont = "timesnewroman";
  138           }
  139       }
  140       
  141       /**
  142        * Normalize the fontname.
  143        *
  144        * @param fontname The name of the font.
  145        *
  146        * @return The normalized name of the font.
  147        * 
  148        */
  149       private static String normalizeFontname(String fontname) 
  150       {
  151           // Terminate all whitespaces, commas and hyphens
  152           String normalizedFontname = fontname.toLowerCase().replaceAll(" ","").replaceAll(",","").replaceAll("-","");
  153           // Terminate trailing characters up to the "+".
  154           // As far as I know, these characters are used in names of embedded fonts
  155           // If the embedded font can't be read, we'll try to find it here
  156           if (normalizedFontname.indexOf("+") > -1)
  157           {
  158               normalizedFontname = normalizedFontname.substring(normalizedFontname.indexOf("+")+1);
  159           }
  160           // normalize all kinds of fonttypes. There are several possible version which have to be normalized
  161           // e.g. Arial,Bold Arial-BoldMT Helevtica-oblique ...
  162           boolean isBold = normalizedFontname.indexOf("bold") > -1;
  163           boolean isItalic = normalizedFontname.indexOf("italic") > -1 || normalizedFontname.indexOf("oblique") > -1;
  164           normalizedFontname = normalizedFontname.toLowerCase().replaceAll("bold" , "")
  165               .replaceAll("italic" , "").replaceAll("oblique" , "");
  166           if (isBold)
  167           {
  168               normalizedFontname += "bold";
  169           }
  170           if (isItalic)
  171           {
  172               normalizedFontname += "italic";
  173           }
  174           return normalizedFontname;
  175       }
  176       
  177       
  178       /**
  179        * Add a font-mapping.
  180        *
  181        * @param font The name of the font.
  182        *
  183        * @param mappedName The name of the mapped font.
  184        * 
  185        */
  186       private static boolean addFontMapping(String font, String mappedName) 
  187       {
  188           String fontname = normalizeFontname(font);
  189           // is there already a font mapping ?
  190           if (envFonts.containsKey(fontname))
  191           {
  192               return false;
  193           }
  194           String mappedFontname = normalizeFontname(mappedName);
  195           // is the mapped font available ?
  196           if (!envFonts.containsKey(mappedFontname))
  197           {
  198               return false;
  199           }
  200           envFonts.put(fontname, envFonts.get(mappedFontname));
  201           return true;
  202       }
  203       
  204       /**
  205        * Load the mapping for the well knwon font-substitutions.
  206        *
  207        */
  208       private static void loadFontMapping() 
  209       {
  210           boolean addedMapping = true;
  211           // There could be some recursive mappings in the fontmapping, so that we have to 
  212           // read the list until no more additional mapping is added to it 
  213           while (addedMapping) 
  214           {
  215               int counter = 0;
  216               Enumeration keys = fontMapping.keys();
  217               while (keys.hasMoreElements()) 
  218               {
  219                   String key = (String)keys.nextElement();
  220                   if (addFontMapping(key,(String)fontMapping.get(key)))
  221                   {
  222                       counter++;
  223                   }
  224               }
  225               if (counter == 0)
  226               {
  227                   addedMapping = false;
  228               }
  229           }
  230       }
  231   
  232       /**
  233        * Mapping for the basefonts.
  234        */
  235       private static void loadBasefontMapping() 
  236       {
  237           addFontMapping("Times-Roman","TimesNewRoman");
  238           addFontMapping("Times-Bold","TimesNewRoman,Bold");
  239           addFontMapping("Times-Italic","TimesNewRoman,Italic");
  240           addFontMapping("Times-BoldItalic","TimesNewRoman,Bold,Italic");
  241           addFontMapping("Helvetica-Oblique","Helvetica,Italic");
  242           addFontMapping("Helvetica-BoldOblique","Helvetica,Bold,Italic");
  243           addFontMapping("Courier-Oblique","Courier,Italic");
  244           addFontMapping("Courier-BoldOblique","Courier,Bold,Italic");
  245       }
  246   
  247       /**
  248        * Try to determine if the font has both a BOLD and an ITALIC-type.
  249        *
  250        * @param name The font.
  251        *
  252        * @return font has BOLD and ITALIC-type or not
  253        */
  254       private static boolean isBoldItalic(java.awt.Font font) 
  255       {
  256           return isBold(font) && isItalic(font);
  257       }
  258       
  259       /**
  260        * Try to determine if the font has a BOLD-type.
  261        *
  262        * @param name The font.
  263        *
  264        * @return font has BOLD-type or not
  265        */
  266       private static boolean isBold(java.awt.Font font) 
  267       {
  268           String name = font.getName().toLowerCase();
  269           if (name.indexOf("bold") > -1)
  270           {
  271               return true;
  272           }
  273           String psname = font.getPSName().toLowerCase();
  274           if (psname.indexOf("bold") > -1)
  275           {
  276               return true;
  277           }
  278           return false;
  279       }
  280       
  281       /**
  282        * Try to determine if the font has an ITALIC-type.
  283        *
  284        * @param name The font.
  285        *
  286        * @return font has ITALIC-type or not
  287        */
  288       private static boolean isItalic(java.awt.Font font) 
  289       {
  290           String name = font.getName().toLowerCase();
  291           // oblique is the same as italic
  292           if (name.indexOf("italic") > -1 || name.indexOf("oblique") > -1)
  293           {
  294               return true;
  295           }
  296           String psname = font.getPSName().toLowerCase();
  297           if (psname.indexOf("italic") > -1 || psname.indexOf("oblique") > -1)
  298           {
  299               return true;
  300           }
  301           return false;
  302       }
  303   }

Save This Page
Home » pdfbox-1.1.0-src » org.apache.pdfbox.pdmodel.font » [javadoc | source]