All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jpedal.fonts.FontMappings Maven / Gradle / Ivy

There is a newer version: 7.15.25
Show newest version
/*
 * ===========================================
 * Java Pdf Extraction Decoding Access Library
 * ===========================================
 *
 * Project Info:  http://www.idrsolutions.com
 * Help section for developers at http://www.idrsolutions.com/support/
 *
 * (C) Copyright 1997-2017 IDRsolutions and Contributors.
 *
 * This file is part of JPedal/JPDF2HTML5
 *
 @LICENSE@
 *
 * ---------------
 * FontMappings.java
 * ---------------
 */
package org.jpedal.fonts;

import java.awt.GraphicsEnvironment;
import java.io.*;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.jpedal.PdfDecoderInt;
import org.jpedal.exception.PdfFontException;
import org.jpedal.io.ObjectStore;
import org.jpedal.parser.DecoderOptions;
import org.jpedal.utils.LogWriter;
import org.jpedal.utils.Strip;

/**
 * Holds Maps which are used to map font names onto actual fonts and files
 */
public final class FontMappings {

    /**
     * ensure fonts setup only once
     */
    public static boolean fontsInitialised;

    /**
     * font to use in preference to Lucida
     */
    public static String defaultFont;

    /**
     * flag to show if there must be a mapping value (program exits if none
     * found)
     */
    public static boolean enforceFontSubstitution;

    /**
     * used to remap fonts onto truetype fonts (set internally)
     */
    public static Map fontSubstitutionTable;

    /**
     * hold details of all fonts
     */
    public static Map fontPropertiesTable;

    public static Map fontPropertiesTableType;

    public static Map fontPropertiesTablePath;

    /**
     * used to ensure substituted fonts unique
     */
    public static Map fontPossDuplicates;

    /**
     * used to store number for subfonts in TTC
     */
    public static Map fontSubstitutionFontID;

    /**
     * used to remap fonts onto truetype fonts (set internally)
     */
    public static Map fontSubstitutionLocation = new ConcurrentHashMap();

    /**
     * used to remap fonts onto truetype fonts (set internally)
     */
    public static Map fontSubstitutionAliasTable = new ConcurrentHashMap();

    /**
     * only upload all fonts once
     */
    private static boolean fontsSet;

    private static final String separator = System.getProperty("file.separator");

    /**
     * put fonts in variable so can be altered if needed by Client
     */
    public static String[] defaultFontDirs = {"C:/windows/fonts/", "C:/winNT/fonts/",
            "/Library/Fonts/",
            //"/System/Library/Fonts/",  ms 20111013 commented out as breaks forms with Zapf
            "/usr/share/fonts/truetype/msttcorefonts/",
            //"/usr/share/fonts/truetype/",
            //"/windows/D/Windows/Fonts/"
            "usr/local/Fonts/",
    };
    /**
     * determine how font substitution is done
     */
    private static int fontSubstitutionMode = PdfDecoderInt.SUBSTITUTE_FONT_USING_FILE_NAME;
    //private static int fontSubstitutionMode=PdfDecoderInt.SUBSTITUTE_FONT_USING_POSTSCRIPT_NAME;
    //private static int fontSubstitutionMode=PdfDecoderInt.SUBSTITUTE_FONT_USING_FULL_FONT_NAME;
    //private static int fontSubstitutionMode=PdfDecoderInt.SUBSTITUTE_FONT_USING_FAMILY_NAME;
    //private static int fontSubstitutionMode=PdfDecoderInt.SUBSTITUTE_FONT_USING_POSTSCRIPT_NAME_USE_FAMILY_NAME_IF_DUPLICATES;

    private FontMappings() {
    }

    /**
     * used internally to pick uo org.jpedal.fontmaps property and set
     */
    public static void initFonts() {

        // pick up D options and use settings

        try {
            final String fontMaps = System.getProperty("org.jpedal.fontmaps");

            if (fontMaps != null) {
                final StringTokenizer fontPaths = new StringTokenizer(fontMaps, ",");

                while (fontPaths.hasMoreTokens()) {

                    final String fontPath = fontPaths.nextToken();
                    final StringTokenizer values = new StringTokenizer(fontPath, "=:");

                    final int count = values.countTokens() - 1;
                    final String[] nameInPDF = new String[count];
                    final String key = values.nextToken();
                    for (int i = 0; i < count; i++) {
                        nameInPDF[i] = values.nextToken();
                    }

                    setSubstitutedFontAliases(key, nameInPDF); //$NON-NLS-1$

                }
            }

        } catch (final Exception e) {
            LogWriter.writeLog("Unable to read org.jpedal.fontmaps " + e.getMessage());
        }

        // pick up D options and use settings

        try {
            final String fontDirs = System.getProperty("org.jpedal.fontdirs");
            String failed = null;
            if (fontDirs != null) {
                failed = FontMappings.addFonts(fontDirs, failed);
            }
            if (failed != null) {
                LogWriter.writeLog("Could not find " + failed);
            }
        } catch (final Exception e) {
            LogWriter.writeLog("Unable to read FontDirs " + e.getMessage());
        }
    }

    /**
     * used to ensure we load once
     */
    private static final Map isLiberationLoaded = new HashMap();

    public static void addLiberationAsFallBackFont(final String family, final String path) throws IOException {

        if (isLiberationLoaded.containsKey(family)) {
            return;
        }

        isLiberationLoaded.put(family, path);

        checkFontTablesInitialised();

        final String[] fontNames = {"-Regular", "-Bold", "-Italic", "-BoldItalic"};
        final int fontCount = fontNames.length;

        for (int i = 0; i < fontCount; i++) {

            final String type = "/TrueType";
            final String fontName = family + fontNames[i];

            final String rawPath = "org/jpedal/res/" + path + "/" + fontName + ".ttf";
            final String outPath = ObjectStore.temp_dir + fontName + ".ttf";

            final InputStream url = FontMappings.class.getClassLoader().getResourceAsStream(rawPath);
            final BufferedOutputStream to = new BufferedOutputStream(new FileOutputStream(outPath));

            ObjectStore.copy(url, to);
            to.close();

            fontSubstitutionTable.put(fontName, type);
            fontSubstitutionLocation.put(fontName, outPath);

            //store details under file
            fontPropertiesTableType.put(fontName, StandardFonts.TRUETYPE);
            fontPropertiesTablePath.put(fontName, outPath);

        } /**/
    }

    /**
     * set mode to use when substituting fonts (default is to use Filename (ie arial.ttf)
     * Options are  SUBSTITUTE_* values from PdfDecoder
     */
    public static void setFontSubstitutionMode(final int mode) {
        fontSubstitutionMode = mode;
    }

    /**
     * set mode to use when substituting fonts (default is to use Filename (ie arial.ttf)
     * Options are  SUBSTITUTE_* values from PdfDecoder
     */
    public static int getFontSubstitutionMode() {
        return fontSubstitutionMode;
    }

    /**
     * allows a number of fonts to be mapped onto an actual font and provides a
     * way around slightly differing font naming when substituting fonts - So if
     * arialMT existed on the target machine and the PDF contained arial and
     * helvetica (which you wished to replace with arialmt), you would use the
     * following code -
     * 
* String[] aliases={"arial","helvetica"}; * currentPdfDecoder.setSubstitutedFontAliases("arialmt",aliases); - *
* comparison is case-insensitive and file type/ending should not be * included - For use in conjunction with -Dorg.jpedal.fontdirs options which allows * user to pass a set of comma separated directories with Truetype fonts * (directories do not need to exist so can be multi-platform setting) */ public static void setSubstitutedFontAliases(final String fontFileName, final String[] aliases) { if (aliases != null) { final String name = fontFileName.toLowerCase(); String alias; for (final String aliase : aliases) { alias = aliase.toLowerCase(); if (!alias.equals(name)) { fontSubstitutionAliasTable.put(alias, name); } } } } /** * takes a comma separated list of font directories and add to substitution */ public static String addFonts(final String fontDirs, final String failed) { final StringTokenizer fontPaths = new StringTokenizer(fontDirs, ","); while (fontPaths.hasMoreTokens()) { String fontPath = fontPaths.nextToken(); if (!fontPath.endsWith("/") && !fontPath.endsWith("\\")) { fontPath += separator; } //LogWriter.writeLog("Looking in " + fontPath + " for TT fonts"); addTTDir(fontPath, failed); } return failed; } public static void dispose() { fontSubstitutionTable = null; fontPropertiesTable = null; fontPropertiesTableType = null; fontPropertiesTablePath = null; fontPossDuplicates = null; fontSubstitutionFontID = null; fontSubstitutionLocation = null; fontSubstitutionAliasTable = null; } /** * add a truetype font directory and contents to substitution */ public static String addTTDir(final String fontPath, String failed) { checkFontTablesInitialised(); final File currentDir = new File(fontPath); if ((currentDir.exists()) && (currentDir.isDirectory())) { final String[] files = currentDir.list(); if (files != null) { for (final String currentFont : files) { addFontFile(currentFont, fontPath); } } } else { if (failed == null) { failed = fontPath; } else { failed = failed + ',' + fontPath; } } return failed; } /** * add a list of settings to map common fonts which can be substituted onto correct platform settings for Windows/MAC/Linux so JPedal * will try to use the fonts on the computer if possible to produce most accurate display. */ public static void setFontReplacements() { //this is where we setup specific font mapping to use fonts on local machines //note different settigns for Win, linux, MAC //general final String[] aliases6 = {/*"AcArial"}; //,/**/"acarialunicodems__cn"}; //,"acarial,bold"}; setSubstitutedFontAliases("adobeheitistd-regular", aliases6); //platform settings if (DecoderOptions.isRunningOnMac) { //Courier (CourierNew) both on Mac and different setSubstitutedFontAliases("Courier italic", new String[]{"Courier-Oblique"}); setSubstitutedFontAliases("Courier bold", new String[]{"Courier-Bold"}); setSubstitutedFontAliases("Courier bold italic", new String[]{"Courier-BoldOblique"}); setSubstitutedFontAliases("Courier new italic", new String[]{"CourierNew,italic", "CourierStd-Oblique", "CourierNewPS-ItalicMT"}); setSubstitutedFontAliases("Courier new bold", new String[]{"CourierNew,Bold", "Courier-Bold", "CourierStd-Bold", "CourierNewPS-BoldMT"}); setSubstitutedFontAliases("Courier new bold italic", new String[]{"CourierNew-BoldOblique", "CourierStd-BoldOblique", "CourierNewPS-BoldItalicMT"}); setSubstitutedFontAliases("Courier new", new String[]{"CourierNew", "Courier", "CourierStd", "CourierNewPSMT"}); //Helvetica (Arial) setSubstitutedFontAliases("arial", new String[]{"Helvetica", "arialmt"}); setSubstitutedFontAliases("arial italic", new String[]{"arial-italic", "arial-italicmt", "Helvetica-Oblique", "Arial,Italic"}); setSubstitutedFontAliases("arial bold", new String[]{"arial-boldmt,bold", "arial-boldmt", "Helvetica-Bold", "Arial,bold"}); setSubstitutedFontAliases("arial bold italic", new String[]{"Arial-BoldItalicMT", "Helvetica-BoldOblique"}); //Arial Narrow - not actually one of fonts but very common so added setSubstitutedFontAliases("arial Narrow", new String[]{"ArialNarrow"}); //called ArialNarrow in PDF, needs to be arialn for Windows setSubstitutedFontAliases("arial Narrow italic", new String[]{"ArialNarrow-italic"}); setSubstitutedFontAliases("arial Narrow bold", new String[]{"ArialNarrow-bold", "ArialNarrow,Bold"}); setSubstitutedFontAliases("arial Narrow bold italic", new String[]{"ArialNarrow-bolditalic"}); //Times/TimesNewRoman setSubstitutedFontAliases("times new roman bold", new String[]{"Times-Bold", "TimesNewRoman,Bold", "TimesNewRomanPS-BoldMT"}); setSubstitutedFontAliases("times new roman bold italic", new String[]{"Times-BoldItalic", "TimesNewRoman,BoldItalic", "TimesNewRomanPS-BoldItalicMT"}); setSubstitutedFontAliases("times new roman italic", new String[]{"Times-Italic", "TimesNewRoman,Italic", "TimesNewRomanPS-ItalicMT"}); setSubstitutedFontAliases("times new roman", new String[]{"Times-Roman", "TimesNewRoman", "Times", "TimesNewRomanPSMT"}); setSubstitutedFontAliases("wingdings", new String[]{"ZapfDingbats", "ZaDb"}); //default at present for others as well } else { //if(PdfDecoder.isRunningOnWindows){ //Courier (CourierNew) setSubstitutedFontAliases("Couri", new String[]{"Courier-Oblique", "CourierNew,italic", "CourierStd-Oblique", "CourierNewPS-ItalicMT"}); setSubstitutedFontAliases("Courbd", new String[]{"Courier-Bold", "CourierNew,Bold", "CourierStd-Bold", "CourierNewPS-BoldMT"}); setSubstitutedFontAliases("Courbi", new String[]{"Courier-BoldOblique", "CourierNew-BoldOblique", "CourierStd-BoldOblique", "CourierNewPS-BoldItalicMT"}); setSubstitutedFontAliases("Cour", new String[]{"CourierNew", "Courier", "CourierStd", "CourierNewPSMT", "CourierNewPSMT"}); //Helvetica (Arial) setSubstitutedFontAliases("arial", new String[]{"Helvetica", "arialmt", "ArialNarrow"}); setSubstitutedFontAliases("ariali", new String[]{"arial-italic", "arial-italicmt", "Helvetica-Oblique", "Arial,Italic", "ArialNarrow-Italic"}); setSubstitutedFontAliases("arialbd", new String[]{"arial-boldmt,bold", "arial-boldmt", "Helvetica-Bold", "Arial,bold", "arial bold", "ArialNarrow-Bold"}); setSubstitutedFontAliases("arialbi", new String[]{"Arial-BoldItalicMT", "Helvetica-BoldOblique", "ArialNarrow-BoldItalic"}); //Font doesn't work in generic Windows 8 (commented out by Mark) 14/11/2013 //Arial Narrow - not actually one of fonts but very common so added //setSubstitutedFontAliases("arialn",new String[]{"ArialNarrow",}); //called ArialNarrow in PDF, needs to be arialn for Windows //setSubstitutedFontAliases("arialni",new String[]{"ArialNarrow-italic"}); //setSubstitutedFontAliases("arialnb",new String[]{"ArialNarrow-bold","ArialNarrow,Bold"}); //setSubstitutedFontAliases("arialnbi",new String[]{"ArialNarrow-bolditalic"}); //Times/TimesNewRoman setSubstitutedFontAliases("timesbd", new String[]{"Times-Bold", "TimesNewRoman,Bold", "TimesNewRomanPS-BoldMT"}); setSubstitutedFontAliases("timesi", new String[]{"Times-BoldItalic", "TimesNewRoman,BoldItalic"}); setSubstitutedFontAliases("timesbi", new String[]{"Times-Italic", "TimesNewRoman,Italic"}); setSubstitutedFontAliases("times", new String[]{"Times-Roman", "TimesNewRoman", "Times", "TimesNewRomanPSMT"}); setSubstitutedFontAliases("wingdings", new String[]{"ZapfDingbats", "ZaDb"}); // setSubstitutedFontAliases("wingding",new String[] {"ZapfDingbats","ZaDb","wingdings"}); } setSubstitutedFontAliases("AdobeSongStd-Light", new String[]{"STSong-Light"}); // setSubstitutedFontAliases("AdobeSongStd-Light",new String[] {"MHei-Medium"}); // setSubstitutedFontAliases("AdobeSongStd-Light",new String[] {"MSung-Light"}); // setSubstitutedFontAliases("AdobeSongStd-Light",new String[] {"HeiseiKakuGo-W5"}); // setSubstitutedFontAliases("AdobeSongStd-Light",new String[] {"HeiseiMin-W3"}); // setSubstitutedFontAliases("AdobeSongStd-Light",new String[] {"HYGoThic-Medium"}); // setSubstitutedFontAliases("AdobeSongStd-Light",new String[] {"HYSMyeongJo-Medium"}); //set general mappings for non-embedded fonts (assumes names the same) - do first time used if (!fontsSet) { fontsSet = true; //now in public static variable so can be altered setFontDirs(defaultFontDirs); /*check for any windows fonts lurking in Adobe folders as well*/ if (DecoderOptions.isRunningOnWindows) { final File adobeFonts = new File("C:\\Program Files\\Adobe\\"); if (adobeFonts.exists()) { final String[] subdirs = adobeFonts.list(); for (final String path : subdirs) { final String adobePath = "C:\\Program Files\\Adobe\\" + path + "\\Resource\\CIDFont"; final File testAdobe = new File(adobePath); //add if it exists if (testAdobe.exists()) { addTTDir(adobePath, ""); } } } } } } /** * takes a String[] of font directories and adds to substitution - Can just * be called for each JVM - Should be called before file opened - this * offers an alternative to the call -DFontDirs - Passing a null value * flushes all settings * * @return String which will be null or list of directories it could not * find */ public static String setFontDirs(final String[] fontDirs) { String failed = null; checkFontTablesInitialised(); try { if (fontDirs == null) { // idiot safety test LogWriter.writeLog("Null font parameter passed"); fontSubstitutionAliasTable.clear(); fontSubstitutionLocation.clear(); fontSubstitutionTable.clear(); fontSubstitutionFontID.clear(); fontPossDuplicates.clear(); fontPropertiesTable.clear(); fontPropertiesTableType.clear(); fontPropertiesTablePath.clear(); fontsSet = false; } else { for (final String fontDir : fontDirs) { String fontPath = fontDir; // allow for 'wrong' separator if (!fontPath.endsWith("/") && !fontPath.endsWith("\\")) { fontPath += separator; } failed = addTTDir(fontPath, failed); } } } catch (final Exception e) { LogWriter.writeLog("Unable to run setFontDirs " + e.getMessage()); } return failed; } private static void checkFontTablesInitialised() { if (FontMappings.fontSubstitutionTable == null) { fontSubstitutionTable = new ConcurrentHashMap(); fontSubstitutionFontID = new ConcurrentHashMap(); fontPossDuplicates = new ConcurrentHashMap(); fontPropertiesTable = new ConcurrentHashMap(); fontPropertiesTableType = new ConcurrentHashMap(); fontPropertiesTablePath = new ConcurrentHashMap(); } } /** * This routine allows the user to add truetype, * type1 or type1C fonts which will be used to disalay the fonts in PDF * rendering and substitution as if the fonts were embedded in the PDF
* This is very useful for clients looking to keep down the size of PDFs * transmitted and control display quality - *
* Thanks to Peter for the idea/code - *
* How to set it up - *
* JPedal will look for the existence of the directory fontPath (ie * com/myCompany/Fonts) - *
* If this exists, Jpedal will look for 3 possible directories (tt,t1c,t1) * and make a note of any fonts if these directories exist - *
* When fonts are resolved, this option will be tested first and if a font * if found, it will be used to display the font (the effect will be the * same as if the font was embedded) - *
* If the enforceMapping is true, JPedal assumes there must be a match and * will throw a PdfFontException - *
* Otherwise Jpedal will look in the java font path for a match or * approximate with Lucida - *
* The Format is defined as follows: - *
* fontname = filename *
* Type1/Type1C Font names exclude any prefix so /OEGPNB+FGHeavyItalic is * resolved to FGHeavyItalic - *
* Each font have the same name as the font it replaces (so Arial will * require a font file such as Arial.ttf) and it must be unique (there * cannot be an Arial font in each sub-directory) - *
* So to use this functionality, place the fonts in a jar or add to the * JPedal jar and call this method after instancing PdfDecoder - JPedal will * do the rest * * @param fontPath - * root directory for fonts * @param enforceMapping - * tell JPedal if all fonts should be in this directory * @return flag (true if fonts added) */ public static boolean addSubstituteFonts(String fontPath, final boolean enforceMapping) { boolean hasFonts = false; InputStream in = null, dir = null; try { final String[] dirs = {"tt", "t1c", "t1"}; final String[] types = {"/TrueType", "/Type1C", "/Type1"}; // check fontpath ends with separator - we may need to check this. // if((!fontPath.endsWith("/"))&(!fontPath.endsWith("\\"))) // fontPath=fontPath=fontPath+separator; enforceFontSubstitution = enforceMapping; final ClassLoader loader = FontMappings.class.getClass().getClassLoader(); // see if root dir exists dir = loader.getResourceAsStream(fontPath); LogWriter.writeLog("Looking for root " + fontPath); // if it does, look for sub-directories if (in != null) { LogWriter.writeLog("Adding fonts fonts found in tt,t1c,t1 sub-directories of " + fontPath); hasFonts = true; for (int i = 0; i < dirs.length; i++) { if (!fontPath.endsWith("/")) { fontPath += '/'; } final String path = fontPath + dirs[i] + '/'; // see if it exists in = loader.getResourceAsStream(path); // if it does read its contents and store if (in != null) { System.out.println("Found " + path + ' ' + in); final ArrayList fonts; try { // works with IDE or jar if (in instanceof ByteArrayInputStream) { fonts = readIndirectValues(in); } else { fonts = getDirectoryMatches(path); } String value, fontName; // now assign the fonts for (final String font : fonts) { value = font; if (value == null) { break; } final int pointer = value.indexOf('.'); if (pointer == -1) { fontName = value.toLowerCase(); } else { fontName = value.substring(0, pointer).toLowerCase(); } fontSubstitutionTable.put(fontName, types[i]); fontSubstitutionLocation.put(fontName, path + value); } } catch (final Exception e) { LogWriter.writeLog("Exception " + e + " reading substitute fonts"); } finally { if (in != null) { try { in.close(); } catch (final IOException e) { LogWriter.writeLog("Exception: " + e.getMessage()); } } } } } } else { LogWriter.writeLog("No fonts found at " + fontPath); } } catch (final Exception e) { LogWriter.writeLog("Exception adding substitute fonts " + e.getMessage()); } finally { //close streams if open if (in != null) { try { in.close(); } catch (final IOException e) { LogWriter.writeLog("Exception: " + e.getMessage()); } } if (dir != null) { try { dir.close(); } catch (final IOException e) { LogWriter.writeLog("Exception: " + e.getMessage()); } } } return hasFonts; } /** * method to add a single file to the PDF renderer * * @param currentFont - actual font name we use to identify * @param fontPath - full path to font file used for this font */ public static void addFontFile(final String currentFont, String fontPath) { checkFontTablesInitialised(); //add separator if needed if (fontPath != null && !fontPath.endsWith("/") && !fontPath.endsWith("\\")) { fontPath += separator; } final String name = currentFont.toLowerCase(); //decide font type final int type = StandardFonts.getFontType(name); InputStream in = null; if (type != StandardFonts.FONT_UNSUPPORTED && new File(fontPath + currentFont).exists()) { // see if root dir exists boolean failed = false; try { in = new FileInputStream(fontPath + currentFont); } catch (final Exception e) { LogWriter.writeLog("Exception: " + e.getMessage()); failed = true; } catch (final Error err) { LogWriter.writeLog("Error: " + err.getMessage()); failed = true; } // if it does, add if (!failed) { final String fontName; //name from file final int pointer = currentFont.indexOf('.'); if (pointer == -1) { fontName = currentFont.toLowerCase(); } else { fontName = currentFont.substring(0, pointer).toLowerCase(); } //choose filename or over-ride if OpenType if (fontSubstitutionMode == PdfDecoderInt.SUBSTITUTE_FONT_USING_FILE_NAME || type == StandardFonts.OPENTYPE) { if (type == StandardFonts.TYPE1) { fontSubstitutionTable.put(fontName, "/Type1"); } else { //TT or OTF fontSubstitutionTable.put(fontName, "/TrueType"); } fontSubstitutionLocation.put(fontName, fontPath + currentFont); //store details under file fontPropertiesTableType.put(fontName, type); fontPropertiesTablePath.put(fontName, fontPath + currentFont); } else if (type == StandardFonts.TRUETYPE_COLLECTION || type == StandardFonts.TRUETYPE) { if (fontSubstitutionMode == PdfDecoderInt.SUBSTITUTE_FONT_USING_POSTSCRIPT_NAME_USE_FAMILY_NAME_IF_DUPLICATES) { //get both possible values String[] postscriptNames = null; try { postscriptNames = StandardFonts.readNamesFromFont(type, fontPath + currentFont, PdfDecoderInt.SUBSTITUTE_FONT_USING_POSTSCRIPT_NAME); } catch (final Exception e) { LogWriter.writeLog("Exception: " + e.getMessage()); } String[] familyNames = null; try { familyNames = StandardFonts.readNamesFromFont(type, fontPath + currentFont, PdfDecoderInt.SUBSTITUTE_FONT_USING_FAMILY_NAME); } catch (final Exception e) { LogWriter.writeLog("Exception: " + e.getMessage()); } int fontCount = 0; if (postscriptNames != null) { fontCount = postscriptNames.length; } for (int ii = 0; ii < fontCount; ii++) { //allow for null and use font name if (postscriptNames[ii] == null) { postscriptNames[ii] = Strip.stripAllSpaces(fontName); } //allow for null and use font name if (familyNames[ii] == null) { familyNames[ii] = Strip.stripAllSpaces(fontName); } final String fontSubValue = fontSubstitutionTable.get(postscriptNames[ii]); final String possDuplicate = fontPossDuplicates.get(postscriptNames[ii]); if (fontSubValue == null && possDuplicate == null) { //first time so store and track //System.out.println("store "+postscriptNames[ii]); fontSubstitutionTable.put(postscriptNames[ii], "/TrueType"); fontSubstitutionLocation.put(postscriptNames[ii], fontPath + currentFont); fontSubstitutionFontID.put(postscriptNames[ii], ii); //and remember in case we need to switch fontPossDuplicates.put(postscriptNames[ii], familyNames[ii]); } else if (!familyNames[ii].equals(postscriptNames[ii])) { //if no duplicates,add to mappings with POSTSCRIPT and log filename //both lists should be in same order and name //else save as FAMILY_NAME fontSubstitutionTable.put(postscriptNames[ii], "/TrueType"); fontSubstitutionLocation.put(postscriptNames[ii], fontPath + currentFont); fontSubstitutionFontID.put(postscriptNames[ii], ii); //store details under file fontPropertiesTableType.put(postscriptNames[ii], type); fontPropertiesTablePath.put(postscriptNames[ii], fontPath + currentFont); //if second find change first match if (!possDuplicate.equals("DONE")) { //System.out.println("replace "+postscriptNames[ii]+" "+familyNames[ii]); //flag as done fontPossDuplicates.put(postscriptNames[ii], "DONE"); //swap over fontSubstitutionTable.remove(postscriptNames[ii]); fontSubstitutionTable.put(familyNames[ii], "/TrueType"); final String font = fontSubstitutionLocation.get(postscriptNames[ii]); fontSubstitutionLocation.remove(postscriptNames[ii]); fontSubstitutionLocation.put(familyNames[ii], font); fontSubstitutionFontID.remove(postscriptNames[ii]); fontSubstitutionFontID.put(familyNames[ii], ii); //store details under file fontPropertiesTablePath.remove(familyNames[ii]); fontPropertiesTableType.remove(familyNames[ii]); fontPropertiesTableType.put(familyNames[ii], type); fontPropertiesTablePath.put(familyNames[ii], fontPath + currentFont); } } } } else { //easy version //read 1 or more font mappings from file String[] fontNames = null; try { fontNames = StandardFonts.readNamesFromFont(type, fontPath + currentFont, fontSubstitutionMode); } catch (final Exception e) { LogWriter.writeLog("Exception: " + e.getMessage()); } if (fontNames != null) { for (int i = 0; i < fontNames.length; i++) { //allow for null and use font name if (fontNames[i] == null) { fontNames[i] = Strip.stripAllSpaces(fontName); } fontSubstitutionTable.put(fontNames[i], "/TrueType"); fontSubstitutionLocation.put(fontNames[i], fontPath + currentFont); fontSubstitutionFontID.put(fontNames[i], i); //store details under file fontPropertiesTableType.put(fontNames[i], type); fontPropertiesTablePath.put(fontNames[i], fontPath + currentFont); } } } } else if (type == StandardFonts.TYPE1) { // || type == StandardFonts.OPENTYPE){ //type1 //read 1 or more font mappings from file String[] fontNames = null; try { fontNames = StandardFonts.readNamesFromFont(type, fontPath + currentFont, fontSubstitutionMode); } catch (final Exception e) { LogWriter.writeLog("Exception: " + e.getMessage()); } if (fontNames != null) { for (int i = 0; i < fontNames.length; i++) { //allow for null and use font name if (fontNames[i] == null) { fontNames[i] = Strip.stripAllSpaces(fontName); } //System.out.println("font="+fontNames[i]); fontSubstitutionTable.put(fontNames[i], "/Type1"); fontSubstitutionLocation.put(fontNames[i], fontPath + currentFont); fontSubstitutionFontID.put(fontNames[i], i); //store details under file fontPropertiesTableType.put(fontNames[i], type); fontPropertiesTablePath.put(fontNames[i], fontPath + currentFont); } } } } else { LogWriter.writeLog("No fonts found at " + fontPath); } } //finally close if (in != null) { try { in.close(); } catch (final IOException e) { LogWriter.writeLog("Exception: " + e.getMessage()); } } } private static ArrayList getDirectoryMatches(String sDirectoryName) throws IOException { sDirectoryName = sDirectoryName.replaceAll("\\.", "/"); final URL u = Thread.currentThread().getContextClassLoader().getResource( sDirectoryName); final ArrayList retValue = new ArrayList(0); String s = u.toString(); System.out.println("scanning " + s); if (s.startsWith("jar:") && s.endsWith(sDirectoryName)) { final int idx = s.lastIndexOf(sDirectoryName); s = s.substring(0, idx); // isolate entry name System.out.println("entry= " + s); final URL url = new URL(s); // Get the jar file final JarURLConnection conn = (JarURLConnection) url.openConnection(); final JarFile jar = conn.getJarFile(); for (final Enumeration e = jar.entries(); e.hasMoreElements(); ) { final JarEntry entry = e.nextElement(); if ((!entry.isDirectory()) && (entry.getName().startsWith(sDirectoryName))) { // this // is how you can match // to find your fonts. // System.out.println("Found a match!"); final String fontName = entry.getName(); final int i = fontName.lastIndexOf('/'); retValue.add(fontName.substring(i + 1)); } } } return retValue; } /** * read values from the classpath */ private static ArrayList readIndirectValues(final InputStream in) throws IOException { final ArrayList fonts; final BufferedReader inpStream = new BufferedReader(new InputStreamReader(in)); fonts = new ArrayList(0); while (true) { final String nextValue = inpStream.readLine(); if (nextValue == null) { break; } fonts.add(nextValue); } inpStream.close(); return fonts; } /** * set the font used for default from Java fonts on system - Java fonts are * case sensitive, but JPedal resolves this internally, so you could use * Webdings, webdings or webDings for Java font Webdings - checks if it is a * valid Java font (otherwise it will default to Lucida anyway) */ public static void setDefaultDisplayFont(final String fontName) throws PdfFontException { boolean isFontInstalled = false; // get list of fonts and see if installed final String[] fontList = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); final int count = fontList.length; for (int i = 0; i < count; i++) { if (fontList[i].equalsIgnoreCase(fontName.toLowerCase())) { isFontInstalled = true; defaultFont = fontList[i]; i = count; } } if (!isFontInstalled) { throw new PdfFontException("Font " + fontName + " is not available."); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy