/** * Sets the XFA key from a byte array. The old XFA is erased. * @param form the data * @param reader the reader * @param writer the writer * @throws java.io.IOException on error */ public static void SetXfa(XfaForm form, PdfReader reader, PdfWriter writer) { PdfDictionary af = (PdfDictionary)PdfReader.GetPdfObjectRelease(reader.Catalog.Get(PdfName.ACROFORM)); if (af == null) { return; } PdfObject xfa = GetXfaObject(reader); if (xfa.IsArray()) { PdfArray ar = (PdfArray)xfa; int t = -1; int d = -1; for (int k = 0; k < ar.Size; k += 2) { PdfString s = ar.GetAsString(k); if ("template".Equals(s.ToString())) { t = k + 1; } if ("datasets".Equals(s.ToString())) { d = k + 1; } } if (t > -1 && d > -1) { reader.KillXref(ar.GetAsIndirectObject(t)); reader.KillXref(ar.GetAsIndirectObject(d)); PdfStream tStream = new PdfStream(SerializeDoc(form.templateNode)); tStream.FlateCompress(writer.CompressionLevel); ar[t] = writer.AddToBody(tStream).IndirectReference; PdfStream dStream = new PdfStream(SerializeDoc(form.datasetsNode)); dStream.FlateCompress(writer.CompressionLevel); ar[d] = writer.AddToBody(dStream).IndirectReference; af.Put(PdfName.XFA, new PdfArray(ar)); return; } } reader.KillXref(af.Get(PdfName.XFA)); PdfStream str = new PdfStream(SerializeDoc(form.domDocument)); str.FlateCompress(writer.CompressionLevel); PdfIndirectReference refe = writer.AddToBody(str).IndirectReference; af.Put(PdfName.XFA, refe); }
internal void FlushObjStm() { if (numObj == 0) return; int first = index.Size; index.Append(streamObjects); PdfStream stream = new PdfStream(index.ToByteArray()); stream.FlateCompress(writer.CompressionLevel); stream.Put(PdfName.TYPE, PdfName.OBJSTM); stream.Put(PdfName.N, new PdfNumber(numObj)); stream.Put(PdfName.FIRST, new PdfNumber(first)); Add(stream, currentObjNum); index = null; streamObjects = null; numObj = 0; }
/** * Returns the CrossReferenceTable of the <CODE>Body</CODE>. * @param os * @param root * @param info * @param encryption * @param fileID * @param prevxref * @throws IOException */ internal void WriteCrossReferenceTable(Stream os, PdfIndirectReference root, PdfIndirectReference info, PdfIndirectReference encryption, PdfObject fileID, int prevxref) { int refNumber = 0; if (writer.FullCompression) { FlushObjStm(); refNumber = IndirectReferenceNumber; xrefs[new PdfCrossReference(refNumber, position)] = null; } int first = ((PdfCrossReference)xrefs.GetMinKey()).Refnum; int len = 0; ArrayList sections = new ArrayList(); foreach (PdfCrossReference entry in xrefs.Keys) { if (first + len == entry.Refnum) ++len; else { sections.Add(first); sections.Add(len); first = entry.Refnum; len = 1; } } sections.Add(first); sections.Add(len); if (writer.FullCompression) { int mid = 4; uint mask = 0xff000000; for (; mid > 1; --mid) { if ((mask & position) != 0) break; mask >>= 8; } ByteBuffer buf = new ByteBuffer(); foreach (PdfCrossReference entry in xrefs.Keys) { entry.ToPdf(mid, buf); } PdfStream xr = new PdfStream(buf.ToByteArray()); buf = null; xr.FlateCompress(writer.CompressionLevel); 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.Count; ++k) idx.Add(new PdfNumber((int)sections[k])); 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.Os); writer.crypto = enc; } else { byte[] tmp = GetISOBytes("xref\n"); os.Write(tmp, 0, tmp.Length); IEnumerator i = xrefs.Keys; i.MoveNext(); for (int k = 0; k < sections.Count; k += 2) { first = (int)sections[k]; len = (int)sections[k + 1]; tmp = GetISOBytes(first.ToString()); os.Write(tmp, 0, tmp.Length); os.WriteByte((byte)' '); tmp = GetISOBytes(len.ToString()); os.Write(tmp, 0, tmp.Length); os.WriteByte((byte)'\n'); while (len-- > 0) { ((PdfCrossReference)i.Current).ToPdf(os); i.MoveNext(); } } } }
/** * Signals that the <CODE>Document</CODE> was closed and that no other * <CODE>Elements</CODE> will be added. * <P> * The pages-tree is built and written to the outputstream. * A Catalog is constructed, as well as an Info-object, * the referencetable is composed and everything is written * to the outputstream embedded in a Trailer. */ public override void Close() { if (open) { if ((currentPageNumber - 1) != pageReferences.Count) throw new Exception("The page " + pageReferences.Count + " was requested but the document has only " + (currentPageNumber - 1) + " pages."); pdf.Close(); AddSharedObjectsToBody(); // add the root to the body PdfIndirectReference rootRef = root.WritePageTree(); // make the catalog-object and add it to the body PdfDictionary catalog = GetCatalog(rootRef); // [C9] if there is XMP data to add: add it if (xmpMetadata != null) { PdfStream xmp = new PdfStream(xmpMetadata); xmp.Put(PdfName.TYPE, PdfName.METADATA); xmp.Put(PdfName.SUBTYPE, PdfName.XML); if (crypto != null && !crypto.IsMetadataEncrypted()) { PdfArray ar = new PdfArray(); ar.Add(PdfName.CRYPT); xmp.Put(PdfName.FILTER, ar); } catalog.Put(PdfName.METADATA, body.Add(xmp).IndirectReference); } // [C10] make pdfx conformant if (IsPdfX()) { pdfxConformance.CompleteInfoDictionary(Info); pdfxConformance.CompleteExtraCatalog(ExtraCatalog); } // [C11] Output Intents if (extraCatalog != null) { catalog.MergeDifferent(extraCatalog); } WriteOutlines(catalog, false); // add the Catalog to the body PdfIndirectObject indirectCatalog = AddToBody(catalog, false); // add the info-object to the body PdfIndirectObject infoObj = AddToBody(Info, false); // [F1] encryption PdfIndirectReference encryption = null; PdfObject fileID = null; body.FlushObjStm(); if (crypto != null) { PdfIndirectObject encryptionObject = AddToBody(crypto.GetEncryptionDictionary(), false); encryption = encryptionObject.IndirectReference; fileID = crypto.FileID; } else fileID = PdfEncryption.CreateInfoId(PdfEncryption.CreateDocumentId()); // write the cross-reference table of the body body.WriteCrossReferenceTable(os, indirectCatalog.IndirectReference, infoObj.IndirectReference, encryption, fileID, prevxref); // make the trailer // [F2] full compression if (fullCompression) { byte[] tmp = GetISOBytes("startxref\n"); os.Write(tmp, 0, tmp.Length); tmp = GetISOBytes(body.Offset.ToString()); os.Write(tmp, 0, tmp.Length); tmp = GetISOBytes("\n%%EOF\n"); os.Write(tmp, 0, tmp.Length); } else { PdfTrailer trailer = new PdfTrailer(body.Size, body.Offset, indirectCatalog.IndirectReference, infoObj.IndirectReference, encryption, fileID, prevxref); trailer.ToPdf(this, os); } base.Close(); } }
/** * Gets an indirect reference to a JBIG2 Globals stream. * Adds the stream if it hasn't already been added to the writer. * @param content a byte array that may already been added to the writer inside a stream object. * @since 2.1.5 */ protected internal PdfIndirectReference GetReferenceJBIG2Globals(byte[] content) { if (content == null) return null; foreach (PdfStream str in JBIG2Globals.Keys) { if (Org.BouncyCastle.Utilities.Arrays.AreEqual(content, str.GetBytes())) { return (PdfIndirectReference) JBIG2Globals[str]; } } PdfStream stream = new PdfStream(content); PdfIndirectObject refi; try { refi = AddToBody(stream); } catch (IOException) { return null; } JBIG2Globals[stream] = refi.IndirectReference; return refi.IndirectReference; }
/** Outputs to the writer the font dictionaries and streams. * @param writer the writer for this document * @param ref the font indirect reference * @param parms several parameters that depend on the font type * @throws IOException on error * @throws DocumentException error in generating the object */ internal override void WriteFont(PdfWriter writer, PdfIndirectReference piref, Object[] parms) { Hashtable longTag = (Hashtable)parms[0]; AddRangeUni(longTag, true, subset); ArrayList tmp = new ArrayList(); foreach (object o in longTag.Values) { tmp.Add(o); } Object[] metrics = tmp.ToArray(); Array.Sort(metrics, this); PdfIndirectReference ind_font = null; PdfObject pobj = null; PdfIndirectObject obj = null; PdfIndirectReference cidset = null; if (writer.PDFXConformance == PdfWriter.PDFA1A || writer.PDFXConformance == PdfWriter.PDFA1B) { PdfStream stream; if (metrics.Length == 0) { stream = new PdfStream(new byte[]{(byte)0x80}); } else { int top = ((int[])metrics[metrics.Length - 1])[0]; byte[] bt = new byte[top / 8 + 1]; for (int k = 0; k < metrics.Length; ++k) { int v = ((int[])metrics[k])[0]; bt[v / 8] |= rotbits[v % 8]; } stream = new PdfStream(bt); stream.FlateCompress(compressionLevel); } cidset = writer.AddToBody(stream).IndirectReference; } // sivan: cff if (cff) { byte[] b = ReadCffFont(); if (subset || subsetRanges != null) { CFFFontSubset cffs = new CFFFontSubset(new RandomAccessFileOrArray(b),longTag); b = cffs.Process((cffs.GetNames())[0] ); } pobj = new StreamFont(b, "CIDFontType0C", compressionLevel); obj = writer.AddToBody(pobj); ind_font = obj.IndirectReference; } else { byte[] b; if (subset || directoryOffset != 0) { TrueTypeFontSubSet sb = new TrueTypeFontSubSet(fileName, new RandomAccessFileOrArray(rf), longTag, directoryOffset, false, false); b = sb.Process(); } else { b = GetFullFont(); } int[] lengths = new int[]{b.Length}; pobj = new StreamFont(b, lengths, compressionLevel); obj = writer.AddToBody(pobj); ind_font = obj.IndirectReference; } String subsetPrefix = ""; if (subset) subsetPrefix = CreateSubsetPrefix(); PdfDictionary dic = GetFontDescriptor(ind_font, subsetPrefix, cidset); obj = writer.AddToBody(dic); ind_font = obj.IndirectReference; pobj = GetCIDFontType2(ind_font, subsetPrefix, metrics); obj = writer.AddToBody(pobj); ind_font = obj.IndirectReference; pobj = GetToUnicode(metrics); PdfIndirectReference toUnicodeRef = null; if (pobj != null) { obj = writer.AddToBody(pobj); toUnicodeRef = obj.IndirectReference; } pobj = GetFontBaseType(ind_font, subsetPrefix, toUnicodeRef); writer.AddToBody(pobj, piref); }
/** Creates a ToUnicode CMap to allow copy and paste from Acrobat. * @param metrics metrics[0] contains the glyph index and metrics[2] * contains the Unicode code * @throws DocumentException on error * @return the stream representing this CMap or <CODE>null</CODE> */ private PdfStream GetToUnicode(Object[] metrics) { if (metrics.Length == 0) return null; StringBuilder buf = new StringBuilder( "/CIDInit /ProcSet findresource begin\n" + "12 dict begin\n" + "begincmap\n" + "/CIDSystemInfo\n" + "<< /Registry (TTX+0)\n" + "/Ordering (T42UV)\n" + "/Supplement 0\n" + ">> def\n" + "/CMapName /TTX+0 def\n" + "/CMapType 2 def\n" + "1 begincodespacerange\n" + "<0000><FFFF>\n" + "endcodespacerange\n"); int size = 0; for (int k = 0; k < metrics.Length; ++k) { if (size == 0) { if (k != 0) { buf.Append("endbfrange\n"); } size = Math.Min(100, metrics.Length - k); buf.Append(size).Append(" beginbfrange\n"); } --size; int[] metric = (int[])metrics[k]; string fromTo = ToHex(metric[0]); buf.Append(fromTo).Append(fromTo).Append(ToHex(metric[2])).Append('\n'); } buf.Append( "endbfrange\n" + "endcmap\n" + "CMapName currentdict /CMap defineresource pop\n" + "end end\n"); string s = buf.ToString(); PdfStream stream = new PdfStream(PdfEncodings.ConvertToBytes(s, null)); stream.FlateCompress(compressionLevel); return stream; }
public void AlterContents() { if (over == null && under == null) return; PdfArray ar = null; PdfObject content = PdfReader.GetPdfObject(pageN.Get(PdfName.CONTENTS), pageN); if (content == null) { ar = new PdfArray(); pageN.Put(PdfName.CONTENTS, ar); } else if (content.IsArray()) { ar = (PdfArray)content; } else if (content.IsStream()) { ar = new PdfArray(); ar.Add(pageN.Get(PdfName.CONTENTS)); pageN.Put(PdfName.CONTENTS, ar); } else { ar = new PdfArray(); pageN.Put(PdfName.CONTENTS, ar); } ByteBuffer out_p = new ByteBuffer(); if (under != null) { out_p.Append(PdfContents.SAVESTATE); ApplyRotation(pageN, out_p); out_p.Append(under.InternalBuffer); out_p.Append(PdfContents.RESTORESTATE); } if (over != null) out_p.Append(PdfContents.SAVESTATE); PdfStream stream = new PdfStream(out_p.ToByteArray()); stream.FlateCompress(cstp.CompressionLevel); PdfIndirectReference ref1 = cstp.AddToBody(stream).IndirectReference; ar.AddFirst(ref1); out_p.Reset(); if (over != null) { out_p.Append(' '); out_p.Append(PdfContents.RESTORESTATE); out_p.Append(PdfContents.SAVESTATE); ApplyRotation(pageN, out_p); out_p.Append(over.InternalBuffer); out_p.Append(PdfContents.RESTORESTATE); stream = new PdfStream(out_p.ToByteArray()); stream.FlateCompress(cstp.CompressionLevel); ar.Add(cstp.AddToBody(stream).IndirectReference); } pageN.Put(PdfName.RESOURCES, pageResources.Resources); }
/** Outputs to the writer the font dictionaries and streams. * @param writer the writer for this document * @param ref the font indirect reference * @param parms several parameters that depend on the font type * @throws IOException on error * @throws DocumentException error in generating the object */ internal override void WriteFont(PdfWriter writer, PdfIndirectReference piref, Object[] parms) { Hashtable longTag = (Hashtable)parms[0]; AddRangeUni(longTag, true, subset); ArrayList tmp = new ArrayList(); foreach (object o in longTag.Values) { tmp.Add(o); } Object[] metrics = tmp.ToArray(); Array.Sort(metrics, this); PdfIndirectReference ind_font = null; PdfObject pobj = null; PdfIndirectObject obj = null; PdfIndirectReference cidset = null; if (writer.PDFXConformance == PdfWriter.PDFA1A || writer.PDFXConformance == PdfWriter.PDFA1B) { PdfStream stream; if (metrics.Length == 0) { stream = new PdfStream(new byte[] { (byte)0x80 }); } else { int top = ((int[])metrics[metrics.Length - 1])[0]; byte[] bt = new byte[top / 8 + 1]; for (int k = 0; k < metrics.Length; ++k) { int v = ((int[])metrics[k])[0]; bt[v / 8] |= rotbits[v % 8]; } stream = new PdfStream(bt); stream.FlateCompress(compressionLevel); } cidset = writer.AddToBody(stream).IndirectReference; } // sivan: cff if (cff) { byte[] b = ReadCffFont(); if (subset || subsetRanges != null) { CFFFontSubset cffs = new CFFFontSubset(new RandomAccessFileOrArray(b), longTag); b = cffs.Process((cffs.GetNames())[0]); } pobj = new StreamFont(b, "CIDFontType0C", compressionLevel); obj = writer.AddToBody(pobj); ind_font = obj.IndirectReference; } else { byte[] b; if (subset || directoryOffset != 0) { TrueTypeFontSubSet sb = new TrueTypeFontSubSet(fileName, new RandomAccessFileOrArray(rf), longTag, directoryOffset, false, false); b = sb.Process(); } else { b = GetFullFont(); } int[] lengths = new int[] { b.Length }; pobj = new StreamFont(b, lengths, compressionLevel); obj = writer.AddToBody(pobj); ind_font = obj.IndirectReference; } String subsetPrefix = ""; if (subset) { subsetPrefix = CreateSubsetPrefix(); } PdfDictionary dic = GetFontDescriptor(ind_font, subsetPrefix, cidset); obj = writer.AddToBody(dic); ind_font = obj.IndirectReference; pobj = GetCIDFontType2(ind_font, subsetPrefix, metrics); obj = writer.AddToBody(pobj); ind_font = obj.IndirectReference; pobj = GetToUnicode(metrics); PdfIndirectReference toUnicodeRef = null; if (pobj != null) { obj = writer.AddToBody(pobj); toUnicodeRef = obj.IndirectReference; } pobj = GetFontBaseType(ind_font, subsetPrefix, toUnicodeRef); writer.AddToBody(pobj, piref); }
internal void AlterContents() { foreach (PageStamp ps in pagesToContent.Values) { PdfDictionary pageN = ps.pageN; MarkUsed(pageN); PdfArray ar = null; PdfObject content = PdfReader.GetPdfObject(pageN.Get(PdfName.CONTENTS), pageN); if (content == null) { ar = new PdfArray(); pageN.Put(PdfName.CONTENTS, ar); } else if (content.IsArray()) { ar = (PdfArray)content; MarkUsed(ar); } else if (content.IsStream()) { ar = new PdfArray(); ar.Add(pageN.Get(PdfName.CONTENTS)); pageN.Put(PdfName.CONTENTS, ar); } else { ar = new PdfArray(); pageN.Put(PdfName.CONTENTS, ar); } ByteBuffer out_p = new ByteBuffer(); if (ps.under != null) { out_p.Append(PdfContents.SAVESTATE); ApplyRotation(pageN, out_p); out_p.Append(ps.under.InternalBuffer); out_p.Append(PdfContents.RESTORESTATE); } if (ps.over != null) out_p.Append(PdfContents.SAVESTATE); PdfStream stream = new PdfStream(out_p.ToByteArray()); stream.FlateCompress(compressionLevel); ar.AddFirst(AddToBody(stream).IndirectReference); out_p.Reset(); if (ps.over != null) { out_p.Append(' '); out_p.Append(PdfContents.RESTORESTATE); ByteBuffer buf = ps.over.InternalBuffer; out_p.Append(buf.Buffer, 0, ps.replacePoint); out_p.Append(PdfContents.SAVESTATE); ApplyRotation(pageN, out_p); out_p.Append(buf.Buffer, ps.replacePoint, buf.Size - ps.replacePoint); out_p.Append(PdfContents.RESTORESTATE); stream = new PdfStream(out_p.ToByteArray()); stream.FlateCompress(compressionLevel); ar.Add(AddToBody(stream).IndirectReference); } AlterResources(ps); } }
internal void Close(Hashtable moreInfo) { if (closed) return; if (useVp) { reader.SetViewerPreferences(viewerPreferences); MarkUsed(reader.Trailer.Get(PdfName.ROOT)); } if (flat) FlatFields(); if (flatFreeText) FlatFreeTextFields(); AddFieldResources(); PdfDictionary catalog = reader.Catalog; PdfDictionary pages = (PdfDictionary)PdfReader.GetPdfObject(catalog.Get(PdfName.PAGES)); pages.Put(PdfName.ITXT, new PdfString(Document.Release)); MarkUsed(pages); PdfDictionary acroForm = (PdfDictionary)PdfReader.GetPdfObject(catalog.Get(PdfName.ACROFORM), reader.Catalog); if (acroFields != null && acroFields.Xfa.Changed) { MarkUsed(acroForm); if (!flat) acroFields.Xfa.SetXfa(this); } if (sigFlags != 0) { if (acroForm != null) { acroForm.Put(PdfName.SIGFLAGS, new PdfNumber(sigFlags)); MarkUsed(acroForm); MarkUsed(catalog); } } closed = true; AddSharedObjectsToBody(); SetOutlines(); SetJavaScript(); AddFileAttachments(); if (openAction != null) { catalog.Put(PdfName.OPENACTION, openAction); } if (pdf.pageLabels != null) catalog.Put(PdfName.PAGELABELS, pdf.pageLabels.GetDictionary(this)); // OCG if (documentOCG.Count > 0) { FillOCProperties(false); PdfDictionary ocdict = catalog.GetAsDict(PdfName.OCPROPERTIES); if (ocdict == null) { reader.Catalog.Put(PdfName.OCPROPERTIES, OCProperties); } else { ocdict.Put(PdfName.OCGS, OCProperties.Get(PdfName.OCGS)); PdfDictionary ddict = ocdict.GetAsDict(PdfName.D); if (ddict == null) { ddict = new PdfDictionary(); ocdict.Put(PdfName.D, ddict); } ddict.Put(PdfName.ORDER, OCProperties.GetAsDict(PdfName.D).Get(PdfName.ORDER)); ddict.Put(PdfName.RBGROUPS, OCProperties.GetAsDict(PdfName.D).Get(PdfName.RBGROUPS)); ddict.Put(PdfName.OFF, OCProperties.GetAsDict(PdfName.D).Get(PdfName.OFF)); ddict.Put(PdfName.AS, OCProperties.GetAsDict(PdfName.D).Get(PdfName.AS)); } } // metadata int skipInfo = -1; PRIndirectReference iInfo = (PRIndirectReference)reader.Trailer.Get(PdfName.INFO); PdfDictionary oldInfo = (PdfDictionary)PdfReader.GetPdfObject(iInfo); String producer = null; if (iInfo != null) skipInfo = iInfo.Number; if (oldInfo != null && oldInfo.Get(PdfName.PRODUCER) != null) producer = oldInfo.GetAsString(PdfName.PRODUCER).ToString(); if (producer == null) { producer = Document.Version; } else if (producer.IndexOf(Document.Product) == -1) { StringBuilder buf = new StringBuilder(producer); buf.Append("; modified using "); buf.Append(Document.Version); producer = buf.ToString(); } // XMP byte[] altMetadata = null; PdfObject xmpo = PdfReader.GetPdfObject(catalog.Get(PdfName.METADATA)); if (xmpo != null && xmpo.IsStream()) { altMetadata = PdfReader.GetStreamBytesRaw((PRStream)xmpo); PdfReader.KillIndirect(catalog.Get(PdfName.METADATA)); } if (xmpMetadata != null) { altMetadata = xmpMetadata; } // if there is XMP data to add: add it PdfDate date = new PdfDate(); if (altMetadata != null) { PdfStream xmp; try { XmpReader xmpr = new XmpReader(altMetadata); if (!xmpr.Replace("http://ns.adobe.com/pdf/1.3/", "Producer", producer)) xmpr.Add("rdf:Description", "http://ns.adobe.com/pdf/1.3/", "pdf:Producer", producer); if (!xmpr.Replace("http://ns.adobe.com/xap/1.0/", "ModifyDate", date.GetW3CDate())) xmpr.Add("rdf:Description", "http://ns.adobe.com/xap/1.0/", "xmp:ModifyDate", date.GetW3CDate()); xmpr.Replace("http://ns.adobe.com/xap/1.0/", "MetadataDate", date.GetW3CDate()); xmp = new PdfStream(xmpr.SerializeDoc()); } catch { xmp = new PdfStream(altMetadata); } xmp.Put(PdfName.TYPE, PdfName.METADATA); xmp.Put(PdfName.SUBTYPE, PdfName.XML); if (crypto != null && !crypto.IsMetadataEncrypted()) { PdfArray ar = new PdfArray(); ar.Add(PdfName.CRYPT); xmp.Put(PdfName.FILTER, ar); } if (append && xmpo != null) { body.Add(xmp, xmpo.IndRef); } else { catalog.Put(PdfName.METADATA, body.Add(xmp).IndirectReference); MarkUsed(catalog); } } try { file.ReOpen(); AlterContents(); int rootN = ((PRIndirectReference)reader.trailer.Get(PdfName.ROOT)).Number; if (append) { int[] keys = marked.GetKeys(); for (int k = 0; k < keys.Length; ++k) { int j = keys[k]; PdfObject obj = reader.GetPdfObjectRelease(j); if (obj != null && skipInfo != j && j < initialXrefSize) { AddToBody(obj, j, j != rootN); } } for (int k = initialXrefSize; k < reader.XrefSize; ++k) { PdfObject obj = reader.GetPdfObject(k); if (obj != null) { AddToBody(obj, GetNewObjectNumber(reader, k, 0)); } } } else { for (int k = 1; k < reader.XrefSize; ++k) { PdfObject obj = reader.GetPdfObjectRelease(k); if (obj != null && skipInfo != k) { AddToBody(obj, GetNewObjectNumber(reader, k, 0), k != rootN); } } } } finally { try { file.Close(); } catch { // empty on purpose } } PdfIndirectReference encryption = null; PdfObject fileID = null; if (crypto != null) { if (append) { encryption = reader.GetCryptoRef(); } else { PdfIndirectObject encryptionObject = AddToBody(crypto.GetEncryptionDictionary(), false); encryption = encryptionObject.IndirectReference; } fileID = crypto.FileID; } else fileID = PdfEncryption.CreateInfoId(PdfEncryption.CreateDocumentId()); PRIndirectReference iRoot = (PRIndirectReference)reader.trailer.Get(PdfName.ROOT); PdfIndirectReference root = new PdfIndirectReference(0, GetNewObjectNumber(reader, iRoot.Number, 0)); PdfIndirectReference info = null; PdfDictionary newInfo = new PdfDictionary(); if (oldInfo != null) { foreach (PdfName key in oldInfo.Keys) { PdfObject value = PdfReader.GetPdfObject(oldInfo.Get(key)); newInfo.Put(key, value); } } if (moreInfo != null) { foreach (DictionaryEntry entry in moreInfo) { PdfName keyName = new PdfName((String)entry.Key); String value = (String)entry.Value; if (value == null) newInfo.Remove(keyName); else newInfo.Put(keyName, new PdfString(value, PdfObject.TEXT_UNICODE)); } } newInfo.Put(PdfName.MODDATE, date); newInfo.Put(PdfName.PRODUCER, new PdfString(producer)); if (append) { if (iInfo == null) info = AddToBody(newInfo, false).IndirectReference; else info = AddToBody(newInfo, iInfo.Number, false).IndirectReference; } else { info = AddToBody(newInfo, false).IndirectReference; } // write the cross-reference table of the body body.WriteCrossReferenceTable(os, root, info, encryption, fileID, prevxref); if (fullCompression) { byte[] tmp = GetISOBytes("startxref\n"); os.Write(tmp, 0, tmp.Length); tmp = GetISOBytes(body.Offset.ToString()); os.Write(tmp, 0, tmp.Length); tmp = GetISOBytes("\n%%EOF\n"); os.Write(tmp, 0, tmp.Length); } else { PdfTrailer trailer = new PdfTrailer(body.Size, body.Offset, root, info, encryption, fileID, prevxref); trailer.ToPdf(this, os); } os.Flush(); if (CloseStream) os.Close(); reader.Close(); }
internal override void WriteFont(PdfWriter writer, PdfIndirectReference piRef, Object[] oParams) { if (this.writer != writer) throw new ArgumentException("Type3 font used with the wrong PdfWriter"); // Get first & lastchar ... int firstChar = 0; while( firstChar < usedSlot.Length && !usedSlot[firstChar] ) firstChar++; if ( firstChar == usedSlot.Length ) { throw new DocumentException( "No glyphs defined for Type3 font" ); } int lastChar = usedSlot.Length - 1; while( lastChar >= firstChar && !usedSlot[lastChar] ) lastChar--; int[] widths = new int[lastChar - firstChar + 1]; int[] invOrd = new int[lastChar - firstChar + 1]; int invOrdIndx = 0, w = 0; for( int u = firstChar; u<=lastChar; u++, w++ ) { if ( usedSlot[u] ) { invOrd[invOrdIndx++] = u; widths[w] = widths3[u]; } } PdfArray diffs = new PdfArray(); PdfDictionary charprocs = new PdfDictionary(); int last = -1; for (int k = 0; k < invOrdIndx; ++k) { int c = invOrd[k]; if (c > last) { last = c; diffs.Add(new PdfNumber(last)); } ++last; int c2 = invOrd[k]; String s = GlyphList.UnicodeToName(c2); if (s == null) s = "a" + c2; PdfName n = new PdfName(s); diffs.Add(n); Type3Glyph glyph = (Type3Glyph)char2glyph[(char)c2]; PdfStream stream = new PdfStream(glyph.ToPdf(null)); stream.FlateCompress(compressionLevel); PdfIndirectReference refp = writer.AddToBody(stream).IndirectReference; charprocs.Put(n, refp); } PdfDictionary font = new PdfDictionary(PdfName.FONT); font.Put(PdfName.SUBTYPE, PdfName.TYPE3); if (colorized) font.Put(PdfName.FONTBBOX, new PdfRectangle(0, 0, 0, 0)); else font.Put(PdfName.FONTBBOX, new PdfRectangle(llx, lly, urx, ury)); font.Put(PdfName.FONTMATRIX, new PdfArray(new float[]{0.001f, 0, 0, 0.001f, 0, 0})); font.Put(PdfName.CHARPROCS, writer.AddToBody(charprocs).IndirectReference); PdfDictionary encoding = new PdfDictionary(); encoding.Put(PdfName.DIFFERENCES, diffs); font.Put(PdfName.ENCODING, writer.AddToBody(encoding).IndirectReference); font.Put(PdfName.FIRSTCHAR, new PdfNumber(firstChar)); font.Put(PdfName.LASTCHAR, new PdfNumber(lastChar)); font.Put(PdfName.WIDTHS, writer.AddToBody(new PdfArray(widths)).IndirectReference); if (pageResources.HasResources()) font.Put(PdfName.RESOURCES, writer.AddToBody(pageResources.Resources).IndirectReference); writer.AddToBody(font, piRef); }
/** Creates a JavaScript action. If the JavaScript is smaller than * 50 characters it will be placed as a string, otherwise it will * be placed as a compressed stream. * @param code the JavaScript code * @param writer the writer for this action * @param unicode select JavaScript unicode. Note that the internal * Acrobat JavaScript engine does not support unicode, * so this may or may not work for you * @return the JavaScript action */ public static PdfAction JavaScript(string code, PdfWriter writer, bool unicode) { PdfAction js = new PdfAction(); js.Put(PdfName.S, PdfName.JAVASCRIPT); if (unicode && code.Length < 50) { js.Put(PdfName.JS, new PdfString(code, PdfObject.TEXT_UNICODE)); } else if (!unicode && code.Length < 100) { js.Put(PdfName.JS, new PdfString(code)); } else { try { byte[] b = PdfEncodings.ConvertToBytes(code, unicode ? PdfObject.TEXT_UNICODE : PdfObject.TEXT_PDFDOCENCODING); PdfStream stream = new PdfStream(b); stream.FlateCompress(writer.CompressionLevel); js.Put(PdfName.JS, writer.AddToBody(stream).IndirectReference); } catch { js.Put(PdfName.JS, new PdfString(code)); } } return js; }
public void AlterContents() { if (over == null && under == null) { return; } PdfArray ar = null; PdfObject content = PdfReader.GetPdfObject(pageN.Get(PdfName.CONTENTS), pageN); if (content == null) { ar = new PdfArray(); pageN.Put(PdfName.CONTENTS, ar); } else if (content.IsArray()) { ar = (PdfArray)content; } else if (content.IsStream()) { ar = new PdfArray(); ar.Add(pageN.Get(PdfName.CONTENTS)); pageN.Put(PdfName.CONTENTS, ar); } else { ar = new PdfArray(); pageN.Put(PdfName.CONTENTS, ar); } ByteBuffer out_p = new ByteBuffer(); if (under != null) { out_p.Append(PdfContents.SAVESTATE); ApplyRotation(pageN, out_p); out_p.Append(under.InternalBuffer); out_p.Append(PdfContents.RESTORESTATE); } if (over != null) { out_p.Append(PdfContents.SAVESTATE); } PdfStream stream = new PdfStream(out_p.ToByteArray()); stream.FlateCompress(cstp.CompressionLevel); PdfIndirectReference ref1 = cstp.AddToBody(stream).IndirectReference; ar.AddFirst(ref1); out_p.Reset(); if (over != null) { out_p.Append(' '); out_p.Append(PdfContents.RESTORESTATE); out_p.Append(PdfContents.SAVESTATE); ApplyRotation(pageN, out_p); out_p.Append(over.InternalBuffer); out_p.Append(PdfContents.RESTORESTATE); stream = new PdfStream(out_p.ToByteArray()); stream.FlateCompress(cstp.CompressionLevel); ar.Add(cstp.AddToBody(stream).IndirectReference); } pageN.Put(PdfName.RESOURCES, pageResources.Resources); }
/** * Makes a new page and sends it to the <CODE>PdfWriter</CODE>. * * @return a <CODE>bool</CODE> * @throws DocumentException on error */ public override bool NewPage() { lastElementType = -1; if (writer == null || (writer.DirectContent.Size == 0 && writer.DirectContentUnder.Size == 0 && (pageEmpty || writer.IsPaused()))) { SetNewPageSizeAndMargins(); return false; } if (!open || close) { throw new Exception("The document isn't open."); } IPdfPageEvent pageEvent = writer.PageEvent; if (pageEvent != null) pageEvent.OnEndPage(writer, this); //Added to inform any listeners that we are moving to a new page (added by David Freels) base.NewPage(); // the following 2 lines were added by Pelikan Stephan indentation.imageIndentLeft = 0; indentation.imageIndentRight = 0; // we flush the arraylist with recently written lines FlushLines(); // we prepare the elements of the page dictionary // [U1] page size and rotation int rotation = pageSize.Rotation; // [C10] if (writer.IsPdfX()) { if (thisBoxSize.ContainsKey("art") && thisBoxSize.ContainsKey("trim")) throw new PdfXConformanceException("Only one of ArtBox or TrimBox can exist in the page."); if (!thisBoxSize.ContainsKey("art") && !thisBoxSize.ContainsKey("trim")) { if (thisBoxSize.ContainsKey("crop")) thisBoxSize["trim"] = thisBoxSize["crop"]; else thisBoxSize["trim"] = new PdfRectangle(pageSize, pageSize.Rotation); } } // [M1] pageResources.AddDefaultColorDiff(writer.DefaultColorspace); if (writer.RgbTransparencyBlending) { PdfDictionary dcs = new PdfDictionary(); dcs.Put(PdfName.CS, PdfName.DEVICERGB); pageResources.AddDefaultColorDiff(dcs); } PdfDictionary resources = pageResources.Resources; // we create the page dictionary PdfPage page = new PdfPage(new PdfRectangle(pageSize, rotation), thisBoxSize, resources, rotation); page.Put(PdfName.TABS, writer.Tabs); // we complete the page dictionary // [C9] if there is XMP data to add: add it if (xmpMetadata != null) { PdfStream xmp = new PdfStream(xmpMetadata); xmp.Put(PdfName.TYPE, PdfName.METADATA); xmp.Put(PdfName.SUBTYPE, PdfName.XML); PdfEncryption crypto = writer.Encryption; if (crypto != null && !crypto.IsMetadataEncrypted()) { PdfArray ar = new PdfArray(); ar.Add(PdfName.CRYPT); xmp.Put(PdfName.FILTER, ar); } page.Put(PdfName.METADATA, writer.AddToBody(xmp).IndirectReference); } // [U3] page actions: transition, duration, additional actions if (this.transition!=null) { page.Put(PdfName.TRANS, this.transition.TransitionDictionary); transition = null; } if (this.duration>0) { page.Put(PdfName.DUR,new PdfNumber(this.duration)); duration = 0; } if (pageAA != null) { page.Put(PdfName.AA, writer.AddToBody(pageAA).IndirectReference); pageAA = null; } // [U4] we add the thumbs if (thumb != null) { page.Put(PdfName.THUMB, thumb); thumb = null; } // [U8] we check if the userunit is defined if (writer.Userunit > 0f) { page.Put(PdfName.USERUNIT, new PdfNumber(writer.Userunit)); } // [C5] and [C8] we add the annotations if (annotationsImp.HasUnusedAnnotations()) { PdfArray array = annotationsImp.RotateAnnotations(writer, pageSize); if (array.Size != 0) page.Put(PdfName.ANNOTS, array); } // [F12] we add tag info if (writer.IsTagged()) page.Put(PdfName.STRUCTPARENTS, new PdfNumber(writer.CurrentPageNumber - 1)); if (text.Size > textEmptySize) text.EndText(); else text = null; writer.Add(page, new PdfContents(writer.DirectContentUnder, graphics, text, writer.DirectContent, pageSize)); // we initialize the new page InitPage(); return true; }
/** * Gets the stream representing this object. * * @param compressionLevel the compressionLevel * @return the stream representing this template * @since 2.1.3 (replacing the method without param compressionLevel) * @throws IOException */ internal override PdfStream GetFormXObject(int compressionLevel) { PdfStream s = new PdfStream(content.ToByteArray()); s.Put(PdfName.TYPE, PdfName.XOBJECT); s.Put(PdfName.SUBTYPE, PdfName.PS); s.FlateCompress(compressionLevel); return s; }