javajs.export.PDFObject Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jmol Show documentation
Show all versions of jmol Show documentation
Jmol: an open-source Java viewer for chemical structures in 3D
package javajs.export;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Hashtable;
import java.util.Map;
import java.util.Map.Entry;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import javajs.util.SB;
/**
* A rudimentary class for working with PDF document creation.
* Written from scratch based on PDF Reference 13.
*
* @author hansonr Bob Hanson [email protected] 10/28/2013
*
*/
class PDFObject extends SB {
private Map dictionary;
private byte[] stream;
private int index;
String type;
int len;
int pt;
PDFObject(int index) {
this.index = index;
}
String getRef() {
return index + " 0 R";
}
String getID() {
return type.substring(0, 1) + index;
}
boolean isFont() {
return "Font".equals(type);
}
void setStream(byte[] stream) {
this.stream = stream;
}
Object getDef(String key) {
return dictionary.get(key);
}
void addDef(String key, Object value) {
if (dictionary == null)
dictionary = new Hashtable();
dictionary.put(key, value);
if (key.equals("Type"))
type = ((String) value).substring(1);
}
void setAsStream() {
stream = toBytes(0, -1);
setLength(0);
}
int output(OutputStream os) throws IOException {
if (index > 0) {
String s = index + " 0 obj\n";
write(os, s.getBytes(), 0);
}
int streamLen = 0;
if (dictionary != null) {
if (dictionary.containsKey("Length")) {
if (stream == null)
setAsStream();
streamLen = stream.length;
boolean doDeflate = (streamLen > 1000);
if (doDeflate) {
Deflater deflater = new Deflater(9);
ByteArrayOutputStream outBytes = new ByteArrayOutputStream(1024);
DeflaterOutputStream compBytes = new DeflaterOutputStream(outBytes,
deflater);
compBytes.write(stream, 0, streamLen);
compBytes.finish();
stream = outBytes.toByteArray();
dictionary.put("Filter", "/FlateDecode");
streamLen = stream.length;
}
dictionary.put("Length", "" + streamLen);
}
write(os, getDictionaryText(dictionary, "\n").getBytes(), 0);
}
if (length() > 0)
write(os, this.toString().getBytes(), 0);
if (stream != null) {
write(os, "stream\r\n".getBytes(), 0);
write(os, stream, streamLen);
write(os, "\r\nendstream\r\n".getBytes(), 0);
}
if (index > 0)
write(os, "endobj\n".getBytes(), 0);
return len;
}
private void write(OutputStream os, byte[] bytes, int nBytes) throws IOException {
if (nBytes == 0)
nBytes = bytes.length;
len += nBytes;
os.write(bytes, 0, nBytes);
}
@SuppressWarnings("unchecked")
private String getDictionaryText(Map d, String nl) {
SB sb = new SB();
sb.append("<<");
if (d.containsKey("Type"))
sb.append("/Type").appendO(d.get("Type"));
for (Entry e : d.entrySet()) {
String s = e.getKey();
if (s.equals("Type") || s.startsWith("!"))
continue;
sb.append("/" + s);
Object o = e.getValue();
if (o instanceof Map, ?>) {
sb.append((getDictionaryText((Map) o, "")));
continue;
}
s = (String) e.getValue();
if (!s.startsWith("/"))
sb.append(" ");
sb.appendO(s);
}
return (sb.length() > 3 ? sb.append(">>").append(nl).toString() : "");
}
@SuppressWarnings("unchecked")
private Map createSubdict(Map d0, String dict) {
Map d = (Map) d0.get(dict);
if (d == null)
d0.put(dict, d = new Hashtable());
return d;
}
void addResource(String type, String key, String value) {
Map r = createSubdict(dictionary, "Resources");
if (type != null)
r = createSubdict(r, type);
r.put(key, value);
}
}