📄 pdfwriter.java
字号:
* This methods creates a <CODE>PdfIndirectObject</CODE> with the number given by * <CODE>ref</CODE>, containing the given <CODE>PdfObject</CODE>. * It also adds a <CODE>PdfCrossReference</CODE> for this object * to an <CODE>ArrayList</CODE> that will be used to build the * Cross-reference Table. * * @param object a <CODE>PdfObject</CODE> * @param ref a <CODE>PdfIndirectReference</CODE> * @return a <CODE>PdfIndirectObject</CODE> * @throws IOException */ PdfIndirectObject add(PdfObject object, PdfIndirectReference ref) throws IOException { return add(object, ref.getNumber()); } PdfIndirectObject add(PdfObject object, PdfIndirectReference ref, boolean inObjStm) throws IOException { return add(object, ref.getNumber(), inObjStm); } PdfIndirectObject add(PdfObject object, int refNumber) throws IOException { return add(object, refNumber, true); // to false } PdfIndirectObject add(PdfObject object, int refNumber, boolean inObjStm) throws IOException { if (inObjStm && object.canBeInObjStm() && writer.isFullCompression()) { PdfCrossReference pxref = addToObjStm(object, refNumber); PdfIndirectObject indirect = new PdfIndirectObject(refNumber, object, writer); if (!xrefs.add(pxref)) { xrefs.remove(pxref); xrefs.add(pxref); } return indirect; } else { PdfIndirectObject indirect = new PdfIndirectObject(refNumber, object, writer); PdfCrossReference pxref = new PdfCrossReference(refNumber, position); if (!xrefs.add(pxref)) { xrefs.remove(pxref); xrefs.add(pxref); } indirect.writeTo(writer.getOs()); position = writer.getOs().getCounter(); return indirect; } } /** * Returns the offset of the Cross-Reference table. * * @return an offset */ int offset() { return position; } /** * Returns the total number of objects contained in the CrossReferenceTable of this <CODE>Body</CODE>. * * @return a number of objects */ int size() { return Math.max(((PdfCrossReference)xrefs.last()).getRefnum() + 1, refnum); } /** * Returns the CrossReferenceTable of the <CODE>Body</CODE>. * @param os * @param root * @param info * @param encryption * @param fileID * @param prevxref * @throws IOException */ void writeCrossReferenceTable(OutputStream os, PdfIndirectReference root, PdfIndirectReference info, PdfIndirectReference encryption, PdfObject fileID, int prevxref) throws IOException { int refNumber = 0; if (writer.isFullCompression()) { flushObjStm(); refNumber = getIndirectReferenceNumber(); xrefs.add(new PdfCrossReference(refNumber, position)); } PdfCrossReference entry = (PdfCrossReference)xrefs.first(); int first = entry.getRefnum(); int len = 0; ArrayList sections = new ArrayList(); for (Iterator i = xrefs.iterator(); i.hasNext(); ) { entry = (PdfCrossReference)i.next(); if (first + len == entry.getRefnum()) ++len; else { sections.add(new Integer(first)); sections.add(new Integer(len)); first = entry.getRefnum(); len = 1; } } sections.add(new Integer(first)); sections.add(new Integer(len)); if (writer.isFullCompression()) { int mid = 4; int mask = 0xff000000; for (; mid > 1; --mid) { if ((mask & position) != 0) break; mask >>>= 8; } ByteBuffer buf = new ByteBuffer(); for (Iterator i = xrefs.iterator(); i.hasNext(); ) { entry = (PdfCrossReference) i.next(); entry.toPdf(mid, buf); } PdfStream xr = new PdfStream(buf.toByteArray()); buf = null; xr.flateCompress(writer.getCompressionLevel()); xr.put(PdfName.SIZE, new PdfNumber(size())); xr.put(PdfName.ROOT, root); if (info != null) { xr.put(PdfName.INFO, info); } if (encryption != null) xr.put(PdfName.ENCRYPT, encryption); if (fileID != null) xr.put(PdfName.ID, fileID); xr.put(PdfName.W, new PdfArray(new int[]{1, mid, 2})); xr.put(PdfName.TYPE, PdfName.XREF); PdfArray idx = new PdfArray(); for (int k = 0; k < sections.size(); ++k) idx.add(new PdfNumber(((Integer)sections.get(k)).intValue())); xr.put(PdfName.INDEX, idx); if (prevxref > 0) xr.put(PdfName.PREV, new PdfNumber(prevxref)); PdfEncryption enc = writer.crypto; writer.crypto = null; PdfIndirectObject indirect = new PdfIndirectObject(refNumber, xr, writer); indirect.writeTo(writer.getOs()); writer.crypto = enc; } else { os.write(getISOBytes("xref\n")); Iterator i = xrefs.iterator(); for (int k = 0; k < sections.size(); k += 2) { first = ((Integer)sections.get(k)).intValue(); len = ((Integer)sections.get(k + 1)).intValue(); os.write(getISOBytes(String.valueOf(first))); os.write(getISOBytes(" ")); os.write(getISOBytes(String.valueOf(len))); os.write('\n'); while (len-- > 0) { entry = (PdfCrossReference) i.next(); entry.toPdf(os); } } } } } /** * <CODE>PdfTrailer</CODE> is the PDF Trailer object. * <P> * This object is described in the 'Portable Document Format Reference Manual version 1.3' * section 5.16 (page 59-60). */ static class PdfTrailer extends PdfDictionary { // membervariables int offset; // constructors /** * Constructs a PDF-Trailer. * * @param size the number of entries in the <CODE>PdfCrossReferenceTable</CODE> * @param offset offset of the <CODE>PdfCrossReferenceTable</CODE> * @param root an indirect reference to the root of the PDF document * @param info an indirect reference to the info object of the PDF document * @param encryption * @param fileID * @param prevxref */ PdfTrailer(int size, int offset, PdfIndirectReference root, PdfIndirectReference info, PdfIndirectReference encryption, PdfObject fileID, int prevxref) { this.offset = offset; put(PdfName.SIZE, new PdfNumber(size)); put(PdfName.ROOT, root); if (info != null) { put(PdfName.INFO, info); } if (encryption != null) put(PdfName.ENCRYPT, encryption); if (fileID != null) put(PdfName.ID, fileID); if (prevxref > 0) put(PdfName.PREV, new PdfNumber(prevxref)); } /** * Returns the PDF representation of this <CODE>PdfObject</CODE>. * @param writer * @param os * @throws IOException */ public void toPdf(PdfWriter writer, OutputStream os) throws IOException { os.write(getISOBytes("trailer\n")); super.toPdf(null, os); os.write(getISOBytes("\nstartxref\n")); os.write(getISOBytes(String.valueOf(offset))); os.write(getISOBytes("\n%%EOF\n")); } }// ESSENTIALS // Construct a PdfWriter instance /** * Constructs a <CODE>PdfWriter</CODE>. */ protected PdfWriter() { } /** * Constructs a <CODE>PdfWriter</CODE>. * <P> * Remark: a PdfWriter can only be constructed by calling the method * <CODE>getInstance(Document document, OutputStream os)</CODE>. * * @param document The <CODE>PdfDocument</CODE> that has to be written * @param os The <CODE>OutputStream</CODE> the writer has to write to. */ protected PdfWriter(PdfDocument document, OutputStream os) { super(document, os); pdf = document; directContent = new PdfContentByte(this); directContentUnder = new PdfContentByte(this); } /** * Use this method to get an instance of the <CODE>PdfWriter</CODE>. * * @param document The <CODE>Document</CODE> that has to be written * @param os The <CODE>OutputStream</CODE> the writer has to write to. * @return a new <CODE>PdfWriter</CODE> * * @throws DocumentException on error */ public static PdfWriter getInstance(Document document, OutputStream os) throws DocumentException { PdfDocument pdf = new PdfDocument(); document.addDocListener(pdf); PdfWriter writer = new PdfWriter(pdf, os); pdf.addWriter(writer); return writer; } /** * Use this method to get an instance of the <CODE>PdfWriter</CODE>. * * @return a new <CODE>PdfWriter</CODE> * @param document The <CODE>Document</CODE> that has to be written * @param os The <CODE>OutputStream</CODE> the writer has to write to. * @param listener A <CODE>DocListener</CODE> to pass to the PdfDocument. * @throws DocumentException on error */ public static PdfWriter getInstance(Document document, OutputStream os, DocListener listener) throws DocumentException { PdfDocument pdf = new PdfDocument(); pdf.addDocListener(listener); document.addDocListener(pdf); PdfWriter writer = new PdfWriter(pdf, os); pdf.addWriter(writer); return writer; }// the PdfDocument instance /** the pdfdocument object. */ protected PdfDocument pdf; /** * Gets the <CODE>PdfDocument</CODE> associated with this writer. * @return the <CODE>PdfDocument</CODE> */ PdfDocument getPdfDocument() { return pdf; } /** * Use this method to get the info dictionary if you want to * change it directly (add keys and values to the info dictionary). * @return the info dictionary */ public PdfDictionary getInfo() { return pdf.getInfo(); } /** * Use this method to get the current vertical page position. * @param ensureNewLine Tells whether a new line shall be enforced. This may cause side effects * for elements that do not terminate the lines they've started because those lines will get * terminated. * @return The current vertical page position. */ public float getVerticalPosition(boolean ensureNewLine) { return pdf.getVerticalPosition(ensureNewLine); } // the PdfDirectContentByte instances /* * You should see Direct Content as a canvas on which you can draw * graphics and text. One canvas goes on top of the page (getDirectContent), * the other goes underneath (getDirectContentUnder). * You can always the same object throughout your document, * even if you have moved to a new page. Whatever you add on * the canvas will be displayed on top or under the current page. */ /** The direct content in this document. */ protected PdfContentByte directContent; /** The direct content under in this document. */ protected PdfContentByte directContentUnder; /** * Use this method to get the direct content for this document. * There is only one direct content, multiple calls to this method * will allways retrieve the same object. * @return the direct content */ public PdfContentByte getDirectContent() { if (!open) throw new RuntimeException("The document is not open."); return directContent; } /** * Use this method to get the direct content under for this document.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -