L.S.,

I've written an extension of DefaultFontMapper that caches fonts in a hashtable. It needs some changes in DefaultFontMapper. Both implementations are attached.

Best regards,
Hans Oesterholt.


package net.oesterholt.jxmlnote.report.pdf;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;

import net.oesterholt.jxmlnote.exceptions.DefaultXMLNoteErrorHandler;
import net.oesterholt.jxmlnote.exceptions.FontPathException;
import net.oesterholt.jxmlnote.internationalization.DefaultXMLNoteTranslator;
import net.oesterholt.jxmlnote.internationalization.XMLNoteTranslator;
import sun.font.FontManager;

import com.itextpdf.text.pdf.FontMapper;

/**
 * This class provides a font mapper for iText that inserts all font directories from the font path
 * of the sun.font.FontMapper. If it cannot insert them, it yields a Warning via XMLNoteErrorHandler
 * and returns the default FontMapper of iText. 
 * <p>
 * This class works via a static method. The constructor is protected.  
 * 
 * @author Hans Oesterholt-Dijkema
 *
 */
public class PdfFontMapper extends MyDefaultFontMapper {
	
	Hashtable<String,Object[]> _cachedNames; 
	Hashtable<String,Integer>  _cachedCounts;
	
	public void insertNames(Object[] names,String path) {
		super.insertNames(names,path);
		_cachedNames.put(path,names);
	}
	
	public int insertFile(File fontFile,int count) {
		String path=fontFile.getPath();
		Object[] names=_cachedNames.get(path);
		if (names!=null) {
			insertNames(names,path);
			count+=_cachedCounts.get(path);
			return count;
		} else {
			count=super.insertFile(fontFile, count);
			_cachedCounts.put(path, new Integer(count));
			return count;
		}
	}
	
	private XMLNoteTranslator	_tr;
	private static FontMapper   _fontmapper=null;
	
	/**
	 * This method creates an instance of this fontmapper, or reuses the existing one if 
	 * it has already been created. 
	 * 
	 * @return the fontmapper for iText. 
	 */
	public static synchronized FontMapper createPdfFontMapper(PdfReport rep,File fontmapcache) {
		if (_fontmapper==null) {
			_fontmapper=new PdfFontMapper(rep,fontmapcache);
		}
		return _fontmapper;
	}
	
	private String[] getFontPath() {
		String fontPath=FontManager.getFontPath(true);
		if (fontPath.indexOf(':')>=0) {
			String[] pathParts=fontPath.split(":");
			return pathParts;
		} else if (fontPath.indexOf(';')>=0) {
			String[] pathParts=fontPath.split(";");
			return pathParts;
		} else {
			return null;
		}
	}
	
	private void readInCache(File f) {
		_cachedNames.clear();
		_cachedCounts.clear();
		if (f.canRead() && f.isFile()) {
			try {
				ObjectInputStream in=new ObjectInputStream(new FileInputStream(f));
				int size=(Integer) in.readObject();
				for (int i=0;i<size;i++) {
					String path=(String) in.readObject();
					Object[] names=(Object []) in.readObject();
					_cachedNames.put(path,names);
				}
				size=(Integer) in.readObject();
				for (int i=0;i<size;i++) {
					String path=(String) in.readObject();
					Integer count=(Integer) in.readObject();
					_cachedCounts.put(path, count);
				}
				in.close();
			} catch (Exception e) {
				DefaultXMLNoteErrorHandler.exception(e);
			}
		}
	}
	
	private void writeOutCache(File f) {
		try {
			ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream(f));
			Set<String> keys=_cachedNames.keySet();
			Iterator<String> it=keys.iterator();
			out.writeObject(keys.size());
			while (it.hasNext()) {
				String path=it.next();
				out.writeObject(path);
				Object [] names=_cachedNames.get(path);
				out.writeObject(names);
			}
			keys=_cachedCounts.keySet();
			it=keys.iterator();
			out.writeObject(keys.size());
			while (it.hasNext()) {
				String path=it.next();
				out.writeObject(path);
				Integer count=_cachedCounts.get(path);
				out.writeObject(count);
			}
			out.close();
		} catch(Exception e) {
			DefaultXMLNoteErrorHandler.exception(e);
		}
	}
	
	private void initializeFonts(PdfReport rep,File persistedCacheWithFontMapInfo) throws FontPathException {
		if (persistedCacheWithFontMapInfo!=null) { readInCache(persistedCacheWithFontMapInfo); }
		String[] paths=getFontPath();
		if (paths==null) {
			throw new FontPathException(_tr._("There seems to be no font path configured for this platform"));
		} else {
			String prev=rep.informStatus(_tr._("Initializing PDF Fonts"));
			float progr=0.0f;
			float step=100.0f/((float) paths.length);
			int prevp=rep.informProgress((int) progr);
			for(String path : paths) {
				progr+=step;
				if (progr>100.0f) { progr=100.0f; }
				rep.informProgress((int) progr);
				super.insertDirectory(path);
			}
			rep.informStatus(prev);
			rep.informProgress(prevp);
		}
		if (persistedCacheWithFontMapInfo!=null) { writeOutCache(persistedCacheWithFontMapInfo); }
	}
	
	protected PdfFontMapper(PdfReport rep,File persistedCacheWithFontMapInfo) {
		_tr=new DefaultXMLNoteTranslator();
		_cachedNames=new Hashtable<String,Object[]>();
		_cachedCounts=new Hashtable<String,Integer>();
		try {
			initializeFonts(rep,persistedCacheWithFontMapInfo);
		} catch (FontPathException e) {
			DefaultXMLNoteErrorHandler.warning(e, -1, e.getMessage());
		}
	}
}
package net.oesterholt.jxmlnote.report.pdf;

import java.io.File;

import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.DefaultFontMapper;

public class MyDefaultFontMapper extends DefaultFontMapper {

	//////////////////////////////////////////////////////////////////////////////////////////////////
	// OVERRIDE methods in DefaultFontMapper with a different implementation   
	// That allows for a more efficiënt implementation 
	//////////////////////////////////////////////////////////////////////////////////////////////////
	
	public int insertFile(File file,int count) {
		String name = file.getPath().toLowerCase();
		try {
			if (name.endsWith(".ttf") || name.endsWith(".otf") || name.endsWith(".afm")) {
				Object allNames[] = BaseFont.getAllFontNames(file.getPath(), BaseFont.CP1252, null);
				insertNames(allNames, file.getPath());
				++count;
			}
			else if (name.endsWith(".ttc")) {
				String ttcs[] = BaseFont.enumerateTTCNames(file.getPath());
				for (int j = 0; j < ttcs.length; ++j) {
					String nt = file.getPath() + "," + j;
					Object allNames[] = BaseFont.getAllFontNames(nt, BaseFont.CP1252, null);
					insertNames(allNames, nt);
				}
				++count;
			}
		}
		catch (Exception e) {
		}
		return count;
	}

	/** Inserts all the fonts recognized by iText in the
	 * <CODE>directory</CODE> into the map. The encoding
	 * will be <CODE>BaseFont.CP1252</CODE> but can be
	 * changed later.
	 * @param dir the directory to scan
	 * @return the number of files processed
	 */
	public int insertDirectory(String dir) {
		File file = new File(dir);
		if (!file.exists() || !file.isDirectory())
			return 0;
		File files[] = file.listFiles();
		if (files == null)
			return 0;
		int count = 0;
		for (int k = 0; k < files.length; ++k) {
			count=insertFile(files[k],count);
		}
		return count;
	}

	//////////////////////////////////////////////////////////////////////////////////////////////////
	// OVERRIDE methods in DefaultFontMapper with a different implementation   
	// That allows for a more efficiënt implementation 
	//////////////////////////////////////////////////////////////////////////////////////////////////

	
}
------------------------------------------------------------------------------
Sell apps to millions through the Intel(R) Atom(Tm) Developer Program
Be part of this innovative community and reach millions of netbook users 
worldwide. Take advantage of special opportunities to increase revenue and 
speed time-to-market. Join now, and jumpstart your future.
http://p.sf.net/sfu/intel-atom-d2d
_______________________________________________
iText-questions mailing list
iText-questions@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/itext-questions

Buy the iText book: http://www.itextpdf.com/book/
Check the site with examples before you ask questions: 
http://www.1t3xt.info/examples/
You can also search the keywords list: http://1t3xt.info/tutorials/keywords/

Reply via email to