com.caucho.quercus.lib.pdf.PDFWriter Maven / Gradle / Ivy
/*
* Copyright (c) 1998-2012 Caucho Technology -- all rights reserved
*
* This file is part of Resin(R) Open Source
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Resin Open Source is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Resin Open Source is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
* of NON-INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Resin Open Source; if not, write to the
*
* Free Software Foundation, Inc.
* 59 Temple Place, Suite 330
* Boston, MA 02111-1307 USA
*
* @author Scott Ferguson
*/
package com.caucho.quercus.lib.pdf;
import com.caucho.util.L10N;
import com.caucho.vfs.WriteStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
/**
* pdf object oriented API facade
*/
public class PDFWriter {
private static final Logger log
= Logger.getLogger(PDFWriter.class.getName());
private static final L10N L = new L10N(PDFWriter.class);
private long _offset;
private WriteStream _out;
private int _objectId = 1;
private int _lastObject;
private String _creator = "Quercus PDF";
private String _author;
private String _title;
private ArrayList _pendingObjects
= new ArrayList();
private ArrayList _xref = new ArrayList();
PDFWriter(WriteStream out)
{
_out = out;
}
public void setCreator(String creator)
{
_creator = creator;
}
public void setAuthor(String author)
{
_author = author;
}
public void setTitle(String title)
{
_title = title;
}
public void beginDocument()
throws IOException
{
println("%PDF-1.4");
println("#\u00c0\u00c3\u00c4\u00c9");
}
public void writeCatalog(int catalogId,
int rootId,
int outlineId,
ArrayList pagesList,
int pageCount)
throws IOException
{
beginObject(catalogId);
println(" << /Type /Catalog");
println(" /Pages " + rootId + " 0 R");
if (outlineId > 0) {
println(" /PageMode /UseOutlines");
println(" /Outlines " + outlineId + " 0 R");
}
println(" >>");
endObject();
if (pagesList.size() > 0) {
beginObject(rootId);
println(" << /Type /Pages");
print(" /Kids [");
for (int i = 0; i < pagesList.size(); i++) {
if (i != 0)
print(" ");
print(pagesList.get(i) + " 0 R");
}
println("]");
println(" /Count " + pageCount);
println(" >>");
endObject();
}
}
public void writeOutline(PDFOutline outline)
throws IOException
{
List roots = outline.getRootDestinations();
beginObject(outline.getId());
println(" << /Type /Outlines");
println(" /First " + roots.get(0).getId() + " 0 R");
println(" /Last " + roots.get(roots.size()-1).getId() + " 0 R");
println(" >>");
endObject();
for(int i=0; i destinations, int index)
throws IOException
{
PDFDestination dest = destinations.get(index);
List children = dest.getChildren();
for(int i=0; i 0)
println(" /Prev " + destinations.get(index-1).getId() + " 0 R");
if (index < (destinations.size()-1))
println(" /Next " + destinations.get(index+1).getId() + " 0 R");
if (! children.isEmpty()) {
println(" /First " + children.get(0).getId() + " 0 R");
println(" /Last " + children.get(children.size()-1).getId() + " 0 R");
println(" /Count " + (children.size() * -1));
}
println(" >>");
endObject();
}
public void writePageGroup(int id, int parentId, ArrayList pages)
throws IOException
{
beginObject(id);
println(" << /Type /Pages");
print(" /Kids [");
for (int i = 0; i < pages.size(); i++) {
if (i != 0)
print(" ");
print(pages.get(i).getId() + " 0 R");
}
println("]");
println(" /Count " + pages.size());
println(" /Parent " + parentId + " 0 R");
println(" >>");
endObject();
for (int i = 0; i < pages.size(); i++) {
pages.get(i).write(this);
}
}
public void writeStream(int id, PDFStream stream)
throws IOException
{
stream.flush();
int length = stream.getLength();
beginObject(id);
println(" << /Length " + length + " >>");
println("stream");
stream.writeToStream(_out);
_offset += length;
println();
println("endstream");
endObject();
}
public void endDocument()
throws IOException
{
long xrefOffset = _offset;
println("xref");
println("0 " + (_xref.size() + 1) + "");
print("0000000000 65535 f \n");
for (int i = 0; i < _xref.size(); i++)
_xref.get(i).write();
println("trailer");
println(" << /Size " + (_xref.size() + 1));
println(" /Root 1 0 R");
println(" >>");
println("startxref");
println(xrefOffset);
println("%%EOF");
}
public int allocateId(int count)
{
int id = _objectId;
_objectId += count;
return id;
}
public void addPendingObject(PDFObject obj)
throws IOException
{
if (_lastObject + 1 == obj.getId()) {
beginObject(obj.getId());
obj.writeObject(this);
endObject();
}
else
_pendingObjects.add(obj);
}
public void beginObject(int id)
throws IOException
{
while (_xref.size() < id)
_xref.add(null);
_xref.set(id - 1, new ObjectDef(id, _offset));
println(id + " 0 obj");
}
public void endObject()
throws IOException
{
println("endobj");
_lastObject++;
for (int i = _pendingObjects.size() - 1; i >= 0; i--) {
PDFObject obj = _pendingObjects.get(i);
if (_lastObject + 1 == obj.getId()) {
_pendingObjects.remove(i);
beginObject(obj.getId());
obj.writeObject(this);
endObject();
break;
}
}
}
public void write(byte []buffer, int offset, int length)
throws IOException
{
_out.write(buffer, offset, length);
_offset += length;
}
public void print(String s)
throws IOException
{
_out.print(s);
_offset += s.length();
}
public void println(String s)
throws IOException
{
_out.println(s);
_offset += s.length() + 1;
}
public void println()
throws IOException
{
_out.println();
_offset += 1;
}
public void print(long v)
throws IOException
{
println(String.valueOf(v));
}
public void println(long v)
throws IOException
{
println(String.valueOf(v));
}
public void print(double v)
throws IOException
{
if ((long) v == v)
print(String.valueOf((long) v));
else
print(String.valueOf(v));
}
public void println(double v)
throws IOException
{
if ((long) v == v)
println(String.valueOf((long) v));
else
println(String.valueOf(v));
}
public String toString()
{
return "PDF[]";
}
class ObjectDef {
private int _id;
private long _offset;
ObjectDef(int id, long offset)
{
_id = id;
_offset = offset;
}
void write()
throws IOException
{
_out.print(_offset / 1000000000L % 10);
_out.print(_offset / 100000000L % 10);
_out.print(_offset / 10000000L % 10);
_out.print(_offset / 1000000L % 10);
_out.print(_offset / 100000L % 10);
_out.print(_offset / 10000L % 10);
_out.print(_offset / 1000L % 10);
_out.print(_offset / 100L % 10);
_out.print(_offset / 10L % 10);
_out.print(_offset % 10);
_out.print(" 00000 n \n");
_offset += 20;
}
}
}