// Copyright 2001-2005 freehep package org.xmind.org.freehep.graphicsio.pdf; import java.awt.font.FontRenderContext; import java.io.IOException; import org.xmind.org.freehep.graphics2d.font.CharTable; import org.xmind.org.freehep.graphicsio.font.FontEmbedder; /** * Superclass of all FontEmbedders for PDF documents. Subclasses must implement * all abstract methods which are called in the following order: * <ul> * <li>addAdditionalEntries * <li>addAdditionalInitDicts * <li>writeGlyph once for each glyph in the order of the encoding * </ul> * * @author Simon Fischer * @author Jason Wong */ @SuppressWarnings("nls") public abstract class PDFFontEmbedder extends FontEmbedder { /** sloppily declared protected */ protected PDFWriter pdf; private PDFDictionary fontDict; private String reference; private PDFRedundanceTracker redundanceTracker; public PDFFontEmbedder(FontRenderContext context, PDFWriter pdf, String reference, PDFRedundanceTracker tracker) { super(context); this.pdf = pdf; this.reference = reference; this.redundanceTracker = tracker; } /** Returns the font subtype (currently only Type3). */ protected abstract String getSubtype(); /** Add additional entries to the font Dictionary. */ protected abstract void addAdditionalEntries(PDFDictionary fontDict) throws IOException; /** * Add additional dicionaries to the PDFWriter which may be referenced by * entries generated by <tt>addAdditionalEntries()</tt> */ protected abstract void addAdditionalInitDicts() throws IOException; /** * Returns the reference String that identifies the font dictionary. Use * this reference plus underscore plus suffix for other dictionaries. */ protected String getReference() { return reference; } protected void openIncludeFont() throws IOException { fontDict = pdf.openDictionary(reference); fontDict.entry("Type", pdf.name("Font")); fontDict.entry("Subtype", pdf.name(getSubtype())); fontDict.entry("Name", pdf.name(getFontName())); fontDict.entry("FirstChar", 0); fontDict.entry("LastChar", 255); // fontDict.entry("Encoding", pdf.ref(reference+"Encoding")); fontDict.entry("Encoding", redundanceTracker.getReference( getEncodingTable(), PDFCharTableWriter.getInstance())); fontDict.entry("Widths", pdf.ref(reference + "Widths")); addAdditionalEntries(fontDict); pdf.close(fontDict); addAdditionalInitDicts(); } protected void closeEmbedFont() { } protected void writeWidths(double[] widths) throws IOException { Object[] widthsObj = new Object[256]; for (int i = 0; i < widthsObj.length; i++) { widthsObj[i] = new Double(widths[i]); } pdf.object(reference + "Widths", widthsObj); } protected void writeEncoding(CharTable charTable) throws IOException { // writeEncoding(pdf, reference+"Encoding", charTable); } public static void writeEncoding(PDFWriter pdf, String ref, CharTable charTable) throws IOException { PDFDictionary encoding = pdf.openDictionary(ref); encoding.entry("Type", pdf.name("Encoding")); Object[] differences = new Object[257]; differences[0] = new Integer(0); for (int i = 0; i < 256; i++) { String charName = charTable.toName(i); differences[i + 1] = (charName != null) ? pdf.name(charName) : pdf .name(NOTDEF); } encoding.entry("Differences", differences); pdf.close(encoding); } protected String createCharacterReference(String characterName) { return "Glyph_" + reference + ":" + characterName; } }