1 29 30 package com.caucho.quercus.lib.pdf; 31 32 import com.caucho.util.L10N; 33 import com.caucho.vfs.WriteStream; 34 35 import java.io.IOException ; 36 import java.util.ArrayList ; 37 import java.util.logging.Logger ; 38 39 42 public class PDFWriter { 43 private static final Logger log 44 = Logger.getLogger(PDFWriter.class.getName()); 45 private static final L10N L = new L10N(PDFWriter.class); 46 47 private long _offset; 48 private WriteStream _out; 49 50 private int _objectId = 1; 51 52 private int _lastObject; 53 54 private String _creator = "Quercus PDF"; 55 private String _author; 56 private String _title; 57 58 private ArrayList <PDFObject> _pendingObjects 59 = new ArrayList <PDFObject>(); 60 61 private ArrayList <ObjectDef> _xref = new ArrayList <ObjectDef>(); 62 63 PDFWriter(WriteStream out) 64 { 65 _out = out; 66 } 67 68 public void setCreator(String creator) 69 { 70 _creator = creator; 71 } 72 73 public void setAuthor(String author) 74 { 75 _author = author; 76 } 77 78 public void setTitle(String title) 79 { 80 _title = title; 81 } 82 83 public void beginDocument() 84 throws IOException 85 { 86 println("%PDF-1.4"); 87 println("#\u00c0\u00c3\u00c4\u00c9"); 88 } 89 90 public void writeCatalog(int catalogId, int pagesId, 91 ArrayList <Integer > pagesList, int pageCount) 92 throws IOException 93 { 94 int pageId = pagesId; 95 96 if (pagesList.size() > 0) 97 pageId = allocateId(1); 98 99 beginObject(catalogId); 100 101 println(" << /Type /Catalog"); 102 println(" /Pages " + pageId + " 0 R"); 103 println(" >>"); 104 105 endObject(); 106 107 if (pagesList.size() > 0) { 108 beginObject(pageId); 109 110 println(" << /Type /Pages"); 111 print(" /Kids ["); 112 113 for (int i = 0; i < pagesList.size(); i++) { 114 if (i != 0) 115 print(" "); 116 117 print(pagesList.get(i) + " 0 R"); 118 } 119 120 println("]"); 121 println(" /Count " + pageCount); 122 println(" >>"); 123 124 endObject(); 125 } 126 } 127 128 public void writePageGroup(int id, ArrayList <PDFPage> pages) 129 throws IOException 130 { 131 beginObject(id); 132 println(" << /Type /Pages"); 133 print(" /Kids ["); 134 135 for (int i = 0; i < pages.size(); i++) { 136 if (i != 0) 137 print(" "); 138 139 print(pages.get(i).getId() + " 0 R"); 140 } 141 142 println("]"); 143 println(" /Count " + pages.size()); 144 println(" >>"); 145 endObject(); 146 147 for (int i = 0; i < pages.size(); i++) { 148 pages.get(i).write(this); 149 } 150 } 151 152 public void writeStream(int id, PDFStream stream) 153 throws IOException 154 { 155 stream.flush(); 156 int length = stream.getLength(); 157 158 beginObject(id); 159 println(" << /Length " + length + " >>"); 160 161 println("stream"); 162 stream.writeToStream(_out); 163 _offset += length; 164 println(); 165 println("endstream"); 166 endObject(); 167 } 168 169 public void endDocument() 170 throws IOException 171 { 172 long xrefOffset = _offset; 173 174 println("xref"); 175 println("0 " + (_xref.size() + 1) + ""); 176 println("0000000000 65535 f"); 177 178 for (int i = 0; i < _xref.size(); i++) 179 _xref.get(i).write(); 180 181 println("trailer"); 182 println(" << /Size " + (_xref.size() + 1)); 183 println(" /Root 1 0 R"); 184 println(" >>"); 185 println("startxref"); 186 println(xrefOffset); 187 println("%%EOF"); 188 } 189 190 public int allocateId(int count) 191 { 192 int id = _objectId; 193 194 _objectId += count; 195 196 return id; 197 } 198 199 public void addPendingObject(PDFObject obj) 200 throws IOException 201 { 202 if (_lastObject + 1 == obj.getId()) { 203 beginObject(obj.getId()); 204 obj.writeObject(this); 205 endObject(); 206 } 207 else 208 _pendingObjects.add(obj); 209 } 210 211 public void beginObject(int id) 212 throws IOException 213 { 214 while (_xref.size() < id) 215 _xref.add(null); 216 217 _xref.set(id - 1, new ObjectDef(id, _offset)); 218 219 println(id + " 0 obj"); 220 } 221 222 public void endObject() 223 throws IOException 224 { 225 println("endobj"); 226 227 _lastObject++; 228 229 for (int i = _pendingObjects.size() - 1; i >= 0; i--) { 230 PDFObject obj = _pendingObjects.get(i); 231 232 if (_lastObject + 1 == obj.getId()) { 233 _pendingObjects.remove(i); 234 235 beginObject(obj.getId()); 236 obj.writeObject(this); 237 endObject(); 238 break; 239 } 240 } 241 } 242 243 public void write(byte []buffer, int offset, int length) 244 throws IOException 245 { 246 _out.write(buffer, offset, length); 247 248 _offset += length; 249 } 250 251 public void print(String s) 252 throws IOException 253 { 254 _out.print(s); 255 256 _offset += s.length(); 257 } 258 259 public void println(String s) 260 throws IOException 261 { 262 _out.println(s); 263 264 _offset += s.length() + 1; 265 } 266 267 public void println() 268 throws IOException 269 { 270 _out.println(); 271 272 _offset += 1; 273 } 274 275 public void print(long v) 276 throws IOException 277 { 278 println(String.valueOf(v)); 279 } 280 281 public void println(long v) 282 throws IOException 283 { 284 println(String.valueOf(v)); 285 } 286 287 public void print(double v) 288 throws IOException 289 { 290 if ((long) v == v) 291 print(String.valueOf((long) v)); 292 else 293 print(String.valueOf(v)); 294 } 295 296 public void println(double v) 297 throws IOException 298 { 299 if ((long) v == v) 300 println(String.valueOf((long) v)); 301 else 302 println(String.valueOf(v)); 303 } 304 305 public String toString() 306 { 307 return "PDF[]"; 308 } 309 310 class ObjectDef { 311 private int _id; 312 private long _offset; 313 314 ObjectDef(int id, long offset) 315 { 316 _id = id; 317 _offset = offset; 318 } 319 320 void write() 321 throws IOException 322 { 323 _out.print(_offset / 1000000000L % 10); 324 _out.print(_offset / 100000000L % 10); 325 _out.print(_offset / 10000000L % 10); 326 _out.print(_offset / 1000000L % 10); 327 _out.print(_offset / 100000L % 10); 328 329 _out.print(_offset / 10000L % 10); 330 _out.print(_offset / 1000L % 10); 331 _out.print(_offset / 100L % 10); 332 _out.print(_offset / 10L % 10); 333 _out.print(_offset % 10); 334 335 _out.print(' '); 336 _out.println("00000 n"); 337 338 _offset += 19; 339 } 340 } 341 } 342 | Popular Tags |