// Copyright 2000-2005 FreeHEP
package org.freehep.graphicsio.pdf;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.Hashtable;
import java.util.Vector;
/**
* Implements the lookup tables.
* <p>
*
* @author Mark Donszelmann
* @version $Id: freehep-graphicsio-pdf/src/main/java/org/freehep/graphicsio/pdf/PDF.java f493ff6e61b2 2005/12/01 18:46:43 duns $
*/
public class PDF {
private int generationNumber = 0;
private Hashtable<String, PDFRef> refsByName = new Hashtable<String, PDFRef>(); // of PDFRefs stored by name
private Vector<PDFRef> refsByNumber = new Vector<PDFRef>(); // of PDFRefs stored by number
private Vector<Integer> xrefsByNumber = new Vector<Integer>(); // of offsets stored by
// refnumber
private int startXref = 0;
protected PDFByteWriter out;
PDF(PDFByteWriter out) {
this.out = out;
// add dummy element to refsByNumber and xrefsByNumber
refsByNumber.addElement(new PDFRef("Dummy", 0, 0));
xrefsByNumber.addElement(new Integer(999999));
}
public PDFName name(String name) {
return new PDFName(name);
}
public PDFRef ref(String name) {
if (name == null)
return null;
PDFRef ref = refsByName.get(name);
if (ref == null) {
int refNumber = refsByNumber.size();
ref = new PDFRef(name, refNumber, generationNumber);
refsByName.put(name, ref);
refsByNumber.add(ref);
xrefsByNumber.add(null);
}
return ref;
}
public PDFRef[] ref(String[] names) {
PDFRef[] refs = new PDFRef[names.length];
for (int i = 0; i < names.length; i++) {
refs[i] = ref(names[i]);
}
return refs;
}
protected void setXRef(int objectNumber, int offset) {
xrefsByNumber.set(objectNumber, new Integer(offset));
}
protected void xref() throws IOException {
DecimalFormat offsetFormat = new DecimalFormat("0000000000");
DecimalFormat linkFormat = new DecimalFormat("00000");
startXref = out.getCount();
out.printPlain("xref");
out.println();
out.printPlain(0 + " " + xrefsByNumber.size());
out.println();
// the free list header
out.printPlain(offsetFormat.format(0) + " " + linkFormat.format(65535)
+ " f\r\n");
// the used list
for (int i = 1; i < xrefsByNumber.size(); i++) {
Integer offsetObject = xrefsByNumber.get(i);
if (offsetObject != null) {
int offset = offsetObject.intValue();
out.printPlain(offsetFormat.format(offset) + " "
+ linkFormat.format(0) + " n\r\n");
} else {
PDFRef ref = refsByNumber.get(i);
System.err.println("PDFWriter: PDFRef '" + ref.getName()
+ "' is used but not defined.");
}
}
out.println();
}
protected void trailer(String rootName, String docInfoName)
throws IOException {
out.println("trailer");
PDFDictionary dictionary = new PDFDictionary(this, out);
dictionary.entry("Size", refsByName.size());
dictionary.entry("Root", ref(rootName));
if (docInfoName != null)
dictionary.entry("Info", ref(docInfoName));
dictionary.close();
out.println();
}
protected void startxref() throws IOException {
out.println("startxref");
out.println(startXref);
out.println();
}
}