org.apache.pdfbox.pdmodel.font.FontManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pdfbox Show documentation
Show all versions of pdfbox Show documentation
The Apache PDFBox library is an open source Java tool for working with PDF documents.
/*
* 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.awt.Font;
import java.awt.GraphicsEnvironment;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.pdfbox.util.ResourceLoader;
/**
* This class is used as font manager.
* @author Andreas Lehmkühler
* @version $Revision: 1.0 $
*/
public class FontManager
{
/**
* Log instance.
*/
private static final Log LOG = LogFactory.getLog(FontManager.class);
// HashMap with all known fonts
private static HashMap envFonts = new HashMap();
// the standard font
private final static String standardFont = "helvetica";
private static Properties fontMapping = new Properties();
static {
try
{
ResourceLoader.loadProperties(
"org/apache/pdfbox/resources/FontMapping.properties",
fontMapping );
}
catch( IOException io )
{
LOG.error(io,io);
throw new RuntimeException( "Error loading font mapping" );
}
loadFonts();
loadBasefontMapping();
loadFontMapping();
}
private FontManager()
{
}
/**
* Get the standard font from the environment, usually Arial or Times New Roman.
*
* @return The standard font
*
*/
public static java.awt.Font getStandardFont()
{
Font awtFont = getAwtFont(standardFont);
if (awtFont == null)
{
// PDFBOX-1069
LOG.error("Standard font '" + standardFont + "' is not part of the environment");
LOG.error("Available fonts:");
for (Font font : GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts())
{
LOG.error("\t" + font.getFontName());
}
}
return awtFont;
}
/**
* Get the font for the given fontname.
*
* @param font The name of the font.
*
* @return The font we are looking for or a similar font or null if nothing is found.
*
*/
public static java.awt.Font getAwtFont(String font)
{
String fontname = normalizeFontname(font);
if (envFonts.containsKey(fontname))
{
return envFonts.get(fontname);
}
return null;
}
/**
* Load all available fonts from the environment.
*/
private static void loadFonts()
{
for (Font font : GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts())
{
String family = normalizeFontname(font.getFamily());
String psname = normalizeFontname(font.getPSName());
if (isBoldItalic(font))
{
envFonts.put(family+"bolditalic", font);
}
else if (isBold(font))
{
envFonts.put(family+"bold", font);
}
else if (isItalic(font))
{
envFonts.put(family+"italic", font);
}
else
{
envFonts.put(family, font);
}
if (!family.equals(psname))
{
envFonts.put(normalizeFontname(font.getPSName()),font);
}
}
}
/**
* 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 boolean addFontMapping(String font, String mappedName)
{
String fontname = normalizeFontname(font);
// is there already a font mapping ?
if (envFonts.containsKey(fontname))
{
return false;
}
String mappedFontname = normalizeFontname(mappedName);
// is the mapped font available ?
if (!envFonts.containsKey(mappedFontname))
{
return false;
}
envFonts.put(fontname, envFonts.get(mappedFontname));
return true;
}
/**
* Load the mapping for the well knwon font-substitutions.
*
*/
private static void loadFontMapping()
{
boolean addedMapping = true;
// There could be some recursive mappings in the fontmapping, so that we have to
// read the list until no more additional mapping is added to it
while (addedMapping)
{
int counter = 0;
Enumeration